1*f504f610SAugustin Cavalier #include <limits.h> 2*f504f610SAugustin Cavalier #include "libm.h" 3*f504f610SAugustin Cavalier ilogb(double x)4*f504f610SAugustin Cavalierint ilogb(double x) 5*f504f610SAugustin Cavalier { 6*f504f610SAugustin Cavalier #pragma STDC FENV_ACCESS ON 7*f504f610SAugustin Cavalier union {double f; uint64_t i;} u = {x}; 8*f504f610SAugustin Cavalier uint64_t i = u.i; 9*f504f610SAugustin Cavalier int e = i>>52 & 0x7ff; 10*f504f610SAugustin Cavalier 11*f504f610SAugustin Cavalier if (!e) { 12*f504f610SAugustin Cavalier i <<= 12; 13*f504f610SAugustin Cavalier if (i == 0) { 14*f504f610SAugustin Cavalier FORCE_EVAL(0/0.0f); 15*f504f610SAugustin Cavalier return FP_ILOGB0; 16*f504f610SAugustin Cavalier } 17*f504f610SAugustin Cavalier /* subnormal x */ 18*f504f610SAugustin Cavalier for (e = -0x3ff; i>>63 == 0; e--, i<<=1); 19*f504f610SAugustin Cavalier return e; 20*f504f610SAugustin Cavalier } 21*f504f610SAugustin Cavalier if (e == 0x7ff) { 22*f504f610SAugustin Cavalier FORCE_EVAL(0/0.0f); 23*f504f610SAugustin Cavalier return i<<12 ? FP_ILOGBNAN : INT_MAX; 24*f504f610SAugustin Cavalier } 25*f504f610SAugustin Cavalier return e - 0x3ff; 26*f504f610SAugustin Cavalier } 27