views:

109

answers:

3
float totalAmount = 0;
.
.
.//totalAmount assigned value 1.05 correctly
.
totalAmount  += float.Parse(dataRow["Amt"].ToString()); //where dataRow["Amt"] has value 4.93

The answer I get for totalAmount is 5.97999954 instead of 5.98

Why is this happening?

+1  A: 

This is due to representing base-10 numbers in a base-2 system.

Floating point math on computers always does this. If you know the level of precision you'll need you should use the appropriate decimal representation.

Ben S
+8  A: 

You state that totalAmount is 1.05, before the accumulation. That would give expected results of:

1.05
4.93 +
------
5.98

You are getting 5.97999954, which is basically the answer as best represented by IEEE floating point, which is a binary format that cannot exactly express every decimal number. For instance, the rather common 0.110 has an infinite binary floating point representation .0001100110011...2.

And a Wikipedia link, for good measure: http://en.wikipedia.org/wiki/Floating%5Fpoint#Accuracy%5Fproblems ;)

jdmichal
+1 - Throw in a Wikipedia link for good measure.
ChaosPandion
Done and done. :)
Randolpho
this little edit war is funny. I'm gonna stop trying.
Randolpho
Hey, I even learned something. Neither .1 nor .01 are representable in floating point. Which makes squaring .1 an interesting case.
jdmichal
I didn't even know we were having a war. I was just editing as requested.
jdmichal
Opimistic concurrency at it's worst :) Luckily there's a rollback feature.
Richard Szalay
A: 

jdmichal is correct, but I'll add that, if you actually want this to add up correctly, you could use the Decimal type (including decimal literals).

Steven Sudit
There are many options available to fix this, depending on the context of the problem. For instance, fixed precision (such as currency) allows separation of the decimal portion into an integral type.
jdmichal