ReactOS 0.4.17-dev-1321-g5c122a9
pow.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS CRT
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Implementation of pow.
5 * COPYRIGHT: Imported from musl libc
6 * https://git.musl-libc.org/cgit/musl/tree/src/math/pow.c
7 * blob: 694c2ef64d008cf78696a6d660353e83792d22f3
8 * See https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
9 */
10
11/*
12 * Double-precision x^y function.
13 *
14 * Copyright (c) 2018, Arm Limited.
15 * SPDX-License-Identifier: MIT
16 */
17
18#include <math.h>
19#include <stdint.h>
20#include "libm.h"
21#include "exp_data.h"
22#include "pow_data.h"
23
24#ifdef _MSC_VER
25#pragma function(pow)
26#endif
27
28/*
29Worst-case error: 0.54 ULP (~= ulperr_exp + 1024*Ln2*relerr_log*2^53)
30relerr_log: 1.3 * 2^-68 (Relative error of log, 1.5 * 2^-68 without fma)
31ulperr_exp: 0.509 ULP (ULP error of exp, 0.511 ULP without fma)
32*/
33
34#define T __pow_log_data.tab
35#define A __pow_log_data.poly
36#define Ln2hi __pow_log_data.ln2hi
37#define Ln2lo __pow_log_data.ln2lo
38#define N (1 << POW_LOG_TABLE_BITS)
39#define OFF 0x3fe6955500000000
40
41/* Top 12 bits of a double (sign and exponent bits). */
42static inline uint32_t top12(double x)
43{
44 return asuint64(x) >> 52;
45}
46
47/* Compute y+TAIL = log(x) where the rounded result is y and TAIL has about
48 additional 15 bits precision. IX is the bit representation of x, but
49 normalized in the subnormal range using the sign bit for the exponent. */
51{
52 /* double_t for better performance on targets with FLT_EVAL_METHOD==2. */
53 double_t z, r, y, invc, logc, logctail, kd, hi, t1, t2, lo, lo1, lo2, p;
54 uint64_t iz, tmp;
55 int k, i;
56
57 /* x = 2^k z; where z is in range [OFF,2*OFF) and exact.
58 The range is split into N subintervals.
59 The ith subinterval contains z and c is near its center. */
60 tmp = ix - OFF;
61 i = (tmp >> (52 - POW_LOG_TABLE_BITS)) % N;
62 k = (int64_t)tmp >> 52; /* arithmetic shift */
63 iz = ix - (tmp & 0xfffULL << 52);
64 z = asdouble(iz);
65 kd = (double_t)k;
66
67 /* log(x) = k*Ln2 + log(c) + log1p(z/c-1). */
68 invc = T[i].invc;
69 logc = T[i].logc;
70 logctail = T[i].logctail;
71
72 /* Note: 1/c is j/N or j/N/2 where j is an integer in [N,2N) and
73 |z/c - 1| < 1/N, so r = z/c - 1 is exactly representible. */
74#if __FP_FAST_FMA
75 r = __builtin_fma(z, invc, -1.0);
76#else
77 /* Split z such that rhi, rlo and rhi*rhi are exact and |rlo| <= |r|. */
78 double_t zhi = asdouble((iz + (1ULL << 31)) & (-1ULL << 32));
79 double_t zlo = z - zhi;
80 double_t rhi = zhi * invc - 1.0;
81 double_t rlo = zlo * invc;
82 r = rhi + rlo;
83#endif
84
85 /* k*Ln2 + log(c) + r. */
86 t1 = kd * Ln2hi + logc;
87 t2 = t1 + r;
88 lo1 = kd * Ln2lo + logctail;
89 lo2 = t1 - t2 + r;
90
91 /* Evaluation is optimized assuming superscalar pipelined execution. */
92 double_t ar, ar2, ar3, lo3, lo4;
93 ar = A[0] * r; /* A[0] = -0.5. */
94 ar2 = r * ar;
95 ar3 = r * ar2;
96 /* k*Ln2 + log(c) + r + A[0]*r*r. */
97#if __FP_FAST_FMA
98 hi = t2 + ar2;
99 lo3 = __builtin_fma(ar, r, -ar2);
100 lo4 = t2 - hi + ar2;
101#else
102 double_t arhi = A[0] * rhi;
103 double_t arhi2 = rhi * arhi;
104 hi = t2 + arhi2;
105 lo3 = rlo * (ar + arhi);
106 lo4 = t2 - hi + arhi2;
107#endif
108 /* p = log1p(r) - r - A[0]*r*r. */
109 p = (ar3 * (A[1] + r * A[2] +
110 ar2 * (A[3] + r * A[4] + ar2 * (A[5] + r * A[6]))));
111 lo = lo1 + lo2 + lo3 + lo4 + p;
112 y = hi + lo;
113 *tail = hi - y + lo;
114 return y;
115}
116
117#undef N
118#undef T
119#define N (1 << EXP_TABLE_BITS)
120#define InvLn2N __exp_data.invln2N
121#define NegLn2hiN __exp_data.negln2hiN
122#define NegLn2loN __exp_data.negln2loN
123#define Shift __exp_data.shift
124#define T __exp_data.tab
125#define C2 __exp_data.poly[5 - EXP_POLY_ORDER]
126#define C3 __exp_data.poly[6 - EXP_POLY_ORDER]
127#define C4 __exp_data.poly[7 - EXP_POLY_ORDER]
128#define C5 __exp_data.poly[8 - EXP_POLY_ORDER]
129#define C6 __exp_data.poly[9 - EXP_POLY_ORDER]
130
131/* Handle cases that may overflow or underflow when computing the result that
132 is scale*(1+TMP) without intermediate rounding. The bit representation of
133 scale is in SBITS, however it has a computed exponent that may have
134 overflown into the sign bit so that needs to be adjusted before using it as
135 a double. (int32_t)KI is the k used in the argument reduction and exponent
136 adjustment of scale, positive k here means the result may overflow and
137 negative k means the result may underflow. */
138static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki)
139{
141
142 if ((ki & 0x80000000) == 0) {
143 /* k > 0, the exponent of scale might have overflowed by <= 460. */
144 sbits -= 1009ull << 52;
145 scale = asdouble(sbits);
146 y = 0x1p1009 * (scale + scale * tmp);
147 return eval_as_double(y);
148 }
149 /* k < 0, need special care in the subnormal range. */
150 sbits += 1022ull << 52;
151 /* Note: sbits is signed scale. */
152 scale = asdouble(sbits);
153 y = scale + scale * tmp;
154 if (fabs(y) < 1.0) {
155 /* Round y to the right precision before scaling it into the subnormal
156 range to avoid double rounding that can cause 0.5+E/2 ulp error where
157 E is the worst-case ulp error outside the subnormal range. So this
158 is only useful if the goal is better than 1 ulp worst-case error. */
159 double_t hi, lo, one = 1.0;
160 if (y < 0.0)
161 one = -1.0;
162 lo = scale - y + scale * tmp;
163 hi = one + y;
164 lo = one - hi + y + lo;
165 y = eval_as_double(hi + lo) - one;
166 /* Fix the sign of 0. */
167 if (y == 0.0)
168 y = asdouble(sbits & 0x8000000000000000);
169 /* The underflow exception needs to be signaled explicitly. */
170 fp_force_eval(fp_barrier(0x1p-1022) * 0x1p-1022);
171 }
172 y = 0x1p-1022 * y;
173 return eval_as_double(y);
174}
175
176#define SIGN_BIAS (0x800 << EXP_TABLE_BITS)
177
178/* Computes sign*exp(x+xtail) where |xtail| < 2^-8/N and |xtail| <= |x|.
179 The sign_bias argument is SIGN_BIAS or 0 and sets the sign to -1 or 1. */
180static inline double exp_inline(double_t x, double_t xtail, uint32_t sign_bias)
181{
182 uint32_t abstop;
183 uint64_t ki, idx, top, sbits;
184 /* double_t for better performance on targets with FLT_EVAL_METHOD==2. */
185 double_t kd, z, r, r2, scale, tail, tmp;
186
187 abstop = top12(x) & 0x7ff;
188 if (predict_false(abstop - top12(0x1p-54) >=
189 top12(512.0) - top12(0x1p-54))) {
190 if (abstop - top12(0x1p-54) >= 0x80000000) {
191 /* Avoid spurious underflow for tiny x. */
192 /* Note: 0 is common input. */
193 double_t one = WANT_ROUNDING ? 1.0 + x : 1.0;
194 return sign_bias ? -one : one;
195 }
196 if (abstop >= top12(1024.0)) {
197 /* Note: inf and nan are already handled. */
198 if (asuint64(x) >> 63)
199 return __math_uflow(sign_bias);
200 else
201 return __math_oflow(sign_bias);
202 }
203 /* Large x is special cased below. */
204 abstop = 0;
205 }
206
207 /* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]. */
208 /* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]. */
209 z = InvLn2N * x;
210#if TOINT_INTRINSICS
211 kd = roundtoint(z);
212 ki = converttoint(z);
213#elif EXP_USE_TOINT_NARROW
214 /* z - kd is in [-0.5-2^-16, 0.5] in all rounding modes. */
215 kd = eval_as_double(z + Shift);
216 ki = asuint64(kd) >> 16;
217 kd = (double_t)(int32_t)ki;
218#else
219 /* z - kd is in [-1, 1] in non-nearest rounding modes. */
220 kd = eval_as_double(z + Shift);
221 ki = asuint64(kd);
222 kd -= Shift;
223#endif
224 r = x + kd * NegLn2hiN + kd * NegLn2loN;
225 /* The code assumes 2^-200 < |xtail| < 2^-8/N. */
226 r += xtail;
227 /* 2^(k/N) ~= scale * (1 + tail). */
228 idx = 2 * (ki % N);
229 top = (ki + sign_bias) << (52 - EXP_TABLE_BITS);
230 tail = asdouble(T[idx]);
231 /* This is only a valid scale when -1023*N < k < 1024*N. */
232 sbits = T[idx + 1] + top;
233 /* exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1). */
234 /* Evaluation is optimized assuming superscalar pipelined execution. */
235 r2 = r * r;
236 /* Without fma the worst case error is 0.25/N ulp larger. */
237 /* Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp. */
238 tmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);
239 if (predict_false(abstop == 0))
240 return specialcase(tmp, sbits, ki);
241 scale = asdouble(sbits);
242 /* Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there
243 is no spurious underflow here even without fma. */
244 return eval_as_double(scale + scale * tmp);
245}
246
247/* Returns 0 if not int, 1 if odd int, 2 if even int. The argument is
248 the bit representation of a non-zero finite floating-point value. */
249static inline int checkint(uint64_t iy)
250{
251 int e = iy >> 52 & 0x7ff;
252 if (e < 0x3ff)
253 return 0;
254 if (e > 0x3ff + 52)
255 return 2;
256 if (iy & ((1ULL << (0x3ff + 52 - e)) - 1))
257 return 0;
258 if (iy & (1ULL << (0x3ff + 52 - e)))
259 return 1;
260 return 2;
261}
262
263/* Returns 1 if input is the bit representation of 0, infinity or nan. */
264static inline int zeroinfnan(uint64_t i)
265{
266 return 2 * i - 1 >= 2 * asuint64(INFINITY) - 1;
267}
268
269double pow(double x, double y)
270{
271 uint32_t sign_bias = 0;
272 uint64_t ix, iy;
273 uint32_t topx, topy;
274
275 ix = asuint64(x);
276 iy = asuint64(y);
277 topx = top12(x);
278 topy = top12(y);
279 if (predict_false(topx - 0x001 >= 0x7ff - 0x001 ||
280 (topy & 0x7ff) - 0x3be >= 0x43e - 0x3be)) {
281 /* Note: if |y| > 1075 * ln2 * 2^53 ~= 0x1.749p62 then pow(x,y) = inf/0
282 and if |y| < 2^-54 / 1075 ~= 0x1.e7b6p-65 then pow(x,y) = +-1. */
283 /* Special cases: (x < 0x1p-126 or inf or nan) or
284 (|y| < 0x1p-65 or |y| >= 0x1p63 or nan). */
286 if (2 * iy == 0)
287 return issignaling_inline(x) ? x + y : 1.0;
288 if (ix == asuint64(1.0))
289 return issignaling_inline(y) ? x + y : 1.0;
290 if (2 * ix > 2 * asuint64(INFINITY) ||
291 2 * iy > 2 * asuint64(INFINITY))
292 return x + y;
293 if (2 * ix == 2 * asuint64(1.0))
294 return 1.0;
295 if ((2 * ix < 2 * asuint64(1.0)) == !(iy >> 63))
296 return 0.0; /* |x|<1 && y==inf or |x|>1 && y==-inf. */
297 return y * y;
298 }
299 if (predict_false(zeroinfnan(ix))) {
300 double_t x2 = x * x;
301 if (ix >> 63 && checkint(iy) == 1)
302 x2 = -x2;
303 /* Without the barrier some versions of clang hoist the 1/x2 and
304 thus division by zero exception can be signaled spuriously. */
305 return iy >> 63 ? fp_barrier(1 / x2) : x2;
306 }
307 /* Here x and y are non-zero finite. */
308 if (ix >> 63) {
309 /* Finite x < 0. */
310 int yint = checkint(iy);
311 if (yint == 0)
312 return __math_invalid(x);
313 if (yint == 1)
314 sign_bias = SIGN_BIAS;
315 ix &= 0x7fffffffffffffff;
316 topx &= 0x7ff;
317 }
318 if ((topy & 0x7ff) - 0x3be >= 0x43e - 0x3be) {
319 /* Note: sign_bias == 0 here because y is not odd. */
320 if (ix == asuint64(1.0))
321 return 1.0;
322 if ((topy & 0x7ff) < 0x3be) {
323 /* |y| < 2^-65, x^y ~= 1 + y*log(x). */
324 if (WANT_ROUNDING)
325 return ix > asuint64(1.0) ? 1.0 + y :
326 1.0 - y;
327 else
328 return 1.0;
329 }
330 return (ix > asuint64(1.0)) == (topy < 0x800) ?
331 __math_oflow(0) :
332 __math_uflow(0);
333 }
334 if (topx == 0) {
335 /* Normalize subnormal x so exponent becomes negative. */
336 ix = asuint64(x * 0x1p52);
337 ix &= 0x7fffffffffffffff;
338 ix -= 52ULL << 52;
339 }
340 }
341
342 double_t lo;
343 double_t hi = log_inline(ix, &lo);
344 double_t ehi, elo;
345#if __FP_FAST_FMA
346 ehi = y * hi;
347 elo = y * lo + __builtin_fma(y, hi, -ehi);
348#else
349 double_t yhi = asdouble(iy & -1ULL << 27);
350 double_t ylo = y - yhi;
351 double_t lhi = asdouble(asuint64(hi) & -1ULL << 27);
352 double_t llo = hi - lhi + lo;
353 ehi = yhi * lhi;
354 elo = ylo * lhi + y * llo; /* |elo| < |ehi| * 2^-25. */
355#endif
356 return exp_inline(ehi, elo, sign_bias);
357}
double __math_invalid(double x)
double __math_oflow(uint32_t sign)
Definition: __math_oflow.c:13
double __math_uflow(uint32_t sign)
Definition: __math_uflow.c:13
struct outqueuenode * tail
Definition: adnsresfilter.c:66
Definition: ehthrow.cxx:93
INT32 int32_t
Definition: types.h:71
UINT32 uint32_t
Definition: types.h:75
UINT64 uint64_t
Definition: types.h:77
unsigned int idx
Definition: utils.c:40
_ACRTIMP double __cdecl fabs(double)
#define INFINITY
Definition: math.h:272
static const uint32_t k[]
Definition: sha256.c:24
#define EXP_TABLE_BITS
Definition: exp_data.h:21
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLfloat GLfloat p
Definition: glext.h:8902
GLdouble GLdouble z
Definition: glext.h:5874
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define e
Definition: ke_i.h:82
#define issignaling_inline(x)
Definition: libm.h:81
static double asdouble(uint64_t i)
Definition: libm.h:142
static uint64_t asuint64(double f)
Definition: libm.h:135
static double eval_as_double(double x)
Definition: libm.h:102
static void fp_force_eval(double x)
Definition: libm.h:57
static double fp_barrier(double x)
Definition: libm.h:114
#define predict_false(x)
Definition: libm.h:93
#define WANT_ROUNDING
Definition: libm.h:76
static DNS_RECORDW r2
Definition: record.c:38
#define int64_t
Definition: nsiface.idl:57
#define N
Definition: pow.c:119
#define T
Definition: pow.c:124
static double_t log_inline(uint64_t ix, double_t *tail)
Definition: pow.c:50
#define NegLn2loN
Definition: pow.c:122
#define OFF
Definition: pow.c:39
#define SIGN_BIAS
Definition: pow.c:176
#define C5
Definition: pow.c:128
#define Ln2hi
Definition: pow.c:36
#define C3
Definition: pow.c:126
static double specialcase(double_t tmp, uint64_t sbits, uint64_t ki)
Definition: pow.c:138
#define Ln2lo
Definition: pow.c:37
#define NegLn2hiN
Definition: pow.c:121
static int zeroinfnan(uint64_t i)
Definition: pow.c:264
#define InvLn2N
Definition: pow.c:120
static double exp_inline(double_t x, double_t xtail, uint32_t sign_bias)
Definition: pow.c:180
double pow(double x, double y)
Definition: pow.c:269
static int checkint(uint64_t iy)
Definition: pow.c:249
static uint32_t top12(double x)
Definition: pow.c:42
#define C4
Definition: pow.c:127
#define C2
Definition: pow.c:125
#define Shift
Definition: pow.c:123
#define POW_LOG_TABLE_BITS
Definition: pow_data.h:20
int one
Definition: sehframes.cpp:28
int iy
Definition: tritemp.h:491
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3710