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__ |
---|
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 */ |
---|