检查浮点数是否不是数字

时间:2015-04-19 13:33:03

标签: c++

此代码来自UE4,我无法理解它。

static FORCEINLINE bool IsNaN( float A ) 
{
    return ((*(uint32*)&A) & 0x7FFFFFFF) > 0x7F800000;
}

(uint32只是一个无符号的int)

第一部分是将一个浮点解释为一个uint32,这是一个简单的部分,但为什么是按位,它与0x7FFFFFFF?最后4位告诉我们的是什么?为什么我们将结果与0x7F800000进行比较?

3 个答案:

答案 0 :(得分:4)

此定义遵循IEEE 754标准中提供的NaN定义。

  

在IEEE 754符合标准的浮点存储格式中,NaN由NaN独有的特定预定义位模式识别。

0x7FFFFFFF是最大的值,可以用31位表示。在这种情况下,它只是忽略位符号,因为:

  

符号位无关紧要。

0x7F800000是指数字段位的掩码。

  

例如,逐位IEEE浮点标准单精度   (32位)NaN将是:s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx其中s   是符号(在应用程序中经常被忽略),x是非零的   (零值编码无穷大)。

s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx s = 0 0x7FFFFFFF(被x = 0}和0x7F800000忽略)等于operator >

使用

x,因为如果设置了有效数据中的任何位(任何0x7F800000),则结果值将大于{{1}}。

为什么要设定?这是因为:

  

标准未定义剩余位[...]的状态/值,除非它们不能全为零。

来源:NaN on Wikipedia

答案 1 :(得分:3)

这是NaN的定义。您可以在wikipedia上详细阅读 使用0x7FFFFFFF是因为符号位在检查中无关紧要 定义说,对于nan,指数字段用1填充,而有些非零数字在有效数字中 0x7F80000这是指数字段的位掩码。因此,如果在有效数字中设置了一个位,则该数字必须大于0x7F800000

请注意,假设sizeof(float) == 4

答案 2 :(得分:0)

isnan()

您可以使用环境定义但具有历史问题的isnan实现(它是一个宏,然后成为tr1下的函数,在某些实现中仍然是宏)。

f!= f

或者,如果您无法在标准库中跟踪它,您可以依赖IEEE标准,声明NaN值具有与其自身不同的特殊属性:f != f
查看来自 IEEE-754 委员会的Stephen Canon的really interesting answer,并解释其背后的基本原理。

请注意,当打开某些优化标记时(例如-ffast-math上的gcc),并非所有编译器都会尊重这一点。