#include <limits.h> | |
#include "libm.h" | |
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 | |
int ilogbl(long double x) { | |
return ilogb(x); | |
} | |
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 | |
int ilogbl(long double x) { | |
PRAGMA_STDC_FENV_ACCESS_ON | |
union ldshape u = {x}; | |
uint64_t m = u.i.m; | |
int e = u.i.se & 0x7fff; | |
if (!e) { | |
if (m == 0) { | |
FORCE_EVAL(0 / 0.0f); | |
return FP_ILOGB0; | |
} | |
/* subnormal x */ | |
for (e = -0x3fff + 1; m >> 63 == 0; e--, m <<= 1) | |
; | |
return e; | |
} | |
if (e == 0x7fff) { | |
FORCE_EVAL(0 / 0.0f); | |
return m << 1 ? FP_ILOGBNAN : INT_MAX; | |
} | |
return e - 0x3fff; | |
} | |
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 | |
int ilogbl(long double x) { | |
#pragma STDC FENV_ACCESS ON | |
union ldshape u = {x}; | |
int e = u.i.se & 0x7fff; | |
if (!e) { | |
if (x == 0) { | |
FORCE_EVAL(0 / 0.0f); | |
return FP_ILOGB0; | |
} | |
/* subnormal x */ | |
x *= 0x1p120; | |
return ilogbl(x) - 120; | |
} | |
if (e == 0x7fff) { | |
FORCE_EVAL(0 / 0.0f); | |
u.i.se = 0; | |
return u.f ? FP_ILOGBNAN : INT_MAX; | |
} | |
return e - 0x3fff; | |
} | |
#endif |