Float addition bug???

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.
 
B

Bruno Jouhier [MVP]

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.
 
R

Rene

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.
 
G

Guest

but , if use 0.01 or 0.5 , it return the same error . so is not binary
representation of 0.1 is infinite.
 
J

Jon Skeet [C# MVP]

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.
 
B

Bruno Jouhier [MVP]

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
 
B

Bruno Jouhier [MVP]

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top