1 2 /* @(#)s_ilogb.c 5.1 93/09/24 */ 3 /* 4 * ==================================================== 5 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 6 * 7 * Developed at SunPro, a Sun Microsystems, Inc. business. 8 * Permission to use, copy, modify, and distribute this 9 * software is freely granted, provided that this notice 10 * is preserved. 11 * ==================================================== 12 */ 13 14 /* 15 FUNCTION 16 <<ilogb>>, <<ilogbf>>---get exponent of floating-point number 17 INDEX 18 ilogb 19 INDEX 20 ilogbf 21 22 SYNOPSIS 23 #include <math.h> 24 int ilogb(double <[val]>); 25 int ilogbf(float <[val]>); 26 27 DESCRIPTION 28 29 All nonzero, normal numbers can be described as <[m]> * 30 2**<[p]>. <<ilogb>> and <<ilogbf>> examine the argument 31 <[val]>, and return <[p]>. The functions <<frexp>> and 32 <<frexpf>> are similar to <<ilogb>> and <<ilogbf>>, but also 33 return <[m]>. 34 35 RETURNS 36 37 <<ilogb>> and <<ilogbf>> return the power of two used to form the 38 floating-point argument. 39 If <[val]> is <<0>>, they return <<FP_ILOGB0>>. 40 If <[val]> is infinite, they return <<INT_MAX>>. 41 If <[val]> is NaN, they return <<FP_ILOGBNAN>>. 42 (<<FP_ILOGB0>> and <<FP_ILOGBNAN>> are defined in math.h, but in turn are 43 defined as INT_MIN or INT_MAX from limits.h. The value of FP_ILOGB0 may be 44 either INT_MIN or -INT_MAX. The value of FP_ILOGBNAN may be either INT_MAX or 45 INT_MIN.) 46 47 @comment The bugs might not be worth noting, given the mass non-C99/POSIX 48 @comment behavior of much of the Newlib math library. 49 @comment BUGS 50 @comment On errors, errno is not set per C99 and POSIX requirements even if 51 @comment (math_errhandling & MATH_ERRNO) is non-zero. 52 53 PORTABILITY 54 C99, POSIX 55 */ 56 57 /* ilogb(double x) 58 * return the binary exponent of non-zero x 59 * ilogb(0) = 0x80000001 60 * ilogb(inf/NaN) = 0x7fffffff (no signal is raised) 61 */ 62 63 #include <limits.h> 64 #include "fdlibm.h" 65 66 #ifndef _DOUBLE_IS_32BITS 67 68 #ifdef __STDC__ ilogb(double x)69 int ilogb(double x) 70 #else 71 int ilogb(x) 72 double x; 73 #endif 74 { 75 __int32_t hx,lx,ix; 76 77 EXTRACT_WORDS(hx,lx,x); 78 hx &= 0x7fffffff; 79 if(hx<0x00100000) { 80 if((hx|lx)==0) 81 return FP_ILOGB0; /* ilogb(0) = special case error */ 82 else /* subnormal x */ 83 if(hx==0) { 84 for (ix = -1043; lx>0; lx<<=1) ix -=1; 85 } else { 86 for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1; 87 } 88 return ix; 89 } 90 else if (hx<0x7ff00000) return (hx>>20)-1023; 91 #if FP_ILOGBNAN != INT_MAX 92 else if (hx>0x7ff00000) return FP_ILOGBNAN; /* NAN */ 93 #endif 94 else return INT_MAX; /* infinite (or, possibly, NAN) */ 95 } 96 97 #endif /* _DOUBLE_IS_32BITS */ 98