You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					1454 lines
				
				51 KiB
			
		
		
			
		
	
	
					1454 lines
				
				51 KiB
			| 
											2 years ago
										 | var bigInt = (function (undefined) { | ||
|  |     "use strict"; | ||
|  | 
 | ||
|  |     var BASE = 1e7, | ||
|  |         LOG_BASE = 7, | ||
|  |         MAX_INT = 9007199254740992, | ||
|  |         MAX_INT_ARR = smallToArray(MAX_INT), | ||
|  |         DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz"; | ||
|  | 
 | ||
|  |     var supportsNativeBigInt = typeof BigInt === "function"; | ||
|  | 
 | ||
|  |     function Integer(v, radix, alphabet, caseSensitive) { | ||
|  |         if (typeof v === "undefined") return Integer[0]; | ||
|  |         if (typeof radix !== "undefined") return +radix === 10 && !alphabet ? parseValue(v) : parseBase(v, radix, alphabet, caseSensitive); | ||
|  |         return parseValue(v); | ||
|  |     } | ||
|  | 
 | ||
|  |     function BigInteger(value, sign) { | ||
|  |         this.value = value; | ||
|  |         this.sign = sign; | ||
|  |         this.isSmall = false; | ||
|  |     } | ||
|  |     BigInteger.prototype = Object.create(Integer.prototype); | ||
|  | 
 | ||
|  |     function SmallInteger(value) { | ||
|  |         this.value = value; | ||
|  |         this.sign = value < 0; | ||
|  |         this.isSmall = true; | ||
|  |     } | ||
|  |     SmallInteger.prototype = Object.create(Integer.prototype); | ||
|  | 
 | ||
|  |     function NativeBigInt(value) { | ||
|  |         this.value = value; | ||
|  |     } | ||
|  |     NativeBigInt.prototype = Object.create(Integer.prototype); | ||
|  | 
 | ||
|  |     function isPrecise(n) { | ||
|  |         return -MAX_INT < n && n < MAX_INT; | ||
|  |     } | ||
|  | 
 | ||
|  |     function smallToArray(n) { // For performance reasons doesn't reference BASE, need to change this function if BASE changes
 | ||
|  |         if (n < 1e7) | ||
|  |             return [n]; | ||
|  |         if (n < 1e14) | ||
|  |             return [n % 1e7, Math.floor(n / 1e7)]; | ||
|  |         return [n % 1e7, Math.floor(n / 1e7) % 1e7, Math.floor(n / 1e14)]; | ||
|  |     } | ||
|  | 
 | ||
|  |     function arrayToSmall(arr) { // If BASE changes this function may need to change
 | ||
|  |         trim(arr); | ||
|  |         var length = arr.length; | ||
|  |         if (length < 4 && compareAbs(arr, MAX_INT_ARR) < 0) { | ||
|  |             switch (length) { | ||
|  |                 case 0: return 0; | ||
|  |                 case 1: return arr[0]; | ||
|  |                 case 2: return arr[0] + arr[1] * BASE; | ||
|  |                 default: return arr[0] + (arr[1] + arr[2] * BASE) * BASE; | ||
|  |             } | ||
|  |         } | ||
|  |         return arr; | ||
|  |     } | ||
|  | 
 | ||
|  |     function trim(v) { | ||
|  |         var i = v.length; | ||
|  |         while (v[--i] === 0); | ||
|  |         v.length = i + 1; | ||
|  |     } | ||
|  | 
 | ||
|  |     function createArray(length) { // function shamelessly stolen from Yaffle's library https://github.com/Yaffle/BigInteger
 | ||
|  |         var x = new Array(length); | ||
|  |         var i = -1; | ||
|  |         while (++i < length) { | ||
|  |             x[i] = 0; | ||
|  |         } | ||
|  |         return x; | ||
|  |     } | ||
|  | 
 | ||
|  |     function truncate(n) { | ||
|  |         if (n > 0) return Math.floor(n); | ||
|  |         return Math.ceil(n); | ||
|  |     } | ||
|  | 
 | ||
|  |     function add(a, b) { // assumes a and b are arrays with a.length >= b.length
 | ||
|  |         var l_a = a.length, | ||
|  |             l_b = b.length, | ||
|  |             r = new Array(l_a), | ||
|  |             carry = 0, | ||
|  |             base = BASE, | ||
|  |             sum, i; | ||
|  |         for (i = 0; i < l_b; i++) { | ||
|  |             sum = a[i] + b[i] + carry; | ||
|  |             carry = sum >= base ? 1 : 0; | ||
|  |             r[i] = sum - carry * base; | ||
|  |         } | ||
|  |         while (i < l_a) { | ||
|  |             sum = a[i] + carry; | ||
|  |             carry = sum === base ? 1 : 0; | ||
|  |             r[i++] = sum - carry * base; | ||
|  |         } | ||
|  |         if (carry > 0) r.push(carry); | ||
|  |         return r; | ||
|  |     } | ||
|  | 
 | ||
|  |     function addAny(a, b) { | ||
|  |         if (a.length >= b.length) return add(a, b); | ||
|  |         return add(b, a); | ||
|  |     } | ||
|  | 
 | ||
|  |     function addSmall(a, carry) { // assumes a is array, carry is number with 0 <= carry < MAX_INT
 | ||
|  |         var l = a.length, | ||
|  |             r = new Array(l), | ||
|  |             base = BASE, | ||
|  |             sum, i; | ||
|  |         for (i = 0; i < l; i++) { | ||
|  |             sum = a[i] - base + carry; | ||
|  |             carry = Math.floor(sum / base); | ||
|  |             r[i] = sum - carry * base; | ||
|  |             carry += 1; | ||
|  |         } | ||
|  |         while (carry > 0) { | ||
|  |             r[i++] = carry % base; | ||
|  |             carry = Math.floor(carry / base); | ||
|  |         } | ||
|  |         return r; | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.add = function (v) { | ||
|  |         var n = parseValue(v); | ||
|  |         if (this.sign !== n.sign) { | ||
|  |             return this.subtract(n.negate()); | ||
|  |         } | ||
|  |         var a = this.value, b = n.value; | ||
|  |         if (n.isSmall) { | ||
|  |             return new BigInteger(addSmall(a, Math.abs(b)), this.sign); | ||
|  |         } | ||
|  |         return new BigInteger(addAny(a, b), this.sign); | ||
|  |     }; | ||
|  |     BigInteger.prototype.plus = BigInteger.prototype.add; | ||
|  | 
 | ||
|  |     SmallInteger.prototype.add = function (v) { | ||
|  |         var n = parseValue(v); | ||
|  |         var a = this.value; | ||
|  |         if (a < 0 !== n.sign) { | ||
|  |             return this.subtract(n.negate()); | ||
|  |         } | ||
|  |         var b = n.value; | ||
|  |         if (n.isSmall) { | ||
|  |             if (isPrecise(a + b)) return new SmallInteger(a + b); | ||
|  |             b = smallToArray(Math.abs(b)); | ||
|  |         } | ||
|  |         return new BigInteger(addSmall(b, Math.abs(a)), a < 0); | ||
|  |     }; | ||
|  |     SmallInteger.prototype.plus = SmallInteger.prototype.add; | ||
|  | 
 | ||
|  |     NativeBigInt.prototype.add = function (v) { | ||
|  |         return new NativeBigInt(this.value + parseValue(v).value); | ||
|  |     } | ||
|  |     NativeBigInt.prototype.plus = NativeBigInt.prototype.add; | ||
|  | 
 | ||
|  |     function subtract(a, b) { // assumes a and b are arrays with a >= b
 | ||
|  |         var a_l = a.length, | ||
|  |             b_l = b.length, | ||
|  |             r = new Array(a_l), | ||
|  |             borrow = 0, | ||
|  |             base = BASE, | ||
|  |             i, difference; | ||
|  |         for (i = 0; i < b_l; i++) { | ||
|  |             difference = a[i] - borrow - b[i]; | ||
|  |             if (difference < 0) { | ||
|  |                 difference += base; | ||
|  |                 borrow = 1; | ||
|  |             } else borrow = 0; | ||
|  |             r[i] = difference; | ||
|  |         } | ||
|  |         for (i = b_l; i < a_l; i++) { | ||
|  |             difference = a[i] - borrow; | ||
|  |             if (difference < 0) difference += base; | ||
|  |             else { | ||
|  |                 r[i++] = difference; | ||
|  |                 break; | ||
|  |             } | ||
|  |             r[i] = difference; | ||
|  |         } | ||
|  |         for (; i < a_l; i++) { | ||
|  |             r[i] = a[i]; | ||
|  |         } | ||
|  |         trim(r); | ||
|  |         return r; | ||
|  |     } | ||
|  | 
 | ||
|  |     function subtractAny(a, b, sign) { | ||
|  |         var value; | ||
|  |         if (compareAbs(a, b) >= 0) { | ||
|  |             value = subtract(a, b); | ||
|  |         } else { | ||
|  |             value = subtract(b, a); | ||
|  |             sign = !sign; | ||
|  |         } | ||
|  |         value = arrayToSmall(value); | ||
|  |         if (typeof value === "number") { | ||
|  |             if (sign) value = -value; | ||
|  |             return new SmallInteger(value); | ||
|  |         } | ||
|  |         return new BigInteger(value, sign); | ||
|  |     } | ||
|  | 
 | ||
|  |     function subtractSmall(a, b, sign) { // assumes a is array, b is number with 0 <= b < MAX_INT
 | ||
|  |         var l = a.length, | ||
|  |             r = new Array(l), | ||
|  |             carry = -b, | ||
|  |             base = BASE, | ||
|  |             i, difference; | ||
|  |         for (i = 0; i < l; i++) { | ||
|  |             difference = a[i] + carry; | ||
|  |             carry = Math.floor(difference / base); | ||
|  |             difference %= base; | ||
|  |             r[i] = difference < 0 ? difference + base : difference; | ||
|  |         } | ||
|  |         r = arrayToSmall(r); | ||
|  |         if (typeof r === "number") { | ||
|  |             if (sign) r = -r; | ||
|  |             return new SmallInteger(r); | ||
|  |         } return new BigInteger(r, sign); | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.subtract = function (v) { | ||
|  |         var n = parseValue(v); | ||
|  |         if (this.sign !== n.sign) { | ||
|  |             return this.add(n.negate()); | ||
|  |         } | ||
|  |         var a = this.value, b = n.value; | ||
|  |         if (n.isSmall) | ||
|  |             return subtractSmall(a, Math.abs(b), this.sign); | ||
|  |         return subtractAny(a, b, this.sign); | ||
|  |     }; | ||
|  |     BigInteger.prototype.minus = BigInteger.prototype.subtract; | ||
|  | 
 | ||
|  |     SmallInteger.prototype.subtract = function (v) { | ||
|  |         var n = parseValue(v); | ||
|  |         var a = this.value; | ||
|  |         if (a < 0 !== n.sign) { | ||
|  |             return this.add(n.negate()); | ||
|  |         } | ||
|  |         var b = n.value; | ||
|  |         if (n.isSmall) { | ||
|  |             return new SmallInteger(a - b); | ||
|  |         } | ||
|  |         return subtractSmall(b, Math.abs(a), a >= 0); | ||
|  |     }; | ||
|  |     SmallInteger.prototype.minus = SmallInteger.prototype.subtract; | ||
|  | 
 | ||
|  |     NativeBigInt.prototype.subtract = function (v) { | ||
|  |         return new NativeBigInt(this.value - parseValue(v).value); | ||
|  |     } | ||
|  |     NativeBigInt.prototype.minus = NativeBigInt.prototype.subtract; | ||
|  | 
 | ||
|  |     BigInteger.prototype.negate = function () { | ||
|  |         return new BigInteger(this.value, !this.sign); | ||
|  |     }; | ||
|  |     SmallInteger.prototype.negate = function () { | ||
|  |         var sign = this.sign; | ||
|  |         var small = new SmallInteger(-this.value); | ||
|  |         small.sign = !sign; | ||
|  |         return small; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.negate = function () { | ||
|  |         return new NativeBigInt(-this.value); | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.abs = function () { | ||
|  |         return new BigInteger(this.value, false); | ||
|  |     }; | ||
|  |     SmallInteger.prototype.abs = function () { | ||
|  |         return new SmallInteger(Math.abs(this.value)); | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.abs = function () { | ||
|  |         return new NativeBigInt(this.value >= 0 ? this.value : -this.value); | ||
|  |     } | ||
|  | 
 | ||
|  | 
 | ||
|  |     function multiplyLong(a, b) { | ||
|  |         var a_l = a.length, | ||
|  |             b_l = b.length, | ||
|  |             l = a_l + b_l, | ||
|  |             r = createArray(l), | ||
|  |             base = BASE, | ||
|  |             product, carry, i, a_i, b_j; | ||
|  |         for (i = 0; i < a_l; ++i) { | ||
|  |             a_i = a[i]; | ||
|  |             for (var j = 0; j < b_l; ++j) { | ||
|  |                 b_j = b[j]; | ||
|  |                 product = a_i * b_j + r[i + j]; | ||
|  |                 carry = Math.floor(product / base); | ||
|  |                 r[i + j] = product - carry * base; | ||
|  |                 r[i + j + 1] += carry; | ||
|  |             } | ||
|  |         } | ||
|  |         trim(r); | ||
|  |         return r; | ||
|  |     } | ||
|  | 
 | ||
|  |     function multiplySmall(a, b) { // assumes a is array, b is number with |b| < BASE
 | ||
|  |         var l = a.length, | ||
|  |             r = new Array(l), | ||
|  |             base = BASE, | ||
|  |             carry = 0, | ||
|  |             product, i; | ||
|  |         for (i = 0; i < l; i++) { | ||
|  |             product = a[i] * b + carry; | ||
|  |             carry = Math.floor(product / base); | ||
|  |             r[i] = product - carry * base; | ||
|  |         } | ||
|  |         while (carry > 0) { | ||
|  |             r[i++] = carry % base; | ||
|  |             carry = Math.floor(carry / base); | ||
|  |         } | ||
|  |         return r; | ||
|  |     } | ||
|  | 
 | ||
|  |     function shiftLeft(x, n) { | ||
|  |         var r = []; | ||
|  |         while (n-- > 0) r.push(0); | ||
|  |         return r.concat(x); | ||
|  |     } | ||
|  | 
 | ||
|  |     function multiplyKaratsuba(x, y) { | ||
|  |         var n = Math.max(x.length, y.length); | ||
|  | 
 | ||
|  |         if (n <= 30) return multiplyLong(x, y); | ||
|  |         n = Math.ceil(n / 2); | ||
|  | 
 | ||
|  |         var b = x.slice(n), | ||
|  |             a = x.slice(0, n), | ||
|  |             d = y.slice(n), | ||
|  |             c = y.slice(0, n); | ||
|  | 
 | ||
|  |         var ac = multiplyKaratsuba(a, c), | ||
|  |             bd = multiplyKaratsuba(b, d), | ||
|  |             abcd = multiplyKaratsuba(addAny(a, b), addAny(c, d)); | ||
|  | 
 | ||
|  |         var product = addAny(addAny(ac, shiftLeft(subtract(subtract(abcd, ac), bd), n)), shiftLeft(bd, 2 * n)); | ||
|  |         trim(product); | ||
|  |         return product; | ||
|  |     } | ||
|  | 
 | ||
|  |     // The following function is derived from a surface fit of a graph plotting the performance difference
 | ||
|  |     // between long multiplication and karatsuba multiplication versus the lengths of the two arrays.
 | ||
|  |     function useKaratsuba(l1, l2) { | ||
|  |         return -0.012 * l1 - 0.012 * l2 + 0.000015 * l1 * l2 > 0; | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.multiply = function (v) { | ||
|  |         var n = parseValue(v), | ||
|  |             a = this.value, b = n.value, | ||
|  |             sign = this.sign !== n.sign, | ||
|  |             abs; | ||
|  |         if (n.isSmall) { | ||
|  |             if (b === 0) return Integer[0]; | ||
|  |             if (b === 1) return this; | ||
|  |             if (b === -1) return this.negate(); | ||
|  |             abs = Math.abs(b); | ||
|  |             if (abs < BASE) { | ||
|  |                 return new BigInteger(multiplySmall(a, abs), sign); | ||
|  |             } | ||
|  |             b = smallToArray(abs); | ||
|  |         } | ||
|  |         if (useKaratsuba(a.length, b.length)) // Karatsuba is only faster for certain array sizes
 | ||
|  |             return new BigInteger(multiplyKaratsuba(a, b), sign); | ||
|  |         return new BigInteger(multiplyLong(a, b), sign); | ||
|  |     }; | ||
|  | 
 | ||
|  |     BigInteger.prototype.times = BigInteger.prototype.multiply; | ||
|  | 
 | ||
|  |     function multiplySmallAndArray(a, b, sign) { // a >= 0
 | ||
|  |         if (a < BASE) { | ||
|  |             return new BigInteger(multiplySmall(b, a), sign); | ||
|  |         } | ||
|  |         return new BigInteger(multiplyLong(b, smallToArray(a)), sign); | ||
|  |     } | ||
|  |     SmallInteger.prototype._multiplyBySmall = function (a) { | ||
|  |         if (isPrecise(a.value * this.value)) { | ||
|  |             return new SmallInteger(a.value * this.value); | ||
|  |         } | ||
|  |         return multiplySmallAndArray(Math.abs(a.value), smallToArray(Math.abs(this.value)), this.sign !== a.sign); | ||
|  |     }; | ||
|  |     BigInteger.prototype._multiplyBySmall = function (a) { | ||
|  |         if (a.value === 0) return Integer[0]; | ||
|  |         if (a.value === 1) return this; | ||
|  |         if (a.value === -1) return this.negate(); | ||
|  |         return multiplySmallAndArray(Math.abs(a.value), this.value, this.sign !== a.sign); | ||
|  |     }; | ||
|  |     SmallInteger.prototype.multiply = function (v) { | ||
|  |         return parseValue(v)._multiplyBySmall(this); | ||
|  |     }; | ||
|  |     SmallInteger.prototype.times = SmallInteger.prototype.multiply; | ||
|  | 
 | ||
|  |     NativeBigInt.prototype.multiply = function (v) { | ||
|  |         return new NativeBigInt(this.value * parseValue(v).value); | ||
|  |     } | ||
|  |     NativeBigInt.prototype.times = NativeBigInt.prototype.multiply; | ||
|  | 
 | ||
|  |     function square(a) { | ||
|  |         //console.assert(2 * BASE * BASE < MAX_INT);
 | ||
|  |         var l = a.length, | ||
|  |             r = createArray(l + l), | ||
|  |             base = BASE, | ||
|  |             product, carry, i, a_i, a_j; | ||
|  |         for (i = 0; i < l; i++) { | ||
|  |             a_i = a[i]; | ||
|  |             carry = 0 - a_i * a_i; | ||
|  |             for (var j = i; j < l; j++) { | ||
|  |                 a_j = a[j]; | ||
|  |                 product = 2 * (a_i * a_j) + r[i + j] + carry; | ||
|  |                 carry = Math.floor(product / base); | ||
|  |                 r[i + j] = product - carry * base; | ||
|  |             } | ||
|  |             r[i + l] = carry; | ||
|  |         } | ||
|  |         trim(r); | ||
|  |         return r; | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.square = function () { | ||
|  |         return new BigInteger(square(this.value), false); | ||
|  |     }; | ||
|  | 
 | ||
|  |     SmallInteger.prototype.square = function () { | ||
|  |         var value = this.value * this.value; | ||
|  |         if (isPrecise(value)) return new SmallInteger(value); | ||
|  |         return new BigInteger(square(smallToArray(Math.abs(this.value))), false); | ||
|  |     }; | ||
|  | 
 | ||
|  |     NativeBigInt.prototype.square = function (v) { | ||
|  |         return new NativeBigInt(this.value * this.value); | ||
|  |     } | ||
|  | 
 | ||
|  |     function divMod1(a, b) { // Left over from previous version. Performs faster than divMod2 on smaller input sizes.
 | ||
|  |         var a_l = a.length, | ||
|  |             b_l = b.length, | ||
|  |             base = BASE, | ||
|  |             result = createArray(b.length), | ||
|  |             divisorMostSignificantDigit = b[b_l - 1], | ||
|  |             // normalization
 | ||
|  |             lambda = Math.ceil(base / (2 * divisorMostSignificantDigit)), | ||
|  |             remainder = multiplySmall(a, lambda), | ||
|  |             divisor = multiplySmall(b, lambda), | ||
|  |             quotientDigit, shift, carry, borrow, i, l, q; | ||
|  |         if (remainder.length <= a_l) remainder.push(0); | ||
|  |         divisor.push(0); | ||
|  |         divisorMostSignificantDigit = divisor[b_l - 1]; | ||
|  |         for (shift = a_l - b_l; shift >= 0; shift--) { | ||
|  |             quotientDigit = base - 1; | ||
|  |             if (remainder[shift + b_l] !== divisorMostSignificantDigit) { | ||
|  |                 quotientDigit = Math.floor((remainder[shift + b_l] * base + remainder[shift + b_l - 1]) / divisorMostSignificantDigit); | ||
|  |             } | ||
|  |             // quotientDigit <= base - 1
 | ||
|  |             carry = 0; | ||
|  |             borrow = 0; | ||
|  |             l = divisor.length; | ||
|  |             for (i = 0; i < l; i++) { | ||
|  |                 carry += quotientDigit * divisor[i]; | ||
|  |                 q = Math.floor(carry / base); | ||
|  |                 borrow += remainder[shift + i] - (carry - q * base); | ||
|  |                 carry = q; | ||
|  |                 if (borrow < 0) { | ||
|  |                     remainder[shift + i] = borrow + base; | ||
|  |                     borrow = -1; | ||
|  |                 } else { | ||
|  |                     remainder[shift + i] = borrow; | ||
|  |                     borrow = 0; | ||
|  |                 } | ||
|  |             } | ||
|  |             while (borrow !== 0) { | ||
|  |                 quotientDigit -= 1; | ||
|  |                 carry = 0; | ||
|  |                 for (i = 0; i < l; i++) { | ||
|  |                     carry += remainder[shift + i] - base + divisor[i]; | ||
|  |                     if (carry < 0) { | ||
|  |                         remainder[shift + i] = carry + base; | ||
|  |                         carry = 0; | ||
|  |                     } else { | ||
|  |                         remainder[shift + i] = carry; | ||
|  |                         carry = 1; | ||
|  |                     } | ||
|  |                 } | ||
|  |                 borrow += carry; | ||
|  |             } | ||
|  |             result[shift] = quotientDigit; | ||
|  |         } | ||
|  |         // denormalization
 | ||
|  |         remainder = divModSmall(remainder, lambda)[0]; | ||
|  |         return [arrayToSmall(result), arrayToSmall(remainder)]; | ||
|  |     } | ||
|  | 
 | ||
|  |     function divMod2(a, b) { // Implementation idea shamelessly stolen from Silent Matt's library http://silentmatt.com/biginteger/
 | ||
|  |         // Performs faster than divMod1 on larger input sizes.
 | ||
|  |         var a_l = a.length, | ||
|  |             b_l = b.length, | ||
|  |             result = [], | ||
|  |             part = [], | ||
|  |             base = BASE, | ||
|  |             guess, xlen, highx, highy, check; | ||
|  |         while (a_l) { | ||
|  |             part.unshift(a[--a_l]); | ||
|  |             trim(part); | ||
|  |             if (compareAbs(part, b) < 0) { | ||
|  |                 result.push(0); | ||
|  |                 continue; | ||
|  |             } | ||
|  |             xlen = part.length; | ||
|  |             highx = part[xlen - 1] * base + part[xlen - 2]; | ||
|  |             highy = b[b_l - 1] * base + b[b_l - 2]; | ||
|  |             if (xlen > b_l) { | ||
|  |                 highx = (highx + 1) * base; | ||
|  |             } | ||
|  |             guess = Math.ceil(highx / highy); | ||
|  |             do { | ||
|  |                 check = multiplySmall(b, guess); | ||
|  |                 if (compareAbs(check, part) <= 0) break; | ||
|  |                 guess--; | ||
|  |             } while (guess); | ||
|  |             result.push(guess); | ||
|  |             part = subtract(part, check); | ||
|  |         } | ||
|  |         result.reverse(); | ||
|  |         return [arrayToSmall(result), arrayToSmall(part)]; | ||
|  |     } | ||
|  | 
 | ||
|  |     function divModSmall(value, lambda) { | ||
|  |         var length = value.length, | ||
|  |             quotient = createArray(length), | ||
|  |             base = BASE, | ||
|  |             i, q, remainder, divisor; | ||
|  |         remainder = 0; | ||
|  |         for (i = length - 1; i >= 0; --i) { | ||
|  |             divisor = remainder * base + value[i]; | ||
|  |             q = truncate(divisor / lambda); | ||
|  |             remainder = divisor - q * lambda; | ||
|  |             quotient[i] = q | 0; | ||
|  |         } | ||
|  |         return [quotient, remainder | 0]; | ||
|  |     } | ||
|  | 
 | ||
|  |     function divModAny(self, v) { | ||
|  |         var value, n = parseValue(v); | ||
|  |         if (supportsNativeBigInt) { | ||
|  |             return [new NativeBigInt(self.value / n.value), new NativeBigInt(self.value % n.value)]; | ||
|  |         } | ||
|  |         var a = self.value, b = n.value; | ||
|  |         var quotient; | ||
|  |         if (b === 0) throw new Error("Cannot divide by zero"); | ||
|  |         if (self.isSmall) { | ||
|  |             if (n.isSmall) { | ||
|  |                 return [new SmallInteger(truncate(a / b)), new SmallInteger(a % b)]; | ||
|  |             } | ||
|  |             return [Integer[0], self]; | ||
|  |         } | ||
|  |         if (n.isSmall) { | ||
|  |             if (b === 1) return [self, Integer[0]]; | ||
|  |             if (b == -1) return [self.negate(), Integer[0]]; | ||
|  |             var abs = Math.abs(b); | ||
|  |             if (abs < BASE) { | ||
|  |                 value = divModSmall(a, abs); | ||
|  |                 quotient = arrayToSmall(value[0]); | ||
|  |                 var remainder = value[1]; | ||
|  |                 if (self.sign) remainder = -remainder; | ||
|  |                 if (typeof quotient === "number") { | ||
|  |                     if (self.sign !== n.sign) quotient = -quotient; | ||
|  |                     return [new SmallInteger(quotient), new SmallInteger(remainder)]; | ||
|  |                 } | ||
|  |                 return [new BigInteger(quotient, self.sign !== n.sign), new SmallInteger(remainder)]; | ||
|  |             } | ||
|  |             b = smallToArray(abs); | ||
|  |         } | ||
|  |         var comparison = compareAbs(a, b); | ||
|  |         if (comparison === -1) return [Integer[0], self]; | ||
|  |         if (comparison === 0) return [Integer[self.sign === n.sign ? 1 : -1], Integer[0]]; | ||
|  | 
 | ||
|  |         // divMod1 is faster on smaller input sizes
 | ||
|  |         if (a.length + b.length <= 200) | ||
|  |             value = divMod1(a, b); | ||
|  |         else value = divMod2(a, b); | ||
|  | 
 | ||
|  |         quotient = value[0]; | ||
|  |         var qSign = self.sign !== n.sign, | ||
|  |             mod = value[1], | ||
|  |             mSign = self.sign; | ||
|  |         if (typeof quotient === "number") { | ||
|  |             if (qSign) quotient = -quotient; | ||
|  |             quotient = new SmallInteger(quotient); | ||
|  |         } else quotient = new BigInteger(quotient, qSign); | ||
|  |         if (typeof mod === "number") { | ||
|  |             if (mSign) mod = -mod; | ||
|  |             mod = new SmallInteger(mod); | ||
|  |         } else mod = new BigInteger(mod, mSign); | ||
|  |         return [quotient, mod]; | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.divmod = function (v) { | ||
|  |         var result = divModAny(this, v); | ||
|  |         return { | ||
|  |             quotient: result[0], | ||
|  |             remainder: result[1] | ||
|  |         }; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.divmod = SmallInteger.prototype.divmod = BigInteger.prototype.divmod; | ||
|  | 
 | ||
|  | 
 | ||
|  |     BigInteger.prototype.divide = function (v) { | ||
|  |         return divModAny(this, v)[0]; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.over = NativeBigInt.prototype.divide = function (v) { | ||
|  |         return new NativeBigInt(this.value / parseValue(v).value); | ||
|  |     }; | ||
|  |     SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide; | ||
|  | 
 | ||
|  |     BigInteger.prototype.mod = function (v) { | ||
|  |         return divModAny(this, v)[1]; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.mod = NativeBigInt.prototype.remainder = function (v) { | ||
|  |         return new NativeBigInt(this.value % parseValue(v).value); | ||
|  |     }; | ||
|  |     SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod; | ||
|  | 
 | ||
|  |     BigInteger.prototype.pow = function (v) { | ||
|  |         var n = parseValue(v), | ||
|  |             a = this.value, | ||
|  |             b = n.value, | ||
|  |             value, x, y; | ||
|  |         if (b === 0) return Integer[1]; | ||
|  |         if (a === 0) return Integer[0]; | ||
|  |         if (a === 1) return Integer[1]; | ||
|  |         if (a === -1) return n.isEven() ? Integer[1] : Integer[-1]; | ||
|  |         if (n.sign) { | ||
|  |             return Integer[0]; | ||
|  |         } | ||
|  |         if (!n.isSmall) throw new Error("The exponent " + n.toString() + " is too large."); | ||
|  |         if (this.isSmall) { | ||
|  |             if (isPrecise(value = Math.pow(a, b))) | ||
|  |                 return new SmallInteger(truncate(value)); | ||
|  |         } | ||
|  |         x = this; | ||
|  |         y = Integer[1]; | ||
|  |         while (true) { | ||
|  |             if (b & 1 === 1) { | ||
|  |                 y = y.times(x); | ||
|  |                 --b; | ||
|  |             } | ||
|  |             if (b === 0) break; | ||
|  |             b /= 2; | ||
|  |             x = x.square(); | ||
|  |         } | ||
|  |         return y; | ||
|  |     }; | ||
|  |     SmallInteger.prototype.pow = BigInteger.prototype.pow; | ||
|  | 
 | ||
|  |     NativeBigInt.prototype.pow = function (v) { | ||
|  |         var n = parseValue(v); | ||
|  |         var a = this.value, b = n.value; | ||
|  |         var _0 = BigInt(0), _1 = BigInt(1), _2 = BigInt(2); | ||
|  |         if (b === _0) return Integer[1]; | ||
|  |         if (a === _0) return Integer[0]; | ||
|  |         if (a === _1) return Integer[1]; | ||
|  |         if (a === BigInt(-1)) return n.isEven() ? Integer[1] : Integer[-1]; | ||
|  |         if (n.isNegative()) return new NativeBigInt(_0); | ||
|  |         var x = this; | ||
|  |         var y = Integer[1]; | ||
|  |         while (true) { | ||
|  |             if ((b & _1) === _1) { | ||
|  |                 y = y.times(x); | ||
|  |                 --b; | ||
|  |             } | ||
|  |             if (b === _0) break; | ||
|  |             b /= _2; | ||
|  |             x = x.square(); | ||
|  |         } | ||
|  |         return y; | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.modPow = function (exp, mod) { | ||
|  |         exp = parseValue(exp); | ||
|  |         mod = parseValue(mod); | ||
|  |         if (mod.isZero()) throw new Error("Cannot take modPow with modulus 0"); | ||
|  |         var r = Integer[1], | ||
|  |             base = this.mod(mod); | ||
|  |         if (exp.isNegative()) { | ||
|  |             exp = exp.multiply(Integer[-1]); | ||
|  |             base = base.modInv(mod); | ||
|  |         } | ||
|  |         while (exp.isPositive()) { | ||
|  |             if (base.isZero()) return Integer[0]; | ||
|  |             if (exp.isOdd()) r = r.multiply(base).mod(mod); | ||
|  |             exp = exp.divide(2); | ||
|  |             base = base.square().mod(mod); | ||
|  |         } | ||
|  |         return r; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.modPow = SmallInteger.prototype.modPow = BigInteger.prototype.modPow; | ||
|  | 
 | ||
|  |     function compareAbs(a, b) { | ||
|  |         if (a.length !== b.length) { | ||
|  |             return a.length > b.length ? 1 : -1; | ||
|  |         } | ||
|  |         for (var i = a.length - 1; i >= 0; i--) { | ||
|  |             if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1; | ||
|  |         } | ||
|  |         return 0; | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.compareAbs = function (v) { | ||
|  |         var n = parseValue(v), | ||
|  |             a = this.value, | ||
|  |             b = n.value; | ||
|  |         if (n.isSmall) return 1; | ||
|  |         return compareAbs(a, b); | ||
|  |     }; | ||
|  |     SmallInteger.prototype.compareAbs = function (v) { | ||
|  |         var n = parseValue(v), | ||
|  |             a = Math.abs(this.value), | ||
|  |             b = n.value; | ||
|  |         if (n.isSmall) { | ||
|  |             b = Math.abs(b); | ||
|  |             return a === b ? 0 : a > b ? 1 : -1; | ||
|  |         } | ||
|  |         return -1; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.compareAbs = function (v) { | ||
|  |         var a = this.value; | ||
|  |         var b = parseValue(v).value; | ||
|  |         a = a >= 0 ? a : -a; | ||
|  |         b = b >= 0 ? b : -b; | ||
|  |         return a === b ? 0 : a > b ? 1 : -1; | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.compare = function (v) { | ||
|  |         // See discussion about comparison with Infinity:
 | ||
|  |         // https://github.com/peterolson/BigInteger.js/issues/61
 | ||
|  |         if (v === Infinity) { | ||
|  |             return -1; | ||
|  |         } | ||
|  |         if (v === -Infinity) { | ||
|  |             return 1; | ||
|  |         } | ||
|  | 
 | ||
|  |         var n = parseValue(v), | ||
|  |             a = this.value, | ||
|  |             b = n.value; | ||
|  |         if (this.sign !== n.sign) { | ||
|  |             return n.sign ? 1 : -1; | ||
|  |         } | ||
|  |         if (n.isSmall) { | ||
|  |             return this.sign ? -1 : 1; | ||
|  |         } | ||
|  |         return compareAbs(a, b) * (this.sign ? -1 : 1); | ||
|  |     }; | ||
|  |     BigInteger.prototype.compareTo = BigInteger.prototype.compare; | ||
|  | 
 | ||
|  |     SmallInteger.prototype.compare = function (v) { | ||
|  |         if (v === Infinity) { | ||
|  |             return -1; | ||
|  |         } | ||
|  |         if (v === -Infinity) { | ||
|  |             return 1; | ||
|  |         } | ||
|  | 
 | ||
|  |         var n = parseValue(v), | ||
|  |             a = this.value, | ||
|  |             b = n.value; | ||
|  |         if (n.isSmall) { | ||
|  |             return a == b ? 0 : a > b ? 1 : -1; | ||
|  |         } | ||
|  |         if (a < 0 !== n.sign) { | ||
|  |             return a < 0 ? -1 : 1; | ||
|  |         } | ||
|  |         return a < 0 ? 1 : -1; | ||
|  |     }; | ||
|  |     SmallInteger.prototype.compareTo = SmallInteger.prototype.compare; | ||
|  | 
 | ||
|  |     NativeBigInt.prototype.compare = function (v) { | ||
|  |         if (v === Infinity) { | ||
|  |             return -1; | ||
|  |         } | ||
|  |         if (v === -Infinity) { | ||
|  |             return 1; | ||
|  |         } | ||
|  |         var a = this.value; | ||
|  |         var b = parseValue(v).value; | ||
|  |         return a === b ? 0 : a > b ? 1 : -1; | ||
|  |     } | ||
|  |     NativeBigInt.prototype.compareTo = NativeBigInt.prototype.compare; | ||
|  | 
 | ||
|  |     BigInteger.prototype.equals = function (v) { | ||
|  |         return this.compare(v) === 0; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.eq = NativeBigInt.prototype.equals = SmallInteger.prototype.eq = SmallInteger.prototype.equals = BigInteger.prototype.eq = BigInteger.prototype.equals; | ||
|  | 
 | ||
|  |     BigInteger.prototype.notEquals = function (v) { | ||
|  |         return this.compare(v) !== 0; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.neq = NativeBigInt.prototype.notEquals = SmallInteger.prototype.neq = SmallInteger.prototype.notEquals = BigInteger.prototype.neq = BigInteger.prototype.notEquals; | ||
|  | 
 | ||
|  |     BigInteger.prototype.greater = function (v) { | ||
|  |         return this.compare(v) > 0; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.gt = NativeBigInt.prototype.greater = SmallInteger.prototype.gt = SmallInteger.prototype.greater = BigInteger.prototype.gt = BigInteger.prototype.greater; | ||
|  | 
 | ||
|  |     BigInteger.prototype.lesser = function (v) { | ||
|  |         return this.compare(v) < 0; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.lt = NativeBigInt.prototype.lesser = SmallInteger.prototype.lt = SmallInteger.prototype.lesser = BigInteger.prototype.lt = BigInteger.prototype.lesser; | ||
|  | 
 | ||
|  |     BigInteger.prototype.greaterOrEquals = function (v) { | ||
|  |         return this.compare(v) >= 0; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.geq = NativeBigInt.prototype.greaterOrEquals = SmallInteger.prototype.geq = SmallInteger.prototype.greaterOrEquals = BigInteger.prototype.geq = BigInteger.prototype.greaterOrEquals; | ||
|  | 
 | ||
|  |     BigInteger.prototype.lesserOrEquals = function (v) { | ||
|  |         return this.compare(v) <= 0; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.leq = NativeBigInt.prototype.lesserOrEquals = SmallInteger.prototype.leq = SmallInteger.prototype.lesserOrEquals = BigInteger.prototype.leq = BigInteger.prototype.lesserOrEquals; | ||
|  | 
 | ||
|  |     BigInteger.prototype.isEven = function () { | ||
|  |         return (this.value[0] & 1) === 0; | ||
|  |     }; | ||
|  |     SmallInteger.prototype.isEven = function () { | ||
|  |         return (this.value & 1) === 0; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.isEven = function () { | ||
|  |         return (this.value & BigInt(1)) === BigInt(0); | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.isOdd = function () { | ||
|  |         return (this.value[0] & 1) === 1; | ||
|  |     }; | ||
|  |     SmallInteger.prototype.isOdd = function () { | ||
|  |         return (this.value & 1) === 1; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.isOdd = function () { | ||
|  |         return (this.value & BigInt(1)) === BigInt(1); | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.isPositive = function () { | ||
|  |         return !this.sign; | ||
|  |     }; | ||
|  |     SmallInteger.prototype.isPositive = function () { | ||
|  |         return this.value > 0; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.isPositive = SmallInteger.prototype.isPositive; | ||
|  | 
 | ||
|  |     BigInteger.prototype.isNegative = function () { | ||
|  |         return this.sign; | ||
|  |     }; | ||
|  |     SmallInteger.prototype.isNegative = function () { | ||
|  |         return this.value < 0; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.isNegative = SmallInteger.prototype.isNegative; | ||
|  | 
 | ||
|  |     BigInteger.prototype.isUnit = function () { | ||
|  |         return false; | ||
|  |     }; | ||
|  |     SmallInteger.prototype.isUnit = function () { | ||
|  |         return Math.abs(this.value) === 1; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.isUnit = function () { | ||
|  |         return this.abs().value === BigInt(1); | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.isZero = function () { | ||
|  |         return false; | ||
|  |     }; | ||
|  |     SmallInteger.prototype.isZero = function () { | ||
|  |         return this.value === 0; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.isZero = function () { | ||
|  |         return this.value === BigInt(0); | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.isDivisibleBy = function (v) { | ||
|  |         var n = parseValue(v); | ||
|  |         if (n.isZero()) return false; | ||
|  |         if (n.isUnit()) return true; | ||
|  |         if (n.compareAbs(2) === 0) return this.isEven(); | ||
|  |         return this.mod(n).isZero(); | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.isDivisibleBy = SmallInteger.prototype.isDivisibleBy = BigInteger.prototype.isDivisibleBy; | ||
|  | 
 | ||
|  |     function isBasicPrime(v) { | ||
|  |         var n = v.abs(); | ||
|  |         if (n.isUnit()) return false; | ||
|  |         if (n.equals(2) || n.equals(3) || n.equals(5)) return true; | ||
|  |         if (n.isEven() || n.isDivisibleBy(3) || n.isDivisibleBy(5)) return false; | ||
|  |         if (n.lesser(49)) return true; | ||
|  |         // we don't know if it's prime: let the other functions figure it out
 | ||
|  |     } | ||
|  | 
 | ||
|  |     function millerRabinTest(n, a) { | ||
|  |         var nPrev = n.prev(), | ||
|  |             b = nPrev, | ||
|  |             r = 0, | ||
|  |             d, t, i, x; | ||
|  |         while (b.isEven()) b = b.divide(2), r++; | ||
|  |         next: for (i = 0; i < a.length; i++) { | ||
|  |             if (n.lesser(a[i])) continue; | ||
|  |             x = bigInt(a[i]).modPow(b, n); | ||
|  |             if (x.isUnit() || x.equals(nPrev)) continue; | ||
|  |             for (d = r - 1; d != 0; d--) { | ||
|  |                 x = x.square().mod(n); | ||
|  |                 if (x.isUnit()) return false; | ||
|  |                 if (x.equals(nPrev)) continue next; | ||
|  |             } | ||
|  |             return false; | ||
|  |         } | ||
|  |         return true; | ||
|  |     } | ||
|  | 
 | ||
|  |     // Set "strict" to true to force GRH-supported lower bound of 2*log(N)^2
 | ||
|  |     BigInteger.prototype.isPrime = function (strict) { | ||
|  |         var isPrime = isBasicPrime(this); | ||
|  |         if (isPrime !== undefined) return isPrime; | ||
|  |         var n = this.abs(); | ||
|  |         var bits = n.bitLength(); | ||
|  |         if (bits <= 64) | ||
|  |             return millerRabinTest(n, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]); | ||
|  |         var logN = Math.log(2) * bits.toJSNumber(); | ||
|  |         var t = Math.ceil((strict === true) ? (2 * Math.pow(logN, 2)) : logN); | ||
|  |         for (var a = [], i = 0; i < t; i++) { | ||
|  |             a.push(bigInt(i + 2)); | ||
|  |         } | ||
|  |         return millerRabinTest(n, a); | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.isPrime = SmallInteger.prototype.isPrime = BigInteger.prototype.isPrime; | ||
|  | 
 | ||
|  |     BigInteger.prototype.isProbablePrime = function (iterations, rng) { | ||
|  |         var isPrime = isBasicPrime(this); | ||
|  |         if (isPrime !== undefined) return isPrime; | ||
|  |         var n = this.abs(); | ||
|  |         var t = iterations === undefined ? 5 : iterations; | ||
|  |         for (var a = [], i = 0; i < t; i++) { | ||
|  |             a.push(bigInt.randBetween(2, n.minus(2), rng)); | ||
|  |         } | ||
|  |         return millerRabinTest(n, a); | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.isProbablePrime = SmallInteger.prototype.isProbablePrime = BigInteger.prototype.isProbablePrime; | ||
|  | 
 | ||
|  |     BigInteger.prototype.modInv = function (n) { | ||
|  |         var t = bigInt.zero, newT = bigInt.one, r = parseValue(n), newR = this.abs(), q, lastT, lastR; | ||
|  |         while (!newR.isZero()) { | ||
|  |             q = r.divide(newR); | ||
|  |             lastT = t; | ||
|  |             lastR = r; | ||
|  |             t = newT; | ||
|  |             r = newR; | ||
|  |             newT = lastT.subtract(q.multiply(newT)); | ||
|  |             newR = lastR.subtract(q.multiply(newR)); | ||
|  |         } | ||
|  |         if (!r.isUnit()) throw new Error(this.toString() + " and " + n.toString() + " are not co-prime"); | ||
|  |         if (t.compare(0) === -1) { | ||
|  |             t = t.add(n); | ||
|  |         } | ||
|  |         if (this.isNegative()) { | ||
|  |             return t.negate(); | ||
|  |         } | ||
|  |         return t; | ||
|  |     }; | ||
|  | 
 | ||
|  |     NativeBigInt.prototype.modInv = SmallInteger.prototype.modInv = BigInteger.prototype.modInv; | ||
|  | 
 | ||
|  |     BigInteger.prototype.next = function () { | ||
|  |         var value = this.value; | ||
|  |         if (this.sign) { | ||
|  |             return subtractSmall(value, 1, this.sign); | ||
|  |         } | ||
|  |         return new BigInteger(addSmall(value, 1), this.sign); | ||
|  |     }; | ||
|  |     SmallInteger.prototype.next = function () { | ||
|  |         var value = this.value; | ||
|  |         if (value + 1 < MAX_INT) return new SmallInteger(value + 1); | ||
|  |         return new BigInteger(MAX_INT_ARR, false); | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.next = function () { | ||
|  |         return new NativeBigInt(this.value + BigInt(1)); | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.prev = function () { | ||
|  |         var value = this.value; | ||
|  |         if (this.sign) { | ||
|  |             return new BigInteger(addSmall(value, 1), true); | ||
|  |         } | ||
|  |         return subtractSmall(value, 1, this.sign); | ||
|  |     }; | ||
|  |     SmallInteger.prototype.prev = function () { | ||
|  |         var value = this.value; | ||
|  |         if (value - 1 > -MAX_INT) return new SmallInteger(value - 1); | ||
|  |         return new BigInteger(MAX_INT_ARR, true); | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.prev = function () { | ||
|  |         return new NativeBigInt(this.value - BigInt(1)); | ||
|  |     } | ||
|  | 
 | ||
|  |     var powersOfTwo = [1]; | ||
|  |     while (2 * powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]); | ||
|  |     var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1]; | ||
|  | 
 | ||
|  |     function shift_isSmall(n) { | ||
|  |         return Math.abs(n) <= BASE; | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.shiftLeft = function (v) { | ||
|  |         var n = parseValue(v).toJSNumber(); | ||
|  |         if (!shift_isSmall(n)) { | ||
|  |             throw new Error(String(n) + " is too large for shifting."); | ||
|  |         } | ||
|  |         if (n < 0) return this.shiftRight(-n); | ||
|  |         var result = this; | ||
|  |         if (result.isZero()) return result; | ||
|  |         while (n >= powers2Length) { | ||
|  |             result = result.multiply(highestPower2); | ||
|  |             n -= powers2Length - 1; | ||
|  |         } | ||
|  |         return result.multiply(powersOfTwo[n]); | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.shiftLeft = SmallInteger.prototype.shiftLeft = BigInteger.prototype.shiftLeft; | ||
|  | 
 | ||
|  |     BigInteger.prototype.shiftRight = function (v) { | ||
|  |         var remQuo; | ||
|  |         var n = parseValue(v).toJSNumber(); | ||
|  |         if (!shift_isSmall(n)) { | ||
|  |             throw new Error(String(n) + " is too large for shifting."); | ||
|  |         } | ||
|  |         if (n < 0) return this.shiftLeft(-n); | ||
|  |         var result = this; | ||
|  |         while (n >= powers2Length) { | ||
|  |             if (result.isZero() || (result.isNegative() && result.isUnit())) return result; | ||
|  |             remQuo = divModAny(result, highestPower2); | ||
|  |             result = remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0]; | ||
|  |             n -= powers2Length - 1; | ||
|  |         } | ||
|  |         remQuo = divModAny(result, powersOfTwo[n]); | ||
|  |         return remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0]; | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.shiftRight = SmallInteger.prototype.shiftRight = BigInteger.prototype.shiftRight; | ||
|  | 
 | ||
|  |     function bitwise(x, y, fn) { | ||
|  |         y = parseValue(y); | ||
|  |         var xSign = x.isNegative(), ySign = y.isNegative(); | ||
|  |         var xRem = xSign ? x.not() : x, | ||
|  |             yRem = ySign ? y.not() : y; | ||
|  |         var xDigit = 0, yDigit = 0; | ||
|  |         var xDivMod = null, yDivMod = null; | ||
|  |         var result = []; | ||
|  |         while (!xRem.isZero() || !yRem.isZero()) { | ||
|  |             xDivMod = divModAny(xRem, highestPower2); | ||
|  |             xDigit = xDivMod[1].toJSNumber(); | ||
|  |             if (xSign) { | ||
|  |                 xDigit = highestPower2 - 1 - xDigit; // two's complement for negative numbers
 | ||
|  |             } | ||
|  | 
 | ||
|  |             yDivMod = divModAny(yRem, highestPower2); | ||
|  |             yDigit = yDivMod[1].toJSNumber(); | ||
|  |             if (ySign) { | ||
|  |                 yDigit = highestPower2 - 1 - yDigit; // two's complement for negative numbers
 | ||
|  |             } | ||
|  | 
 | ||
|  |             xRem = xDivMod[0]; | ||
|  |             yRem = yDivMod[0]; | ||
|  |             result.push(fn(xDigit, yDigit)); | ||
|  |         } | ||
|  |         var sum = fn(xSign ? 1 : 0, ySign ? 1 : 0) !== 0 ? bigInt(-1) : bigInt(0); | ||
|  |         for (var i = result.length - 1; i >= 0; i -= 1) { | ||
|  |             sum = sum.multiply(highestPower2).add(bigInt(result[i])); | ||
|  |         } | ||
|  |         return sum; | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.not = function () { | ||
|  |         return this.negate().prev(); | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.not = SmallInteger.prototype.not = BigInteger.prototype.not; | ||
|  | 
 | ||
|  |     BigInteger.prototype.and = function (n) { | ||
|  |         return bitwise(this, n, function (a, b) { return a & b; }); | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.and = SmallInteger.prototype.and = BigInteger.prototype.and; | ||
|  | 
 | ||
|  |     BigInteger.prototype.or = function (n) { | ||
|  |         return bitwise(this, n, function (a, b) { return a | b; }); | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.or = SmallInteger.prototype.or = BigInteger.prototype.or; | ||
|  | 
 | ||
|  |     BigInteger.prototype.xor = function (n) { | ||
|  |         return bitwise(this, n, function (a, b) { return a ^ b; }); | ||
|  |     }; | ||
|  |     NativeBigInt.prototype.xor = SmallInteger.prototype.xor = BigInteger.prototype.xor; | ||
|  | 
 | ||
|  |     var LOBMASK_I = 1 << 30, LOBMASK_BI = (BASE & -BASE) * (BASE & -BASE) | LOBMASK_I; | ||
|  |     function roughLOB(n) { // get lowestOneBit (rough)
 | ||
|  |         // SmallInteger: return Min(lowestOneBit(n), 1 << 30)
 | ||
|  |         // BigInteger: return Min(lowestOneBit(n), 1 << 14) [BASE=1e7]
 | ||
|  |         var v = n.value, | ||
|  |             x = typeof v === "number" ? v | LOBMASK_I : | ||
|  |                 typeof v === "bigint" ? v | BigInt(LOBMASK_I) : | ||
|  |                     v[0] + v[1] * BASE | LOBMASK_BI; | ||
|  |         return x & -x; | ||
|  |     } | ||
|  | 
 | ||
|  |     function integerLogarithm(value, base) { | ||
|  |         if (base.compareTo(value) <= 0) { | ||
|  |             var tmp = integerLogarithm(value, base.square(base)); | ||
|  |             var p = tmp.p; | ||
|  |             var e = tmp.e; | ||
|  |             var t = p.multiply(base); | ||
|  |             return t.compareTo(value) <= 0 ? { p: t, e: e * 2 + 1 } : { p: p, e: e * 2 }; | ||
|  |         } | ||
|  |         return { p: bigInt(1), e: 0 }; | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.bitLength = function () { | ||
|  |         var n = this; | ||
|  |         if (n.compareTo(bigInt(0)) < 0) { | ||
|  |             n = n.negate().subtract(bigInt(1)); | ||
|  |         } | ||
|  |         if (n.compareTo(bigInt(0)) === 0) { | ||
|  |             return bigInt(0); | ||
|  |         } | ||
|  |         return bigInt(integerLogarithm(n, bigInt(2)).e).add(bigInt(1)); | ||
|  |     } | ||
|  |     NativeBigInt.prototype.bitLength = SmallInteger.prototype.bitLength = BigInteger.prototype.bitLength; | ||
|  | 
 | ||
|  |     function max(a, b) { | ||
|  |         a = parseValue(a); | ||
|  |         b = parseValue(b); | ||
|  |         return a.greater(b) ? a : b; | ||
|  |     } | ||
|  |     function min(a, b) { | ||
|  |         a = parseValue(a); | ||
|  |         b = parseValue(b); | ||
|  |         return a.lesser(b) ? a : b; | ||
|  |     } | ||
|  |     function gcd(a, b) { | ||
|  |         a = parseValue(a).abs(); | ||
|  |         b = parseValue(b).abs(); | ||
|  |         if (a.equals(b)) return a; | ||
|  |         if (a.isZero()) return b; | ||
|  |         if (b.isZero()) return a; | ||
|  |         var c = Integer[1], d, t; | ||
|  |         while (a.isEven() && b.isEven()) { | ||
|  |             d = min(roughLOB(a), roughLOB(b)); | ||
|  |             a = a.divide(d); | ||
|  |             b = b.divide(d); | ||
|  |             c = c.multiply(d); | ||
|  |         } | ||
|  |         while (a.isEven()) { | ||
|  |             a = a.divide(roughLOB(a)); | ||
|  |         } | ||
|  |         do { | ||
|  |             while (b.isEven()) { | ||
|  |                 b = b.divide(roughLOB(b)); | ||
|  |             } | ||
|  |             if (a.greater(b)) { | ||
|  |                 t = b; b = a; a = t; | ||
|  |             } | ||
|  |             b = b.subtract(a); | ||
|  |         } while (!b.isZero()); | ||
|  |         return c.isUnit() ? a : a.multiply(c); | ||
|  |     } | ||
|  |     function lcm(a, b) { | ||
|  |         a = parseValue(a).abs(); | ||
|  |         b = parseValue(b).abs(); | ||
|  |         return a.divide(gcd(a, b)).multiply(b); | ||
|  |     } | ||
|  |     function randBetween(a, b, rng) { | ||
|  |         a = parseValue(a); | ||
|  |         b = parseValue(b); | ||
|  |         var usedRNG = rng || Math.random; | ||
|  |         var low = min(a, b), high = max(a, b); | ||
|  |         var range = high.subtract(low).add(1); | ||
|  |         if (range.isSmall) return low.add(Math.floor(usedRNG() * range)); | ||
|  |         var digits = toBase(range, BASE).value; | ||
|  |         var result = [], restricted = true; | ||
|  |         for (var i = 0; i < digits.length; i++) { | ||
|  |             var top = restricted ? digits[i] + (i + 1 < digits.length ? digits[i + 1] / BASE : 0) : BASE; | ||
|  |             var digit = truncate(usedRNG() * top); | ||
|  |             result.push(digit); | ||
|  |             if (digit < digits[i]) restricted = false; | ||
|  |         } | ||
|  |         return low.add(Integer.fromArray(result, BASE, false)); | ||
|  |     } | ||
|  | 
 | ||
|  |     var parseBase = function (text, base, alphabet, caseSensitive) { | ||
|  |         alphabet = alphabet || DEFAULT_ALPHABET; | ||
|  |         text = String(text); | ||
|  |         if (!caseSensitive) { | ||
|  |             text = text.toLowerCase(); | ||
|  |             alphabet = alphabet.toLowerCase(); | ||
|  |         } | ||
|  |         var length = text.length; | ||
|  |         var i; | ||
|  |         var absBase = Math.abs(base); | ||
|  |         var alphabetValues = {}; | ||
|  |         for (i = 0; i < alphabet.length; i++) { | ||
|  |             alphabetValues[alphabet[i]] = i; | ||
|  |         } | ||
|  |         for (i = 0; i < length; i++) { | ||
|  |             var c = text[i]; | ||
|  |             if (c === "-") continue; | ||
|  |             if (c in alphabetValues) { | ||
|  |                 if (alphabetValues[c] >= absBase) { | ||
|  |                     if (c === "1" && absBase === 1) continue; | ||
|  |                     throw new Error(c + " is not a valid digit in base " + base + "."); | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |         base = parseValue(base); | ||
|  |         var digits = []; | ||
|  |         var isNegative = text[0] === "-"; | ||
|  |         for (i = isNegative ? 1 : 0; i < text.length; i++) { | ||
|  |             var c = text[i]; | ||
|  |             if (c in alphabetValues) digits.push(parseValue(alphabetValues[c])); | ||
|  |             else if (c === "<") { | ||
|  |                 var start = i; | ||
|  |                 do { i++; } while (text[i] !== ">" && i < text.length); | ||
|  |                 digits.push(parseValue(text.slice(start + 1, i))); | ||
|  |             } | ||
|  |             else throw new Error(c + " is not a valid character"); | ||
|  |         } | ||
|  |         return parseBaseFromArray(digits, base, isNegative); | ||
|  |     }; | ||
|  | 
 | ||
|  |     function parseBaseFromArray(digits, base, isNegative) { | ||
|  |         var val = Integer[0], pow = Integer[1], i; | ||
|  |         for (i = digits.length - 1; i >= 0; i--) { | ||
|  |             val = val.add(digits[i].times(pow)); | ||
|  |             pow = pow.times(base); | ||
|  |         } | ||
|  |         return isNegative ? val.negate() : val; | ||
|  |     } | ||
|  | 
 | ||
|  |     function stringify(digit, alphabet) { | ||
|  |         alphabet = alphabet || DEFAULT_ALPHABET; | ||
|  |         if (digit < alphabet.length) { | ||
|  |             return alphabet[digit]; | ||
|  |         } | ||
|  |         return "<" + digit + ">"; | ||
|  |     } | ||
|  | 
 | ||
|  |     function toBase(n, base) { | ||
|  |         base = bigInt(base); | ||
|  |         if (base.isZero()) { | ||
|  |             if (n.isZero()) return { value: [0], isNegative: false }; | ||
|  |             throw new Error("Cannot convert nonzero numbers to base 0."); | ||
|  |         } | ||
|  |         if (base.equals(-1)) { | ||
|  |             if (n.isZero()) return { value: [0], isNegative: false }; | ||
|  |             if (n.isNegative()) | ||
|  |                 return { | ||
|  |                     value: [].concat.apply([], Array.apply(null, Array(-n.toJSNumber())) | ||
|  |                         .map(Array.prototype.valueOf, [1, 0]) | ||
|  |                     ), | ||
|  |                     isNegative: false | ||
|  |                 }; | ||
|  | 
 | ||
|  |             var arr = Array.apply(null, Array(n.toJSNumber() - 1)) | ||
|  |                 .map(Array.prototype.valueOf, [0, 1]); | ||
|  |             arr.unshift([1]); | ||
|  |             return { | ||
|  |                 value: [].concat.apply([], arr), | ||
|  |                 isNegative: false | ||
|  |             }; | ||
|  |         } | ||
|  | 
 | ||
|  |         var neg = false; | ||
|  |         if (n.isNegative() && base.isPositive()) { | ||
|  |             neg = true; | ||
|  |             n = n.abs(); | ||
|  |         } | ||
|  |         if (base.isUnit()) { | ||
|  |             if (n.isZero()) return { value: [0], isNegative: false }; | ||
|  | 
 | ||
|  |             return { | ||
|  |                 value: Array.apply(null, Array(n.toJSNumber())) | ||
|  |                     .map(Number.prototype.valueOf, 1), | ||
|  |                 isNegative: neg | ||
|  |             }; | ||
|  |         } | ||
|  |         var out = []; | ||
|  |         var left = n, divmod; | ||
|  |         while (left.isNegative() || left.compareAbs(base) >= 0) { | ||
|  |             divmod = left.divmod(base); | ||
|  |             left = divmod.quotient; | ||
|  |             var digit = divmod.remainder; | ||
|  |             if (digit.isNegative()) { | ||
|  |                 digit = base.minus(digit).abs(); | ||
|  |                 left = left.next(); | ||
|  |             } | ||
|  |             out.push(digit.toJSNumber()); | ||
|  |         } | ||
|  |         out.push(left.toJSNumber()); | ||
|  |         return { value: out.reverse(), isNegative: neg }; | ||
|  |     } | ||
|  | 
 | ||
|  |     function toBaseString(n, base, alphabet) { | ||
|  |         var arr = toBase(n, base); | ||
|  |         return (arr.isNegative ? "-" : "") + arr.value.map(function (x) { | ||
|  |             return stringify(x, alphabet); | ||
|  |         }).join(''); | ||
|  |     } | ||
|  | 
 | ||
|  |     BigInteger.prototype.toArray = function (radix) { | ||
|  |         return toBase(this, radix); | ||
|  |     }; | ||
|  | 
 | ||
|  |     SmallInteger.prototype.toArray = function (radix) { | ||
|  |         return toBase(this, radix); | ||
|  |     }; | ||
|  | 
 | ||
|  |     NativeBigInt.prototype.toArray = function (radix) { | ||
|  |         return toBase(this, radix); | ||
|  |     }; | ||
|  | 
 | ||
|  |     BigInteger.prototype.toString = function (radix, alphabet) { | ||
|  |         if (radix === undefined) radix = 10; | ||
|  |         if (radix !== 10) return toBaseString(this, radix, alphabet); | ||
|  |         var v = this.value, l = v.length, str = String(v[--l]), zeros = "0000000", digit; | ||
|  |         while (--l >= 0) { | ||
|  |             digit = String(v[l]); | ||
|  |             str += zeros.slice(digit.length) + digit; | ||
|  |         } | ||
|  |         var sign = this.sign ? "-" : ""; | ||
|  |         return sign + str; | ||
|  |     }; | ||
|  | 
 | ||
|  |     SmallInteger.prototype.toString = function (radix, alphabet) { | ||
|  |         if (radix === undefined) radix = 10; | ||
|  |         if (radix != 10) return toBaseString(this, radix, alphabet); | ||
|  |         return String(this.value); | ||
|  |     }; | ||
|  | 
 | ||
|  |     NativeBigInt.prototype.toString = SmallInteger.prototype.toString; | ||
|  | 
 | ||
|  |     NativeBigInt.prototype.toJSON = BigInteger.prototype.toJSON = SmallInteger.prototype.toJSON = function () { return this.toString(); } | ||
|  | 
 | ||
|  |     BigInteger.prototype.valueOf = function () { | ||
|  |         return parseInt(this.toString(), 10); | ||
|  |     }; | ||
|  |     BigInteger.prototype.toJSNumber = BigInteger.prototype.valueOf; | ||
|  | 
 | ||
|  |     SmallInteger.prototype.valueOf = function () { | ||
|  |         return this.value; | ||
|  |     }; | ||
|  |     SmallInteger.prototype.toJSNumber = SmallInteger.prototype.valueOf; | ||
|  |     NativeBigInt.prototype.valueOf = NativeBigInt.prototype.toJSNumber = function () { | ||
|  |         return parseInt(this.toString(), 10); | ||
|  |     } | ||
|  | 
 | ||
|  |     function parseStringValue(v) { | ||
|  |         if (isPrecise(+v)) { | ||
|  |             var x = +v; | ||
|  |             if (x === truncate(x)) | ||
|  |                 return supportsNativeBigInt ? new NativeBigInt(BigInt(x)) : new SmallInteger(x); | ||
|  |             throw new Error("Invalid integer: " + v); | ||
|  |         } | ||
|  |         var sign = v[0] === "-"; | ||
|  |         if (sign) v = v.slice(1); | ||
|  |         var split = v.split(/e/i); | ||
|  |         if (split.length > 2) throw new Error("Invalid integer: " + split.join("e")); | ||
|  |         if (split.length === 2) { | ||
|  |             var exp = split[1]; | ||
|  |             if (exp[0] === "+") exp = exp.slice(1); | ||
|  |             exp = +exp; | ||
|  |             if (exp !== truncate(exp) || !isPrecise(exp)) throw new Error("Invalid integer: " + exp + " is not a valid exponent."); | ||
|  |             var text = split[0]; | ||
|  |             var decimalPlace = text.indexOf("."); | ||
|  |             if (decimalPlace >= 0) { | ||
|  |                 exp -= text.length - decimalPlace - 1; | ||
|  |                 text = text.slice(0, decimalPlace) + text.slice(decimalPlace + 1); | ||
|  |             } | ||
|  |             if (exp < 0) throw new Error("Cannot include negative exponent part for integers"); | ||
|  |             text += (new Array(exp + 1)).join("0"); | ||
|  |             v = text; | ||
|  |         } | ||
|  |         var isValid = /^([0-9][0-9]*)$/.test(v); | ||
|  |         if (!isValid) throw new Error("Invalid integer: " + v); | ||
|  |         if (supportsNativeBigInt) { | ||
|  |             return new NativeBigInt(BigInt(sign ? "-" + v : v)); | ||
|  |         } | ||
|  |         var r = [], max = v.length, l = LOG_BASE, min = max - l; | ||
|  |         while (max > 0) { | ||
|  |             r.push(+v.slice(min, max)); | ||
|  |             min -= l; | ||
|  |             if (min < 0) min = 0; | ||
|  |             max -= l; | ||
|  |         } | ||
|  |         trim(r); | ||
|  |         return new BigInteger(r, sign); | ||
|  |     } | ||
|  | 
 | ||
|  |     function parseNumberValue(v) { | ||
|  |         if (supportsNativeBigInt) { | ||
|  |             return new NativeBigInt(BigInt(v)); | ||
|  |         } | ||
|  |         if (isPrecise(v)) { | ||
|  |             if (v !== truncate(v)) throw new Error(v + " is not an integer."); | ||
|  |             return new SmallInteger(v); | ||
|  |         } | ||
|  |         return parseStringValue(v.toString()); | ||
|  |     } | ||
|  | 
 | ||
|  |     function parseValue(v) { | ||
|  |         if (typeof v === "number") { | ||
|  |             return parseNumberValue(v); | ||
|  |         } | ||
|  |         if (typeof v === "string") { | ||
|  |             return parseStringValue(v); | ||
|  |         } | ||
|  |         if (typeof v === "bigint") { | ||
|  |             return new NativeBigInt(v); | ||
|  |         } | ||
|  |         return v; | ||
|  |     } | ||
|  |     // Pre-define numbers in range [-999,999]
 | ||
|  |     for (var i = 0; i < 1000; i++) { | ||
|  |         Integer[i] = parseValue(i); | ||
|  |         if (i > 0) Integer[-i] = parseValue(-i); | ||
|  |     } | ||
|  |     // Backwards compatibility
 | ||
|  |     Integer.one = Integer[1]; | ||
|  |     Integer.zero = Integer[0]; | ||
|  |     Integer.minusOne = Integer[-1]; | ||
|  |     Integer.max = max; | ||
|  |     Integer.min = min; | ||
|  |     Integer.gcd = gcd; | ||
|  |     Integer.lcm = lcm; | ||
|  |     Integer.isInstance = function (x) { return x instanceof BigInteger || x instanceof SmallInteger || x instanceof NativeBigInt; }; | ||
|  |     Integer.randBetween = randBetween; | ||
|  | 
 | ||
|  |     Integer.fromArray = function (digits, base, isNegative) { | ||
|  |         return parseBaseFromArray(digits.map(parseValue), parseValue(base || 10), isNegative); | ||
|  |     }; | ||
|  | 
 | ||
|  |     return Integer; | ||
|  | })(); | ||
|  | 
 | ||
|  | // Node.js check
 | ||
|  | if (typeof module !== "undefined" && module.hasOwnProperty("exports")) { | ||
|  |     module.exports = bigInt; | ||
|  | } | ||
|  | 
 | ||
|  | //amd check
 | ||
|  | if (typeof define === "function" && define.amd) { | ||
|  |     define( function () { | ||
|  |         return bigInt; | ||
|  |     }); | ||
|  | } |