1 |
|
|
/* @(#)e_log.c 1.3 95/01/18 */ |
2 |
|
|
/* |
3 |
|
|
* ==================================================== |
4 |
|
|
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
5 |
|
|
* |
6 |
|
|
* Developed at SunSoft, 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 <float.h> |
14 |
|
|
#include <math.h> |
15 |
|
|
|
16 |
|
|
#include "math_private.h" |
17 |
|
|
|
18 |
|
|
static const double |
19 |
|
|
ln2 = 0.6931471805599452862268, |
20 |
|
|
two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ |
21 |
|
|
Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ |
22 |
|
|
Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ |
23 |
|
|
Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ |
24 |
|
|
Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ |
25 |
|
|
Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ |
26 |
|
|
Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ |
27 |
|
|
Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ |
28 |
|
|
|
29 |
|
|
static const double zero = 0.0; |
30 |
|
|
|
31 |
|
|
double |
32 |
|
|
log2(double x) |
33 |
|
|
{ |
34 |
|
|
double hfsq,f,s,z,R,w,t1,t2,dk; |
35 |
|
|
int32_t k,hx,i,j; |
36 |
|
|
u_int32_t lx; |
37 |
|
|
|
38 |
|
|
EXTRACT_WORDS(hx,lx,x); |
39 |
|
|
|
40 |
|
|
k=0; |
41 |
|
|
if (hx < 0x00100000) { /* x < 2**-1022 */ |
42 |
|
|
if (((hx&0x7fffffff)|lx)==0) |
43 |
|
|
return -two54/zero; /* log(+-0)=-inf */ |
44 |
|
|
if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ |
45 |
|
|
k -= 54; x *= two54; /* subnormal number, scale up x */ |
46 |
|
|
GET_HIGH_WORD(hx,x); |
47 |
|
|
} |
48 |
|
|
if (hx >= 0x7ff00000) return x+x; |
49 |
|
|
k += (hx>>20)-1023; |
50 |
|
|
hx &= 0x000fffff; |
51 |
|
|
i = (hx+0x95f64)&0x100000; |
52 |
|
|
SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */ |
53 |
|
|
k += (i>>20); |
54 |
|
|
f = x-1.0; |
55 |
|
|
dk = (double)k; |
56 |
|
|
if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */ |
57 |
|
|
if (f==zero) |
58 |
|
|
return (dk); |
59 |
|
|
R = f*f*(0.5-0.33333333333333333*f); |
60 |
|
|
return (dk-(R-f)/ln2); |
61 |
|
|
} |
62 |
|
|
s = f/(2.0+f); |
63 |
|
|
z = s*s; |
64 |
|
|
i = hx-0x6147a; |
65 |
|
|
w = z*z; |
66 |
|
|
j = 0x6b851-hx; |
67 |
|
|
t1= w*(Lg2+w*(Lg4+w*Lg6)); |
68 |
|
|
t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); |
69 |
|
|
i |= j; |
70 |
|
|
R = t2+t1; |
71 |
|
|
if(i>0) { |
72 |
|
|
hfsq=0.5*f*f; |
73 |
|
|
return (dk-(hfsq-s*(hfsq+R)-f)/ln2); |
74 |
|
|
} else |
75 |
|
|
return (dk-((s*(f-R))-f)/ln2); |
76 |
|
|
} |
77 |
|
|
DEF_STD(log2); |
78 |
|
|
LDBL_MAYBE_UNUSED_CLONE(log2); |