如何在c中生成NaN浮子?

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

如果它是NaNf不会大于/等于/小于0

但是如何在第一时间产生这样的f

我尝试了各种方法来生产NaN ,但没有一种方法可行。

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

这个C程序打印-nan

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

NaN看起来对计算机而言,两个“无效”数字被保留用于“信令”和“安静”NaN(类似于为正无穷大保留的两个无效数字)。 维基百科条目提供了有关NaN如何表示为IEE浮点数的更多详细信息。

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

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

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

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

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

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

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

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

该宏是在ISO C99标准中引入的。

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

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

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

您可以使用NAN宏,也可以只使用nan/nanf函数之一为变量分配nan值。
要检查您是否正在处理nan值,可以使用isnan() 。 这是一个例子:

 #include  #include  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/

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

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

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

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

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

 static double my_nan = 0.0 / 0.0; 

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

 static double zero = 0.0; 

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

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

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

 #include  #include  #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

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