如何在c中生产NaN浮子?

时间:2011-08-27 03:24:04

标签: c floating-point nan

float f = (float)'a';
if(f < 0){ 
}   
else if(f == 0){ 
}   
else if(f > 0){ 
}   
else{
    printf("NaN\n");                                                          
}   

f如果是0,则不会大于/等于/小于NaN

但首先如何制作这样的f

我尝试了各种方法来制作NaN,但都没有效果......

9 个答案:

答案 0 :(得分:18)

使用浮点数,0.0 / 0.0不是“除以零”错误;它会产生NaN

此C程序打印-nan

#include <stdio.h>

int main()
{
    float x = 0.0 / 0.0;
    printf("%f\n", x);
    return 0;
}

就计算机的NaN看起来而言,两个“无效”数字被保留用于“信令”和“安静”NaN(类似于为正无穷大保留的两个无效数字)。 Wikipedia entry有更多关于如何将NaN表示为IEE浮点数的详细信息。

答案 1 :(得分:18)

要产生纳米,有几种方法:

1)手动生成它(读ieee754以正确设置位)

2)使用宏。 GCC公开了一个宏NAN。它在math.h中定义

检查nan的一般方法是检查if (f == f)(对于nan值应该失败)

对于nan,浮点表示中的指数位应全部设置为1(float由一个有符号位,一组指数位和一组尾数位组成)

答案 2 :(得分:4)

您可以使用NAN宏,或只使用nan/nanf函数中的一个来为变量指定nan值。
要检查您是否正在处理nan值,可以使用isnan()。 这是一个例子:

#include <stdio.h>
#include <math.h>

int main(void) {

    float a = NAN;//using the macro in math.h
    float f = nanf("");//using the function version 
    double d = nan("");//same as above but for doubles!

    printf("a = %f\nf = %f\nd = %f\n",a,f,d);

    if(isnan(a))
        puts("a is a not a number!(NAN)\n");

    return 0;
}

运行上面的代码段将为您提供此输出:

a = nan
f = nan
d = nan
a is a not a number!(NAN)

自己运行代码:http://ideone.com/WWZBl8
阅读更多信息:http://www.cplusplus.com/reference/cmath/NAN/

答案 3 :(得分:3)

从GNU GCC手册math.h定义允许您将变量显式设置为无穷大或NaN的宏。由于这是C99的一部分,因此您可以将以下宏与其他符合c99标准的编译器一起使用。

- Macro:浮动INFINITY 表示正无穷大的表达式。它等于1.0 / 0.0等数学运算产生的值。 -INFINITY表示负无穷大。

通过将浮点值与此宏进行比较,可以测试浮点值是否为无限值。但是,不建议这样做;你应该使用isfinite宏代替。请参阅浮点类。

此宏已在ISO C99标准中引入。

- Macro:浮动NAN 表示“非数字”的值的表达式。此宏是GNU扩展,仅在支持“非数字”值的计算机上可用 - 也就是说,在所有支持IEEE浮点的计算机上都可用。

您可以使用'#ifdef NAN'来测试机器是否支持NaN。 (当然,您必须安排GNU扩展可见,例如通过定义_GNU_SOURCE,然后您必须包含math.h。)

有关详细信息,请参阅此处: http://www.gnu.org/s/hello/manual/libc/Infinity-and-NaN.html

答案 4 :(得分:3)

对于托管C实现,可以执行#include <math.h>并使用NAN宏(如果已定义)。例如,使用GCC,它由内置函数(__builtin_nanf (""))实现。

对于独立式C实现(<math.h>标头可能不可用)或未定义NAN宏(即使可能支持NaN可能会发生),也可以生成NaN具有浮点运算,例如0.0 / 0.0。但是,它可能存在一些问题。

首先,这样的操作也会生成异常,在某些C实现上可能存在陷阱。可以确保它在编译时使用:

计算
static double my_nan = 0.0 / 0.0;

另一个问题是Microsoft Visual C ++(至少某些版本)尝试在编译时评估0.0 / 0.0(即使此表达式位于代码中的任意位置)并抱怨其有效性。所以,这里的解决方案是相反的:确保编译器不会在编译时评估它,通过执行:

static double zero = 0.0;

然后使用zero / zero。由于这些解决方案存在冲突,因此可以使用specific macros上的预处理程序指令(#if ...)测试编译器。

也可以选择基于NaN编码的解决方案,但也存在可移植性问题。首先,IEEE 754标准没有完全定义NaN的编码,特别是区分安静和信令NaN的方式(硬件在实践中有所不同);信令NaN将产生不确定的行为。此外,IEEE 754标准没有定义如何在存储器中表示比特串,即可能需要检测字节序。如果这些问题得到解决,带有指针转换的unsigned char的联合或数组可以很好地获得浮点类型。不要使用在其地址上强制转换指针的整数来进行类型惩罚,因为这会破坏C别名规则。

答案 5 :(得分:1)

这也适用于常量(0/0会在vs上产生编译错误):

const unsigned maxU = ~0;
const float qNan =  *((float*)&maxU);

答案 6 :(得分:1)

也可以通过将浮点变量的所有32位设置为1来产生-nan,如下所示:

float nan_val = 0xffffffff;

此外,您可以通过检查与自身的比较是否失败来明确比较float变量是否为-nan

if (nan_val != nan_val) {
// executes iff nan_val is -nan
}

这种比较方法应适用于使用IEEE浮点数的编译器。

答案 7 :(得分:0)

以下C程序将产生一个NaN。第二个陈述将导致NaN。

#include <stdio.h>
#include <tchar.h>
#include "math.h"

int _tmain(int argc, _TCHAR* argv[])
{
    double dSQRTValue = sqrt( -1.00 ); 
    double dResult = -dSQRTValue;  // This statement will result in a NaN.
    printf( "\n %lf", dResult );

    return 0;
}

以下是该计划的输出。

1.#QNAN0

答案 8 :(得分:0)

当程序包含像@Dan Cecile OR sqrt(-1)所述的0.0 / 0.0之类的值时,会生成