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

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

Issue 2083573002: [builtins] Unify Cosh, Sinh and Tanh as exports from flibm (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE and windows fix. Created 4 years, 5 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 // ====================================================
(...skipping 2290 matching lines...) Expand 10 before | Expand all | Expand 10 after
2301 /* tan(Inf or NaN) is NaN */ 2301 /* tan(Inf or NaN) is NaN */
2302 return x - x; /* NaN */ 2302 return x - x; /* NaN */
2303 } else { 2303 } else {
2304 /* argument reduction needed */ 2304 /* argument reduction needed */
2305 n = __ieee754_rem_pio2(x, y); 2305 n = __ieee754_rem_pio2(x, y);
2306 /* 1 -> n even, -1 -> n odd */ 2306 /* 1 -> n even, -1 -> n odd */
2307 return __kernel_tan(y[0], y[1], 1 - ((n & 1) << 1)); 2307 return __kernel_tan(y[0], y[1], 1 - ((n & 1) << 1));
2308 } 2308 }
2309 } 2309 }
2310 2310
2311 /*
2312 * ES6 draft 09-27-13, section 20.2.2.12.
2313 * Math.cosh
2314 * Method :
2315 * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
2316 * 1. Replace x by |x| (cosh(x) = cosh(-x)).
2317 * 2.
2318 * [ exp(x) - 1 ]^2
2319 * 0 <= x <= ln2/2 : cosh(x) := 1 + -------------------
2320 * 2*exp(x)
2321 *
2322 * exp(x) + 1/exp(x)
2323 * ln2/2 <= x <= 22 : cosh(x) := -------------------
2324 * 2
2325 * 22 <= x <= lnovft : cosh(x) := exp(x)/2
2326 * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2)
2327 * ln2ovft < x : cosh(x) := huge*huge (overflow)
2328 *
2329 * Special cases:
2330 * cosh(x) is |x| if x is +INF, -INF, or NaN.
2331 * only cosh(0)=1 is exact for finite x.
2332 */
2333 double cosh(double x) {
2334 static const double KCOSH_OVERFLOW = 710.4758600739439;
2335 static const double one = 1.0, half = 0.5;
2336 static volatile double huge = 1.0e+300;
2337
2338 int32_t ix;
2339
2340 /* High word of |x|. */
2341 GET_HIGH_WORD(ix, x);
2342 ix &= 0x7fffffff;
2343
2344 // |x| in [0,0.5*log2], return 1+expm1(|x|)^2/(2*exp(|x|))
2345 if (ix < 0x3fd62e43) {
2346 double t = expm1(fabs(x));
2347 double w = one + t;
2348 // For |x| < 2^-55, cosh(x) = 1
2349 if (ix < 0x3c800000) return w;
2350 return one + (t * t) / (w + w);
2351 }
2352
2353 // |x| in [0.5*log2, 22], return (exp(|x|)+1/exp(|x|)/2
2354 if (ix < 0x40360000) {
2355 double t = exp(fabs(x));
2356 return half * t + half / t;
2357 }
2358
2359 // |x| in [22, log(maxdouble)], return half*exp(|x|)
2360 if (ix < 0x40862e42) return half * exp(fabs(x));
2361
2362 // |x| in [log(maxdouble), overflowthreshold]
2363 if (fabs(x) <= KCOSH_OVERFLOW) {
2364 double w = exp(half * fabs(x));
2365 double t = half * w;
2366 return t * w;
2367 }
2368
2369 /* x is INF or NaN */
2370 if (ix >= 0x7ff00000) return x * x;
2371
2372 // |x| > overflowthreshold.
2373 return huge * huge;
2374 }
2375
2376 /*
2377 * ES6 draft 09-27-13, section 20.2.2.30.
2378 * Math.sinh
2379 * Method :
2380 * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
2381 * 1. Replace x by |x| (sinh(-x) = -sinh(x)).
2382 * 2.
2383 * E + E/(E+1)
2384 * 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x)
2385 * 2
2386 *
2387 * 22 <= x <= lnovft : sinh(x) := exp(x)/2
2388 * lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2)
2389 * ln2ovft < x : sinh(x) := x*shuge (overflow)
2390 *
2391 * Special cases:
2392 * sinh(x) is |x| if x is +Infinity, -Infinity, or NaN.
2393 * only sinh(0)=0 is exact for finite x.
2394 */
2395 double sinh(double x) {
2396 static const double KSINH_OVERFLOW = 710.4758600739439,
2397 TWO_M28 =
2398 3.725290298461914e-9, // 2^-28, empty lower half
2399 LOG_MAXD = 709.7822265625; // 0x40862e42 00000000, empty lower half
2400 static const double shuge = 1.0e307;
2401
2402 double h = (x < 0) ? -0.5 : 0.5;
2403 // |x| in [0, 22]. return sign(x)*0.5*(E+E/(E+1))
2404 double ax = fabs(x);
2405 if (ax < 22) {
2406 // For |x| < 2^-28, sinh(x) = x
2407 if (ax < TWO_M28) return x;
2408 double t = expm1(ax);
2409 if (ax < 1) {
2410 return h * (2 * t - t * t / (t + 1));
2411 }
2412 return h * (t + t / (t + 1));
2413 }
2414 // |x| in [22, log(maxdouble)], return 0.5 * exp(|x|)
2415 if (ax < LOG_MAXD) return h * exp(ax);
2416 // |x| in [log(maxdouble), overflowthreshold]
2417 // overflowthreshold = 710.4758600739426
2418 if (ax <= KSINH_OVERFLOW) {
2419 double w = exp(0.5 * ax);
2420 double t = h * w;
2421 return t * w;
2422 }
2423 // |x| > overflowthreshold or is NaN.
2424 // Return Infinity of the appropriate sign or NaN.
2425 return x * shuge;
2426 }
2427
2428 /* Tanh(x)
2429 * Return the Hyperbolic Tangent of x
2430 *
2431 * Method :
2432 * x -x
2433 * e - e
2434 * 0. tanh(x) is defined to be -----------
2435 * x -x
2436 * e + e
2437 * 1. reduce x to non-negative by tanh(-x) = -tanh(x).
2438 * 2. 0 <= x < 2**-28 : tanh(x) := x with inexact if x != 0
2439 * -t
2440 * 2**-28 <= x < 1 : tanh(x) := -----; t = expm1(-2x)
2441 * t + 2
2442 * 2
2443 * 1 <= x < 22 : tanh(x) := 1 - -----; t = expm1(2x)
2444 * t + 2
2445 * 22 <= x <= INF : tanh(x) := 1.
2446 *
2447 * Special cases:
2448 * tanh(NaN) is NaN;
2449 * only tanh(0)=0 is exact for finite argument.
2450 */
2451 double tanh(double x) {
2452 static const volatile double tiny = 1.0e-300;
2453 static const double one = 1.0, two = 2.0, huge = 1.0e300;
2454 double t, z;
2455 int32_t jx, ix;
2456
2457 GET_HIGH_WORD(jx, x);
2458 ix = jx & 0x7fffffff;
2459
2460 /* x is INF or NaN */
2461 if (ix >= 0x7ff00000) {
2462 if (jx >= 0)
2463 return one / x + one; /* tanh(+-inf)=+-1 */
2464 else
2465 return one / x - one; /* tanh(NaN) = NaN */
2466 }
2467
2468 /* |x| < 22 */
2469 if (ix < 0x40360000) { /* |x|<22 */
2470 if (ix < 0x3e300000) { /* |x|<2**-28 */
2471 if (huge + x > one) return x; /* tanh(tiny) = tiny with inexact */
2472 }
2473 if (ix >= 0x3ff00000) { /* |x|>=1 */
2474 t = expm1(two * fabs(x));
2475 z = one - two / (t + two);
2476 } else {
2477 t = expm1(-two * fabs(x));
2478 z = -t / (t + two);
2479 }
2480 /* |x| >= 22, return +-1 */
2481 } else {
2482 z = one - tiny; /* raise inexact flag */
2483 }
2484 return (jx >= 0) ? z : -z;
2485 }
2486
2311 } // namespace ieee754 2487 } // namespace ieee754
2312 } // namespace base 2488 } // namespace base
2313 } // namespace v8 2489 } // 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