aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-12-30 11:05:26 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-12-30 11:05:26 -0800
commitea655d0482618759fc08ca681083ad86f9a6c28b (patch)
tree0bd3c1efb5daa7270722e4dfb6de0e0cecdefbea /src
parent29d1e223681c3d33ab44dac76592ef9eab88bc1a (diff)
update bignum code with bugfix from upstream, and add i64Math code to parse
Diffstat (limited to 'src')
-rw-r--r--src/long.js43
1 files changed, 36 insertions, 7 deletions
diff --git a/src/long.js b/src/long.js
index d5770e48..dda68d5b 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;
}
@@ -1552,9 +1552,15 @@ var i64Math = (function() { // Emscripten wrapper
Wrapper.result[0] = ret.low_;
Wrapper.result[1] = 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();
@@ -1568,7 +1574,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);
@@ -1613,10 +1619,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();
@@ -1624,6 +1627,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;