Comment

Comment by ambrop7

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.

parent ambrop7 6 years ago

Discussion

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton