diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-04-01 18:14:46 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-04-01 18:14:46 -0700 |
commit | 609bf2ea07190fd87a875ce5fef7016ee2a0ee9b (patch) | |
tree | 2d2d7da9bfcad051fe2e1ed0d47eac8f9ed855bd /src | |
parent | a08fe05250cd2ebd89dd832321d7d2f6c1711b9a (diff) |
proper precise unsigned i64 modulo, and passing tests for i64 division and modulo
Diffstat (limited to 'src')
-rw-r--r-- | src/long.js | 26 | ||||
-rw-r--r-- | src/parseTools.js | 2 |
2 files changed, 21 insertions, 7 deletions
diff --git a/src/long.js b/src/long.js index 47a194ce..71cffa79 100644 --- a/src/long.js +++ b/src/long.js @@ -1588,12 +1588,26 @@ var Wrapper = { Wrapper.result[1] = parseInt(h.toString()) | 0; } }, - modulo: function(xl, xh, yl, yh) { - var x = new goog.math.Long(xl, xh); - var y = new goog.math.Long(yl, yh); - var ret = x.modulo(y); - Wrapper.result[0] = ret.low_; - Wrapper.result[1] = ret.high_; + modulo: function(xl, xh, yl, yh, unsigned) { + if (!Wrapper.two32) Wrapper.makeTwo32(); + if (!unsigned) { + var x = new goog.math.Long(xl, xh); + var y = new goog.math.Long(yl, yh); + var ret = x.modulo(y); + Wrapper.result[0] = ret.low_; + Wrapper.result[1] = ret.high_; + } else { + // slow precise bignum division + var x = Wrapper.lh2bignum(xl >>> 0, xh >>> 0); + var y = Wrapper.lh2bignum(yl >>> 0, yh >>> 0); + var z = new BigInteger(); + x.divRemTo(y, null, z); + var l = new BigInteger(); + var h = new BigInteger(); + z.divRemTo(Wrapper.two32, h, l); + Wrapper.result[0] = parseInt(l.toString()) | 0; + Wrapper.result[1] = parseInt(h.toString()) | 0; + } }, stringify: function(l, h, unsigned) { var ret = new goog.math.Long(l, h).toString(); diff --git a/src/parseTools.js b/src/parseTools.js index a37a7c54..c8543963 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1741,7 +1741,7 @@ function processMathop(item) { } case 'urem': case 'srem': { if (PRECISE_I64_MATH) { - return i64PreciseOp('modulo'); + return i64PreciseOp('modulo', op[0] === 'u'); } else { warnI64_1(); return finish(splitI64(mergeI64(idents[0], op[0] === 'u') + '%' + mergeI64(idents[1], op[0] === 'u'))); |