Skip to content

Commit

Permalink
Use JS array buffers for decodeDouble/Float. Faster, cleaner and less…
Browse files Browse the repository at this point in the history
… buggy.
  • Loading branch information
valderman committed Jun 12, 2013
1 parent 8a1a96a commit 6d09e2b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 45 deletions.
15 changes: 5 additions & 10 deletions lib/Integer.js
Original file line number Diff line number Diff line change
Expand Up @@ -715,17 +715,12 @@ var I_abs = function(self) {
};

var I_decodeDouble = function(x) {
if(isNaN(x)) {
return [1, 972, I_fromString('-6755399441055744')];
var dec = decodeDouble(x);
var mantissa = Integer.fromBits([dec[3], dec[2]]);
if(dec[1] < 0) {
mantissa = I_negate(mantissa);
}
var sig = x > 0 ? 1 : -1;
if(!isFinite(x)) {
return [1, 972, I_fromNumber(sig) * I_fromString('4503599627370496')];
}
x = Math.abs(x);
var exp = log2(x)-52; // log2 is defined in rts.js
var man = x/Math.pow(2, exp);
return [1, exp, I_fromNumber(sig*man)];
return [1, dec[4], mantissa];
}

var I_toString = function(self) {
Expand Down
60 changes: 25 additions & 35 deletions lib/rts.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,47 +115,37 @@ function cosh (arg) {
return (Math.exp(arg) + Math.exp(-arg)) / 2;
}

function log2(x) {
var high = 1024;
var low = -1024;
var i = 0;
var x2;
for(;;) {
x2 = Math.pow(2, i);
if(x2 <= (x >> 1)) {
low = i;
i += (high - i) >> 1;
} else if(x2 > x) {
high = i;
i += (low - i) >> 1;
} else {
return i;
}
}
return i;
}
// Scratch space for byte arrays.
var rts_scratchBuf = new ArrayBuffer(8);
var rts_scratchW32 = new Uint32Array(rts_scratchBuf);
var rts_scratchFloat = new Float32Array(rts_scratchBuf);
var rts_scratchDouble = new Float64Array(rts_scratchBuf);

function decodeFloat(x) {
if(isNaN(x)) {
return [1, -6755399441055744, 972];
}
var sig = x > 0 ? 1 : -1;
if(!isFinite(x)) {
return [1, sig * 4503599627370496, 972];
rts_scratchFloat[0] = x;
var sign = x < 0 ? -1 : 1;
var exp = ((rts_scratchW32[0] >> 23) & 0xff) - 150;
var man = rts_scratchW32[0] & 0x7fffff;
if(exp === 0) {
++exp;
} else {
man |= (1 << 23);
}
x = Math.abs(x);
var exp = log2(x)-52;
var man = x/Math.pow(2, exp);
return [1, sig*man, exp];
return [1, sign*man, exp];
}

function decodeDouble(x) {
var decoded = decodeFloat(x);
var sign = decoded[1] < 0 ? -1 : 1;
var mantissa = decoded[1]*sign;
var manLow = mantissa % 0x100000000;
var manHigh = Math.floor(mantissa / 0x100000000);
return [1, sign, manHigh, manLow, decoded[2]];
rts_scratchDouble[0] = x;
var sign = x < 0 ? -1 : 1;
var manHigh = rts_scratchW32[1] & 0xfffff;
var manLow = rts_scratchW32[0];
var exp = ((rts_scratchW32[1] >> 20) & 0x7ff) - 1075;
if(exp === 0) {
++exp;
} else {
manHigh |= (1 << 20);
}
return [1, sign, manHigh, manLow, exp];
}

function err(str) {
Expand Down

0 comments on commit 6d09e2b

Please sign in to comment.