我有大量的 python 代码试图处理具有 4 位小数精度的数字,并且由于多种原因我被 python 2.4 卡住了。该代码进行了非常简单的数学运算(它是一个信用管理代码,主要用于获取或添加信用)
它混合使用 float 和 Decimal(MySQLdb 为 SQL DECIMAL 类型返回 Decimal 对象)。在使用过程中出现了几个奇怪的错误之后,我发现根本原因是代码中的一些地方正在比较浮点数和小数。
我遇到过这样的情况:
>>> from decimal import Decimal
>>> max(Decimal('0.06'), 0.6)
Decimal("0.06")
现在我担心的是我可能无法在代码中捕获所有此类情况。(一个普通的程序员会继续做 x > 0 而不是 x > Decimal('0.0000') 并且很难避免)
我想出了一个补丁(灵感来自对 python 2.7 中十进制包的改进)。
import decimal
def _convert_other(other):
"""Convert other to Decimal.
Verifies that it's ok to use in an implicit construction.
"""
if isinstance(other, Decimal):
return other
if isinstance(other, (int, long)):
return Decimal(other)
# Our small patch begins
if isinstance(other, float):
return Decimal(str(other))
# Our small patch ends
return NotImplemented
decimal._convert_other = _convert_other
我只是在一个非常早的加载库中执行此操作,它将通过允许在比较之前将浮点数转换为十进制来改变十进制包的行为(以避免遇到 python 的默认对象到对象比较)。
我专门使用“str”而不是“repr”,因为它修复了一些 float 的舍入情况。例如
>>> Decimal(str(0.6))
Decimal("0.6")
>>> Decimal(repr(0.6))
Decimal("0.59999999999999998")
现在我的问题是:我在这里遗漏了什么吗?这相当安全吗?还是我在这里打破了什么?(我认为该软件包的作者有非常充分的理由来避免如此多的浮动)