|
|
|
|
|
by ambrop7
2342 days ago
|
|
Each floating point value that is not a NaN represents a certain real number, -inf or +inf (this can be expressed in terms of the sign bit, exponent and mantissa). Knowing that, a == b when neither operand is a NaN is defined as equality of what they represent, in purely mathematical terms. Similar can be said for inequality operators. Be aware that +0.0 and -0.0 are different floating point values but represent the same real number, so +0.0 == -0.0 follows. People who say == means nothing for floating point and you always need epsilon checks are wrong, plain and simple. == is very well defined. Don't confuse the definition of floating point operations with common practices for using them effectively. You can iterate through all non-NaN values and check that successive ones are indeed not equal: #include <math.h>
#include <stdint.h>
#include <assert.h>
#include <stdio.h>
#include <inttypes.h>
int main()
{
float x = (float)-INFINITY;
uint64_t count = 1;
while (x != (float)INFINITY) {
float y = nextafterf(x, (float)INFINITY);
assert(y != x);
x = y;
++count;
}
printf("Found %" PRIu64 " floats.\n", count);
return 0;
}
$ gcc -std=c99 -O3 a.c -lm -o a
$ ./a
Found 4278190081 floats.
(a little bit harder for doubles)Interestingly, this only finds one zero (-0.0), hence the assert doesn't actually fail around zero. |
|
(a) get x casted to a float
(b) get `div` instead (like in Python 2) and obtain a false result
(c) get cursed out with a type error.
These three options are available because it's possible to determine whether a given real number is representable as an int or not. This is not possible with floats.