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