-1

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?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Nasser Kessas
  • 359
  • 1
  • 13
  • 2
    Hmm ... *it is comparing 0 and -0* ... Maybe it is, maybe it isn't. Change the output formats to something like `%25.22lf` to see the full(er) values of those numbers. – Adrian Mole Dec 30 '22 at 07:25
  • Generally, you shouldn't be using `==` with computed doubles (or floats). They're almost never going to be exactly what you think they should be. – Ouroborus Dec 30 '22 at 07:28
  • That helped @Adrian Mole, now I got `-0.0000000000000000555112 0.0000000000000000000000 0` for the line in question. But I'm still not sure how to compare them properly. – Nasser Kessas Dec 30 '22 at 07:28
  • What should I use instead @Ouroborus – Nasser Kessas Dec 30 '22 at 07:29
  • Either convert your formulas so they use `int` or `long` right up until you actually need `double`s or do your comparisons on a narrow range, for example: `y > -1e-10 && y < 1e-10` – Ouroborus Dec 30 '22 at 07:31
  • 1
    You're missing a `-` there but I understood what you mean. It worked so thanks a lot. You can submit this as an answer if you'd like credit. – Nasser Kessas Dec 30 '22 at 07:34
  • 1
    For future reference, adding many incremental steps is not the most precise way to work with floating point values. ("Cumulative error". Research Lorenz, the beginning of Chaos Theory and the significance of minute errors when iteration is involved.) Had you calculated the values of y (from integers as suggested by @Ouroborus), it's likely your zero would have been zero... – Fe2O3 Dec 30 '22 at 07:43
  • @Fe2O3 I acknowledge, this although there is no iteration involved in what I am doing – Nasser Kessas Dec 30 '22 at 08:04
  • A synonym of "iteration" is "repetition"... That's what `for()` is for... iterating... – Fe2O3 Dec 30 '22 at 08:09
  • Ah, I see what you mean. I meant that there was no iterating following the comparison, but you are correct. – Nasser Kessas Dec 30 '22 at 08:11

1 Answers1

1

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.

Nasser Kessas
  • 359
  • 1
  • 13