New submission from AVicennA <tural.jalilov...@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@python
components: Documentation, FreeBSD, IDLE, Interpreter Core, Library (Lib), 
Tests, Windows, macOS
messages: 358467
nosy: AVicennA, docs@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 <rep...@bugs.python.org>
<https://bugs.python.org/issue39059>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to