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.16 2016/08/26 08:20:31 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 #define __TEST_FENV 26 #include <fenv.h> 27 #ifndef __HAVE_FENV 28 #define feraiseexcept(a) 29 #endif 30 #include "math_private.h" 31 32 #ifndef __HAVE_LONG_DOUBLE 33 __strong_alias(ilogbl,ilogb) 34 #endif 35 36 int 37 ilogb(double x) 38 { 39 int32_t hx, lx, ix; 40 41 GET_HIGH_WORD(hx, x); 42 hx &= 0x7fffffff; 43 if (hx < 0x00100000) { 44 GET_LOW_WORD(lx, x); 45 if ((hx | lx) == 0) { 46 feraiseexcept(FE_INVALID); 47 return FP_ILOGB0; /* ilogb(0) = 0x80000001 */ 48 } 49 if (hx == 0) { 50 for (ix = -1043; lx > 0; lx <<= 1) ix -= 1; 51 } else { 52 for (ix = -1022, hx <<= 11; hx > 0; hx <<= 1) ix -= 1; 53 } 54 return ix; 55 } 56 57 if (hx < 0x7ff00000) { 58 return (hx >> 20) - 1023; 59 } 60 61 feraiseexcept(FE_INVALID); 62 return isnan(x) ? FP_ILOGBNAN : INT_MAX; 63 } 64