tags:

views:

385

answers:

5

Possible Duplicate:
python - decimal place issues with floats

In [4]: 52+121.2

Out[4]: 173.19999999999999

+21  A: 

Short answer: Python uses binary arithmetic for floating-point numbers, not decimal arithmetic. Decimal fractions are not exactly representable in binary.

Long answer: What Every Computer Scientist Should Know About Floating-Point Arithmetic

Adam Rosenfield
+7  A: 

See the first answer to http://stackoverflow.com/questions/286061/python-decimal-place-issues-with-floats.

Nosredna
+7  A: 

If you're familiar with the idea that the number "thirteen point two" is written in base ten as "13.2" because it's "10^1 * 1 + 10^0 * 3 + 10^-1 * 2" then try to do the same thing with a base of 2 instead of 10 for the number 173.2.

Here's the whole part: (1 * 2^7) + (0 * 2^6) + (1 * 2^5) + (0 * 2^4) + (1 * 2^3) + (1 * 2^2) + (0 * 2^1) + (0 * 2^0)

Now here's the start fractional part: (0 * 2^-1) + (0 * 2^-2) + (1 * 2^-3)

That's .125, which isn't yet 2/10ths so we need more additions that are of the form (1 * 2^-n), we can carry this out a bit further with (1 * 2^-4) + (1 * 2^-7), which gets us a bit closer ... to 0.1953125, but no matter how long we do this, we'll never get to ".2" because ".2" is not representable as a addition of sums of numbers of the form (1 * 2^-n).

Also see .9999… = 1.0 (http://en.wikipedia.org/wiki/0.999...)

Jon Hess
I think "thirteen point three" is actually written in base ten as "13.3"! :)
Kylotan
Haha, Yep. Edited.
Jon Hess
+6  A: 

Try this:

>>> from decimal import Decimal
>>> Decimal("52") + Decimal("121.2")
Decimal("173.2")
Mark Lutton
In any language, if you are doing calculations with money, you should always use fixed-point decimal, never floating-point binary. Money calculations need to be exactly correct according to specific accounting rules. Take for instance $5.01 / 2. You may be required to apply the rule "always round down", i.e. $2.50, or the rule "round down if less than .005, otherwise up", i.e. $2.51. When doing a chain of calculations you may be required to round to the penny after each step or not round until the last step.
Mark Lutton
+2  A: 

The other answers, pointing to good floating-point resources, are where to start. If you understand floating point roundoff errors, however, and just want your numbers to look prettier and not include a dozen extra digits for that extra last bit of precision, try using str() to print the number rather than repr():

>>> 52+121.2 
173.19999999999999
>>> str(52+121.2)
'173.2'
Brandon Craig Rhodes