Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1906 serge 1
/*							__powil.c
2
 *
3
 *	Real raised to integer power, long double precision
4
 *
5
 *
6
 *
7
 * SYNOPSIS:
8
 *
9
 * long double x, y, __powil();
10
 * int n;
11
 *
12
 * y = __powil( x, n );
13
 *
14
 *
15
 *
16
 * DESCRIPTION:
17
 *
18
 * Returns argument x raised to the nth power.
19
 * The routine efficiently decomposes n as a sum of powers of
20
 * two. The desired power is a product of two-to-the-kth
21
 * powers of x.  Thus to compute the 32767 power of x requires
22
 * 28 multiplications instead of 32767 multiplications.
23
 *
24
 *
25
 *
26
 * ACCURACY:
27
 *
28
 *
29
 *                      Relative error:
30
 * arithmetic   x domain   n domain  # trials      peak         rms
31
 *    IEEE     .001,1000  -1022,1023  50000       4.3e-17     7.8e-18
32
 *    IEEE        1,2     -1022,1023  20000       3.9e-17     7.6e-18
33
 *    IEEE     .99,1.01     0,8700    10000       3.6e-16     7.2e-17
34
 *
35
 * Returns INFINITY on overflow, zero on underflow.
36
 *
37
 */
38
 
39
/*							__powil.c	*/
40
 
41
/*
42
Cephes Math Library Release 2.2:  December, 1990
43
Copyright 1984, 1990 by Stephen L. Moshier
44
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
45
*/
46
 
47
/*
48
Modified for mingw
49
2002-07-22 Danny Smith 
50
*/
51
 
52
#ifdef __MINGW32__
53
#include "cephes_mconf.h"
54
#else
55
#include "mconf.h"
56
extern long double MAXNUML, MAXLOGL, MINLOGL;
57
extern long double LOGE2L;
58
#ifdef ANSIPROT
59
extern long double frexpl ( long double, int * );
60
#else
61
long double frexpl();
62
#endif
63
#endif /* __MINGW32__ */
64
 
65
#ifndef _SET_ERRNO
66
#define _SET_ERRNO(x)
67
#endif
68
 
69
long double __powil( x, nn )
70
long double x;
71
int nn;
72
{
73
long double w, y;
74
long double s;
75
int n, e, sign, asign, lx;
76
 
77
if( x == 0.0L )
78
	{
79
	if( nn == 0 )
80
		return( 1.0L );
81
	else if( nn < 0 )
82
		return( INFINITYL );
83
	else
84
		return( 0.0L );
85
	}
86
 
87
if( nn == 0 )
88
	return( 1.0L );
89
 
90
 
91
if( x < 0.0L )
92
	{
93
	asign = -1;
94
	x = -x;
95
	}
96
else
97
	asign = 0;
98
 
99
 
100
if( nn < 0 )
101
	{
102
	sign = -1;
103
	n = -nn;
104
	}
105
else
106
	{
107
	sign = 1;
108
	n = nn;
109
	}
110
 
111
/* Overflow detection */
112
 
113
/* Calculate approximate logarithm of answer */
114
s = x;
115
s = frexpl( s, &lx );
116
e = (lx - 1)*n;
117
if( (e == 0) || (e > 64) || (e < -64) )
118
	{
119
	s = (s - 7.0710678118654752e-1L) / (s +  7.0710678118654752e-1L);
120
	s = (2.9142135623730950L * s - 0.5L + lx) * nn * LOGE2L;
121
	}
122
else
123
	{
124
	s = LOGE2L * e;
125
	}
126
 
127
if( s > MAXLOGL )
128
	{
129
	mtherr( "__powil", OVERFLOW );
130
	_SET_ERRNO(ERANGE);
131
	y = INFINITYL;
132
	goto done;
133
	}
134
 
135
if( s < MINLOGL )
136
	{
137
	mtherr( "__powil", UNDERFLOW );
138
	_SET_ERRNO(ERANGE);
139
	return(0.0L);
140
	}
141
/* Handle tiny denormal answer, but with less accuracy
142
 * since roundoff error in 1.0/x will be amplified.
143
 * The precise demarcation should be the gradual underflow threshold.
144
 */
145
if( s < (-MAXLOGL+2.0L) )
146
	{
147
	x = 1.0L/x;
148
	sign = -sign;
149
	}
150
 
151
/* First bit of the power */
152
if( n & 1 )
153
	y = x;
154
 
155
else
156
	{
157
	y = 1.0L;
158
	asign = 0;
159
	}
160
 
161
w = x;
162
n >>= 1;
163
while( n )
164
	{
165
	w = w * w;	/* arg to the 2-to-the-kth power */
166
	if( n & 1 )	/* if that bit is set, then include in product */
167
		y *= w;
168
	n >>= 1;
169
	}
170
 
171
 
172
done:
173
 
174
if( asign )
175
	y = -y; /* odd power of negative number */
176
if( sign < 0 )
177
	y = 1.0L/y;
178
return(y);
179
}