为什么GCC生成-nan, clang生成+nan,而intel生成+nan ?

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

本文关键字:生成 +nan intel GCC 为什么 clang -nan      更新时间:2023-10-16

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

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

编辑

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

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

谁能安排一下这件事?x86 FPU的符号位是否设置为1 ?

IEEE-754未指定NaN符号:

当输入或结果为NaN时,此标准不为NaN解释NaN的符号。但是请注意,操作是在位上进行的字符串- copy, negate, abs, copySign -指定NaN结果的符号位,有时基于NaN操作数的符号位。的逻辑谓词totalOrder也受a的符号位的影响南操作数。对于所有其他操作,本标准没有规定NaN结果的符号位,即使只有一个输入NaN,或当NaN由无效操作产生时。

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

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

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