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