Python3 Infinity/NaN:十进制与浮点数
Posted
技术标签:
【中文标题】Python3 Infinity/NaN:十进制与浮点数【英文标题】:Python3 Infinity/NaN: Decimal vs. float 【发布时间】:2015-04-06 22:11:58 【问题描述】:给定(Python3):
>>> float('inf') == Decimal('inf')
True
>>> float('-inf') <= float('nan') <= float('inf')
False
>>> float('-inf') <= Decimal(1) <= float('inf')
True
为什么以下无效?我已阅读Special values。
无效
>>> Decimal('-inf') <= Decimal('nan') <= Decimal('inf')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
>>> Decimal('-inf') <= float('nan') <= Decimal('inf')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
>>> float('-inf') <= Decimal('nan') <= float('inf')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
【问题讨论】:
你读过例如docs.python.org/3/library/decimal.html#special-values 是的;但不是参考的 IEEE 854 标准(参见第 5.7 节中的表 3)。 【参考方案1】:来自decimal.py
source code:
# Note: The Decimal standard doesn't cover rich comparisons for
# Decimals. In particular, the specification is silent on the
# subject of what should happen for a comparison involving a NaN.
# We take the following approach:
#
# == comparisons involving a quiet NaN always return False
# != comparisons involving a quiet NaN always return True
# == or != comparisons involving a signaling NaN signal
# InvalidOperation, and return False or True as above if the
# InvalidOperation is not trapped.
# <, >, <= and >= comparisons involving a (quiet or signaling)
# NaN signal InvalidOperation, and return False if the
# InvalidOperation is not trapped.
#
# This behavior is designed to conform as closely as possible to
# that specified by IEEE 754.
从Special values section 你说你读到了:
如果任一操作数为
NaN
,则尝试使用<
、<=
、>
或>=
运算符比较两个小数,将引发InvalidOperation
信号,并返回False
如果这个信号没有被捕获。
注意 IEEE 754 使用 NaN 作为浮点 异常值;例如你做了一些无法计算的事情,你得到了一个异常。它是一个信号值,应该被视为一个错误,而不是用来比较其他浮点数的东西,这就是为什么在 IEEE 754 标准中它不等于其他任何东西。
此外,特殊值部分提到:
请注意,通用十进制算术规范没有指定直接比较的行为;这些涉及
NaN
的比较规则取自 IEEE 854 标准(参见第 5.7 节中的表 3)。
和looking at IEEE 854 section 5.7 我们发现:
除了真/假响应外,还应发出无效操作异常(见 7.1)信号 如表 3 的最后一列所示,当使用其中一个谓词比较“无序”操作数时 涉及“”但不涉及“?.” (这里的符号“?”表示“无序”。)
与分类为无序的 NaN 进行比较。
默认情况下InvalidOperation
被捕获,因此在使用<=
和>=
对抗Decimal('NaN')
时会引发Python 异常。这是一个逻辑扩展; Python 有 实际 异常,因此如果您与 NaN 异常值进行比较,您可以预期会引发异常。
您可以使用Decimal.localcontext()
禁用陷印:
>>> from decimal import localcontext, Decimal, InvalidOperation
>>> with localcontext() as ctx:
... ctx.traps[InvalidOperation] = 0
... Decimal('-inf') <= Decimal('nan') <= Decimal('inf')
...
False
【讨论】:
在这种情况下如何“解开”InvalidOperation
?
@ddenhartog:例如使用本地上下文。
谢谢 :) 我没有理由不能在任何一边都使用 float('nan') ;我只是出于学习目的而好奇!以上是关于Python3 Infinity/NaN:十进制与浮点数的主要内容,如果未能解决你的问题,请参考以下文章