time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

exp10.js (3442B)


      1 /**
      2 * @license Apache-2.0
      3 *
      4 * Copyright (c) 2018 The Stdlib Authors.
      5 *
      6 * Licensed under the Apache License, Version 2.0 (the "License");
      7 * you may not use this file except in compliance with the License.
      8 * You may obtain a copy of the License at
      9 *
     10 *    http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing, software
     13 * distributed under the License is distributed on an "AS IS" BASIS,
     14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 * See the License for the specific language governing permissions and
     16 * limitations under the License.
     17 *
     18 *
     19 * ## Notice
     20 *
     21 * The original C code, long comment, copyright, license, and constants are from [Cephes]{@link http://www.netlib.org/cephes}. The implementation follows the original, but has been modified for JavaScript.
     22 *
     23 * ```text
     24 * Copyright 1984, 1991, 2000 by Stephen L. Moshier
     25 *
     26 * Some software in this archive may be from the book _Methods and Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster International, 1989) or from the Cephes Mathematical Library, a commercial product. In either event, it is copyrighted by the author. What you see here may be used freely but it comes with no support or guarantee.
     27 *
     28 * Stephen L. Moshier
     29 * moshier@na-net.ornl.gov
     30 * ```
     31 */
     32 
     33 'use strict';
     34 
     35 // MODULES //
     36 
     37 var floor = require( './../../../../base/special/floor' );
     38 var ldexp = require( './../../../../base/special/ldexp' );
     39 var isnan = require( './../../../../base/assert/is-nan' );
     40 var MAXL10 = require( '@stdlib/constants/float64/max-base10-exponent' );
     41 var MINL10 = require( '@stdlib/constants/float64/min-base10-exponent' );
     42 var PINF = require( '@stdlib/constants/float64/pinf' );
     43 var polyvalP = require( './polyval_p.js' );
     44 var polyvalQ = require( './polyval_q.js' );
     45 
     46 
     47 // VARIABLES //
     48 
     49 var LOG210 = 3.32192809488736234787e0;
     50 var LG102A = 3.01025390625000000000e-1;
     51 var LG102B = 4.60503898119521373889e-6;
     52 
     53 
     54 // MAIN //
     55 
     56 /**
     57 * Returns `10` raised to the `x` power.
     58 *
     59 * ## Method
     60 *
     61 * -   Range reduction is accomplished by expressing the argument as \\( 10^x = 2^n 10^f \\), with \\( |f| < 0.5 log_{10}(2) \\). The Pade' form
     62 *
     63 *     ```tex
     64 *     1 + 2x \frac{P(x^2)}{Q(x^2) - P(x^2)}
     65 *     ```
     66 *
     67 *     is used to approximate \\( 10^f \\).
     68 *
     69 *
     70 * ## Notes
     71 *
     72 * -   Relative error:
     73 *
     74 *     | arithmetic | domain      | # trials | peak    | rms     |
     75 *     |:----------:|:-----------:|:--------:|:-------:|:-------:|
     76 *     | IEEE       | -307,+307   |  30000   | 2.2e-16 | 5.5e-17 |
     77 *
     78 *
     79 * @param {number} x - input value
     80 * @returns {number} function value
     81 *
     82 * @example
     83 * var v = exp10( 3.0 );
     84 * // returns 1000.0
     85 *
     86 * @example
     87 * var v = exp10( -9.0 );
     88 * // returns 1.0e-9
     89 *
     90 * @example
     91 * var v = exp10( 0.0 );
     92 * // returns 1.0
     93 *
     94 * @example
     95 * var v = exp10( NaN );
     96 * // returns NaN
     97 */
     98 function exp10( x ) {
     99 	var px;
    100 	var xx;
    101 	var n;
    102 
    103 	if ( isnan( x ) ) {
    104 		return x;
    105 	}
    106 	if ( x > MAXL10 ) {
    107 		return PINF;
    108 	}
    109 	if ( x < MINL10 ) {
    110 		return 0.0;
    111 	}
    112 
    113 	// Express 10^x = 10^g 2^n = 10^g 10^( n log10(2) ) = 10^( g + n log10(2) )
    114 	px = floor( (LOG210*x) + 0.5 );
    115 	n = px;
    116 	x -= px * LG102A;
    117 	x -= px * LG102B;
    118 
    119 	// Rational approximation for exponential of the fractional part: 10^x = 1 + 2x P(x^2)/( Q(x^2) - P(x^2) )
    120 	xx = x * x;
    121 	px = x * polyvalP( xx );
    122 	x = px / ( polyvalQ( xx ) - px );
    123 	x = 1.0 + ldexp( x, 1 );
    124 
    125 	// Multiply by power of 2:
    126 	return ldexp( x, n );
    127 }
    128 
    129 
    130 // EXPORTS //
    131 
    132 module.exports = exp10;