检查数字是+ -Inf还是NaN

出于鲁棒性原因,我想检查浮点数是IEEE-754 + -Inf还是IEEE-754 Nan。 我的代码如下,我想知道它是否正确:

#define PLUS_INFINITE (1.0f/0.0f) #define MINUS_INFINITE (-1.0f/0.0f) #define NAN (0.0f/0.0f) float Local_Var; /*F is a float numnber.*/ if((unsigned long)(F) == 0x7f800000ul) { Local_Var = PLUS_INFINITE; } elseif((unsigned long)(F) == 0xff800000ul) { Local_Var = MINUS_INFINITE; } /*fraction = anything except all 0 bits (since all 0 bits represents infinity).*/ elseif((((unsigned long)(F) & 0x007ffffful) != 0ul ) &&((unsigned long)(F) == 0x7f800000ul)) || (((unsigned long)(F) & 0x807ffffful) != 0ul ) && ((unsigned long)(F) == 0xff800000ul)) { Local_Var = NAN; } else{} 

C99具有用于浮点数分类的宏:

fpclassify(x)返回以下之一:

  • FP_NANx不是数字;
  • FP_INFINITEx是正或负无限;
  • FP_ZEROx为零;
  • FP_SUBNORMALx太小而无法以标准化格式表示或
  • FP_NORMAL :正常的浮点数,即以上都不是。

还有一些快捷方式可以检查其中一个类,如果x是什么,则返回非零值:

  isfinite(x) isnormal(x) isnan(x) isinf(x) 

参数x可以是任何浮点表达式; 宏检测参数的类型,并为floatdouble

编辑 :既然你不想使用(或不能使用) ,你可以使用nan和inf的其他属性来分类你的数字:

  • nan将错误与所有数字进行比较,包括对自身;
  • inf大于FLT_MAX ;
  • -inf小于-FLT_MAX

所以:

 #include  #include  #include  int main() { float f[] = { 0.0, 1.0, FLT_MAX, 0.0 / 0.0, 1.0/0.0, -1.0/0.0 }; int i; for (i = 0; i < 6; i++) { float x = f[i]; int is_nan = (x != x); int is_inf = (x < -FLT_MAX || x > FLT_MAX); printf("%20g%4d%4d\n", x, is_nan, is_inf); } return 0; } 

在此解决方案中,如果要使用double ,则必须调整限制。

将漂浮物浇到那样的长条上是错误的。 它应该是一个联合或一个类型惩罚的指针。

这是dietlibc(带双打)的一个工作示例:
https://github.com/ensc/dietlibc/blob/master/lib/__isinf.c https://github.com/ensc/dietlibc/blob/master/lib/__isnan.c

Musl有一个较短的fpclassify,以及浮动的适当常量:
http://git.musl-libc.org/cgit/musl/tree/src/math/__fpclassifyf.c

最好使用fpclassify()函数回答

备择方案:

 float F; if (F <= FLT_MAX) { if (F >= -FLT_MAX) { puts("Finite"); } else { puts("-Infinity"); } } else { if (F > 0) { puts("+Infinity"); } else { puts("NaN"); } } 

如果代码想要弄乱这些位并假设float是二进制32格式:

 assert(sizeof (float) == sizeof (uint32_t)); union { float f; uint32_t u32; } x; xf = F; 

掩码依赖于floatuint32_t endian的相对endian。 它们通常是一样的。

 // Is F one of the 3 special: +inf, -inf, NaN? if (x.u32 & 0x7F800000 == 0x7F800000) { if (x.u32 & 0x007FFFFF) { puts("NaN"); } else if (x.u32 & 0x80000000) { puts("-Inf"); } else { puts("+Inf"); } }