检查数字是否为 +-Inf 或 NaN

标签 c

出于稳健性原因,我想检查 float 是 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有 float 分类的宏:

fpclassify(x)返回以下之一:

  • FP_NAN : x不是数字;
  • FP_INFINITE : x正负无限;
  • FP_ZERO : x为零;
  • FP_SUBNORMAL : x太小而无法以规范化格式表示,或者
  • FP_NORMAL : 普通 float ,即以上都不是。

还有检查这些类之一的快捷方式,如果 x 则返回非零值是什么:

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

参数x可以是任何浮点表达式;宏检测参数的类型并为 float 工作和 double .

编辑:因为您不想使用(或不能使用)<math.h> ,您可以使用 nan 和 inf 的其他属性对您的数字进行分类:

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

所以:

#include <stdlib.h>
#include <stdio.h>
#include <float.h>

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,则必须调整限制.

关于检查数字是否为 +-Inf 或 NaN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36150514/

相关文章:

c - C语言从文件中读取数据

C++读取大量文件的一小部分

c - 转义序列在 C 中产生意外输出

类型转换指针时崩溃 - C

c - PowerPC 从内存中的已知地址加载方法地址并调用该方法

c - Linux C 数组长度问题

c++ - 如何告诉 XCode 调试器只在断点处停止? (也不异常(exception))

c - 错误 : PHDR segment not covered by LOAD segment

c - 为什么系统调用位左移?

c++ - 字符串 "sizeof"的意外结果