Inf和NaN是如何实现的?

12

作为数学概念,我很清楚infnan的含义。但我真正感兴趣的是它们在编程语言中的实现。

在Python中,我可以在算术和条件表达式中使用infnan,像这样:

>>> nan = float('nan')
>>> inf = float('inf')
>>> 1 + inf
inf
>>> inf + inf
inf
>>> inf - inf
nan

这让我相信Python内部有一个特殊的保留位序列,用于表示这两个数学量,没有其他数字可以占据这些位置。我的假设正确吗?请在这方面给我一些启示。

如果我的假设是正确的,那么这可以很容易地解释:

>>> inf == inf
True

然而,这不是:

>>> nan == nan
False

显然,在数学上,这是正确的答案。但Python如何知道它应该在这种情况下输出False

此外,Python的实现与Java或C ++有何不同?


1
由于浮点机器指令比较时将nan与任何值(包括自身)进行比较都会返回false。 - camelccc
10
这与 IEEE 754 标准有关。 - E net4
1
几乎所有编程语言都使用IEEE 754来处理浮点数值,该标准精确地定义了这些特殊值是什么,它们如何表示以及在各种操作中的行为。 - Matteo Italia
现代CPU已经支持这个功能,不需要进行“实现”。 - klutt
2
请阅读关于函数式编程数学的经典论文:http://www.lsi.upc.edu/~robert/teaching/master/material/p5-goldberg.pdf - Severin Pappadeux
太棒了。我从来不知道CPU本身支持无穷大和NaN。我一直以为它们是应用程序级别的概念。 - cs95
2个回答

10

通常,浮点数算法是通过硬件直接实现的。确实存在特殊的位模式用于表示无穷大和NaN,这些位模式可被硬件浮点单元识别。

IEEE 64位浮点数是在典型系统上使用的类型,例如CPython, 其中有1位用于符号、11位用于指数、52位用于尾数。参见https://en.wikipedia.org/wiki/Double-precision_floating-point_format

若指数包含0b11111111111(全为1),则该数字是inf或nan,具体取决于存储在尾数中的内容。Python不需要进行任何特殊处理来处理这些情况。您将获得与Python、C、Java或汇编语言中比较数字相同的结果。


我认为提及硬件指令用于比较浮点数的设计是有用的,因为如果两个操作数中的任何一个是NaN,即使它们具有相同的位模式,该指令也会表明它们不相等。作者的问题表明他们可能认为相同的位模式必然表示相等,或者至少他们不理解如何说相同的位模式不相等。 - Eric Postpischil
谢谢回答。我明白了。 - cs95
@EricPostpischil:这听起来并不有用,只会重复您评论中的信息。下次,如果您有对问题提出者有用的信息,请建议编辑或发布针对问题提出者的评论。 - Dietrich Epp

5
那些并不是Python特有的行为,而是浮点标准Python使用的(可能是所有常见语言?)。
nan和inf是IEEE_754浮点标准的特殊值。它们当然有内部表示(你提到的位序列),但它们的行为并不寻常。这种行为与其他浮点值不同,但在IEEE_754中已经定义得很清楚了。实现是在指令级别处理的。(处理器在其浮点单元电路中处理此过程)
其中一个明确且不平凡的行为是NaN!=一切,包括自己。
知道这一点,您可以编写类似以下内容的东西:
def isNaN(f): return f != f

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接