time-to-botec

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

frexp.js (3098B)


      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 'use strict';
     20 
     21 // MODULES //
     22 
     23 var isnan = require( './../../../../base/assert/is-nan' );
     24 var isInfinite = require( './../../../../base/assert/is-infinite' );
     25 var normalize = require( '@stdlib/number/float64/base/normalize' );
     26 var floatExp = require( '@stdlib/number/float64/base/exponent' );
     27 var toWords = require( '@stdlib/number/float64/base/to-words' );
     28 var fromWords = require( '@stdlib/number/float64/base/from-words' );
     29 
     30 
     31 // VARIABLES //
     32 
     33 // Exponent all 0s: 1 00000000000 11111111111111111111 => 2148532223
     34 var CLEAR_EXP_MASK = 0x800fffff>>>0; // asm type annotation
     35 
     36 // Exponent equal to 1022 (BIAS-1): 0 01111111110 00000000000000000000 => 1071644672
     37 var SET_EXP_MASK = 0x3fe00000|0; // asm type annotation
     38 
     39 // Normalization workspace:
     40 var X = [ 0.0, 0.0 ]; // WARNING: not thread safe
     41 
     42 // High/low words workspace:
     43 var WORDS = [ 0, 0 ]; // WARNING: not thread safe
     44 
     45 
     46 // MAIN //
     47 
     48 /**
     49 * Splits a double-precision floating-point number into a normalized fraction and an integer power of two.
     50 *
     51 * @private
     52 * @param {(Array|TypedArray|Object)} out - output array
     53 * @param {number} x - input value
     54 * @returns {(Array|TypedArray|Object)} output array
     55 *
     56 * @example
     57 * var out = frexp( new Array( 2 ), 4.0 );
     58 * // returns [ 0.5, 3 ]
     59 *
     60 * @example
     61 * var out = frexp( new Array( 2 ), 0.0 );
     62 * // returns [ 0.0, 0 ]
     63 *
     64 * @example
     65 * var out = frexp( new Array( 2 ), -0.0 );
     66 * // returns [ -0.0, 0 ]
     67 *
     68 * @example
     69 * var out = frexp( new Array( 2 ), NaN );
     70 * // returns [ NaN, 0 ]
     71 *
     72 * @example
     73 * var out = frexp( new Array( 2 ), Infinity );
     74 * // returns [ Infinity , 0 ]
     75 *
     76 * @example
     77 * var out = frexp( new Array( 2 ), -Infinity );
     78 * // returns [ -Infinity , 0 ]
     79 */
     80 function frexp( out, x ) {
     81 	var high;
     82 	var exp;
     83 	if (
     84 		x === 0.0 || // handles -0
     85 		isnan( x ) ||
     86 		isInfinite( x )
     87 	) {
     88 		out[ 0 ] = x;
     89 		out[ 1 ] = 0;
     90 		return out;
     91 	}
     92 	// If `x` is subnormal, normalize it...
     93 	normalize( X, x );
     94 
     95 	// Extract the exponent from `x` and add the normalization exponent:
     96 	exp = floatExp( X[0] ) + X[ 1 ] + 1;
     97 
     98 	// Break `x` into two unsigned 32-bit integers (higher and lower order words):
     99 	toWords( WORDS, X[ 0 ] );
    100 	high = WORDS[ 0 ];
    101 
    102 	// Clear the exponent bits within the higher order word:
    103 	high &= CLEAR_EXP_MASK;
    104 
    105 	// Set the exponent bits within the higher order word to BIAS-1 (1023-1=1022):
    106 	high |= SET_EXP_MASK;
    107 
    108 	// Create a new floating-point number:
    109 	x = fromWords( high, WORDS[ 1 ] );
    110 
    111 	out[ 0 ] = x;
    112 	out[ 1 ] = exp;
    113 	return out;
    114 }
    115 
    116 
    117 // EXPORTS //
    118 
    119 module.exports = frexp;