e_powl.c revision 1.1 1 1.1 christos /*-
2 1.1 christos * Copyright (c) 2008 Stephen L. Moshier <steve (at) moshier.net>
3 1.1 christos *
4 1.1 christos * Permission to use, copy, modify, and distribute this software for any
5 1.1 christos * purpose with or without fee is hereby granted, provided that the above
6 1.1 christos * copyright notice and this permission notice appear in all copies.
7 1.1 christos *
8 1.1 christos * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 1.1 christos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 1.1 christos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 1.1 christos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 1.1 christos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 1.1 christos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 1.1 christos * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 1.1 christos */
16 1.1 christos
17 1.1 christos #include <sys/cdefs.h>
18 1.1 christos #include <math.h>
19 1.1 christos
20 1.1 christos #include "math_private.h"
21 1.1 christos
22 1.1 christos /*
23 1.1 christos * Polynomial evaluator:
24 1.1 christos * P[0] x^n + P[1] x^(n-1) + ... + P[n]
25 1.1 christos */
26 1.1 christos static inline long double
27 1.1 christos __polevll(long double x, long double *PP, int n)
28 1.1 christos {
29 1.1 christos long double y;
30 1.1 christos long double *P;
31 1.1 christos
32 1.1 christos P = PP;
33 1.1 christos y = *P++;
34 1.1 christos do {
35 1.1 christos y = y * x + *P++;
36 1.1 christos } while (--n);
37 1.1 christos
38 1.1 christos return (y);
39 1.1 christos }
40 1.1 christos
41 1.1 christos /*
42 1.1 christos * Polynomial evaluator:
43 1.1 christos * x^n + P[0] x^(n-1) + P[1] x^(n-2) + ... + P[n]
44 1.1 christos */
45 1.1 christos static inline long double
46 1.1 christos __p1evll(long double x, long double *PP, int n)
47 1.1 christos {
48 1.1 christos long double y;
49 1.1 christos long double *P;
50 1.1 christos
51 1.1 christos P = PP;
52 1.1 christos n -= 1;
53 1.1 christos y = x + *P++;
54 1.1 christos do {
55 1.1 christos y = y * x + *P++;
56 1.1 christos } while (--n);
57 1.1 christos
58 1.1 christos return (y);
59 1.1 christos }
60 1.1 christos
61 1.1 christos /* powl.c
62 1.1 christos *
63 1.1 christos * Power function, long double precision
64 1.1 christos *
65 1.1 christos *
66 1.1 christos *
67 1.1 christos * SYNOPSIS:
68 1.1 christos *
69 1.1 christos * long double x, y, z, powl();
70 1.1 christos *
71 1.1 christos * z = powl( x, y );
72 1.1 christos *
73 1.1 christos *
74 1.1 christos *
75 1.1 christos * DESCRIPTION:
76 1.1 christos *
77 1.1 christos * Computes x raised to the yth power. Analytically,
78 1.1 christos *
79 1.1 christos * x**y = exp( y log(x) ).
80 1.1 christos *
81 1.1 christos * Following Cody and Waite, this program uses a lookup table
82 1.1 christos * of 2**-i/32 and pseudo extended precision arithmetic to
83 1.1 christos * obtain several extra bits of accuracy in both the logarithm
84 1.1 christos * and the exponential.
85 1.1 christos *
86 1.1 christos *
87 1.1 christos *
88 1.1 christos * ACCURACY:
89 1.1 christos *
90 1.1 christos * The relative error of pow(x,y) can be estimated
91 1.1 christos * by y dl ln(2), where dl is the absolute error of
92 1.1 christos * the internally computed base 2 logarithm. At the ends
93 1.1 christos * of the approximation interval the logarithm equal 1/32
94 1.1 christos * and its relative error is about 1 lsb = 1.1e-19. Hence
95 1.1 christos * the predicted relative error in the result is 2.3e-21 y .
96 1.1 christos *
97 1.1 christos * Relative error:
98 1.1 christos * arithmetic domain # trials peak rms
99 1.1 christos *
100 1.1 christos * IEEE +-1000 40000 2.8e-18 3.7e-19
101 1.1 christos * .001 < x < 1000, with log(x) uniformly distributed.
102 1.1 christos * -1000 < y < 1000, y uniformly distributed.
103 1.1 christos *
104 1.1 christos * IEEE 0,8700 60000 6.5e-18 1.0e-18
105 1.1 christos * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed.
106 1.1 christos *
107 1.1 christos *
108 1.1 christos * ERROR MESSAGES:
109 1.1 christos *
110 1.1 christos * message condition value returned
111 1.1 christos * pow overflow x**y > MAXNUM INFINITY
112 1.1 christos * pow underflow x**y < 1/MAXNUM 0.0
113 1.1 christos * pow domain x<0 and y noninteger 0.0
114 1.1 christos *
115 1.1 christos */
116 1.1 christos
117 1.1 christos #include <sys/cdefs.h>
118 1.1 christos #include <float.h>
119 1.1 christos #include <math.h>
120 1.1 christos
121 1.1 christos #include "math_private.h"
122 1.1 christos
123 1.1 christos /* Table size */
124 1.1 christos #define NXT 32
125 1.1 christos /* log2(Table size) */
126 1.1 christos #define LNXT 5
127 1.1 christos
128 1.1 christos /* log(1+x) = x - .5x^2 + x^3 * P(z)/Q(z)
129 1.1 christos * on the domain 2^(-1/32) - 1 <= x <= 2^(1/32) - 1
130 1.1 christos */
131 1.1 christos static long double P[] = {
132 1.1 christos 8.3319510773868690346226E-4L,
133 1.1 christos 4.9000050881978028599627E-1L,
134 1.1 christos 1.7500123722550302671919E0L,
135 1.1 christos 1.4000100839971580279335E0L,
136 1.1 christos };
137 1.1 christos static long double Q[] = {
138 1.1 christos /* 1.0000000000000000000000E0L,*/
139 1.1 christos 5.2500282295834889175431E0L,
140 1.1 christos 8.4000598057587009834666E0L,
141 1.1 christos 4.2000302519914740834728E0L,
142 1.1 christos };
143 1.1 christos /* A[i] = 2^(-i/32), rounded to IEEE long double precision.
144 1.1 christos * If i is even, A[i] + B[i/2] gives additional accuracy.
145 1.1 christos */
146 1.1 christos static long double A[33] = {
147 1.1 christos 1.0000000000000000000000E0L,
148 1.1 christos 9.7857206208770013448287E-1L,
149 1.1 christos 9.5760328069857364691013E-1L,
150 1.1 christos 9.3708381705514995065011E-1L,
151 1.1 christos 9.1700404320467123175367E-1L,
152 1.1 christos 8.9735453750155359320742E-1L,
153 1.1 christos 8.7812608018664974155474E-1L,
154 1.1 christos 8.5930964906123895780165E-1L,
155 1.1 christos 8.4089641525371454301892E-1L,
156 1.1 christos 8.2287773907698242225554E-1L,
157 1.1 christos 8.0524516597462715409607E-1L,
158 1.1 christos 7.8799042255394324325455E-1L,
159 1.1 christos 7.7110541270397041179298E-1L,
160 1.1 christos 7.5458221379671136985669E-1L,
161 1.1 christos 7.3841307296974965571198E-1L,
162 1.1 christos 7.2259040348852331001267E-1L,
163 1.1 christos 7.0710678118654752438189E-1L,
164 1.1 christos 6.9195494098191597746178E-1L,
165 1.1 christos 6.7712777346844636413344E-1L,
166 1.1 christos 6.6261832157987064729696E-1L,
167 1.1 christos 6.4841977732550483296079E-1L,
168 1.1 christos 6.3452547859586661129850E-1L,
169 1.1 christos 6.2092890603674202431705E-1L,
170 1.1 christos 6.0762367999023443907803E-1L,
171 1.1 christos 5.9460355750136053334378E-1L,
172 1.1 christos 5.8186242938878875689693E-1L,
173 1.1 christos 5.6939431737834582684856E-1L,
174 1.1 christos 5.5719337129794626814472E-1L,
175 1.1 christos 5.4525386633262882960438E-1L,
176 1.1 christos 5.3357020033841180906486E-1L,
177 1.1 christos 5.2213689121370692017331E-1L,
178 1.1 christos 5.1094857432705833910408E-1L,
179 1.1 christos 5.0000000000000000000000E-1L,
180 1.1 christos };
181 1.1 christos static long double B[17] = {
182 1.1 christos 0.0000000000000000000000E0L,
183 1.1 christos 2.6176170809902549338711E-20L,
184 1.1 christos -1.0126791927256478897086E-20L,
185 1.1 christos 1.3438228172316276937655E-21L,
186 1.1 christos 1.2207982955417546912101E-20L,
187 1.1 christos -6.3084814358060867200133E-21L,
188 1.1 christos 1.3164426894366316434230E-20L,
189 1.1 christos -1.8527916071632873716786E-20L,
190 1.1 christos 1.8950325588932570796551E-20L,
191 1.1 christos 1.5564775779538780478155E-20L,
192 1.1 christos 6.0859793637556860974380E-21L,
193 1.1 christos -2.0208749253662532228949E-20L,
194 1.1 christos 1.4966292219224761844552E-20L,
195 1.1 christos 3.3540909728056476875639E-21L,
196 1.1 christos -8.6987564101742849540743E-22L,
197 1.1 christos -1.2327176863327626135542E-20L,
198 1.1 christos 0.0000000000000000000000E0L,
199 1.1 christos };
200 1.1 christos
201 1.1 christos /* 2^x = 1 + x P(x),
202 1.1 christos * on the interval -1/32 <= x <= 0
203 1.1 christos */
204 1.1 christos static long double R[] = {
205 1.1 christos 1.5089970579127659901157E-5L,
206 1.1 christos 1.5402715328927013076125E-4L,
207 1.1 christos 1.3333556028915671091390E-3L,
208 1.1 christos 9.6181291046036762031786E-3L,
209 1.1 christos 5.5504108664798463044015E-2L,
210 1.1 christos 2.4022650695910062854352E-1L,
211 1.1 christos 6.9314718055994530931447E-1L,
212 1.1 christos };
213 1.1 christos
214 1.1 christos #define douba(k) A[k]
215 1.1 christos #define doubb(k) B[k]
216 1.1 christos #define MEXP (NXT*16384.0L)
217 1.1 christos /* The following if denormal numbers are supported, else -MEXP: */
218 1.1 christos #define MNEXP (-NXT*(16384.0L+64.0L))
219 1.1 christos /* log2(e) - 1 */
220 1.1 christos #define LOG2EA 0.44269504088896340735992L
221 1.1 christos
222 1.1 christos #define F W
223 1.1 christos #define Fa Wa
224 1.1 christos #define Fb Wb
225 1.1 christos #define G W
226 1.1 christos #define Ga Wa
227 1.1 christos #define Gb u
228 1.1 christos #define H W
229 1.1 christos #define Ha Wb
230 1.1 christos #define Hb Wb
231 1.1 christos
232 1.1 christos static const long double MAXLOGL = 1.1356523406294143949492E4L;
233 1.1 christos static const long double MINLOGL = -1.13994985314888605586758E4L;
234 1.1 christos static const long double LOGE2L = 6.9314718055994530941723E-1L;
235 1.1 christos static volatile long double z;
236 1.1 christos static long double w, W, Wa, Wb, ya, yb, u;
237 1.1 christos static const long double huge = 0x1p10000L;
238 1.1 christos #if 0 /* XXX Prevent gcc from erroneously constant folding this. */
239 1.1 christos static const long double twom10000 = 0x1p-10000L;
240 1.1 christos #else
241 1.1 christos static volatile long double twom10000 = 0x1p-10000L;
242 1.1 christos #endif
243 1.1 christos
244 1.1 christos static long double reducl( long double );
245 1.1 christos static long double powil ( long double, int );
246 1.1 christos
247 1.1 christos long double
248 1.1 christos powl(long double x, long double y)
249 1.1 christos {
250 1.1 christos /* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */
251 1.1 christos int i, nflg, iyflg, yoddint;
252 1.1 christos long e;
253 1.1 christos
254 1.1 christos if( y == 0.0L )
255 1.1 christos return( 1.0L );
256 1.1 christos
257 1.1 christos if( x == 1.0L )
258 1.1 christos return( 1.0L );
259 1.1 christos
260 1.1 christos if( isnan(x) )
261 1.1 christos return ( nan_mix(x, y) );
262 1.1 christos if( isnan(y) )
263 1.1 christos return ( nan_mix(x, y) );
264 1.1 christos
265 1.1 christos if( y == 1.0L )
266 1.1 christos return( x );
267 1.1 christos
268 1.1 christos if( !isfinite(y) && x == -1.0L )
269 1.1 christos return( 1.0L );
270 1.1 christos
271 1.1 christos if( y >= LDBL_MAX )
272 1.1 christos {
273 1.1 christos if( x > 1.0L )
274 1.1 christos return( INFINITY );
275 1.1 christos if( x > 0.0L && x < 1.0L )
276 1.1 christos return( 0.0L );
277 1.1 christos if( x < -1.0L )
278 1.1 christos return( INFINITY );
279 1.1 christos if( x > -1.0L && x < 0.0L )
280 1.1 christos return( 0.0L );
281 1.1 christos }
282 1.1 christos if( y <= -LDBL_MAX )
283 1.1 christos {
284 1.1 christos if( x > 1.0L )
285 1.1 christos return( 0.0L );
286 1.1 christos if( x > 0.0L && x < 1.0L )
287 1.1 christos return( INFINITY );
288 1.1 christos if( x < -1.0L )
289 1.1 christos return( 0.0L );
290 1.1 christos if( x > -1.0L && x < 0.0L )
291 1.1 christos return( INFINITY );
292 1.1 christos }
293 1.1 christos if( x >= LDBL_MAX )
294 1.1 christos {
295 1.1 christos if( y > 0.0L )
296 1.1 christos return( INFINITY );
297 1.1 christos return( 0.0L );
298 1.1 christos }
299 1.1 christos
300 1.1 christos w = floorl(y);
301 1.1 christos /* Set iyflg to 1 if y is an integer. */
302 1.1 christos iyflg = 0;
303 1.1 christos if( w == y )
304 1.1 christos iyflg = 1;
305 1.1 christos
306 1.1 christos /* Test for odd integer y. */
307 1.1 christos yoddint = 0;
308 1.1 christos if( iyflg )
309 1.1 christos {
310 1.1 christos ya = fabsl(y);
311 1.1 christos ya = floorl(0.5L * ya);
312 1.1 christos yb = 0.5L * fabsl(w);
313 1.1 christos if( ya != yb )
314 1.1 christos yoddint = 1;
315 1.1 christos }
316 1.1 christos
317 1.1 christos if( x <= -LDBL_MAX )
318 1.1 christos {
319 1.1 christos if( y > 0.0L )
320 1.1 christos {
321 1.1 christos if( yoddint )
322 1.1 christos return( -INFINITY );
323 1.1 christos return( INFINITY );
324 1.1 christos }
325 1.1 christos if( y < 0.0L )
326 1.1 christos {
327 1.1 christos if( yoddint )
328 1.1 christos return( -0.0L );
329 1.1 christos return( 0.0 );
330 1.1 christos }
331 1.1 christos }
332 1.1 christos
333 1.1 christos
334 1.1 christos nflg = 0; /* flag = 1 if x<0 raised to integer power */
335 1.1 christos if( x <= 0.0L )
336 1.1 christos {
337 1.1 christos if( x == 0.0L )
338 1.1 christos {
339 1.1 christos if( y < 0.0 )
340 1.1 christos {
341 1.1 christos if( signbit(x) && yoddint )
342 1.1 christos return( -INFINITY );
343 1.1 christos return( INFINITY );
344 1.1 christos }
345 1.1 christos if( y > 0.0 )
346 1.1 christos {
347 1.1 christos if( signbit(x) && yoddint )
348 1.1 christos return( -0.0L );
349 1.1 christos return( 0.0 );
350 1.1 christos }
351 1.1 christos if( y == 0.0L )
352 1.1 christos return( 1.0L ); /* 0**0 */
353 1.1 christos else
354 1.1 christos return( 0.0L ); /* 0**y */
355 1.1 christos }
356 1.1 christos else
357 1.1 christos {
358 1.1 christos if( iyflg == 0 )
359 1.1 christos return (x - x) / (x - x); /* (x<0)**(non-int) is NaN */
360 1.1 christos nflg = 1;
361 1.1 christos }
362 1.1 christos }
363 1.1 christos
364 1.1 christos /* Integer power of an integer. */
365 1.1 christos
366 1.1 christos if( iyflg )
367 1.1 christos {
368 1.1 christos i = w;
369 1.1 christos w = floorl(x);
370 1.1 christos if( (w == x) && (fabsl(y) < 32768.0) )
371 1.1 christos {
372 1.1 christos w = powil( x, (int) y );
373 1.1 christos return( w );
374 1.1 christos }
375 1.1 christos }
376 1.1 christos
377 1.1 christos
378 1.1 christos if( nflg )
379 1.1 christos x = fabsl(x);
380 1.1 christos
381 1.1 christos /* separate significand from exponent */
382 1.1 christos x = frexpl( x, &i );
383 1.1 christos e = i;
384 1.1 christos
385 1.1 christos /* find significand in antilog table A[] */
386 1.1 christos i = 1;
387 1.1 christos if( x <= douba(17) )
388 1.1 christos i = 17;
389 1.1 christos if( x <= douba(i+8) )
390 1.1 christos i += 8;
391 1.1 christos if( x <= douba(i+4) )
392 1.1 christos i += 4;
393 1.1 christos if( x <= douba(i+2) )
394 1.1 christos i += 2;
395 1.1 christos if( x >= douba(1) )
396 1.1 christos i = -1;
397 1.1 christos i += 1;
398 1.1 christos
399 1.1 christos
400 1.1 christos /* Find (x - A[i])/A[i]
401 1.1 christos * in order to compute log(x/A[i]):
402 1.1 christos *
403 1.1 christos * log(x) = log( a x/a ) = log(a) + log(x/a)
404 1.1 christos *
405 1.1 christos * log(x/a) = log(1+v), v = x/a - 1 = (x-a)/a
406 1.1 christos */
407 1.1 christos x -= douba(i);
408 1.1 christos x -= doubb(i/2);
409 1.1 christos x /= douba(i);
410 1.1 christos
411 1.1 christos
412 1.1 christos /* rational approximation for log(1+v):
413 1.1 christos *
414 1.1 christos * log(1+v) = v - v**2/2 + v**3 P(v) / Q(v)
415 1.1 christos */
416 1.1 christos z = x*x;
417 1.1 christos w = x * ( z * __polevll( x, P, 3 ) / __p1evll( x, Q, 3 ) );
418 1.1 christos w = w - ldexpl( z, -1 ); /* w - 0.5 * z */
419 1.1 christos
420 1.1 christos /* Convert to base 2 logarithm:
421 1.1 christos * multiply by log2(e) = 1 + LOG2EA
422 1.1 christos */
423 1.1 christos z = LOG2EA * w;
424 1.1 christos z += w;
425 1.1 christos z += LOG2EA * x;
426 1.1 christos z += x;
427 1.1 christos
428 1.1 christos /* Compute exponent term of the base 2 logarithm. */
429 1.1 christos w = -i;
430 1.1 christos w = ldexpl( w, -LNXT ); /* divide by NXT */
431 1.1 christos w += e;
432 1.1 christos /* Now base 2 log of x is w + z. */
433 1.1 christos
434 1.1 christos /* Multiply base 2 log by y, in extended precision. */
435 1.1 christos
436 1.1 christos /* separate y into large part ya
437 1.1 christos * and small part yb less than 1/NXT
438 1.1 christos */
439 1.1 christos ya = reducl(y);
440 1.1 christos yb = y - ya;
441 1.1 christos
442 1.1 christos /* (w+z)(ya+yb)
443 1.1 christos * = w*ya + w*yb + z*y
444 1.1 christos */
445 1.1 christos F = z * y + w * yb;
446 1.1 christos Fa = reducl(F);
447 1.1 christos Fb = F - Fa;
448 1.1 christos
449 1.1 christos G = Fa + w * ya;
450 1.1 christos Ga = reducl(G);
451 1.1 christos Gb = G - Ga;
452 1.1 christos
453 1.1 christos H = Fb + Gb;
454 1.1 christos Ha = reducl(H);
455 1.1 christos w = ldexpl( Ga+Ha, LNXT );
456 1.1 christos
457 1.1 christos /* Test the power of 2 for overflow */
458 1.1 christos if( w > MEXP )
459 1.1 christos return (huge * huge); /* overflow */
460 1.1 christos
461 1.1 christos if( w < MNEXP )
462 1.1 christos return (twom10000 * twom10000); /* underflow */
463 1.1 christos
464 1.1 christos e = w;
465 1.1 christos Hb = H - Ha;
466 1.1 christos
467 1.1 christos if( Hb > 0.0L )
468 1.1 christos {
469 1.1 christos e += 1;
470 1.1 christos Hb -= (1.0L/NXT); /*0.0625L;*/
471 1.1 christos }
472 1.1 christos
473 1.1 christos /* Now the product y * log2(x) = Hb + e/NXT.
474 1.1 christos *
475 1.1 christos * Compute base 2 exponential of Hb,
476 1.1 christos * where -0.0625 <= Hb <= 0.
477 1.1 christos */
478 1.1 christos z = Hb * __polevll( Hb, R, 6 ); /* z = 2**Hb - 1 */
479 1.1 christos
480 1.1 christos /* Express e/NXT as an integer plus a negative number of (1/NXT)ths.
481 1.1 christos * Find lookup table entry for the fractional power of 2.
482 1.1 christos */
483 1.1 christos if( e < 0 )
484 1.1 christos i = 0;
485 1.1 christos else
486 1.1 christos i = 1;
487 1.1 christos i = e/NXT + i;
488 1.1 christos e = NXT*i - e;
489 1.1 christos w = douba( e );
490 1.1 christos z = w * z; /* 2**-e * ( 1 + (2**Hb-1) ) */
491 1.1 christos z = z + w;
492 1.1 christos z = ldexpl( z, i ); /* multiply by integer power of 2 */
493 1.1 christos
494 1.1 christos if( nflg )
495 1.1 christos {
496 1.1 christos /* For negative x,
497 1.1 christos * find out if the integer exponent
498 1.1 christos * is odd or even.
499 1.1 christos */
500 1.1 christos w = ldexpl( y, -1 );
501 1.1 christos w = floorl(w);
502 1.1 christos w = ldexpl( w, 1 );
503 1.1 christos if( w != y )
504 1.1 christos z = -z; /* odd exponent */
505 1.1 christos }
506 1.1 christos
507 1.1 christos return( z );
508 1.1 christos }
509 1.1 christos
510 1.1 christos
511 1.1 christos /* Find a multiple of 1/NXT that is within 1/NXT of x. */
512 1.1 christos static inline long double
513 1.1 christos reducl(long double x)
514 1.1 christos {
515 1.1 christos long double t;
516 1.1 christos
517 1.1 christos t = ldexpl( x, LNXT );
518 1.1 christos t = floorl( t );
519 1.1 christos t = ldexpl( t, -LNXT );
520 1.1 christos return(t);
521 1.1 christos }
522 1.1 christos
523 1.1 christos /* powil.c
524 1.1 christos *
525 1.1 christos * Real raised to integer power, long double precision
526 1.1 christos *
527 1.1 christos *
528 1.1 christos *
529 1.1 christos * SYNOPSIS:
530 1.1 christos *
531 1.1 christos * long double x, y, powil();
532 1.1 christos * int n;
533 1.1 christos *
534 1.1 christos * y = powil( x, n );
535 1.1 christos *
536 1.1 christos *
537 1.1 christos *
538 1.1 christos * DESCRIPTION:
539 1.1 christos *
540 1.1 christos * Returns argument x raised to the nth power.
541 1.1 christos * The routine efficiently decomposes n as a sum of powers of
542 1.1 christos * two. The desired power is a product of two-to-the-kth
543 1.1 christos * powers of x. Thus to compute the 32767 power of x requires
544 1.1 christos * 28 multiplications instead of 32767 multiplications.
545 1.1 christos *
546 1.1 christos *
547 1.1 christos *
548 1.1 christos * ACCURACY:
549 1.1 christos *
550 1.1 christos *
551 1.1 christos * Relative error:
552 1.1 christos * arithmetic x domain n domain # trials peak rms
553 1.1 christos * IEEE .001,1000 -1022,1023 50000 4.3e-17 7.8e-18
554 1.1 christos * IEEE 1,2 -1022,1023 20000 3.9e-17 7.6e-18
555 1.1 christos * IEEE .99,1.01 0,8700 10000 3.6e-16 7.2e-17
556 1.1 christos *
557 1.1 christos * Returns MAXNUM on overflow, zero on underflow.
558 1.1 christos *
559 1.1 christos */
560 1.1 christos
561 1.1 christos static long double
562 1.1 christos powil(long double x, int nn)
563 1.1 christos {
564 1.1 christos long double ww, y;
565 1.1 christos long double s;
566 1.1 christos int n, e, sign, asign, lx;
567 1.1 christos
568 1.1 christos if( x == 0.0L )
569 1.1 christos {
570 1.1 christos if( nn == 0 )
571 1.1 christos return( 1.0L );
572 1.1 christos else if( nn < 0 )
573 1.1 christos return( LDBL_MAX );
574 1.1 christos else
575 1.1 christos return( 0.0L );
576 1.1 christos }
577 1.1 christos
578 1.1 christos if( nn == 0 )
579 1.1 christos return( 1.0L );
580 1.1 christos
581 1.1 christos
582 1.1 christos if( x < 0.0L )
583 1.1 christos {
584 1.1 christos asign = -1;
585 1.1 christos x = -x;
586 1.1 christos }
587 1.1 christos else
588 1.1 christos asign = 0;
589 1.1 christos
590 1.1 christos
591 1.1 christos if( nn < 0 )
592 1.1 christos {
593 1.1 christos sign = -1;
594 1.1 christos n = -nn;
595 1.1 christos }
596 1.1 christos else
597 1.1 christos {
598 1.1 christos sign = 1;
599 1.1 christos n = nn;
600 1.1 christos }
601 1.1 christos
602 1.1 christos /* Overflow detection */
603 1.1 christos
604 1.1 christos /* Calculate approximate logarithm of answer */
605 1.1 christos s = x;
606 1.1 christos s = frexpl( s, &lx );
607 1.1 christos e = (lx - 1)*n;
608 1.1 christos if( (e == 0) || (e > 64) || (e < -64) )
609 1.1 christos {
610 1.1 christos s = (s - 7.0710678118654752e-1L) / (s + 7.0710678118654752e-1L);
611 1.1 christos s = (2.9142135623730950L * s - 0.5L + lx) * nn * LOGE2L;
612 1.1 christos }
613 1.1 christos else
614 1.1 christos {
615 1.1 christos s = LOGE2L * e;
616 1.1 christos }
617 1.1 christos
618 1.1 christos if( s > MAXLOGL )
619 1.1 christos return (huge * huge); /* overflow */
620 1.1 christos
621 1.1 christos if( s < MINLOGL )
622 1.1 christos return (twom10000 * twom10000); /* underflow */
623 1.1 christos /* Handle tiny denormal answer, but with less accuracy
624 1.1 christos * since roundoff error in 1.0/x will be amplified.
625 1.1 christos * The precise demarcation should be the gradual underflow threshold.
626 1.1 christos */
627 1.1 christos if( s < (-MAXLOGL+2.0L) )
628 1.1 christos {
629 1.1 christos x = 1.0L/x;
630 1.1 christos sign = -sign;
631 1.1 christos }
632 1.1 christos
633 1.1 christos /* First bit of the power */
634 1.1 christos if( n & 1 )
635 1.1 christos y = x;
636 1.1 christos
637 1.1 christos else
638 1.1 christos {
639 1.1 christos y = 1.0L;
640 1.1 christos asign = 0;
641 1.1 christos }
642 1.1 christos
643 1.1 christos ww = x;
644 1.1 christos n >>= 1;
645 1.1 christos while( n )
646 1.1 christos {
647 1.1 christos ww = ww * ww; /* arg to the 2-to-the-kth power */
648 1.1 christos if( n & 1 ) /* if that bit is set, then include in product */
649 1.1 christos y *= ww;
650 1.1 christos n >>= 1;
651 1.1 christos }
652 1.1 christos
653 1.1 christos if( asign )
654 1.1 christos y = -y; /* odd power of negative number */
655 1.1 christos if( sign < 0 )
656 1.1 christos y = 1.0L/y;
657 1.1 christos return(y);
658 1.1 christos }
659