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,则尝试使用&lt;&lt;=&gt;&gt;= 运算符比较两个小数,将引发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 被捕获,因此在使用&lt;=&gt;= 对抗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:十进制与浮点数的主要内容,如果未能解决你的问题,请参考以下文章

Js 运算符(加减乘除)

ES6随笔--各数据类型的扩展--数值

json模块使用

《JavaScript权威指南》读书笔记

三个特殊的浮点类型的数值

Python3 数值类型与运算符