kanatunta

BigInteger

Dec 18th, 2018
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ////////////////////////////////////////////////////
  2. //https://github.com/peterolson/BigInteger.js
  3.  
  4. var bigInt = function (undefined) {
  5.     //"use strict";
  6.  
  7.     var BASE = 1e7,
  8.         LOG_BASE = 7,
  9.         MAX_INT = 9007199254740992,
  10.         MAX_INT_ARR = smallToArray(MAX_INT),
  11.         LOG_MAX_INT = Math.log(MAX_INT);
  12.  
  13.     function Integer(v, radix) {
  14.         if (typeof v === "undefined") return Integer[0];
  15.         if (typeof radix !== "undefined") return +radix === 10 ? parseValue(v) : parseBase(v, radix);
  16.         return parseValue(v);
  17.     }
  18.  
  19.     function BigInteger(value, sign) {
  20.         this.value = value;
  21.         this.sign = sign;
  22.         this.isSmall = false;
  23.     }
  24.     BigInteger.prototype = Object.create(Integer.prototype);
  25.  
  26.     function SmallInteger(value) {
  27.         this.value = value;
  28.         this.sign = value < 0;
  29.         this.isSmall = true;
  30.     }
  31.     SmallInteger.prototype = Object.create(Integer.prototype);
  32.  
  33.     function isPrecise(n) {
  34.         return -MAX_INT < n && n < MAX_INT;
  35.     }
  36.  
  37.     function smallToArray(n) { // For performance reasons doesn't reference BASE, need to change this function if BASE changes
  38.         if (n < 1e7)
  39.             return [n];
  40.         if (n < 1e14)
  41.             return [n % 1e7, Math.floor(n / 1e7)];
  42.         return [n % 1e7, Math.floor(n / 1e7) % 1e7, Math.floor(n / 1e14)];
  43.     }
  44.  
  45.     function arrayToSmall(arr) { // If BASE changes this function may need to change
  46.         trim(arr);
  47.         var length = arr.length;
  48.         if (length < 4 && compareAbs(arr, MAX_INT_ARR) < 0) {
  49.             switch (length) {
  50.                 case 0: return 0;
  51.                 case 1: return arr[0];
  52.                 case 2: return arr[0] + arr[1] * BASE;
  53.                 default: return arr[0] + (arr[1] + arr[2] * BASE) * BASE;
  54.             }
  55.         }
  56.         return arr;
  57.     }
  58.  
  59.     function trim(v) {
  60.         var i = v.length;
  61.         while (v[--i] === 0);
  62.         v.length = i + 1;
  63.     }
  64.  
  65.     function createArray(length) { // function shamelessly stolen from Yaffle's library https://github.com/Yaffle/BigInteger
  66.         var x = new Array(length);
  67.         var i = -1;
  68.         while (++i < length) {
  69.             x[i] = 0;
  70.         }
  71.         return x;
  72.     }
  73.  
  74.     function truncate(n) {
  75.         if (n > 0) return Math.floor(n);
  76.         return Math.ceil(n);
  77.     }
  78.  
  79.     function add(a, b) { // assumes a and b are arrays with a.length >= b.length
  80.         var l_a = a.length,
  81.             l_b = b.length,
  82.             r = new Array(l_a),
  83.             carry = 0,
  84.             base = BASE,
  85.             sum, i;
  86.         for (i = 0; i < l_b; i++) {
  87.             sum = a[i] + b[i] + carry;
  88.             carry = sum >= base ? 1 : 0;
  89.             r[i] = sum - carry * base;
  90.         }
  91.         while (i < l_a) {
  92.             sum = a[i] + carry;
  93.             carry = sum === base ? 1 : 0;
  94.             r[i++] = sum - carry * base;
  95.         }
  96.         if (carry > 0) r.push(carry);
  97.         return r;
  98.     }
  99.  
  100.     function addAny(a, b) {
  101.         if (a.length >= b.length) return add(a, b);
  102.         return add(b, a);
  103.     }
  104.  
  105.     function addSmall(a, carry) { // assumes a is array, carry is number with 0 <= carry < MAX_INT
  106.         var l = a.length,
  107.             r = new Array(l),
  108.             base = BASE,
  109.             sum, i;
  110.         for (i = 0; i < l; i++) {
  111.             sum = a[i] - base + carry;
  112.             carry = Math.floor(sum / base);
  113.             r[i] = sum - carry * base;
  114.             carry += 1;
  115.         }
  116.         while (carry > 0) {
  117.             r[i++] = carry % base;
  118.             carry = Math.floor(carry / base);
  119.         }
  120.         return r;
  121.     }
  122.  
  123.     BigInteger.prototype.add = function (v) {
  124.         var n = parseValue(v);
  125.         if (this.sign !== n.sign) {
  126.             return this.subtract(n.negate());
  127.         }
  128.         var a = this.value, b = n.value;
  129.         if (n.isSmall) {
  130.             return new BigInteger(addSmall(a, Math.abs(b)), this.sign);
  131.         }
  132.         return new BigInteger(addAny(a, b), this.sign);
  133.     };
  134.     BigInteger.prototype.plus = BigInteger.prototype.add;
  135.  
  136.     SmallInteger.prototype.add = function (v) {
  137.         var n = parseValue(v);
  138.         var a = this.value;
  139.         if (a < 0 !== n.sign) {
  140.             return this.subtract(n.negate());
  141.         }
  142.         var b = n.value;
  143.         if (n.isSmall) {
  144.             if (isPrecise(a + b)) return new SmallInteger(a + b);
  145.             b = smallToArray(Math.abs(b));
  146.         }
  147.         return new BigInteger(addSmall(b, Math.abs(a)), a < 0);
  148.     };
  149.     SmallInteger.prototype.plus = SmallInteger.prototype.add;
  150.  
  151.     function subtract(a, b) { // assumes a and b are arrays with a >= b
  152.         var a_l = a.length,
  153.             b_l = b.length,
  154.             r = new Array(a_l),
  155.             borrow = 0,
  156.             base = BASE,
  157.             i, difference;
  158.         for (i = 0; i < b_l; i++) {
  159.             difference = a[i] - borrow - b[i];
  160.             if (difference < 0) {
  161.                 difference += base;
  162.                 borrow = 1;
  163.             } else borrow = 0;
  164.             r[i] = difference;
  165.         }
  166.         for (i = b_l; i < a_l; i++) {
  167.             difference = a[i] - borrow;
  168.             if (difference < 0) difference += base;
  169.             else {
  170.                 r[i++] = difference;
  171.                 break;
  172.             }
  173.             r[i] = difference;
  174.         }
  175.         for (; i < a_l; i++) {
  176.             r[i] = a[i];
  177.         }
  178.         trim(r);
  179.         return r;
  180.     }
  181.  
  182.     function subtractAny(a, b, sign) {
  183.         var value;
  184.         if (compareAbs(a, b) >= 0) {
  185.             value = subtract(a, b);
  186.         } else {
  187.             value = subtract(b, a);
  188.             sign = !sign;
  189.         }
  190.         value = arrayToSmall(value);
  191.         if (typeof value === "number") {
  192.             if (sign) value = -value;
  193.             return new SmallInteger(value);
  194.         }
  195.         return new BigInteger(value, sign);
  196.     }
  197.  
  198.     function subtractSmall(a, b, sign) { // assumes a is array, b is number with 0 <= b < MAX_INT
  199.         var l = a.length,
  200.             r = new Array(l),
  201.             carry = -b,
  202.             base = BASE,
  203.             i, difference;
  204.         for (i = 0; i < l; i++) {
  205.             difference = a[i] + carry;
  206.             carry = Math.floor(difference / base);
  207.             difference %= base;
  208.             r[i] = difference < 0 ? difference + base : difference;
  209.         }
  210.         r = arrayToSmall(r);
  211.         if (typeof r === "number") {
  212.             if (sign) r = -r;
  213.             return new SmallInteger(r);
  214.         } return new BigInteger(r, sign);
  215.     }
  216.  
  217.     BigInteger.prototype.subtract = function (v) {
  218.         var n = parseValue(v);
  219.         if (this.sign !== n.sign) {
  220.             return this.add(n.negate());
  221.         }
  222.         var a = this.value, b = n.value;
  223.         if (n.isSmall)
  224.             return subtractSmall(a, Math.abs(b), this.sign);
  225.         return subtractAny(a, b, this.sign);
  226.     };
  227.     BigInteger.prototype.minus = BigInteger.prototype.subtract;
  228.  
  229.     SmallInteger.prototype.subtract = function (v) {
  230.         var n = parseValue(v);
  231.         var a = this.value;
  232.         if (a < 0 !== n.sign) {
  233.             return this.add(n.negate());
  234.         }
  235.         var b = n.value;
  236.         if (n.isSmall) {
  237.             return new SmallInteger(a - b);
  238.         }
  239.         return subtractSmall(b, Math.abs(a), a >= 0);
  240.     };
  241.     SmallInteger.prototype.minus = SmallInteger.prototype.subtract;
  242.  
  243.     BigInteger.prototype.negate = function () {
  244.         return new BigInteger(this.value, !this.sign);
  245.     };
  246.     SmallInteger.prototype.negate = function () {
  247.         var sign = this.sign;
  248.         var small = new SmallInteger(-this.value);
  249.         small.sign = !sign;
  250.         return small;
  251.     };
  252.  
  253.     BigInteger.prototype.abs = function () {
  254.         return new BigInteger(this.value, false);
  255.     };
  256.     SmallInteger.prototype.abs = function () {
  257.         return new SmallInteger(Math.abs(this.value));
  258.     };
  259.  
  260.     function multiplyLong(a, b) {
  261.         var a_l = a.length,
  262.             b_l = b.length,
  263.             l = a_l + b_l,
  264.             r = createArray(l),
  265.             base = BASE,
  266.             product, carry, i, a_i, b_j;
  267.         for (i = 0; i < a_l; ++i) {
  268.             a_i = a[i];
  269.             for (var j = 0; j < b_l; ++j) {
  270.                 b_j = b[j];
  271.                 product = a_i * b_j + r[i + j];
  272.                 carry = Math.floor(product / base);
  273.                 r[i + j] = product - carry * base;
  274.                 r[i + j + 1] += carry;
  275.             }
  276.         }
  277.         trim(r);
  278.         return r;
  279.     }
  280.  
  281.     function multiplySmall(a, b) { // assumes a is array, b is number with |b| < BASE
  282.         var l = a.length,
  283.             r = new Array(l),
  284.             base = BASE,
  285.             carry = 0,
  286.             product, i;
  287.         for (i = 0; i < l; i++) {
  288.             product = a[i] * b + carry;
  289.             carry = Math.floor(product / base);
  290.             r[i] = product - carry * base;
  291.         }
  292.         while (carry > 0) {
  293.             r[i++] = carry % base;
  294.             carry = Math.floor(carry / base);
  295.         }
  296.         return r;
  297.     }
  298.  
  299.     function shiftLeft(x, n) {
  300.         var r = [];
  301.         while (n-- > 0) r.push(0);
  302.         return r.concat(x);
  303.     }
  304.  
  305.     function multiplyKaratsuba(x, y) {
  306.         var n = Math.max(x.length, y.length);
  307.  
  308.         if (n <= 30) return multiplyLong(x, y);
  309.         n = Math.ceil(n / 2);
  310.  
  311.         var b = x.slice(n),
  312.             a = x.slice(0, n),
  313.             d = y.slice(n),
  314.             c = y.slice(0, n);
  315.  
  316.         var ac = multiplyKaratsuba(a, c),
  317.             bd = multiplyKaratsuba(b, d),
  318.             abcd = multiplyKaratsuba(addAny(a, b), addAny(c, d));
  319.  
  320.         var product = addAny(addAny(ac, shiftLeft(subtract(subtract(abcd, ac), bd), n)), shiftLeft(bd, 2 * n));
  321.         trim(product);
  322.         return product;
  323.     }
  324.  
  325.     // The following function is derived from a surface fit of a graph plotting the performance difference
  326.     // between long multiplication and karatsuba multiplication versus the lengths of the two arrays.
  327.     function useKaratsuba(l1, l2) {
  328.         return -0.012 * l1 - 0.012 * l2 + 0.000015 * l1 * l2 > 0;
  329.     }
  330.  
  331.     BigInteger.prototype.multiply = function (v) {
  332.         var n = parseValue(v),
  333.             a = this.value, b = n.value,
  334.             sign = this.sign !== n.sign,
  335.             abs;
  336.         if (n.isSmall) {
  337.             if (b === 0) return Integer[0];
  338.             if (b === 1) return this;
  339.             if (b === -1) return this.negate();
  340.             abs = Math.abs(b);
  341.             if (abs < BASE) {
  342.                 return new BigInteger(multiplySmall(a, abs), sign);
  343.             }
  344.             b = smallToArray(abs);
  345.         }
  346.         if (useKaratsuba(a.length, b.length)) // Karatsuba is only faster for certain array sizes
  347.             return new BigInteger(multiplyKaratsuba(a, b), sign);
  348.         return new BigInteger(multiplyLong(a, b), sign);
  349.     };
  350.  
  351.     BigInteger.prototype.times = BigInteger.prototype.multiply;
  352.  
  353.     function multiplySmallAndArray(a, b, sign) { // a >= 0
  354.         if (a < BASE) {
  355.             return new BigInteger(multiplySmall(b, a), sign);
  356.         }
  357.         return new BigInteger(multiplyLong(b, smallToArray(a)), sign);
  358.     }
  359.     SmallInteger.prototype._multiplyBySmall = function (a) {
  360.         if (isPrecise(a.value * this.value)) {
  361.             return new SmallInteger(a.value * this.value);
  362.         }
  363.         return multiplySmallAndArray(Math.abs(a.value), smallToArray(Math.abs(this.value)), this.sign !== a.sign);
  364.     };
  365.     BigInteger.prototype._multiplyBySmall = function (a) {
  366.         if (a.value === 0) return Integer[0];
  367.         if (a.value === 1) return this;
  368.         if (a.value === -1) return this.negate();
  369.         return multiplySmallAndArray(Math.abs(a.value), this.value, this.sign !== a.sign);
  370.     };
  371.     SmallInteger.prototype.multiply = function (v) {
  372.         return parseValue(v)._multiplyBySmall(this);
  373.     };
  374.     SmallInteger.prototype.times = SmallInteger.prototype.multiply;
  375.  
  376.     function square(a) {
  377.         //console.assert(2 * BASE * BASE < MAX_INT);
  378.         var l = a.length,
  379.             r = createArray(l + l),
  380.             base = BASE,
  381.             product, carry, i, a_i, a_j;
  382.         for (i = 0; i < l; i++) {
  383.             a_i = a[i];
  384.             carry = 0 - a_i * a_i;
  385.             for (var j = i; j < l; j++) {
  386.                 a_j = a[j];
  387.                 product = 2 * (a_i * a_j) + r[i + j] + carry;
  388.                 carry = Math.floor(product / base);
  389.                 r[i + j] = product - carry * base;
  390.             }
  391.             r[i + l] = carry;
  392.         }
  393.         trim(r);
  394.         return r;
  395.     }
  396.  
  397.     BigInteger.prototype.square = function () {
  398.         return new BigInteger(square(this.value), false);
  399.     };
  400.  
  401.     SmallInteger.prototype.square = function () {
  402.         var value = this.value * this.value;
  403.         if (isPrecise(value)) return new SmallInteger(value);
  404.         return new BigInteger(square(smallToArray(Math.abs(this.value))), false);
  405.     };
  406.  
  407.     function divMod1(a, b) { // Left over from previous version. Performs faster than divMod2 on smaller input sizes.
  408.         var a_l = a.length,
  409.             b_l = b.length,
  410.             base = BASE,
  411.             result = createArray(b.length),
  412.             divisorMostSignificantDigit = b[b_l - 1],
  413.             // normalization
  414.             lambda = Math.ceil(base / (2 * divisorMostSignificantDigit)),
  415.             remainder = multiplySmall(a, lambda),
  416.             divisor = multiplySmall(b, lambda),
  417.             quotientDigit, shift, carry, borrow, i, l, q;
  418.         if (remainder.length <= a_l) remainder.push(0);
  419.         divisor.push(0);
  420.         divisorMostSignificantDigit = divisor[b_l - 1];
  421.         for (shift = a_l - b_l; shift >= 0; shift--) {
  422.             quotientDigit = base - 1;
  423.             if (remainder[shift + b_l] !== divisorMostSignificantDigit) {
  424.                 quotientDigit = Math.floor((remainder[shift + b_l] * base + remainder[shift + b_l - 1]) / divisorMostSignificantDigit);
  425.             }
  426.             // quotientDigit <= base - 1
  427.             carry = 0;
  428.             borrow = 0;
  429.             l = divisor.length;
  430.             for (i = 0; i < l; i++) {
  431.                 carry += quotientDigit * divisor[i];
  432.                 q = Math.floor(carry / base);
  433.                 borrow += remainder[shift + i] - (carry - q * base);
  434.                 carry = q;
  435.                 if (borrow < 0) {
  436.                     remainder[shift + i] = borrow + base;
  437.                     borrow = -1;
  438.                 } else {
  439.                     remainder[shift + i] = borrow;
  440.                     borrow = 0;
  441.                 }
  442.             }
  443.             while (borrow !== 0) {
  444.                 quotientDigit -= 1;
  445.                 carry = 0;
  446.                 for (i = 0; i < l; i++) {
  447.                     carry += remainder[shift + i] - base + divisor[i];
  448.                     if (carry < 0) {
  449.                         remainder[shift + i] = carry + base;
  450.                         carry = 0;
  451.                     } else {
  452.                         remainder[shift + i] = carry;
  453.                         carry = 1;
  454.                     }
  455.                 }
  456.                 borrow += carry;
  457.             }
  458.             result[shift] = quotientDigit;
  459.         }
  460.         // denormalization
  461.         remainder = divModSmall(remainder, lambda)[0];
  462.         return [arrayToSmall(result), arrayToSmall(remainder)];
  463.     }
  464.  
  465.     function divMod2(a, b) { // Implementation idea shamelessly stolen from Silent Matt's library http://silentmatt.com/biginteger/
  466.         // Performs faster than divMod1 on larger input sizes.
  467.         var a_l = a.length,
  468.             b_l = b.length,
  469.             result = [],
  470.             part = [],
  471.             base = BASE,
  472.             guess, xlen, highx, highy, check;
  473.         while (a_l) {
  474.             part.unshift(a[--a_l]);
  475.             trim(part);
  476.             if (compareAbs(part, b) < 0) {
  477.                 result.push(0);
  478.                 continue;
  479.             }
  480.             xlen = part.length;
  481.             highx = part[xlen - 1] * base + part[xlen - 2];
  482.             highy = b[b_l - 1] * base + b[b_l - 2];
  483.             if (xlen > b_l) {
  484.                 highx = (highx + 1) * base;
  485.             }
  486.             guess = Math.ceil(highx / highy);
  487.             do {
  488.                 check = multiplySmall(b, guess);
  489.                 if (compareAbs(check, part) <= 0) break;
  490.                 guess--;
  491.             } while (guess);
  492.             result.push(guess);
  493.             part = subtract(part, check);
  494.         }
  495.         result.reverse();
  496.         return [arrayToSmall(result), arrayToSmall(part)];
  497.     }
  498.  
  499.     function divModSmall(value, lambda) {
  500.         var length = value.length,
  501.             quotient = createArray(length),
  502.             base = BASE,
  503.             i, q, remainder, divisor;
  504.         remainder = 0;
  505.         for (i = length - 1; i >= 0; --i) {
  506.             divisor = remainder * base + value[i];
  507.             q = truncate(divisor / lambda);
  508.             remainder = divisor - q * lambda;
  509.             quotient[i] = q | 0;
  510.         }
  511.         return [quotient, remainder | 0];
  512.     }
  513.  
  514.     function divModAny(self, v) {
  515.         var value, n = parseValue(v);
  516.         var a = self.value, b = n.value;
  517.         var quotient;
  518.         if (b === 0) throw new Error("Cannot divide by zero");
  519.         if (self.isSmall) {
  520.             if (n.isSmall) {
  521.                 return [new SmallInteger(truncate(a / b)), new SmallInteger(a % b)];
  522.             }
  523.             return [Integer[0], self];
  524.         }
  525.         if (n.isSmall) {
  526.             if (b === 1) return [self, Integer[0]];
  527.             if (b == -1) return [self.negate(), Integer[0]];
  528.             var abs = Math.abs(b);
  529.             if (abs < BASE) {
  530.                 value = divModSmall(a, abs);
  531.                 quotient = arrayToSmall(value[0]);
  532.                 var remainder = value[1];
  533.                 if (self.sign) remainder = -remainder;
  534.                 if (typeof quotient === "number") {
  535.                     if (self.sign !== n.sign) quotient = -quotient;
  536.                     return [new SmallInteger(quotient), new SmallInteger(remainder)];
  537.                 }
  538.                 return [new BigInteger(quotient, self.sign !== n.sign), new SmallInteger(remainder)];
  539.             }
  540.             b = smallToArray(abs);
  541.         }
  542.         var comparison = compareAbs(a, b);
  543.         if (comparison === -1) return [Integer[0], self];
  544.         if (comparison === 0) return [Integer[self.sign === n.sign ? 1 : -1], Integer[0]];
  545.  
  546.         // divMod1 is faster on smaller input sizes
  547.         if (a.length + b.length <= 200)
  548.             value = divMod1(a, b);
  549.         else value = divMod2(a, b);
  550.  
  551.         quotient = value[0];
  552.         var qSign = self.sign !== n.sign,
  553.             mod = value[1],
  554.             mSign = self.sign;
  555.         if (typeof quotient === "number") {
  556.             if (qSign) quotient = -quotient;
  557.             quotient = new SmallInteger(quotient);
  558.         } else quotient = new BigInteger(quotient, qSign);
  559.         if (typeof mod === "number") {
  560.             if (mSign) mod = -mod;
  561.             mod = new SmallInteger(mod);
  562.         } else mod = new BigInteger(mod, mSign);
  563.         return [quotient, mod];
  564.     }
  565.  
  566.     BigInteger.prototype.divmod = function (v) {
  567.         var result = divModAny(this, v);
  568.         return {
  569.             quotient: result[0],
  570.             remainder: result[1]
  571.         };
  572.     };
  573.     SmallInteger.prototype.divmod = BigInteger.prototype.divmod;
  574.  
  575.     BigInteger.prototype.divide = function (v) {
  576.         return divModAny(this, v)[0];
  577.     };
  578.     SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide;
  579.  
  580.     BigInteger.prototype.mod = function (v) {
  581.         return divModAny(this, v)[1];
  582.     };
  583.     SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod;
  584.  
  585.     BigInteger.prototype.pow = function (v) {
  586.         var n = parseValue(v),
  587.             a = this.value,
  588.             b = n.value,
  589.             value, x, y;
  590.         if (b === 0) return Integer[1];
  591.         if (a === 0) return Integer[0];
  592.         if (a === 1) return Integer[1];
  593.         if (a === -1) return n.isEven() ? Integer[1] : Integer[-1];
  594.         if (n.sign) {
  595.             return Integer[0];
  596.         }
  597.         if (!n.isSmall) throw new Error("The exponent " + n.toString() + " is too large.");
  598.         if (this.isSmall) {
  599.             if (isPrecise(value = Math.pow(a, b)))
  600.                 return new SmallInteger(truncate(value));
  601.         }
  602.         x = this;
  603.         y = Integer[1];
  604.         while (true) {
  605.             if (b & 1 === 1) {
  606.                 y = y.times(x);
  607.                 --b;
  608.             }
  609.             if (b === 0) break;
  610.             b /= 2;
  611.             x = x.square();
  612.         }
  613.         return y;
  614.     };
  615.     SmallInteger.prototype.pow = BigInteger.prototype.pow;
  616.  
  617.     BigInteger.prototype.modPow = function (exp, mod) {
  618.         exp = parseValue(exp);
  619.         mod = parseValue(mod);
  620.         if (mod.isZero()) throw new Error("Cannot take modPow with modulus 0");
  621.         var r = Integer[1],
  622.             base = this.mod(mod);
  623.         while (exp.isPositive()) {
  624.             if (base.isZero()) return Integer[0];
  625.             if (exp.isOdd()) r = r.multiply(base).mod(mod);
  626.             exp = exp.divide(2);
  627.             base = base.square().mod(mod);
  628.         }
  629.         return r;
  630.     };
  631.     SmallInteger.prototype.modPow = BigInteger.prototype.modPow;
  632.  
  633.     function compareAbs(a, b) {
  634.         if (a.length !== b.length) {
  635.             return a.length > b.length ? 1 : -1;
  636.         }
  637.         for (var i = a.length - 1; i >= 0; i--) {
  638.             if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1;
  639.         }
  640.         return 0;
  641.     }
  642.  
  643.     BigInteger.prototype.compareAbs = function (v) {
  644.         var n = parseValue(v),
  645.             a = this.value,
  646.             b = n.value;
  647.         if (n.isSmall) return 1;
  648.         return compareAbs(a, b);
  649.     };
  650.     SmallInteger.prototype.compareAbs = function (v) {
  651.         var n = parseValue(v),
  652.             a = Math.abs(this.value),
  653.             b = n.value;
  654.         if (n.isSmall) {
  655.             b = Math.abs(b);
  656.             return a === b ? 0 : a > b ? 1 : -1;
  657.         }
  658.         return -1;
  659.     };
  660.  
  661.     BigInteger.prototype.compare = function (v) {
  662.         // See discussion about comparison with Infinity:
  663.         // https://github.com/peterolson/BigInteger.js/issues/61
  664.         if (v === Infinity) {
  665.             return -1;
  666.         }
  667.         if (v === -Infinity) {
  668.             return 1;
  669.         }
  670.  
  671.         var n = parseValue(v),
  672.             a = this.value,
  673.             b = n.value;
  674.         if (this.sign !== n.sign) {
  675.             return n.sign ? 1 : -1;
  676.         }
  677.         if (n.isSmall) {
  678.             return this.sign ? -1 : 1;
  679.         }
  680.         return compareAbs(a, b) * (this.sign ? -1 : 1);
  681.     };
  682.     BigInteger.prototype.compareTo = BigInteger.prototype.compare;
  683.  
  684.     SmallInteger.prototype.compare = function (v) {
  685.         if (v === Infinity) {
  686.             return -1;
  687.         }
  688.         if (v === -Infinity) {
  689.             return 1;
  690.         }
  691.  
  692.         var n = parseValue(v),
  693.             a = this.value,
  694.             b = n.value;
  695.         if (n.isSmall) {
  696.             return a == b ? 0 : a > b ? 1 : -1;
  697.         }
  698.         if (a < 0 !== n.sign) {
  699.             return a < 0 ? -1 : 1;
  700.         }
  701.         return a < 0 ? 1 : -1;
  702.     };
  703.     SmallInteger.prototype.compareTo = SmallInteger.prototype.compare;
  704.  
  705.     BigInteger.prototype.equals = function (v) {
  706.         return this.compare(v) === 0;
  707.     };
  708.     SmallInteger.prototype.eq = SmallInteger.prototype.equals = BigInteger.prototype.eq = BigInteger.prototype.equals;
  709.  
  710.     BigInteger.prototype.notEquals = function (v) {
  711.         return this.compare(v) !== 0;
  712.     };
  713.     SmallInteger.prototype.neq = SmallInteger.prototype.notEquals = BigInteger.prototype.neq = BigInteger.prototype.notEquals;
  714.  
  715.     BigInteger.prototype.greater = function (v) {
  716.         return this.compare(v) > 0;
  717.     };
  718.     SmallInteger.prototype.gt = SmallInteger.prototype.greater = BigInteger.prototype.gt = BigInteger.prototype.greater;
  719.  
  720.     BigInteger.prototype.lesser = function (v) {
  721.         return this.compare(v) < 0;
  722.     };
  723.     SmallInteger.prototype.lt = SmallInteger.prototype.lesser = BigInteger.prototype.lt = BigInteger.prototype.lesser;
  724.  
  725.     BigInteger.prototype.greaterOrEquals = function (v) {
  726.         return this.compare(v) >= 0;
  727.     };
  728.     SmallInteger.prototype.geq = SmallInteger.prototype.greaterOrEquals = BigInteger.prototype.geq = BigInteger.prototype.greaterOrEquals;
  729.  
  730.     BigInteger.prototype.lesserOrEquals = function (v) {
  731.         return this.compare(v) <= 0;
  732.     };
  733.     SmallInteger.prototype.leq = SmallInteger.prototype.lesserOrEquals = BigInteger.prototype.leq = BigInteger.prototype.lesserOrEquals;
  734.  
  735.     BigInteger.prototype.isEven = function () {
  736.         return (this.value[0] & 1) === 0;
  737.     };
  738.     SmallInteger.prototype.isEven = function () {
  739.         return (this.value & 1) === 0;
  740.     };
  741.  
  742.     BigInteger.prototype.isOdd = function () {
  743.         return (this.value[0] & 1) === 1;
  744.     };
  745.     SmallInteger.prototype.isOdd = function () {
  746.         return (this.value & 1) === 1;
  747.     };
  748.  
  749.     BigInteger.prototype.isPositive = function () {
  750.         return !this.sign;
  751.     };
  752.     SmallInteger.prototype.isPositive = function () {
  753.         return this.value > 0;
  754.     };
  755.  
  756.     BigInteger.prototype.isNegative = function () {
  757.         return this.sign;
  758.     };
  759.     SmallInteger.prototype.isNegative = function () {
  760.         return this.value < 0;
  761.     };
  762.  
  763.     BigInteger.prototype.isUnit = function () {
  764.         return false;
  765.     };
  766.     SmallInteger.prototype.isUnit = function () {
  767.         return Math.abs(this.value) === 1;
  768.     };
  769.  
  770.     BigInteger.prototype.isZero = function () {
  771.         return false;
  772.     };
  773.     SmallInteger.prototype.isZero = function () {
  774.         return this.value === 0;
  775.     };
  776.     BigInteger.prototype.isDivisibleBy = function (v) {
  777.         var n = parseValue(v);
  778.         var value = n.value;
  779.         if (value === 0) return false;
  780.         if (value === 1) return true;
  781.         if (value === 2) return this.isEven();
  782.         return this.mod(n).isZero();
  783.     };
  784.     SmallInteger.prototype.isDivisibleBy = BigInteger.prototype.isDivisibleBy;
  785.  
  786.     function isBasicPrime(v) {
  787.         var n = v.abs();
  788.         if (n.isUnit()) return false;
  789.         if (n.equals(2) || n.equals(3) || n.equals(5)) return true;
  790.         if (n.isEven() || n.isDivisibleBy(3) || n.isDivisibleBy(5)) return false;
  791.         if (n.lesser(49)) return true;
  792.         // we don't know if it's prime: let the other functions figure it out
  793.     }
  794.    
  795.     function millerRabinTest(n, a) {
  796.         var nPrev = n.prev(),
  797.             b = nPrev,
  798.             r = 0,
  799.             d, t, i, x;
  800.         while (b.isEven()) b = b.divide(2), r++;
  801.         next : for (i = 0; i < a.length; i++) {
  802.             if (n.lesser(a[i])) continue;
  803.             x = bigInt(a[i]).modPow(b, n);
  804.             if (x.isUnit() || x.equals(nPrev)) continue;
  805.             for (d = r - 1; d != 0; d--) {
  806.                 x = x.square().mod(n);
  807.                 if (x.isUnit()) return false;    
  808.                 if (x.equals(nPrev)) continue next;
  809.             }
  810.             return false;
  811.         }
  812.         return true;
  813.     }
  814.    
  815. // Set "strict" to true to force GRH-supported lower bound of 2*log(N)^2
  816.     BigInteger.prototype.isPrime = function (strict) {
  817.         var isPrime = isBasicPrime(this);
  818.         if (isPrime !== undefined) return isPrime;
  819.         var n = this.abs();
  820.         var bits = n.bitLength();
  821.         if (bits <= 64)
  822.             return millerRabinTest(n, [2, 325, 9375, 28178, 450775, 9780504, 1795265022]);
  823.         var logN = Math.log(2) * bits;
  824.         var t = Math.ceil((strict === true) ? (2 * Math.pow(logN, 2)) : logN);
  825.         for (var a = [], i = 0; i < t; i++) {
  826.             a.push(bigInt(i + 2));
  827.         }
  828.         return millerRabinTest(n, a);
  829.     };
  830.     SmallInteger.prototype.isPrime = BigInteger.prototype.isPrime;
  831.  
  832.     BigInteger.prototype.isProbablePrime = function (iterations) {
  833.         var isPrime = isBasicPrime(this);
  834.         if (isPrime !== undefined) return isPrime;
  835.         var n = this.abs();
  836.         var t = iterations === undefined ? 5 : iterations;
  837.         for (var a = [], i = 0; i < t; i++) {
  838.             a.push(bigInt.randBetween(2, n.minus(2)));
  839.         }
  840.         return millerRabinTest(n, a);
  841.     };
  842.     SmallInteger.prototype.isProbablePrime = BigInteger.prototype.isProbablePrime;
  843.  
  844.     BigInteger.prototype.modInv = function (n) {
  845.         var t = bigInt.zero, newT = bigInt.one, r = parseValue(n), newR = this.abs(), q, lastT, lastR;
  846.         while (!newR.isZero()) {
  847.             q = r.divide(newR);
  848.             lastT = t;
  849.             lastR = r;
  850.             t = newT;
  851.             r = newR;
  852.             newT = lastT.subtract(q.multiply(newT));
  853.             newR = lastR.subtract(q.multiply(newR));
  854.         }
  855.         if (!r.isUnit()) throw new Error(this.toString() + " and " + n.toString() + " are not co-prime");
  856.         if (t.compare(0) === -1) {
  857.             t = t.add(n);
  858.         }
  859.         if (this.isNegative()) {
  860.             return t.negate();
  861.         }
  862.         return t;
  863.     };
  864.  
  865.     SmallInteger.prototype.modInv = BigInteger.prototype.modInv;
  866.  
  867.     BigInteger.prototype.next = function () {
  868.         var value = this.value;
  869.         if (this.sign) {
  870.             return subtractSmall(value, 1, this.sign);
  871.         }
  872.         return new BigInteger(addSmall(value, 1), this.sign);
  873.     };
  874.     SmallInteger.prototype.next = function () {
  875.         var value = this.value;
  876.         if (value + 1 < MAX_INT) return new SmallInteger(value + 1);
  877.         return new BigInteger(MAX_INT_ARR, false);
  878.     };
  879.  
  880.     BigInteger.prototype.prev = function () {
  881.         var value = this.value;
  882.         if (this.sign) {
  883.             return new BigInteger(addSmall(value, 1), true);
  884.         }
  885.         return subtractSmall(value, 1, this.sign);
  886.     };
  887.     SmallInteger.prototype.prev = function () {
  888.         var value = this.value;
  889.         if (value - 1 > -MAX_INT) return new SmallInteger(value - 1);
  890.         return new BigInteger(MAX_INT_ARR, true);
  891.     };
  892.  
  893.     var powersOfTwo = [1];
  894.     while (2 * powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
  895.     var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1];
  896.  
  897.     function shift_isSmall(n) {
  898.         return ((typeof n === "number" || typeof n === "string") && +Math.abs(n) <= BASE) ||
  899.             (n instanceof BigInteger && n.value.length <= 1);
  900.     }
  901.  
  902.     BigInteger.prototype.shiftLeft = function (n) {
  903.         if (!shift_isSmall(n)) {
  904.             throw new Error(String(n) + " is too large for shifting.");
  905.         }
  906.         n = +n;
  907.         if (n < 0) return this.shiftRight(-n);
  908.         var result = this;
  909.         if (result.isZero()) return result;
  910.         while (n >= powers2Length) {
  911.             result = result.multiply(highestPower2);
  912.             n -= powers2Length - 1;
  913.         }
  914.         return result.multiply(powersOfTwo[n]);
  915.     };
  916.     SmallInteger.prototype.shiftLeft = BigInteger.prototype.shiftLeft;
  917.  
  918.     BigInteger.prototype.shiftRight = function (n) {
  919.         var remQuo;
  920.         if (!shift_isSmall(n)) {
  921.             throw new Error(String(n) + " is too large for shifting.");
  922.         }
  923.         n = +n;
  924.         if (n < 0) return this.shiftLeft(-n);
  925.         var result = this;
  926.         while (n >= powers2Length) {
  927.             if (result.isZero() || (result.isNegative() && result.isUnit())) return result;
  928.             remQuo = divModAny(result, highestPower2);
  929.             result = remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
  930.             n -= powers2Length - 1;
  931.         }
  932.         remQuo = divModAny(result, powersOfTwo[n]);
  933.         return remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
  934.     };
  935.     SmallInteger.prototype.shiftRight = BigInteger.prototype.shiftRight;
  936.  
  937.     function bitwise(x, y, fn) {
  938.         y = parseValue(y);
  939.         var xSign = x.isNegative(), ySign = y.isNegative();
  940.         var xRem = xSign ? x.not() : x,
  941.             yRem = ySign ? y.not() : y;
  942.         var xDigit = 0, yDigit = 0;
  943.         var xDivMod = null, yDivMod = null;
  944.         var result = [];
  945.         while (!xRem.isZero() || !yRem.isZero()) {
  946.             xDivMod = divModAny(xRem, highestPower2);
  947.             xDigit = xDivMod[1].toJSNumber();
  948.             if (xSign) {
  949.                 xDigit = highestPower2 - 1 - xDigit; // two's complement for negative numbers
  950.             }
  951.  
  952.             yDivMod = divModAny(yRem, highestPower2);
  953.             yDigit = yDivMod[1].toJSNumber();
  954.             if (ySign) {
  955.                 yDigit = highestPower2 - 1 - yDigit; // two's complement for negative numbers
  956.             }
  957.  
  958.             xRem = xDivMod[0];
  959.             yRem = yDivMod[0];
  960.             result.push(fn(xDigit, yDigit));
  961.         }
  962.         var sum = fn(xSign ? 1 : 0, ySign ? 1 : 0) !== 0 ? bigInt(-1) : bigInt(0);
  963.         for (var i = result.length - 1; i >= 0; i -= 1) {
  964.             sum = sum.multiply(highestPower2).add(bigInt(result[i]));
  965.         }
  966.         return sum;
  967.     }
  968.  
  969.     BigInteger.prototype.not = function () {
  970.         return this.negate().prev();
  971.     };
  972.     SmallInteger.prototype.not = BigInteger.prototype.not;
  973.  
  974.     BigInteger.prototype.and = function (n) {
  975.         return bitwise(this, n, function (a, b) { return a & b; });
  976.     };
  977.     SmallInteger.prototype.and = BigInteger.prototype.and;
  978.  
  979.     BigInteger.prototype.or = function (n) {
  980.         return bitwise(this, n, function (a, b) { return a | b; });
  981.     };
  982.     SmallInteger.prototype.or = BigInteger.prototype.or;
  983.  
  984.     BigInteger.prototype.xor = function (n) {
  985.         return bitwise(this, n, function (a, b) { return a ^ b; });
  986.     };
  987.     SmallInteger.prototype.xor = BigInteger.prototype.xor;
  988.  
  989.     var LOBMASK_I = 1 << 30, LOBMASK_BI = (BASE & -BASE) * (BASE & -BASE) | LOBMASK_I;
  990.     function roughLOB(n) { // get lowestOneBit (rough)
  991.         // SmallInteger: return Min(lowestOneBit(n), 1 << 30)
  992.         // BigInteger: return Min(lowestOneBit(n), 1 << 14) [BASE=1e7]
  993.         var v = n.value, x = typeof v === "number" ? v | LOBMASK_I : v[0] + v[1] * BASE | LOBMASK_BI;
  994.         return x & -x;
  995.     }
  996.  
  997.     function integerLogarithm(value, base) {
  998.         if (base.compareTo(value) <= 0) {
  999.             var tmp = integerLogarithm(value, base.square(base));
  1000.             var p = tmp.p;
  1001.             var e = tmp.e;
  1002.             var t = p.multiply(base);
  1003.             return t.compareTo(value) <= 0 ? { p: t, e: e * 2 + 1 } : { p: p, e: e * 2 };
  1004.         }
  1005.         return { p: bigInt(1), e: 0 };
  1006.     }
  1007.  
  1008.     BigInteger.prototype.bitLength = function () {
  1009.         var n = this;
  1010.         if (n.compareTo(bigInt(0)) < 0) {
  1011.             n = n.negate().subtract(bigInt(1));
  1012.         }
  1013.         if (n.compareTo(bigInt(0)) === 0) {
  1014.             return bigInt(0);
  1015.         }
  1016.         return bigInt(integerLogarithm(n, bigInt(2)).e).add(bigInt(1));
  1017.     }
  1018.     SmallInteger.prototype.bitLength = BigInteger.prototype.bitLength;
  1019.  
  1020.     function max(a, b) {
  1021.         a = parseValue(a);
  1022.         b = parseValue(b);
  1023.         return a.greater(b) ? a : b;
  1024.     }
  1025.     function min(a, b) {
  1026.         a = parseValue(a);
  1027.         b = parseValue(b);
  1028.         return a.lesser(b) ? a : b;
  1029.     }
  1030.     function gcd(a, b) {
  1031.         a = parseValue(a).abs();
  1032.         b = parseValue(b).abs();
  1033.         if (a.equals(b)) return a;
  1034.         if (a.isZero()) return b;
  1035.         if (b.isZero()) return a;
  1036.         var c = Integer[1], d, t;
  1037.         while (a.isEven() && b.isEven()) {
  1038.             d = Math.min(roughLOB(a), roughLOB(b));
  1039.             a = a.divide(d);
  1040.             b = b.divide(d);
  1041.             c = c.multiply(d);
  1042.         }
  1043.         while (a.isEven()) {
  1044.             a = a.divide(roughLOB(a));
  1045.         }
  1046.         do {
  1047.             while (b.isEven()) {
  1048.                 b = b.divide(roughLOB(b));
  1049.             }
  1050.             if (a.greater(b)) {
  1051.                 t = b; b = a; a = t;
  1052.             }
  1053.             b = b.subtract(a);
  1054.         } while (!b.isZero());
  1055.         return c.isUnit() ? a : a.multiply(c);
  1056.     }
  1057.     function lcm(a, b) {
  1058.         a = parseValue(a).abs();
  1059.         b = parseValue(b).abs();
  1060.         return a.divide(gcd(a, b)).multiply(b);
  1061.     }
  1062.     function randBetween(a, b) {
  1063.         a = parseValue(a);
  1064.         b = parseValue(b);
  1065.         var low = min(a, b), high = max(a, b);
  1066.         var range = high.subtract(low).add(1);
  1067.         if (range.isSmall) return low.add(Math.floor(Math.random() * range));
  1068.         var length = range.value.length - 1;
  1069.         var result = [], restricted = true;
  1070.         for (var i = length; i >= 0; i--) {
  1071.             var top = restricted ? range.value[i] : BASE;
  1072.             var digit = truncate(Math.random() * top);
  1073.             result.unshift(digit);
  1074.             if (digit < top) restricted = false;
  1075.         }
  1076.         result = arrayToSmall(result);
  1077.         return low.add(typeof result === "number" ? new SmallInteger(result) : new BigInteger(result, false));
  1078.     }
  1079.     var parseBase = function (text, base) {
  1080.         var length = text.length;
  1081.         var i;
  1082.         var absBase = Math.abs(base);
  1083.         for (var i = 0; i < length; i++) {
  1084.             var c = text[i].toLowerCase();
  1085.             if (c === "-") continue;
  1086.             if (/[a-z0-9]/.test(c)) {
  1087.                 if (/[0-9]/.test(c) && +c >= absBase) {
  1088.                     if (c === "1" && absBase === 1) continue;
  1089.                     throw new Error(c + " is not a valid digit in base " + base + ".");
  1090.                 } else if (c.charCodeAt(0) - 87 >= absBase) {
  1091.                     throw new Error(c + " is not a valid digit in base " + base + ".");
  1092.                 }
  1093.             }
  1094.         }
  1095.         if (2 <= base && base <= 36) {
  1096.             if (length <= LOG_MAX_INT / Math.log(base)) {
  1097.                 var result = parseInt(text, base);
  1098.                 if (isNaN(result)) {
  1099.                     throw new Error(c + " is not a valid digit in base " + base + ".");
  1100.                 }
  1101.                 return new SmallInteger(parseInt(text, base));
  1102.             }
  1103.         }
  1104.         base = parseValue(base);
  1105.         var digits = [];
  1106.         var isNegative = text[0] === "-";
  1107.         for (i = isNegative ? 1 : 0; i < text.length; i++) {
  1108.             var c = text[i].toLowerCase(),
  1109.                 charCode = c.charCodeAt(0);
  1110.             if (48 <= charCode && charCode <= 57) digits.push(parseValue(c));
  1111.             else if (97 <= charCode && charCode <= 122) digits.push(parseValue(c.charCodeAt(0) - 87));
  1112.             else if (c === "<") {
  1113.                 var start = i;
  1114.                 do { i++; } while (text[i] !== ">");
  1115.                 digits.push(parseValue(text.slice(start + 1, i)));
  1116.             }
  1117.             else throw new Error(c + " is not a valid character");
  1118.         }
  1119.         return parseBaseFromArray(digits, base, isNegative);
  1120.     };
  1121.  
  1122.     function parseBaseFromArray(digits, base, isNegative) {
  1123.         var val = Integer[0], pow = Integer[1], i;
  1124.         for (i = digits.length - 1; i >= 0; i--) {
  1125.             val = val.add(digits[i].times(pow));
  1126.             pow = pow.times(base);
  1127.         }
  1128.         return isNegative ? val.negate() : val;
  1129.     }
  1130.  
  1131.     function stringify(digit) {
  1132.         if (digit <= 35) {
  1133.             return "0123456789abcdefghijklmnopqrstuvwxyz".charAt(digit);
  1134.         }
  1135.         return "<" + digit + ">";
  1136.     }
  1137.  
  1138.     function toBase(n, base) {
  1139.         base = bigInt(base);
  1140.         if (base.isZero()) {
  1141.             if (n.isZero()) return { value: [0], isNegative: false };
  1142.             throw new Error("Cannot convert nonzero numbers to base 0.");
  1143.         }
  1144.         if (base.equals(-1)) {
  1145.             if (n.isZero()) return { value: [0], isNegative: false };
  1146.             if (n.isNegative())
  1147.                 return {
  1148.                     value: [].concat.apply([], Array.apply(null, Array(-n))
  1149.                         .map(Array.prototype.valueOf, [1, 0])
  1150.                     ),
  1151.                     isNegative: false
  1152.                 };
  1153.  
  1154.             var arr = Array.apply(null, Array(+n - 1))
  1155.                 .map(Array.prototype.valueOf, [0, 1]);
  1156.             arr.unshift([1]);
  1157.             return {
  1158.                 value: [].concat.apply([], arr),
  1159.                 isNegative: false
  1160.             };
  1161.         }
  1162.  
  1163.         var neg = false;
  1164.         if (n.isNegative() && base.isPositive()) {
  1165.             neg = true;
  1166.             n = n.abs();
  1167.         }
  1168.         if (base.isUnit()) {
  1169.             if (n.isZero()) return { value: [0], isNegative: false };
  1170.  
  1171.             return {
  1172.                 value: Array.apply(null, Array(+n))
  1173.                     .map(Number.prototype.valueOf, 1),
  1174.                 isNegative: neg
  1175.             };
  1176.         }
  1177.         var out = [];
  1178.         var left = n, divmod;
  1179.         while (left.isNegative() || left.compareAbs(base) >= 0) {
  1180.             divmod = left.divmod(base);
  1181.             left = divmod.quotient;
  1182.             var digit = divmod.remainder;
  1183.             if (digit.isNegative()) {
  1184.                 digit = base.minus(digit).abs();
  1185.                 left = left.next();
  1186.             }
  1187.             out.push(digit.toJSNumber());
  1188.         }
  1189.         out.push(left.toJSNumber());
  1190.         return { value: out.reverse(), isNegative: neg };
  1191.     }
  1192.  
  1193.     function toBaseString(n, base) {
  1194.         var arr = toBase(n, base);
  1195.         return (arr.isNegative ? "-" : "") + arr.value.map(stringify).join('');
  1196.     }
  1197.  
  1198.     BigInteger.prototype.toArray = function (radix) {
  1199.         return toBase(this, radix);
  1200.     };
  1201.  
  1202.     SmallInteger.prototype.toArray = function (radix) {
  1203.         return toBase(this, radix);
  1204.     };
  1205.  
  1206.     BigInteger.prototype.toString = function (radix) {
  1207.         if (radix === undefined) radix = 10;
  1208.         if (radix !== 10) return toBaseString(this, radix);
  1209.         var v = this.value, l = v.length, str = String(v[--l]), zeros = "0000000", digit;
  1210.         while (--l >= 0) {
  1211.             digit = String(v[l]);
  1212.             str += zeros.slice(digit.length) + digit;
  1213.         }
  1214.         var sign = this.sign ? "-" : "";
  1215.         return sign + str;
  1216.     };
  1217.  
  1218.     SmallInteger.prototype.toString = function (radix) {
  1219.         if (radix === undefined) radix = 10;
  1220.         if (radix != 10) return toBaseString(this, radix);
  1221.         return String(this.value);
  1222.     };
  1223.     BigInteger.prototype.toJSON = SmallInteger.prototype.toJSON = function () { return this.toString(); }
  1224.  
  1225.     BigInteger.prototype.valueOf = function () {
  1226.         return parseInt(this.toString(), 10);
  1227.     };
  1228.     BigInteger.prototype.toJSNumber = BigInteger.prototype.valueOf;
  1229.  
  1230.     SmallInteger.prototype.valueOf = function () {
  1231.         return this.value;
  1232.     };
  1233.     SmallInteger.prototype.toJSNumber = SmallInteger.prototype.valueOf;
  1234.  
  1235.     function parseStringValue(v) {
  1236.         if (isPrecise(+v)) {
  1237.             var x = +v;
  1238.             if (x === truncate(x))
  1239.                 return new SmallInteger(x);
  1240.             throw new Error("Invalid integer: " + v);
  1241.         }
  1242.         var sign = v[0] === "-";
  1243.         if (sign) v = v.slice(1);
  1244.         var split = v.split(/e/i);
  1245.         if (split.length > 2) throw new Error("Invalid integer: " + split.join("e"));
  1246.         if (split.length === 2) {
  1247.             var exp = split[1];
  1248.             if (exp[0] === "+") exp = exp.slice(1);
  1249.             exp = +exp;
  1250.             if (exp !== truncate(exp) || !isPrecise(exp)) throw new Error("Invalid integer: " + exp + " is not a valid exponent.");
  1251.             var text = split[0];
  1252.             var decimalPlace = text.indexOf(".");
  1253.             if (decimalPlace >= 0) {
  1254.                 exp -= text.length - decimalPlace - 1;
  1255.                 text = text.slice(0, decimalPlace) + text.slice(decimalPlace + 1);
  1256.             }
  1257.             if (exp < 0) throw new Error("Cannot include negative exponent part for integers");
  1258.             text += (new Array(exp + 1)).join("0");
  1259.             v = text;
  1260.         }
  1261.         var isValid = /^([0-9][0-9]*)$/.test(v);
  1262.         if (!isValid) throw new Error("Invalid integer: " + v);
  1263.         var r = [], max = v.length, l = LOG_BASE, min = max - l;
  1264.         while (max > 0) {
  1265.             r.push(+v.slice(min, max));
  1266.             min -= l;
  1267.             if (min < 0) min = 0;
  1268.             max -= l;
  1269.         }
  1270.         trim(r);
  1271.         return new BigInteger(r, sign);
  1272.     }
  1273.  
  1274.     function parseNumberValue(v) {
  1275.         if (isPrecise(v)) {
  1276.             if (v !== truncate(v)) throw new Error(v + " is not an integer.");
  1277.             return new SmallInteger(v);
  1278.         }
  1279.         return parseStringValue(v.toString());
  1280.     }
  1281.  
  1282.     function parseValue(v) {
  1283.         if (typeof v === "number") {
  1284.             return parseNumberValue(v);
  1285.         }
  1286.         if (typeof v === "string") {
  1287.             return parseStringValue(v);
  1288.         }
  1289.         return v;
  1290.     }
  1291.     // Pre-define numbers in range [-999,999]
  1292.     for (var i = 0; i < 1000; i++) {
  1293.         Integer[i] = new SmallInteger(i);
  1294.         if (i > 0) Integer[-i] = new SmallInteger(-i);
  1295.     }
  1296.     // Backwards compatibility
  1297.     Integer.one = Integer[1];
  1298.     Integer.zero = Integer[0];
  1299.     Integer.minusOne = Integer[-1];
  1300.     Integer.max = max;
  1301.     Integer.min = min;
  1302.     Integer.gcd = gcd;
  1303.     Integer.lcm = lcm;
  1304.     Integer.isInstance = function (x) { return x instanceof BigInteger || x instanceof SmallInteger; };
  1305.     Integer.randBetween = randBetween;
  1306.  
  1307.     Integer.fromArray = function (digits, base, isNegative) {
  1308.         return parseBaseFromArray(digits.map(parseValue), parseValue(base || 10), isNegative);
  1309.     };
  1310.  
  1311.     return Integer;
  1312. }();
  1313.  
  1314.  
  1315. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1316. //tribunachi
  1317. let data=['2','3','4',15000];
  1318. let N = parseInt(data[3]);
  1319. let d;
  1320. let a = bigInt(data[0]);
  1321. let b= bigInt(data[1]);
  1322. let c= bigInt(data[2]);
  1323.  
  1324. // Substraction bignumbers
  1325. // let num1='22222222222222222222222222222222222222222222222222222222222';
  1326. // let num2='11111111111111111111111111111111111111111111111111111111111';
  1327. // let sub=bigInt(num1).subtract(num2)
  1328. // console.log(`BigInt substraction ${sub}`);
  1329.  
  1330. for (let indx = 3; indx < N; indx++) {
  1331.   d=bigInt(a).add(b).add(c);
  1332.   a=b;
  1333.   b=c;
  1334.   c=d;
  1335. }
  1336.  
  1337. console.log(d.toString());
Advertisement
Add Comment
Please, Sign In to add comment