You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

83 lines
2.5 KiB

'use strict';
const { assert } = require('./assert');
const { hexDecode, hexEncodeLower } = require('./hex');
// Split an IEEE double given as a big endian Uint8Array into logical components.
// Mantissa can be represented accurately as a double.
function splitU8Double(u8) {
assert(u8 instanceof Uint8Array);
assert(u8.length === 8);
var sign = (u8[0] & 0x80) >>> 7;
var exponent = ((u8[0] & 0x7f) << 4) + ((u8[1] & 0xf0) >>> 4);
var mantissa = (u8[1] & 0x0f) >>> 0;
for (let i = 2; i < 8; i++) {
mantissa = (mantissa * 256) + u8[i];
}
return { sign, exponent, mantissa };
}
exports.splitU8Double = splitU8Double;
function splitHexDouble(hexbytes) {
assert(typeof hexbytes === 'string');
var u8 = hexDecode(hexbytes);
if (u8.length !== 8) {
throw new TypeError('invalid bytes for double value: ' + hexbytes);
}
return splitU8Double(u8);
}
exports.splitHexDouble = splitHexDouble;
function splitDouble(v) {
assert(typeof v === 'number');
var u8 = new Uint8Array(8);
new DataView(u8.buffer).setFloat64(0, v);
return splitU8Double(u8);
}
exports.splitDouble = splitDouble;
function numberToDoubleHex(v) {
var ab = new ArrayBuffer(8);
var dv = new DataView(ab);
dv.setFloat64(0, v);
return hexEncodeLower(new Uint8Array(ab));
}
exports.numberToDoubleHex = numberToDoubleHex;
function isWhole(x) {
return typeof x === 'number' && !Number.isNaN(x) && Math.floor(x) === x;
}
exports.isWhole = isWhole;
function isWholeFinite(x) {
return isWhole(x) && x !== Number.POSITIVE_INFINITY && x !== Number.NEGATIVE_INFINITY;
}
exports.isWholeFinite = isWholeFinite;
function isPowerOfTwo(x) {
// For normals mantissa is zero because of an implicit leading 1-bit.
// Denormals are not whole numbers.
return isWholeFinite(x) && x > 0 && splitDouble(x).mantissa === 0;
}
exports.isPowerOfTwo = isPowerOfTwo;
// Shuffle bytes of a big endian double (Uint8Array) into indicated
// byte order.
function shuffleDoubleBytesFromBigEndian(src, dst, doubleByteOrder) {
assert(src instanceof Uint8Array);
assert(dst instanceof Uint8Array);
assert(src !== dst);
assert(typeof doubleByteOrder === 'string');
var indexList = ({
big: [ 0, 1, 2, 3, 4, 5, 6, 7 ],
little: [ 7, 6, 5, 4, 3, 2, 1, 0 ],
mixed: [ 3, 2, 1, 0, 7, 6, 5, 4 ]
})[doubleByteOrder];
assert(indexList);
for (let i = 0; i < indexList.length; i++) {
dst[i] = src[indexList[i]];
}
}
exports.shuffleDoubleBytesFromBigEndian = shuffleDoubleBytesFromBigEndian;