OLD | NEW |
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 Loading... |
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 |
OLD | NEW |