当我调试代码时,我发现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的除法
您可以看到,对于该值,符号位已设置。