From b1f6284813da96bd257f4f5479deab115f8e15c2 Mon Sep 17 00:00:00 2001 From: Geert Weening Date: Tue, 27 May 2014 15:12:52 -0700 Subject: [PATCH] [CHORE] add IEEE-754 Double Precision float support for an 8 byte representation of floats --- src/js/ripple/ieee754.js | 107 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/js/ripple/ieee754.js diff --git a/src/js/ripple/ieee754.js b/src/js/ripple/ieee754.js new file mode 100644 index 00000000..d5d61878 --- /dev/null +++ b/src/js/ripple/ieee754.js @@ -0,0 +1,107 @@ +// 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") +} \ No newline at end of file