Người ta biết rằng NaNs lan truyền trong số học, nhưng tôi không thể tìm thấy bất kỳ cuộc biểu tình nào, vì vậy tôi đã viết một bài kiểm tra nhỏ:
#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: %f\nsub: %f %f %f\nadd: %f %f\ndiv: %f %f %f\nmul: %f %f\n",
neg, sub1,sub2,sub3, add1,add2, div1,div2,div3, mul1,mul2
);
return 0;
}
Ví dụ ( chạy trực tiếp tại đây ) tạo ra về cơ bản những gì tôi mong đợi (tiêu cực hơi kỳ lạ, nhưng nó có ý nghĩa):
neg: -nan
sub: nan nan nan
add: nan nan
div: nan nan nan
mul: nan nan
MSVC 2015 sản xuất một cái gì đó tương tự. Tuy nhiên, Intel C ++ 15 tạo ra:
neg: -nan(ind)
sub: nan nan 0.000000
add: nan nan
div: nan nan nan
mul: nan nan
Cụ thể qNaN - qNaN == 0.0
,.
Điều này ... không thể đúng, phải không? Các tiêu chuẩn liên quan (ISO C, ISO C ++, IEEE 754) nói gì về điều này và tại sao có sự khác biệt về hành vi giữa các trình biên dịch?
-ffast-math
trên gcc)?
Nan-NaN
làNaN
. Perl và Scala cũng hành xử tương tự.