Python Decimal与零相乘为何返回0E-28而非普通零?
为什么Decimal(0)相乘会返回0E-28而不是普通的0?
先看这段代码的执行结果:
from decimal import Decimal result = Decimal('0') * Decimal('0.8881783462119193534061639577') print(result) # 输出:0E-28
追踪Python标准库_pydecimal.py的源码,发现零值相乘的处理逻辑如下:
if not self or not other: ans = _dec_from_triple(resultsign, '0', resultexp) # Fixing in case the exponent is out of bounds ans = ans._fix(context) return ans
原因解析
Decimal类型的内部采用符号、系数、指数的三元组结构存储数值:
Decimal('0')的三元组是:符号0(正)、系数'0'、指数0Decimal('0.8881783462119193534061639577')的三元组是:符号0、系数'8881783462119193534061639577'、指数-28(因为该数等价于8881783462119193534061639577 × 10^-28)
根据库的运算规则,当其中一个操作数是0时:
- 结果符号为两个操作数符号的异或(这里都是正,所以符号为正)
- 结果系数固定为
'0' - 结果指数为两个操作数的指数之和:
0 + (-28) = -28
由此构造出的Decimal实例就是0E-28,而非直觉中的0。
补充说明
数学上0和0E-28是等价的,但Decimal库设计时会保留运算过程带来的指数属性,不会自动归一化到最简形式。如果需要得到普通的0,可以调用normalize()方法:
print(result.normalize()) # 输出:0
内容的提问来源于stack exchange,提问作者tonysepia
相关产品推荐
相关产品推荐

