Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么GCC会让nan、clang和intel产生+;0.0/0.0的nan?_C++_Gcc_Nan_Ieee 754 - Fatal编程技术网

C++ 为什么GCC会让nan、clang和intel产生+;0.0/0.0的nan?

C++ 为什么GCC会让nan、clang和intel产生+;0.0/0.0的nan?,c++,gcc,nan,ieee-754,C++,Gcc,Nan,Ieee 754,当我调试代码时,我发现GCC和Clang都会为0.0/0.0生成nan,这是我所期望的,但是GCC会生成一个符号位设置为1的nan,而Clang会将其设置为0(如果我没记错的话,与ICC一致) 现在显然这两种形式都是允许的,但我一直想知道为什么0.0/0.0会使GCC输出一个“负”结果(打印它会给出-nan),而-(0.0/0.0)会给出一个“正”结果?更令人困惑的是,-0.0/0.0又是“负”的。这是一个不断折叠的奇怪现象吗 编辑 实际上,正是不断的折叠使它成为一个正的nan。如果我在运行时强

当我调试代码时,我发现GCC和Clang都会为
0.0/0.0
生成nan,这是我所期望的,但是GCC会生成一个符号位设置为1的nan,而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
volatile float zero=0.0;

标准::coutIEEE-754未指定NaN的符号:

当输入或结果为NaN时,本标准不适用 解读“南”的符号。然而,请注意,位上的操作 串 -copy、negate、abs、copySign-指定NaN结果的符号位,有时基于NaN操作数的符号位。这个 逻辑谓词totalOrder也受 NaN操作数。对于所有其他操作,本标准未规定 NaN结果的符号位,即使只有一个输入NaN, 或者当NaN是由无效操作生成的

现在让我们看一看

在这种情况下,Intel确实指定了NaN的特定值,称为
QNaN浮点不定值
(见表4-1),该值在
#IA
(无效算术异常)时返回(见表8-10)。 查找0乘0的除法


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

啊,我明白了。因此,根据您是直接计算0/0还是启用优化,clang和icc似乎会产生不一致的结果。那是故意的吗?不知道你的意思。编译器可以对符号位执行任何操作。IEEE标准中未指定符号位。在这里使用+NaN或-NaN是编译器的良好权利。但是,x86 Intel CPU将始终生成带负号位的NaN,这在标准中也是有效的。有些编译器可能知道这种硬件行为,有些不知道,有些可能不在乎。如果您好奇的话,这里的铿锵源代码是llvm/lib/Support/APFloat.cpp,divideSpecial方法。我真的懒得深入研究gcc源代码^^^仅供参考,ARM VFP将产生一个积极的信号,硬件制造商之间并没有达成协议。