[New-bugs-announce] [issue39059] Getting incorrect results in rounding procedures

AVicennA report at bugs.python.org
Mon Dec 16 03:50:51 EST 2019


New submission from AVicennA <tural.jalilov.92 at gmail.com>:

This is about rounding process and getting incorrect results. In documentation written
that, "This is not a bug: it’s a result of the fact that most decimal fractions can’t be 
represented exactly as a float". - https://docs.python.org/3/library/functions.html?highlight=round#round
It is also related with hardware. I wrote some code parts that shows it and used decimal value
as in documentation sample:

''' 2.675(4) - (4) or (3) or (2) etc. I have given range 2, and the result is influenced not 
    just by one number after those 2 ranges, but also the another number consistently. '''

>>> round(2.675, 2)
2.67
>>>
>>> round(5.765, 2)
5.76
>>>
>>> round(2.6754, 2)
2.68
>>>
>>> round(5.7652, 2)
5.77

''' "format" is also not working properly. Gives incorrect results. '''

>>> format(2.675, ".2f")  
'2.67'
>>>
>>> format(2.678, ".2f")
'2.68'
>>>
>>> '{:0.2f}'.format(2.675)
'2.67'
>>>
>>> '{:0.2f}'.format(2.678)
'2.68'

''' Because, when the decimal string is converted to a binary floating-point number, it's 
    again replaced with a binary approximation:

    Whose exact value is 5.765 --> 5.76499999999999968025576890795491635799407958984375
                                                 &&
                         2.675 --> 2.67499999999999982236431605997495353221893310546875

    It means that, the 76(5) --> 5 replaced in a memory as 4.(999999999999)
                                                 &&
                       67(5) --> 5 replaced in a memory as 4.(999999999999) '''

>>> from decimal import Decimal
>>> Decimal(2.675)
Decimal('2.67499999999999982236431605997495353221893310546875')
>>>
>>> Decimal(5.765)
Decimal('5.76499999999999968025576890795491635799407958984375')

''' Used float point precision(FPU) with math lib to apply a certain correct form. 
    I propose to use some tricks. But again incorrect result in third sample: '''

>>> import math
>>> math.ceil(2.675 * 100) / 100
2.68
>>>
>>> print("%.2f" % (math.ceil(2.675 * 100) / 100))
2.68
>>> math.ceil(2.673 * 100) / 100
2.68

''' The most correct form is using by round: '''

>>> round(2.675 * 100) / 100
2.68
>>>
>>> round(2.673 * 100) / 100
2.67
>>> round(2.674 * 100) / 100
2.67
>>> round(2.676 * 100) / 100
2.68

''' In this case, whatever the range the full right result is a return.
    Mostly can be using in fraction side correctness. '''

>>> def my_round(val, n):
...     return round(val * 10 ** n) / 10 ** n
...
>>> my_round(2.675, 2)
2.68
>>>
>>> my_round(2.676, 2)
2.68
>>>
>>> my_round(2.674, 2)
2.67
>>>
>>> my_round(2.673, 2)
2.67
>>>
>>> my_round(2.674, 3)
2.674
>>>
>>> my_round(55.37678, 3)
55.377
>>>
>>> my_round(55.37678, 2)
55.38
>>>
>>> my_round(55.37478, 2)
55.37
>>>
>>> my_round(224.562563, 2)
224.56
>>>
>>> my_round(224.562563, 3)
224.563
>>>
>>> my_round(224.562563, 4)
224.5626
>>>
>>> my_round(224.562563, 5)
224.56256
>>>
>>> my_round(224.562563, 7)
224.562563
>>>
>>> my_round(224.562563, 11)
224.562563

''' my_round - function tested on Windows and Linux platforms(x64). This can be added in Python
    next releases to solve this problem which related with the IEEE 754 and PEP 754 problems. '''

----------
assignee: docs at python
components: Documentation, FreeBSD, IDLE, Interpreter Core, Library (Lib), Tests, Windows, macOS
messages: 358467
nosy: AVicennA, docs at python, koobs, ned.deily, paul.moore, ronaldoussoren, steve.dower, terry.reedy, tim.golden, zach.ware
priority: normal
severity: normal
status: open
title: Getting incorrect results in rounding procedures
type: behavior
versions: Python 3.6, Python 3.7, Python 3.8, Python 3.9

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue39059>
_______________________________________


More information about the New-bugs-announce mailing list