2014-02-10 49 views
2

據我所知,NaN's在雙重表示和非零分數的指數部分都是1表示的。 (從here信息)C++使用cast來測試NaN是否安全?

它是安全的楠使用類似的測試:

double num = 1.0; 

// Do something to make num NaN 

double* pointer = # 
unsigned long long num2 = *((unsigned long long*)pointer); 

if((unsigned long long)num2 == 0x7FF8000000000001) 
{ 
    // Got a NaN 
} 

我希望0x7FF8000000000001是正確的測試。

由於分數必須是非零來表示一個NaN,所以我猜測雙重表示的小數部分可以是任何東西,所以也許需要更復雜的測試,它將小數部分轉換爲1,如數字0x7FF8000000000001所示。 (注意結尾處的1,小數部分。)

那麼,像這樣的東西可以安全地使用?

編輯:正如邁克提到的,例如我應該用一個指針來得到位,我會讓現在這種變化......

+0

http://stackoverflow.com/questions/10366485/problems-casting-nan-floats-to-int? – jcoder

+0

有不同種類的南非,有std :: isnan ... – PlasmaHH

+3

該演員做數字轉換;您需要投入一個引用或指針來重新解釋「double」的位爲整數類型。正如你所說的,你需要測試這個分數是非零的,不等於1.'std :: isnan'將正確和可移植地測試NaN;我只是用它。 –

回答

3

不少不同的64位的位模式浮動意味着NaN -點。邁克西摩告訴你使用isnan,這是可讀的方式來檢查NaN。您也可以使用浮點比較x != x,僅當xNaN時纔會失敗。

但是,如果你堅持用位模式做:

  • 符號位是無關緊要的。
  • 有效數字不能爲零;如果是這樣,你有一個無窮大,而不是一個NaN
  • 有偏指數必須是0x7ff;否則,你有一個正常或低於正常的浮點數。

所以我建議,再次只要你堅持使用位模式和捆綁自己,自己不可移植的代碼,類似下面的醜,不可移植,未經測試的代碼段:

u64 xl = (u64 &)x; 
u64 sig = xl & 0xfffffffffffffull; 
if ((xl >> 52 & 0x7ff) == 0x7ff && sig != 0) return 1; 
else return 0; 

最高位的有效數字告訴你你是否有「安靜的NaN」或「信號NaN」。

+0

應該避免測試'x!= x'。一些優化編譯器會用'false'來代替'x!= x'。 – user763305

+0

@ user763305:哪些編譯器?因爲它聽起來像那些編譯器壞了。 – tmyklebu

+0

我不記得了,但它發生在我身上。它也取決於你使用哪個編譯器標誌。 – user763305

相關問題