C ++使用强制转换来测试NaN是否安全?

时间:2014-02-10 13:03:15

标签: c++ c floating-point double nan

据我所知,NaN由双重表示和非零分数的指数部分中的所有1表示。 (来自here的信息)

使用类似的东西测试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,小数部分。)

那么,这样的东西会安全使用吗?

编辑:正如Mike所说,在示例中我应该使用指针获取位,我现在将进行此更改...

1 个答案:

答案 0 :(得分:3)

相当多的不同64位位模式在浮点数中意味着NaN。 Mike Seymour告诉您使用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。"