Floating Points and == operator

Jul 11, 2008 at 7:30pm
My code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <math.h>
	
int main() {

double dbl1 = 1.0 / 10.0;
printf("dbl1 == %f\n", dbl1);

double dbl2 = pow(2.0, -20.0) * dbl1;
printf("dbl2 == %f\n", dbl2);

double dbl3 = 9.54 * pow(10.0, -8.0);
printf("dbl3 == %f\n", dbl3);

printf("\n");


/* second printf statements */

if (dbl1 == dbl2) printf("dbl1 == dbl2\n");
else printf("dbl1 != dbl2\n");

if (dbl1 == dbl3) printf("dbl1 == dbl3\n");
else printf("dbl1 != dbl3\n");

if (dbl2 == dbl3) printf("dbl2 == dbl3\n");
else printf("dbl2 != dbl3\n");
return 0;
}



Result:
/*******************
dbl1 == 0.100000
dbl2 == 0.000000
dbl3 == 0.000000

dbl1 != dbl2
dbl1 != dbl3
dbl2 != dbl3
/********************

As you can see, even though dbl2 and dbl3 are equal, the last statement
dbl2 != dbl3 contradicts. Further investigation, I printed out their hex values as follows:

1
2
printf("hex of dbl2 %x\n", dbl2);
printf("hex of dbl3 %x\n", dbl3);


Result:
/***************************
printf("hex of dbl2 %x\n", 9999999a);
printf("hex of dbl3 %x\n", 8c737e42);
/***************************

even though the numbers are the same why is dbl2 != dbl3. A conceptual explanation would really help here.

Thanks!

Jul 11, 2008 at 7:48pm
Floating point arithmetic is not exact. (It is only precise.)

Here is a large paper that deals with it (if you are up to the reading)
http://docs.sun.com/source/806-3568/ncg_goldberg.html

but here is some quick and simple reading
http://www.petebecker.com/js/js200006.html
http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
http://www.cprogramming.com/tutorial.html#fptutorial

I'm not sure if any of the articles touch on the reasons for it, but they are esoteric. Basically it is a mismatch of precision due to conversion between one value and another on the FPU's stack.

Hope this helps.
Jul 12, 2008 at 1:38am
modified the code and got the output a bit more detailed:

old code:
1
2
3
printf("dbl1 == %f\n", dbl1);
printf("dbl2 == %f\n", dbl2);


new:
1
2
printf("dbl1 == %.12f\n", dbl1); //show 12 after the decimal point
printf("dbl2 == %.12f\n", dbl2);


output:
dbl2 = 0.000000095367
dbl3 = 0.000000095400

This shows as you increase the precision you are able to see the difference.

so a loss of precision has occurred which is why dbl2 != dbl3.
Now I need some help in putting what I just did in plain English. :)

Jul 12, 2008 at 2:48am
Perhaps round to whatever you think is significant. Then your =='s might be the way you mean them. I'm new to this whole thing and I find it a bit interesting.
Jul 13, 2008 at 7:00pm
Ok. As Duoas will happily point out. Macros aren't wonderful etc etc.

But. I do use this (in commercial software) as an easy way to simply compare doubles/floats.

1
2
3
4
#define ZERO 1e-10
#define isSame(A, B) ( ((A-B) < ZERO) && ((A-B) > -ZERO) )

if (isSame(double1, double2)) { }
Jul 13, 2008 at 7:58pm
...which is actually the correct way to do it.

What Zaita has done is check to see whether the difference between the two values are within an acceptable distance from true zero. This allows for any accuracy errors.
Jul 13, 2008 at 10:34pm
Yep :)
But macro's should be well defined in your documentation in commercial projects to ensure they are not used incorrectly. This macro is known to the other developers as a simple double/float check. They know it's context and when to not use it. It's also defined in our documentation :)
Topic archived. No new replies allowed.