Search code examples
cif-statementdoublecomparison-operators

C double comparison not working as intended: -0 not equal to 0


I have a program in which I am plotting a function in the console, and I am iterating through a value of y which is a float. However, when this value is equal to zero, I would like to draw the axis. The problem arises when I try to compare this value to zero in an if statement.

My code (reduced for simplicity):

double y;
double stepy = (double) RANGE / YUNITSIZE

for (y = -RANGE; y <= ((double) RANGE + stepy); y += stepy) {
    printf("%f %f %d", y, (double) 0, y == (double) 0); // added for debugging
    if ((double) y == (double) 0) { // not executing
        for (double i = 0; i <= DOMAIN * 2; i += stepy) {
            putchar('-');
        }
    }
    putchar('\n');
}

Output:

-1.000000 0.000000 0
-0.800000 0.000000 0
-0.600000 0.000000 0
-0.400000 0.000000 0
-0.200000 0.000000 0
-0.000000 0.000000 0
0.200000 0.000000 0
0.400000 0.000000 0
0.600000 0.000000 0
0.800000 0.000000 0
1.000000 0.000000 0
1.200000 0.000000 0

You can see that, in this line: -0.000000 0.000000 0, it is comparing 0 and -0 and finding them not equal. I also tried to compare y to -0 except when I typecasted it to a double it converted back to 0.

I have looked at this description of a similar problem, but the answers say they should still be equal which in my case is not true. I also had a look at this, but I am not sure if this is the same case with C and my values appear to be exactly zero.

I would like to know what is going on here and what can I do to fix the if condition?


Solution

  • It turned out that these zero values were in fact not zero (-0.0000000000000000555112). Thanks to Adrian Mole for finding this in the comments. I ended up using Ouroborus's method for the comparison (using a narrow range) although for people viewing this in the future, it is better not to use a narrow range and instead translate these values to floats when they are actually needed as floats and compare the values as ints for reasons suggested by Fe2O3 in the comments.