float f = (float)'a';
if(f < 0){
}
else if(f == 0){
}
else if(f > 0){
}
else{
printf("NaN\n");
}
f
如果是0
,则不会大于/等于/小于NaN
。
但首先如何制作这样的f
?
我尝试了各种方法来制作NaN
,但都没有效果......
答案 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)
。