ilogbl.c raw

   1  #include <limits.h>
   2  #include "libm.h"
   3  
   4  #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
   5  int ilogbl(long double x)
   6  {
   7  	return ilogb(x);
   8  }
   9  #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
  10  int ilogbl(long double x)
  11  {
  12  	#pragma STDC FENV_ACCESS ON
  13  	union ldshape u = {x};
  14  	uint64_t m = u.i.m;
  15  	int e = u.i.se & 0x7fff;
  16  
  17  	if (!e) {
  18  		if (m == 0) {
  19  			FORCE_EVAL(0/0.0f);
  20  			return FP_ILOGB0;
  21  		}
  22  		/* subnormal x */
  23  		for (e = -0x3fff+1; m>>63 == 0; e--, m<<=1);
  24  		return e;
  25  	}
  26  	if (e == 0x7fff) {
  27  		FORCE_EVAL(0/0.0f);
  28  		return m<<1 ? FP_ILOGBNAN : INT_MAX;
  29  	}
  30  	return e - 0x3fff;
  31  }
  32  #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
  33  int ilogbl(long double x)
  34  {
  35  	#pragma STDC FENV_ACCESS ON
  36  	union ldshape u = {x};
  37  	int e = u.i.se & 0x7fff;
  38  
  39  	if (!e) {
  40  		if (x == 0) {
  41  			FORCE_EVAL(0/0.0f);
  42  			return FP_ILOGB0;
  43  		}
  44  		/* subnormal x */
  45  		x *= 0x1p120;
  46  		return ilogbl(x) - 120;
  47  	}
  48  	if (e == 0x7fff) {
  49  		FORCE_EVAL(0/0.0f);
  50  		u.i.se = 0;
  51  		return u.f ? FP_ILOGBNAN : INT_MAX;
  52  	}
  53  	return e - 0x3fff;
  54  }
  55  #endif
  56