我刚刚发现,当使用任何优化选项进行编译时,当将 float 无穷大除以自身时,会在 clang 上产生不同的 NaN。
std::numeric_limits<float>::infinity()/std::numeric_limits<float>::infinity()
产生以下位组:
01111111110000000000000000000000
使用 -O1 编译时,以及11111111110000000000000000000000
不使用它进行编译时。区别仅在于符号位。
我认为如何表示 NaN 的决定取决于编译器,但令我惊讶的是我们会在同一编译器中看到不同的表示形式。无论优化如何,GCC 和 MSVC 似乎都是一致的 (
11111111110000000000000000000000
)。
我的问题是:
扫描 C++ 标准(2020 年草案 N4849)没有显示任何指定 NaN 结果的符号应该是什么的内容。
C++ 不要求实现符合 IEEE-754。尽管如此,假设实现确实如此,那么 IEEE-754 2019 6.3“符号位”说:
…对于所有其他操作,本标准没有指定符号 NaN 结果的一位,即使只有一个输入 NaN,或者 NaN 是由无效值产生的 操作…
“所有其他操作”包括除法,因为之前讨论的操作是
copy
、negate
、abs
、copySign
、totalOrder
和 isSignMinus
。