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: Weird add operation of "0.2222 + 0.1111"
Type: behavior Stage: resolved
Components: Versions: Python 3.8
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: steven.daprano, ungedummt
Priority: normal Keywords:

Created on 2020-10-03 11:39 by ungedummt, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (8)
msg377871 - (view) Author: Leonard Schwennesen (ungedummt) Date: 2020-10-03 11:39
If I add 0.2222 + 0.1111 in the python cli I get the value 0.33330000000000004 and not 0.3333. Also the other way around.
But if I enter for example 0.22222+0.11111 I get 0.33333 so that's right.
Here are a few examples I tested that working properly:

>>> 0.22+0.11
0.33
>>> 0.222+0.111
0.333
>>> 0.22222+0.11111
0.33333
>>> 0.3333+0.7777
1.111
>>> 0.3333+0.6666
0.9999
>>> 0.3333+0.3333
0.6666
>>> 0.6666+0.1111
0.7777
>>> 0.2222+0.3333
0.5555

Python 3.8.5
[GCC 10.2.0] on linux

I also tested that in a newly setup VM, same issue
msg377874 - (view) Author: Leonard Schwennesen (ungedummt) Date: 2020-10-03 11:50
Same problem with 0.3333-0.1111 python returns 0.22219999999999998 and not 0.2222
msg377875 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2020-10-03 12:04
Please forgive me if my answer is a little bit brusque, but we get essentially this same bug report regularly, only the numbers are different.

This is not a bug in Python, it is an unavoidable consequence of how floating point arithmetic works in every single programming language that does floating point arithmetic.

There's a FAQ about it:

https://docs.python.org/3/faq/design.html#why-am-i-getting-strange-results-with-simple-arithmetic-operations

it's discussed in the tutorial:

https://docs.python.org/3/tutorial/floatingpoint.html#tut-fp-issues

there's probably a million websites, blog posts, Stackoverflow questions etc about it, and computer scientists write papers about it:

https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
msg377876 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2020-10-03 12:15
Some further resources:

https://stackoverflow.com/questions/8215437/floating-point-accuracy-in-python

https://stackoverflow.com/questions/21895756/why-are-floating-point-numbers-inaccurate

https://stackoverflow.com/questions/1089018/why-cant-decimal-numbers-be-represented-exactly-in-binary?noredirect=1&lq=1

https://randomascii.wordpress.com/category/floating-point/page/1/


If you google a bit you will find many other places that discuss this.
msg377877 - (view) Author: Leonard Schwennesen (ungedummt) Date: 2020-10-03 12:23
Ok thank you for these resources. I didn't know that before. (;
msg377878 - (view) Author: Leonard Schwennesen (ungedummt) Date: 2020-10-03 12:27
But this "bug" only affects floating numbers?
msg377906 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2020-10-03 23:24
Hi Leonard,

Any number which has only fixed precision will experience similar 
issues. It might affect different calculations.

In Python, float, complex and Decimal have fixed precision, so they can 
experience this issue.

But for simple calculations, Decimal may be better for you, as it uses 
base-10 floats, not base-2, so many numbers which are rounded off in 
binary floats are not rounded in Decimal:

    py> from decimal import Decimal
    py> 0.1111 + 0.2222  # binary floats
    0.33330000000000004
    py> Decimal('0.1111') + Decimal('0.2222')  # decimal floats
    Decimal('0.3333')

But with Decimal, you have other numbers which are rounded off and so 
are not exact:

    py> one_third = 1/Decimal(3)
    py> 3*one_third  # should be exactly 1
    Decimal('0.9999999999999999999999999999')

    py> (1/Decimal(6)) * 3
    Decimal('0.5000000000000000000000000001')

ints are always exact, but you can only do whole numbers with ints. 
Fractions are also exact:

    py> from fractions import Fraction
    py> Fraction(1111, 10000) + Fraction(2222, 10000)
    Fraction(3333, 10000)

Using Fraction is a good way to see what number a binary float really 
is:

    py> Fraction(0.1111)
    Fraction(4002799348806897, 36028797018963968)
msg378132 - (view) Author: Leonard Schwennesen (ungedummt) Date: 2020-10-06 19:13
Hi Steven,
Thanks for your detailed explanations. They where very helpful for me. Now I know a bit more about Python and Computers in general. (;
History
Date User Action Args
2022-04-11 14:59:36adminsetgithub: 86086
2020-10-06 19:13:08ungedummtsetmessages: + msg378132
2020-10-03 23:24:10steven.dapranosetmessages: + msg377906
2020-10-03 12:27:17ungedummtsetmessages: + msg377878
2020-10-03 12:23:07ungedummtsetmessages: + msg377877
2020-10-03 12:15:03steven.dapranosetmessages: + msg377876
2020-10-03 12:04:34steven.dapranosetstatus: open -> closed

nosy: + steven.daprano
messages: + msg377875

resolution: not a bug
stage: resolved
2020-10-03 11:50:13ungedummtsetmessages: + msg377874
2020-10-03 11:39:41ungedummtcreate