Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a number is +-Inf or NaN

Tags:

c

For the robustness reason, I want check if a float number is IEEE-754 +-Inf or IEEE-754 Nan. My code is in the following, I want know if it is correct:

 #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{}
like image 202
Stack Over Avatar asked Mar 22 '16 09:03

Stack Over


People also ask

How do you check if a Number is NaN or not?

The Number. isNaN() method returns true if the value is NaN , and the type is a Number.

Is NaN () is used to test for NaN?

General description. The isnan() function tests whether x is NaN (not a number).

How do you compare NaN?

In JavaScript, the best way to check for NaN is by checking for self-equality using either of the built-in equality operators, == or === . Because NaN is not equal to itself, NaN != NaN will always return true .


1 Answers

C99 has macros for the classification of floating-point numbers:

fpclassify(x) returns one of:

  • FP_NAN: x is not a number;
  • FP_INFINITE: x is plus or minus infinite;
  • FP_ZERO: x is zero;
  • FP_SUBNORMAL: x is too small to be represented in normalized format or
  • FP_NORMAL: normal floating-point number, i.e. none of the above.

There are also shortcuts that check for one of these classes, which return non-zero if x is what :

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

The argument x can be any floating-point expression; the macros detect the type of the argument and work for float and double.

EDIT: Since you don't want to use (or cannot use) <math.h>, you could use other properties of nan and inf to classify your numers:

  • nan compares false to all numbers, including to itself;
  • inf is greater than FLT_MAX;
  • -inf is smaller than -FLT_MAX.

So:

#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;
}

In this solution, you must adapt the limits if you want to use double.

like image 54
M Oehm Avatar answered Sep 27 '22 18:09

M Oehm