ReactOS 0.4.17-dev-1321-g5c122a9
pow.c File Reference
#include <math.h>
#include <stdint.h>
#include "libm.h"
#include "exp_data.h"
#include "pow_data.h"
Include dependency graph for pow.c:

Go to the source code of this file.

Macros

#define T   __pow_log_data.tab
 
#define A   __pow_log_data.poly
 
#define Ln2hi   __pow_log_data.ln2hi
 
#define Ln2lo   __pow_log_data.ln2lo
 
#define N   (1 << POW_LOG_TABLE_BITS)
 
#define OFF   0x3fe6955500000000
 
#define N   (1 << EXP_TABLE_BITS)
 
#define InvLn2N   __exp_data.invln2N
 
#define NegLn2hiN   __exp_data.negln2hiN
 
#define NegLn2loN   __exp_data.negln2loN
 
#define Shift   __exp_data.shift
 
#define T   __exp_data.tab
 
#define C2   __exp_data.poly[5 - EXP_POLY_ORDER]
 
#define C3   __exp_data.poly[6 - EXP_POLY_ORDER]
 
#define C4   __exp_data.poly[7 - EXP_POLY_ORDER]
 
#define C5   __exp_data.poly[8 - EXP_POLY_ORDER]
 
#define C6   __exp_data.poly[9 - EXP_POLY_ORDER]
 
#define SIGN_BIAS   (0x800 << EXP_TABLE_BITS)
 

Functions

static uint32_t top12 (double x)
 
static double_t log_inline (uint64_t ix, double_t *tail)
 
static double specialcase (double_t tmp, uint64_t sbits, uint64_t ki)
 
static double exp_inline (double_t x, double_t xtail, uint32_t sign_bias)
 
static int checkint (uint64_t iy)
 
static int zeroinfnan (uint64_t i)
 
double pow (double x, double y)
 

Macro Definition Documentation

◆ A

#define A   __pow_log_data.poly

Definition at line 35 of file pow.c.

◆ C2

#define C2   __exp_data.poly[5 - EXP_POLY_ORDER]

Definition at line 125 of file pow.c.

◆ C3

#define C3   __exp_data.poly[6 - EXP_POLY_ORDER]

Definition at line 126 of file pow.c.

◆ C4

#define C4   __exp_data.poly[7 - EXP_POLY_ORDER]

Definition at line 127 of file pow.c.

◆ C5

#define C5   __exp_data.poly[8 - EXP_POLY_ORDER]

Definition at line 128 of file pow.c.

◆ C6

#define C6   __exp_data.poly[9 - EXP_POLY_ORDER]

Definition at line 129 of file pow.c.

◆ InvLn2N

#define InvLn2N   __exp_data.invln2N

Definition at line 120 of file pow.c.

◆ Ln2hi

#define Ln2hi   __pow_log_data.ln2hi

Definition at line 36 of file pow.c.

◆ Ln2lo

#define Ln2lo   __pow_log_data.ln2lo

Definition at line 37 of file pow.c.

◆ N [1/2]

#define N   (1 << POW_LOG_TABLE_BITS)

Definition at line 119 of file pow.c.

◆ N [2/2]

#define N   (1 << EXP_TABLE_BITS)

Definition at line 119 of file pow.c.

◆ NegLn2hiN

#define NegLn2hiN   __exp_data.negln2hiN

Definition at line 121 of file pow.c.

◆ NegLn2loN

#define NegLn2loN   __exp_data.negln2loN

Definition at line 122 of file pow.c.

◆ OFF

#define OFF   0x3fe6955500000000

Definition at line 39 of file pow.c.

◆ Shift

#define Shift   __exp_data.shift

Definition at line 123 of file pow.c.

◆ SIGN_BIAS

#define SIGN_BIAS   (0x800 << EXP_TABLE_BITS)

Definition at line 176 of file pow.c.

◆ T [1/2]

Definition at line 124 of file pow.c.

◆ T [2/2]

Definition at line 124 of file pow.c.

Function Documentation

◆ checkint()

static int checkint ( uint64_t  iy)
inlinestatic

Definition at line 249 of file pow.c.

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}
#define e
Definition: ke_i.h:82
int iy
Definition: tritemp.h:491

Referenced by pow().

◆ exp_inline()

static double exp_inline ( double_t  x,
double_t  xtail,
uint32_t  sign_bias 
)
inlinestatic

Definition at line 180 of file pow.c.

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}
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
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
#define EXP_TABLE_BITS
Definition: exp_data.h:21
GLint GLint GLint GLint GLint x
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
GLdouble GLdouble z
Definition: glext.h:5874
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
#define predict_false(x)
Definition: libm.h:93
#define WANT_ROUNDING
Definition: libm.h:76
static DNS_RECORDW r2
Definition: record.c:38
#define N
Definition: pow.c:119
#define T
Definition: pow.c:124
#define NegLn2loN
Definition: pow.c:122
#define C5
Definition: pow.c:128
#define C3
Definition: pow.c:126
static double specialcase(double_t tmp, uint64_t sbits, uint64_t ki)
Definition: pow.c:138
#define NegLn2hiN
Definition: pow.c:121
#define InvLn2N
Definition: pow.c:120
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
int one
Definition: sehframes.cpp:28

Referenced by pow().

◆ log_inline()

static double_t log_inline ( uint64_t  ix,
double_t *  tail 
)
inlinestatic

Definition at line 50 of file pow.c.

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}
Definition: ehthrow.cxx:93
static const uint32_t k[]
Definition: sha256.c:24
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLfloat GLfloat p
Definition: glext.h:8902
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 int64_t
Definition: nsiface.idl:57
#define OFF
Definition: pow.c:39
#define Ln2hi
Definition: pow.c:36
#define Ln2lo
Definition: pow.c:37
#define POW_LOG_TABLE_BITS
Definition: pow_data.h:20

Referenced by pow().

◆ pow()

double pow ( double  x,
double  y 
)

This file has no copyright assigned and is placed in the Public Domain. This file is part of the w64 mingw-runtime package. No warranty is given; refer to the file DISCLAIMER.PD within this package.

Definition at line 269 of file pow.c.

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)
#define INFINITY
Definition: math.h:272
#define issignaling_inline(x)
Definition: libm.h:81
static double fp_barrier(double x)
Definition: libm.h:114
static double_t log_inline(uint64_t ix, double_t *tail)
Definition: pow.c:50
#define SIGN_BIAS
Definition: pow.c:176
static int zeroinfnan(uint64_t i)
Definition: pow.c:264
static double exp_inline(double_t x, double_t xtail, uint32_t sign_bias)
Definition: pow.c:180
static int checkint(uint64_t iy)
Definition: pow.c:249
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3710

Referenced by exp2(), exp2f(), powf(), and powl().

◆ specialcase()

static double specialcase ( double_t  tmp,
uint64_t  sbits,
uint64_t  ki 
)
inlinestatic

Definition at line 138 of file pow.c.

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}
_ACRTIMP double __cdecl fabs(double)
static void fp_force_eval(double x)
Definition: libm.h:57

Referenced by exp_inline().

◆ top12()

static uint32_t top12 ( double  x)
inlinestatic

Definition at line 42 of file pow.c.

43{
44 return asuint64(x) >> 52;
45}

Referenced by exp_inline(), and pow().

◆ zeroinfnan()

static int zeroinfnan ( uint64_t  i)
inlinestatic

Definition at line 264 of file pow.c.

265{
266 return 2 * i - 1 >= 2 * asuint64(INFINITY) - 1;
267}

Referenced by pow().