From 0f0e4d15f7e23102ebb374504322942e3771357e Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 26 Apr 2017 23:48:06 +1000 Subject: Move frexp and ldexp to luaconf.js --- src/luaconf.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/luaconf.js') diff --git a/src/luaconf.js b/src/luaconf.js index 803bb90..7cf3d06 100644 --- a/src/luaconf.js +++ b/src/luaconf.js @@ -32,6 +32,31 @@ const lua_getlocaledecpoint = function() { return (1.1).toLocaleString().substring(1, 2); }; +// See: http://croquetweak.blogspot.fr/2014/08/deconstructing-floats-frexp-and-ldexp.html +const frexp = function(value) { + if (value === 0) return [value, 0]; + var data = new DataView(new ArrayBuffer(8)); + data.setFloat64(0, value); + var bits = (data.getUint32(0) >>> 20) & 0x7FF; + if (bits === 0) { // denormal + data.setFloat64(0, value * Math.pow(2, 64)); // exp + 64 + bits = ((data.getUint32(0) >>> 20) & 0x7FF) - 64; + } + var exponent = bits - 1022; + var mantissa = ldexp(value, -exponent); + return [mantissa, exponent]; +}; + +const ldexp = function(mantissa, exponent) { + var steps = Math.min(3, Math.ceil(Math.abs(exponent) / 1023)); + var result = mantissa; + for (var i = 0; i < steps; i++) + result *= Math.pow(2, Math.floor((exponent + i) / steps)); + return result; +}; + +module.exports.frexp = frexp; +module.exports.ldexp = ldexp; module.exports.LUAI_MAXSTACK = LUAI_MAXSTACK; module.exports.LUA_IDSIZE = LUA_IDSIZE; module.exports.LUA_INTEGER_FMT = LUA_INTEGER_FMT; -- cgit v1.2.3-54-g00ecf