Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a float is infinity/zero/denormal?

int is_infinity/is_zero/is_denormal(float f){
    //do something, return 0 or 1
}

This is what I did for checking if a float is negative. I want to do something similar for the other functions, but I'm not sure how.

int is_negative(float val){
    union sp_object copy;
    copy.frep = val;
    if((copy.irep & 0x80000000) != 0)
        return 1;
    else
        return 0;
}
like image 929
HOHO Avatar asked Jun 05 '17 19:06

HOHO


1 Answers

I want to do something similar for the other functions

Avoid bit fields, @David, as it depends on implementation specifics. <math.h> contains macros to classify a float. These macros work for double and long double too.

#include <math.h>

// Adjust returns values as desired.
int is_infinity_is_zero_is_denormal(float f) {
  if (isinf(f)) return 'i';
  if (f == 0.0f) return 'z';
  if (isnan(f)) return 'n';
  if (isnormal(f)) return 0;  // neither zero, subnormal, infinite, nor NaN

  // All that is left is de-normal/sub-normal.
  return 'd';
}

Or maybe simply

bool is_infinity_is_zero_is_denormal(float f) {
  return !(isnormal(f) || isnan(f));
}

Also see int fpclassify(real-floating x); to classify the number in one step.

classifies its argument value as NaN, infinite, normal, subnormal, zero, or into another implementation-defined category. C11 §7.12.3.1 2

The number classification macros FP_INFINITE FP_NAN FP_NORMAL FP_SUBNORMAL FP_ZERO represent the mutually exclusive kinds of floating-point values. They expand to integer constant expressions with distinct values. §7.12 6

bool is_infinity_is_zero_is_denormal(float f) {
  // return fpclassify(f) & (FP_INFINITE | FP_ZERO | FP_SUBNORMAL);  // not good
  switch (fpclassify(f)) {
    case FP_INFINITE:
    case FP_ZERO:
    case FP_SUBNORMAL:
      return true;
  }
  return false;
}

Let the compiler handle the optimization.

like image 148
chux - Reinstate Monica Avatar answered Sep 17 '22 20:09

chux - Reinstate Monica