繁体   English   中英

浮点格式的Python精度问题

[英]Python precision issues with float formatting

请查看下面我输入到Python 3.6解释器中的Python代码:

>>> 0.00225 * 100.0
0.22499999999999998
>>> '{:.2f}'.format(0.00225 * 100.0)
'0.22'
>>> '{:.2f}'.format(0.225)
'0.23'
>>>  '{:.2f}'.format(round(0.00225 * 100.0, 10))
'0.23'

希望你能立即理解为什么我感到沮丧。 我试图在我的GUI上显示value * 100.0 ,将全精度存储在一个单元格后面,但仅显示2个小数点(或任何用户精度设置)。 GUI与Excel电子表格相似。

我不希望丢失诸如0.22222444937645之类的精度并舍入为10 ,但是我也不希望诸如0.00225 * 100.0类的值显示为0.22

我对了解解决这种情况的标准方法或针对我的具体情况的补救方法感兴趣。 提前感谢您的任何帮助。

考虑使用Decimal模块 ,该模块 “提供对快速正确舍入的十进制浮点算术的支持”。 与您的用例相关的Decimal的主要优点是:

  • 小数可以精确表示。 相反,像1.12.2这样的数字在二进制浮点数中没有确切的表示形式。 最终用户通常不会期望1.1 + 2.2像二进制浮点那样显示为3.3000000000000003

  • 精确度会延续到算术运算中。 在十进制浮点数中, 0.1 + 0.1 + 0.1 - 0.3完全等于零。 在二进制浮点中,结果是
    5.5511151231257827e-017 当接近零时,差异会阻止可靠的相等性测试,并且差异会累积。 因此,在具有严格相等不变性的会计应用程序中,首选十进制。

根据您在问题中提供的信息,我不能说迁移到Decimal所需的大修量。 但是,如果您要创建类似电子表格的应用程序,并且始终希望保持最大的精度,那么您可能希望早晚重构为使用Decimal以避免面向用户的GUI中出现意外的数字。

要获得所需的行为,您可能需要更改Decimal实例的舍入模式(默认为ROUND_HALF_EVEN )。

from decimal import getcontext, ROUND_HALF_UP

getcontext().rounding = ROUND_HALF_UP

n = round(Decimal('0.00225') * Decimal('100'), 2)
print(n)  # prints Decimal('0.23')

m = round(Decimal('0.00225') * 100, 2)
print(m)  # prints Decimal('0.23')

也许用十进制? docs.python.org/2/library/decimal.html

from decimal import *
getcontext().prec = 2
n = Decimal.from_float(0.00225)
m = n * 100
print(n, m)
print(m.quantize(Decimal('.01'), rounding=ROUND_DOWN))
print(m.quantize(Decimal('.01'), rounding=ROUND_UP)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM