Float addition bug???

  • Thread starter Thread starter Rene
  • Start date Start date
R

Rene

The following code:

float someFloat = 0;
for(int x = 1; x <= 10; x++)
{
someFloat += .1F;
Console.WriteLine(someFloat.ToString());
}


Returns:
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8000001
0.9000001
1


WHY, WHY, WHY, WHY, WHY, WHY, WHY, WHY, WHY, WHY, WHY!!! What happened to
the nice and rounded 0.8 and 0.9? I know that the float variable is prone to
rounding issues but come on!! I am just adding a 0.1. I haven't even gotten
to where it needs to start rounding!! What's going on???? Is this normal? It
probaly is, isn't it?

Thaks for any help.
 
The problem is that 0.1 cannot be represented **exactly** as a float
(surprise!)

Float (and double) can only represent exactly numbers that can be written as
m * 2^e where m and e are integers (possibly negative).
Numbers like 0.5, 0.25, 0.125 or 0.875 are exactly representable as floats
(1*2^-1, 1*2^-2, 1^2-3, 7*2^-3) but 0.1 is not (its binary representation is
infinite)!

So, 0.1f is only an approximation of 0.1 and the error will accumulate when
you add.

Morale: if you don't want to be surprised and you don't need huge numbers
(you are not doing scientific computation with Avogadro's number or with
parsecs), then use the **decimal** type. The decimal type represents
**exactly** all the decimal numbers that fall in its range (and its range is
quite large).

Bruno.
 
Thanks Bruno, I was aware of the decimal, in fact I had the variable
declared as a decimal before but changed it to float because I thought that
adding 0.1 would be no problem for the float and there was no need for the
decimal.

I did a little hack and added the line:

someFloat = (float)Math.Round(someFloat, 1);

This fixed the problem but I think the better way is going to be to declare
it as decimal. agggg!
Thanks for the clarification.
 
but , if use 0.01 or 0.5 , it return the same error . so is not binary
representation of 0.1 is infinite.
 
Weixiao Fan said:
I mean that if use 0.5 , I can not find any error . why ?

Because 0.5 is exactly representable in binary - it's 0.1.
0.1 (decimal) isn't exactly representable in binary though.
 
Weixiao Fan said:
I mean that if use 0.5 , I can not find any error . why ?

Read my post again:
0.5 is exactly representable by the float type
0.1 is not exactly representable by the float type
So, you will get errors with 0.1 but not with 0.5

Bruno
 
Dave Weber said:
Not 100% applicable (not language specific) but it talks about the
representation of floating numbers in a binary computer (basic binary
computer architecture problem).

*just realized that the freshman computer architecture class actually
taught me something*

http://www.nuvisionmiami.com/books/asm/workbook/floating_tut.htm

The problem that was raised is not language specific, it is related to the
IEEE 754 floating point formats (single and double precision) and shows up
in all languages that use these formats (C, Java and lots of others). So,
your link is 100% relevant.

For those who really want to know everything about fp arithmetics (see the
article's title) and are not too shy about maths, I would recommend:
http://docs.sun.com/source/806-3568/ncg_goldberg.html
 
Back
Top