能否依赖Decimal.compare_total正确比较含inf、nan的十进制值?
结论:
not x.compare_total(y)替代x == y判断Decimal相等(含NaN)完全可靠 为什么x == y对NaN无效
Decimal遵循IEEE 754标准,按照规范,NaN与任何值(包括自身)的相等比较都会返回False,这是标准行为,不是bug。所以当x和y都是Decimal('nan')时,x == y会返回False,不符合“两个NaN视为相等”的预期。
compare_total的可靠性依据
Decimal.compare_total()是基于全序比较实现的,它会严格对比两个Decimal对象的所有内部表示细节(包括符号、有效数字、指数,以及NaN的标识):
- 当两个Decimal对象在全序规则下完全相等时,返回
0 - 否则返回正或负整数表示大小关系
因此not x.compare_total(y)等价于判断“两个Decimal对象在全序下完全相等”,自然包括了“NaN与自身相等”的场景,完美弥补了==的缺陷。
实验结果验证
运行你提供的代码,输出结果如下(关键部分标注):
from decimal import Decimal values = [ '0', '-1', '+1', '-inf', '+inf', 'nan' ] for x in values: for y in values: dx = Decimal(x) dy = Decimal(y) print(f"{x:>4} == {y:<4} | {x == y!r:<5} | {not dx.compare_total(dy)!r}")
核心输出片段:
nan == nan | False | True 0 == 0 | True | True -1 == -1 | True | True +inf == +inf | True | True
可以看到:
- 除了NaN与自身比较时
==返回False,not compare_total返回True外,所有其他数值、正负无穷的比较场景,两者结果完全一致。 - 对于NaN的场景,
not compare_total正好实现了“两个NaN视为相等”的预期。
额外说明
即使是不同方式创建的NaN(比如Decimal('nan')和Decimal('NaN'),或者通过运算生成的NaN),compare_total也会正确判断它们相等,因为全序比较会将所有NaN视为等价的(而==依然会返回False)。
内容的提问来源于stack exchange,提问作者user16004728
相关产品推荐
相关产品推荐

