2 * Double-precision 2^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 N (1 << EXP_TABLE_BITS)
15 #define Shift __exp_data.exp2_shift
16 #define T __exp_data.tab
17 #define C1 __exp_data.exp2_poly[0]
18 #define C2 __exp_data.exp2_poly[1]
19 #define C3 __exp_data.exp2_poly[2]
20 #define C4 __exp_data.exp2_poly[3]
21 #define C5 __exp_data.exp2_poly[4]
22 #define C6 __exp_data.exp2_poly[5]
24 /* Handle cases that may overflow or underflow when computing the result that
25 is scale*(1+TMP) without intermediate rounding. The bit representation of
26 scale is in SBITS, however it has a computed exponent that may have
27 overflown into the sign bit so that needs to be adjusted before using it as
28 a double. (int32_t)KI is the k used in the argument reduction and exponent
29 adjustment of scale, positive k here means the result may overflow and
30 negative k means the result may underflow. */
32 specialcase (double_t tmp
, uint64_t sbits
, uint64_t ki
)
36 if ((ki
& 0x80000000) == 0)
38 /* k > 0, the exponent of scale might have overflowed by 1. */
40 scale
= asdouble (sbits
);
41 y
= 2 * (scale
+ scale
* tmp
);
42 return check_oflow (eval_as_double (y
));
44 /* k < 0, need special care in the subnormal range. */
45 sbits
+= 1022ull << 52;
46 scale
= asdouble (sbits
);
47 y
= scale
+ scale
* tmp
;
50 /* Round y to the right precision before scaling it into the subnormal
51 range to avoid double rounding that can cause 0.5+E/2 ulp error where
52 E is the worst-case ulp error outside the subnormal range. So this
53 is only useful if the goal is better than 1 ulp worst-case error. */
55 lo
= scale
- y
+ scale
* tmp
;
57 lo
= 1.0 - hi
+ y
+ lo
;
58 y
= eval_as_double (hi
+ lo
) - 1.0;
59 /* Avoid -0.0 with downward rounding. */
60 if (WANT_ROUNDING
&& y
== 0.0)
62 /* The underflow exception needs to be signaled explicitly. */
63 force_eval_double (opt_barrier_double (0x1p
-1022) * 0x1p
-1022);
66 return check_uflow (eval_as_double (y
));
69 /* Top 12 bits of a double (sign and exponent bits). */
70 static inline uint32_t
73 return asuint64 (x
) >> 52;
80 uint64_t ki
, idx
, top
, sbits
;
81 /* double_t for better performance on targets with FLT_EVAL_METHOD==2. */
82 double_t kd
, r
, r2
, scale
, tail
, tmp
;
84 abstop
= top12 (x
) & 0x7ff;
85 if (unlikely (abstop
- top12 (0x1p
-54) >= top12 (512.0) - top12 (0x1p
-54)))
87 if (abstop
- top12 (0x1p
-54) >= 0x80000000)
88 /* Avoid spurious underflow for tiny x. */
89 /* Note: 0 is common input. */
90 return WANT_ROUNDING
? 1.0 + x
: 1.0;
91 if (abstop
>= top12 (1024.0))
93 if (asuint64 (x
) == asuint64 (-INFINITY
))
95 if (abstop
>= top12 (INFINITY
))
97 if (!(asuint64 (x
) >> 63))
98 return __math_oflow (0);
99 else if (asuint64 (x
) >= asuint64 (-1075.0))
100 return __math_uflow (0);
102 if (2 * asuint64 (x
) > 2 * asuint64 (928.0))
103 /* Large x is special cased below. */
107 /* exp2(x) = 2^(k/N) * 2^r, with 2^r in [2^(-1/2N),2^(1/2N)]. */
108 /* x = k/N + r, with int k and r in [-1/2N, 1/2N]. */
109 kd
= eval_as_double (x
+ Shift
);
110 ki
= asuint64 (kd
); /* k. */
111 kd
-= Shift
; /* k/N for int k. */
113 /* 2^(k/N) ~= scale * (1 + tail). */
115 top
= ki
<< (52 - EXP_TABLE_BITS
);
116 tail
= asdouble (T
[idx
]);
117 /* This is only a valid scale when -1023*N < k < 1024*N. */
118 sbits
= T
[idx
+ 1] + top
;
119 /* exp2(x) = 2^(k/N) * 2^r ~= scale + scale * (tail + 2^r - 1). */
120 /* Evaluation is optimized assuming superscalar pipelined execution. */
122 /* Without fma the worst case error is 0.5/N ulp larger. */
123 /* Worst case error is less than 0.5+0.86/N+(abs poly error * 2^53) ulp. */
124 #if EXP2_POLY_ORDER == 4
125 tmp
= tail
+ r
* C1
+ r2
* C2
+ r
* r2
* (C3
+ r
* C4
);
126 #elif EXP2_POLY_ORDER == 5
127 tmp
= tail
+ r
* C1
+ r2
* (C2
+ r
* C3
) + r2
* r2
* (C4
+ r
* C5
);
128 #elif EXP2_POLY_ORDER == 6
129 tmp
= tail
+ r
* C1
+ r2
* (0.5 + r
* C3
) + r2
* r2
* (C4
+ r
* C5
+ r2
* C6
);
131 if (unlikely (abstop
== 0))
132 return specialcase (tmp
, sbits
, ki
);
133 scale
= asdouble (sbits
);
134 /* Note: tmp == 0 or |tmp| > 2^-65 and scale > 2^-928, so there
135 is no spurious underflow here even without fma. */
136 return eval_as_double (scale
+ scale
* tmp
);
139 strong_alias (exp2
, __exp2_finite
)
140 hidden_alias (exp2
, __ieee754_exp2
)
141 # if LDBL_MANT_DIG == 53
142 long double exp2l (long double x
) { return exp2 (x
); }