IEEE 754 中是否规定了涉及无穷大和 NaN 的浮点计算结果?

Are the results of floating point calculations involving infinity and NaN specified in IEEE 754?

例如使用 Visual Studio 2017 我得到以下结果

inf + inf 的计算结果为 inf

inf + (-inf) 计算为 -nan(ind)

涉及无穷大和 NaN 的浮点计算结果是在 IEEE 754 中指定的还是依赖于编译器?

当然,IEEE 754 指定了无穷大和 NaN 的行为。微软说 “Microsoft Visual C++ is consistent with the IEEE numeric standards.” 我加了重点;一致性不是一致性,所以微软在这个声明中似乎并没有承诺完全一致性。 Microsoft 对 C pow 例程的执行乏善可陈是 Stack Overflow 上出现许多重复问题的原因,我不相信他们的二进制-十进制或十进制-二进制转换(如 printfscanf 转换)符合 IEEE 754.

Visual Studio 编译的程序执行的大部分算术是由硬件提供的。 Intel 64 and IA-32 Architectures Software Developer's Manual 说它的浮点数据格式“直接对应”IEEE 754 格式,并没有说算法符合标准。本手册包含散布在其中的有关 IEEE 754 的附加声明,因此确定哪些特定行为符合 IEEE 754 以及以何种方式需要仔细阅读。这些架构中的英特尔处理器在很大程度上设计为在基本操作中符合 IEEE 754,但具有将次正规值替换为零的模式,出于性能原因,操作系统可能默认启用该模式。

在 IEEE 754 中,“浮点运算中无穷大的行为源自具有任意大操作数的实数运算的极限情况,当存在这样的极限时……对无限操作数的运算通常是精确的,因此不发出异常信号,... 只有当 [∞ 是无效操作数,∞ 是通过溢出或除以零从有限操作数创建的,或者余数(次正规,∞)信号下溢时,才会发出与无穷大有关的异常信号。]”

IEEE 754 规定有两种 NaN,信号和静默。信号 NaN 在一般操作中会导致异常,并且旨在用于标记未初始化的数据或实现自定义算术功能(通过处理异常并以自定义方式替换结果或以其他方式转移正常计算)。安静的 NaN 通常不会导致异常,并且应该保留存储在其中的有效负载数据(这样计算的结果可能会提供一些关于 NaN 起源位置的线索)。

尽管 Visual C++ 可能与 IEEE 754 “一致”,但也有一些注意事项。例如,给定类型 doubleabc,可以实现表达式 a*b + c

  • 使用 IEEE 754 乘法基本 64 位二进制格式,然后添加该格式。
  • 使用融合乘加指令,在乘法和加法之间没有舍入误差。
  • 具有扩展精度。

一般来说,我希望无穷大和 NaN 在已编译程序的基本基本操作中按照 IEEE 754 中的规定运行,但重要的是要意识到 Visual C++ 实现在遵守IEEE 754.