ripplelib
Version:
A JavaScript API for interacting with Ripple in Node.js and the browser
113 lines (98 loc) • 3.06 kB
JavaScript
// Convert a JavaScript number to IEEE-754 Double Precision
// value represented as an array of 8 bytes (octets)
//
// Based on:
// http://cautionsingularityahead.blogspot.com/2010/04/javascript-and-ieee754-redux.html
//
// Found and modified from:
// https://gist.github.com/bartaz/1119041
;
var Float = exports.Float = {};
Float.toIEEE754 = function (v, ebits, fbits) {
var bias = (1 << ebits - 1) - 1;
// Compute sign, exponent, fraction
var s, e, f;
if (isNaN(v)) {
e = (1 << bias) - 1;f = 1;s = 0;
} else if (v === Infinity || v === -Infinity) {
e = (1 << bias) - 1;f = 0;s = v < 0 ? 1 : 0;
} else if (v === 0) {
e = 0;f = 0;s = 1 / v === -Infinity ? 1 : 0;
} else {
s = v < 0;
v = Math.abs(v);
if (v >= Math.pow(2, 1 - bias)) {
var ln = Math.min(Math.floor(Math.log(v) / Math.LN2), bias);
e = ln + bias;
f = v * Math.pow(2, fbits - ln) - Math.pow(2, fbits);
} else {
e = 0;
f = v / Math.pow(2, 1 - bias - fbits);
}
}
// Pack sign, exponent, fraction
var i,
bits = [];
for (i = fbits; i; i -= 1) {
bits.push(f % 2 ? 1 : 0);f = Math.floor(f / 2);
}
for (i = ebits; i; i -= 1) {
bits.push(e % 2 ? 1 : 0);e = Math.floor(e / 2);
}
bits.push(s ? 1 : 0);
bits.reverse();
var str = bits.join('');
// Bits to bytes
var bytes = [];
while (str.length) {
bytes.push(parseInt(str.substring(0, 8), 2));
str = str.substring(8);
}
return bytes;
};
Float.fromIEEE754 = function (bytes, ebits, fbits) {
// Bytes to bits
var bits = [];
for (var i = bytes.length; i; i -= 1) {
var byte = bytes[i - 1];
for (var j = 8; j; j -= 1) {
bits.push(byte % 2 ? 1 : 0);byte = byte >> 1;
}
}
bits.reverse();
var str = bits.join('');
// Unpack sign, exponent, fraction
var bias = (1 << ebits - 1) - 1;
var s = parseInt(str.substring(0, 1), 2) ? -1 : 1;
var e = parseInt(str.substring(1, 1 + ebits), 2);
var f = parseInt(str.substring(1 + ebits), 2);
// Produce number
if (e === (1 << ebits) - 1) {
return f !== 0 ? NaN : s * Infinity;
} else if (e > 0) {
return s * Math.pow(2, e - bias) * (1 + f / Math.pow(2, fbits));
} else if (f !== 0) {
return s * Math.pow(2, -(bias - 1)) * (f / Math.pow(2, fbits));
} else {
return s * 0;
}
};
Float.fromIEEE754Double = function (b) {
return Float.fromIEEE754(b, 11, 52);
};
Float.toIEEE754Double = function (v) {
return Float.toIEEE754(v, 11, 52);
};
Float.fromIEEE754Single = function (b) {
return Float.fromIEEE754(b, 8, 23);
};
Float.toIEEE754Single = function (v) {
return Float.toIEEE754(v, 8, 23);
};
// Convert array of octets to string binary representation
// by bartaz
Float.toIEEE754DoubleString = function (v) {
return exports.toIEEE754Double(v).map(function (n) {
for (n = n.toString(2); n.length < 8; n = "0" + n);return n;
}).join('').replace(/(.)(.{11})(.{52})/, "$1 $2 $3");
};