Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: fusl/src/math/powl.c

Issue 1714623002: [fusl] clang-format fusl (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: headers too Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_powl.c */ 1 /* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_powl.c */
2 /* 2 /*
3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> 3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
4 * 4 *
5 * Permission to use, copy, modify, and distribute this software for any 5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies. 7 * copyright notice and this permission notice appear in all copies.
8 * 8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 * message condition value returned 63 * message condition value returned
64 * pow overflow x**y > MAXNUM INFINITY 64 * pow overflow x**y > MAXNUM INFINITY
65 * pow underflow x**y < 1/MAXNUM 0.0 65 * pow underflow x**y < 1/MAXNUM 0.0
66 * pow domain x<0 and y noninteger 0.0 66 * pow domain x<0 and y noninteger 0.0
67 * 67 *
68 */ 68 */
69 69
70 #include "libm.h" 70 #include "libm.h"
71 71
72 #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 72 #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
73 long double powl(long double x, long double y) 73 long double powl(long double x, long double y) {
74 { 74 return pow(x, y);
75 » return pow(x, y);
76 } 75 }
77 #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 76 #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
78 77
79 /* Table size */ 78 /* Table size */
80 #define NXT 32 79 #define NXT 32
81 80
82 /* log(1+x) = x - .5x^2 + x^3 * P(z)/Q(z) 81 /* log(1+x) = x - .5x^2 + x^3 * P(z)/Q(z)
83 * on the domain 2^(-1/32) - 1 <= x <= 2^(1/32) - 1 82 * on the domain 2^(-1/32) - 1 <= x <= 2^(1/32) - 1
84 */ 83 */
85 static const long double P[] = { 84 static const long double P[] = {
86 8.3319510773868690346226E-4L, 85 8.3319510773868690346226E-4L, 4.9000050881978028599627E-1L,
87 4.9000050881978028599627E-1L, 86 1.7500123722550302671919E0L, 1.4000100839971580279335E0L,
88 1.7500123722550302671919E0L,
89 1.4000100839971580279335E0L,
90 }; 87 };
91 static const long double Q[] = { 88 static const long double Q[] = {
92 /* 1.0000000000000000000000E0L,*/ 89 /* 1.0000000000000000000000E0L,*/
93 5.2500282295834889175431E0L, 90 5.2500282295834889175431E0L, 8.4000598057587009834666E0L,
94 8.4000598057587009834666E0L, 91 4.2000302519914740834728E0L,
95 4.2000302519914740834728E0L,
96 }; 92 };
97 /* A[i] = 2^(-i/32), rounded to IEEE long double precision. 93 /* A[i] = 2^(-i/32), rounded to IEEE long double precision.
98 * If i is even, A[i] + B[i/2] gives additional accuracy. 94 * If i is even, A[i] + B[i/2] gives additional accuracy.
99 */ 95 */
100 static const long double A[33] = { 96 static const long double A[33] = {
101 1.0000000000000000000000E0L, 97 1.0000000000000000000000E0L, 9.7857206208770013448287E-1L,
102 9.7857206208770013448287E-1L, 98 9.5760328069857364691013E-1L, 9.3708381705514995065011E-1L,
103 9.5760328069857364691013E-1L, 99 9.1700404320467123175367E-1L, 8.9735453750155359320742E-1L,
104 9.3708381705514995065011E-1L, 100 8.7812608018664974155474E-1L, 8.5930964906123895780165E-1L,
105 9.1700404320467123175367E-1L, 101 8.4089641525371454301892E-1L, 8.2287773907698242225554E-1L,
106 8.9735453750155359320742E-1L, 102 8.0524516597462715409607E-1L, 7.8799042255394324325455E-1L,
107 8.7812608018664974155474E-1L, 103 7.7110541270397041179298E-1L, 7.5458221379671136985669E-1L,
108 8.5930964906123895780165E-1L, 104 7.3841307296974965571198E-1L, 7.2259040348852331001267E-1L,
109 8.4089641525371454301892E-1L, 105 7.0710678118654752438189E-1L, 6.9195494098191597746178E-1L,
110 8.2287773907698242225554E-1L, 106 6.7712777346844636413344E-1L, 6.6261832157987064729696E-1L,
111 8.0524516597462715409607E-1L, 107 6.4841977732550483296079E-1L, 6.3452547859586661129850E-1L,
112 7.8799042255394324325455E-1L, 108 6.2092890603674202431705E-1L, 6.0762367999023443907803E-1L,
113 7.7110541270397041179298E-1L, 109 5.9460355750136053334378E-1L, 5.8186242938878875689693E-1L,
114 7.5458221379671136985669E-1L, 110 5.6939431737834582684856E-1L, 5.5719337129794626814472E-1L,
115 7.3841307296974965571198E-1L, 111 5.4525386633262882960438E-1L, 5.3357020033841180906486E-1L,
116 7.2259040348852331001267E-1L, 112 5.2213689121370692017331E-1L, 5.1094857432705833910408E-1L,
117 7.0710678118654752438189E-1L, 113 5.0000000000000000000000E-1L,
118 6.9195494098191597746178E-1L,
119 6.7712777346844636413344E-1L,
120 6.6261832157987064729696E-1L,
121 6.4841977732550483296079E-1L,
122 6.3452547859586661129850E-1L,
123 6.2092890603674202431705E-1L,
124 6.0762367999023443907803E-1L,
125 5.9460355750136053334378E-1L,
126 5.8186242938878875689693E-1L,
127 5.6939431737834582684856E-1L,
128 5.5719337129794626814472E-1L,
129 5.4525386633262882960438E-1L,
130 5.3357020033841180906486E-1L,
131 5.2213689121370692017331E-1L,
132 5.1094857432705833910408E-1L,
133 5.0000000000000000000000E-1L,
134 }; 114 };
135 static const long double B[17] = { 115 static const long double B[17] = {
136 0.0000000000000000000000E0L, 116 0.0000000000000000000000E0L, 2.6176170809902549338711E-20L,
137 2.6176170809902549338711E-20L, 117 -1.0126791927256478897086E-20L, 1.3438228172316276937655E-21L,
138 -1.0126791927256478897086E-20L, 118 1.2207982955417546912101E-20L, -6.3084814358060867200133E-21L,
139 1.3438228172316276937655E-21L, 119 1.3164426894366316434230E-20L, -1.8527916071632873716786E-20L,
140 1.2207982955417546912101E-20L, 120 1.8950325588932570796551E-20L, 1.5564775779538780478155E-20L,
141 -6.3084814358060867200133E-21L, 121 6.0859793637556860974380E-21L, -2.0208749253662532228949E-20L,
142 1.3164426894366316434230E-20L, 122 1.4966292219224761844552E-20L, 3.3540909728056476875639E-21L,
143 -1.8527916071632873716786E-20L, 123 -8.6987564101742849540743E-22L, -1.2327176863327626135542E-20L,
144 1.8950325588932570796551E-20L, 124 0.0000000000000000000000E0L,
145 1.5564775779538780478155E-20L,
146 6.0859793637556860974380E-21L,
147 -2.0208749253662532228949E-20L,
148 1.4966292219224761844552E-20L,
149 3.3540909728056476875639E-21L,
150 -8.6987564101742849540743E-22L,
151 -1.2327176863327626135542E-20L,
152 0.0000000000000000000000E0L,
153 }; 125 };
154 126
155 /* 2^x = 1 + x P(x), 127 /* 2^x = 1 + x P(x),
156 * on the interval -1/32 <= x <= 0 128 * on the interval -1/32 <= x <= 0
157 */ 129 */
158 static const long double R[] = { 130 static const long double R[] = {
159 1.5089970579127659901157E-5L, 131 1.5089970579127659901157E-5L, 1.5402715328927013076125E-4L,
160 1.5402715328927013076125E-4L, 132 1.3333556028915671091390E-3L, 9.6181291046036762031786E-3L,
161 1.3333556028915671091390E-3L, 133 5.5504108664798463044015E-2L, 2.4022650695910062854352E-1L,
162 9.6181291046036762031786E-3L, 134 6.9314718055994530931447E-1L,
163 5.5504108664798463044015E-2L,
164 2.4022650695910062854352E-1L,
165 6.9314718055994530931447E-1L,
166 }; 135 };
167 136
168 #define MEXP (NXT*16384.0L) 137 #define MEXP (NXT * 16384.0L)
169 /* The following if denormal numbers are supported, else -MEXP: */ 138 /* The following if denormal numbers are supported, else -MEXP: */
170 #define MNEXP (-NXT*(16384.0L+64.0L)) 139 #define MNEXP (-NXT * (16384.0L + 64.0L))
171 /* log2(e) - 1 */ 140 /* log2(e) - 1 */
172 #define LOG2EA 0.44269504088896340735992L 141 #define LOG2EA 0.44269504088896340735992L
173 142
174 #define F W 143 #define F W
175 #define Fa Wa 144 #define Fa Wa
176 #define Fb Wb 145 #define Fb Wb
177 #define G W 146 #define G W
178 #define Ga Wa 147 #define Ga Wa
179 #define Gb u 148 #define Gb u
180 #define H W 149 #define H W
181 #define Ha Wb 150 #define Ha Wb
182 #define Hb Wb 151 #define Hb Wb
183 152
184 static const long double MAXLOGL = 1.1356523406294143949492E4L; 153 static const long double MAXLOGL = 1.1356523406294143949492E4L;
185 static const long double MINLOGL = -1.13994985314888605586758E4L; 154 static const long double MINLOGL = -1.13994985314888605586758E4L;
186 static const long double LOGE2L = 6.9314718055994530941723E-1L; 155 static const long double LOGE2L = 6.9314718055994530941723E-1L;
187 static const long double huge = 0x1p10000L; 156 static const long double huge = 0x1p10000L;
188 /* XXX Prevent gcc from erroneously constant folding this. */ 157 /* XXX Prevent gcc from erroneously constant folding this. */
189 static const volatile long double twom10000 = 0x1p-10000L; 158 static const volatile long double twom10000 = 0x1p-10000L;
190 159
191 static long double reducl(long double); 160 static long double reducl(long double);
192 static long double powil(long double, int); 161 static long double powil(long double, int);
193 162
194 long double powl(long double x, long double y) 163 long double powl(long double x, long double y) {
195 { 164 /* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */
196 » /* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */ 165 int i, nflg, iyflg, yoddint;
197 » int i, nflg, iyflg, yoddint; 166 long e;
198 » long e; 167 volatile long double z = 0;
199 » volatile long double z=0; 168 long double w = 0, W = 0, Wa = 0, Wb = 0, ya = 0, yb = 0, u = 0;
200 » long double w=0, W=0, Wa=0, Wb=0, ya=0, yb=0, u=0; 169
201 170 /* make sure no invalid exception is raised by nan comparision */
202 » /* make sure no invalid exception is raised by nan comparision */ 171 if (isnan(x)) {
203 » if (isnan(x)) { 172 if (!isnan(y) && y == 0.0)
204 » » if (!isnan(y) && y == 0.0) 173 return 1.0;
205 » » » return 1.0; 174 return x;
206 » » return x; 175 }
207 » } 176 if (isnan(y)) {
208 » if (isnan(y)) { 177 if (x == 1.0)
209 » » if (x == 1.0) 178 return 1.0;
210 » » » return 1.0; 179 return y;
211 » » return y; 180 }
212 » } 181 if (x == 1.0)
213 » if (x == 1.0) 182 return 1.0; /* 1**y = 1, even if y is nan */
214 » » return 1.0; /* 1**y = 1, even if y is nan */ 183 if (x == -1.0 && !isfinite(y))
215 » if (x == -1.0 && !isfinite(y)) 184 return 1.0; /* -1**inf = 1 */
216 » » return 1.0; /* -1**inf = 1 */ 185 if (y == 0.0)
217 » if (y == 0.0) 186 return 1.0; /* x**0 = 1, even if x is nan */
218 » » return 1.0; /* x**0 = 1, even if x is nan */ 187 if (y == 1.0)
219 » if (y == 1.0) 188 return x;
220 » » return x; 189 if (y >= LDBL_MAX) {
221 » if (y >= LDBL_MAX) { 190 if (x > 1.0 || x < -1.0)
222 » » if (x > 1.0 || x < -1.0) 191 return INFINITY;
223 » » » return INFINITY; 192 if (x != 0.0)
224 » » if (x != 0.0) 193 return 0.0;
225 » » » return 0.0; 194 }
226 » } 195 if (y <= -LDBL_MAX) {
227 » if (y <= -LDBL_MAX) { 196 if (x > 1.0 || x < -1.0)
228 » » if (x > 1.0 || x < -1.0) 197 return 0.0;
229 » » » return 0.0; 198 if (x != 0.0 || y == -INFINITY)
230 » » if (x != 0.0 || y == -INFINITY) 199 return INFINITY;
231 » » » return INFINITY; 200 }
232 » } 201 if (x >= LDBL_MAX) {
233 » if (x >= LDBL_MAX) { 202 if (y > 0.0)
234 » » if (y > 0.0) 203 return INFINITY;
235 » » » return INFINITY; 204 return 0.0;
236 » » return 0.0; 205 }
237 » } 206
238 207 w = floorl(y);
239 » w = floorl(y); 208
240 209 /* Set iyflg to 1 if y is an integer. */
241 » /* Set iyflg to 1 if y is an integer. */ 210 iyflg = 0;
242 » iyflg = 0; 211 if (w == y)
243 » if (w == y) 212 iyflg = 1;
244 » » iyflg = 1; 213
245 214 /* Test for odd integer y. */
246 » /* Test for odd integer y. */ 215 yoddint = 0;
247 » yoddint = 0; 216 if (iyflg) {
248 » if (iyflg) { 217 ya = fabsl(y);
249 » » ya = fabsl(y); 218 ya = floorl(0.5 * ya);
250 » » ya = floorl(0.5 * ya); 219 yb = 0.5 * fabsl(w);
251 » » yb = 0.5 * fabsl(w); 220 if (ya != yb)
252 » » if( ya != yb ) 221 yoddint = 1;
253 » » » yoddint = 1; 222 }
254 » } 223
255 224 if (x <= -LDBL_MAX) {
256 » if (x <= -LDBL_MAX) { 225 if (y > 0.0) {
257 » » if (y > 0.0) { 226 if (yoddint)
258 » » » if (yoddint) 227 return -INFINITY;
259 » » » » return -INFINITY; 228 return INFINITY;
260 » » » return INFINITY; 229 }
261 » » } 230 if (y < 0.0) {
262 » » if (y < 0.0) { 231 if (yoddint)
263 » » » if (yoddint) 232 return -0.0;
264 » » » » return -0.0; 233 return 0.0;
265 » » » return 0.0; 234 }
266 » » } 235 }
267 » } 236 nflg = 0; /* (x<0)**(odd int) */
268 » nflg = 0; /* (x<0)**(odd int) */ 237 if (x <= 0.0) {
269 » if (x <= 0.0) { 238 if (x == 0.0) {
270 » » if (x == 0.0) { 239 if (y < 0.0) {
271 » » » if (y < 0.0) { 240 if (signbit(x) && yoddint)
272 » » » » if (signbit(x) && yoddint) 241 /* (-0.0)**(-odd int) = -inf, divbyzero */
273 » » » » » /* (-0.0)**(-odd int) = -inf, divbyzero */ 242 return -1.0 / 0.0;
274 » » » » » return -1.0/0.0; 243 /* (+-0.0)**(negative) = inf, divbyzero */
275 » » » » /* (+-0.0)**(negative) = inf, divbyzero */ 244 return 1.0 / 0.0;
276 » » » » return 1.0/0.0; 245 }
277 » » » } 246 if (signbit(x) && yoddint)
278 » » » if (signbit(x) && yoddint) 247 return -0.0;
279 » » » » return -0.0; 248 return 0.0;
280 » » » return 0.0; 249 }
281 » » } 250 if (iyflg == 0)
282 » » if (iyflg == 0) 251 return (x - x) / (x - x); /* (x<0)**(non-int) is NaN */
283 » » » return (x - x) / (x - x); /* (x<0)**(non-int) is NaN */ 252 /* (x<0)**(integer) */
284 » » /* (x<0)**(integer) */ 253 if (yoddint)
285 » » if (yoddint) 254 nflg = 1; /* negate result */
286 » » » nflg = 1; /* negate result */ 255 x = -x;
287 » » x = -x; 256 }
288 » } 257 /* (+integer)**(integer) */
289 » /* (+integer)**(integer) */ 258 if (iyflg && floorl(x) == x && fabsl(y) < 32768.0) {
290 » if (iyflg && floorl(x) == x && fabsl(y) < 32768.0) { 259 w = powil(x, (int)y);
291 » » w = powil(x, (int)y); 260 return nflg ? -w : w;
292 » » return nflg ? -w : w; 261 }
293 » } 262
294 263 /* separate significand from exponent */
295 » /* separate significand from exponent */ 264 x = frexpl(x, &i);
296 » x = frexpl(x, &i); 265 e = i;
297 » e = i; 266
298 267 /* find significand in antilog table A[] */
299 » /* find significand in antilog table A[] */ 268 i = 1;
300 » i = 1; 269 if (x <= A[17])
301 » if (x <= A[17]) 270 i = 17;
302 » » i = 17; 271 if (x <= A[i + 8])
303 » if (x <= A[i+8]) 272 i += 8;
304 » » i += 8; 273 if (x <= A[i + 4])
305 » if (x <= A[i+4]) 274 i += 4;
306 » » i += 4; 275 if (x <= A[i + 2])
307 » if (x <= A[i+2]) 276 i += 2;
308 » » i += 2; 277 if (x >= A[1])
309 » if (x >= A[1]) 278 i = -1;
310 » » i = -1; 279 i += 1;
311 » i += 1; 280
312 281 /* Find (x - A[i])/A[i]
313 » /* Find (x - A[i])/A[i] 282 * in order to compute log(x/A[i]):
314 » * in order to compute log(x/A[i]): 283 *
315 » * 284 * log(x) = log( a x/a ) = log(a) + log(x/a)
316 » * log(x) = log( a x/a ) = log(a) + log(x/a) 285 *
317 » * 286 * log(x/a) = log(1+v), v = x/a - 1 = (x-a)/a
318 » * log(x/a) = log(1+v), v = x/a - 1 = (x-a)/a 287 */
319 » */ 288 x -= A[i];
320 » x -= A[i]; 289 x -= B[i / 2];
321 » x -= B[i/2]; 290 x /= A[i];
322 » x /= A[i]; 291
323 292 /* rational approximation for log(1+v):
324 » /* rational approximation for log(1+v): 293 *
325 » * 294 * log(1+v) = v - v**2/2 + v**3 P(v) / Q(v)
326 » * log(1+v) = v - v**2/2 + v**3 P(v) / Q(v) 295 */
327 » */ 296 z = x * x;
328 » z = x*x; 297 w = x * (z * __polevll(x, P, 3) / __p1evll(x, Q, 3));
329 » w = x * (z * __polevll(x, P, 3) / __p1evll(x, Q, 3)); 298 w = w - 0.5 * z;
330 » w = w - 0.5*z; 299
331 300 /* Convert to base 2 logarithm:
332 » /* Convert to base 2 logarithm: 301 * multiply by log2(e) = 1 + LOG2EA
333 » * multiply by log2(e) = 1 + LOG2EA 302 */
334 » */ 303 z = LOG2EA * w;
335 » z = LOG2EA * w; 304 z += w;
336 » z += w; 305 z += LOG2EA * x;
337 » z += LOG2EA * x; 306 z += x;
338 » z += x; 307
339 308 /* Compute exponent term of the base 2 logarithm. */
340 » /* Compute exponent term of the base 2 logarithm. */ 309 w = -i;
341 » w = -i; 310 w /= NXT;
342 » w /= NXT; 311 w += e;
343 » w += e; 312 /* Now base 2 log of x is w + z. */
344 » /* Now base 2 log of x is w + z. */ 313
345 314 /* Multiply base 2 log by y, in extended precision. */
346 » /* Multiply base 2 log by y, in extended precision. */ 315
347 316 /* separate y into large part ya
348 » /* separate y into large part ya 317 * and small part yb less than 1/NXT
349 » * and small part yb less than 1/NXT 318 */
350 » */ 319 ya = reducl(y);
351 » ya = reducl(y); 320 yb = y - ya;
352 » yb = y - ya; 321
353 322 /* (w+z)(ya+yb)
354 » /* (w+z)(ya+yb) 323 * = w*ya + w*yb + z*y
355 » * = w*ya + w*yb + z*y 324 */
356 » */ 325 F = z * y + w * yb;
357 » F = z * y + w * yb; 326 Fa = reducl(F);
358 » Fa = reducl(F); 327 Fb = F - Fa;
359 » Fb = F - Fa; 328
360 329 G = Fa + w * ya;
361 » G = Fa + w * ya; 330 Ga = reducl(G);
362 » Ga = reducl(G); 331 Gb = G - Ga;
363 » Gb = G - Ga; 332
364 333 H = Fb + Gb;
365 » H = Fb + Gb; 334 Ha = reducl(H);
366 » Ha = reducl(H); 335 w = (Ga + Ha) * NXT;
367 » w = (Ga + Ha) * NXT; 336
368 337 /* Test the power of 2 for overflow */
369 » /* Test the power of 2 for overflow */ 338 if (w > MEXP)
370 » if (w > MEXP) 339 return huge * huge; /* overflow */
371 » » return huge * huge; /* overflow */ 340 if (w < MNEXP)
372 » if (w < MNEXP) 341 return twom10000 * twom10000; /* underflow */
373 » » return twom10000 * twom10000; /* underflow */ 342
374 343 e = w;
375 » e = w; 344 Hb = H - Ha;
376 » Hb = H - Ha; 345
377 346 if (Hb > 0.0) {
378 » if (Hb > 0.0) { 347 e += 1;
379 » » e += 1; 348 Hb -= 1.0 / NXT; /*0.0625L;*/
380 » » Hb -= 1.0/NXT; /*0.0625L;*/ 349 }
381 » } 350
382 351 /* Now the product y * log2(x) = Hb + e/NXT.
383 » /* Now the product y * log2(x) = Hb + e/NXT. 352 *
384 » * 353 * Compute base 2 exponential of Hb,
385 » * Compute base 2 exponential of Hb, 354 * where -0.0625 <= Hb <= 0.
386 » * where -0.0625 <= Hb <= 0. 355 */
387 » */ 356 z = Hb * __polevll(Hb, R, 6); /* z = 2**Hb - 1 */
388 » z = Hb * __polevll(Hb, R, 6); /* z = 2**Hb - 1 */ 357
389 358 /* Express e/NXT as an integer plus a negative number of (1/NXT)ths.
390 » /* Express e/NXT as an integer plus a negative number of (1/NXT)ths. 359 * Find lookup table entry for the fractional power of 2.
391 » * Find lookup table entry for the fractional power of 2. 360 */
392 » */ 361 if (e < 0)
393 » if (e < 0) 362 i = 0;
394 » » i = 0; 363 else
395 » else 364 i = 1;
396 » » i = 1; 365 i = e / NXT + i;
397 » i = e/NXT + i; 366 e = NXT * i - e;
398 » e = NXT*i - e; 367 w = A[e];
399 » w = A[e]; 368 z = w * z; /* 2**-e * ( 1 + (2**Hb-1) ) */
400 » z = w * z; /* 2**-e * ( 1 + (2**Hb-1) ) */ 369 z = z + w;
401 » z = z + w; 370 z = scalbnl(z, i); /* multiply by integer power of 2 */
402 » z = scalbnl(z, i); /* multiply by integer power of 2 */ 371
403 372 if (nflg)
404 » if (nflg) 373 z = -z;
405 » » z = -z; 374 return z;
406 » return z;
407 } 375 }
408 376
409
410 /* Find a multiple of 1/NXT that is within 1/NXT of x. */ 377 /* Find a multiple of 1/NXT that is within 1/NXT of x. */
411 static long double reducl(long double x) 378 static long double reducl(long double x) {
412 { 379 long double t;
413 » long double t; 380
414 381 t = x * NXT;
415 » t = x * NXT; 382 t = floorl(t);
416 » t = floorl(t); 383 t = t / NXT;
417 » t = t / NXT; 384 return t;
418 » return t;
419 } 385 }
420 386
421 /* 387 /*
422 * Positive real raised to integer power, long double precision 388 * Positive real raised to integer power, long double precision
423 * 389 *
424 * 390 *
425 * SYNOPSIS: 391 * SYNOPSIS:
426 * 392 *
427 * long double x, y, powil(); 393 * long double x, y, powil();
428 * int n; 394 * int n;
(...skipping 14 matching lines...) Expand all
443 * 409 *
444 * Relative error: 410 * Relative error:
445 * arithmetic x domain n domain # trials peak rms 411 * arithmetic x domain n domain # trials peak rms
446 * IEEE .001,1000 -1022,1023 50000 4.3e-17 7.8e-18 412 * IEEE .001,1000 -1022,1023 50000 4.3e-17 7.8e-18
447 * IEEE 1,2 -1022,1023 20000 3.9e-17 7.6e-18 413 * IEEE 1,2 -1022,1023 20000 3.9e-17 7.6e-18
448 * IEEE .99,1.01 0,8700 10000 3.6e-16 7.2e-17 414 * IEEE .99,1.01 0,8700 10000 3.6e-16 7.2e-17
449 * 415 *
450 * Returns MAXNUM on overflow, zero on underflow. 416 * Returns MAXNUM on overflow, zero on underflow.
451 */ 417 */
452 418
453 static long double powil(long double x, int nn) 419 static long double powil(long double x, int nn) {
454 { 420 long double ww, y;
455 » long double ww, y; 421 long double s;
456 » long double s; 422 int n, e, sign, lx;
457 » int n, e, sign, lx;
458 423
459 » if (nn == 0) 424 if (nn == 0)
460 » » return 1.0; 425 return 1.0;
461 426
462 » if (nn < 0) { 427 if (nn < 0) {
463 » » sign = -1; 428 sign = -1;
464 » » n = -nn; 429 n = -nn;
465 » } else { 430 } else {
466 » » sign = 1; 431 sign = 1;
467 » » n = nn; 432 n = nn;
468 » } 433 }
469 434
470 » /* Overflow detection */ 435 /* Overflow detection */
471 436
472 » /* Calculate approximate logarithm of answer */ 437 /* Calculate approximate logarithm of answer */
473 » s = x; 438 s = x;
474 » s = frexpl( s, &lx); 439 s = frexpl(s, &lx);
475 » e = (lx - 1)*n; 440 e = (lx - 1) * n;
476 » if ((e == 0) || (e > 64) || (e < -64)) { 441 if ((e == 0) || (e > 64) || (e < -64)) {
477 » » s = (s - 7.0710678118654752e-1L) / (s + 7.0710678118654752e-1L) ; 442 s = (s - 7.0710678118654752e-1L) / (s + 7.0710678118654752e-1L);
478 » » s = (2.9142135623730950L * s - 0.5 + lx) * nn * LOGE2L; 443 s = (2.9142135623730950L * s - 0.5 + lx) * nn * LOGE2L;
479 » } else { 444 } else {
480 » » s = LOGE2L * e; 445 s = LOGE2L * e;
481 » } 446 }
482 447
483 » if (s > MAXLOGL) 448 if (s > MAXLOGL)
484 » » return huge * huge; /* overflow */ 449 return huge * huge; /* overflow */
485 450
486 » if (s < MINLOGL) 451 if (s < MINLOGL)
487 » » return twom10000 * twom10000; /* underflow */ 452 return twom10000 * twom10000; /* underflow */
488 » /* Handle tiny denormal answer, but with less accuracy 453 /* Handle tiny denormal answer, but with less accuracy
489 » * since roundoff error in 1.0/x will be amplified. 454 * since roundoff error in 1.0/x will be amplified.
490 » * The precise demarcation should be the gradual underflow threshold. 455 * The precise demarcation should be the gradual underflow threshold.
491 » */ 456 */
492 » if (s < -MAXLOGL+2.0) { 457 if (s < -MAXLOGL + 2.0) {
493 » » x = 1.0/x; 458 x = 1.0 / x;
494 » » sign = -sign; 459 sign = -sign;
495 » } 460 }
496 461
497 » /* First bit of the power */ 462 /* First bit of the power */
498 » if (n & 1) 463 if (n & 1)
499 » » y = x; 464 y = x;
500 » else 465 else
501 » » y = 1.0; 466 y = 1.0;
502 467
503 » ww = x; 468 ww = x;
504 » n >>= 1; 469 n >>= 1;
505 » while (n) { 470 while (n) {
506 » » ww = ww * ww; /* arg to the 2-to-the-kth power */ 471 ww = ww * ww; /* arg to the 2-to-the-kth power */
507 » » if (n & 1) /* if that bit is set, then include in product */ 472 if (n & 1) /* if that bit is set, then include in product */
508 » » » y *= ww; 473 y *= ww;
509 » » n >>= 1; 474 n >>= 1;
510 » } 475 }
511 476
512 » if (sign < 0) 477 if (sign < 0)
513 » » y = 1.0/y; 478 y = 1.0 / y;
514 » return y; 479 return y;
515 } 480 }
516 #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 481 #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
517 // TODO: broken implementation to make things compile 482 // TODO: broken implementation to make things compile
518 long double powl(long double x, long double y) 483 long double powl(long double x, long double y) {
519 { 484 return pow(x, y);
520 » return pow(x, y);
521 } 485 }
522 #endif 486 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698