1570af302Sopenharmony_ci#include <limits.h> 2570af302Sopenharmony_ci#include "libm.h" 3570af302Sopenharmony_ci 4570af302Sopenharmony_ci#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 5570af302Sopenharmony_ciint ilogbl(long double x) 6570af302Sopenharmony_ci{ 7570af302Sopenharmony_ci return ilogb(x); 8570af302Sopenharmony_ci} 9570af302Sopenharmony_ci#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 10570af302Sopenharmony_ciint ilogbl(long double x) 11570af302Sopenharmony_ci{ 12570af302Sopenharmony_ci #pragma STDC FENV_ACCESS ON 13570af302Sopenharmony_ci union ldshape u = {x}; 14570af302Sopenharmony_ci uint64_t m = u.i.m; 15570af302Sopenharmony_ci int e = u.i.se & 0x7fff; 16570af302Sopenharmony_ci 17570af302Sopenharmony_ci if (!e) { 18570af302Sopenharmony_ci if (m == 0) { 19570af302Sopenharmony_ci FORCE_EVAL(0/0.0f); 20570af302Sopenharmony_ci return FP_ILOGB0; 21570af302Sopenharmony_ci } 22570af302Sopenharmony_ci /* subnormal x */ 23570af302Sopenharmony_ci for (e = -0x3fff+1; m>>63 == 0; e--, m<<=1); 24570af302Sopenharmony_ci return e; 25570af302Sopenharmony_ci } 26570af302Sopenharmony_ci if (e == 0x7fff) { 27570af302Sopenharmony_ci FORCE_EVAL(0/0.0f); 28570af302Sopenharmony_ci return m<<1 ? FP_ILOGBNAN : INT_MAX; 29570af302Sopenharmony_ci } 30570af302Sopenharmony_ci return e - 0x3fff; 31570af302Sopenharmony_ci} 32570af302Sopenharmony_ci#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 33570af302Sopenharmony_ciint ilogbl(long double x) 34570af302Sopenharmony_ci{ 35570af302Sopenharmony_ci #pragma STDC FENV_ACCESS ON 36570af302Sopenharmony_ci union ldshape u = {x}; 37570af302Sopenharmony_ci int e = u.i.se & 0x7fff; 38570af302Sopenharmony_ci 39570af302Sopenharmony_ci if (!e) { 40570af302Sopenharmony_ci if (x == 0) { 41570af302Sopenharmony_ci FORCE_EVAL(0/0.0f); 42570af302Sopenharmony_ci return FP_ILOGB0; 43570af302Sopenharmony_ci } 44570af302Sopenharmony_ci /* subnormal x */ 45570af302Sopenharmony_ci x *= 0x1p120; 46570af302Sopenharmony_ci return ilogbl(x) - 120; 47570af302Sopenharmony_ci } 48570af302Sopenharmony_ci if (e == 0x7fff) { 49570af302Sopenharmony_ci FORCE_EVAL(0/0.0f); 50570af302Sopenharmony_ci u.i.se = 0; 51570af302Sopenharmony_ci return u.f ? FP_ILOGBNAN : INT_MAX; 52570af302Sopenharmony_ci } 53570af302Sopenharmony_ci return e - 0x3fff; 54570af302Sopenharmony_ci} 55570af302Sopenharmony_ci#endif 56