1 /* @(#)s_ilogb.c 5.1 93/09/24 */ 2 /* 3 * ==================================================== 4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 5 * 6 * Developed at SunPro, a Sun Microsystems, Inc. business. 7 * Permission to use, copy, modify, and distribute this 8 * software is freely granted, provided that this notice 9 * is preserved. 10 * ==================================================== 11 */ 12 13 #include <sys/cdefs.h> 14 #if defined(LIBM_SCCS) && !defined(lint) 15 __RCSID("$NetBSD: s_ilogb.c,v 1.15 2016/08/24 10:03:32 christos Exp $"); 16 #endif 17 18 /* ilogb(double x) 19 * return the binary exponent of non-zero x 20 * ilogb(0) = 0x80000001 21 * ilogb(inf/NaN) = 0x7fffffff (no signal is raised) 22 */ 23 24 #include <math.h> 25 #include <fenv.h> 26 #include "math_private.h" 27 28 #ifndef __HAVE_LONG_DOUBLE 29 __strong_alias(ilogbl,ilogb) 30 #endif 31 32 int 33 ilogb(double x) 34 { 35 int32_t hx, lx, ix; 36 37 GET_HIGH_WORD(hx, x); 38 hx &= 0x7fffffff; 39 if (hx < 0x00100000) { 40 GET_LOW_WORD(lx, x); 41 if ((hx | lx) == 0) { 42 feraiseexcept(FE_INVALID); 43 return FP_ILOGB0; /* ilogb(0) = 0x80000001 */ 44 } 45 if (hx == 0) { 46 for (ix = -1043; lx > 0; lx <<= 1) ix -= 1; 47 } else { 48 for (ix = -1022, hx <<= 11; hx > 0; hx <<= 1) ix -= 1; 49 } 50 return ix; 51 } 52 53 if (hx < 0x7ff00000) { 54 return (hx >> 20) - 1023; 55 } 56 57 feraiseexcept(FE_INVALID); 58 return isnan(x) ? FP_ILOGBNAN : INT_MAX; 59 } 60