[question] с-double: 35.7 * 100 vs 3570.0

Hi all!

There is a simple c code:

double a = 3570.0;
double b = 35.7 * 100;
int main ()
{
if (b != a) return 1;
return 0;
}

It returns 1 due to:
40abe400 00000000 //a = 3570.0
40abe400 00000001 //b = 35.7 * 100;

gcc do the same thing, so I think it’s ok but why?

For floats:

float a = 3570.0;
float b = 35.7 * 100;
int main ()
{
if (b != a) return 1;
return 0;
}

It returns 0…
455f2000 //a = 3570.0
455f2000 //b = 35.7 * 100;

I will be grateful to get any explanations.

Floating point arithmetic is not intuitive. http://www.lsi.upc.edu/~robert/teaching/master/material/p5-goldberg.pdf is a good introduction to the common pitfalls.

TL;DR 35.7 cannot be represented exactly as a floating point number.

- Matthias

Thank you!

Your problem is that while 35.7 looks nice and neat in decimal – it’s 357/10 – computers store numbers in binary. In the case of IEEE double precision floating point it will be stored as 5024328334285210/2^47 which is 5024328334285210/140737488355328. That’s the nearest you can do in binary floating point with a 53 bit mantissa.

Multiply by 100 and you get 502432833428521000/140737488355328, which if you work it out is 3570, with 40 left over. Which is not exactly 3570. But it’s close.

If you need more accurate than that you should use fractions (in fact, “bignum” fractions), not floating point.