The following code works as expected for me under 64-bits, but fails under 32-bit at -O2 and -O3, the expected output is 1.1, under the bugged systems it prints 1.0. I’m trying to establish if this is a bug in my code (making some bad assumptions about how floats work) or in GCC. If it’s in my code, how on earth do I go about fixing it?
#include <math.h>
#include <stdio.h>
int f(double x) {
return isinf(1.0 / x);
}
int m_isinf(double x) {
return x != 0 && x * 0.5 == x;
}
int g(double x) {
return m_isinf(1.0 / x);
}
double values[] = {
5.5e-309,
-1.0
};
int main() {
int i;
for (i = 0; values[i] != -1.0; i++) {
printf("%d\n", f(values[i]));
printf("%d\n", g(values[i]));
}
return 0;
}
Expression may be evaluated with more precision than the type. In your 32 bit build, the compiler is probably using the 80 bits long double (which is no more used in 64 bits) to evaluate
x != 0 && x * 0.5 == x.(GCC has know problems with this rules, evaluating with more precisions in context where it can’t).
6.3.1.8/2 in C99 (6.2.1.5 in C90 is equivalent):
In a conforming implementation:
should work. But gcc bug (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 look at the number of duplicates) often prevent this to work. There are some work around in the bug report.