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

Side by Side Diff: src/base/ieee754.cc

Issue 2065503002: [builtins] Introduce proper Float64Atan and Float64Atan2 operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: [WIP] Fix GCC/Win32. Created 4 years, 6 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
« no previous file with comments | « src/base/ieee754.h ('k') | src/bootstrapper.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // The following is adapted from fdlibm (http://www.netlib.org/fdlibm). 1 // The following is adapted from fdlibm (http://www.netlib.org/fdlibm).
2 // 2 //
3 // ==================================================== 3 // ====================================================
4 // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 4 // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 // 5 //
6 // Developed at SunSoft, a Sun Microsystems, Inc. business. 6 // Developed at SunSoft, a Sun Microsystems, Inc. business.
7 // Permission to use, copy, modify, and distribute this 7 // Permission to use, copy, modify, and distribute this
8 // software is freely granted, provided that this notice 8 // software is freely granted, provided that this notice
9 // is preserved. 9 // is preserved.
10 // ==================================================== 10 // ====================================================
11 // 11 //
12 // The original source code covered by the above license above has been 12 // The original source code covered by the above license above has been
13 // modified significantly by Google Inc. 13 // modified significantly by Google Inc.
14 // Copyright 2016 the V8 project authors. All rights reserved. 14 // Copyright 2016 the V8 project authors. All rights reserved.
15 15
16 #include "src/base/ieee754.h" 16 #include "src/base/ieee754.h"
17 17
18 #include <cmath>
18 #include <limits> 19 #include <limits>
19 20
20 #include "src/base/build_config.h" 21 #include "src/base/build_config.h"
21 #include "src/base/macros.h" 22 #include "src/base/macros.h"
22 23
23 namespace v8 { 24 namespace v8 {
24 namespace base { 25 namespace base {
25 namespace ieee754 { 26 namespace ieee754 {
26 27
27 namespace { 28 namespace {
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 sl_u.parts.lsw = (v); \ 163 sl_u.parts.lsw = (v); \
163 (d) = sl_u.value; \ 164 (d) = sl_u.value; \
164 } while (0) 165 } while (0)
165 166
166 /* Support macro. */ 167 /* Support macro. */
167 168
168 #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval)) 169 #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval))
169 170
170 } // namespace 171 } // namespace
171 172
173 /* atan(x)
174 * Method
175 * 1. Reduce x to positive by atan(x) = -atan(-x).
176 * 2. According to the integer k=4t+0.25 chopped, t=x, the argument
177 * is further reduced to one of the following intervals and the
178 * arctangent of t is evaluated by the corresponding formula:
179 *
180 * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
181 * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
182 * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
183 * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
184 * [39/16,INF] atan(x) = atan(INF) + atan( -1/t )
185 *
186 * Constants:
187 * The hexadecimal values are the intended ones for the following
188 * constants. The decimal values may be used, provided that the
189 * compiler will convert from decimal to binary accurately enough
190 * to produce the hexadecimal values shown.
191 */
192 double atan(double x) {
193 static const double atanhi[] = {
194 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
195 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
196 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
197 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
198 };
199
200 static const double atanlo[] = {
201 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
202 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
203 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
204 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
205 };
206
207 static const double aT[] = {
208 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
209 -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
210 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
211 -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
212 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
213 -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
214 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
215 -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
216 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
217 -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
218 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
219 };
220
221 static const double one = 1.0, huge = 1.0e300;
222
223 double w, s1, s2, z;
224 int32_t ix, hx, id;
225
226 GET_HIGH_WORD(hx, x);
227 ix = hx & 0x7fffffff;
228 if (ix >= 0x44100000) { /* if |x| >= 2^66 */
229 u_int32_t low;
230 GET_LOW_WORD(low, x);
231 if (ix > 0x7ff00000 || (ix == 0x7ff00000 && (low != 0)))
232 return x + x; /* NaN */
233 if (hx > 0)
234 return atanhi[3] + *(volatile double *)&atanlo[3];
235 else
236 return -atanhi[3] - *(volatile double *)&atanlo[3];
237 }
238 if (ix < 0x3fdc0000) { /* |x| < 0.4375 */
239 if (ix < 0x3e400000) { /* |x| < 2^-27 */
240 if (huge + x > one) return x; /* raise inexact */
241 }
242 id = -1;
243 } else {
244 x = fabs(x);
245 if (ix < 0x3ff30000) { /* |x| < 1.1875 */
246 if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */
247 id = 0;
248 x = (2.0 * x - one) / (2.0 + x);
249 } else { /* 11/16<=|x|< 19/16 */
250 id = 1;
251 x = (x - one) / (x + one);
252 }
253 } else {
254 if (ix < 0x40038000) { /* |x| < 2.4375 */
255 id = 2;
256 x = (x - 1.5) / (one + 1.5 * x);
257 } else { /* 2.4375 <= |x| < 2^66 */
258 id = 3;
259 x = -1.0 / x;
260 }
261 }
262 }
263 /* end of argument reduction */
264 z = x * x;
265 w = z * z;
266 /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
267 s1 = z * (aT[0] +
268 w * (aT[2] + w * (aT[4] + w * (aT[6] + w * (aT[8] + w * aT[10])))));
269 s2 = w * (aT[1] + w * (aT[3] + w * (aT[5] + w * (aT[7] + w * aT[9]))));
270 if (id < 0) {
271 return x - x * (s1 + s2);
272 } else {
273 z = atanhi[id] - ((x * (s1 + s2) - atanlo[id]) - x);
274 return (hx < 0) ? -z : z;
275 }
276 }
277
278 /* atan2(y,x)
279 * Method :
280 * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
281 * 2. Reduce x to positive by (if x and y are unexceptional):
282 * ARG (x+iy) = arctan(y/x) ... if x > 0,
283 * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
284 *
285 * Special cases:
286 *
287 * ATAN2((anything), NaN ) is NaN;
288 * ATAN2(NAN , (anything) ) is NaN;
289 * ATAN2(+-0, +(anything but NaN)) is +-0 ;
290 * ATAN2(+-0, -(anything but NaN)) is +-pi ;
291 * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
292 * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
293 * ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
294 * ATAN2(+-INF,+INF ) is +-pi/4 ;
295 * ATAN2(+-INF,-INF ) is +-3pi/4;
296 * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
297 *
298 * Constants:
299 * The hexadecimal values are the intended ones for the following
300 * constants. The decimal values may be used, provided that the
301 * compiler will convert from decimal to binary accurately enough
302 * to produce the hexadecimal values shown.
303 */
304 double atan2(double y, double x) {
305 static volatile double tiny = 1.0e-300;
306 static const double
307 zero = 0.0,
308 pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */
309 pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */
310 pi = 3.1415926535897931160E+00; /* 0x400921FB, 0x54442D18 */
311 static volatile double pi_lo =
312 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
313
314 double z;
315 int32_t k, m, hx, hy, ix, iy;
316 u_int32_t lx, ly;
317
318 EXTRACT_WORDS(hx, lx, x);
319 ix = hx & 0x7fffffff;
320 EXTRACT_WORDS(hy, ly, y);
321 iy = hy & 0x7fffffff;
322 if (((ix | ((lx | -static_cast<int32_t>(lx)) >> 31)) > 0x7ff00000) ||
323 ((iy | ((ly | -static_cast<int32_t>(ly)) >> 31)) > 0x7ff00000)) {
324 return x + y; /* x or y is NaN */
325 }
326 if (((hx - 0x3ff00000) | lx) == 0) return atan(y); /* x=1.0 */
327 m = ((hy >> 31) & 1) | ((hx >> 30) & 2); /* 2*sign(x)+sign(y) */
328
329 /* when y = 0 */
330 if ((iy | ly) == 0) {
331 switch (m) {
332 case 0:
333 case 1:
334 return y; /* atan(+-0,+anything)=+-0 */
335 case 2:
336 return pi + tiny; /* atan(+0,-anything) = pi */
337 case 3:
338 return -pi - tiny; /* atan(-0,-anything) =-pi */
339 }
340 }
341 /* when x = 0 */
342 if ((ix | lx) == 0) return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny;
343
344 /* when x is INF */
345 if (ix == 0x7ff00000) {
346 if (iy == 0x7ff00000) {
347 switch (m) {
348 case 0:
349 return pi_o_4 + tiny; /* atan(+INF,+INF) */
350 case 1:
351 return -pi_o_4 - tiny; /* atan(-INF,+INF) */
352 case 2:
353 return 3.0 * pi_o_4 + tiny; /*atan(+INF,-INF)*/
354 case 3:
355 return -3.0 * pi_o_4 - tiny; /*atan(-INF,-INF)*/
356 }
357 } else {
358 switch (m) {
359 case 0:
360 return zero; /* atan(+...,+INF) */
361 case 1:
362 return -zero; /* atan(-...,+INF) */
363 case 2:
364 return pi + tiny; /* atan(+...,-INF) */
365 case 3:
366 return -pi - tiny; /* atan(-...,-INF) */
367 }
368 }
369 }
370 /* when y is INF */
371 if (iy == 0x7ff00000) return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny;
372
373 /* compute y/x */
374 k = (iy - ix) >> 20;
375 if (k > 60) { /* |y/x| > 2**60 */
376 z = pi_o_2 + 0.5 * pi_lo;
377 m &= 1;
378 } else if (hx < 0 && k < -60) {
379 z = 0.0; /* 0 > |y|/x > -2**-60 */
380 } else {
381 z = atan(fabs(y / x)); /* safe to do y/x */
382 }
383 switch (m) {
384 case 0:
385 return z; /* atan(+,+) */
386 case 1:
387 return -z; /* atan(-,+) */
388 case 2:
389 return pi - (z - pi_lo); /* atan(+,-) */
390 default: /* case 3 */
391 return (z - pi_lo) - pi; /* atan(-,-) */
392 }
393 }
394
172 /* log(x) 395 /* log(x)
173 * Return the logrithm of x 396 * Return the logrithm of x
174 * 397 *
175 * Method : 398 * Method :
176 * 1. Argument Reduction: find k and f such that 399 * 1. Argument Reduction: find k and f such that
177 * x = 2^k * (1+f), 400 * x = 2^k * (1+f),
178 * where sqrt(2)/2 < 1+f < sqrt(2) . 401 * where sqrt(2)/2 < 1+f < sqrt(2) .
179 * 402 *
180 * 2. Approximation of log(1+f). 403 * 2. Approximation of log(1+f).
181 * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) 404 * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 z * (Lp2 + z * (Lp3 + z * (Lp4 + z * (Lp5 + z * (Lp6 + z * Lp7)))))); 681 z * (Lp2 + z * (Lp3 + z * (Lp4 + z * (Lp5 + z * (Lp6 + z * Lp7))))));
459 if (k == 0) 682 if (k == 0)
460 return f - (hfsq - s * (hfsq + R)); 683 return f - (hfsq - s * (hfsq + R));
461 else 684 else
462 return k * ln2_hi - ((hfsq - (s * (hfsq + R) + (k * ln2_lo + c))) - f); 685 return k * ln2_hi - ((hfsq - (s * (hfsq + R) + (k * ln2_lo + c))) - f);
463 } 686 }
464 687
465 } // namespace ieee754 688 } // namespace ieee754
466 } // namespace base 689 } // namespace base
467 } // namespace v8 690 } // namespace v8
OLDNEW
« no previous file with comments | « src/base/ieee754.h ('k') | src/bootstrapper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698