不是数字 (NaN)

Not a Number (NaN)

为什么有些数字在浮点运算中被定义为非数字(NaN)? (虽然可以用IEEE格式表示,确实是实数)

问题的作者也发表了这条评论:

I don't understand how numbers for which "all exponent bits are 1's and mantissa is not all zeros" is not a real number.

这条评论背后的原因似乎是:二进制浮点格式有一个符号位 s,一些指数位 e和一些有效位 f。对于e的大部分值,表示的值为(−1)s•1.f•2e-bias(其中“1.f”是由“1.”连接而成的二进制数,位 fbias 是指数的编码偏差)。使用此方案,所有的指数值将是一个数字,那么它是 NaN 吗?

答案是 IEEE-754 标准指定了浮点编码的位代表什么,它指出:

  • 如果e为零,表示的值为(−1)s• 0.f•2emin,其中emin 是格式的最小指数。 (emin 等于 1-bias。)
  • e不全为0或全1,则表示的值为(−1)s•1.f•2e-bias.
  • 如果e全为1,f为0,则表示的值为(−1)s•∞.
  • 如果e全为1且f不为零,则表示的值为NaN。 (有一些关于发信号 NaN 与安静 NaN 的实现相关的细节,以及使用 f 的位来传达附加信息。)

在(但不包括)全 0 和全 1 之间存在代表 e 值的值模式的事实并不意味着模式必须扩展到 e 是全零或全一。逻辑或物理学并没有迫使我们设计将模式扩展到 e 的所有值的硬件。规则如上所述制定,IEEE-754 浮点数的实现遵循这些规则。

此外,上述值构成了一组 IEEE-754 称为 浮点数据 的集合。该集合包括 −∞ 和 +∞,由 se 的值产生的各种非零实数f,两个用符号区分的“零”:-0 和 +0,以及 NaN。许多 IEEE-754 算术运算规范随后使用这些值。例如,加法被定义为产生一个结果,就好像计算了精确的数学总和,然后对其应用了舍入规则。每个舍入规则指定,如果值超出特定范围,则结果为无穷大。否则,精确的数学和将在舍入规则指定的方向上舍入到最接近的可表示值(例如在任一方向上最接近,朝向 +∞、朝向 −∞ 或朝向零)。

因此,在实施 IEEE-754 时,无论是在硬件还是软件中,实施都旨在遵循这些规则。当规则说要产生无穷大时,实现会产生代表无穷大的位模式。当输入操作数具有无穷大的位模式时,实现将其视为无穷大,而不是如果指数编码具有扩展正常数字模式的意义,则将其视为它所表示的实数。

Inf 和 NaN 的特殊情况不被视为数字,因为根据定义它们是 Inf 和 NaN。该定义在 IEEE 754-2008(不是免费标准)的第 6.2.1 节中。

NaN 的生成和传播是在硬件中处理的(至少在 Intel 硬件上,参见 "Intel® 64 and IA-32 Architectures Software Developer’s Manual" 作为示例,特别是 E4.2.2,其中详细介绍了它)。