New submission from AVicennA <[email protected]>:
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 <[email protected]>
<https://bugs.python.org/issue39059>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com