2

Possible Duplicate:
python - decimal place issues with floats

In [4]: 52+121.2

Out[4]: 173.19999999999999

Community
  • 1
  • 1
  • 1
    Duplicate: http://stackoverflow.com/questions/286061/python-decimal-place-issues-with-floats – S.Lott Jun 02 '09 at 10:17
  • See the first answer to http://stackoverflow.com/questions/286061/python-decimal-place-issues-with-floats. – Nosredna Jun 02 '09 at 02:38

4 Answers4

22

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
  • 390,455
  • 97
  • 512
  • 589
8

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
  • 14,237
  • 1
  • 47
  • 51
7

Try this:

>>> from decimal import Decimal
>>> Decimal("52") + Decimal("121.2")
Decimal("173.2")
codeape
  • 97,830
  • 24
  • 159
  • 188
Mark Lutton
  • 6,959
  • 7
  • 41
  • 57
  • 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 Jun 12 '09 at 12:08
3

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 Rhodes
  • 83,755
  • 16
  • 106
  • 147