time-to-botec

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

main.js (3808B)


      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 PINF = require( '@stdlib/constants/float64/pinf' );
     24 var NINF = require( '@stdlib/constants/float64/ninf' );
     25 var BIAS = require( '@stdlib/constants/float64/exponent-bias' );
     26 var pow = require( '@stdlib/math/base/special/pow' );
     27 var toDouble = require( './todouble.js' );
     28 
     29 
     30 // MAIN //
     31 
     32 /**
     33 * Creates a double-precision floating-point number from a literal bit representation.
     34 *
     35 * @param {BinaryString} bstr - string which is a literal bit representation
     36 * @throws {Error} must provide a string with a length equal to `64`
     37 * @returns {number} double
     38 *
     39 * @example
     40 * var bstr = '0100000000010000000000000000000000000000000000000000000000000000';
     41 * var val = fromBinaryString( bstr );
     42 * // returns 4.0
     43 *
     44 * @example
     45 * var bstr = '0100000000001001001000011111101101010100010001000010110100011000';
     46 * var val = fromBinaryString( bstr );
     47 * // returns 3.141592653589793
     48 *
     49 * @example
     50 * var bstr = '1111111111100001110011001111001110000101111010111100100010100000';
     51 * var val = fromBinaryString( bstr );
     52 * // returns -1.0e308
     53 *
     54 * @example
     55 * var bstr = '1000000000000000000000000000000000000000000000000001100011010011';
     56 * var val = fromBinaryString( bstr );
     57 * // returns -3.14e-320
     58 *
     59 * @example
     60 * var bstr = '0000000000000000000000000000000000000000000000000000000000000001';
     61 * var val = fromBinaryString( bstr );
     62 * // returns 5.0e-324
     63 *
     64 * @example
     65 * var bstr = '0000000000000000000000000000000000000000000000000000000000000000';
     66 * var val = fromBinaryString( bstr );
     67 * // returns 0.0
     68 *
     69 * @example
     70 * var bstr = '1000000000000000000000000000000000000000000000000000000000000000';
     71 * var val = fromBinaryString( bstr );
     72 * // returns -0.0
     73 *
     74 * @example
     75 * var bstr = '0111111111111000000000000000000000000000000000000000000000000000';
     76 * var val = fromBinaryString( bstr );
     77 * // returns NaN
     78 *
     79 * @example
     80 * var bstr = '0111111111110000000000000000000000000000000000000000000000000000';
     81 * var val = fromBinaryString( bstr );
     82 * // returns Infinity
     83 *
     84 * @example
     85 * var bstr = '1111111111110000000000000000000000000000000000000000000000000000';
     86 * var val = fromBinaryString( bstr );
     87 * // returns -Infinity
     88 */
     89 function fromBinaryString( bstr ) {
     90 	var sign;
     91 	var frac;
     92 	var exp;
     93 
     94 	if ( bstr.length !== 64 ) {
     95 		throw new Error( 'invalid argument. Input string must have a length equal to 64. Value: `'+bstr+'`.' );
     96 	}
     97 	// Sign bit:
     98 	sign = ( bstr[0] === '1' ) ? -1.0 : 1.0;
     99 
    100 	// Exponent bits:
    101 	exp = parseInt( bstr.substring(1, 12), 2 ) - BIAS;
    102 
    103 	// Fraction bits:
    104 	frac = toDouble( bstr.substring( 12 ) );
    105 
    106 	// Detect `0` (all 0s) and subnormals (exponent bits are all 0, but fraction bits are not all 0s)...
    107 	if ( exp === -BIAS ) {
    108 		if ( frac === 0.0 ) {
    109 			return ( sign === 1.0 ) ? 0.0 : -0.0;
    110 		}
    111 		exp = -1022; // (1-BIAS); subnormals are special
    112 	}
    113 	// Detect `+-inf` (exponent bits are all 1 and fraction is 0) and `NaN` (exponent bits are all 1 and fraction is not 0)...
    114 	else if ( exp === BIAS+1 ) {
    115 		if ( frac === 0.0 ) {
    116 			return ( sign === 1.0 ) ? PINF : NINF;
    117 		}
    118 		return NaN;
    119 	}
    120 	// Normal numbers...
    121 	else {
    122 		// Account for hidden/implicit bit (2^0):
    123 		frac += 1.0;
    124 	}
    125 	return sign * frac * pow( 2.0, exp );
    126 }
    127 
    128 
    129 // EXPORTS //
    130 
    131 module.exports = fromBinaryString;