为什么 GCC 为 0.0/0.0 产生 -nan 而 clang 和 intel 产生 +nan?

Why does GCC yield -nan and clang and intel yield +nan for 0.0/0.0?

当我调试代码时,我发现 GCC 和 Clang 都为 0.0/0.0 产生了 nan,这正是我所期望的,但是 GCC 产生了一个符号位设置为 1 的 nan,而 Clang 设置了它到 0(如果我没记错的话,与 ICC 一致)。

现在显然这两种形式都是允许的,但我一直想知道为什么 0.0/0.0 会使 GCC 输出 "negative" 结果(打印它给出 -nan),而 -(0.0/0.0)给出 "positive" 结果?更令人困惑的是 -0.0/0.0 又是 "negative"。这是一个持续的折叠怪异吗?

编辑

实际上,正是不断的折叠使它成为正 nan。如果我在运行时强制计算,我在 GCC 和 Clang 上都会得到负 nan

volatile float zero = 0.0;
std::cout << (zero/zero); // -nan

有人可以安排一下吗? x86 FPU 上的符号位是否设置为 1?

IEEE-754 没有指定 NaN 的符号:

When either an input or result is NaN, this standard does not interpret the sign of a NaN. Note, however, that operations on bit strings - copy, negate, abs, copySign — specify the sign bit of a NaN result, sometimes based upon the sign bit of a NaN operand. The logical predicate totalOrder is also affected by the sign bit of a NaN operand. For all other operations, this standard does not specify the sign bit of a NaN result, even when there is only one input NaN, or when the NaN is produced from an invalid operation.

现在让我们看看Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 1: Basic Architecture

其中,Intel 在这种情况下确实指定了一个特定的 NaN 值,称为 QNaN Floating-Point Indefinite(参见 Table 4-1),它在 #IA 时返回(无效算术异常)(参见 Table 8-10)。 查找 0 除以 0。

您会看到,对于该值,已设置符号位。