为什么有些数字在浮点运算中被定义为不是数字(NaN)?(虽然它们可以用 IEEE 格式表示并且确实是实数)
2 回答
问题的作者也发表了这条评论:
我不明白“所有指数位都是 1,尾数不是全零”的数字不是实数。
此评论背后的原因似乎是:二进制浮点格式具有符号位s、一些指数位e和一些有效位f。对于大多数e值,表示的值是 (-1) s •1。f •2 e -偏差(其中“1. f ”是由连接“1.”形成的二进制数字,位f和偏差是指数的编码偏差)。使用这种方案,所有 1 的指数值将是一个数字,那么它如何是 NaN?
答案是 IEEE-754 标准指定了浮点编码的位代表什么,它指出:
- 如果e为零,则表示的值为 (-1) s •0。f •2 e min,其中e min是格式的最小指数。(e min等于 1-偏差。)
- 如果e不是全零或全一,则表示的值为 (-1) s •1。f • 2 e-偏差。
- 如果e为全 1 且f为零,则表示的值为 (-1) s •∞。
- 如果e为全 1 且f不为零,则表示的值为 NaN。(关于信号 NaN 与安静 NaN 以及使用f的位来传达附加信息,有一些与实现相关的细节。)
在(但不包括)全零和全一之间存在一个表示e值的值模式的事实并不意味着该模式必须扩展到当e全为零或全一时。没有任何关于逻辑或物理的东西迫使我们设计将模式扩展到所有e值的硬件。规则是如上所述制定的,IEEE-754 浮点的实现遵循这些规则。
此外,上述值形成了 IEEE-754 称为浮点数据的集合。该集合包括 −∞ 和 +∞,由s、e和f的值产生的各种非零实数,两个以符号区分的“零”:-0 和 +0,以及 NaN。许多 IEEE-754 算术运算规范然后使用这些值。例如,加法被定义为产生一个结果,就好像计算了精确的数学总和,然后对其应用了舍入规则。每个舍入规则都指定,如果值超出特定范围,则结果为无穷大。否则,精确的数学总和将在舍入规则指定的方向上四舍五入到最接近的可表示值(例如在任一方向上最接近、朝向 +∞、朝向 -∞ 或朝向零)。
因此,当 IEEE-754 以硬件或软件形式实施时,实施旨在遵循这些规则。当规则说要产生无穷大时,实现产生代表无穷大的位模式。当输入操作数具有无穷大的位模式时,实现将其视为无穷大,而不是如果指数编码具有扩展正常数字模式的含义,它将表示的实数。
Inf 和 NaN 的特殊情况不被视为数字,因为根据定义它们是 Inf 和 NaN。该定义在 IEEE 754-2008(不是免费标准)的第 6.2.1 节中。
NaN 的生成和传播是在硬件中处理的(至少在英特尔硬件上,请参阅“英特尔® 64 和 IA-32 架构软件开发人员手册”作为示例,特别是详细介绍它的 E4.2.2)。