This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: floating point representation issues
Type: behavior Stage: resolved
Components: Interpreter Core, Library (Lib) Versions:
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: atuccia, eric.smith, steven.daprano
Priority: normal Keywords:

Created on 2020-10-25 16:49 by atuccia, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (5)
msg379589 - (view) Author: Andrea Tuccia (atuccia) Date: 2020-10-25 16:49
I'm noticing some floating point representation precision issues that occurs on all versions and platforms:

>>> 277*0.1
27.700000000000003
>>> 1.2-1.0
0.19999999999999996
>>> import numpy as np
>>> np.double(277*0.1)
27.700000000000003
>>> np.double(1.2-1.0)
0.19999999999999996
>>> np.longdouble(277*0.1)
27.700000000000002842
>>> np.longdouble(1.2-1.0)
0.19999999999999995559

Verified with python 2.7 to 3.8. On x86 (i386 and amd64) and ARM (32 and 64 bits). It does not occur in C, LUA, Perl, ...
msg379592 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2020-10-25 17:28
This isn't a bug. It's due to the base 2 representation of floating point numbers. See for example: See https://docs.python.org/3/tutorial/floatingpoint.html

It's possible, depending on your use case, you might want to use the decimal module. But that has it's own issues that you should be aware of. For example, 1/7 is not exactly representable in either floats or Decimals.
msg379620 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2020-10-25 23:55
Eric I would normally agree with you but the only thing which gives me pause is the statement that this doesn't occur with C, Lua and Perl.

That alone doesn't mean much. Different interpreters can use different algorithms for printing floats, Python changed its algorithm in 3.1 and backported it to 2.7:

https://docs.python.org/3.1/whatsnew/3.1.html#other-language-changes

and now uses Gay's algorithm which will often give different, shorter, results than other algorithms. Other languages do other things, for example R is notorious for just terminating the float output after a few decimal places, so you have numbers which look identical but are unequal.

Andrea, do you still think this is a bug? Can you demonstrate some code in another language that shows the output you expect? (Preferably an interpreter rather than C.)

Most importantly, can you demonstrate that the other language's output is correct and Python's is wrong? In particular, are you sure that the output in those other languages is not just rounding the result to a certain number of decimal places?

If you can satisfy those, please re-open the ticket, otherwise I expect that Eric is correct.
msg379624 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2020-10-26 00:14
It looks like Python is correct and the other languages may be just truncating the output.


In the Lua interpreter:

> =277*0.1
27.7
> = 277*0.1 == 27.7
false


Perl:

$ perl -e "use feature qw(say); say 277*0.1"
27.7
$ perl -e "use feature qw(say); if (277*0.1 != 27.7) {say 'unequal'}"
unequal

In Ruby:

irb(main):001:0> 277*0.1
=> 27.7
irb(main):002:0> 277*0.1 == 27.7
=> false


Julia agrees with Python:

julia> 277*0.1
27.700000000000003

So does the Rhino javascript interpreter:

js> 277*0.1
27.700000000000003

I think Eric's instinct was correct.
msg379625 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2020-10-26 00:18
Thanks for double-checking the other languages, Steven.
History
Date User Action Args
2022-04-11 14:59:37adminsetgithub: 86314
2020-10-26 00:18:06eric.smithsetmessages: + msg379625
2020-10-26 00:14:06steven.dapranosetmessages: + msg379624
2020-10-25 23:55:13steven.dapranosetnosy: + steven.daprano
messages: + msg379620
2020-10-25 17:28:49eric.smithsetstatus: open -> closed

nosy: + eric.smith
messages: + msg379592

resolution: not a bug
stage: resolved
2020-10-25 16:49:56atucciacreate