NaN == 0.0与英特尔C ++编译器?
众所周知,NaNs在算术中传播,但我找不到任何示范,所以我写了一个小测试:
#include <limits>
#include <cstdio>
int main(int argc, char* argv[]) {
float qNaN = std::numeric_limits<float>::quiet_NaN();
float neg = -qNaN;
float sub1 = 6.0f - qNaN;
float sub2 = qNaN - 6.0f;
float sub3 = qNaN - qNaN;
float add1 = 6.0f + qNaN;
float add2 = qNaN + qNaN;
float div1 = 6.0f / qNaN;
float div2 = qNaN / 6.0f;
float div3 = qNaN / qNaN;
float mul1 = 6.0f * qNaN;
float mul2 = qNaN * qNaN;
printf(
"neg: %fnsub: %f %f %fnadd: %f %fndiv: %f %f %fnmul: %f %fn",
neg, sub1,sub2,sub3, add1,add2, div1,div2,div3, mul1,mul2
);
return 0;
}
这个例子(在这里运行)基本上产生了我期望的结果(负面有点奇怪,但它有道理):
neg: -nan
sub: nan nan nan
add: nan nan
div: nan nan nan
mul: nan nan
MSVC 2015产生类似的东西。 但是,英特尔C ++ 15产生:
neg: -nan(ind)
sub: nan nan 0.000000
add: nan nan
div: nan nan nan
mul: nan nan
具体来说, qNaN - qNaN == 0.0
。
这......不对,对吗? 相关标准(ISO C,ISO C ++,IEEE 754)对此有何评论,为什么编译器之间的行为有所不同?
英特尔C ++编译器中的默认浮点处理是/fp:fast
,它处理NaN
的不安全(例如,这也导致NaN == NaN
为true
)。 尝试指定/fp:strict
或/fp:precise
并查看是否有帮助。
这个 。 。 。 不可能是对的,对吧? 我的问题:相关标准(ISO C,ISO C ++,IEEE 754)对此有何评论?
Petr Abdulin已经回答了为什么编译器给出了0.0
答案。
以下是IEEE-754:2008所说的内容:
(6.2使用NaN进行操作)“[...]对于具有安静NaN输入的操作,除了最大和最小操作外,如果要传送浮点结果,结果应该是安静的NaN,它应该是输入NaN“。
所以减去两个安静的NaN操作数的唯一有效结果是一个安静的NaN; 任何其他结果无效。
C标准说:
(C11,F.9.2表达式转换p1)“[...]
x - x→0 0“如果x是一个NaN或无限的”0“,则表达式x - x和0 0不等价。
(这里NaN表示按照F.2.1p1的安静的NaN“本规范没有定义信号NaN的行为,它通常使用术语NaN来表示安静的NaN”)
由于我看到一个反驳英特尔编译器符合标准的答案,而其他人没有提到这一点,所以我会指出,GCC和Clang都有一种模式,可以让他们做类似的事情。 他们的默认行为是符合IEEE标准的 -
$ g++ -O2 test.cc && ./a.out
neg: -nan
sub: nan nan nan
add: nan nan
div: nan nan nan
mul: nan nan
$ clang++ -O2 test.cc && ./a.out
neg: -nan
sub: -nan nan nan
add: nan nan
div: nan nan nan
mul: nan nan
- 但如果你以牺牲正确性为代价要求速度,你会得到你所要求的 -
$ g++ -O2 -ffast-math test.cc && ./a.out
neg: -nan
sub: nan nan 0.000000
add: nan nan
div: nan nan 1.000000
mul: nan nan
$ clang++ -O2 -ffast-math test.cc && ./a.out
neg: -nan
sub: -nan nan 0.000000
add: nan nan
div: nan nan nan
mul: nan nan
我认为批评ICC的默认选择是完全公平的,但我不会把整个Unix战争都读回这个决定。
链接地址: http://www.djcxy.com/p/14993.html