测试浮点值是否为NaN

14
我需要检查 float 是否为 NaN。通过阅读一些链接,我发现最常见的检查方法是:Checking if a double (or float) is nan in C++
FLOAT32 f32_test_NaN = (some_value);
if (f32_test_NaN == f32_test_NaN)
{
    //do something;
}
else
{
    // do something;
}

但是这对我似乎不起作用。我的代码如下:

FLOAT32 test_NaN = 0x414570A3;//some value - is this ok?

GDB上的调试:

(gdb) p test_NaN
$1 = 1.09506982e+09

(gdb) p/x test_NaN
$2 = 0x41457080 // Hex is not same as init value - What is compiler doing?

在我的情况下,test_NaN等于test_NaN

请告诉我是否需要进行任何编译器设置。我正在Solaris上运行。还有其他检查相同的方法吗?

提前致谢。


1
https://dev59.com/YHRB5IYBdhLWcg3wn4YL - Mehrdad Afshari
3
为什么不使用来自math.h的isnan()函数?有什么特别的原因吗? - Constantin
该标准函数在此环境中不可用。 - kp11
2
不是重复 - 这是关于C语言,而不是C++。 - einpoklum
标题可能有误导性 - 它是关于一个所谓的“nan”实际上并不是“nan”的问题。 - ead
4个回答

23

包含头文件math.h,使用int isnan(x)函数。别忘了链接使用-lm选项。


1
或许应该补充说明的是,“only” 出现在 C99 中,因此并不是所有编译器都会实现它。 - Jens Gustedt
1
suncc支持它,这似乎是提问者正在使用的。 - Stephen Canon
1
实际上,isnan不是一个函数,至少在包含math.h后使用它时不是:它是一个具有实现定义定义的宏。 - Ruslan

10
如果<math.h>不可用,则执行以下操作:
if (x != x)
{
    // x is NaN
}

谢谢,我正在做同样的事情,但可能我没有正确初始化。你能告诉我我可以用什么值来初始化“x”以测试NaN吗? - kp11
@kp11 任何浮点表达式都可以。 - fuz

7

如果 (x != x)

当 x = 0x7FBFFFFF (符号位为0,a=0,其余位为1) 时

http://en.wikipedia.org/wiki/NaN

IEEE浮点标准单精度(32位)NaN的按位示例:s111 1111 1axx xxxx xxxx xxxx xxxx xxxx,其中s是符号,x是有效负载,a确定NaN的类型。如果 a = 1,则为静默NaN;如果a为零且有效负载非零,则为信号NaN


1

问题可能出在你的初始化上(至少这可以解释你在gdb中看到的值):

FLOAT32 test_NaN = 0x414570A3;

给定的十六进制值被视为整数并转换为浮点数(带有指数和值),这意味着它以不同的格式存储。

如果您想强制修改浮点数内部的比特,则需要使用 memcpy:

FLOAT32 test_NaN;
memcpy(&test_NaN, 0x414570A3, 4);

酷!!我知道问题出在哪里了。但是对我来说,memcpy崩溃了。 因此,我只是做了这个,并且它起作用了!! UINT32 test_NaN [2] = {0xffffffff,0xfffffff7}; FLOAT32 test = ( FLOAT32)test_NaN;(在注释中不显示指针(?!?)) - kp11
6
你的代码有误。memcpy必须从一个地址复制。所以先将0x414570A3存储在一个整型变量中。 - Calmarius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接