Javascript and IEEE754 Redux
Here's the logical evolution of the previously posted code. I wanted to handle single precision in addition to double precision, and did some extensive tidying. Sorry about the round-trips through strings - JavaScript bit operations are limited to 32 bits.
It now correctly handles all of the boundary values on this IEEE-754 reference page as far as possible.
It now correctly handles all of the boundary values on this IEEE-754 reference page as far as possible.
Don't use this - see the code in Typed Array Polyfill instead
function toIEEE754(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; } function fromIEEE754(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; } } function fromIEEE754Double(b) { return fromIEEE754(b, 11, 52); } function toIEEE754Double(v) { return toIEEE754(v, 11, 52); } function fromIEEE754Single(b) { return fromIEEE754(b, 8, 23); } function toIEEE754Single(v) { return toIEEE754(v, 8, 23); }
I'm building an MIT licensed packet parser for Node.js.
ReplyDeletehttp://github.com/bigeasy/node-packet
I'd like to use this code, as is in the library. Could you please make it available under the MIT License? It would be a great help.
I've subscribed to updates via email for this thread, so you can respond here, send me a message via GitHub, or email me at alan@blogometer.com.
It's included in:
ReplyDeletehttp://hg.secondlife.com/llsd/src/tip/js/typedarray.js
...which is part of an MIT-licensed package