python floating number [duplicate]
Asked Answered
C

4

10

i am kind of confused why python add some additional decimal number in this case, please help to explain

>>> mylist = ["list item 1", 2, 3.14]
>>> print mylist ['list item 1', 2, 3.1400000000000001]
Chemoprophylaxis answered 6/6, 2010 at 22:22 Comment(3)
+1 for asking an intelligent question, not assuming that this was a bug in Python.Ganja
Similar to https://mcmap.net/q/473690/-python-rounding-problemChristy
It's a FAQ: pyfaq.infogami.com/…Priggery
S
14

Floating point numbers are an approximation, they cannot store decimal numbers exactly. Because they try to represent a very large range of numbers in only 64 bits, they must approximate to some extent.

It is very important to be aware of this, because it results in some weird side-effects. For example, you might very reasonably think that the sum of ten lots of 0.1 would be 1.0. While this seems logical, it is also wrong when it comes to floating point:

>>> f = 0.0
>>> for _ in range (10):
...  f += 0.1
...
>>> print f == 1.0
False
>>> f
0.99999999999999989
>>> str(f)
1.0

You might think that n / m * m == n. Once again, floating-point world disagrees:

>>> (1.0 / 103.0) * 103.0
0.99999999999999989

Or perhaps just as strangely, one might think that for all n, n + 1 != n. In floating point land, numbers just don't work like this:

>>> 10.0**200
9.9999999999999997e+199
>>> 10.0**200 == 10.0**200 + 1
True
# How much do we have to add to 10.0**200 before its 
# floating point representation changes?
>>> 10.0**200 == 10.0**200 + 10.0**183
True
>>> 10.0**200 == 10.0**200 + 10.0**184
False

See What every computer scientist should know about floating point numbers for an excellent summary of the issues.

If you need exact decimal representation, check out the decimal module, part of the python standard library since 2.4. It allows you to specify the number of significant figures. The downside is, it is much slower than floating point, because floating point operations are implemented in hardware whereas decimal operations happen purely in software. It also has its own imprecision issues, but if you need exact representation of decimal numbers (e.g. for a financial application) it's ideal.

For example:

>>> 3.14
3.1400000000000001
>>> import decimal
>>> decimal.Decimal('3.14')
>>> print decimal.Decimal('3.14')
3.14
# change the precision:
>>> decimal.getcontext().prec = 6
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.142857')
>>> decimal.getcontext().prec = 28
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.1428571428571428571428571429')
Siltstone answered 6/6, 2010 at 22:26 Comment(3)
>>> from decimal import * Traceback (innermost last): File "<interactive input>", line 1, in ? ImportError: No module named decimal there is error when i try to import decimal module, where can i get it? it might sound stupid, but i am new to python.Chemoprophylaxis
decimal is available from python version 2.4 and later.Unexpressive
@zhack, we're a developer community answering questions for no gain. Stop saying your questions are stupid.Ablation
T
6

It is worthwhile to note that Python 3.1 has a new floating point output routine that rounds this in the expected manner (it has also been backported to Python 2.7):

Python 3.1 (r31:73572, Aug 15 2009, 17:12:41) 
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [3.14]
>>> print(a)
[3.14]

From the What's New in Python 3.1 document:

Python now uses David Gay’s algorithm for finding the shortest floating point representation that doesn’t change its value. This should help mitigate some of the confusion surrounding binary floating point numbers.

The significance is easily seen with a number like 1.1 which does not have an exact equivalent in binary floating point. Since there is no exact equivalent, an expression like float('1.1') evaluates to the nearest representable value which is 0x1.199999999999ap+0 in hex or 1.100000000000000088817841970012523233890533447265625 in decimal. That nearest value was and still is used in subsequent floating point calculations.

Trenchant answered 6/6, 2010 at 22:47 Comment(0)
R
0

As mentioned before, it's all about floating points being an approximation.

If you want exactness you can use a decimal (which is a precise representation): http://docs.python.org/library/decimal.html

a = [1.5, 1.49999]
a
[1.5, 1.4999899999999999]

from decimal import Decimal
b = [1.5, Decimal('1.4999')]
b
[1.5, Decimal('1.4999')]
Renwick answered 6/6, 2010 at 22:30 Comment(1)
Keep in mind that a lot of non-financial applications don't NEED exactness. And functions like sin, ln, and sqrt don't return exact answers in any base.Priggery
G
-1

We can fix it by this command:

>>> x = 1.2 - 1.0
>>> x
0.19999999999999996
>>> y = float(str(x))
>>> y
0.2

I add an answer from @mark

Goglet answered 30/6, 2015 at 16:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.