为啥 IEEE 754 保留这么多 NaN 值?
Posted
技术标签:
【中文标题】为啥 IEEE 754 保留这么多 NaN 值?【英文标题】:Why does IEEE 754 reserve so many NaN values?为什么 IEEE 754 保留这么多 NaN 值? 【发布时间】:2013-11-17 00:02:04 【问题描述】:似乎 IEEE 754 标准将 16,777,214 个 32 位浮点值定义为 NaN,或所有可能值的 0.4%。
我想知道保留这么多有用值的理由是什么,而本质上只需要两个:一个用于发信号,一个用于安静的 NaN。
对不起,如果这个问题很琐碎,我在互联网上找不到任何解释。
【问题讨论】:
请注意,NaN 值表示的可能值的百分比随着格式大小的增加而下降,因为分配给指数的位数在较大的 IEEE 754 二进制格式中按比例减少。跨度> @Pacerier:问题是正确的; binary32 中有 2^24 - 2 个 NaN。 (缺少的两个是正无穷和负无穷。) 因此动态语言实现者可以使用该空间来存储所有其他非浮动对象。 【参考方案1】:IEEE-754 标准将 NaN 定义为指数中全为 1 且有效数非零的数字。有效数字中的最高位指定 NaN 是信令还是静默。有效数字的剩余位构成了 NaN 的 有效载荷。
只要操作的一个操作数是 NaN,结果就是一个 NaN,并且结果的有效负载等于其中一个 NaN 操作数的有效负载。有效载荷保留对efficiency in scientific computing 很重要,at least one company 已提议将 NaN 有效载荷用于专有用途。
在更基本的术语中,NaN 不携带任何有用的数字信息,并且无论如何都必须保留整个 32 位,因此如果标准中没有定义有效负载,则有效数字中未使用的位将被浪费.
【讨论】:
1) 据我了解,建议提供用于利用 NaN 负载的工具,这似乎是试图减少价值浪费造成的危害,但在 IEEE -754 标准已制定。 该标准有意模糊,将这些位仅描述为有效负载。最后一段只是说明,如果您不使用这些位,它们就会被闲置。这些位必须在那里;还不如把它们用于某事。 “IEEE-754 标准将 NaN 定义为指数中全为 1 的数字,并且有效数为非零……无论如何都必须保留整个 32 位”在“它之所以如此,是因为它是如此”,颜色(但话说回来,这是一个“为什么……?”问题)。与其将MAX_FLOAT
定义为0x1.fffffep127
,不如将其定义为0x1.fffff0p128
,最后一对位模式仅用于inf
和NaN
,而不是牺牲整个指数值他们。
关于为什么没有选择这种其他表示的推测可能包括硬件实现的简单性,以及关于浮点行为的严格数学证明已经需要足够的特殊情况,即使可表示的正常值可用在整个binades。有效载荷的事情看起来像是事后才想到的,特别是因为当对两个 NaN 应用二进制运算时,标准甚至没有指定两个有效载荷中的哪一个最终出现在结果中(对称选择是指定按位或例如两个有效载荷)。
应该注意的一点是,“保留 NaN 有效载荷”是标准的“应该”而不是“应”规定。第 6.2 节部分内容如下:“为了促进 NaN 中包含的诊断信息的传播,应在 NaN 操作结果中保留尽可能多的信息”。【参考方案2】:
根据 IEEE-754 格式的设计者之一 this series of notes by William Kahan,使用多个 NaN 旨在让硬件首先填写有关触发 NaN 的信息,以便最终产生的计算结果在 NaN 中可以运行完成,然后让程序员编写代码来分析出了什么问题:
IEEE 754 的 NaN 规范赋予它一个位字段,软件可以在其中记录 NaN 是如何和/或在何处出现的。该信息对于随后对故障计算的“回顾性诊断”非常有帮助,但现在还没有软件可以使用它。通常,该字段已从操作数 NaN 复制到每个算术运算的结果 NaN,或者在未捕获的 INVALID 操作创建新的 NaN 时填充二进制 1000...000。由于缺乏可以利用它的软件,这种习惯一直在萎缩。
所以这似乎是故意的并且未指定,以便不同的系统可以以不同的方式处理事情。回想起来,这似乎从未真正结束过,但这似乎是一个合理的想法!
【讨论】:
在大型机时代特别合理,您将作业提交为一堆打孔卡,然后去拿结果的打印输出。对于大多数用例而言,交互式调试会大大降低这一点。【参考方案3】:同样还有一个 64 位浮点数的有效载荷,有大约 10^15 个可能的值。不幸的是,对于负载应该如何在 32 位和 64 位浮点数之间传输并再次传输回来,实现存在分歧,即您是否保留最高有效位或最低有效位。由于负载处理是特定于机器的,因此您需要不同的代码来处理不同机器上的负载。
我不会太担心在二进制操作之后传播哪个 NaN 有效负载。 NaN 是出现概率低的异常值,得到其中 2 个的概率不大。
【讨论】:
计算机是确定性的,而不是概率性的。因此,如果 NaN 意味着要发生,它就会发生。 @Rainb 存在不确定性计算机。看看具有多线程或 GPU 的普通 CPU。以上是关于为啥 IEEE 754 保留这么多 NaN 值?的主要内容,如果未能解决你的问题,请参考以下文章