/***
* @license
* https://github.com/ealmansi/elen
* Copyright (c) 2017 Emilio Almansi
* Distributed under the MIT software license, see the accompanying
* file LICENSE or http://www.opensource.org/licenses/mit-license.php.
*/
const MAX_EXPONENT = 2047
const MAX_MANTISSA = 4503599627370495
/**
* Constructs a JavaScript number given the values for the sign, exponent,
* and mantissa in its binary64 representation.
*
* @param {object} - Containing: sign, exponent, mantissa.
*/
function construct({ sign, exponent, mantissa }) {
const buffer = new ArrayBuffer(8)
const floatArray = new Float64Array(buffer)
const intArray = new Uint8Array(buffer)
set_sign(sign, intArray)
set_exponent(exponent, intArray)
set_mantissa(mantissa, intArray)
return floatArray[0]
}
/**
* Returns an object with the values for the sign, exponent, and mantissa
* in the binary64 representation of the number n.
*
* @param {number} n
* @returns {object}
* @throws {InvalidArgumentException}
*/
function deconstruct(n) {
const buffer = new ArrayBuffer(8)
const floatArray = new Float64Array(buffer)
const intArray = new Uint8Array(buffer)
floatArray[0] = n
return {
sign: getSign(intArray),
exponent: getExponent(intArray),
mantissa: getMantissa(intArray),
}
}
function getSign(intArray) {
return intArray[7] >> 7
}
function set_sign(sign, intArray) {
intArray[7] |= (sign << 7)
}
function getExponent(intArray) {
let r = 0
r += (intArray[7] & 0x7F) << 4
r += intArray[6] >> 4
return r
}
function set_exponent(exponent, intArray) {
intArray[7] |= exponent >> 4
intArray[6] |= (exponent & 0xF) << 4
}
function getMantissa(intArray) {
let r = 0
r += (intArray[6] & 0x0F) * Math.pow(2, 48)
r += intArray[5] * Math.pow(2, 40)
r += intArray[4] * Math.pow(2, 32)
r += intArray[3] * Math.pow(2, 24)
r += intArray[2] * Math.pow(2, 16)
r += intArray[1] * Math.pow(2, 8)
r += intArray[0]
return r
}
function set_mantissa(mantissa, intArray) {
intArray[6] |= (mantissa / Math.pow(2, 48)) & 0xFF
intArray[5] |= (mantissa / Math.pow(2, 40)) & 0xFF
intArray[4] |= (mantissa / Math.pow(2, 32)) & 0xFF
intArray[3] |= (mantissa / Math.pow(2, 24)) & 0xFF
intArray[2] |= (mantissa / Math.pow(2, 16)) & 0xFF
intArray[1] |= (mantissa / Math.pow(2, 8)) & 0xFF
intArray[0] |= mantissa & 0xFF
}
module.exports = { MAX_EXPONENT, MAX_MANTISSA, construct, deconstruct }