2 * Double-precision log(x) function.
4 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 * See https://llvm.org/LICENSE.txt for license information.
6 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
12 #include "math_config.h"
14 #define T __log_data.tab
15 #define T2 __log_data.tab2
16 #define B __log_data.poly1
17 #define A __log_data.poly
18 #define Ln2hi __log_data.ln2hi
19 #define Ln2lo __log_data.ln2lo
20 #define N (1 << LOG_TABLE_BITS)
21 #define OFF 0x3fe6000000000000
23 /* Top 16 bits of a double. */
24 static inline uint32_t
27 return asuint64 (x
) >> 48;
33 /* double_t for better performance on targets with FLT_EVAL_METHOD==2. */
34 double_t w
, z
, r
, r2
, r3
, y
, invc
, logc
, kd
, hi
, lo
;
42 #if LOG_POLY1_ORDER == 10 || LOG_POLY1_ORDER == 11
43 # define LO asuint64 (1.0 - 0x1p-5)
44 # define HI asuint64 (1.0 + 0x1.1p-5)
45 #elif LOG_POLY1_ORDER == 12
46 # define LO asuint64 (1.0 - 0x1p-4)
47 # define HI asuint64 (1.0 + 0x1.09p-4)
49 if (unlikely (ix
- LO
< HI
- LO
))
51 /* Handle close to 1.0 inputs separately. */
52 /* Fix sign of zero with downward rounding when x==1. */
53 if (WANT_ROUNDING
&& unlikely (ix
== asuint64 (1.0)))
58 #if LOG_POLY1_ORDER == 10
59 /* Worst-case error is around 0.516 ULP. */
60 y
= r3
* (B
[1] + r
* B
[2] + r2
* B
[3]
61 + r3
* (B
[4] + r
* B
[5] + r2
* B
[6] + r3
* (B
[7] + r
* B
[8])));
62 w
= B
[0] * r2
; /* B[0] == -0.5. */
66 #elif LOG_POLY1_ORDER == 11
67 /* Worst-case error is around 0.516 ULP. */
68 y
= r3
* (B
[1] + r
* B
[2]
69 + r2
* (B
[3] + r
* B
[4] + r2
* B
[5]
70 + r3
* (B
[6] + r
* B
[7] + r2
* B
[8] + r3
* B
[9])));
71 w
= B
[0] * r2
; /* B[0] == -0.5. */
75 #elif LOG_POLY1_ORDER == 12
76 y
= r3
* (B
[1] + r
* B
[2] + r2
* B
[3]
77 + r3
* (B
[4] + r
* B
[5] + r2
* B
[6]
78 + r3
* (B
[7] + r
* B
[8] + r2
* B
[9] + r3
* B
[10])));
80 /* Worst-case error is around 0.532 ULP. */
81 w
= B
[0] * r2
; /* B[0] == -0.5. */
86 /* Worst-case error is around 0.507 ULP. */
88 double_t rhi
= r
+ w
- w
;
89 double_t rlo
= r
- rhi
;
90 w
= rhi
* rhi
* B
[0]; /* B[0] == -0.5. */
93 lo
+= B
[0] * rlo
* (rhi
+ r
);
98 return eval_as_double (y
);
100 if (unlikely (top
- 0x0010 >= 0x7ff0 - 0x0010))
102 /* x < 0x1p-1022 or inf or nan. */
104 return __math_divzero (1);
105 if (ix
== asuint64 (INFINITY
)) /* log(inf) == inf. */
107 if ((top
& 0x8000) || (top
& 0x7ff0) == 0x7ff0)
108 return __math_invalid (x
);
109 /* x is subnormal, normalize it. */
110 ix
= asuint64 (x
* 0x1p
52);
114 /* x = 2^k z; where z is in range [OFF,2*OFF) and exact.
115 The range is split into N subintervals.
116 The ith subinterval contains z and c is near its center. */
118 i
= (tmp
>> (52 - LOG_TABLE_BITS
)) % N
;
119 k
= (int64_t) tmp
>> 52; /* arithmetic shift */
120 iz
= ix
- (tmp
& 0xfffULL
<< 52);
125 /* log(x) = log1p(z/c-1) + log(c) + k*Ln2. */
126 /* r ~= z/c - 1, |r| < 1/(2*N). */
128 /* rounding error: 0x1p-55/N. */
129 r
= fma (z
, invc
, -1.0);
131 /* rounding error: 0x1p-55/N + 0x1p-66. */
132 r
= (z
- T2
[i
].chi
- T2
[i
].clo
) * invc
;
136 /* hi + lo = r + log(c) + k*Ln2. */
137 w
= kd
* Ln2hi
+ logc
;
139 lo
= w
- hi
+ r
+ kd
* Ln2lo
;
141 /* log(x) = lo + (log1p(r) - r) + hi. */
142 r2
= r
* r
; /* rounding error: 0x1p-54/N^2. */
143 /* Worst case error if |y| > 0x1p-5:
144 0.5 + 4.13/N + abs-poly-error*2^57 ULP (+ 0.002 ULP without fma)
145 Worst case error if |y| > 0x1p-4:
146 0.5 + 2.06/N + abs-poly-error*2^56 ULP (+ 0.001 ULP without fma). */
147 #if LOG_POLY_ORDER == 6
148 y
= lo
+ r2
* A
[0] + r
* r2
* (A
[1] + r
* A
[2] + r2
* (A
[3] + r
* A
[4])) + hi
;
149 #elif LOG_POLY_ORDER == 7
151 + r2
* (A
[0] + r
* A
[1] + r2
* (A
[2] + r
* A
[3])
152 + r2
* r2
* (A
[4] + r
* A
[5]))
155 return eval_as_double (y
);
158 strong_alias (log
, __log_finite
)
159 hidden_alias (log
, __ieee754_log
)
160 # if LDBL_MANT_DIG == 53
161 long double logl (long double x
) { return log (x
); }