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: should we expect round(0.95,1) to be 1.0, instead of 0.9?
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.7, Python 3.6, Python 3.5, Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: mark.dickinson, serhiy.storchaka, steven.daprano, yudongliu
Priority: normal Keywords:

Created on 2019-11-05 19:53 by yudongliu, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (5)
msg356054 - (view) Author: Yudong Liu (yudongliu) Date: 2019-11-05 19:53
Python 3.7.0 (default, Aug 22 2018, 20:50:05) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> round(0.95,1)
0.9
>>> round(0.95)
1
>>> round(0.96,1)
1.0
msg356056 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-11-05 20:08
0.95 is actually 278419646001971/4503599627370496 which is smaller than 95/100.

>>> from fractions import Fraction
>>> Fraction(0.95)
Fraction(4278419646001971, 4503599627370496)
>>> Fraction(0.95) - Fraction(95, 100)
Fraction(-1, 22517998136852480)

It is closer to 0.9 than to 1.0.

>>> Fraction(0.95) - Fraction(0.9)
Fraction(450359962737049, 9007199254740992)
>>> Fraction(1) - Fraction(0.95)
Fraction(225179981368525, 4503599627370496)
>>> (Fraction(1) - Fraction(0.95)) - (Fraction(0.95) - Fraction(0.9))
Fraction(1, 9007199254740992)
msg356063 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2019-11-05 21:07
What Serhiy said. round is behaving as intended and as designed here.

Note: you can also see the actual value of a float object easily by using Decimal:

    >>> from decimal import Decimal
    >>> Decimal(0.95)
    Decimal('0.9499999999999999555910790149937383830547332763671875')

... which demonstrates clearly that the value being rounded is closer to 0.9 than to 1.0.
msg356080 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2019-11-06 00:15
Possibly even easier than using Decimal:

py> '%.17f' % 0.95
'0.94999999999999996'

BTW, this is a FAQ:

https://docs.python.org/3/faq/design.html#why-are-floating-point-calculations-so-inaccurate
msg356127 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2019-11-06 13:08
[Steven]

py> '%.17f' % 0.95
'0.94999999999999996'

That's tricky to use correctly: it's not a priori clear how many digits after the point are needed to give you a faithful representation (the "17" in "%.17f" isn't going to be the right thing for most values). You really want to specify the number of significant digits rather than the number of places after the point, and even then there are going to be cases where 17 significant digits aren't enough to show you which side of a tie the exact value lies.
History
Date User Action Args
2022-04-11 14:59:22adminsetgithub: 82884
2019-11-06 13:08:52mark.dickinsonsetmessages: + msg356127
2019-11-06 00:15:16steven.dapranosetnosy: + steven.daprano
messages: + msg356080
2019-11-05 21:07:57mark.dickinsonsetstatus: open -> closed

nosy: + mark.dickinson
messages: + msg356063

resolution: not a bug
stage: resolved
2019-11-05 20:08:27serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg356056
2019-11-05 19:53:04yudongliucreate