From 7770a6bffefa38d79d10f0e46d776f7d129a6b19 Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Sat, 18 Feb 2017 09:17:08 -0800 Subject: [PATCH] Added an "early out" for Int36 division --- modules/shared/lib/int36.js | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/modules/shared/lib/int36.js b/modules/shared/lib/int36.js index 7529005d7..7ce14574d 100644 --- a/modules/shared/lib/int36.js +++ b/modules/shared/lib/int36.js @@ -590,6 +590,24 @@ class Int36 { this.extend(); + /* + * Initialize the four double-length 72-bit "bits" values we need for the division process. + * + * The process involves shifting the divisor left 1 bit (ie, doubling it) until it equals + * or exceeds the dividend, and then repeatedly subtracting the divisor from the dividend and + * shifting the divisor right 1 bit until the divisor is "exhausted" (no bits left), with an + * "early out" if the dividend gets "exhausted" first. + * + * Note that each element of these "bits" arrays is a 36-bit value, so it's rarely a good idea + * to use bit-wise operators on them, because those would operate on only the low 32 bits. + * Stick with the "bits" worker functions I've created, and trust your JavaScript engine to + * inline/optimize the code. + * + * TODO: Profile this code to determine if individual variables (eg, bitsResLo and bitsResHi) + * instead of 2-element arrays is faster and/or less impactful on garbage collection. I prefer + * both the simplified syntax of arrays as well as their extensibility if we ever want/need + * to go beyond 72 bits. + */ var bitsRes = [0, 0]; var bitsPow = [1, 0]; var bitsDiv = [divisor, 0]; @@ -603,10 +621,11 @@ class Int36 { if (Int36.cmpBits(bitsRem, bitsDiv) >= 0) { Int36.subBits(bitsRem, bitsDiv); Int36.addBits(bitsRes, bitsPow); + if (Int36.zeroBits(bitsRem)) break; } Int36.shrBits(bitsDiv); Int36.shrBits(bitsPow); - } while (bitsPow[0] || bitsPow[1]); + } while (!Int36.zeroBits(bitsPow)); /* * Since divisors are limited to 36-bit values, something's wrong if we have an extended remainder. @@ -784,6 +803,18 @@ class Int36 { } } + /** + * zeroBits(bits) + * + * True if bits are all zero, false otherwise. + * + * @param {Array.} bits + */ + static zeroBits(bits) + { + return !bits[0] && !bits[1]; + } + /** * octal(value) *