为什么 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。
您会看到,对于该值,已设置符号位。
当我调试代码时,我发现 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。
您会看到,对于该值,已设置符号位。