Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weird add operation of "0.2222 + 0.1111" #86086

Closed
ungedummt mannequin opened this issue Oct 3, 2020 · 8 comments
Closed

Weird add operation of "0.2222 + 0.1111" #86086

ungedummt mannequin opened this issue Oct 3, 2020 · 8 comments
Labels
3.8 only security fixes type-bug An unexpected behavior, bug, or error

Comments

@ungedummt
Copy link
Mannequin

ungedummt mannequin commented Oct 3, 2020

BPO 41920
Nosy @stevendaprano

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2020-10-03.12:04:34.221>
created_at = <Date 2020-10-03.11:39:41.517>
labels = ['invalid', 'type-bug', '3.8']
title = 'Weird add operation of "0.2222 + 0.1111"'
updated_at = <Date 2020-10-06.19:13:08.548>
user = 'https://bugs.python.org/ungedummt'

bugs.python.org fields:

activity = <Date 2020-10-06.19:13:08.548>
actor = 'ungedummt'
assignee = 'none'
closed = True
closed_date = <Date 2020-10-03.12:04:34.221>
closer = 'steven.daprano'
components = []
creation = <Date 2020-10-03.11:39:41.517>
creator = 'ungedummt'
dependencies = []
files = []
hgrepos = []
issue_num = 41920
keywords = []
message_count = 8.0
messages = ['377871', '377874', '377875', '377876', '377877', '377878', '377906', '378132']
nosy_count = 2.0
nosy_names = ['steven.daprano', 'ungedummt']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue41920'
versions = ['Python 3.8']

@ungedummt
Copy link
Mannequin Author

ungedummt mannequin commented Oct 3, 2020

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

@ungedummt ungedummt mannequin added 3.8 only security fixes type-bug An unexpected behavior, bug, or error labels Oct 3, 2020
@ungedummt
Copy link
Mannequin Author

ungedummt mannequin commented Oct 3, 2020

Same problem with 0.3333-0.1111 python returns 0.22219999999999998 and not 0.2222

@stevendaprano
Copy link
Member

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

@ungedummt
Copy link
Mannequin Author

ungedummt mannequin commented Oct 3, 2020

Ok thank you for these resources. I didn't know that before. (;

@ungedummt
Copy link
Mannequin Author

ungedummt mannequin commented Oct 3, 2020

But this "bug" only affects floating numbers?

@stevendaprano
Copy link
Member

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)

@ungedummt
Copy link
Mannequin Author

ungedummt mannequin commented Oct 6, 2020

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. (;

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.8 only security fixes type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

1 participant