diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-12-31 11:56:53 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-12-31 11:56:53 -0800 |
commit | 2325baf34e144586d71251f31c01c7f2abfdb8b7 (patch) | |
tree | 6dec7e37e75040034d443786d4701e62b38a4d6d /src/long.js | |
parent | 8aa6919b7acf0b4034735ac7ee597e946fefaf4d (diff) | |
parent | a55c2a24a50a93fcf9035eb2a809d13d3a8d3555 (diff) |
Merge branch 'incoming' into asm_js
Conflicts:
src/library_browser.js
Diffstat (limited to 'src/long.js')
-rw-r--r-- | src/long.js | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/src/long.js b/src/long.js index 865540db..a5367b2c 100644 --- a/src/long.js +++ b/src/long.js @@ -1053,7 +1053,7 @@ var i64Math = (function() { // Emscripten wrapper if(r != 0) return r; var i = this.t; r = i-a.t; - if(r != 0) return r; + if(r != 0) return (this.s<0)?-r:r; while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; return 0; } @@ -1551,9 +1551,15 @@ var i64Math = (function() { // Emscripten wrapper HEAP32[tempDoublePtr>>2] = ret.low_; HEAP32[tempDoublePtr+4>>2] = ret.high_; }, - makeTwo32: function() { + ensureTemps: function() { + if (Wrapper.ensuredTemps) return; + Wrapper.ensuredTemps = true; Wrapper.two32 = new BigInteger(); Wrapper.two32.fromString('4294967296', 10); + Wrapper.two64 = new BigInteger(); + Wrapper.two64.fromString('18446744073709551616', 10); + Wrapper.temp1 = new BigInteger(); + Wrapper.temp2 = new BigInteger(); }, lh2bignum: function(l, h) { var a = new BigInteger(); @@ -1567,7 +1573,7 @@ var i64Math = (function() { // Emscripten wrapper return d; }, divide: function(xl, xh, yl, yh, unsigned) { - if (!Wrapper.two32) Wrapper.makeTwo32(); + Wrapper.ensureTemps(); if (!unsigned) { var x = new goog.math.Long(xl, xh); var y = new goog.math.Long(yl, yh); @@ -1588,7 +1594,7 @@ var i64Math = (function() { // Emscripten wrapper } }, modulo: function(xl, xh, yl, yh, unsigned) { - if (!Wrapper.two32) Wrapper.makeTwo32(); + Wrapper.ensureTemps(); if (!unsigned) { var x = new goog.math.Long(xl, xh); var y = new goog.math.Long(yl, yh); @@ -1612,10 +1618,7 @@ var i64Math = (function() { // Emscripten wrapper var ret = new goog.math.Long(l, h).toString(); if (unsigned && ret[0] == '-') { // unsign slowly using jsbn bignums - if (!Wrapper.two64) { - Wrapper.two64 = new BigInteger(); - Wrapper.two64.fromString('18446744073709551616', 10); - } + Wrapper.ensureTemps(); var bignum = new BigInteger(); bignum.fromString(ret, 10); ret = new BigInteger(); @@ -1623,6 +1626,32 @@ var i64Math = (function() { // Emscripten wrapper ret = ret.toString(10); } return ret; + }, + fromString: function(str, base, min, max, unsigned) { + Wrapper.ensureTemps(); + var bignum = new BigInteger(); + bignum.fromString(str, base); + var bigmin = new BigInteger(); + bigmin.fromString(min, 10); + var bigmax = new BigInteger(); + bigmax.fromString(max, 10); + if (unsigned && bignum.compareTo(BigInteger.ZERO) < 0) { + var temp = new BigInteger(); + bignum.addTo(Wrapper.two64, temp); + bignum = temp; + } + var error = false; + if (bignum.compareTo(bigmin) < 0) { + bignum = bigmin; + error = true; + } else if (bignum.compareTo(bigmax) > 0) { + bignum = bigmax; + error = true; + } + var ret = goog.math.Long.fromString(bignum.toString()); // min-max checks should have clamped this to a range goog.math.Long can handle well + Wrapper.result[0] = ret.low_; + Wrapper.result[1] = ret.high_; + if (error) throw 'range error'; } }; return Wrapper; |