2016-04-26 78 views
5

我有以下程序:double和NaN的比較結果是什麼?

#include <iostream> 
#include <cmath> 

int main() { 
    double a = 1; 
    double b = nan(""); 

    std::cout << (a > b) << std::endl; 
    std::cout << (b > a) << std::endl; 

    return 0; 
} 

輸出:

0 
0 

一般從nan意義 - not a number很顯然,與nan任何操作基本上是沒有意義的。從我在互聯網上發現的IEEE-754我發現如果在FPU中至少有一個操作數是nan,結果也是nan,但我沒有發現正常值和nan之間的比較,如上例。

標準對此有何評論?

+1

FPU函數和比較的邏輯結果可能是兩個不同的東西。你的反彙編說什麼? – tadman

+0

您的代碼可能(或可能不會)缺少'=='比較。你確實檢查了'<' and '>'而不是'=='。也許你打算使用'<' and '> ='或'<=' and '>'。 – jotik

回答

7

標準對此有何評論?

C++標準沒有說明如何操作NaNs的行爲。它是未指定的。所以,就C++而言,任何結果都是可能的並且是允許的。

ANSI/IEEE標準754-1985說:

5.7。比較

...每個NaN都會將無序與包括它自己在內的所有事物進行比較。 ...什麼無序裝置恰好被示出在表4中相同的部分

。但簡而言之,這意味着如果任何操作數是NaN,那麼比較將返回錯誤,除了!=將返回true。

+0

也許我沒有讀到它的好處。謝謝! – Alex

1

0這裏意味着錯誤。 Nan不等於或與任何值相當,所以操作的結果是錯誤的(0)。

+0

你說的非常合乎邏輯,但是你可以在定義它的地方給出任何參考。 – Alex

2

您看到的0意味着false在這種情況下,因爲這是默認情況下流顯示爲false的內容。如果你想看到它作爲truefalse使用std::boolalpha

std::cout << std::boolalpha << (a > b) << std::endl; 

乳清比較浮點值,其中值之一是楠則x<yx>yx<=yx>=y,並且x==y都會計算爲假,而x!=y將永遠是真實的。 Andrew Koenig在Dr Dobbs網站上有一篇關於此的好文章。

當您考慮它時,結果不能爲nan,因爲比較運算符需要返回一個只能有2個狀態的布爾值。

+0

你能否在這個行爲定義的地方提供任何引用(我的意思是NaN和任何其他正常值之間的比較操作)? – Alex

+0

@Alex - 我提供了一篇文章鏈接 – Sean

0

那麼,在@ user2079303頂部的相當不錯的答案,有兩個NaN:安靜的NaN和信號NaN。您可以在您的平臺上檢查std::numeric_limits<T>::has_signaling_NaN是否有信號NaN可用。如果這是真的和值包含std::numeric_limits<T>::signaling_NaN,然後

當NaN被用作參數的算術表達式的信令,適當的浮點異常可以被升高和NaN被「安靜」,即,表達式返回一個安靜的NaN。

要真正獲得FP異常,您可能需要設置FPU控制字(對於x87單元)或MXCSR寄存器(對於SSE2 +單元)。這對於x86/x64平臺是正確的,請檢查您的平臺文檔是否具有類似的功能