我對IEEE-754浮點比較規則的理解是,除!=
之外的所有比較運算符將返回false,如果其中一個或兩個參數都是NaN,而!=
運算符將返回true。我可以很容易地重現此問題有一個簡單的獨立測試:如果任一參數是NaN,會導致C/C++ <,<=和==運算符返回true?
for (int ii = 0; ii < 4; ++ii)
{
float a = (ii & 1) != 0 ? NAN : 1.0f;
float b = (ii & 2) != 0 ? NAN : 2.0f;
#define TEST(OP) printf("%4.1f %2s %4.1f => %s\n", a, #OP, b, a OP b ? "true" : "false");
TEST(<)
TEST(>)
TEST(<=)
TEST(>=)
TEST(==)
TEST(!=)
}
這將打印預期結果:(NAN在MSVC運行時格式化爲-1.$
)
1.0 < 2.0 => true
1.0 > 2.0 => false
1.0 <= 2.0 => true
1.0 >= 2.0 => false
1.0 == 2.0 => false
1.0 != 2.0 => true
-1.$ < 2.0 => false
-1.$ > 2.0 => false
-1.$ <= 2.0 => false
-1.$ >= 2.0 => false
-1.$ == 2.0 => false
-1.$ != 2.0 => true
1.0 < -1.$ => false
1.0 > -1.$ => false
1.0 <= -1.$ => false
1.0 >= -1.$ => false
1.0 == -1.$ => false
1.0 != -1.$ => true
-1.$ < -1.$ => false
-1.$ > -1.$ => false
-1.$ <= -1.$ => false
-1.$ >= -1.$ => false
-1.$ == -1.$ => false
-1.$ != -1.$ => true
然而,當我粘貼此塊代碼倒在我的應用程序的內部循環,所有的浮點運算進行,我得到的最深處莫名的這些結果:
1.0 < 2.0 => true
1.0 > 2.0 => false
1.0 <= 2.0 => true
1.0 >= 2.0 => false
1.0 == 2.0 => false
1.0 != 2.0 => true
-1.$ < 2.0 => true
-1.$ > 2.0 => false
-1.$ <= 2.0 => true
-1.$ >= 2.0 => false
-1.$ == 2.0 => true
-1.$ != 2.0 => false
1.0 < -1.$ => true
1.0 > -1.$ => false
1.0 <= -1.$ => true
1.0 >= -1.$ => false
1.0 == -1.$ => true
1.0 != -1.$ => false
-1.$ < -1.$ => true
-1.$ > -1.$ => false
-1.$ <= -1.$ => true
-1.$ >= -1.$ => false
-1.$ == -1.$ => true
-1.$ != -1.$ => false
出於某種原因,當其中一個或兩個參數都是NaN時,<
,<=
和==
運算符意外返回true。此外,!=
運算符意外返回false。
這是使用Visual Studio 2010構建的64位代碼,運行在Intel Xeon E5-2650上。使用_mm_getcsr()
,我已確認CSR註冊在兩種情況下都保持相同的值。
還有什麼可以影響像這樣的浮點數學行爲?
我討厭只有迪爾伯特的報價,但「這裏有鎳,孩子。讓自己更好的編譯器「 –
你確定他們傳統的準C89模式被廣告爲符合IEEE-754標準?無論如何,你有快速數學或一些這樣的啓用? – Deduplicator
好像你的編譯器正在拋出規範的某些部分以提高性能...... – Synxis