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;