1570af302Sopenharmony_ci#include <limits.h> 2570af302Sopenharmony_ci#include "libm.h" 3570af302Sopenharmony_ci 4570af302Sopenharmony_ciint ilogb(double x) 5570af302Sopenharmony_ci{ 6570af302Sopenharmony_ci #pragma STDC FENV_ACCESS ON 7570af302Sopenharmony_ci union {double f; uint64_t i;} u = {x}; 8570af302Sopenharmony_ci uint64_t i = u.i; 9570af302Sopenharmony_ci int e = i>>52 & 0x7ff; 10570af302Sopenharmony_ci 11570af302Sopenharmony_ci if (!e) { 12570af302Sopenharmony_ci i <<= 12; 13570af302Sopenharmony_ci if (i == 0) { 14570af302Sopenharmony_ci FORCE_EVAL(0/0.0f); 15570af302Sopenharmony_ci return FP_ILOGB0; 16570af302Sopenharmony_ci } 17570af302Sopenharmony_ci /* subnormal x */ 18570af302Sopenharmony_ci for (e = -0x3ff; i>>63 == 0; e--, i<<=1); 19570af302Sopenharmony_ci return e; 20570af302Sopenharmony_ci } 21570af302Sopenharmony_ci if (e == 0x7ff) { 22570af302Sopenharmony_ci FORCE_EVAL(0/0.0f); 23570af302Sopenharmony_ci return i<<12 ? FP_ILOGBNAN : INT_MAX; 24570af302Sopenharmony_ci } 25570af302Sopenharmony_ci return e - 0x3ff; 26570af302Sopenharmony_ci} 27