├── BigInteger.js ├── LICENSE ├── README.md ├── SmallBigInt.js ├── benchmark ├── benchmark.js ├── generated-tests.js ├── iframe.html ├── iframe.js ├── index.html ├── index.js ├── libs.js ├── libs │ ├── data_application_javascript_dynamic___dispatch_____B___bn_js.js │ ├── http___ofmind_net_doc_hapint.js │ ├── http___www_cs_students_stanford_edu__tjw_jsbn_.js │ ├── http___www_leemon_com_crypto_BigInt_html.js │ ├── https___github_com_GoogleChromeLabs_jsbi.js │ ├── https___github_com_MikeMcl_big_js.js │ ├── https___github_com_MikeMcl_bignumber_js.js │ ├── https___github_com_MikeMcl_decimal_js.js │ ├── https___github_com_MikeMcl_decimal_js_light.js │ ├── https___github_com_Yaffle_BigInteger.js │ ├── https___github_com_chromium_octane_blob_master_crypto_js.js │ ├── https___github_com_dankogai_js_math_bigint.js │ ├── https___github_com_defunctzombie_int.js │ ├── https___github_com_dtrebbien_BigDecimal_js.js │ ├── https___github_com_indutny_bn_js.js │ ├── https___github_com_iriscouch_bigdecimal_js.js │ ├── https___github_com_jtobey_javascript_bignum.js │ ├── https___github_com_jtobey_javascript_bignum_blob_master_schemeNumber_js.js │ ├── https___github_com_node_modules_node_biginteger.js │ ├── https___github_com_peterolson_BigInteger_js.js │ ├── https___github_com_peteroupc_BigNumber.js │ ├── https___github_com_silentmatt_javascript_biginteger.js │ ├── https___github_com_tabatkins_bignum.js │ ├── https___github_com_vukicevic_crunch.js │ └── https___rawgit_com_Yaffle_BigInteger_master_SmallBigInt_js.js ├── randomTestsGenerator.html ├── test-generator.html └── tests.js └── package.json /BigInteger.js: -------------------------------------------------------------------------------- 1 | /*jslint plusplus: true, vars: true, indent: 2*/ 2 | 3 | (function (global) { 4 | "use strict"; 5 | 6 | // BigInteger.js 7 | // Available under Public Domain 8 | // https://github.com/Yaffle/BigInteger/ 9 | 10 | // For implementation details, see "The Handbook of Applied Cryptography" 11 | // http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf 12 | 13 | var parseInteger = function (s, from, to, radix) { 14 | var i = from - 1; 15 | var n = 0; 16 | var y = radix < 10 ? radix : 10; 17 | while (++i < to) { 18 | var code = s.charCodeAt(i); 19 | var v = code - "0".charCodeAt(0); 20 | if (v < 0 || y <= v) { 21 | v = 10 - "A".charCodeAt(0) + code; 22 | if (v < 10 || radix <= v) { 23 | v = 10 - "a".charCodeAt(0) + code; 24 | if (v < 10 || radix <= v) { 25 | throw new RangeError(); 26 | } 27 | } 28 | } 29 | n = n * radix + v; 30 | } 31 | return n; 32 | }; 33 | 34 | var createArray = function (length) { 35 | var x = new Array(length); 36 | var i = -1; 37 | while (++i < length) { 38 | x[i] = 0; 39 | } 40 | return x; 41 | }; 42 | 43 | var epsilon = 2 / (9007199254740991 + 1); 44 | while (1 + epsilon / 2 !== 1) { 45 | epsilon /= 2; 46 | } 47 | var BASE = 2 / epsilon; 48 | var s = 134217728; 49 | while (s * s < 2 / epsilon) { 50 | s *= 2; 51 | } 52 | var SPLIT = s + 1; 53 | var BASELOG2 = Math.ceil(Math.log(BASE) / Math.log(2)); 54 | 55 | // Veltkamp-Dekker's algorithm 56 | // see http://web.mit.edu/tabbott/Public/quaddouble-debian/qd-2.3.4-old/docs/qd.pdf 57 | var fma = function (a, b, product) { 58 | var at = SPLIT * a; 59 | var ahi = at - (at - a); 60 | var alo = a - ahi; 61 | var bt = SPLIT * b; 62 | var bhi = bt - (bt - b); 63 | var blo = b - bhi; 64 | var error = ((ahi * bhi + product) + ahi * blo + alo * bhi) + alo * blo; 65 | return error; 66 | }; 67 | 68 | var fastTrunc = function (x) { 69 | var v = (x - BASE) + BASE; 70 | return v > x ? v - 1 : v; 71 | }; 72 | 73 | var performMultiplication = function (carry, a, b) { 74 | var product = a * b; 75 | var error = fma(a, b, -product); 76 | 77 | var hi = (product / BASE) - BASE + BASE; 78 | var lo = product - hi * BASE + error; 79 | 80 | if (lo >= 0) { 81 | lo -= BASE; 82 | hi += 1; 83 | } 84 | 85 | lo += carry; 86 | if (lo < 0) { 87 | lo += BASE; 88 | hi -= 1; 89 | } 90 | 91 | return {lo: lo, hi: hi}; 92 | }; 93 | 94 | var performDivision = function (a, b, divisor) { 95 | if (a >= divisor) { 96 | throw new RangeError(); 97 | } 98 | var p = a * BASE; 99 | var q = fastTrunc(p / divisor); 100 | 101 | var r = 0 - fma(q, divisor, -p); 102 | if (r < 0) { 103 | q -= 1; 104 | r += divisor; 105 | } 106 | 107 | r += b - divisor; 108 | if (r < 0) { 109 | r += divisor; 110 | } else { 111 | q += 1; 112 | } 113 | var y = fastTrunc(r / divisor); 114 | r -= y * divisor; 115 | q += y; 116 | return {q: q, r: r}; 117 | }; 118 | 119 | function BigInteger(sign, magnitude, length) { 120 | this.sign = sign; 121 | this.magnitude = magnitude; 122 | this.length = length; 123 | } 124 | 125 | var createBigInteger = function (sign, magnitude, length) { 126 | return new BigInteger(sign, magnitude, length); 127 | }; 128 | 129 | var fromHugeNumber = function (n) { 130 | var sign = n < 0 ? 1 : 0; 131 | var a = n < 0 ? 0 - n : 0 + n; 132 | if (a === 1 / 0) { 133 | throw new RangeError(); 134 | } 135 | console.assert(BASE === Math.pow(2, 53)); 136 | var i = 0; 137 | while (a >= Math.pow(BASE, 2)) { 138 | a /= BASE; 139 | i += 1; 140 | } 141 | var hi = Math.floor(a / BASE); 142 | var lo = a - hi * BASE; 143 | var digits = createArray(i + 2); 144 | digits[i + 1] = hi; 145 | digits[i + 0] = lo; 146 | return createBigInteger(sign, digits, i + 2); 147 | }; 148 | 149 | var fromNumber = function (n) { 150 | if (Math.floor(n) !== n) { 151 | throw new RangeError("Cannot convert " + n + " to BigInteger"); 152 | } 153 | if (n < BASE && 0 - n < BASE) { 154 | var a = createArray(1); 155 | a[0] = n < 0 ? 0 - n : 0 + n; 156 | return createBigInteger(n < 0 ? 1 : 0, a, n === 0 ? 0 : 1); 157 | } 158 | return fromHugeNumber(n); 159 | }; 160 | 161 | var fromString = function (s) { 162 | var length = s.length; 163 | if (length === 0) { 164 | throw new RangeError(); 165 | } 166 | var sign = 0; 167 | var signCharCode = s.charCodeAt(0); 168 | var from = 0; 169 | if (signCharCode === "+".charCodeAt(0)) { 170 | from = 1; 171 | } 172 | if (signCharCode === "-".charCodeAt(0)) { 173 | from = 1; 174 | sign = 1; 175 | } 176 | var radix = 10; 177 | if (from === 0 && length >= 2 && s.charCodeAt(0) === "0".charCodeAt(0)) { 178 | if (s.charCodeAt(1) === "b".charCodeAt(0)) { 179 | radix = 2; 180 | from = 2; 181 | } else if (s.charCodeAt(1) === "o".charCodeAt(0)) { 182 | radix = 8; 183 | from = 2; 184 | } else if (s.charCodeAt(1) === "x".charCodeAt(0)) { 185 | radix = 16; 186 | from = 2; 187 | } 188 | } 189 | length -= from; 190 | if (length === 0) { 191 | throw new RangeError(); 192 | } 193 | 194 | var groupLength = 0; 195 | var groupRadix = 1; 196 | var limit = fastTrunc(BASE / radix); 197 | while (groupRadix <= limit) { 198 | groupLength += 1; 199 | groupRadix *= radix; 200 | } 201 | 202 | var size = Math.floor((length - 1) / groupLength) + 1; 203 | var magnitude = createArray(size); 204 | var start = from + 1 + (length - 1 - (size - 1) * groupLength) - groupLength; 205 | 206 | var j = -1; 207 | while (++j < size) { 208 | var groupStart = start + j * groupLength; 209 | var c = parseInteger(s, (groupStart >= from ? groupStart : from), groupStart + groupLength, radix); 210 | var l = -1; 211 | while (++l < j) { 212 | var tmp = performMultiplication(c, magnitude[l], groupRadix); 213 | var lo = tmp.lo; 214 | var hi = tmp.hi; 215 | magnitude[l] = lo; 216 | c = hi; 217 | } 218 | magnitude[j] = c; 219 | } 220 | 221 | while (size > 0 && magnitude[size - 1] === 0) { 222 | size -= 1; 223 | } 224 | 225 | return createBigInteger(size === 0 ? 0 : sign, magnitude, size); 226 | }; 227 | 228 | // Math.pow(2, n) is slow in Chrome 93 229 | function exp(x, n) { 230 | var a = 1; 231 | while (n !== 0) { 232 | var q = (n >> 1); 233 | if (n !== (q << 1)) { 234 | a *= x; 235 | } 236 | n = q; 237 | x *= x; 238 | } 239 | return a; 240 | } 241 | 242 | BigInteger.BigInt = function (x) { 243 | if (typeof x === "number") { 244 | return fromNumber(x); 245 | } 246 | if (typeof x === "string") { 247 | return fromString(x); 248 | } 249 | if (typeof x === "bigint") { 250 | return fromString(x.toString()); 251 | } 252 | if (x instanceof BigInteger) { 253 | return x; 254 | } 255 | if (typeof x === "boolean") { 256 | return fromNumber(Number(x)); 257 | } 258 | throw new RangeError(); 259 | }; 260 | 261 | BigInteger.asUintN = function (bits, bigint) { 262 | if (bits < 0) { 263 | throw new RangeError("bits argument should be non-negative"); 264 | } 265 | if (bigint.sign === 1) { 266 | var X = BigInteger.asUintN(bits, BigInteger.unaryMinus(bigint)); 267 | return BigInteger.equal(X, BigInteger.BigInt(0)) ? X : BigInteger.subtract(BigInteger.leftShift(BigInteger.BigInt(1), BigInteger.BigInt(bits)), X); 268 | } 269 | var n = Math.ceil(bits / BASELOG2); 270 | bits -= BASELOG2 * n; 271 | if (n > bigint.length) { 272 | return bigint; 273 | } 274 | var array = createArray(n); 275 | for (var i = 0; i < n; i += 1) { 276 | array[i] = bigint.magnitude[i]; 277 | } 278 | var m = exp(2, BASELOG2 + bits); 279 | array[n - 1] = array[n - 1] - Math.floor(array[n - 1] / m) * m; 280 | while (n >= 0 && array[n - 1] === 0) { 281 | n -= 1; 282 | } 283 | return createBigInteger(0, array, n); 284 | }; 285 | 286 | BigInteger.asIntN = function (bits, bigint) { 287 | if (bits === 0) { 288 | return BigInteger.BigInt(0); 289 | } 290 | var A = BigInteger.asUintN(bits, bigint); 291 | var X = BigInteger.leftShift(BigInteger.BigInt(1), BigInteger.BigInt(bits - 1)); 292 | return BigInteger.greaterThanOrEqual(A, X) ? BigInteger.subtract(A, BigInteger.add(X, X)) : A; 293 | }; 294 | 295 | BigInteger.toNumber = function (a) { 296 | if (a.length === 0) { 297 | return 0; 298 | } 299 | if (a.length === 1) { 300 | return a.sign === 1 ? 0 - a.magnitude[0] : a.magnitude[0]; 301 | } 302 | if (BASE + 1 !== BASE) { 303 | throw new RangeError(); 304 | } 305 | var x = a.magnitude[a.length - 1]; 306 | var y = a.magnitude[a.length - 2]; 307 | var i = a.length - 3; 308 | while (i >= 0 && a.magnitude[i] === 0) { 309 | i -= 1; 310 | } 311 | if (i >= 0 && (x !== 1 && y % 2 === 0 || x === 1 && y % 2 === 1)) { 312 | y += 1; 313 | } 314 | var z = (x * BASE + y) * exp(BASE, a.length - 2); 315 | return a.sign === 1 ? 0 - z : z; 316 | }; 317 | 318 | var compareMagnitude = function (a, b) { 319 | if (a === b) { 320 | return 0; 321 | } 322 | var c1 = a.length - b.length; 323 | if (c1 !== 0) { 324 | return c1 < 0 ? -1 : +1; 325 | } 326 | var i = a.length; 327 | while (--i >= 0) { 328 | var c = a.magnitude[i] - b.magnitude[i]; 329 | if (c !== 0) { 330 | return c < 0 ? -1 : +1; 331 | } 332 | } 333 | return 0; 334 | }; 335 | 336 | var compareTo = function (a, b) { 337 | var c = a.sign === b.sign ? compareMagnitude(a, b) : 1; 338 | return a.sign === 1 ? 0 - c : c; // positive zero will be returned for c === 0 339 | }; 340 | 341 | var addAndSubtract = function (a, b, isSubtraction) { 342 | var z = compareMagnitude(a, b); 343 | var resultSign = z < 0 ? (isSubtraction !== 0 ? 1 - b.sign : b.sign) : a.sign; 344 | var min = z < 0 ? a : b; 345 | var max = z < 0 ? b : a; 346 | // |a| <= |b| 347 | if (min.length === 0) { 348 | return createBigInteger(resultSign, max.magnitude, max.length); 349 | } 350 | var subtract = 0; 351 | var resultLength = max.length; 352 | if (a.sign !== (isSubtraction !== 0 ? 1 - b.sign : b.sign)) { 353 | subtract = 1; 354 | if (min.length === resultLength) { 355 | while (resultLength > 0 && min.magnitude[resultLength - 1] === max.magnitude[resultLength - 1]) { 356 | resultLength -= 1; 357 | } 358 | } 359 | if (resultLength === 0) { // a === (-b) 360 | return createBigInteger(0, createArray(0), 0); 361 | } 362 | } 363 | // result !== 0 364 | var result = createArray(resultLength + (1 - subtract)); 365 | var i = -1; 366 | var c = 0; 367 | while (++i < min.length) { 368 | var aDigit = min.magnitude[i]; 369 | c += max.magnitude[i] + (subtract !== 0 ? 0 - aDigit : aDigit - BASE); 370 | if (c < 0) { 371 | result[i] = BASE + c; 372 | c = 0 - subtract; 373 | } else { 374 | result[i] = c; 375 | c = 1 - subtract; 376 | } 377 | } 378 | i -= 1; 379 | while (++i < resultLength) { 380 | c += max.magnitude[i] + (subtract !== 0 ? 0 : 0 - BASE); 381 | if (c < 0) { 382 | result[i] = BASE + c; 383 | c = 0 - subtract; 384 | } else { 385 | result[i] = c; 386 | c = 1 - subtract; 387 | } 388 | } 389 | if (subtract === 0) { 390 | result[resultLength] = c; 391 | resultLength += c !== 0 ? 1 : 0; 392 | } else { 393 | while (resultLength > 0 && result[resultLength - 1] === 0) { 394 | resultLength -= 1; 395 | } 396 | } 397 | return createBigInteger(resultSign, result, resultLength); 398 | }; 399 | 400 | BigInteger.add = function (a, b) { 401 | return addAndSubtract(a, b, 0); 402 | }; 403 | 404 | BigInteger.subtract = function (a, b) { 405 | return addAndSubtract(a, b, 1); 406 | }; 407 | 408 | BigInteger.multiply = function (a, b) { 409 | if (a.length < b.length) { 410 | var tmp = a; 411 | a = b; 412 | b = tmp; 413 | } 414 | var alength = a.length; 415 | var blength = b.length; 416 | var am = a.magnitude; 417 | var bm = b.magnitude; 418 | var asign = a.sign; 419 | var bsign = b.sign; 420 | if (alength === 0 || blength === 0) { 421 | return createBigInteger(0, createArray(0), 0); 422 | } 423 | if (alength === 1 && am[0] === 1) { 424 | return createBigInteger(asign === 1 ? 1 - bsign : bsign, bm, blength); 425 | } 426 | if (blength === 1 && bm[0] === 1) { 427 | return createBigInteger(asign === 1 ? 1 - bsign : bsign, am, alength); 428 | } 429 | var astart = 0; 430 | while (am[astart] === 0) { // to optimize multiplications of a power of BASE 431 | astart += 1; 432 | } 433 | var resultSign = asign === 1 ? 1 - bsign : bsign; 434 | var resultLength = alength + blength; 435 | var result = createArray(resultLength); 436 | var i = -1; 437 | while (++i < blength) { 438 | var digit = bm[i]; 439 | if (digit !== 0) { // to optimize multiplications by a power of BASE 440 | var c = 0; 441 | var j = astart - 1; 442 | while (++j < alength) { 443 | var carry = 1; 444 | c += result[j + i] - BASE; 445 | if (c < 0) { 446 | c += BASE; 447 | carry = 0; 448 | } 449 | var tmp = performMultiplication(c, am[j], digit); 450 | var lo = tmp.lo; 451 | var hi = tmp.hi; 452 | result[j + i] = lo; 453 | c = hi + carry; 454 | } 455 | result[alength + i] = c; 456 | } 457 | } 458 | if (result[resultLength - 1] === 0) { 459 | resultLength -= 1; 460 | } 461 | return createBigInteger(resultSign, result, resultLength); 462 | }; 463 | 464 | var divideAndRemainder = function (a, b, isDivision) { 465 | if (b.length === 0) { 466 | throw new RangeError(); 467 | } 468 | if (a.length === 0) { 469 | return createBigInteger(0, createArray(0), 0); 470 | } 471 | var quotientSign = a.sign === 1 ? 1 - b.sign : b.sign; 472 | if (b.length === 1 && b.magnitude[0] === 1) { 473 | if (isDivision !== 0) { 474 | return createBigInteger(quotientSign, a.magnitude, a.length); 475 | } 476 | return createBigInteger(0, createArray(0), 0); 477 | } 478 | 479 | var divisorOffset = a.length + 1; // `+ 1` for extra digit in case of normalization 480 | var divisorAndRemainder = createArray(divisorOffset + b.length + 1); // `+ 1` to avoid `index < length` checks 481 | var divisor = divisorAndRemainder; 482 | var remainder = divisorAndRemainder; 483 | var n = -1; 484 | while (++n < a.length) { 485 | remainder[n] = a.magnitude[n]; 486 | } 487 | var m = -1; 488 | while (++m < b.length) { 489 | divisor[divisorOffset + m] = b.magnitude[m]; 490 | } 491 | 492 | var top = divisor[divisorOffset + b.length - 1]; 493 | 494 | // normalization 495 | var lambda = 1; 496 | if (b.length > 1) { 497 | lambda = fastTrunc(BASE / (top + 1)); 498 | if (lambda > 1) { 499 | var carry = 0; 500 | var l = -1; 501 | while (++l < divisorOffset + b.length) { 502 | var tmp = performMultiplication(carry, divisorAndRemainder[l], lambda); 503 | var lo = tmp.lo; 504 | var hi = tmp.hi; 505 | divisorAndRemainder[l] = lo; 506 | carry = hi; 507 | } 508 | divisorAndRemainder[divisorOffset + b.length] = carry; 509 | top = divisor[divisorOffset + b.length - 1]; 510 | } 511 | // assertion 512 | if (top < fastTrunc(BASE / 2)) { 513 | throw new RangeError(); 514 | } 515 | } 516 | 517 | var shift = a.length - b.length + 1; 518 | if (shift < 0) { 519 | shift = 0; 520 | } 521 | var quotient = undefined; 522 | var quotientLength = 0; 523 | 524 | // to optimize divisions by a power of BASE 525 | var lastNonZero = 0; 526 | while (divisor[divisorOffset + lastNonZero] === 0) { 527 | lastNonZero += 1; 528 | } 529 | 530 | var i = shift; 531 | while (--i >= 0) { 532 | var t = b.length + i; 533 | var q = BASE - 1; 534 | if (remainder[t] !== top) { 535 | var tmp2 = performDivision(remainder[t], remainder[t - 1], top); 536 | var q2 = tmp2.q; 537 | //var r2 = tmp2.r; 538 | q = q2; 539 | } 540 | 541 | var ax = 0; 542 | var bx = 0; 543 | var j = i - 1 + lastNonZero; 544 | while (++j <= t) { 545 | var tmp3 = performMultiplication(bx, q, divisor[divisorOffset + j - i]); 546 | var lo3 = tmp3.lo; 547 | var hi3 = tmp3.hi; 548 | bx = hi3; 549 | ax += remainder[j] - lo3; 550 | if (ax < 0) { 551 | remainder[j] = BASE + ax; 552 | ax = -1; 553 | } else { 554 | remainder[j] = ax; 555 | ax = 0; 556 | } 557 | } 558 | while (ax !== 0) { 559 | q -= 1; 560 | var c = 0; 561 | var k = i - 1 + lastNonZero; 562 | while (++k <= t) { 563 | c += remainder[k] - BASE + divisor[divisorOffset + k - i]; 564 | if (c < 0) { 565 | remainder[k] = BASE + c; 566 | c = 0; 567 | } else { 568 | remainder[k] = c; 569 | c = +1; 570 | } 571 | } 572 | ax += c; 573 | } 574 | if (isDivision !== 0 && q !== 0) { 575 | if (quotientLength === 0) { 576 | quotientLength = i + 1; 577 | quotient = createArray(quotientLength); 578 | } 579 | quotient[i] = q; 580 | } 581 | } 582 | 583 | if (isDivision !== 0) { 584 | if (quotientLength === 0) { 585 | return createBigInteger(0, createArray(0), 0); 586 | } 587 | return createBigInteger(quotientSign, quotient, quotientLength); 588 | } 589 | 590 | var remainderLength = a.length + 1; 591 | if (lambda > 1) { 592 | var r = 0; 593 | var p = remainderLength; 594 | while (--p >= 0) { 595 | var tmp4 = performDivision(r, remainder[p], lambda); 596 | var q4 = tmp4.q; 597 | var r4 = tmp4.r; 598 | remainder[p] = q4; 599 | r = r4; 600 | } 601 | if (r !== 0) { 602 | // assertion 603 | throw new RangeError(); 604 | } 605 | } 606 | while (remainderLength > 0 && remainder[remainderLength - 1] === 0) { 607 | remainderLength -= 1; 608 | } 609 | if (remainderLength === 0) { 610 | return createBigInteger(0, createArray(0), 0); 611 | } 612 | var result = createArray(remainderLength); 613 | var o = -1; 614 | while (++o < remainderLength) { 615 | result[o] = remainder[o]; 616 | } 617 | return createBigInteger(a.sign, result, remainderLength); 618 | }; 619 | 620 | BigInteger.divide = function (a, b) { 621 | return divideAndRemainder(a, b, 1); 622 | }; 623 | 624 | BigInteger.remainder = function (a, b) { 625 | return divideAndRemainder(a, b, 0); 626 | }; 627 | 628 | BigInteger.unaryMinus = function (a) { 629 | return createBigInteger(a.length === 0 ? a.sign : 1 - a.sign, a.magnitude, a.length); 630 | }; 631 | 632 | BigInteger.equal = function (a, b) { 633 | return compareTo(a, b) === 0; 634 | }; 635 | BigInteger.lessThan = function (a, b) { 636 | return compareTo(a, b) < 0; 637 | }; 638 | BigInteger.greaterThan = function (a, b) { 639 | return compareTo(a, b) > 0; 640 | }; 641 | BigInteger.notEqual = function (a, b) { 642 | return compareTo(a, b) !== 0; 643 | }; 644 | BigInteger.lessThanOrEqual = function (a, b) { 645 | return compareTo(a, b) <= 0; 646 | }; 647 | BigInteger.greaterThanOrEqual = function (a, b) { 648 | return compareTo(a, b) >= 0; 649 | }; 650 | 651 | BigInteger.exponentiate = function (a, b) { 652 | var n = BigInteger.toNumber(b); 653 | if (n < 0) { 654 | throw new RangeError(); 655 | } 656 | if (n > 9007199254740991) { 657 | var y = BigInteger.toNumber(a); 658 | if (y === 0 || y === -1 || y === +1) { 659 | return y === -1 && BigInteger.toNumber(BigInteger.remainder(b, BigInteger.BigInt(2))) === 0 ? BigInteger.unaryMinus(a) : a; 660 | } 661 | throw new RangeError(); 662 | } 663 | if (n === 0) { 664 | return BigInteger.BigInt(1); 665 | } 666 | if (a.length === 1 && (a.magnitude[0] === 2 || a.magnitude[0] === 16)) { 667 | var bits = Math.floor(Math.log(BASE) / Math.log(2) + 0.5); 668 | var abits = Math.floor(Math.log(a.magnitude[0]) / Math.log(2) + 0.5); 669 | var nn = abits * n; 670 | var q = Math.floor(nn / bits); 671 | var r = nn - q * bits; 672 | var array = createArray(q + 1); 673 | array[q] = Math.pow(2, r); 674 | return createBigInteger(a.sign === 0 || n % 2 === 0 ? 0 : 1, array, q + 1); 675 | } 676 | var x = a; 677 | while (n % 2 === 0) { 678 | n = Math.floor(n / 2); 679 | x = BigInteger.multiply(x, x); 680 | } 681 | var accumulator = x; 682 | n -= 1; 683 | if (n >= 2) { 684 | while (n >= 2) { 685 | var t = Math.floor(n / 2); 686 | if (t * 2 !== n) { 687 | accumulator = BigInteger.multiply(accumulator, x); 688 | } 689 | n = t; 690 | x = BigInteger.multiply(x, x); 691 | } 692 | accumulator = BigInteger.multiply(accumulator, x); 693 | } 694 | return accumulator; 695 | }; 696 | 697 | BigInteger.prototype.toString = function (radix) { 698 | if (radix == undefined) { 699 | radix = 10; 700 | } 701 | if (radix !== 10 && (radix < 2 || radix > 36 || radix !== Math.floor(radix))) { 702 | throw new RangeError("radix argument must be an integer between 2 and 36"); 703 | } 704 | 705 | // console.time(); var n = BigInteger.exponentiate(2**4, 2**16); console.timeEnd(); console.time(); n.toString(16).length; console.timeEnd(); 706 | if (this.length > 8 && true) { // https://github.com/GoogleChromeLabs/jsbi/blob/c9b179a4d5d34d35dd24cf84f7c1def54dc4a590/jsbi.mjs#L880 707 | if (this.sign === 1) { 708 | return '-' + BigInteger.unaryMinus(this).toString(radix); 709 | } 710 | var s = Math.floor(this.length * Math.log(BASE) / Math.log(radix) / 2 + 0.5 - 1); 711 | var split = BigInteger.exponentiate(BigInteger.BigInt(radix), BigInteger.BigInt(s)); 712 | var q = BigInteger.divide(this, split); 713 | var r = BigInteger.subtract(this, BigInteger.multiply(q, split)); 714 | var a = r.toString(radix); 715 | return q.toString(radix) + '0'.repeat(s - a.length) + a; 716 | } 717 | 718 | var a = this; 719 | var result = a.sign === 1 ? "-" : ""; 720 | 721 | var remainderLength = a.length; 722 | if (remainderLength === 0) { 723 | return "0"; 724 | } 725 | if (remainderLength === 1) { 726 | result += a.magnitude[0].toString(radix); 727 | return result; 728 | } 729 | var groupLength = 0; 730 | var groupRadix = 1; 731 | var limit = fastTrunc(BASE / radix); 732 | while (groupRadix <= limit) { 733 | groupLength += 1; 734 | groupRadix *= radix; 735 | } 736 | // assertion 737 | if (groupRadix * radix <= BASE) { 738 | throw new RangeError(); 739 | } 740 | var size = remainderLength + Math.floor((remainderLength - 1) / groupLength) + 1; 741 | var remainder = createArray(size); 742 | var n = -1; 743 | while (++n < remainderLength) { 744 | remainder[n] = a.magnitude[n]; 745 | } 746 | 747 | var k = size; 748 | while (remainderLength !== 0) { 749 | var groupDigit = 0; 750 | var i = remainderLength; 751 | while (--i >= 0) { 752 | var tmp = performDivision(groupDigit, remainder[i], groupRadix); 753 | var q = tmp.q; 754 | var r = tmp.r; 755 | remainder[i] = q; 756 | groupDigit = r; 757 | } 758 | while (remainderLength > 0 && remainder[remainderLength - 1] === 0) { 759 | remainderLength -= 1; 760 | } 761 | k -= 1; 762 | remainder[k] = groupDigit; 763 | } 764 | result += remainder[k].toString(radix); 765 | while (++k < size) { 766 | var t = remainder[k].toString(radix); 767 | result += "0".repeat(groupLength - t.length) + t; 768 | } 769 | return result; 770 | }; 771 | var signedRightShift = function (x, n) { 772 | // (!) it should work fast if n ~ size(x) - 53 773 | if (x.length === 0) { 774 | return x; 775 | } 776 | var shift = Math.floor(n / BASELOG2); 777 | var length = x.length - shift; 778 | if (length <= 0) { 779 | if (x.sign === 1) { 780 | var minusOne = createArray(1); 781 | minusOne[0] = 1; 782 | return createBigInteger(1, minusOne, 1); 783 | } 784 | return createBigInteger(0, createArray(0), 0); 785 | } 786 | var digits = createArray(length + (x.sign === 1 ? 1 : 0)); 787 | for (var i = 0; i < length; i += 1) { 788 | digits[i] = i + shift < 0 ? 0 : x.magnitude[i + shift]; 789 | } 790 | n -= shift * BASELOG2; 791 | var s = exp(2, n); 792 | var s1 = Math.floor(BASE / s); 793 | var pr = 0; 794 | for (var i = length - 1; i >= 0; i -= 1) { 795 | var q = Math.floor(digits[i] / s); 796 | var r = digits[i] - q * s; 797 | digits[i] = q + pr * s1; 798 | pr = r; 799 | } 800 | if (length >= 1 && digits[length - 1] === 0) { 801 | length -= 1; 802 | } 803 | if (x.sign === 1) { 804 | var hasRemainder = pr > 0; 805 | for (var i = 0; i < shift && !hasRemainder; i += 1) { 806 | hasRemainder = x.magnitude[i] !== 0; 807 | } 808 | if (hasRemainder) { 809 | if (length === 0) { 810 | length += 1; 811 | digits[0] = 1; 812 | } else { 813 | // subtract one 814 | var i = 0; 815 | while (i < length && digits[i] === BASE - 1) { 816 | digits[i] = 0; 817 | i += 1; 818 | } 819 | if (i < length) { 820 | digits[i] += 1; 821 | } else { 822 | length += 1; 823 | digits[i] = 1; 824 | } 825 | } 826 | } 827 | } 828 | return createBigInteger(x.sign, digits, length); 829 | }; 830 | BigInteger.signedRightShift = function (x, n) { 831 | return signedRightShift(x, BigInteger.toNumber(n)); 832 | }; 833 | BigInteger.leftShift = function (x, n) { 834 | return signedRightShift(x, 0 - BigInteger.toNumber(n)); 835 | }; 836 | BigInteger.prototype.valueOf = function () { 837 | //throw new TypeError(); 838 | console.error('BigInteger#valueOf is called'); 839 | return this; 840 | }; 841 | 842 | (global || globalThis).BigInteger = BigInteger; 843 | 844 | }(this)); 845 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | BigInteger 2 | ========== 3 | 4 | Yet another BigInteger class in JavaScript 5 | This library performs arithmetic operations on integers of arbitrary size. 6 | 7 | To use it from a web browser: 8 | ``` 9 | 10 | ``` 11 | To use it from the node.js: 12 | ``` 13 | npm install Yaffle/BigInteger 14 | ``` 15 | Then: 16 | ``` 17 | var BigInteger = require("js-big-integer").BigInteger; 18 | ``` 19 | 20 | The API is terrible, but small integers are stored as primitive numbers, so operations on small integers are faster. 21 | The API was updated to match the API provided by https://github.com/GoogleChromeLabs/jsbi 22 | 23 | Operation | `BigInteger` | `Number` | `BigInt` (https://github.com/tc39/proposal-bigint) 24 | -----------------------|--------------------------------------|----------------------------------|--------------------------------------------------- 25 | Conversion from String | `BigInteger.BigInt(string)` | `Number(string)` | `BigInt(string)` 26 | Conversion from Number | `BigInteger.BigInt(number)` | N/A | `BigInt(number)` 27 | Conversion to String | `a.toString(radix)` | `a.toString(radix)` | `a.toString(radix)` 28 | Conversion to Number | `a.toNumber()` | N/A | `Number(bigint)` 29 | Addition | `BigInteger.add(a, b)` | `a + b` | `a + b` 30 | Subtraction | `BigInteger.subtract(a, b)` | `a - b` | `a - b` 31 | Multiplication | `BigInteger.multiply(a, b)` | `0 + a * b` | `a * b` 32 | Division | `BigInteger.divide(a, b)` | `0 + Math.trunc(a / b)` | `a / b` 33 | Remainder | `BigInteger.remainder(a, b)` | `0 + a % b` | `a % b` 34 | Exponentiation | `BigInteger.exponentiate(a, b)` | `0 + a**b` | `a**b` 35 | Negation | `BigInteger.unaryMinus(a)` | `0 - a` | `-a` 36 | Comparison | `BigInteger.equal(a, b)` | `a === b` | `a === b` 37 | ... | `BigInteger.lessThan(a, b)` | `a < b` | `a < b` 38 | ... | `BigInteger.greaterThan(a, b)` | `a > b` | `a > b` 39 | ... | `BigInteger.notEqual(a, b)` | `a !== b` | `a !== b` 40 | ... | `BigInteger.lessThanOrEqual(a, b)` | `a <= b` | `a <= b` 41 | ... | `BigInteger.greaterThanOrEqual(a, b)`| `a >= b` | `a >= b` 42 | Signed Right Shift | `BigInteger.signedRightShift(a, b)` | `a >> b` | `a >> b` 43 | Left Shift | `BigInteger.leftShift(a, b)` | `a << b` | `a << b` 44 | 45 | Example 46 | ======= 47 | ```javascript 48 | 49 | var factorial = function (n) { 50 | var result = BigInteger.BigInt(1); 51 | var i = 0; 52 | while (++i <= n) { 53 | result = BigInteger.multiply(result, BigInteger.BigInt(i)); 54 | } 55 | return result; 56 | }; 57 | 58 | console.log(factorial(30).toString(10)); 59 | 60 | ``` 61 | 62 | Other pure JavaScript implementations: 63 | 1. 64 | 2. 65 | 3. 66 | 4. 67 | 5. 68 | 6. 69 | 7. 70 | 8. 71 | 9. 72 | 10. 73 | 11. 74 | 12. 75 | 13. 76 | 14. 77 | 15. 78 | 16. 79 | 17. 80 | 18. 81 | 82 | Benchmark: 83 | 84 | -------------------------------------------------------------------------------- /SmallBigInt.js: -------------------------------------------------------------------------------- 1 | 2 | (function () { 3 | "use strict"; 4 | 5 | function BigIntWrapper() { 6 | } 7 | BigIntWrapper.BigInt = function (x) { 8 | return BigInt(x); 9 | }; 10 | BigIntWrapper.asIntN = function (bits, bigint) { 11 | return BigInt.asIntN(bits, bigint); 12 | }; 13 | BigIntWrapper.asUintN = function (bits, bigint) { 14 | return BigInt.asUintN(bits, bigint); 15 | }; 16 | BigIntWrapper.toNumber = function (bigint) { 17 | return Number(bigint); 18 | }; 19 | BigIntWrapper.add = function (a, b) { 20 | return a + b; 21 | }; 22 | BigIntWrapper.subtract = function (a, b) { 23 | return a - b; 24 | }; 25 | BigIntWrapper.multiply = function (a, b) { 26 | return a * b; 27 | }; 28 | BigIntWrapper.divide = function (a, b) { 29 | return a / b; 30 | }; 31 | BigIntWrapper.remainder = function (a, b) { 32 | return a % b; 33 | }; 34 | BigIntWrapper.unaryMinus = function (a) { 35 | return -a; 36 | }; 37 | BigIntWrapper.equal = function (a, b) { 38 | return a === b; 39 | }; 40 | BigIntWrapper.lessThan = function (a, b) { 41 | return a < b; 42 | }; 43 | BigIntWrapper.greaterThan = function (a, b) { 44 | return a > b; 45 | }; 46 | BigIntWrapper.notEqual = function (a, b) { 47 | return a !== b; 48 | }; 49 | BigIntWrapper.lessThanOrEqual = function (a, b) { 50 | return a <= b; 51 | }; 52 | BigIntWrapper.greaterThanOrEqual = function (a, b) { 53 | return a >= b; 54 | }; 55 | BigIntWrapper.exponentiate = function (a, b) { // a**b 56 | if (typeof a !== "bigint" || typeof b !== "bigint") { 57 | throw new TypeError(); 58 | } 59 | var n = Number(b); 60 | if (n < 0) { 61 | throw new RangeError(); 62 | } 63 | if (n > Number.MAX_SAFE_INTEGER) { 64 | var y = Number(a); 65 | if (y === 0 || y === -1 || y === +1) { 66 | return y === -1 && Number(b % BigInt(2)) === 0 ? -a : a; 67 | } 68 | throw new RangeError(); 69 | } 70 | if (a === BigInt(2)) { 71 | return BigInt(1) << b; 72 | } 73 | if (n === 0) { 74 | return BigInt(1); 75 | } 76 | var x = a; 77 | while (n % 2 === 0) { 78 | n = Math.floor(n / 2); 79 | x *= x; 80 | } 81 | var accumulator = x; 82 | n -= 1; 83 | if (n >= 2) { 84 | while (n >= 2) { 85 | var t = Math.floor(n / 2); 86 | if (t * 2 !== n) { 87 | accumulator *= x; 88 | } 89 | n = t; 90 | x *= x; 91 | } 92 | accumulator *= x; 93 | } 94 | return accumulator; 95 | }; 96 | BigIntWrapper.signedRightShift = function (a, n) { 97 | return a >> n; 98 | }; 99 | BigIntWrapper.leftShift = function (a, n) { 100 | return a << n; 101 | }; 102 | if (Symbol.hasInstance != undefined) { 103 | Object.defineProperty(BigIntWrapper, Symbol.hasInstance, { 104 | value: function (a) { 105 | return typeof a === 'bigint'; 106 | } 107 | }); 108 | } 109 | 110 | var supportsBigInt = Symbol.hasInstance != undefined && 111 | typeof BigInt !== "undefined" && 112 | BigInt(Number.MAX_SAFE_INTEGER) + BigInt(2) - BigInt(2) === BigInt(Number.MAX_SAFE_INTEGER); 113 | 114 | if (supportsBigInt) { 115 | // https://twitter.com/mild_sunrise/status/1339174371550760961 116 | // Chrome < 87 117 | if (((-BigInt('0xffffffffffffffffffffffffffffffff')) >> BigInt(0x40)).toString() !== '-18446744073709551616') { // ((-(2**128 - 1)) >> 64) !== -1 * 2**64 118 | BigIntWrapper.signedRightShift = function (a, n) { 119 | var b = BigInt(1) << n; 120 | return a >= BigInt(0) ? a / b : (a - b + BigInt(1)) / b; 121 | }; 122 | } 123 | } 124 | if (supportsBigInt) { 125 | try { 126 | BigInt(Number.MAX_SAFE_INTEGER + 1); 127 | } catch (error) { 128 | // Chrome 67 129 | BigIntWrapper.BigInt = function (x) { 130 | if (typeof x === "number") { 131 | var e = 0; 132 | var f = x; 133 | while (f >= Number.MAX_SAFE_INTEGER + 1) { 134 | f /= (Number.MAX_SAFE_INTEGER + 1); 135 | e += Math.round(Math.log2(Number.MAX_SAFE_INTEGER + 1)); 136 | } 137 | if (e !== 0) { 138 | return BigInt(f) << BigInt(e); 139 | } 140 | } 141 | return BigInt(x); 142 | }; 143 | } 144 | } 145 | 146 | var Internal = BigIntWrapper; 147 | 148 | // noinline 149 | var n = function (f) { 150 | return function (x, y) { 151 | return f(x, y); 152 | }; 153 | }; 154 | 155 | var cache = new Array(16 * 2 + 1); 156 | for (var i = 0; i < cache.length; i += 1) { 157 | cache[i] = undefined; 158 | } 159 | function LastTwoMap() { 160 | this.a = undefined; 161 | this.aKey = 0; 162 | this.b = undefined; 163 | this.bKey = 0; 164 | this.last = 0; 165 | } 166 | LastTwoMap.prototype.get = function (key) { 167 | if (this.aKey === key) { 168 | this.last = 0; 169 | return this.a; 170 | } 171 | if (this.bKey === key) { 172 | this.last = 1; 173 | return this.b; 174 | } 175 | return undefined; 176 | }; 177 | LastTwoMap.prototype.set = function (key, value) { 178 | if (this.last === 0) { 179 | this.bKey = key; 180 | this.b = value; 181 | this.last = 1; 182 | } else { 183 | this.aKey = key; 184 | this.a = value; 185 | this.last = 0; 186 | } 187 | }; 188 | var map = new LastTwoMap(); // to optimize when some number is multiplied by few numbers sequencely 189 | var toNumber = n(function (a) { 190 | return Internal.toNumber(a); 191 | }); 192 | var valueOf = function (x) { 193 | if (typeof x === "number") { 194 | if (x >= -16 && x <= +16) { 195 | var value = cache[x + 16]; 196 | if (value == undefined) { 197 | value = Internal.BigInt(x); 198 | cache[x + 16] = value; 199 | } 200 | return value; 201 | } 202 | var value = map.get(x); 203 | if (value == undefined) { 204 | value = Internal.BigInt(x); 205 | map.set(x, value); 206 | } 207 | return value; 208 | } 209 | return x; 210 | }; 211 | var B1 = undefined; 212 | var B2 = undefined; 213 | var initB1B2 = function () { 214 | B1 = Internal.BigInt(-9007199254740991); 215 | B2 = Internal.BigInt(9007199254740991); 216 | }; 217 | var toResult = function (x) { 218 | if (!Internal.lessThan(x, B1) && !Internal.greaterThan(x, B2)) { 219 | return Internal.toNumber(x); 220 | } 221 | return x; 222 | }; 223 | // the version above much faster somehow (when false) with native bigint in Chrome 224 | //var toResult = function (x) { 225 | // var value = Internal.toNumber(x); 226 | // if (value >= -9007199254740991 && value <= 9007199254740991) { 227 | // return value; 228 | // } 229 | // return x; 230 | //}; 231 | var add = n(function (x, y) { 232 | if (typeof x === "string" || typeof y === "string") { 233 | return x + y; 234 | } 235 | if (typeof x === "number" && x === 0) { 236 | return y; 237 | } 238 | if (typeof y === "number" && y === 0) { 239 | return x; 240 | } 241 | var a = valueOf(x); 242 | var b = valueOf(y); 243 | var sum = Internal.add(a, b); 244 | return typeof x === "number" && typeof y === "number" ? sum : toResult(sum); 245 | }); 246 | var subtract = n(function (x, y) { 247 | if (typeof x === "number" && x === 0) { 248 | return unaryMinus(y); 249 | } 250 | // quite good optimization for comparision of big integers 251 | if (typeof y === "number" && y === 0) { 252 | return x; 253 | } 254 | var a = valueOf(x); 255 | var b = valueOf(y); 256 | var difference = Internal.subtract(a, b); 257 | return typeof x === "number" && typeof y === "number" ? difference : toResult(difference); 258 | }); 259 | var multiply = n(function (x, y) { 260 | if (typeof x === "number" && x === 0) { 261 | return 0; 262 | } 263 | if (typeof x === "number" && x === 1) { 264 | return y; 265 | } 266 | if (typeof x === "number" && x === -1) { 267 | return Internal.unaryMinus(y); 268 | } 269 | if (typeof y === "number" && y === 0) { 270 | return 0; 271 | } 272 | if (typeof y === "number" && y === 1) { 273 | return x; 274 | } 275 | if (typeof y === "number" && y === -1) { 276 | return Internal.unaryMinus(x); 277 | } 278 | var a = valueOf(x); 279 | var b = valueOf(y); 280 | return Internal.multiply(a, b); 281 | }); 282 | var divide = n(function (x, y) { 283 | if (typeof x === "number" && typeof y !== "number") { 284 | return 0; 285 | } 286 | if (typeof y === "number" && y === 1) { 287 | return x; 288 | } 289 | if (typeof y === "number" && y === -1) { 290 | return Internal.unaryMinus(x); 291 | } 292 | var a = valueOf(x); 293 | var b = valueOf(y); 294 | return toResult(Internal.divide(a, b)); 295 | }); 296 | var remainder = n(function (x, y) { 297 | if (typeof x === "number" && typeof y !== "number") { 298 | return x; 299 | } 300 | if (typeof y === "number" && y === 1) { 301 | return 0; 302 | } 303 | if (typeof y === "number" && y === -1) { 304 | return 0; 305 | } 306 | var a = valueOf(x); 307 | var b = valueOf(y); 308 | return toResult(Internal.remainder(a, b)); 309 | }); 310 | var exponentiate = n(function (x, y) { 311 | if (typeof y === "number") { 312 | if (y === 0) { 313 | return 1; 314 | } 315 | if (y === 1) { 316 | return x; 317 | } 318 | if (y === 2) { 319 | return multiply(x, x); 320 | } 321 | if (typeof x === "number" && Math.abs(x) > 2 && y >= 0) { 322 | if (y > 42 && x % 2 === 0) {//TODO: ? 323 | return multiply(exponentiate(2, y), exponentiate(x / 2, y)); 324 | } 325 | var k = Math.floor(Math.log(9007199254740991) / Math.log(Math.abs(x) + 0.5)); 326 | if (k >= 2) { 327 | return multiply(Math.pow(x, y % k), exponentiate(Math.pow(x, k), Math.floor(y / k))); 328 | } 329 | } 330 | } 331 | var a = valueOf(x); 332 | var b = valueOf(y); 333 | var power = Internal.exponentiate(a, b); 334 | return typeof x === "number" && Math.abs(x) <= 1 ? toResult(power) : power; 335 | }); 336 | var unaryMinus = n(function (x) { 337 | var a = valueOf(x); 338 | return Internal.unaryMinus(a); 339 | }); 340 | var equal = n(function (x, y) { 341 | if (typeof x === "number") { 342 | return false; 343 | } 344 | if (typeof y === "number") { 345 | return false; 346 | } 347 | return Internal.equal(x, y); 348 | }); 349 | var lessThan = n(function (x, y) { 350 | if (typeof x === "number") { 351 | return x < Internal.toNumber(y); 352 | } 353 | if (typeof y === "number") { 354 | return Internal.toNumber(x) < y; 355 | } 356 | return Internal.lessThan(x, y); 357 | }); 358 | var greaterThan = n(function (x, y) { 359 | if (typeof x === "number") { 360 | return x > Internal.toNumber(y); 361 | } 362 | if (typeof y === "number") { 363 | return Internal.toNumber(x) > y; 364 | } 365 | return Internal.greaterThan(x, y); 366 | }); 367 | 368 | function SmallBigInt() { 369 | } 370 | 371 | // Conversion from String: 372 | // Conversion from Number: 373 | SmallBigInt.BigInt = function (x) { 374 | if (typeof x === "number" || typeof x === "string" || typeof x === "bigint") { 375 | var value = 0 + (typeof x === "number" ? x : Number(x)); 376 | if (value >= -9007199254740991 && value <= 9007199254740991) { 377 | return value; 378 | } 379 | } 380 | return toResult(Internal.BigInt(x)); 381 | }; 382 | SmallBigInt.asIntN = function (n, x) { 383 | return toResult(Internal.asIntN(n, Internal.BigInt(x))); 384 | }; 385 | SmallBigInt.asUintN = function (n, x) { 386 | if (typeof x === "number" && x >= 0 && n >= 0 && n <= 53) { 387 | var m = Math.pow(2, n); 388 | return x - Math.floor(x / m) * m; 389 | } 390 | return toResult(Internal.asUintN(n, Internal.BigInt(x))); 391 | }; 392 | // Conversion to Number: 393 | SmallBigInt.toNumber = function (x) { 394 | if (typeof x === "number") { 395 | return x; 396 | } 397 | return toNumber(x); 398 | }; 399 | 400 | // Arithmetic: 401 | SmallBigInt.add = function (x, y) { 402 | if (typeof x === "number" && typeof y === "number") { 403 | var value = x + y; 404 | if (value >= -9007199254740991 && value <= 9007199254740991) { 405 | return value; 406 | } 407 | } 408 | return add(x, y); 409 | }; 410 | SmallBigInt.subtract = function (x, y) { 411 | if (typeof x === "number" && typeof y === "number") { 412 | var value = x - y; 413 | if (value >= -9007199254740991 && value <= 9007199254740991) { 414 | return value; 415 | } 416 | } 417 | return subtract(x, y); 418 | }; 419 | SmallBigInt.multiply = function (x, y) { 420 | if (typeof x === "number" && typeof y === "number") { 421 | var value = 0 + x * y; 422 | if (value >= -9007199254740991 && value <= 9007199254740991) { 423 | return value; 424 | } 425 | } 426 | return multiply(x, y); 427 | }; 428 | SmallBigInt.divide = function (x, y) { 429 | if (typeof x === "number" && typeof y === "number") { 430 | if (y !== 0) { 431 | return x === 0 ? 0 : (x > 0 && y > 0) || (x < 0 && y < 0) ? 0 + Math.floor(x / y) : 0 - Math.floor((0 - x) / y); 432 | } 433 | } 434 | return divide(x, y); 435 | }; 436 | SmallBigInt.remainder = function (x, y) { 437 | if (typeof x === "number" && typeof y === "number") { 438 | if (y !== 0) { 439 | return 0 + x % y; 440 | } 441 | } 442 | return remainder(x, y); 443 | }; 444 | SmallBigInt.unaryMinus = function (x) { 445 | if (typeof x === "number") { 446 | return 0 - x; 447 | } 448 | return unaryMinus(x); 449 | }; 450 | 451 | // Comparison: 452 | SmallBigInt.equal = function (x, y) { 453 | if (typeof x === "number" && typeof y === "number") { 454 | return x === y; 455 | } 456 | return equal(x, y); 457 | }; 458 | SmallBigInt.lessThan = function (x, y) { 459 | if (typeof x === "number" && typeof y === "number") { 460 | return x < y; 461 | } 462 | return lessThan(x, y); 463 | }; 464 | SmallBigInt.greaterThan = function (x, y) { 465 | if (typeof x === "number" && typeof y === "number") { 466 | return x > y; 467 | } 468 | return greaterThan(x, y); 469 | }; 470 | SmallBigInt.notEqual = function (x, y) { 471 | return !SmallBigInt.equal(x, y); 472 | }; 473 | SmallBigInt.lessThanOrEqual = function (x, y) { 474 | return !SmallBigInt.greaterThan(x, y); 475 | }; 476 | SmallBigInt.greaterThanOrEqual = function (x, y) { 477 | return !SmallBigInt.lessThan(x, y); 478 | }; 479 | 480 | SmallBigInt.exponentiate = function (x, y) { 481 | if (typeof x === "number" && typeof y === "number") { 482 | if (y >= 0 && (y < 53 || x >= -1 && x <= 1)) { // 53 === log2(9007199254740991 + 1) 483 | var value = 0 + Math.pow(x, y); 484 | if (value >= -9007199254740991 && value <= 9007199254740991) { 485 | return value; 486 | } 487 | } 488 | } 489 | return exponentiate(x, y); 490 | }; 491 | SmallBigInt.signedRightShift = function (x, n) { 492 | return toResult(Internal.signedRightShift(valueOf(x), valueOf(n))); 493 | }; 494 | SmallBigInt.leftShift = function (x, n) { 495 | if (typeof n === "number" && n >= 0) { 496 | if (typeof x === "number") { 497 | var value = n === 0 ? x : x * Math.pow(2, n); 498 | if (value >= -9007199254740991 && value <= 9007199254740991) { 499 | return value; 500 | } 501 | } 502 | return Internal.leftShift(valueOf(x), valueOf(n)); 503 | } 504 | return toResult(Internal.leftShift(valueOf(x), valueOf(n))); 505 | }; 506 | if (Symbol.hasInstance != undefined) { 507 | Object.defineProperty(SmallBigInt, Symbol.hasInstance, { 508 | value: function (a) { 509 | return typeof a === 'number' || a instanceof Internal; 510 | } 511 | }); 512 | } 513 | 514 | globalThis.SmallBigInt = SmallBigInt; 515 | 516 | globalThis.JSBI = supportsBigInt ? BigIntWrapper : (globalThis.JSBI || globalThis.BigInteger); 517 | Internal = globalThis.JSBI; 518 | initB1B2(); 519 | 520 | }()); 521 | -------------------------------------------------------------------------------- /benchmark/iframe.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /benchmark/iframe.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var global = this; 4 | 5 | // for crypto.js 6 | function BenchmarkSuite() { 7 | } 8 | global.BenchmarkSuite = BenchmarkSuite 9 | 10 | var I = undefined; 11 | global.url = undefined; 12 | global.benchmarkSuite = undefined; 13 | global.testSuite = undefined; 14 | var base = this.parent !== undefined ? this.parent : { 15 | postMessage: function (message) { 16 | global.postMessage(message); 17 | } 18 | }; 19 | 20 | var loadScripts = function (src, callback) { 21 | if (src === "") { 22 | setTimeout(callback, 0); 23 | } else { 24 | if (global.importScripts !== undefined) { 25 | global.importScripts(src); 26 | setTimeout(callback, 0); 27 | } else { 28 | var script = document.createElement("script"); 29 | script.src = src; 30 | script.onload = callback; 31 | script.onreadystatechange = function() { // IE 32 | if (script.readyState === "complete" || script.readyState === "loaded") { 33 | script.onload = undefined; 34 | callback(); 35 | } 36 | }; 37 | document.documentElement.appendChild(script); 38 | } 39 | } 40 | }; 41 | 42 | var transform = function (f) { 43 | return eval("(" + f.toString().replace(/I\.([a-zA-Z]+)\(([^,\)]+)(?:,([^,\)]+))?(?:,([^,\)]+))?\)/g, function (p, o, a, b, c) { 44 | if (I[o] == undefined || I[o] === "") { 45 | return p; 46 | } 47 | return I[o].replace(/([a-zA-Z]+)/g, function (t) { 48 | return t === "a" ? a.trim() : (t === "b" ? b.trim() : (t === "c" ? c.trim() : t)); 49 | }); 50 | }) + ")"); 51 | }; 52 | 53 | var invervalId = setInterval(function () { 54 | console.log("!"); 55 | }, 10000); 56 | 57 | self.onmessage = function (event) { 58 | if (event.data === "start:benchmarks" || event.data === "start:tests") { 59 | var type = event.data; 60 | var src = decodeURIComponent(/src\=([^&]*)/.exec(location.search)[1]); 61 | loadScripts("benchmark.js", function () { 62 | Benchmark.options.minTime = 1 / 128; 63 | Benchmark.options.maxTime = 1 / 4; 64 | Benchmark.options.minSamples = 7; 65 | 66 | benchmarkSuite = new Benchmark.Suite(); 67 | benchmarkSuite.on("cycle", function (event) { 68 | base.postMessage(JSON.stringify({ 69 | message: event.target.toString(), 70 | url: url, 71 | name: event.target.name, 72 | result: (1 / event.target.times.period) 73 | }), "*"); 74 | }); 75 | var complete = false; 76 | var finish = function () { 77 | if (!complete) { 78 | complete = true; 79 | base.postMessage(JSON.stringify({ 80 | message: "", 81 | url: url, 82 | name: "complete", 83 | result: 0 84 | }), "*"); 85 | clearInterval(invervalId); 86 | } 87 | }; 88 | benchmarkSuite.on("error", function (event) { 89 | finish(); 90 | }); 91 | benchmarkSuite.on("complete", function (event) { 92 | finish(); 93 | }); 94 | testSuite = { 95 | callbacks: [], 96 | add: function (title, callback) { 97 | this.callbacks.push({ 98 | title: title, 99 | callback: callback 100 | }); 101 | }, 102 | run: function (options) { 103 | for (var i = 0; i < this.callbacks.length; i += 1) { 104 | var test = this.callbacks[i]; 105 | var data = ""; 106 | try { 107 | test.callback(I); 108 | } catch (e) { 109 | data = e.toString(); 110 | if (e.message === "-") { 111 | data = "N/A"; 112 | } 113 | } 114 | base.postMessage(JSON.stringify({ 115 | message: test.title, 116 | url: url, 117 | name: "test", 118 | result: data 119 | }), "*"); 120 | } 121 | } 122 | }; 123 | loadScripts("libs.js", function () { 124 | var special = { 125 | "data:text/plain,number": "", 126 | "data:text/plain,bigint": "" 127 | }; 128 | var notTestable = { 129 | "data:text/plain,number": true 130 | }; 131 | loadScripts(src in special ? special[src] : src, function () { 132 | var lib = undefined; 133 | for (var i = 0; i < libs.length; i += 1) { 134 | if (libs[i].src === src) { 135 | lib = libs[i]; 136 | } 137 | } 138 | I = lib; 139 | url = lib.url;//! 140 | loadScripts("generated-tests.js", function () { 141 | loadScripts("tests.js", function () { 142 | if (I.setup != undefined) { 143 | I.setup(); 144 | } 145 | var f = transform(wrapper.toString()); 146 | f(); 147 | setTimeout(function () { 148 | if (type === "start:tests") { 149 | if (!(src in notTestable)) { 150 | testSuite.run(); 151 | } 152 | finish(); 153 | } 154 | if (type === "start:benchmarks") { 155 | benchmarkSuite.run({ 156 | async: true 157 | }); 158 | } 159 | }, 64); 160 | }); 161 | }); 162 | }); 163 | }); 164 | }); 165 | } 166 | }; 167 | -------------------------------------------------------------------------------- /benchmark/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Benchmarks for some JavaScript implementations of arbitrary length integers 5 | 6 | 7 | 8 | 9 | 73 | 74 | 75 | 76 |

77 | 78 |
79 | 80 |
81 | 82 |
83 | 84 |
85 | 86 | 87 | 88 | 89 |
tests
-
90 | 91 | 92 | Fork me on GitHub 93 | 94 | 95 | -------------------------------------------------------------------------------- /benchmark/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var filter = function (description) { 4 | var table = document.querySelector("table"); 5 | var rows = table.querySelectorAll("tr"); 6 | var row = undefined; 7 | var i = -1; 8 | while (++i < rows.length) { 9 | var a = rows[i].querySelector("td > a[href]"); 10 | if (a != undefined && a.href === description.url) { 11 | row = rows[i]; 12 | } 13 | } 14 | if (!row.querySelector("input[type=checkbox]").checked) { 15 | return false; 16 | } 17 | 18 | //if (description.url.indexOf("XXX") !== -1) { 19 | // return false; 20 | //} 21 | return true; 22 | }; 23 | 24 | var hardwareConcurrency = 1;//navigator.hardwareConcurrency != undefined ? navigator.hardwareConcurrency : 1; 25 | var lastIndex = -1; 26 | var running = 0; 27 | var test = undefined; 28 | var type = undefined; 29 | 30 | self.onmessage = function (e) { 31 | e = e || window.event; 32 | 33 | var data = JSON.parse(e.data); 34 | if (data.name === "test") { 35 | if (data.result !== "") { 36 | var table = document.querySelector("table.tests"); 37 | var rows = table.rows; 38 | var row = undefined; 39 | var testRow = undefined; 40 | var i = -1; 41 | i += 1; 42 | while (++i < rows.length) { 43 | var a = rows[i].cells[0]; 44 | if (a.getAttribute("data.message") === data.message) { 45 | testRow = rows[i]; 46 | } 47 | } 48 | if (testRow == undefined) { 49 | testRow = table.insertRow(-1); 50 | var c = testRow.insertCell(-1); 51 | c.setAttribute("data.message", data.message); 52 | c.innerHTML = data.message; 53 | for (var i = 1; i < table.rows[0].cells.length; i += 1) { 54 | testRow.insertCell(-1); 55 | } 56 | } 57 | var row = rows[0]; 58 | var cellIndex = 0; 59 | while (cellIndex < row.cells.length && row.cells[cellIndex].getAttribute("data-url") !== data.url) { 60 | cellIndex += 1; 61 | } 62 | if (cellIndex === row.cells.length) { 63 | for (var i = 0; i < rows.length; i += 1) { 64 | rows[i].insertCell(cellIndex); 65 | } 66 | row.cells[cellIndex].setAttribute("data-url", data.url); 67 | row.cells[cellIndex].innerHTML = data.url; 68 | } 69 | testRow.cells[cellIndex].innerHTML = data.result === "" ? "OK" : data.result; 70 | if (data.result !== "") { 71 | if (testRow.classList != undefined) { 72 | testRow.classList.add("y"); 73 | } 74 | } 75 | } 76 | } else if (data.name !== "complete") { 77 | /* 78 | var tables = document.querySelectorAll("table"); 79 | var e = undefined; 80 | var i = -1; 81 | while (++i < tables.length) { 82 | if (tables[i].getAttribute("data-name") === data.name) { 83 | e = tables[i]; 84 | } 85 | } 86 | if (e == undefined) { 87 | e = document.createElement("table"); 88 | e.setAttribute("sortable", "sortable"); 89 | e.setAttribute("data-name", data.name); 90 | e.style.marginTop = "0.25em"; 91 | e.style.marginBottom = "0.25em"; 92 | document.body.appendChild(e); 93 | var caption = document.createElement("caption"); 94 | e.appendChild(caption) 95 | caption.innerHTML = data.name; 96 | caption.style.textAlign = "left"; 97 | caption.style.fontWeight = "bold"; 98 | var head = document.createElement("thead"); 99 | e.appendChild(head) 100 | var row = head.insertRow(-1); 101 | var th0 = row.insertCell(0); 102 | th0.tabIndex = 0; 103 | th0.innerHTML = "URL"; 104 | var th1 = row.insertCell(1); 105 | th1.tabIndex = 0; 106 | th1.innerHTML = "benchmark"; 107 | var th2 = row.insertCell(2); 108 | th2.tabIndex = 0; 109 | th2.innerHTML = "ops/sec"; 110 | th2.setAttribute("sorted", "reversed 1"); 111 | var body = document.createElement("tbody"); 112 | e.appendChild(body); 113 | } 114 | var x = e.tBodies[0].insertRow(-1); 115 | x.className = "result"; 116 | var c0 = x.insertCell(0); 117 | c0.innerHTML = data.url === "number" ? data.url : "" + data.url + ""; 118 | 119 | 120 | var match = /([\s\S]*?)\sx\s([^\(]*)([\s\S]*)/.exec(data.message); 121 | 122 | var c1 = x.insertCell(1); 123 | c1.innerHTML = data.name; 124 | var c2 = x.insertCell(2); 125 | c2.style.textAlign = "right"; 126 | c2.innerHTML = match == undefined ? "-" : match[2]; 127 | 128 | sortTable(e); 129 | */ 130 | var table = document.querySelector("table"); 131 | var rows = table.querySelectorAll("tr"); 132 | var row = undefined; 133 | var i = -1; 134 | while (++i < rows.length) { 135 | var a = rows[i].querySelector("td > a[href]"); 136 | if (a != undefined && a.href === data.url) { 137 | row = rows[i]; 138 | } 139 | } 140 | if (row === undefined) { 141 | throw new Error(data.url); 142 | } 143 | var cellIndex = -1; 144 | var cells = table.querySelectorAll("thead tr > td"); 145 | var j = -1; 146 | while (++j < cells.length) { 147 | if (cells[j].getAttribute("id") === data.name) { 148 | cellIndex = j; 149 | } 150 | } 151 | if (cellIndex === -1) { 152 | throw new Error(data.name); 153 | } 154 | var match = /([\s\S]*?)\sx\s([^\(]*)([\s\S]*)/.exec(data.message); 155 | 156 | row.cells[cellIndex].appendChild(document.createTextNode(match == undefined ? "-" : match[2])); 157 | 158 | } else { 159 | running -= 1; 160 | window.setTimeout(function () { 161 | test(); 162 | }, 0); 163 | } 164 | }; 165 | 166 | test = function () { 167 | var i = lastIndex; 168 | while (++i < libs.length) { 169 | if (running < hardwareConcurrency && filter(libs[i])) { 170 | running += 1; 171 | lastIndex = i; 172 | var src = libs[i].src; 173 | if (self.Worker !== undefined && location.protocol !== "file:") { 174 | var w = new self.Worker("iframe.js?src=" + encodeURIComponent(src)); 175 | w.onmessage = function (event) { 176 | self.postMessage(event.data, "*"); 177 | }; 178 | w.onerror = function (src, e) { 179 | console.log(e, src); 180 | }.bind(undefined, src); 181 | w.postMessage("start:" + type); 182 | } else { 183 | var w = document.createElement("iframe"); 184 | w.style.visibility = "hidden"; 185 | w.style.width = "0px"; 186 | w.style.height = "0px"; 187 | document.body.appendChild(w); 188 | w.setAttribute("src", "iframe.html?src=" + encodeURIComponent(src)); 189 | w.onload = function () { 190 | w.contentWindow.postMessage("start:" + type, "*"); 191 | }; 192 | } 193 | } 194 | } 195 | }; 196 | 197 | window.setTimeout(function () { 198 | document.getElementById("table-container").innerHTML = generateTable(); 199 | document.getElementById("info-table-container").innerHTML = generateInfoTable(); 200 | 201 | 202 | var c = document.querySelector("input[type=checkbox]"); 203 | c.onchange = function () { 204 | var value = c.checked; 205 | var elements = document.querySelectorAll("input[type=checkbox]"); 206 | for (var i = 0; i < elements.length; i += 1) { 207 | elements[i].checked = value; 208 | } 209 | }; 210 | var startTests = function () { 211 | var state = []; 212 | var elements = document.querySelectorAll("input[type=checkbox]"); 213 | for (var i = 0; i < elements.length; i += 1) { 214 | state[i] = elements[i].checked; 215 | } 216 | var s = JSON.stringify(state); 217 | try { 218 | window.localStorage.setItem("state", s); 219 | } catch (error) { 220 | console.log(error); 221 | } 222 | lastIndex = -1; 223 | test(); 224 | }; 225 | document.querySelector("button.tests").onclick = function () { 226 | type = "tests"; 227 | startTests(); 228 | }; 229 | document.querySelector("button.benchmarks").onclick = function () { 230 | type = "benchmarks"; 231 | startTests(); 232 | }; 233 | window.addEventListener("message", function (e) { 234 | if (running > 0) { 235 | document.querySelector("span.working").removeAttribute("hidden"); 236 | } else { 237 | document.querySelector("span.working").setAttribute("hidden", "hidden"); 238 | } 239 | }, false); 240 | 241 | var s = null; 242 | try { 243 | s = window.localStorage.getItem("state"); 244 | } catch (error) { 245 | console.log(error); 246 | } 247 | var state = JSON.parse(s || "[]"); 248 | var elements = document.querySelectorAll("input[type=checkbox]"); 249 | for (var i = 0; i < elements.length; i += 1) { 250 | elements[i].checked = i < state.length ? state[i] : false; 251 | } 252 | 253 | }, 128); 254 | 255 | // 256 | 257 | var sortTable = function (table) { 258 | var cellIndex = -1; 259 | var cells = table.tHead.rows[0].cells; 260 | var k = -1; 261 | var reversed = false; 262 | while (++k < cells.length) { 263 | var s = cells[k].getAttribute("sorted"); 264 | if (s === "1" || s === "reversed 1") { 265 | cellIndex = k; 266 | reversed = s === "reversed 1"; 267 | } 268 | } 269 | if (cellIndex !== -1) { 270 | var values = []; 271 | var rows = table.tBodies[0].rows; 272 | var i = -1; 273 | while (++i < rows.length) { 274 | var row = rows[i]; 275 | var value = row.cells[cellIndex].textContent; 276 | var match = (/^[\d,]+(?:[\.][\d,]*)?|^\-$/).exec(value); 277 | if (match != undefined) { 278 | value = Number(match[0].replace(/,/g, "")); 279 | if (value !== value) { 280 | value = -1.0 / 0.0; 281 | } 282 | } 283 | values.push({ 284 | value: value, 285 | index: i, 286 | row: row 287 | }); 288 | } 289 | values = values.sort(function (a, b) { 290 | if (a.value < b.value) { 291 | return reversed ? +1 : -1; 292 | } 293 | if (b.value < a.value) { 294 | return reversed ? -1 : +1; 295 | } 296 | return a.index - b.index; 297 | }); 298 | while (table.tBodies[0].firstChild != undefined) { 299 | table.tBodies[0].removeChild(table.tBodies[0].firstChild); 300 | } 301 | var j = -1; 302 | while (++j < values.length) { 303 | var value = values[j]; 304 | table.tBodies[0].appendChild(value.row); 305 | } 306 | } 307 | }; 308 | 309 | (function () { 310 | 311 | document.addEventListener("click", function (e) { 312 | if (!e.defaultPrevented) { 313 | var t = e.target; 314 | while (t != undefined && t.tagName !== "TD") { 315 | t = t.parentNode; 316 | } 317 | if (t != undefined && t.parentNode.parentNode.tagName === "THEAD" && t.parentNode.parentNode.parentNode.getAttribute("sortable") != undefined) { 318 | var cellIndex = t.cellIndex; 319 | var sorted = t.getAttribute("sorted"); 320 | var cells = t.parentNode.cells; 321 | var k = -1; 322 | while (++k < cells.length) { 323 | cells[k].setAttribute("sorted", ""); 324 | } 325 | var reversed = sorted !== "reversed 1"; 326 | t.setAttribute("sorted", reversed ? "reversed 1" : "1"); 327 | var table = t.parentNode.parentNode.parentNode; 328 | sortTable(table); 329 | } 330 | } 331 | }, false); 332 | }()); 333 | 334 | 335 | var escapeHTML = function (s) { 336 | return s.replace(/&/g, "&") 337 | .replace(/"/g, """) 338 | .replace(//g, ">"); 340 | }; 341 | 342 | var generateTable = function () { 343 | var html = ""; 344 | html += "\n
"; 345 | html += "\n"; 346 | html += "\n "; 347 | html += "\n "; 348 | html += "\n "; 349 | var benchmarks = [ 350 | {id: "create-10", url: "https://github.com/indutny/bn.js/blob/master/benchmarks/index.js"}, 351 | {id: "create-hex", url: "https://github.com/indutny/bn.js/blob/master/benchmarks/index.js"}, 352 | {id: "toString-10", url: "https://github.com/indutny/bn.js/blob/master/benchmarks/index.js"}, 353 | {id: "toString-hex", url: "https://github.com/indutny/bn.js/blob/master/benchmarks/index.js"}, 354 | {id: "add", url: "https://github.com/indutny/bn.js/blob/master/benchmarks/index.js"}, 355 | {id: "mul", url: "https://github.com/indutny/bn.js/blob/master/benchmarks/index.js"}, 356 | {id: "mul-jumbo", url: "https://github.com/indutny/bn.js/blob/master/benchmarks/index.js"}, 357 | {id: "div", url: "https://github.com/indutny/bn.js/blob/master/benchmarks/index.js"}, 358 | {id: "mod", url: "https://github.com/indutny/bn.js/blob/master/benchmarks/index.js"}, 359 | {id: "10*10==20", url: "#1"}, 360 | {id: "27*27==54", url: "#2"}, 361 | {id: "bitwise-shift-operators", url: "#3"}, 362 | {id: "bitwise-logical-operators", url: "#4"}, 363 | {id: "gcd-jumbo", url: "#5"}, 364 | {id: "joseprio", url: "http://www.joseprio.com/blog/2013/04/27/biginteger-libraries-for-js"}, 365 | ]; 366 | for (var i = 0; i < benchmarks.length; i += 1) { 367 | var benchmark = benchmarks[i]; 368 | html += "\n ".replace("${id}", benchmark.id).replace("${url}", benchmark.url).replace("${id}", benchmark.id); 369 | } 370 | html += "\n "; 371 | html += "\n"; 372 | html += "\n"; 373 | for (var i = 0; i < libs.length; i += 1) { 374 | var lib = libs[i]; 375 | html += "\n "; 376 | html += "\n "; 377 | html += "\n ".replace(/\$\{url\}/g, escapeHTML(lib.url)); 378 | for (var j = 0; j < benchmarks.length; j += 1) { 379 | html += "\n "; 380 | } 381 | html += "\n "; 382 | } 383 | html += "\n"; 384 | html += "\n
URL${id}
${url}
"; 385 | return html; 386 | }; 387 | 388 | //console.log(generateTable()); 389 | 390 | var generateInfoTable = function () { 391 | var object = {}; 392 | object["url"] = ""; 393 | for (var i = 0; i < libs.length; i += 1) { 394 | object = Object.assign(object, libs[i]); 395 | } 396 | 397 | var html = ""; 398 | html += ""; 399 | html += ""; 400 | html += ""; 401 | for (var key in object) { 402 | if (Object.prototype.hasOwnProperty.call(object, key)) { 403 | if (key !== "src" && key !== "source" && key !== "setup") { 404 | html += ""; 407 | } 408 | } 409 | } 410 | html += ""; 411 | html += ""; 412 | html += ""; 413 | for (var i = 0; i < libs.length; i += 1) { 414 | html += ""; 415 | for (var key in object) { 416 | if (Object.prototype.hasOwnProperty.call(object, key)) { 417 | if (key !== "src" && key !== "source" && key !== "setup") { 418 | html += key === "url" ? ""; 422 | } 423 | } 424 | } 425 | html += ""; 426 | } 427 | html += ""; 428 | html += "
"; 405 | html += escapeHTML(key); 406 | html += "
" : ""; 419 | var v = libs[i][key]; 420 | html += escapeHTML(typeof v === "function" ? "function" : (typeof v === "boolean" ? (v ? "+" : "-") : (v == undefined ? "undefined" : v || "-"))); 421 | html += key === "url" ? "" : "
"; 429 | return html; 430 | }; 431 | -------------------------------------------------------------------------------- /benchmark/libs.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (Object.assign == undefined) { 4 | Object.assign = function (target) { 5 | for (var i = 1; i < arguments.length; i += 1) { 6 | var nextSource = arguments[i]; 7 | if (nextSource != undefined) { 8 | for (var key in nextSource) { 9 | if (Object.prototype.hasOwnProperty.call(nextSource, key)) { 10 | target[key] = nextSource[key]; 11 | } 12 | } 13 | } 14 | } 15 | return target; 16 | }; 17 | } 18 | 19 | if (Math.sign == undefined) { 20 | Math.sign = function (x) { 21 | return x < 0 ? -1 : (x > 0 ? 1 : x); 22 | }; 23 | } 24 | 25 | if (Number.EPSILON == undefined) { 26 | Number.EPSILON = 2 / 9007199254740992; 27 | } 28 | 29 | if (Number.parseInt == undefined) { 30 | Number.parseInt = parseInt; 31 | } 32 | 33 | // parseInt, toString, shiftLeft, shiftRight, pow: b is a number value 34 | 35 | var JavaBigInteger = { 36 | add: "a.add(b)", 37 | subtract: "a.subtract(b)", 38 | multiply: "a.multiply(b)", 39 | divide: "a.divide(b)", 40 | remainder: "a.remainder(b)", 41 | negate: "a.negate()", 42 | compareTo: "a.compareTo(b)", 43 | parseInt: "new BigInteger(a, b)", 44 | toString: "a.toString(b)", 45 | and: "a.and(b)", 46 | or: "a.or(b)", 47 | xor: "a.xor(b)", 48 | not: "a.not()", 49 | shiftLeft: "a.shiftLeft(b)", 50 | shiftRight: "a.shiftRight(b)", 51 | bitLength: "a.bitLength()", 52 | pow: "a.pow(b)", 53 | fromNumber: "BigInteger.valueOf(a)", 54 | toNumber: "a.doubleValue()", 55 | setup: undefined, 56 | mod: "a.mod(b)", 57 | modPow: "a.modPow(b, c)", 58 | modInverse: "a.modInverse(b)", 59 | gcd: "a.gcd(b)", 60 | floatingPoint: false 61 | }; 62 | 63 | var NodeBigInteger = { 64 | add: "a.add(b)", 65 | subtract: "a.sub(b)", 66 | multiply: "a.mul(b)", 67 | divide: "a.div(b)", 68 | remainder: "a.mod(b)", 69 | negate: "a.neg()", 70 | compareTo: "a.cmp(b)", 71 | parseInt: "new BN(a, b)", 72 | toString: "a.toString(b)", 73 | and: "a.and(b)", 74 | or: "a.or(b)", 75 | xor: "a.xor(b)", 76 | not: "a.not()", 77 | shiftLeft: "a.shln(b)", 78 | shiftRight: "a.shrn(b)", 79 | bitLength: "a.bitLength()", 80 | pow: "a.pow(b)", 81 | fromNumber: "new BN(a)", 82 | toNumber: "a.toNumber()", 83 | setup: undefined, 84 | mod: "a.mod(b)", 85 | modPow: undefined, 86 | modInverse: "a.invm(b)", 87 | gcd: "a.gcd(b)", 88 | floatingPoint: false 89 | }; 90 | 91 | var MikeMclBigNumber = { 92 | add: "a.plus(b)", 93 | subtract: "a.minus(b)", 94 | multiply: "a.times(b)", 95 | divide: "a.div(b)", 96 | remainder: "a.mod(b)", 97 | negate: "a.neg()", 98 | compareTo: "a.cmp(b)", 99 | parseInt: "new BigNumber(a, b)", 100 | toString: "a.toString(b)", 101 | and: "", 102 | or: "", 103 | xor: "", 104 | not: "", 105 | shiftLeft: "", 106 | shiftRight: "", 107 | bitLength: "a.logarithm(2)", 108 | pow: "a.toPower(b)", 109 | fromNumber: "new BigNumber(a)", 110 | toNumber: "a.toNumber()", 111 | floatingPoint: true 112 | }; 113 | 114 | var libs = [ 115 | Object.assign({}, JavaBigInteger, { 116 | url: "http://www.leemon.com/crypto/BigInt.html", 117 | source: "http://www.leemon.com/crypto/BigInt.js", 118 | setup: function () { 119 | var add = self.add; 120 | var sub = self.sub; 121 | var str2bigInt = self.str2bigInt; 122 | var mult = self.mult; 123 | var divide_ = self.divide_; 124 | var mod = self.mod; 125 | var bigInt2str = self.bigInt2str; 126 | var zero = str2bigInt("0", 10, 0); 127 | var greater = self.greater; 128 | var expand = self.expand; 129 | var bitSize = self.bitSize; 130 | var powMod = self.powMod; 131 | var inverseMod = self.inverseMod; 132 | var GCD = self.GCD; 133 | 134 | // Big Thanks to @jtobey - https://github.com/jtobey/javascript-bignum/blob/master/lib/leemonBigInt.js 135 | function BigInt(sign, bigInt) { 136 | //assert(this instanceof BigInt); 137 | this._s = sign; 138 | this._b = bigInt; 139 | } 140 | function BigInt_numberToString(radix) { 141 | return (this._s === -1 ? "-" : "") + bigInt2str(this._b, radix || 10); 142 | } 143 | function _divMod(b1, b2) { 144 | if (isZero(b2)) 145 | raiseDivisionByExactZero(); 146 | var m = mod(b1, b2); // s5 contains the quotient. 147 | return [dup(s5), m]; 148 | } 149 | function _divAndMod(x, y) { 150 | var dm = _divMod(x._b, y._b); 151 | if (x._s > 0) 152 | // XXX any problem if n is negative and dm[0] is zero? 153 | return [isZero(dm[0]) ? BigInt.ZERO : new BigInt(y._s, dm[0]), new BigInt(1, dm[1])]; 154 | var q = dm[0], r = dm[1]; 155 | if (isZero(r)) 156 | return [new BigInt(-y._s, q), BigInt.ZERO]; 157 | q.push(0); 158 | addInt_(q, 1); 159 | return [new BigInt(-y._s, trim(q, 1)), new BigInt(1, sub(y._b, r))]; 160 | } 161 | function BigInt_divAndMod(n) { 162 | return _divAndMod(this, n); 163 | } 164 | function BigInt_div(n) { 165 | return _divAndMod(this, n)[0]; 166 | } 167 | function BigInt_mod(n) { 168 | return _divAndMod(this, n)[1]; 169 | } 170 | function BigInt_negate() { return isZero(this._b) ? BigInt.ZERO : new BigInt(-this._s, this._b); } 171 | function BigInt_compare(n) { 172 | if (isZero(n._b)) 173 | return isZero(this._b) ? 0 : this._s; 174 | var ret = (this._s - n._s) / 2; 175 | if (ret) 176 | return ret; 177 | if (equals(this._b, n._b)) 178 | return 0; 179 | return this._s * (greater(this._b, n._b) ? 1 : -1); 180 | } 181 | function BigInt_add(n) { 182 | if (this._s === 1) { 183 | if (n._s === 1) 184 | return new BigInt(1, add(this._b, n._b)); 185 | if (greater(n._b, this._b)) 186 | return new BigInt(-1, sub(n._b, this._b)); 187 | return new BigInt(1, sub(this._b, n._b)); 188 | } 189 | if (n._s === -1) 190 | return new BigInt(-1, add(this._b, n._b)); 191 | if (greater(this._b, n._b)) 192 | return new BigInt(-1, sub(this._b, n._b)); 193 | return new BigInt(1, sub(n._b, this._b)); 194 | } 195 | 196 | function BigInt_multiply(n) { 197 | var data = mult(this._b, n._b); 198 | if (isZero(data)) { 199 | return BigInt.ZERO; 200 | } 201 | return new BigInt(this._s * n._s, data); 202 | } 203 | 204 | BigInt.parseInt = function (string, radix) { 205 | var sign = +1; 206 | if (string.slice(0, 1) === "-") { 207 | sign = -1; 208 | string = string.slice(1); 209 | } 210 | var data = str2bigInt(string, radix == undefined ? 10 : radix, 0); 211 | if (isZero(data)) { 212 | return BigInt.ZERO; 213 | } 214 | return new BigInt(sign, data); 215 | }; 216 | BigInt.prototype.negate = BigInt_negate; 217 | BigInt.prototype.compareTo = BigInt_compare; 218 | 219 | BigInt.prototype.add = BigInt_add; 220 | BigInt.prototype.subtract = function (y) { 221 | return this.add(y.negate()); 222 | }; 223 | BigInt.prototype.multiply = BigInt_multiply; 224 | BigInt.prototype.divide = BigInt_div; 225 | BigInt.prototype.remainder = BigInt_mod; 226 | BigInt.prototype.toString = BigInt_numberToString; 227 | BigInt.prototype.bitLength = function () { 228 | return bitSize(this._b); 229 | }; 230 | BigInt.prototype.pow = function (y) { 231 | var n = BigInt.parseInt("1000000000000000000000000000000000000000000000000000000000000000000000000", 16); 232 | return new BigInt(1, powMod(this._b, y._b, n._b)); 233 | }; 234 | BigInt.prototype.mod = function (b) { 235 | return new BigInt(1, mod(this._b, b._b)); 236 | }; 237 | BigInt.prototype.modInverse = function (b) { 238 | return new BigInt(1, inverseMod(this._b, b._b)); 239 | }; 240 | BigInt.prototype.modPow = function (b, c) { 241 | return new BigInt(1, powMod(this._b, b._b, c._b)); 242 | }; 243 | BigInt.prototype.gcd = function (b) { 244 | return new BigInt(1, GCD(this._b, b._b)); 245 | }; 246 | BigInt.ZERO = new BigInt(1, zero); 247 | self.BigInteger = BigInt; 248 | }, 249 | parseInt: "BigInteger.parseInt(a, b)", 250 | floatingPoint: false 251 | }), 252 | { 253 | url: "https://github.com/jtobey/javascript-bignum", 254 | source: "https://raw.githubusercontent.com/jtobey/javascript-bignum/master/biginteger.js https://raw.githubusercontent.com/jtobey/javascript-bignum/master/schemeNumber.js https://raw.githubusercontent.com/jtobey/javascript-bignum/master/lib/hybridBigInteger.js", 255 | add: "SchemeNumber.fn[\"+\"](a, b)", 256 | subtract: "SchemeNumber.fn[\"-\"](a, b)", 257 | multiply: "SchemeNumber.fn[\"*\"](a, b)", 258 | divide: "SchemeNumber.fn[\"div\"](a, b)", 259 | remainder: "SchemeNumber.fn[\"mod\"](a, b)", 260 | negate: "SchemeNumber.fn[\"-\"](a)", 261 | compareTo: "(SchemeNumber.fn[\"<\"](a, b) ? -1 : (SchemeNumber.fn[\"<\"](b, a) ? +1 : 0))", 262 | parseInt: "SchemeNumber.plugins.get(\"parseExactInteger\")(1, a, b)", 263 | toString: "SchemeNumber.plugins.get(\"numberToString\")(a, b, 0)", 264 | and: "SchemeNumber.plugins.get(\"bitwiseAnd\")(a, b)", 265 | or: "SchemeNumber.plugins.get(\"bitwiseIor\")(a, b)", 266 | xor: "SchemeNumber.plugins.get(\"bitwiseXor\")(a, b)", 267 | shiftLeft: "SchemeNumber.plugins.get(\"bitShift\")(a, SchemeNumber.plugins.get(\"parseExactInteger\")(1, (0 + b).toString(), 10))", 268 | not: "SchemeNumber.plugins.get(\"bitwiseNot\")(a)", 269 | shiftRight: "SchemeNumber.plugins.get(\"bitShift\")(a, SchemeNumber.plugins.get(\"parseExactInteger\")(1, (0 - b).toString(), 10))", 270 | bitLength: "Number.parseInt(SchemeNumber.plugins.get(\"numberToString\")(SchemeNumber.plugins.get(\"bitLength\")(a), 10, 0), 10)", 271 | pow: "SchemeNumber.plugins.get(\"expt\")(a, SchemeNumber.plugins.get(\"parseExactInteger\")(1, b.toString(), 10))", 272 | gcd: "SchemeNumber.plugins.get(\"gcd\")(a, b)", 273 | floatingPoint: true, 274 | fromNumber: undefined, 275 | toNumber: undefined 276 | }, 277 | Object.assign({}, JavaBigInteger, { 278 | url: "https://github.com/node-modules/node-biginteger", 279 | source: "https://raw.githubusercontent.com/node-modules/node-biginteger/master/lib/BigInteger.js", 280 | parseInt: "BigInteger.fromString(a, b)", 281 | fromNumber: "BigInteger.fromLong(a)", 282 | gcd: undefined, 283 | toNumber: "a.longValue()" 284 | }), 285 | { 286 | url: "https://github.com/GoogleChromeLabs/jsbi", 287 | source: "https://raw.githubusercontent.com/GoogleChromeLabs/jsbi/master/jsbi.mjs", 288 | add: "JSBI.add(a, b)", 289 | subtract: "JSBI.subtract(a, b)", 290 | multiply: "JSBI.multiply(a, b)", 291 | divide: "JSBI.divide(a, b)", 292 | remainder: "JSBI.remainder(a, b)", 293 | negate: "JSBI.unaryMinus(a)", 294 | compareTo: "(JSBI.lessThan(a, b) ? -1 : (JSBI.lessThan(b, a) ? +1 : 0))", 295 | parseInt: "JSBI.parseInt(a, b)", 296 | toString: "a.toString(b)", 297 | and: "JSBI.bitwiseAnd(a, b)", 298 | or: "JSBI.bitwiseOr(a, b)", 299 | xor: "JSBI.bitwiseXor(a, b)", 300 | not: "JSBI.bitwiseNot(a)", 301 | shiftLeft: "JSBI.leftShift(a, JSBI.BigInt(b))", 302 | shiftRight: "JSBI.signedRightShift(a, JSBI.BigInt(b))", 303 | bitLength: "", 304 | pow: "JSBI.exponentiate(a, JSBI.BigInt(b))", 305 | setup: function () { 306 | JSBI.parseInt = function (string, radix) { 307 | var prefix = radix === 10 ? "" : (radix === 2 ? "0b" : (radix === 8 ? "0o" : (radix === 16 ? "0x" : ""))); 308 | return JSBI.BigInt(prefix === "" ? string : prefix + string); 309 | }; 310 | }, 311 | fromNumber: "JSBI.BigInt(a)", 312 | toNumber: "JSBI.toNumber(a)", 313 | mod: "", 314 | modPow: "", 315 | modInverse: "", 316 | gcd: "", 317 | floatingPoint: false 318 | }, 319 | { 320 | url: "https://github.com/vukicevic/crunch", 321 | source: "https://raw.githubusercontent.com/vukicevic/crunch/master/crunch.js", 322 | add: "crunch.add(a, b)", 323 | subtract: "crunch.sub(a, b)", 324 | multiply: "crunch.mul(a, b)", 325 | divide: "crunch.div(a, b)", 326 | remainder: "crunch.mod(a, b)", 327 | negate: "crunch.mul(crunch.parse(\"-1\"), a)", 328 | compareTo: "crunch.compare(a, b)", 329 | parseInt: "crunch.parse(a)", 330 | toString: "(a.length === 0 ? \"0\" : (a[0] < 0 ? \"-\" + crunch.stringify(crunch.mul(crunch.parse(\"-1\"), a)) : crunch.stringify(a)))", 331 | and: "crunch.and(a, b)", 332 | or: "crunch.or(a, b)", 333 | xor: "crunch.xor(a, b)", 334 | not: "crunch.not(a)", 335 | shiftLeft: "crunch.leftShift(a, b)", 336 | shiftRight: "crunch.rightShift(a, b)", 337 | bitLength: "", 338 | pow: "crunch.exp(a, b)", 339 | setup: function () { 340 | self.crunch = self.Crunch(); 341 | }, 342 | fromNumber: "", 343 | toNumber: "", 344 | mod: "crunch.mod(a, b)", 345 | modPow: "crunch.exp(a, b, c)", 346 | modInverse: "crunch.inv(a, b)", 347 | //gcd: "crunch.gcd(a, b)", 348 | floatingPoint: false 349 | }, 350 | Object.assign({}, MikeMclBigNumber, { 351 | url: "https://github.com/MikeMcl/bignumber.js", 352 | source: "https://raw.githubusercontent.com/MikeMcl/bignumber.js/master/bignumber.js", 353 | compareTo: "a.comparedTo(b)", 354 | setup: function () { 355 | //BigNumber.config({precision: 2048, rounding: 1, toExpPos: 2048}); 356 | //BigNumber.DP = 0; 357 | //BigNumber.RM = 0; 358 | //BigNumber.E_POS = 2048; 359 | BigNumber.config({DECIMAL_PLACES: 0, ROUNDING_MODE: 1, EXPONENTIAL_AT: 2048}); 360 | } 361 | }), 362 | Object.assign({}, MikeMclBigNumber, { 363 | url: "https://github.com/MikeMcl/big.js", 364 | source: "https://raw.githubusercontent.com/MikeMcl/big.js/master/big.js", 365 | parseInt: "(b === 10 ? new BigNumber(a, b) : new BigNumber(\"0\"))", 366 | toString: "a.toFixed(0)", 367 | setup: function () { 368 | self.BigNumber = self.Big; 369 | //BigNumber.config({precision: 2048, rounding: 1, toExpPos: 2048}); 370 | BigNumber.DP = 0; 371 | BigNumber.RM = 0; 372 | BigNumber.E_POS = 2048; 373 | //BigNumber.config({DECIMAL_PLACES: 0, ROUNDING_MODE: 1, EXPONENTIAL_AT: 2048}); 374 | var MINUS_ONE = new BigNumber("-1", 10); 375 | BigNumber.prototype.neg = function () { 376 | return MINUS_ONE.times(this); 377 | }; 378 | } 379 | }), 380 | Object.assign({}, MikeMclBigNumber, { 381 | url: "https://github.com/MikeMcl/decimal.js", 382 | parseInt: "(b === 10 ? new BigNumber(a, b) : new BigNumber(\"0\"))", 383 | source: "https://raw.githubusercontent.com/MikeMcl/decimal.js/master/decimal.js", 384 | divide: "a.div(b).trunc()", 385 | remainder: "a.minus(a.div(b).trunc().times(b))", 386 | setup: function () { 387 | self.BigNumber = self.Decimal; 388 | BigNumber.config({precision: 2048, rounding: 1, toExpPos: 2048}); 389 | } 390 | }), 391 | Object.assign({}, MikeMclBigNumber, { 392 | url: "https://github.com/MikeMcl/decimal.js-light", 393 | parseInt: "(b === 10 ? new BigNumber(a, b) : new BigNumber(\"0\"))", 394 | source: "https://raw.githubusercontent.com/MikeMcl/decimal.js/master/decimal.js", 395 | divide: "a.div(b).trunc()", 396 | remainder: "a.minus(a.div(b).trunc().times(b))", 397 | setup: function () { 398 | self.BigNumber = self.Decimal; 399 | BigNumber.set({precision: 2048, rounding: BigNumber.ROUND_DOWN, toExpPos: 2048}); 400 | } 401 | }), 402 | Object.assign({}, JavaBigInteger, { 403 | url: "https://github.com/peterolson/BigInteger.js", 404 | source: "https://rawgit.com/peterolson/BigInteger.js/master/BigInteger.js", 405 | parseInt: "bigInt(a, b === 10 ? undefined : b)", 406 | modInverse: "a.modInv(b)", 407 | gcd: "bigInt.gcd(a, b)", 408 | fromNumber: "bigInt(a)", 409 | toNumber: "a.toJSNumber()" 410 | }), 411 | Object.assign({}, JavaBigInteger, { 412 | url: "https://github.com/silentmatt/javascript-biginteger", 413 | source: "https://rawgit.com/silentmatt/javascript-biginteger/master/biginteger.js", 414 | parseInt: "BigInteger.parse(a, b)", 415 | compareTo: "a.compare(b)", 416 | fromNumber: "BigInteger(a)", 417 | toNumber: "a.toJSValue()" 418 | }), 419 | Object.assign({}, JavaBigInteger, { 420 | url: "http://www-cs-students.stanford.edu/~tjw/jsbn/", 421 | source: "https://raw.githubusercontent.com/jasondavies/jsbn/master/jsbn.js https://raw.githubusercontent.com/jasondavies/jsbn/master/jsbn2.js", 422 | fromNumber: "(globalThis.tmp = new BigInteger(), globalThis.tmp.fromInt(a), globalThis.tmp)", 423 | toNumber: "a.intValue()" 424 | }), 425 | Object.assign({}, JavaBigInteger, { 426 | url: "https://github.com/chromium/octane/blob/master/crypto.js", 427 | source: "https://raw.githubusercontent.com/chromium/octane/master/crypto.js", 428 | }), 429 | { 430 | url: "https://github.com/Yaffle/BigInteger", 431 | source: "https://rawgit.com/Yaffle/BigInteger/master/BigInteger.js", 432 | add: "BigInteger.add(a, b)", 433 | subtract: "BigInteger.subtract(a, b)", 434 | multiply: "BigInteger.multiply(a, b)", 435 | divide: "BigInteger.divide(a, b)", 436 | remainder: "BigInteger.remainder(a, b)", 437 | negate: "BigInteger.unaryMinus(a)", 438 | compareTo: "(BigInteger.lessThan(a, b) ? -1 : (BigInteger.lessThan(b, a) ? +1 : 0))", 439 | parseInt: "BigInteger.parseInt(a, b)", 440 | toString: "a.toString(b)", 441 | and: "", 442 | or: "", 443 | xor: "", 444 | not: "", 445 | shiftLeft: "BigInteger.leftShift(a, b)", 446 | shiftRight: "BigInteger.signedRightShift(a, b)", 447 | bitLength: "", 448 | pow: "BigInteger.exponentiate(a, BigInteger.BigInt(b))", 449 | fromNumber: "BigInteger.BigInt(a)", 450 | toNumber: "BigInteger.toNumber(a)", 451 | mod: "", 452 | modInverse: "", 453 | modPow: "", 454 | gcd: "", 455 | setup: function () { 456 | BigInteger.parseInt = function (string, radix) { 457 | var prefix = radix === 10 ? "" : (radix === 2 ? "0b" : (radix === 8 ? "0o" : (radix === 16 ? "0x" : ""))); 458 | return BigInteger.BigInt(prefix === "" ? string : prefix + string); 459 | }; 460 | }, 461 | floatingPoint: false 462 | }, 463 | { 464 | url: "https://rawgit.com/Yaffle/BigInteger/master/SmallBigInt.js", 465 | source: "https://rawgit.com/Yaffle/BigInteger/master/SmallBigInt.js", 466 | add: "SmallBigInt.add(a, b)", 467 | subtract: "SmallBigInt.subtract(a, b)", 468 | multiply: "SmallBigInt.multiply(a, b)", 469 | divide: "SmallBigInt.divide(a, b)", 470 | remainder: "SmallBigInt.remainder(a, b)", 471 | negate: "SmallBigInt.unaryMinus(a)", 472 | compareTo: "(SmallBigInt.lessThan(a, b) ? -1 : (SmallBigInt.lessThan(b, a) ? +1 : 0))", 473 | parseInt: "SmallBigInt.parseInt(a, b)", 474 | toString: "a.toString(b)", 475 | and: "", 476 | or: "", 477 | xor: "", 478 | not: "", 479 | shiftLeft: "SmallBigInt.leftShift(a, b)", 480 | shiftRight: "SmallBigInt.signedRightShift(a, b)", 481 | bitLength: "", 482 | pow: "SmallBigInt.exponentiate(a, SmallBigInt.BigInt(b))", 483 | fromNumber: "SmallBigInt.BigInt(a)", 484 | toNumber: "SmallBigInt.toNumber(a)", 485 | mod: "", 486 | modInverse: "", 487 | modPow: "", 488 | gcd: "", 489 | setup: function () { 490 | SmallBigInt.parseInt = function (string, radix) { 491 | var prefix = radix === 10 ? "" : (radix === 2 ? "0b" : (radix === 8 ? "0o" : (radix === 16 ? "0x" : ""))); 492 | return SmallBigInt.BigInt(prefix === "" ? string : prefix + string); 493 | }; 494 | }, 495 | floatingPoint: false 496 | }, 497 | { 498 | url: "data:text/plain,bigint", // https://tc39.github.io/proposal-bigint/ 499 | source: "data:application/javascript,%3B", 500 | add: "a + b", 501 | subtract: "a - b", 502 | multiply: "a * b", 503 | divide: "a / b", 504 | remainder: "a % b", 505 | negate: "-a", 506 | compareTo: "(a < b ? -1 : (b < a ? +1 : 0))", 507 | parseInt: "BigInt.parseInt(a, b)", 508 | toString: "a.toString(b)", 509 | and: "a & b", 510 | or: "a | b", 511 | xor: "a ^ b", 512 | not: "~a", 513 | shiftLeft: "a << BigInt(b)", 514 | shiftRight: "a >> BigInt(b)", 515 | bitLength: "", 516 | pow: typeof self !== "undefined" && self.BigInt != undefined ? "a**BigInt(b)" : undefined, 517 | setup: undefined, 518 | fromNumber: "BigInt(a)", 519 | toNumber: "Number(a)", 520 | floatingPoint: false, 521 | setup: function () { 522 | if (self.BigInt != undefined) { 523 | self.BigInt.parseInt = function (string, radix) { 524 | if (radix === 2) { 525 | return self.BigInt("0b" + string); 526 | } else if (radix === 8) { 527 | return self.BigInt("0o" + string); 528 | } else if (radix === 10) { 529 | return self.BigInt("" + string); 530 | } else if (radix === 16) { 531 | return self.BigInt("0x" + string); 532 | } 533 | throw new RangeError(); 534 | }; 535 | } 536 | } 537 | }, 538 | { 539 | url: "data:text/plain,number", 540 | source: "data:application/javascript,%3B", 541 | add: "a + b", 542 | subtract: "a - b", 543 | multiply: "0 + a * b", 544 | divide: "0 + Math.trunc(a / b)", 545 | remainder: "0 + a % b", 546 | negate: "0 - a", 547 | compareTo: "(a < b ? -1 : (b < a ? +1 : 0))", 548 | parseInt: "Number.parseInt(a, b)", 549 | toString: "a.toString(b)", 550 | and: "a & b", 551 | or: "a | b", 552 | xor: "a ^ b", 553 | not: "~a", 554 | shiftLeft: "a << b", 555 | shiftRight: "a >> b", 556 | bitLength: "32 - Math.clz32(a)", 557 | pow: "Math.pow(a, b)", 558 | setup: undefined, 559 | fromNumber: "a", 560 | toNumber: "a", 561 | floatingPoint: true 562 | }, 563 | Object.assign({}, JavaBigInteger, { 564 | url: "https://github.com/peteroupc/BigNumber", 565 | source: "https://rawgit.com/peteroupc/BigNumber/master/BigInteger.js", 566 | parseInt: "BigInteger.fromRadixString(a, b)", 567 | toString: "a.toRadixString(b)", 568 | modPow: "a.ModPow(b, c)", 569 | fromNumber: "BigInteger.valueOf(a)", 570 | floatingPoint: true 571 | }), 572 | Object.assign({}, NodeBigInteger, { 573 | url: "https://github.com/indutny/bn.js", 574 | source: "https://rawgit.com/indutny/bn.js/master/lib/bn.js", 575 | modPow: "BN.modPow(a, b, c)", 576 | pow: "BN.pow(a, b)", 577 | setup: function () { 578 | self.BN = self.module.exports; 579 | self.BN.pow = function (x, n) { 580 | return x.pow(new BN(n.toString(), 10)); 581 | }; 582 | self.BN.modPow = function (a, b, c) { 583 | var ctx = BN.mont(new BN(c)); 584 | return a.toRed(ctx).redPow(b).fromRed(); 585 | }; 586 | } 587 | }), 588 | Object.assign({}, NodeBigInteger, { 589 | url: "https://github.com/dankogai/js-math-bigint", 590 | source: "https://rawgit.com/dankogai/js-math-bigint/master/bigint.js", 591 | parseInt: "Math.BigInt.parseInt(a, b)", 592 | toString: "a.toStringBase(b)", 593 | setup: function () { 594 | Math.BigInt.parseInt = function (string, radix) { 595 | radix = radix == undefined ? 10 : radix; 596 | string = string.replace(/^(\-?)0*/, "$1"); 597 | string = string === "-" || string === "" ? "0" : string; 598 | var prefix = ""; 599 | if (radix === 16) { 600 | prefix = "0x"; 601 | } 602 | if (radix === 8) { 603 | prefix = "0o"; 604 | } 605 | if (radix === 2) { 606 | prefix = "0b"; 607 | } 608 | if (prefix !== "") { 609 | string = string.replace(/^(\-)?/, "$1" + prefix); 610 | } 611 | return self.bigint(string); 612 | }; 613 | }, 614 | fromNumber: "self.bigint(a)" 615 | }), 616 | Object.assign({}, NodeBigInteger, { 617 | url: "https://github.com/defunctzombie/int", 618 | source: "https://raw.githubusercontent.com/defunctzombie/int/master/int.js", 619 | parseInt: "new Int(a, b)", 620 | pow: "a.pow2(b)", 621 | fromNumber: "Int(a)" 622 | }), 623 | Object.assign({}, JavaBigInteger, { 624 | url: "https://github.com/dtrebbien/BigDecimal.js", 625 | source: "https://rawgit.com/dtrebbien/BigDecimal.js/master/build/BigDecimal-all-last.js", 626 | parseInt: "(b === 10 ? new BigDecimal(a) : new BigDecimal(\"0\"))", 627 | pow: "a.pow(new BigDecimal(b.toString()))", 628 | setup: function () { 629 | var BigDecimal = self.BigDecimal; 630 | var divideFunction = BigDecimal.prototype.divide; 631 | var mc = new MathContext(0, MathContext.prototype.PLAIN, false, BigDecimal.ROUND_DOWN); 632 | BigDecimal.prototype.divide = function (x) { 633 | return divideFunction.call(this, x, mc); 634 | }; 635 | }, 636 | floatingPoint: true 637 | }), 638 | Object.assign({}, JavaBigInteger, { 639 | url: "https://github.com/iriscouch/bigdecimal.js", 640 | source: "http://jhs.iriscouch.com/demo/_design/bigdecimal/bigdecimal.js", 641 | floatingPoint: true 642 | }), 643 | Object.assign({}, JavaBigInteger, { 644 | url: "http://ofmind.net/doc/hapint", 645 | source: "http://ofmind.net/script/hapint/hapint.es", 646 | parseInt: "new self.Math.BigInt(a, b)", 647 | fromNumber: "self.Math.BigInt.valueOf(a)" 648 | }), 649 | Object.assign({}, JavaBigInteger, { 650 | url: "https://github.com/tabatkins/bignum", 651 | source: "https://raw.githubusercontent.com/tabatkins/bignum/master/Z.js", 652 | add: "Z.add(a, b)", 653 | subtract: "Z.sub(a, b)", 654 | multiply: "Z.mul(a, b)", 655 | divide: "Z.div(a, b)", 656 | remainder: "Z.mod(a, b)", 657 | negate: "a.negate()", 658 | compareTo: "(Z.lt(a, b) ? -1 : (Z.lt(b, a) ? +1 : 0))", 659 | parseInt: "new Z(a, b)", 660 | toString: "a.toString(b)", 661 | and: "", 662 | or: "", 663 | xor: "", 664 | not: "", 665 | shiftLeft: "", 666 | shiftRight: "", 667 | bitLength: "", 668 | pow: "Z.pow(a, b)", 669 | fromNumber: "new Z(a)", 670 | toNumber: "a.toNum()", 671 | mod: "", 672 | modInverse: "", 673 | modPow: "", 674 | setup: function () { 675 | //TODO: !!! 676 | Z.mod = function (a, b) { 677 | return Z.sub(a, Z.mul(Z.div(a, b), b)); 678 | }; 679 | }, 680 | floatingPoint: false 681 | }) 682 | ]; 683 | 684 | if (this.window != undefined && this.window.opera != undefined) { 685 | libs = libs.filter(function (x) { 686 | return x.url !== "https://github.com/node-modules/node-biginteger"; 687 | }); 688 | } 689 | 690 | var i = -1; 691 | while (++i < libs.length) { 692 | if (libs[i].url.indexOf("data:") === -1) { 693 | libs[i].src = "./libs/" + libs[i].url.replace(/[^a-zA-Z0-9]/g, "_") + ".js"; 694 | } else { 695 | libs[i].src = libs[i].url; 696 | } 697 | } 698 | 699 | if (typeof self === "undefined") { 700 | libs.forEach(function (x, index) { 701 | setTimeout(function () { 702 | var https = require("https"); 703 | var http = require("http"); 704 | var fs = require("fs"); 705 | var fileData = ""; 706 | var sources = x.source.split(" "); 707 | var i = 0; 708 | var download = function () { 709 | if (i < sources.length) { 710 | var source = sources[i]; 711 | i += 1; 712 | console.log(x.source); 713 | 714 | if (source.slice(0, 5) === "data:") { 715 | download(); 716 | } else { 717 | (source.slice(0, 6) === "https:" ? https : http).get(source, function (response) { 718 | if (response.statusCode === 200) { 719 | response.on("data", function (chunk) { 720 | fileData += chunk; 721 | }); 722 | response.on("end", function () { 723 | download(); 724 | }); 725 | } 726 | }).on("error", function (error) { 727 | console.log(error); 728 | }); 729 | } 730 | } else { 731 | var fs = require("fs"); 732 | fs.writeFile(x.src, fileData, function (error) { 733 | if (error != undefined) { 734 | return console.log(error); 735 | } 736 | }); 737 | } 738 | }; 739 | download(); 740 | 741 | }, index * 300); 742 | }); 743 | } else { 744 | // will not work with jtobey 745 | //this.require = function () { 746 | // return {}; 747 | //}; 748 | //iriscouch 749 | if (this.window == undefined) { 750 | this.window = this; 751 | } 752 | this.module = this; 753 | } 754 | 755 | this.libs = libs; 756 | -------------------------------------------------------------------------------- /benchmark/libs/https___github_com_MikeMcl_big_js.js: -------------------------------------------------------------------------------- 1 | /* 2 | * big.js v6.2.1 3 | * A small, fast, easy-to-use library for arbitrary-precision decimal arithmetic. 4 | * Copyright (c) 2022 Michael Mclaughlin 5 | * https://github.com/MikeMcl/big.js/LICENCE.md 6 | */ 7 | ;(function (GLOBAL) { 8 | 'use strict'; 9 | var Big, 10 | 11 | 12 | /************************************** EDITABLE DEFAULTS *****************************************/ 13 | 14 | 15 | // The default values below must be integers within the stated ranges. 16 | 17 | /* 18 | * The maximum number of decimal places (DP) of the results of operations involving division: 19 | * div and sqrt, and pow with negative exponents. 20 | */ 21 | DP = 20, // 0 to MAX_DP 22 | 23 | /* 24 | * The rounding mode (RM) used when rounding to the above decimal places. 25 | * 26 | * 0 Towards zero (i.e. truncate, no rounding). (ROUND_DOWN) 27 | * 1 To nearest neighbour. If equidistant, round up. (ROUND_HALF_UP) 28 | * 2 To nearest neighbour. If equidistant, to even. (ROUND_HALF_EVEN) 29 | * 3 Away from zero. (ROUND_UP) 30 | */ 31 | RM = 1, // 0, 1, 2 or 3 32 | 33 | // The maximum value of DP and Big.DP. 34 | MAX_DP = 1E6, // 0 to 1000000 35 | 36 | // The maximum magnitude of the exponent argument to the pow method. 37 | MAX_POWER = 1E6, // 1 to 1000000 38 | 39 | /* 40 | * The negative exponent (NE) at and beneath which toString returns exponential notation. 41 | * (JavaScript numbers: -7) 42 | * -1000000 is the minimum recommended exponent value of a Big. 43 | */ 44 | NE = -7, // 0 to -1000000 45 | 46 | /* 47 | * The positive exponent (PE) at and above which toString returns exponential notation. 48 | * (JavaScript numbers: 21) 49 | * 1000000 is the maximum recommended exponent value of a Big, but this limit is not enforced. 50 | */ 51 | PE = 21, // 0 to 1000000 52 | 53 | /* 54 | * When true, an error will be thrown if a primitive number is passed to the Big constructor, 55 | * or if valueOf is called, or if toNumber is called on a Big which cannot be converted to a 56 | * primitive number without a loss of precision. 57 | */ 58 | STRICT = false, // true or false 59 | 60 | 61 | /**************************************************************************************************/ 62 | 63 | 64 | // Error messages. 65 | NAME = '[big.js] ', 66 | INVALID = NAME + 'Invalid ', 67 | INVALID_DP = INVALID + 'decimal places', 68 | INVALID_RM = INVALID + 'rounding mode', 69 | DIV_BY_ZERO = NAME + 'Division by zero', 70 | 71 | // The shared prototype object. 72 | P = {}, 73 | UNDEFINED = void 0, 74 | NUMERIC = /^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i; 75 | 76 | 77 | /* 78 | * Create and return a Big constructor. 79 | */ 80 | function _Big_() { 81 | 82 | /* 83 | * The Big constructor and exported function. 84 | * Create and return a new instance of a Big number object. 85 | * 86 | * n {number|string|Big} A numeric value. 87 | */ 88 | function Big(n) { 89 | var x = this; 90 | 91 | // Enable constructor usage without new. 92 | if (!(x instanceof Big)) return n === UNDEFINED ? _Big_() : new Big(n); 93 | 94 | // Duplicate. 95 | if (n instanceof Big) { 96 | x.s = n.s; 97 | x.e = n.e; 98 | x.c = n.c.slice(); 99 | } else { 100 | if (typeof n !== 'string') { 101 | if (Big.strict === true && typeof n !== 'bigint') { 102 | throw TypeError(INVALID + 'value'); 103 | } 104 | 105 | // Minus zero? 106 | n = n === 0 && 1 / n < 0 ? '-0' : String(n); 107 | } 108 | 109 | parse(x, n); 110 | } 111 | 112 | // Retain a reference to this Big constructor. 113 | // Shadow Big.prototype.constructor which points to Object. 114 | x.constructor = Big; 115 | } 116 | 117 | Big.prototype = P; 118 | Big.DP = DP; 119 | Big.RM = RM; 120 | Big.NE = NE; 121 | Big.PE = PE; 122 | Big.strict = STRICT; 123 | Big.roundDown = 0; 124 | Big.roundHalfUp = 1; 125 | Big.roundHalfEven = 2; 126 | Big.roundUp = 3; 127 | 128 | return Big; 129 | } 130 | 131 | 132 | /* 133 | * Parse the number or string value passed to a Big constructor. 134 | * 135 | * x {Big} A Big number instance. 136 | * n {number|string} A numeric value. 137 | */ 138 | function parse(x, n) { 139 | var e, i, nl; 140 | 141 | if (!NUMERIC.test(n)) { 142 | throw Error(INVALID + 'number'); 143 | } 144 | 145 | // Determine sign. 146 | x.s = n.charAt(0) == '-' ? (n = n.slice(1), -1) : 1; 147 | 148 | // Decimal point? 149 | if ((e = n.indexOf('.')) > -1) n = n.replace('.', ''); 150 | 151 | // Exponential form? 152 | if ((i = n.search(/e/i)) > 0) { 153 | 154 | // Determine exponent. 155 | if (e < 0) e = i; 156 | e += +n.slice(i + 1); 157 | n = n.substring(0, i); 158 | } else if (e < 0) { 159 | 160 | // Integer. 161 | e = n.length; 162 | } 163 | 164 | nl = n.length; 165 | 166 | // Determine leading zeros. 167 | for (i = 0; i < nl && n.charAt(i) == '0';) ++i; 168 | 169 | if (i == nl) { 170 | 171 | // Zero. 172 | x.c = [x.e = 0]; 173 | } else { 174 | 175 | // Determine trailing zeros. 176 | for (; nl > 0 && n.charAt(--nl) == '0';); 177 | x.e = e - i - 1; 178 | x.c = []; 179 | 180 | // Convert string to array of digits without leading/trailing zeros. 181 | for (e = 0; i <= nl;) x.c[e++] = +n.charAt(i++); 182 | } 183 | 184 | return x; 185 | } 186 | 187 | 188 | /* 189 | * Round Big x to a maximum of sd significant digits using rounding mode rm. 190 | * 191 | * x {Big} The Big to round. 192 | * sd {number} Significant digits: integer, 0 to MAX_DP inclusive. 193 | * rm {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). 194 | * [more] {boolean} Whether the result of division was truncated. 195 | */ 196 | function round(x, sd, rm, more) { 197 | var xc = x.c; 198 | 199 | if (rm === UNDEFINED) rm = x.constructor.RM; 200 | if (rm !== 0 && rm !== 1 && rm !== 2 && rm !== 3) { 201 | throw Error(INVALID_RM); 202 | } 203 | 204 | if (sd < 1) { 205 | more = 206 | rm === 3 && (more || !!xc[0]) || sd === 0 && ( 207 | rm === 1 && xc[0] >= 5 || 208 | rm === 2 && (xc[0] > 5 || xc[0] === 5 && (more || xc[1] !== UNDEFINED)) 209 | ); 210 | 211 | xc.length = 1; 212 | 213 | if (more) { 214 | 215 | // 1, 0.1, 0.01, 0.001, 0.0001 etc. 216 | x.e = x.e - sd + 1; 217 | xc[0] = 1; 218 | } else { 219 | 220 | // Zero. 221 | xc[0] = x.e = 0; 222 | } 223 | } else if (sd < xc.length) { 224 | 225 | // xc[sd] is the digit after the digit that may be rounded up. 226 | more = 227 | rm === 1 && xc[sd] >= 5 || 228 | rm === 2 && (xc[sd] > 5 || xc[sd] === 5 && 229 | (more || xc[sd + 1] !== UNDEFINED || xc[sd - 1] & 1)) || 230 | rm === 3 && (more || !!xc[0]); 231 | 232 | // Remove any digits after the required precision. 233 | xc.length = sd; 234 | 235 | // Round up? 236 | if (more) { 237 | 238 | // Rounding up may mean the previous digit has to be rounded up. 239 | for (; ++xc[--sd] > 9;) { 240 | xc[sd] = 0; 241 | if (sd === 0) { 242 | ++x.e; 243 | xc.unshift(1); 244 | break; 245 | } 246 | } 247 | } 248 | 249 | // Remove trailing zeros. 250 | for (sd = xc.length; !xc[--sd];) xc.pop(); 251 | } 252 | 253 | return x; 254 | } 255 | 256 | 257 | /* 258 | * Return a string representing the value of Big x in normal or exponential notation. 259 | * Handles P.toExponential, P.toFixed, P.toJSON, P.toPrecision, P.toString and P.valueOf. 260 | */ 261 | function stringify(x, doExponential, isNonzero) { 262 | var e = x.e, 263 | s = x.c.join(''), 264 | n = s.length; 265 | 266 | // Exponential notation? 267 | if (doExponential) { 268 | s = s.charAt(0) + (n > 1 ? '.' + s.slice(1) : '') + (e < 0 ? 'e' : 'e+') + e; 269 | 270 | // Normal notation. 271 | } else if (e < 0) { 272 | for (; ++e;) s = '0' + s; 273 | s = '0.' + s; 274 | } else if (e > 0) { 275 | if (++e > n) { 276 | for (e -= n; e--;) s += '0'; 277 | } else if (e < n) { 278 | s = s.slice(0, e) + '.' + s.slice(e); 279 | } 280 | } else if (n > 1) { 281 | s = s.charAt(0) + '.' + s.slice(1); 282 | } 283 | 284 | return x.s < 0 && isNonzero ? '-' + s : s; 285 | } 286 | 287 | 288 | // Prototype/instance methods 289 | 290 | 291 | /* 292 | * Return a new Big whose value is the absolute value of this Big. 293 | */ 294 | P.abs = function () { 295 | var x = new this.constructor(this); 296 | x.s = 1; 297 | return x; 298 | }; 299 | 300 | 301 | /* 302 | * Return 1 if the value of this Big is greater than the value of Big y, 303 | * -1 if the value of this Big is less than the value of Big y, or 304 | * 0 if they have the same value. 305 | */ 306 | P.cmp = function (y) { 307 | var isneg, 308 | x = this, 309 | xc = x.c, 310 | yc = (y = new x.constructor(y)).c, 311 | i = x.s, 312 | j = y.s, 313 | k = x.e, 314 | l = y.e; 315 | 316 | // Either zero? 317 | if (!xc[0] || !yc[0]) return !xc[0] ? !yc[0] ? 0 : -j : i; 318 | 319 | // Signs differ? 320 | if (i != j) return i; 321 | 322 | isneg = i < 0; 323 | 324 | // Compare exponents. 325 | if (k != l) return k > l ^ isneg ? 1 : -1; 326 | 327 | j = (k = xc.length) < (l = yc.length) ? k : l; 328 | 329 | // Compare digit by digit. 330 | for (i = -1; ++i < j;) { 331 | if (xc[i] != yc[i]) return xc[i] > yc[i] ^ isneg ? 1 : -1; 332 | } 333 | 334 | // Compare lengths. 335 | return k == l ? 0 : k > l ^ isneg ? 1 : -1; 336 | }; 337 | 338 | 339 | /* 340 | * Return a new Big whose value is the value of this Big divided by the value of Big y, rounded, 341 | * if necessary, to a maximum of Big.DP decimal places using rounding mode Big.RM. 342 | */ 343 | P.div = function (y) { 344 | var x = this, 345 | Big = x.constructor, 346 | a = x.c, // dividend 347 | b = (y = new Big(y)).c, // divisor 348 | k = x.s == y.s ? 1 : -1, 349 | dp = Big.DP; 350 | 351 | if (dp !== ~~dp || dp < 0 || dp > MAX_DP) { 352 | throw Error(INVALID_DP); 353 | } 354 | 355 | // Divisor is zero? 356 | if (!b[0]) { 357 | throw Error(DIV_BY_ZERO); 358 | } 359 | 360 | // Dividend is 0? Return +-0. 361 | if (!a[0]) { 362 | y.s = k; 363 | y.c = [y.e = 0]; 364 | return y; 365 | } 366 | 367 | var bl, bt, n, cmp, ri, 368 | bz = b.slice(), 369 | ai = bl = b.length, 370 | al = a.length, 371 | r = a.slice(0, bl), // remainder 372 | rl = r.length, 373 | q = y, // quotient 374 | qc = q.c = [], 375 | qi = 0, 376 | p = dp + (q.e = x.e - y.e) + 1; // precision of the result 377 | 378 | q.s = k; 379 | k = p < 0 ? 0 : p; 380 | 381 | // Create version of divisor with leading zero. 382 | bz.unshift(0); 383 | 384 | // Add zeros to make remainder as long as divisor. 385 | for (; rl++ < bl;) r.push(0); 386 | 387 | do { 388 | 389 | // n is how many times the divisor goes into current remainder. 390 | for (n = 0; n < 10; n++) { 391 | 392 | // Compare divisor and remainder. 393 | if (bl != (rl = r.length)) { 394 | cmp = bl > rl ? 1 : -1; 395 | } else { 396 | for (ri = -1, cmp = 0; ++ri < bl;) { 397 | if (b[ri] != r[ri]) { 398 | cmp = b[ri] > r[ri] ? 1 : -1; 399 | break; 400 | } 401 | } 402 | } 403 | 404 | // If divisor < remainder, subtract divisor from remainder. 405 | if (cmp < 0) { 406 | 407 | // Remainder can't be more than 1 digit longer than divisor. 408 | // Equalise lengths using divisor with extra leading zero? 409 | for (bt = rl == bl ? b : bz; rl;) { 410 | if (r[--rl] < bt[rl]) { 411 | ri = rl; 412 | for (; ri && !r[--ri];) r[ri] = 9; 413 | --r[ri]; 414 | r[rl] += 10; 415 | } 416 | r[rl] -= bt[rl]; 417 | } 418 | 419 | for (; !r[0];) r.shift(); 420 | } else { 421 | break; 422 | } 423 | } 424 | 425 | // Add the digit n to the result array. 426 | qc[qi++] = cmp ? n : ++n; 427 | 428 | // Update the remainder. 429 | if (r[0] && cmp) r[rl] = a[ai] || 0; 430 | else r = [a[ai]]; 431 | 432 | } while ((ai++ < al || r[0] !== UNDEFINED) && k--); 433 | 434 | // Leading zero? Do not remove if result is simply zero (qi == 1). 435 | if (!qc[0] && qi != 1) { 436 | 437 | // There can't be more than one zero. 438 | qc.shift(); 439 | q.e--; 440 | p--; 441 | } 442 | 443 | // Round? 444 | if (qi > p) round(q, p, Big.RM, r[0] !== UNDEFINED); 445 | 446 | return q; 447 | }; 448 | 449 | 450 | /* 451 | * Return true if the value of this Big is equal to the value of Big y, otherwise return false. 452 | */ 453 | P.eq = function (y) { 454 | return this.cmp(y) === 0; 455 | }; 456 | 457 | 458 | /* 459 | * Return true if the value of this Big is greater than the value of Big y, otherwise return 460 | * false. 461 | */ 462 | P.gt = function (y) { 463 | return this.cmp(y) > 0; 464 | }; 465 | 466 | 467 | /* 468 | * Return true if the value of this Big is greater than or equal to the value of Big y, otherwise 469 | * return false. 470 | */ 471 | P.gte = function (y) { 472 | return this.cmp(y) > -1; 473 | }; 474 | 475 | 476 | /* 477 | * Return true if the value of this Big is less than the value of Big y, otherwise return false. 478 | */ 479 | P.lt = function (y) { 480 | return this.cmp(y) < 0; 481 | }; 482 | 483 | 484 | /* 485 | * Return true if the value of this Big is less than or equal to the value of Big y, otherwise 486 | * return false. 487 | */ 488 | P.lte = function (y) { 489 | return this.cmp(y) < 1; 490 | }; 491 | 492 | 493 | /* 494 | * Return a new Big whose value is the value of this Big minus the value of Big y. 495 | */ 496 | P.minus = P.sub = function (y) { 497 | var i, j, t, xlty, 498 | x = this, 499 | Big = x.constructor, 500 | a = x.s, 501 | b = (y = new Big(y)).s; 502 | 503 | // Signs differ? 504 | if (a != b) { 505 | y.s = -b; 506 | return x.plus(y); 507 | } 508 | 509 | var xc = x.c.slice(), 510 | xe = x.e, 511 | yc = y.c, 512 | ye = y.e; 513 | 514 | // Either zero? 515 | if (!xc[0] || !yc[0]) { 516 | if (yc[0]) { 517 | y.s = -b; 518 | } else if (xc[0]) { 519 | y = new Big(x); 520 | } else { 521 | y.s = 1; 522 | } 523 | return y; 524 | } 525 | 526 | // Determine which is the bigger number. Prepend zeros to equalise exponents. 527 | if (a = xe - ye) { 528 | 529 | if (xlty = a < 0) { 530 | a = -a; 531 | t = xc; 532 | } else { 533 | ye = xe; 534 | t = yc; 535 | } 536 | 537 | t.reverse(); 538 | for (b = a; b--;) t.push(0); 539 | t.reverse(); 540 | } else { 541 | 542 | // Exponents equal. Check digit by digit. 543 | j = ((xlty = xc.length < yc.length) ? xc : yc).length; 544 | 545 | for (a = b = 0; b < j; b++) { 546 | if (xc[b] != yc[b]) { 547 | xlty = xc[b] < yc[b]; 548 | break; 549 | } 550 | } 551 | } 552 | 553 | // x < y? Point xc to the array of the bigger number. 554 | if (xlty) { 555 | t = xc; 556 | xc = yc; 557 | yc = t; 558 | y.s = -y.s; 559 | } 560 | 561 | /* 562 | * Append zeros to xc if shorter. No need to add zeros to yc if shorter as subtraction only 563 | * needs to start at yc.length. 564 | */ 565 | if ((b = (j = yc.length) - (i = xc.length)) > 0) for (; b--;) xc[i++] = 0; 566 | 567 | // Subtract yc from xc. 568 | for (b = i; j > a;) { 569 | if (xc[--j] < yc[j]) { 570 | for (i = j; i && !xc[--i];) xc[i] = 9; 571 | --xc[i]; 572 | xc[j] += 10; 573 | } 574 | 575 | xc[j] -= yc[j]; 576 | } 577 | 578 | // Remove trailing zeros. 579 | for (; xc[--b] === 0;) xc.pop(); 580 | 581 | // Remove leading zeros and adjust exponent accordingly. 582 | for (; xc[0] === 0;) { 583 | xc.shift(); 584 | --ye; 585 | } 586 | 587 | if (!xc[0]) { 588 | 589 | // n - n = +0 590 | y.s = 1; 591 | 592 | // Result must be zero. 593 | xc = [ye = 0]; 594 | } 595 | 596 | y.c = xc; 597 | y.e = ye; 598 | 599 | return y; 600 | }; 601 | 602 | 603 | /* 604 | * Return a new Big whose value is the value of this Big modulo the value of Big y. 605 | */ 606 | P.mod = function (y) { 607 | var ygtx, 608 | x = this, 609 | Big = x.constructor, 610 | a = x.s, 611 | b = (y = new Big(y)).s; 612 | 613 | if (!y.c[0]) { 614 | throw Error(DIV_BY_ZERO); 615 | } 616 | 617 | x.s = y.s = 1; 618 | ygtx = y.cmp(x) == 1; 619 | x.s = a; 620 | y.s = b; 621 | 622 | if (ygtx) return new Big(x); 623 | 624 | a = Big.DP; 625 | b = Big.RM; 626 | Big.DP = Big.RM = 0; 627 | x = x.div(y); 628 | Big.DP = a; 629 | Big.RM = b; 630 | 631 | return this.minus(x.times(y)); 632 | }; 633 | 634 | 635 | /* 636 | * Return a new Big whose value is the value of this Big negated. 637 | */ 638 | P.neg = function () { 639 | var x = new this.constructor(this); 640 | x.s = -x.s; 641 | return x; 642 | }; 643 | 644 | 645 | /* 646 | * Return a new Big whose value is the value of this Big plus the value of Big y. 647 | */ 648 | P.plus = P.add = function (y) { 649 | var e, k, t, 650 | x = this, 651 | Big = x.constructor; 652 | 653 | y = new Big(y); 654 | 655 | // Signs differ? 656 | if (x.s != y.s) { 657 | y.s = -y.s; 658 | return x.minus(y); 659 | } 660 | 661 | var xe = x.e, 662 | xc = x.c, 663 | ye = y.e, 664 | yc = y.c; 665 | 666 | // Either zero? 667 | if (!xc[0] || !yc[0]) { 668 | if (!yc[0]) { 669 | if (xc[0]) { 670 | y = new Big(x); 671 | } else { 672 | y.s = x.s; 673 | } 674 | } 675 | return y; 676 | } 677 | 678 | xc = xc.slice(); 679 | 680 | // Prepend zeros to equalise exponents. 681 | // Note: reverse faster than unshifts. 682 | if (e = xe - ye) { 683 | if (e > 0) { 684 | ye = xe; 685 | t = yc; 686 | } else { 687 | e = -e; 688 | t = xc; 689 | } 690 | 691 | t.reverse(); 692 | for (; e--;) t.push(0); 693 | t.reverse(); 694 | } 695 | 696 | // Point xc to the longer array. 697 | if (xc.length - yc.length < 0) { 698 | t = yc; 699 | yc = xc; 700 | xc = t; 701 | } 702 | 703 | e = yc.length; 704 | 705 | // Only start adding at yc.length - 1 as the further digits of xc can be left as they are. 706 | for (k = 0; e; xc[e] %= 10) k = (xc[--e] = xc[e] + yc[e] + k) / 10 | 0; 707 | 708 | // No need to check for zero, as +x + +y != 0 && -x + -y != 0 709 | 710 | if (k) { 711 | xc.unshift(k); 712 | ++ye; 713 | } 714 | 715 | // Remove trailing zeros. 716 | for (e = xc.length; xc[--e] === 0;) xc.pop(); 717 | 718 | y.c = xc; 719 | y.e = ye; 720 | 721 | return y; 722 | }; 723 | 724 | 725 | /* 726 | * Return a Big whose value is the value of this Big raised to the power n. 727 | * If n is negative, round to a maximum of Big.DP decimal places using rounding 728 | * mode Big.RM. 729 | * 730 | * n {number} Integer, -MAX_POWER to MAX_POWER inclusive. 731 | */ 732 | P.pow = function (n) { 733 | var x = this, 734 | one = new x.constructor('1'), 735 | y = one, 736 | isneg = n < 0; 737 | 738 | if (n !== ~~n || n < -MAX_POWER || n > MAX_POWER) { 739 | throw Error(INVALID + 'exponent'); 740 | } 741 | 742 | if (isneg) n = -n; 743 | 744 | for (;;) { 745 | if (n & 1) y = y.times(x); 746 | n >>= 1; 747 | if (!n) break; 748 | x = x.times(x); 749 | } 750 | 751 | return isneg ? one.div(y) : y; 752 | }; 753 | 754 | 755 | /* 756 | * Return a new Big whose value is the value of this Big rounded to a maximum precision of sd 757 | * significant digits using rounding mode rm, or Big.RM if rm is not specified. 758 | * 759 | * sd {number} Significant digits: integer, 1 to MAX_DP inclusive. 760 | * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). 761 | */ 762 | P.prec = function (sd, rm) { 763 | if (sd !== ~~sd || sd < 1 || sd > MAX_DP) { 764 | throw Error(INVALID + 'precision'); 765 | } 766 | return round(new this.constructor(this), sd, rm); 767 | }; 768 | 769 | 770 | /* 771 | * Return a new Big whose value is the value of this Big rounded to a maximum of dp decimal places 772 | * using rounding mode rm, or Big.RM if rm is not specified. 773 | * If dp is negative, round to an integer which is a multiple of 10**-dp. 774 | * If dp is not specified, round to 0 decimal places. 775 | * 776 | * dp? {number} Integer, -MAX_DP to MAX_DP inclusive. 777 | * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). 778 | */ 779 | P.round = function (dp, rm) { 780 | if (dp === UNDEFINED) dp = 0; 781 | else if (dp !== ~~dp || dp < -MAX_DP || dp > MAX_DP) { 782 | throw Error(INVALID_DP); 783 | } 784 | return round(new this.constructor(this), dp + this.e + 1, rm); 785 | }; 786 | 787 | 788 | /* 789 | * Return a new Big whose value is the square root of the value of this Big, rounded, if 790 | * necessary, to a maximum of Big.DP decimal places using rounding mode Big.RM. 791 | */ 792 | P.sqrt = function () { 793 | var r, c, t, 794 | x = this, 795 | Big = x.constructor, 796 | s = x.s, 797 | e = x.e, 798 | half = new Big('0.5'); 799 | 800 | // Zero? 801 | if (!x.c[0]) return new Big(x); 802 | 803 | // Negative? 804 | if (s < 0) { 805 | throw Error(NAME + 'No square root'); 806 | } 807 | 808 | // Estimate. 809 | s = Math.sqrt(x + ''); 810 | 811 | // Math.sqrt underflow/overflow? 812 | // Re-estimate: pass x coefficient to Math.sqrt as integer, then adjust the result exponent. 813 | if (s === 0 || s === 1 / 0) { 814 | c = x.c.join(''); 815 | if (!(c.length + e & 1)) c += '0'; 816 | s = Math.sqrt(c); 817 | e = ((e + 1) / 2 | 0) - (e < 0 || e & 1); 818 | r = new Big((s == 1 / 0 ? '5e' : (s = s.toExponential()).slice(0, s.indexOf('e') + 1)) + e); 819 | } else { 820 | r = new Big(s + ''); 821 | } 822 | 823 | e = r.e + (Big.DP += 4); 824 | 825 | // Newton-Raphson iteration. 826 | do { 827 | t = r; 828 | r = half.times(t.plus(x.div(t))); 829 | } while (t.c.slice(0, e).join('') !== r.c.slice(0, e).join('')); 830 | 831 | return round(r, (Big.DP -= 4) + r.e + 1, Big.RM); 832 | }; 833 | 834 | 835 | /* 836 | * Return a new Big whose value is the value of this Big times the value of Big y. 837 | */ 838 | P.times = P.mul = function (y) { 839 | var c, 840 | x = this, 841 | Big = x.constructor, 842 | xc = x.c, 843 | yc = (y = new Big(y)).c, 844 | a = xc.length, 845 | b = yc.length, 846 | i = x.e, 847 | j = y.e; 848 | 849 | // Determine sign of result. 850 | y.s = x.s == y.s ? 1 : -1; 851 | 852 | // Return signed 0 if either 0. 853 | if (!xc[0] || !yc[0]) { 854 | y.c = [y.e = 0]; 855 | return y; 856 | } 857 | 858 | // Initialise exponent of result as x.e + y.e. 859 | y.e = i + j; 860 | 861 | // If array xc has fewer digits than yc, swap xc and yc, and lengths. 862 | if (a < b) { 863 | c = xc; 864 | xc = yc; 865 | yc = c; 866 | j = a; 867 | a = b; 868 | b = j; 869 | } 870 | 871 | // Initialise coefficient array of result with zeros. 872 | for (c = new Array(j = a + b); j--;) c[j] = 0; 873 | 874 | // Multiply. 875 | 876 | // i is initially xc.length. 877 | for (i = b; i--;) { 878 | b = 0; 879 | 880 | // a is yc.length. 881 | for (j = a + i; j > i;) { 882 | 883 | // Current sum of products at this digit position, plus carry. 884 | b = c[j] + yc[i] * xc[j - i - 1] + b; 885 | c[j--] = b % 10; 886 | 887 | // carry 888 | b = b / 10 | 0; 889 | } 890 | 891 | c[j] = b; 892 | } 893 | 894 | // Increment result exponent if there is a final carry, otherwise remove leading zero. 895 | if (b) ++y.e; 896 | else c.shift(); 897 | 898 | // Remove trailing zeros. 899 | for (i = c.length; !c[--i];) c.pop(); 900 | y.c = c; 901 | 902 | return y; 903 | }; 904 | 905 | 906 | /* 907 | * Return a string representing the value of this Big in exponential notation rounded to dp fixed 908 | * decimal places using rounding mode rm, or Big.RM if rm is not specified. 909 | * 910 | * dp? {number} Decimal places: integer, 0 to MAX_DP inclusive. 911 | * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). 912 | */ 913 | P.toExponential = function (dp, rm) { 914 | var x = this, 915 | n = x.c[0]; 916 | 917 | if (dp !== UNDEFINED) { 918 | if (dp !== ~~dp || dp < 0 || dp > MAX_DP) { 919 | throw Error(INVALID_DP); 920 | } 921 | x = round(new x.constructor(x), ++dp, rm); 922 | for (; x.c.length < dp;) x.c.push(0); 923 | } 924 | 925 | return stringify(x, true, !!n); 926 | }; 927 | 928 | 929 | /* 930 | * Return a string representing the value of this Big in normal notation rounded to dp fixed 931 | * decimal places using rounding mode rm, or Big.RM if rm is not specified. 932 | * 933 | * dp? {number} Decimal places: integer, 0 to MAX_DP inclusive. 934 | * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). 935 | * 936 | * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'. 937 | * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. 938 | */ 939 | P.toFixed = function (dp, rm) { 940 | var x = this, 941 | n = x.c[0]; 942 | 943 | if (dp !== UNDEFINED) { 944 | if (dp !== ~~dp || dp < 0 || dp > MAX_DP) { 945 | throw Error(INVALID_DP); 946 | } 947 | x = round(new x.constructor(x), dp + x.e + 1, rm); 948 | 949 | // x.e may have changed if the value is rounded up. 950 | for (dp = dp + x.e + 1; x.c.length < dp;) x.c.push(0); 951 | } 952 | 953 | return stringify(x, false, !!n); 954 | }; 955 | 956 | 957 | /* 958 | * Return a string representing the value of this Big. 959 | * Return exponential notation if this Big has a positive exponent equal to or greater than 960 | * Big.PE, or a negative exponent equal to or less than Big.NE. 961 | * Omit the sign for negative zero. 962 | */ 963 | P.toJSON = P.toString = function () { 964 | var x = this, 965 | Big = x.constructor; 966 | return stringify(x, x.e <= Big.NE || x.e >= Big.PE, !!x.c[0]); 967 | }; 968 | 969 | 970 | /* 971 | * Return the value of this Big as a primitve number. 972 | */ 973 | P.toNumber = function () { 974 | var n = Number(stringify(this, true, true)); 975 | if (this.constructor.strict === true && !this.eq(n.toString())) { 976 | throw Error(NAME + 'Imprecise conversion'); 977 | } 978 | return n; 979 | }; 980 | 981 | 982 | /* 983 | * Return a string representing the value of this Big rounded to sd significant digits using 984 | * rounding mode rm, or Big.RM if rm is not specified. 985 | * Use exponential notation if sd is less than the number of digits necessary to represent 986 | * the integer part of the value in normal notation. 987 | * 988 | * sd {number} Significant digits: integer, 1 to MAX_DP inclusive. 989 | * rm? {number} Rounding mode: 0 (down), 1 (half-up), 2 (half-even) or 3 (up). 990 | */ 991 | P.toPrecision = function (sd, rm) { 992 | var x = this, 993 | Big = x.constructor, 994 | n = x.c[0]; 995 | 996 | if (sd !== UNDEFINED) { 997 | if (sd !== ~~sd || sd < 1 || sd > MAX_DP) { 998 | throw Error(INVALID + 'precision'); 999 | } 1000 | x = round(new Big(x), sd, rm); 1001 | for (; x.c.length < sd;) x.c.push(0); 1002 | } 1003 | 1004 | return stringify(x, sd <= x.e || x.e <= Big.NE || x.e >= Big.PE, !!n); 1005 | }; 1006 | 1007 | 1008 | /* 1009 | * Return a string representing the value of this Big. 1010 | * Return exponential notation if this Big has a positive exponent equal to or greater than 1011 | * Big.PE, or a negative exponent equal to or less than Big.NE. 1012 | * Include the sign for negative zero. 1013 | */ 1014 | P.valueOf = function () { 1015 | var x = this, 1016 | Big = x.constructor; 1017 | if (Big.strict === true) { 1018 | throw Error(NAME + 'valueOf disallowed'); 1019 | } 1020 | return stringify(x, x.e <= Big.NE || x.e >= Big.PE, true); 1021 | }; 1022 | 1023 | 1024 | // Export 1025 | 1026 | 1027 | Big = _Big_(); 1028 | 1029 | Big['default'] = Big.Big = Big; 1030 | 1031 | //AMD. 1032 | if (typeof define === 'function' && define.amd) { 1033 | define(function () { return Big; }); 1034 | 1035 | // Node and other CommonJS-like environments that support module.exports. 1036 | } else if (typeof module !== 'undefined' && module.exports) { 1037 | module.exports = Big; 1038 | 1039 | //Browser. 1040 | } else { 1041 | GLOBAL.Big = Big; 1042 | } 1043 | })(this); 1044 | -------------------------------------------------------------------------------- /benchmark/libs/https___github_com_Yaffle_BigInteger.js: -------------------------------------------------------------------------------- 1 | /*jslint plusplus: true, vars: true, indent: 2*/ 2 | 3 | (function (global) { 4 | "use strict"; 5 | 6 | // BigInteger.js 7 | // Available under Public Domain 8 | // https://github.com/Yaffle/BigInteger/ 9 | 10 | // For implementation details, see "The Handbook of Applied Cryptography" 11 | // http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf 12 | 13 | var parseInteger = function (s, from, to, radix) { 14 | var i = from - 1; 15 | var n = 0; 16 | var y = radix < 10 ? radix : 10; 17 | while (++i < to) { 18 | var code = s.charCodeAt(i); 19 | var v = code - "0".charCodeAt(0); 20 | if (v < 0 || y <= v) { 21 | v = 10 - "A".charCodeAt(0) + code; 22 | if (v < 10 || radix <= v) { 23 | v = 10 - "a".charCodeAt(0) + code; 24 | if (v < 10 || radix <= v) { 25 | throw new RangeError(); 26 | } 27 | } 28 | } 29 | n = n * radix + v; 30 | } 31 | return n; 32 | }; 33 | 34 | var createArray = function (length) { 35 | var x = new Array(length); 36 | var i = -1; 37 | while (++i < length) { 38 | x[i] = 0; 39 | } 40 | return x; 41 | }; 42 | 43 | var epsilon = 2 / (9007199254740991 + 1); 44 | while (1 + epsilon / 2 !== 1) { 45 | epsilon /= 2; 46 | } 47 | var BASE = 2 / epsilon; 48 | var s = 134217728; 49 | while (s * s < 2 / epsilon) { 50 | s *= 2; 51 | } 52 | var SPLIT = s + 1; 53 | var BASELOG2 = Math.ceil(Math.log(BASE) / Math.log(2)); 54 | 55 | // Veltkamp-Dekker's algorithm 56 | // see http://web.mit.edu/tabbott/Public/quaddouble-debian/qd-2.3.4-old/docs/qd.pdf 57 | var fma = function (a, b, product) { 58 | var at = SPLIT * a; 59 | var ahi = at - (at - a); 60 | var alo = a - ahi; 61 | var bt = SPLIT * b; 62 | var bhi = bt - (bt - b); 63 | var blo = b - bhi; 64 | var error = ((ahi * bhi + product) + ahi * blo + alo * bhi) + alo * blo; 65 | return error; 66 | }; 67 | 68 | var fastTrunc = function (x) { 69 | var v = (x - BASE) + BASE; 70 | return v > x ? v - 1 : v; 71 | }; 72 | 73 | var performMultiplication = function (carry, a, b) { 74 | var product = a * b; 75 | var error = fma(a, b, -product); 76 | 77 | var hi = (product / BASE) - BASE + BASE; 78 | var lo = product - hi * BASE + error; 79 | 80 | if (lo >= 0) { 81 | lo -= BASE; 82 | hi += 1; 83 | } 84 | 85 | lo += carry; 86 | if (lo < 0) { 87 | lo += BASE; 88 | hi -= 1; 89 | } 90 | 91 | return {lo: lo, hi: hi}; 92 | }; 93 | 94 | var performDivision = function (a, b, divisor) { 95 | if (a >= divisor) { 96 | throw new RangeError(); 97 | } 98 | var p = a * BASE; 99 | var q = fastTrunc(p / divisor); 100 | 101 | var r = 0 - fma(q, divisor, -p); 102 | if (r < 0) { 103 | q -= 1; 104 | r += divisor; 105 | } 106 | 107 | r += b - divisor; 108 | if (r < 0) { 109 | r += divisor; 110 | } else { 111 | q += 1; 112 | } 113 | var y = fastTrunc(r / divisor); 114 | r -= y * divisor; 115 | q += y; 116 | return {q: q, r: r}; 117 | }; 118 | 119 | function BigInteger(sign, magnitude, length) { 120 | this.sign = sign; 121 | this.magnitude = magnitude; 122 | this.length = length; 123 | } 124 | 125 | var createBigInteger = function (sign, magnitude, length) { 126 | return new BigInteger(sign, magnitude, length); 127 | }; 128 | 129 | var fromHugeNumber = function (n) { 130 | var sign = n < 0 ? 1 : 0; 131 | var a = n < 0 ? 0 - n : 0 + n; 132 | if (a === 1 / 0) { 133 | throw new RangeError(); 134 | } 135 | console.assert(BASE === Math.pow(2, 53)); 136 | var i = 0; 137 | while (a >= Math.pow(BASE, 2)) { 138 | a /= BASE; 139 | i += 1; 140 | } 141 | var hi = Math.floor(a / BASE); 142 | var lo = a - hi * BASE; 143 | var digits = createArray(i + 2); 144 | digits[i + 1] = hi; 145 | digits[i + 0] = lo; 146 | return createBigInteger(sign, digits, i + 2); 147 | }; 148 | 149 | var fromNumber = function (n) { 150 | if (Math.floor(n) !== n) { 151 | throw new RangeError("Cannot convert " + n + " to BigInteger"); 152 | } 153 | if (n < BASE && 0 - n < BASE) { 154 | var a = createArray(1); 155 | a[0] = n < 0 ? 0 - n : 0 + n; 156 | return createBigInteger(n < 0 ? 1 : 0, a, n === 0 ? 0 : 1); 157 | } 158 | return fromHugeNumber(n); 159 | }; 160 | 161 | var fromString = function (s) { 162 | var length = s.length; 163 | if (length === 0) { 164 | throw new RangeError(); 165 | } 166 | var sign = 0; 167 | var signCharCode = s.charCodeAt(0); 168 | var from = 0; 169 | if (signCharCode === "+".charCodeAt(0)) { 170 | from = 1; 171 | } 172 | if (signCharCode === "-".charCodeAt(0)) { 173 | from = 1; 174 | sign = 1; 175 | } 176 | var radix = 10; 177 | if (from === 0 && length >= 2 && s.charCodeAt(0) === "0".charCodeAt(0)) { 178 | if (s.charCodeAt(1) === "b".charCodeAt(0)) { 179 | radix = 2; 180 | from = 2; 181 | } else if (s.charCodeAt(1) === "o".charCodeAt(0)) { 182 | radix = 8; 183 | from = 2; 184 | } else if (s.charCodeAt(1) === "x".charCodeAt(0)) { 185 | radix = 16; 186 | from = 2; 187 | } 188 | } 189 | length -= from; 190 | if (length === 0) { 191 | throw new RangeError(); 192 | } 193 | 194 | var groupLength = 0; 195 | var groupRadix = 1; 196 | var limit = fastTrunc(BASE / radix); 197 | while (groupRadix <= limit) { 198 | groupLength += 1; 199 | groupRadix *= radix; 200 | } 201 | 202 | var size = Math.floor((length - 1) / groupLength) + 1; 203 | var magnitude = createArray(size); 204 | var start = from + 1 + (length - 1 - (size - 1) * groupLength) - groupLength; 205 | 206 | var j = -1; 207 | while (++j < size) { 208 | var groupStart = start + j * groupLength; 209 | var c = parseInteger(s, (groupStart >= from ? groupStart : from), groupStart + groupLength, radix); 210 | var l = -1; 211 | while (++l < j) { 212 | var tmp = performMultiplication(c, magnitude[l], groupRadix); 213 | var lo = tmp.lo; 214 | var hi = tmp.hi; 215 | magnitude[l] = lo; 216 | c = hi; 217 | } 218 | magnitude[j] = c; 219 | } 220 | 221 | while (size > 0 && magnitude[size - 1] === 0) { 222 | size -= 1; 223 | } 224 | 225 | return createBigInteger(size === 0 ? 0 : sign, magnitude, size); 226 | }; 227 | 228 | // Math.pow(2, n) is slow in Chrome 93 229 | function exp(x, n) { 230 | var a = 1; 231 | while (n !== 0) { 232 | var q = (n >> 1); 233 | if (n !== (q << 1)) { 234 | a *= x; 235 | } 236 | n = q; 237 | x *= x; 238 | } 239 | return a; 240 | } 241 | 242 | BigInteger.BigInt = function (x) { 243 | if (typeof x === "number") { 244 | return fromNumber(x); 245 | } 246 | if (typeof x === "string") { 247 | return fromString(x); 248 | } 249 | if (typeof x === "bigint") { 250 | return fromString(x.toString()); 251 | } 252 | if (x instanceof BigInteger) { 253 | return x; 254 | } 255 | if (typeof x === "boolean") { 256 | return fromNumber(Number(x)); 257 | } 258 | throw new RangeError(); 259 | }; 260 | 261 | BigInteger.asUintN = function (bits, bigint) { 262 | if (bits < 0) { 263 | throw new RangeError(); 264 | } 265 | var n = Math.ceil(bits / BASELOG2); 266 | bits -= BASELOG2 * n; 267 | if (bigint.sign === 1) { 268 | throw new RangeError("not implemented"); 269 | } 270 | if (n > bigint.length) { 271 | return bigint; 272 | } 273 | var array = createArray(n); 274 | for (var i = 0; i < n; i += 1) { 275 | array[i] = bigint.magnitude[i]; 276 | } 277 | var m = exp(2, BASELOG2 + bits); 278 | array[n - 1] = array[n - 1] - Math.floor(array[n - 1] / m) * m; 279 | while (n >= 0 && array[n - 1] === 0) { 280 | n -= 1; 281 | } 282 | return createBigInteger(0, array, n); 283 | }; 284 | 285 | BigInteger.asIntN = function (bits, bigint) { 286 | //TODO: !? 287 | }; 288 | 289 | BigInteger.toNumber = function (a) { 290 | if (a.length === 0) { 291 | return 0; 292 | } 293 | if (a.length === 1) { 294 | return a.sign === 1 ? 0 - a.magnitude[0] : a.magnitude[0]; 295 | } 296 | if (BASE + 1 !== BASE) { 297 | throw new RangeError(); 298 | } 299 | var x = a.magnitude[a.length - 1]; 300 | var y = a.magnitude[a.length - 2]; 301 | var i = a.length - 3; 302 | while (i >= 0 && a.magnitude[i] === 0) { 303 | i -= 1; 304 | } 305 | if (i >= 0 && (x !== 1 && y % 2 === 0 || x === 1 && y % 2 === 1)) { 306 | y += 1; 307 | } 308 | var z = (x * BASE + y) * exp(BASE, a.length - 2); 309 | return a.sign === 1 ? 0 - z : z; 310 | }; 311 | 312 | var compareMagnitude = function (a, b) { 313 | if (a === b) { 314 | return 0; 315 | } 316 | var c1 = a.length - b.length; 317 | if (c1 !== 0) { 318 | return c1 < 0 ? -1 : +1; 319 | } 320 | var i = a.length; 321 | while (--i >= 0) { 322 | var c = a.magnitude[i] - b.magnitude[i]; 323 | if (c !== 0) { 324 | return c < 0 ? -1 : +1; 325 | } 326 | } 327 | return 0; 328 | }; 329 | 330 | var compareTo = function (a, b) { 331 | var c = a.sign === b.sign ? compareMagnitude(a, b) : 1; 332 | return a.sign === 1 ? 0 - c : c; // positive zero will be returned for c === 0 333 | }; 334 | 335 | var addAndSubtract = function (a, b, isSubtraction) { 336 | var z = compareMagnitude(a, b); 337 | var resultSign = z < 0 ? (isSubtraction !== 0 ? 1 - b.sign : b.sign) : a.sign; 338 | var min = z < 0 ? a : b; 339 | var max = z < 0 ? b : a; 340 | // |a| <= |b| 341 | if (min.length === 0) { 342 | return createBigInteger(resultSign, max.magnitude, max.length); 343 | } 344 | var subtract = 0; 345 | var resultLength = max.length; 346 | if (a.sign !== (isSubtraction !== 0 ? 1 - b.sign : b.sign)) { 347 | subtract = 1; 348 | if (min.length === resultLength) { 349 | while (resultLength > 0 && min.magnitude[resultLength - 1] === max.magnitude[resultLength - 1]) { 350 | resultLength -= 1; 351 | } 352 | } 353 | if (resultLength === 0) { // a === (-b) 354 | return createBigInteger(0, createArray(0), 0); 355 | } 356 | } 357 | // result !== 0 358 | var result = createArray(resultLength + (1 - subtract)); 359 | var i = -1; 360 | var c = 0; 361 | while (++i < min.length) { 362 | var aDigit = min.magnitude[i]; 363 | c += max.magnitude[i] + (subtract !== 0 ? 0 - aDigit : aDigit - BASE); 364 | if (c < 0) { 365 | result[i] = BASE + c; 366 | c = 0 - subtract; 367 | } else { 368 | result[i] = c; 369 | c = 1 - subtract; 370 | } 371 | } 372 | i -= 1; 373 | while (++i < resultLength) { 374 | c += max.magnitude[i] + (subtract !== 0 ? 0 : 0 - BASE); 375 | if (c < 0) { 376 | result[i] = BASE + c; 377 | c = 0 - subtract; 378 | } else { 379 | result[i] = c; 380 | c = 1 - subtract; 381 | } 382 | } 383 | if (subtract === 0) { 384 | result[resultLength] = c; 385 | resultLength += c !== 0 ? 1 : 0; 386 | } else { 387 | while (resultLength > 0 && result[resultLength - 1] === 0) { 388 | resultLength -= 1; 389 | } 390 | } 391 | return createBigInteger(resultSign, result, resultLength); 392 | }; 393 | 394 | BigInteger.add = function (a, b) { 395 | return addAndSubtract(a, b, 0); 396 | }; 397 | 398 | BigInteger.subtract = function (a, b) { 399 | return addAndSubtract(a, b, 1); 400 | }; 401 | 402 | BigInteger.multiply = function (a, b) { 403 | if (a.length < b.length) { 404 | var tmp = a; 405 | a = b; 406 | b = tmp; 407 | } 408 | var alength = a.length; 409 | var blength = b.length; 410 | var am = a.magnitude; 411 | var bm = b.magnitude; 412 | var asign = a.sign; 413 | var bsign = b.sign; 414 | if (alength === 0 || blength === 0) { 415 | return createBigInteger(0, createArray(0), 0); 416 | } 417 | if (alength === 1 && am[0] === 1) { 418 | return createBigInteger(asign === 1 ? 1 - bsign : bsign, bm, blength); 419 | } 420 | if (blength === 1 && bm[0] === 1) { 421 | return createBigInteger(asign === 1 ? 1 - bsign : bsign, am, alength); 422 | } 423 | var astart = 0; 424 | while (am[astart] === 0) { // to optimize multiplications of a power of BASE 425 | astart += 1; 426 | } 427 | var resultSign = asign === 1 ? 1 - bsign : bsign; 428 | var resultLength = alength + blength; 429 | var result = createArray(resultLength); 430 | var i = -1; 431 | while (++i < blength) { 432 | var digit = bm[i]; 433 | if (digit !== 0) { // to optimize multiplications by a power of BASE 434 | var c = 0; 435 | var j = astart - 1; 436 | while (++j < alength) { 437 | var carry = 1; 438 | c += result[j + i] - BASE; 439 | if (c < 0) { 440 | c += BASE; 441 | carry = 0; 442 | } 443 | var tmp = performMultiplication(c, am[j], digit); 444 | var lo = tmp.lo; 445 | var hi = tmp.hi; 446 | result[j + i] = lo; 447 | c = hi + carry; 448 | } 449 | result[alength + i] = c; 450 | } 451 | } 452 | if (result[resultLength - 1] === 0) { 453 | resultLength -= 1; 454 | } 455 | return createBigInteger(resultSign, result, resultLength); 456 | }; 457 | 458 | var divideAndRemainder = function (a, b, isDivision) { 459 | if (b.length === 0) { 460 | throw new RangeError(); 461 | } 462 | if (a.length === 0) { 463 | return createBigInteger(0, createArray(0), 0); 464 | } 465 | var quotientSign = a.sign === 1 ? 1 - b.sign : b.sign; 466 | if (b.length === 1 && b.magnitude[0] === 1) { 467 | if (isDivision !== 0) { 468 | return createBigInteger(quotientSign, a.magnitude, a.length); 469 | } 470 | return createBigInteger(0, createArray(0), 0); 471 | } 472 | 473 | var divisorOffset = a.length + 1; // `+ 1` for extra digit in case of normalization 474 | var divisorAndRemainder = createArray(divisorOffset + b.length + 1); // `+ 1` to avoid `index < length` checks 475 | var divisor = divisorAndRemainder; 476 | var remainder = divisorAndRemainder; 477 | var n = -1; 478 | while (++n < a.length) { 479 | remainder[n] = a.magnitude[n]; 480 | } 481 | var m = -1; 482 | while (++m < b.length) { 483 | divisor[divisorOffset + m] = b.magnitude[m]; 484 | } 485 | 486 | var top = divisor[divisorOffset + b.length - 1]; 487 | 488 | // normalization 489 | var lambda = 1; 490 | if (b.length > 1) { 491 | lambda = fastTrunc(BASE / (top + 1)); 492 | if (lambda > 1) { 493 | var carry = 0; 494 | var l = -1; 495 | while (++l < divisorOffset + b.length) { 496 | var tmp = performMultiplication(carry, divisorAndRemainder[l], lambda); 497 | var lo = tmp.lo; 498 | var hi = tmp.hi; 499 | divisorAndRemainder[l] = lo; 500 | carry = hi; 501 | } 502 | divisorAndRemainder[divisorOffset + b.length] = carry; 503 | top = divisor[divisorOffset + b.length - 1]; 504 | } 505 | // assertion 506 | if (top < fastTrunc(BASE / 2)) { 507 | throw new RangeError(); 508 | } 509 | } 510 | 511 | var shift = a.length - b.length + 1; 512 | if (shift < 0) { 513 | shift = 0; 514 | } 515 | var quotient = undefined; 516 | var quotientLength = 0; 517 | 518 | // to optimize divisions by a power of BASE 519 | var lastNonZero = 0; 520 | while (divisor[divisorOffset + lastNonZero] === 0) { 521 | lastNonZero += 1; 522 | } 523 | 524 | var i = shift; 525 | while (--i >= 0) { 526 | var t = b.length + i; 527 | var q = BASE - 1; 528 | if (remainder[t] !== top) { 529 | var tmp2 = performDivision(remainder[t], remainder[t - 1], top); 530 | var q2 = tmp2.q; 531 | //var r2 = tmp2.r; 532 | q = q2; 533 | } 534 | 535 | var ax = 0; 536 | var bx = 0; 537 | var j = i - 1 + lastNonZero; 538 | while (++j <= t) { 539 | var tmp3 = performMultiplication(bx, q, divisor[divisorOffset + j - i]); 540 | var lo3 = tmp3.lo; 541 | var hi3 = tmp3.hi; 542 | bx = hi3; 543 | ax += remainder[j] - lo3; 544 | if (ax < 0) { 545 | remainder[j] = BASE + ax; 546 | ax = -1; 547 | } else { 548 | remainder[j] = ax; 549 | ax = 0; 550 | } 551 | } 552 | while (ax !== 0) { 553 | q -= 1; 554 | var c = 0; 555 | var k = i - 1 + lastNonZero; 556 | while (++k <= t) { 557 | c += remainder[k] - BASE + divisor[divisorOffset + k - i]; 558 | if (c < 0) { 559 | remainder[k] = BASE + c; 560 | c = 0; 561 | } else { 562 | remainder[k] = c; 563 | c = +1; 564 | } 565 | } 566 | ax += c; 567 | } 568 | if (isDivision !== 0 && q !== 0) { 569 | if (quotientLength === 0) { 570 | quotientLength = i + 1; 571 | quotient = createArray(quotientLength); 572 | } 573 | quotient[i] = q; 574 | } 575 | } 576 | 577 | if (isDivision !== 0) { 578 | if (quotientLength === 0) { 579 | return createBigInteger(0, createArray(0), 0); 580 | } 581 | return createBigInteger(quotientSign, quotient, quotientLength); 582 | } 583 | 584 | var remainderLength = a.length + 1; 585 | if (lambda > 1) { 586 | var r = 0; 587 | var p = remainderLength; 588 | while (--p >= 0) { 589 | var tmp4 = performDivision(r, remainder[p], lambda); 590 | var q4 = tmp4.q; 591 | var r4 = tmp4.r; 592 | remainder[p] = q4; 593 | r = r4; 594 | } 595 | if (r !== 0) { 596 | // assertion 597 | throw new RangeError(); 598 | } 599 | } 600 | while (remainderLength > 0 && remainder[remainderLength - 1] === 0) { 601 | remainderLength -= 1; 602 | } 603 | if (remainderLength === 0) { 604 | return createBigInteger(0, createArray(0), 0); 605 | } 606 | var result = createArray(remainderLength); 607 | var o = -1; 608 | while (++o < remainderLength) { 609 | result[o] = remainder[o]; 610 | } 611 | return createBigInteger(a.sign, result, remainderLength); 612 | }; 613 | 614 | BigInteger.divide = function (a, b) { 615 | return divideAndRemainder(a, b, 1); 616 | }; 617 | 618 | BigInteger.remainder = function (a, b) { 619 | return divideAndRemainder(a, b, 0); 620 | }; 621 | 622 | BigInteger.unaryMinus = function (a) { 623 | return createBigInteger(a.length === 0 ? a.sign : 1 - a.sign, a.magnitude, a.length); 624 | }; 625 | 626 | BigInteger.equal = function (a, b) { 627 | return compareTo(a, b) === 0; 628 | }; 629 | BigInteger.lessThan = function (a, b) { 630 | return compareTo(a, b) < 0; 631 | }; 632 | BigInteger.greaterThan = function (a, b) { 633 | return compareTo(a, b) > 0; 634 | }; 635 | BigInteger.notEqual = function (a, b) { 636 | return compareTo(a, b) !== 0; 637 | }; 638 | BigInteger.lessThanOrEqual = function (a, b) { 639 | return compareTo(a, b) <= 0; 640 | }; 641 | BigInteger.greaterThanOrEqual = function (a, b) { 642 | return compareTo(a, b) >= 0; 643 | }; 644 | 645 | BigInteger.exponentiate = function (a, b) { 646 | var n = BigInteger.toNumber(b); 647 | if (n < 0) { 648 | throw new RangeError(); 649 | } 650 | if (n > 9007199254740991) { 651 | var y = BigInteger.toNumber(a); 652 | if (y === 0 || y === -1 || y === +1) { 653 | return y === -1 && BigInteger.toNumber(BigInteger.remainder(b, BigInteger.BigInt(2))) === 0 ? BigInteger.unaryMinus(a) : a; 654 | } 655 | throw new RangeError(); 656 | } 657 | if (n === 0) { 658 | return BigInteger.BigInt(1); 659 | } 660 | if (a.length === 1 && (a.magnitude[0] === 2 || a.magnitude[0] === 16)) { 661 | var bits = Math.floor(Math.log(BASE) / Math.log(2) + 0.5); 662 | var abits = Math.floor(Math.log(a.magnitude[0]) / Math.log(2) + 0.5); 663 | var nn = abits * n; 664 | var q = Math.floor(nn / bits); 665 | var r = nn - q * bits; 666 | var array = createArray(q + 1); 667 | array[q] = Math.pow(2, r); 668 | return createBigInteger(a.sign === 0 || n % 2 === 0 ? 0 : 1, array, q + 1); 669 | } 670 | var x = a; 671 | while (n % 2 === 0) { 672 | n = Math.floor(n / 2); 673 | x = BigInteger.multiply(x, x); 674 | } 675 | var accumulator = x; 676 | n -= 1; 677 | if (n >= 2) { 678 | while (n >= 2) { 679 | var t = Math.floor(n / 2); 680 | if (t * 2 !== n) { 681 | accumulator = BigInteger.multiply(accumulator, x); 682 | } 683 | n = t; 684 | x = BigInteger.multiply(x, x); 685 | } 686 | accumulator = BigInteger.multiply(accumulator, x); 687 | } 688 | return accumulator; 689 | }; 690 | 691 | BigInteger.prototype.toString = function (radix) { 692 | if (radix == undefined) { 693 | radix = 10; 694 | } 695 | if (radix !== 10 && (radix < 2 || radix > 36 || radix !== Math.floor(radix))) { 696 | throw new RangeError("radix argument must be an integer between 2 and 36"); 697 | } 698 | 699 | // console.time(); var n = BigInteger.exponentiate(2**4, 2**16); console.timeEnd(); console.time(); n.toString(16).length; console.timeEnd(); 700 | if (this.length > 8 && true) { // https://github.com/GoogleChromeLabs/jsbi/blob/c9b179a4d5d34d35dd24cf84f7c1def54dc4a590/jsbi.mjs#L880 701 | if (this.sign === 1) { 702 | return '-' + BigInteger.unaryMinus(this).toString(radix); 703 | } 704 | var s = Math.floor(this.length * Math.log(BASE) / Math.log(radix) / 2 + 0.5 - 1); 705 | var split = BigInteger.exponentiate(BigInteger.BigInt(radix), BigInteger.BigInt(s)); 706 | var q = BigInteger.divide(this, split); 707 | var r = BigInteger.subtract(this, BigInteger.multiply(q, split)); 708 | var a = r.toString(radix); 709 | return q.toString(radix) + '0'.repeat(s - a.length) + a; 710 | } 711 | 712 | var a = this; 713 | var result = a.sign === 1 ? "-" : ""; 714 | 715 | var remainderLength = a.length; 716 | if (remainderLength === 0) { 717 | return "0"; 718 | } 719 | if (remainderLength === 1) { 720 | result += a.magnitude[0].toString(radix); 721 | return result; 722 | } 723 | var groupLength = 0; 724 | var groupRadix = 1; 725 | var limit = fastTrunc(BASE / radix); 726 | while (groupRadix <= limit) { 727 | groupLength += 1; 728 | groupRadix *= radix; 729 | } 730 | // assertion 731 | if (groupRadix * radix <= BASE) { 732 | throw new RangeError(); 733 | } 734 | var size = remainderLength + Math.floor((remainderLength - 1) / groupLength) + 1; 735 | var remainder = createArray(size); 736 | var n = -1; 737 | while (++n < remainderLength) { 738 | remainder[n] = a.magnitude[n]; 739 | } 740 | 741 | var k = size; 742 | while (remainderLength !== 0) { 743 | var groupDigit = 0; 744 | var i = remainderLength; 745 | while (--i >= 0) { 746 | var tmp = performDivision(groupDigit, remainder[i], groupRadix); 747 | var q = tmp.q; 748 | var r = tmp.r; 749 | remainder[i] = q; 750 | groupDigit = r; 751 | } 752 | while (remainderLength > 0 && remainder[remainderLength - 1] === 0) { 753 | remainderLength -= 1; 754 | } 755 | k -= 1; 756 | remainder[k] = groupDigit; 757 | } 758 | result += remainder[k].toString(radix); 759 | while (++k < size) { 760 | var t = remainder[k].toString(radix); 761 | result += "0".repeat(groupLength - t.length) + t; 762 | } 763 | return result; 764 | }; 765 | var signedRightShift = function (x, n) { 766 | // (!) it should work fast if n ~ size(x) - 53 767 | if (x.length === 0) { 768 | return x; 769 | } 770 | var shift = Math.floor(n / BASELOG2); 771 | var length = x.length - shift; 772 | if (length <= 0) { 773 | if (x.sign === 1) { 774 | var minusOne = createArray(1); 775 | minusOne[0] = 1; 776 | return createBigInteger(1, minusOne, 1); 777 | } 778 | return createBigInteger(0, createArray(0), 0); 779 | } 780 | var digits = createArray(length + (x.sign === 1 ? 1 : 0)); 781 | for (var i = 0; i < length; i += 1) { 782 | digits[i] = i + shift < 0 ? 0 : x.magnitude[i + shift]; 783 | } 784 | n -= shift * BASELOG2; 785 | var s = exp(2, n); 786 | var s1 = Math.floor(BASE / s); 787 | var pr = 0; 788 | for (var i = length - 1; i >= 0; i -= 1) { 789 | var q = Math.floor(digits[i] / s); 790 | var r = digits[i] - q * s; 791 | digits[i] = q + pr * s1; 792 | pr = r; 793 | } 794 | if (length >= 1 && digits[length - 1] === 0) { 795 | length -= 1; 796 | } 797 | if (x.sign === 1) { 798 | var hasRemainder = pr > 0; 799 | for (var i = 0; i < shift && !hasRemainder; i += 1) { 800 | hasRemainder = x.magnitude[i] !== 0; 801 | } 802 | if (hasRemainder) { 803 | if (length === 0) { 804 | length += 1; 805 | digits[0] = 1; 806 | } else { 807 | // subtract one 808 | var i = 0; 809 | while (i < length && digits[i] === BASE - 1) { 810 | digits[i] = 0; 811 | i += 1; 812 | } 813 | if (i < length) { 814 | digits[i] += 1; 815 | } else { 816 | length += 1; 817 | digits[i] = 1; 818 | } 819 | } 820 | } 821 | } 822 | return createBigInteger(x.sign, digits, length); 823 | }; 824 | BigInteger.signedRightShift = function (x, n) { 825 | return signedRightShift(x, BigInteger.toNumber(n)); 826 | }; 827 | BigInteger.leftShift = function (x, n) { 828 | return signedRightShift(x, 0 - BigInteger.toNumber(n)); 829 | }; 830 | BigInteger.prototype.valueOf = function () { 831 | //throw new TypeError(); 832 | console.error('BigInteger#valueOf is called'); 833 | return this; 834 | }; 835 | 836 | (global || globalThis).BigInteger = BigInteger; 837 | 838 | }(this)); 839 | -------------------------------------------------------------------------------- /benchmark/libs/https___github_com_dankogai_js_math_bigint.js: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: bigint.js,v 0.2 2011/12/13 17:29:51 dankogai Exp dankogai $ 3 | */ 4 | 5 | (function() { 6 | 7 | // Original: http://www.onicos.com/staff/iz/amuse/javascript/expert/BigInt.txt 8 | // 9 | // BigInt.js - Arbitrary size integer math package for JavaScript 10 | // Copyright (C) 2000 Masanao Izumo 11 | // Copyright (C) 2010 Dan Kogai 12 | // Copyright (C) 2014 yottan 13 | // Licence: GPL 14 | // 15 | // This program is free software; you can redistribute it and/or modify 16 | // it under the terms of the GNU General Public License as published by 17 | // the Free Software Foundation; either version 2 of the License, or 18 | // (at your option) any later version. 19 | // 20 | // This program is distributed in the hope that it will be useful, 21 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | // GNU General Public License for more details. 24 | // 25 | // bigint_sub_internal was buggy so rewritten. 26 | 27 | function _BigInt_toString() { 28 | return this.toStringBase(10); 29 | } 30 | 31 | function _BigInt_toStringBase(base) { 32 | var i, j, hbase, t, ds, c; 33 | i = this.len; 34 | if (i === 0) return '0'; 35 | if (i === 1 && !this.digits[0]) return '0'; 36 | switch (base) { 37 | default: 38 | case 10: 39 | j = Math.floor((2 * 8 * i * 241) / 800) + 2; 40 | hbase = 10000; 41 | break; 42 | case 16: 43 | j = Math.floor((2 * 8 * i) / 4) + 2; 44 | hbase = 0x10000; 45 | break; 46 | case 8: 47 | j = (2 * 8 * i) + 2; 48 | hbase = 010000; 49 | break; 50 | case 2: 51 | j = (2 * 8 * i) + 2; 52 | hbase = 020; 53 | break; 54 | } 55 | t = this.clone(); 56 | ds = t.digits; 57 | s = ''; 58 | while (i && j) { 59 | var k = i, num = 0; 60 | while (k--) { 61 | num = (num << 16) + ds[k]; 62 | if (num < 0) num += 4294967296; 63 | ds[k] = Math.floor(num / hbase); 64 | num %= hbase; 65 | } 66 | if (ds[i - 1] === 0) i--; 67 | k = 4; 68 | while (k--) { 69 | c = (num % base); 70 | s = '0123456789abcdef'.charAt(c) + s; 71 | --j; 72 | num = Math.floor(num / base); 73 | if (i === 0 && num === 0) { 74 | break; 75 | } 76 | } 77 | } 78 | i = 0; 79 | while (i < s.length && s.charAt(i) === '0') i++; 80 | if (i) s = s.substring(i, s.length); 81 | if (!this.sign) s = '-' + s; 82 | return s; 83 | } 84 | function _BigInt_clone() { 85 | var i, l, x = new BigInt(this.len, this.sign); 86 | for (i = 0, l = this.len; i < l; i++) x.digits[i] = this.digits[i]; 87 | return x; 88 | } 89 | function BigInt(len, sign) { 90 | var i, x, need_init; 91 | // Setup member functions. 92 | // Note: There is G.C. bug of function() in Netscape! 93 | // Don't use anonymous function. 94 | if (arguments.length === 0) { 95 | this.sign = true; 96 | this.len = len = 1; 97 | this.digits = new Array(1); 98 | need_init = true; 99 | } else if (arguments.length === 1) { 100 | x = bigint_from_any(arguments[0]); 101 | if (x === arguments[0]) x = x.clone(); 102 | this.sign = x.sign; 103 | this.len = x.len; 104 | this.digits = x.digits; 105 | need_init = false; 106 | } else { 107 | this.sign = (sign ? true : false); 108 | this.len = len; 109 | this.digits = new Array(len); 110 | need_init = true; 111 | } 112 | if (need_init) { 113 | for (i = 0; i < len; i++) 114 | this.digits[i] = 0; 115 | } 116 | } 117 | 118 | function bigint_norm(x) { 119 | var len = x.len, ds = x.digits; 120 | while (len-- && len && !ds[len]); 121 | x.len = ++len; 122 | if (x.len === 1 && ds[0] === 0) 123 | { 124 | x.sign = true; 125 | } 126 | return x; 127 | } 128 | function bigint_from_int(n) { 129 | var sign, big, i; 130 | if (n < 0) { 131 | n = -n; 132 | sign = false; 133 | } else { 134 | sign = true; 135 | } 136 | n &= 0x7fffffff; 137 | if (n <= 0xffff) { 138 | big = new BigInt(1, sign); 139 | big.digits[0] = n; 140 | } else { 141 | big = new BigInt(2, sign); 142 | big.digits[0] = (n & 0xffff); 143 | big.digits[1] = ((n >> 16) & 0xffff); 144 | } 145 | return big; 146 | } 147 | function bigint_from_string(str, base) { 148 | var str_i, sign = true, c, len, z, zds, num, i, blen = 1; 149 | str += '@'; // Terminator; 150 | str_i = 0; 151 | // TODO: skip white spaces 152 | if (str.charAt(str_i) === '+') { 153 | str_i++; 154 | } else if (str.charAt(str_i) === '-') { 155 | str_i++; 156 | sign = false; 157 | } 158 | if (str.charAt(str_i) === '@') return null; 159 | if (!base) { 160 | if (str.charAt(str_i) === '0') { 161 | c = str.charAt(str_i + 1); 162 | if (c === 'x' || c === 'X') { 163 | base = 16; 164 | } 165 | else if (c === 'b' || c === 'B') { 166 | base = 2; 167 | } 168 | else { 169 | base = 8; 170 | } 171 | } 172 | else { 173 | base = 10; 174 | } 175 | } 176 | if (base === 8) { 177 | while (str.charAt(str_i) === '0') str_i++; 178 | len = 3 * (str.length - str_i); 179 | } else { // base === 10, 2 or 16 180 | if (base === 16 && str.charAt(str_i) === '0' && 181 | (str.charAt(str_i + 1) === 'x' || str.charAt(str_i + 1) === 'X')) { 182 | str_i += 2; 183 | } 184 | if (base === 2 && str.charAt(str_i) === '0' && 185 | (str.charAt(str_i + 1) === 'b' || str.charAt(str_i + 1) === 'B')) { 186 | str_i += 2; 187 | } 188 | while (str.charAt(str_i) === '0') 189 | str_i++; 190 | if (str.charAt(str_i) === '@') str_i--; 191 | len = 4 * (str.length - str_i); 192 | } 193 | len = (len >> 4) + 1; 194 | z = new BigInt(len, sign); 195 | zds = z.digits; 196 | while (true) { 197 | c = str.charAt(str_i++); 198 | if (c === '@') break; 199 | switch (c) { 200 | case '0': c = 0; break; 201 | case '1': c = 1; break; 202 | case '2': c = 2; break; 203 | case '3': c = 3; break; 204 | case '4': c = 4; break; 205 | case '5': c = 5; break; 206 | case '6': c = 6; break; 207 | case '7': c = 7; break; 208 | case '8': c = 8; break; 209 | case '9': c = 9; break; 210 | case 'a': case 'A': c = 10; break; 211 | case 'b': case 'B': c = 11; break; 212 | case 'c': case 'C': c = 12; break; 213 | case 'd': case 'D': c = 13; break; 214 | case 'e': case 'E': c = 14; break; 215 | case 'f': case 'F': c = 15; break; 216 | default: 217 | c = base; 218 | break; 219 | } 220 | if (c >= base) break; 221 | i = 0; 222 | num = c; 223 | while (true) { 224 | while (i < blen) { 225 | num += zds[i] * base; 226 | zds[i++] = (num & 0xffff); 227 | num >>>= 16; 228 | } 229 | if (num) { 230 | blen++; 231 | continue; 232 | } 233 | break; 234 | } 235 | } 236 | return bigint_norm(z); 237 | } 238 | function bigint_from_any(x) { 239 | if (typeof(x) === 'object') { 240 | return (x instanceof BigInt) ? x : new BigInt(1, true); 241 | } 242 | if (typeof(x) === 'string') { 243 | return bigint_from_string(x); 244 | } 245 | if (typeof(x) === 'number') { 246 | var i, x1, x2, fpt, np; 247 | if (-2147483647 <= x && x <= 2147483647) { 248 | return bigint_from_int(x); 249 | } 250 | x = x + ''; 251 | i = x.indexOf('e', 0); 252 | if (i === -1) return bigint_from_string(x); 253 | x1 = x.substr(0, i); 254 | x2 = x.substr(i + 2, x.length - (i + 2)); 255 | fpt = x1.indexOf('.', 0); 256 | if (fpt != -1) { 257 | np = x1.length - (fpt + 1); 258 | x1 = x1.substr(0, fpt) + x1.substr(fpt + 1, np); 259 | x2 = parseInt(x2) - np; 260 | } else { 261 | x2 = parseInt(x2); 262 | } 263 | while (x2-- > 0) { 264 | x1 += '0'; 265 | } 266 | return bigint_from_string(x1); 267 | } 268 | return new BigInt(1, 1); 269 | } 270 | function bigint_neg(x) { 271 | var z = x.clone(); 272 | z.sign = !z.sign; 273 | return bigint_norm(z); 274 | } 275 | function bigint_add_internal(x, y, ySign) { // ySign is instead of y.sign 276 | if (x.sign !== ySign) { 277 | return bigint_sub_internal(x, y, !ySign); 278 | } 279 | var z, num, i, len = y.len; 280 | if (x.len > y.len) { 281 | len = x.len; 282 | z = x; x = y; y = z; 283 | } 284 | z = new BigInt(++len, ySign); 285 | len = x.len; 286 | for (i = 0, num = 0; i < len; i++) { 287 | num += x.digits[i] + y.digits[i]; 288 | z.digits[i] = (num & 0xffff); 289 | num >>>= 16; 290 | } 291 | len = y.len; 292 | while (num && i < len) { 293 | num += y.digits[i]; 294 | z.digits[i++] = (num & 0xffff); 295 | num >>>= 16; 296 | } 297 | while (i < len) { 298 | z.digits[i] = y.digits[i]; 299 | i++; 300 | } 301 | z.digits[i] = (num & 0xffff); 302 | return bigint_norm(z); 303 | } 304 | function bigint_sub_internal(x, y, ySign) { // ySign is instead of y.sign 305 | if (x.sign !== ySign) { 306 | return bigint_add_internal(x, y, !ySign); 307 | } 308 | var z, len = x.len; 309 | if (x.len < y.len) { 310 | len = y.len; 311 | ySign = !ySign; 312 | z = x; x = y; y = z; // swap x y 313 | } 314 | else if (x.len == y.len) { 315 | while (len-- && (x.digits[len] == y.digits[len])); 316 | if (len < 0) return new BigInt(1, true); 317 | if (x.digits[len] < y.digits[len]) { 318 | ySign = !ySign; 319 | z = x; x = y; y = z; // swap x y 320 | } 321 | len++; 322 | } 323 | 324 | z = new BigInt(len, ySign); 325 | var num, i, zds = z.digits, xds = x.digits, yds = y.digits, minLen = Math.min(y.len, len); 326 | for (i = 0, num = 0; i < minLen; i++) { 327 | num += xds[i] - yds[i]; 328 | zds[i] = (num & 0xffff); 329 | num >>= 16; 330 | } 331 | while (num && i < len) { 332 | num += xds[i]; 333 | zds[i++] = (num & 0xffff); 334 | num >>= 16; 335 | } 336 | while (i < len) { 337 | zds[i] = xds[i]; 338 | i++; 339 | } 340 | return bigint_norm(z); 341 | } 342 | function bigint_add(x, y) { 343 | x = bigint_from_any(x); 344 | y = bigint_from_any(y); 345 | return bigint_add_internal(x, y, y.sign); 346 | } 347 | function bigint_sub(x, y) { 348 | x = bigint_from_any(x); 349 | y = bigint_from_any(y); 350 | return bigint_sub_internal(x, y, y.sign); 351 | } 352 | function bigint_mul(x, y) { 353 | var i, j, n = 0, z, zds, xds, yds, dd, ee, ylen; 354 | x = bigint_from_any(x); 355 | y = bigint_from_any(y); 356 | j = x.len + y.len + 1; 357 | z = new BigInt(j, x.sign === y.sign); 358 | xds = x.digits; 359 | yds = y.digits; 360 | zds = z.digits; 361 | ylen = y.len; 362 | while (j--) zds[j] = 0; 363 | for (i = 0; i < x.len; i++) { 364 | dd = xds[i]; 365 | if (dd === 0) 366 | continue; 367 | n = 0; 368 | for (j = 0; j < ylen; j++) { 369 | ee = n + dd * yds[j]; 370 | n = zds[i + j] + ee; 371 | if (ee) 372 | zds[i + j] = (n & 0xffff); 373 | n >>>= 16; 374 | } 375 | if (n) { 376 | zds[i + j] = n; 377 | } 378 | } 379 | return bigint_norm(z); 380 | } 381 | function bigint_divmod(x, y, modulo) { 382 | var nx = x.len, 383 | ny = y.len, 384 | i, j, 385 | yy, z, 386 | xds, yds, zds, tds, 387 | t2, 388 | num, 389 | dd, q, 390 | ee, 391 | mod, div; 392 | yds = y.digits; 393 | if (ny === 1 && yds[0] === 0) return null; // Division by zero 394 | if (nx < ny || nx === ny && x.digits[nx - 1] < y.digits[ny - 1]) { 395 | if (modulo) return x.clone(); 396 | return new BigInt(1, 1); 397 | } 398 | xds = x.digits; 399 | if (ny === 1) { 400 | dd = yds[0]; 401 | z = x.clone(); 402 | zds = z.digits; 403 | t2 = 0; 404 | i = nx; 405 | while (i--) { 406 | t2 = t2 * 65536 + zds[i]; 407 | zds[i] = (t2 / dd) & 0xffff; 408 | t2 %= dd; 409 | } 410 | z.sign = (x.sign === y.sign); 411 | if (modulo) { 412 | if (!x.sign) t2 = -t2; 413 | return bigint_from_int(t2); 414 | } 415 | return bigint_norm(z); 416 | } 417 | z = new BigInt(nx === ny ? nx + 2 : nx + 1, x.sign === y.sign); 418 | zds = z.digits; 419 | if (nx === ny) zds[nx + 1] = 0; 420 | while (!yds[ny - 1]) ny--; 421 | if ((dd = ((65536 / (yds[ny - 1] + 1)) & 0xffff)) != 1) { 422 | yy = y.clone(); 423 | tds = yy.digits; 424 | j = 0; 425 | num = 0; 426 | while (j < ny) { 427 | num += yds[j] * dd; 428 | tds[j++] = num & 0xffff; 429 | num >>= 16; 430 | } 431 | yds = tds; 432 | j = 0; 433 | num = 0; 434 | while (j < nx) { 435 | num += xds[j] * dd; 436 | zds[j++] = num & 0xffff; 437 | num >>= 16; 438 | } 439 | zds[j] = num & 0xffff; 440 | } 441 | else { 442 | zds[nx] = 0; 443 | j = nx; 444 | while (j--) zds[j] = xds[j]; 445 | } 446 | j = nx === ny ? nx + 1 : nx; 447 | do { 448 | if (zds[j] === yds[ny - 1]) q = 65535; 449 | else q = ((zds[j] * 65536 + zds[j - 1]) / yds[ny - 1]) & 0xffff; 450 | if (q) { 451 | i = 0; num = 0; t2 = 0; 452 | do { // multiply and subtract 453 | t2 += yds[i] * q; 454 | ee = num - (t2 & 0xffff); 455 | num = zds[j - ny + i] + ee; 456 | if (ee) zds[j - ny + i] = num & 0xffff; 457 | num >>= 16; 458 | t2 >>>= 16; 459 | } while (++i < ny); 460 | num += zds[j - ny + i] - t2; // borrow from high digit; don't update 461 | while (num) { // "add back" required 462 | i = 0; num = 0; q--; 463 | do { 464 | ee = num + yds[i]; 465 | num = zds[j - ny + i] + ee; 466 | if (ee) zds[j - ny + i] = num & 0xffff; 467 | num >>= 16; 468 | } while (++i < ny); 469 | num--; 470 | } 471 | } 472 | zds[j] = q; 473 | } while (--j >= ny); 474 | if (modulo) { // just normalize remainder 475 | mod = z.clone(); 476 | if (dd) { 477 | zds = mod.digits; 478 | t2 = 0; i = ny; 479 | while (i--) { 480 | t2 = (t2 * 65536) + zds[i]; 481 | zds[i] = (t2 / dd) & 0xffff; 482 | t2 %= dd; 483 | } 484 | } 485 | mod.len = ny; 486 | mod.sign = x.sign; 487 | return bigint_norm(mod); 488 | } 489 | div = z.clone(); 490 | zds = div.digits; 491 | j = (nx === ny ? nx + 2 : nx + 1) - ny; 492 | for (i = 0; i < j; i++) zds[i] = zds[i + ny]; 493 | div.len = i; 494 | return bigint_norm(div); 495 | } 496 | function bigint_div(x, y) { 497 | x = bigint_from_any(x); 498 | y = bigint_from_any(y); 499 | return bigint_divmod(x, y, 0); 500 | } 501 | function bigint_mod(x, y) { 502 | x = bigint_from_any(x); 503 | y = bigint_from_any(y); 504 | return bigint_divmod(x, y, 1); 505 | } 506 | function bigint_cmp(x, y) { 507 | var xlen; 508 | if (x === y) return 0; // Same object 509 | x = bigint_from_any(x); 510 | y = bigint_from_any(y); 511 | xlen = x.len; 512 | if (x.sign != y.sign) { 513 | if (x.sign) return 1; 514 | return -1; 515 | } 516 | if (xlen < y.len) return (x.sign) ? -1 : 1; 517 | if (xlen > y.len) return (x.sign) ? 1 : -1; 518 | while (xlen-- && (x.digits[xlen] === y.digits[xlen])); 519 | if (-1 === xlen) return 0; 520 | return (x.digits[xlen] > y.digits[xlen]) ? 521 | (x.sign ? 1 : -1) : (x.sign ? -1 : 1); 522 | } 523 | function bigint_number(x) { 524 | var d = 0.0; 525 | var i = x.len; 526 | var ds = x.digits; 527 | while (i--) { 528 | d = ds[i] + 65536.0 * d; 529 | } 530 | if (!x.sign) d = -d; 531 | return d; 532 | } 533 | 534 | /* 535 | * By Dan Kogai 536 | */ 537 | 538 | (function(proto){ 539 | for (var name in proto) BigInt.prototype[name] = proto[name]; 540 | })({ 541 | toString: _BigInt_toString, 542 | toStringBase: _BigInt_toStringBase, 543 | clone: _BigInt_clone, 544 | add: function(y) { return bigint_add(y, this) }, 545 | sub: function(y) { return bigint_sub(this, y) }, 546 | mul: function(y) { return bigint_mul(this, y) }, 547 | div: function(y) { return bigint_div(this, y) }, 548 | mod: function(y) { return bigint_mod(this, y) }, 549 | cmp: function(y) { return bigint_cmp(this, y) }, 550 | neg: function(y) { return bigint_neg(this) }, 551 | VERSION: "2.2.1" 552 | }); 553 | 554 | Math.BigInt = BigInt; 555 | bigint = function(a) { 556 | var x = bigint_from_any(a); 557 | return (x === a) ? x = x.clone() : x; 558 | }; 559 | 560 | })(); 561 | -------------------------------------------------------------------------------- /benchmark/libs/https___github_com_defunctzombie_int.js: -------------------------------------------------------------------------------- 1 | 2 | var Int = function(num) { 3 | // can be called as a function 4 | if (!(this instanceof Int)) { 5 | return new Int(num); 6 | } 7 | 8 | var self = this; 9 | 10 | // copy existing Int object 11 | if (num instanceof Int){ 12 | self._s = num._s; 13 | self._d = num._d.slice(); 14 | return; 15 | } 16 | 17 | // default value 0 18 | num = num || 0; 19 | 20 | // sign 21 | self._s = ((num += '').charAt(0) === '-') ? 1 : 0; 22 | 23 | // digits 24 | self._d = []; 25 | 26 | num = num.replace(/^[+-]/, ''); 27 | var orig = num; 28 | 29 | // remove any leading - or + as well as other invalid characters 30 | num = num.replace(/[^\d]/g, ''); 31 | 32 | // detect if value is not a number 33 | if (orig !== num) { 34 | self._nan = true; 35 | return; 36 | } 37 | 38 | // _d is the array of single digits making up the number 39 | var ln = num.length; 40 | for (var i=0 ; i= 0, j >= 0 ; --i, --j) { 85 | res[i] += carry + a[j]; 86 | carry = 0; 87 | 88 | if (res[i] >= 10) { 89 | res[i] -= 10; 90 | carry = 1; 91 | } 92 | } 93 | 94 | // carry the rest of the way 95 | for (; i >= 0 ; --i) { 96 | res[i] += carry; 97 | carry = 0; 98 | if (res[i] >= 10) { 99 | res[i] -= 10; 100 | carry = 1; 101 | } 102 | 103 | // no carry, rest of the number will be unchanged 104 | if (carry === 0) { 105 | break; 106 | } 107 | } 108 | 109 | // remaining carry? 110 | if (carry > 0) { 111 | res.unshift(1); 112 | } 113 | 114 | return out; 115 | } 116 | 117 | Int.prototype.sub = function(num) { 118 | var self = this; 119 | 120 | // some operations are destructive 121 | var num = Int(num); 122 | 123 | if(self._s != num._s) { 124 | num._s ^= 1; 125 | var res = this.add(num); 126 | num._s ^= 1; 127 | return res; 128 | } 129 | 130 | var s1 = self._s; 131 | var s2 = num._s; 132 | 133 | // make numbers positive for determining the greater one 134 | // in absolute terms 135 | self._s = num._s = 0; 136 | 137 | // make a the smaller number (abs value) 138 | var c = self.lt(num); 139 | var a = c ? self._d : num._d; 140 | var b = c ? num._d : self._d; 141 | 142 | // restore original signs 143 | self._s = s1; 144 | num._s = s2; 145 | 146 | var la = a.length; 147 | var lb = b.length; 148 | 149 | var out = Int((c) ? num : self); 150 | out._s = num._s & self._s; // ?? 151 | var res = out._d; 152 | 153 | // basic subtraction for common size 154 | var borrow = 0; 155 | for (var i = lb - 1, j = la - 1; i >= 0, j >= 0 ; --i, --j) { 156 | res[i] -= a[j] + borrow; 157 | borrow = 0; 158 | 159 | if (res[i] < 0) { 160 | res[i] += 10; 161 | borrow = 1; 162 | } 163 | } 164 | 165 | // carry the rest of the way 166 | for (; i >= 0 ; --i) { 167 | res[i] -= borrow; 168 | borrow = 0; 169 | if (res[i] < 0) { 170 | res[i] += 10; 171 | borrow = 1; 172 | } 173 | 174 | // no carry, rest of the number will be unchanged 175 | if (borrow === 0) { 176 | break; 177 | } 178 | } 179 | 180 | // flip the sign if sub num was larger 181 | c && (out._s ^= 1); 182 | 183 | trim_zeros(out); 184 | 185 | // TODO the subtraction should just be smarter 186 | if (out._d.length === 0) { 187 | out._s = 0; 188 | } 189 | 190 | return out; 191 | }; 192 | 193 | Int.prototype.mul = function(num) { 194 | var self = this; 195 | 196 | var r = self._d.length >= (num = Int(num))._d.length; 197 | var a = (r ? self : num)._d; 198 | var b = (r ? num : self)._d; 199 | 200 | var la = a.length; 201 | var lb = b.length; 202 | 203 | var sum = Int(); 204 | var zeros = []; 205 | 206 | // loop for smaller number 207 | for (var i = lb - 1 ; i >= 0 ; --i) { 208 | var out = Int(); 209 | 210 | // insert proper number of trailing 0s 211 | var val = out._d = out._d.concat(zeros); 212 | 213 | // reset carry 214 | var carry = 0; 215 | 216 | // top number 217 | for (var j = la - 1; j >= 0; --j) { 218 | // multiplication result 219 | var mul = b[i] * a[j] + carry; 220 | 221 | // this is the single digit we keep 222 | var res = mul % 10; 223 | 224 | // carry amount 225 | carry = Math.floor(mul / 10); 226 | 227 | // insert the number into our new integer 228 | val.unshift(res); 229 | } 230 | 231 | // apply any remaining carry 232 | if (carry) { 233 | val.unshift(carry); 234 | } 235 | 236 | sum = sum.add(out); 237 | zeros.push(0); 238 | } 239 | 240 | sum._s = self._s ^ num._s; 241 | return sum; 242 | }; 243 | 244 | Int.prototype.div = function(num) { 245 | var self = this; 246 | 247 | // copy since we change sign of num 248 | var num = Int(num); 249 | 250 | if(num == '0') { 251 | throw new Error('Division by 0'); 252 | } 253 | else if(self == '0') { 254 | return Int(); 255 | } 256 | 257 | // copy since we do destructive things 258 | var numerator = self._d.slice(); 259 | 260 | var quo = Int(); 261 | quo._s = self._s ^ num._s; 262 | 263 | // normalize num to positive number 264 | var orig_s = num._s; 265 | num._s = 0; 266 | 267 | // remainder from previous calculation 268 | var rem = Int(); 269 | 270 | while (numerator.length) { 271 | // long division 272 | // shift numbers off the numerator until we have achieved size 273 | // every number after the first causes a 0 to be inserted 274 | // numbers shifted in from the remainder should not cause 0 insertion 275 | 276 | var c = 0; 277 | while (numerator.length && rem.lt(num)) { 278 | if (c++ > 0) { 279 | quo._d.push(0); 280 | } 281 | 282 | // shift a number from numerator to our running num 283 | rem._d.push(numerator.shift()); 284 | 285 | // important to trim here since 009 - N won't be done right otherwise 286 | trim_zeros(rem); 287 | } 288 | 289 | var count = 0; 290 | while(rem.gte(num) && ++count) { 291 | rem = rem.sub(num); 292 | } 293 | 294 | if (count === 0) { 295 | quo._d.push(0); 296 | break; 297 | } 298 | 299 | quo._d.push(count); 300 | } 301 | 302 | var rlen = rem._d.length; 303 | 304 | if (rlen > 1 || (quo._s && rlen > 0)) { 305 | rem = rem.add(5); 306 | } 307 | 308 | if (quo._s && (rlen !== rem._d.length || rem._d[0] >= 5)) { 309 | quo = quo.sub(1); 310 | } 311 | 312 | // put back the sign of num 313 | num._s = orig_s; 314 | 315 | return trim_zeros(quo); 316 | }; 317 | 318 | Int.prototype.mod = function(num) { 319 | return this.sub(this.div(num).mul(num)); 320 | }; 321 | 322 | Int.prototype.pow = function(num) { 323 | var out = Int(this); 324 | if((num = (Int(num))) == 0) { 325 | return out.set(1); 326 | } 327 | 328 | for(var i = Math.abs(num); --i; out.set(out.mul(this))); 329 | return num < 0 ? out.set((Int(1)).div(out)) : out; 330 | }; 331 | 332 | /// set this number to the value of num 333 | Int.prototype.set = function(num) { 334 | this.constructor(num); 335 | return this; 336 | }; 337 | 338 | /// -1 if self < n, 0 if self == n, 1 if self > n 339 | Int.prototype.cmp = function(num) { 340 | var self = this; 341 | var num = ensure_int(num); 342 | 343 | if (self._s != num._s) { 344 | return self._s ? -1 : 1; 345 | } 346 | 347 | var a = self._d; 348 | var b = num._d; 349 | 350 | var la = a.length; 351 | var lb = b.length; 352 | 353 | if (la != lb) { 354 | return ((la > lb) ^ self._s) ? 1 : -1; 355 | } 356 | 357 | for (var i = 0; i < la; ++i) { 358 | if (a[i] != b[i]) { 359 | return ((a[i] > b[i]) ^ self._s) ? 1 : -1; 360 | } 361 | } 362 | 363 | // no differences 364 | return 0; 365 | }; 366 | 367 | Int.prototype.neg = function() { 368 | var out = Int(this); 369 | out._s ^= 1; 370 | return out; 371 | }; 372 | 373 | Int.prototype.abs = function() { 374 | var out = Int(this); 375 | out._s = 0; 376 | return out; 377 | }; 378 | 379 | // alphabet for converting to a specific base 380 | var alphabet = '0123456789abcdefghijklmnopqrstuvwxyz'; 381 | 382 | Int.prototype.valueOf = Int.prototype.toString = function(radix){ 383 | var self = this; 384 | 385 | if (self._nan) { 386 | return NaN; 387 | } 388 | 389 | if (!radix || radix === 10) { 390 | return (self._s && self._d.length ? '-' : '') + ((self._d.length) ? self._d.join('') : '0'); 391 | } 392 | 393 | if (radix < 2 || radix > 36) { 394 | throw RangeError('radix out of range: ' + radix); 395 | } 396 | 397 | var radix_pow = Math.pow(radix, 6); 398 | 399 | var rem = self; 400 | var result = ''; 401 | while (true) { 402 | var div = rem.div(radix_pow); 403 | var int = rem.sub(div.mul(radix_pow)); 404 | var digits = (+int.toString()).toString(radix); 405 | rem = div; 406 | 407 | if (rem.eq(0)) { 408 | return digits + result; 409 | } 410 | else { 411 | while (digits.length < 6) { 412 | digits = '0' + digits; 413 | } 414 | result = '' + digits + result; 415 | } 416 | } 417 | }; 418 | 419 | Int.prototype.gt = function (num) { 420 | return this.cmp(num) > 0; 421 | }; 422 | 423 | Int.prototype.gte = function (num) { 424 | return this.cmp(num) >= 0; 425 | }; 426 | 427 | Int.prototype.eq = function (num) { 428 | return this.cmp(num) === 0; 429 | }; 430 | 431 | Int.prototype.ne = function (num) { 432 | return this.cmp(num) !== 0; 433 | }; 434 | 435 | Int.prototype.lt = function (num) { 436 | return this.cmp(num) < 0; 437 | }; 438 | 439 | Int.prototype.lte = function (num) { 440 | return this.cmp(num) <= 0; 441 | }; 442 | 443 | /// private api 444 | 445 | function ensure_int(val) { 446 | if (val instanceof Int) { 447 | return val; 448 | } 449 | 450 | return Int(val); 451 | } 452 | 453 | /// remove leading 0's from the int 454 | function trim_zeros(int) { 455 | while (int._d.length && int._d[0] === 0) { 456 | int._d.shift(); 457 | } 458 | 459 | return int; 460 | } 461 | 462 | module.exports = Int; 463 | 464 | -------------------------------------------------------------------------------- /benchmark/libs/https___github_com_tabatkins_bignum.js: -------------------------------------------------------------------------------- 1 | class Z { 2 | constructor(num, base = num.base || Z.defaultBase) { 3 | this.base = base; 4 | this._sign = 1; 5 | this._digits = []; 6 | if(!num) return this; 7 | 8 | if(isNumber(num)) { 9 | return Z._fromNum(num, this); 10 | } else if(typeof num == "string" || num instanceof String) { 11 | return Z._fromString(num, base, this); 12 | } else if(num instanceof Array) { 13 | return Z._fromArray(num, base); 14 | } else if(num instanceof Z) { 15 | this._digits = num._digits.slice(); 16 | this._sign = num.sign; 17 | return this._normalize(); 18 | } else { 19 | throw TypeError("Can't understand type of first argument."); 20 | } 21 | } 22 | 23 | clone() { 24 | return new Z(this); 25 | } 26 | 27 | adopt(that) { 28 | // Mutates this to have the same value as that. 29 | if(isNumber(that)) { 30 | return Z._fromNum(that, this); 31 | } 32 | if(that instanceof Z) { 33 | this._digits = that._digits; 34 | this.sign = that.sign; 35 | this.base = that.base; 36 | return this; 37 | } 38 | console.log(that); 39 | throw new TypeError("Don't know how to adopt the value.", that); 40 | } 41 | 42 | get length() { 43 | return this._digits.length; 44 | } 45 | 46 | get sign() { 47 | if(this.length == 0) return 0; 48 | return this._sign; 49 | } 50 | set sign(val) { 51 | return this._sign = Math.sign(val); 52 | } 53 | 54 | add(that) { 55 | // Fath-path special cases. 56 | if(Z.isZero(that)) return this; 57 | if(this.isZero()) return this.adopt(that); 58 | var digit; 59 | if(digit = singleDigit(that)) { 60 | if(this.sign == 1) this._digits[0] += digit; 61 | else this._digits[0] -= digit; 62 | if(this._digits[0] < 0 || this._digits[0] >= Z._innerBase) this._normalize(); 63 | return this; 64 | } 65 | return this._add(Z.lift(that)); 66 | } 67 | _add(that) { 68 | // Expects that to be a Z. 69 | // Non-destructive; this is just the shared slowpath for add/sub. 70 | var thisSign = this.sign; 71 | var thatSign = that.sign; 72 | var len = Math.max(this._digits.length, that._digits.length); 73 | if(thisSign == thatSign) { 74 | for(var i = 0; i < len; i++) { 75 | this._digits[i] = (this._digits[i]||0) + (that._digits[i]||0); 76 | } 77 | return this._normalize(); 78 | } 79 | this.sign = 1; 80 | that.sign = 1; 81 | if(this.ge(that)) { 82 | for(var i = 0; i < len; i++) { 83 | this._digits[i] = (this._digits[i]||0) - (that._digits[i]||0); 84 | } 85 | this.sign = thisSign; 86 | } else { 87 | for(var i = 0; i < len; i++) { 88 | this._digits[i] = (that._digits[i]||0) - (this._digits[i]||0); 89 | } 90 | this.sign = thatSign; 91 | } 92 | that.sign = thatSign; 93 | return this._normalize(); 94 | } 95 | 96 | sub(that) { 97 | // Fast-path special cases. 98 | if(Z.isZero(that)) return this; 99 | if(this.isZero()) return this.adopt(that).negate(); 100 | var digit; 101 | if(digit = singleDigit(that)) { 102 | if(this.sign == 1) this._digits[0] -= digit; 103 | else this._digits[0] += digit; 104 | if(this._digits[0] < 0 || this._digits[0] >= Z._innerBase) this._normalize(); 105 | return this; 106 | } 107 | // General case 108 | that = Z.lift(that).negate() 109 | this._add(that); 110 | that.negate(); // Restore original sign of that. 111 | return this; 112 | } 113 | 114 | _normalize(that) { 115 | // Put every digit back into the range [0, 2^25) 116 | var carry = 0; 117 | for(var i = 0; i < this.length; i++) { 118 | var digit = (this._digits[i]||0) + carry; 119 | carry = Math.floor(digit / Z._innerBase); 120 | this._digits[i] = (digit % Z._innerBase + Z._innerBase) % Z._innerBase; 121 | } 122 | // If final carry is negative, entire number was negative. 123 | if(carry < 0) { 124 | this.sign *= -1; 125 | carry = -carry - 1; 126 | for(var i = 0; i < this._digits.length; i++) 127 | this._digits[i] = Z._innerBase - this._digits[i] + (i == 0 ? 0 : -1); 128 | } 129 | // If there's any final carry, add more digits. 130 | while(carry > 0) { 131 | this._digits.push(carry % Z._innerBase); 132 | carry = Math.floor(carry / Z._innerBase); 133 | } 134 | // Drop any leading zeros. 135 | for(var i = this._digits.length-1; i>=0; i--) { 136 | if(this._digits[i] === 0) 137 | this._digits.pop(); 138 | else 139 | break; 140 | } 141 | return this; 142 | } 143 | 144 | negate() { 145 | this.sign *= -1; 146 | return this; 147 | } 148 | 149 | abs() { 150 | this.sign = 1; 151 | return this; 152 | } 153 | 154 | mul(that) { 155 | // Fast-path special cases. 156 | if(this.isZero()) return this; 157 | if(Z.isZero(that)) { this._digits = []; return this; } 158 | var thisDigit, thatDigit; 159 | if(thatDigit = singleDigit(that)) { 160 | for(var i = 0; i < this._digits.length; i++) 161 | this._digits[i] *= thatDigit; 162 | return this._normalize(); 163 | } 164 | // General case. 165 | that = Z.lift(that); 166 | var answerSign = this.sign * that.sign; 167 | var thisLength = this._digits.length; 168 | var thatLength = that._digits.length; 169 | var karatsubaBound = 25; // Experimentally determined, but could still be +- 5 or so. 170 | if(thisLength < karatsubaBound || thatLength < karatsubaBound) { 171 | var thisDigits = this._digits.slice(); 172 | // Preload this with first multiplication. 173 | var thatDigit = that._digits[0]; 174 | for(var i = 0; i < thisLength; i++) 175 | this._digits[i] *= thatDigit; 176 | // Manually push multiplied digits from thisClone directly into this, shifted appropriately. 177 | for(var thatIndex = 1; thatIndex < thatLength; thatIndex++) { 178 | var thatDigit = that._digits[thatIndex]; 179 | for(var thisIndex = 0; thisIndex < thisLength; thisIndex++) { 180 | this._digits[thisIndex+thatIndex] = (this._digits[thisIndex+thatIndex]||0) + (thisDigits[thisIndex]||0) * thatDigit; 181 | } 182 | // I have enough wiggle room that 6 or 7 additions can be done without normalizing. 183 | if(thatIndex%6 == 0) this._normalize(); 184 | } 185 | this._normalize(); 186 | } else { 187 | // Karatsuba algorithm 188 | var chunkLength = Math.ceil(thisLength > thatLength ? thisLength/2 : thatLength/2); 189 | var a2 = Z._fromDigits(this._digits.slice(0, chunkLength)); 190 | var a1 = Z._fromDigits(this._digits.slice(chunkLength)); 191 | var b2 = Z._fromDigits(that._digits.slice(0, chunkLength)); 192 | var b1 = Z._fromDigits(that._digits.slice(chunkLength)); 193 | var z0 = Z.mul(a1, b1); 194 | var z2 = Z.mul(a2, b2); 195 | var z1 = a1.add(a2).mul(b1.add(b2)).sub(z0).sub(z2); 196 | var result = z0._shift(chunkLength*2).add(z1._shift(chunkLength)).add(z2); 197 | this._digits = result._digits; 198 | } 199 | this.sign = answerSign; 200 | return this; 201 | } 202 | 203 | _shift(digits) { 204 | if(this._digits.length == 0) return this; 205 | this._digits.reverse(); 206 | for(var i = 0; i < digits; i++) 207 | this._digits.push(0); 208 | this._digits.reverse(); 209 | return this; 210 | } 211 | 212 | pow(exp) { 213 | if(Z.isZero(exp)) return this.adopt(1); 214 | if(this.isZero()) return this; // 0^n = 0 (Except 0^0=1, caught by previous line.) 215 | var expDigit = Z.toNum(exp); 216 | if(expDigit == 1) return this; 217 | if(expDigit == 2) return this.square(); 218 | var digit; 219 | if(expDigit && (digit = posSingleDigit(this))) { 220 | if(digit == 1) return this; // 1^n = 1 221 | // Power of 2 fast-paths 222 | for(var i = 1; i < 25; i++) { 223 | if(digit == Math.pow(2,i) && expDigit*i <= Number.MAX_SAFE_INTEGER) return this.adopt(_pow2(expDigit*i)); 224 | } 225 | // Computable within JS num limits (answer is less than 2^53) 226 | if( (digit == 3 && expDigit <= 33) || 227 | (digit == 5 && expDigit <= 22) || 228 | (digit == 6 && expDigit <= 20) || 229 | (digit == 7 && expDigit <= 18) || 230 | (digit == 9 && expDigit <= 16) || 231 | (digit <= 11 && expDigit <= 15) || 232 | (digit <= 13 && expDigit <= 14) || 233 | (digit <= 16 && expDigit <= 13) || 234 | (digit <= 21 && expDigit <= 12) || 235 | (digit <= 28 && expDigit <= 11) || 236 | (digit <= 39 && expDigit <= 10) || 237 | (digit <= 59 && expDigit <= 9) || 238 | (digit <= 98 && expDigit <= 8) || 239 | (digit <= 190 && expDigit <= 7) || 240 | (digit <= 456 && expDigit <= 6) || 241 | (digit <= 1552 && expDigit <= 5) || 242 | (digit <= 9741 && expDigit <= 4) || 243 | (digit <= 208063 && expDigit <= 3)) 244 | return this.adopt(Math.pow(digit, expDigit)); 245 | // Otherwise, fall through to the slow path! 246 | } 247 | var originalBase = this.clone(); 248 | var bitPattern = Z.digits(exp, 2); 249 | for(var i = 1; i < bitPattern.length; i++) { 250 | this.square(); 251 | if(bitPattern[i] == 1) this.mul(originalBase); 252 | } 253 | return this; 254 | } 255 | 256 | square() { 257 | if(this.isZero()) return this; 258 | this.sign = 1; // Squaring always gives a positive number. 259 | var digit; 260 | if(digit = singleDigit(this)) { 261 | this._digits[0] *= this._digits[0]; 262 | if(this._digits[0] >= Z._innerBase) this._normalize(); 263 | return this; 264 | } 265 | if(this._digits.length < 10) { 266 | var self = this; 267 | var result = self._digits.map(function(d, i) { 268 | var digits = self._digits.map(function(d2){return d*d2;}).reverse(); 269 | for(;i > 0;i--) digits.push(0); 270 | return Z._fromDigits(digits.reverse()); 271 | }).reduce(Z.add, new Z(0)); 272 | this._digits = result._digits; 273 | return this; 274 | } 275 | var chunkLength = Math.ceil(this._digits.length/2); 276 | var high = Z._fromDigits(this._digits.slice(chunkLength)); 277 | this._digits.length = chunkLength; // truncate - one less copy! 278 | var low = this; 279 | var z0 = Z.square(high); 280 | var z2 = Z.square(low); 281 | var z1 = high.add(low).square().sub(z0).sub(z2); 282 | var result = z0._shift(chunkLength*2).add(z1._shift(chunkLength)).add(z2); 283 | this._digits = result._digits; 284 | return this; 285 | } 286 | 287 | powmod(exponent, modulus) { 288 | if(Z.isZero(modulus)) throw "Division by 0 is not allowed."; 289 | if(Z.isZero(exponent)) return this.adopt(1); 290 | if(this.isZero()) return this; 291 | if(Z.toNum(exponent) == 1) return this.mod(modulus); 292 | var digit; 293 | if(digit = posSingleDigit(modulus)) { 294 | var base = this.mod(digit)._digits[0]; 295 | var accum = base; 296 | var bitPattern = Z.digits(exponent, 2); 297 | for(var i = 1; i < bitPattern.length; i++) { 298 | accum = accum * accum % digit; 299 | if(bitPattern[i] == 1) accum = accum * base % digit; 300 | } 301 | return this.adopt(accum); 302 | } 303 | var base = this.mod(modulus).clone(); 304 | var bitPattern = Z.digits(exponent, 2); 305 | for(var i = 1; i < bitPattern.length; i++) { 306 | this.square().mod(modulus); 307 | if(bitPattern[i] == 1) this.mul(base).mod(modulus); 308 | } 309 | return this; 310 | } 311 | 312 | divmod(divisor) { 313 | if(Z.isZero(divisor)) throw "Division by 0 is not allowed."; 314 | if(this.isZero()) return [this, new Z(0)]; 315 | if(singleDigit(divisor)) { 316 | divisor = singleDigit(divisor); 317 | var dividend; 318 | if(dividend = singleDigit(this)) { 319 | return [this.adopt(Math.trunc(dividend/divisor)), new Z(dividend % divisor)]; 320 | } 321 | var remainder = 0; 322 | for(var i = this.length-1; i >= 0; i--) { 323 | remainder = this._digits[i] + remainder * Z._innerBase; 324 | this._digits[i] = Math.trunc(remainder / divisor); 325 | remainder = remainder % divisor; 326 | } 327 | return [this._normalize(), new Z(remainder).mul(this.sign)]; 328 | } else { 329 | // Do the same thing as the above, but with all Zs. 330 | divisor = Z.lift(divisor); 331 | var remainder = new Z(0); 332 | for(var i = this._digits.length -1; i >= 0; i--) { 333 | // aka multiply remainder by innerBase, add current digit 334 | remainder._digits.unshift(this._digits[i]); 335 | var [newDigit, remainder] = _truncDiv(remainder, divisor); 336 | this._digits[i] = newDigit; 337 | } 338 | remainder.sign = this.sign; 339 | return [this._normalize(), remainder]; 340 | } 341 | } 342 | 343 | div(divisor) { 344 | return this.divmod(divisor)[0]; 345 | } 346 | 347 | mod(modulus, remainderPositive) { 348 | if(Z.isZero(modulus)) throw "Division by 0 is not allowed."; 349 | if(this.isZero()) return this; 350 | var digit; 351 | var accumulatedBaseMod; 352 | if(digit = posSingleDigit(modulus)) { 353 | if(this.toNum()) return this.adopt(this.toNum() % digit); 354 | accumulatedBaseMod = 1; 355 | var sum = 0; 356 | for(var i = 0; i < this._digits.length; i++) { 357 | sum = (this._digits[i]%digit * accumulatedBaseMod + sum) % digit; 358 | accumulatedBaseMod = accumulatedBaseMod * Z._innerBase % digit; 359 | } 360 | this._digits[0] = sum; 361 | this._digits.length = 1; 362 | if(remainderPositive == "positive") 363 | this.sign = 1; 364 | else if (this.sign == -1) 365 | this._digits[0] = digit - this._digits[0]; 366 | return this; 367 | } 368 | // For now, just use the full divmod algo. 369 | // Complexity of multi-digit mod is high enough to not be worth implementing yet. 370 | return this.adopt(this.divmod(modulus, remainderPositive)[1]); 371 | } 372 | 373 | factorize() { 374 | let digit; 375 | if(digit = posSingleDigit(this)) { 376 | return Primes.factorize(digit); 377 | } 378 | let factors = new Map(); 379 | let num = this.clone(); 380 | let i = 0; 381 | for(let p of Primes.primes(Z)) { 382 | let count = new Z(0); 383 | while(Z.mod(num, p).isZero()) { 384 | count.add(1); 385 | num.div(p); 386 | } 387 | if(count.isPos()) 388 | factors.set(new Z(p), count); 389 | if(singleDigit(num) === 1) 390 | return factors; 391 | } 392 | } 393 | 394 | lt(that) { 395 | that = new Z(that); 396 | if(this.sign != that.sign) return this.sign < that.sign; 397 | if(this._digits.length != that._digits.length) { 398 | if(this.sign == 1) return this._digits.length < that._digits.length; 399 | else return this._digits.length > that._digits.length; 400 | } 401 | for(var i = this.length - 1; i >= 0; i--) { 402 | if(this._digits[i] < that._digits[i]) 403 | return true; 404 | if(this._digits[i] > that._digits[i]) 405 | return false; 406 | } 407 | return false; 408 | } 409 | 410 | eq(that) { 411 | that = new Z(that); 412 | if(this.sign != that.sign) return false; 413 | if(this._digits.length != that._digits.length) return false; 414 | for(var i = 0; i < this.length; i++) { 415 | if(this._digits[i] != that._digits[i]) 416 | return false; 417 | } 418 | return true; 419 | } 420 | 421 | ne(that) { return !this.eq(that); } 422 | ge(that) { return !this.lt(that); } 423 | le(that) { return this.eq(that) || this.lt(that); } 424 | gt(that) { return !this.le(that); } 425 | 426 | isZero() { 427 | for(var i = 0; i < this._digits.length; i++) 428 | if(this._digits[i] != 0) return false; 429 | return true; 430 | } 431 | 432 | toNum() { 433 | // Converts the Z into a JS num, if possible; otherwise returns false. 434 | if(this.length == 0) return 0; 435 | if(this.length == 1) return this._digits[0] * this.sign; 436 | if(this.length == 2) return (this._digits[0] + this._digits[1]*Z._innerBase)*this.sign; 437 | if(this.length == 3 && this._digits[3] < 8) 438 | return (this._digits[0] + this._digits[1]*Z._innerBase + this._digits[2]*Z._innerBase*Z._innerBase)*this.sign; 439 | return false; 440 | } 441 | 442 | valueOf() { 443 | var val = this.toNum(); 444 | if(val !== false) return val; 445 | return NaN; 446 | } 447 | 448 | isPos() { 449 | return this.sign == 1; 450 | } 451 | 452 | isNeg() { 453 | return this.sign == -1; 454 | } 455 | 456 | digits(base) { 457 | base = Math.floor(base || this.base); 458 | if(base < 2) throw new TypeError("Can't find digits in a base < 2; got "+base); 459 | if(base > Math.MAX_SAFE_INTEGER) throw new TypeError("Base is too large."); 460 | var num = this.clone(); 461 | var digits = []; 462 | do { 463 | digits.push(singleDigit(num.divmod(base)[1])); 464 | } while(!num.isZero()); 465 | return digits.reverse(); 466 | } 467 | 468 | toString(base) { 469 | base = Math.floor(base || this.base); 470 | if(base < 2 || base > 36) 471 | throw TypeError("Can only toString a Z when 2 <= base <= 36."); 472 | var s; 473 | if(s = singleDigit(this)) return s.toString(base); 474 | var result = Z.abs(this).digits(base).map(x=>x.toString(base)).join(''); 475 | if(this.isNeg() && result !== "0") 476 | result = "-" + result; 477 | return result; 478 | } 479 | 480 | __traceToString__() { 481 | return "Z("+(this.sign<0?'-':'+')+'['+this._digits.reverse()+"])"; 482 | } 483 | } 484 | 485 | function _truncDiv(dividend, divisor) { 486 | // Binary search to find trunc(dividend/divisor), 487 | // where both are Zs, 488 | // and dividend is no more than innerBase*divisor 489 | var dividendSign = dividend.sign; 490 | dividend.sign = 1; 491 | var divisorSign = divisor.sign; 492 | divisor.sign = 1; 493 | if(dividend.lt(divisor)) { 494 | dividend.sign = dividendSign; 495 | divisor.sign = divisorSign; 496 | return [0, dividend.clone()]; 497 | } 498 | let low = 1; 499 | let high = Z._innerBase - 1; 500 | let rem = new Z(0); 501 | let candidateProduct = new Z(0); 502 | var loops = 100; 503 | while(loops-->0) { 504 | var n = Math.ceil((low+high)/2); 505 | candidateProduct = Z.mul(divisor, n); 506 | if(candidateProduct.gt(dividend)) { 507 | high = n-1; continue; 508 | } 509 | rem = Z.sub(dividend, candidateProduct); 510 | if(rem.lt(divisor)) { 511 | dividend.sign = dividendSign; 512 | divisor.sign = divisorSign; 513 | return [n*dividendSign*divisorSign, rem.mul(dividendSign)]; 514 | } else { 515 | low = n+1; continue; 516 | } 517 | } 518 | throw new Error("whoops infinite loop") 519 | } 520 | 521 | function _pow2(exp) { 522 | // Quick 2^n - this assumes that the innerBase is a power of 2 (specifically, 2^25). 523 | var n = new Z(0); 524 | while(exp >= 25) { 525 | n._digits.push(0); 526 | exp -= 25; // innerBase exponent 527 | } 528 | n._digits.push(Math.pow(2, exp)); 529 | return n; 530 | } 531 | 532 | function isNumber(x) { 533 | return x instanceof Number || (typeof x) == "number"; 534 | } 535 | 536 | function singleDigit(a) { 537 | // Returns a JS number if arg fits within or contains a single Z digit. 538 | if(isNumber(a) && Math.abs(a) < Z._innerBase) { 539 | return a; 540 | } 541 | if(a instanceof Z) { 542 | if(a.length == 0) return 0; 543 | if(a.length == 1) return a._digits[0] * a._sign; 544 | } 545 | return false; 546 | } 547 | function posSingleDigit(a) { 548 | // Same as digit(), but only returns if the value is positive. 549 | // (useful for some algorithms) 550 | const result = singleDigit(a); 551 | if(a >= 0) return a; 552 | return false; 553 | } 554 | 555 | 556 | 557 | Z.of = function(num) { 558 | return new Z(num); 559 | } 560 | Z.lift = function(num) { 561 | if(num instanceof Z) return num; 562 | return new Z(num); 563 | } 564 | Z._fromNum = function(num, z) { 565 | if(num > Number.MAX_SAFE_INTEGER) throw TypeError("Number is too large to reliably generate a Z from."); 566 | z.sign = Math.sign(num); 567 | num = Math.abs(num); 568 | z._digits = []; 569 | while(num > 0) { 570 | z._digits.push(num % Z._innerBase); 571 | num = Math.floor(num / Z._innerBase); 572 | } 573 | return z; 574 | } 575 | Z._fromString = function(num, base, z) { 576 | var sign = 1; 577 | if(num[0] == "-") { 578 | num = num.slice(1); 579 | sign = -1; 580 | } 581 | var digits = num.split('').map(function(x){ 582 | var digit = parseInt(x,base); 583 | if(Number.isNaN(digit)) 584 | throw TypeError('"'+num+'" is not a base '+base+' number.'); 585 | return digit; 586 | }); 587 | return Z._fromArray(digits, base, sign); 588 | } 589 | Z._fromArray = function(num, base, sign) { 590 | // Put the digits in LSD order. 591 | var digits = num.slice().reverse(); 592 | // First, collect input digits together into a larger base, 593 | // as large as I can get without overshooting innerBase, 594 | // for better efficiency (less steps later). 595 | // Then, just use Z math to do the conversion for me; 596 | // nothing particularly clever going on here. 597 | var size = Math.floor(Math.log(Z._innerBase) / Math.log(base)); 598 | var bigDigits = Math.ceil(digits.length / size); 599 | var pieces = []; 600 | for(var i = 0; i < bigDigits; i++) { 601 | var offset = i*size; 602 | var sum = 0; 603 | for(var j = 0; j < size; j++) { 604 | sum += (digits[offset+j]||0) * Math.pow(base, j); 605 | } 606 | pieces.push(new Z(sum).mul(new Z(base).pow(offset))); 607 | } 608 | var result = pieces.reduce(Z.add, new Z(0)); 609 | result.sign = sign; 610 | return result; 611 | } 612 | Z._fromDigits = function(digits) { 613 | // This function does nothing intelligent. 614 | // It assumes that the digit array is in innerBase already. 615 | var result = new Z(0); 616 | result._digits = digits; 617 | return result; 618 | } 619 | Z._innerBase = Math.pow(2, 25); 620 | Z.defaultBase = 10; 621 | Z.sign = function(a) { 622 | if(isNumber(a)) { 623 | if(a < 0) return -1; 624 | if(a > 0) return 1; 625 | return 0; 626 | } 627 | return Z.lift(a).sign; 628 | } 629 | Z.add = function(a,b) { 630 | return new Z(a).add(b); 631 | } 632 | Z.sub = function(a,b) { 633 | return new Z(a).sub(b); 634 | } 635 | Z.negate = function(a) { 636 | return new Z(a).negate(); 637 | } 638 | Z.abs = function(a) { 639 | return new Z(a).abs(); 640 | } 641 | Z.mul = function(a,b) { 642 | return new Z(a).mul(b); 643 | } 644 | Z.pow = function(a,b) { 645 | return new Z(a).pow(b); 646 | } 647 | Z.square = function(a) { 648 | return new Z(a).square(); 649 | } 650 | Z.powmod = function(a,b,c) { 651 | return new Z(a).powmod(b,c); 652 | } 653 | Z.divmod = function(a,b) { 654 | return new Z(a).divmod(b); 655 | } 656 | Z.div = function(a,b) { 657 | return new Z(a).divmod(b)[0]; 658 | } 659 | Z.mod = function(a,b,remainderPositive) { 660 | return new Z(a).mod(b, remainderPositive); 661 | } 662 | Z.fact = function(num) { 663 | num = Z.toNum(num); 664 | if(num === false) throw "Keep your factorials less than Number.MAX_SAFE_INTEGER, please." 665 | var product = new Z(1); 666 | for(var i = 2; i <= num; i++) 667 | product.mul(i); 668 | return product; 669 | } 670 | Z.lt = function(a,b) { return Z.lift(a).lt(b); } 671 | Z.le = function(a,b) { return Z.lift(a).le(b); } 672 | Z.gt = function(a,b) { return Z.lift(a).gt(b); } 673 | Z.ge = function(a,b) { return Z.lift(a).ge(b); } 674 | Z.eq = function(a,b) { return Z.lift(a).eq(b); } 675 | Z.ne = function(a,b) { return Z.lift(a).ne(b); } 676 | Z.isZero = function(a) { 677 | if(isNumber(a)) return a == 0; 678 | return Z.lift(a).isZero(); 679 | } 680 | Z.toNum = function(a) { 681 | if(isNumber(a) && a >= -Number.MAX_SAFE_INTEGER && a <= Number.MAX_SAFE_INTEGER) return a; 682 | return Z.lift(a).toNum(); 683 | } 684 | Z.isPos = function(a) { 685 | if(isNumber(a)) return a > 0; 686 | return Z.lift(a).isPos(); 687 | } 688 | Z.isNeg = function(a) { 689 | if(isNumber(a)) return a < 0; 690 | return Z.lift(a).isNeg(); 691 | } 692 | Z.adopt = function(a,b) { 693 | return Z.lift(a).adopt(b); 694 | } 695 | Z.digits = function(a, base) { 696 | return Z.lift(a).digits(base); 697 | } 698 | Z.toString = function(a, base) { 699 | if(isNumber(a)) return a.toString(base); 700 | return Z.lift(a).toString(base); 701 | } -------------------------------------------------------------------------------- /benchmark/libs/https___rawgit_com_Yaffle_BigInteger_master_SmallBigInt_js.js: -------------------------------------------------------------------------------- 1 | 2 | (function (global) { 3 | "use strict"; 4 | 5 | function BigIntWrapper() { 6 | } 7 | BigIntWrapper.BigInt = function (x) { 8 | return BigInt(x); 9 | }; 10 | BigIntWrapper.asIntN = function (bits, bigint) { 11 | return BigInt.asIntN(bits, bigint); 12 | }; 13 | BigIntWrapper.asUintN = function (bits, bigint) { 14 | return BigInt.asUintN(bits, bigint); 15 | }; 16 | BigIntWrapper.toNumber = function (bigint) { 17 | return Number(bigint); 18 | }; 19 | BigIntWrapper.add = function (a, b) { 20 | return a + b; 21 | }; 22 | BigIntWrapper.subtract = function (a, b) { 23 | return a - b; 24 | }; 25 | BigIntWrapper.multiply = function (a, b) { 26 | return a * b; 27 | }; 28 | BigIntWrapper.divide = function (a, b) { 29 | return a / b; 30 | }; 31 | BigIntWrapper.remainder = function (a, b) { 32 | return a % b; 33 | }; 34 | BigIntWrapper.unaryMinus = function (a) { 35 | return -a; 36 | }; 37 | BigIntWrapper.equal = function (a, b) { 38 | return a === b; 39 | }; 40 | BigIntWrapper.lessThan = function (a, b) { 41 | return a < b; 42 | }; 43 | BigIntWrapper.greaterThan = function (a, b) { 44 | return a > b; 45 | }; 46 | BigIntWrapper.notEqual = function (a, b) { 47 | return a !== b; 48 | }; 49 | BigIntWrapper.lessThanOrEqual = function (a, b) { 50 | return a <= b; 51 | }; 52 | BigIntWrapper.greaterThanOrEqual = function (a, b) { 53 | return a >= b; 54 | }; 55 | BigIntWrapper.exponentiate = function (a, b) { // a**b 56 | if (typeof a !== "bigint" || typeof b !== "bigint") { 57 | throw new TypeError(); 58 | } 59 | var n = Number(b); 60 | if (n < 0) { 61 | throw new RangeError(); 62 | } 63 | if (n > Number.MAX_SAFE_INTEGER) { 64 | var y = Number(a); 65 | if (y === 0 || y === -1 || y === +1) { 66 | return y === -1 && Number(b % BigInt(2)) === 0 ? -a : a; 67 | } 68 | throw new RangeError(); 69 | } 70 | if (a === BigInt(2)) { 71 | return BigInt(1) << b; 72 | } 73 | if (n === 0) { 74 | return BigInt(1); 75 | } 76 | var x = a; 77 | while (n % 2 === 0) { 78 | n = Math.floor(n / 2); 79 | x *= x; 80 | } 81 | var accumulator = x; 82 | n -= 1; 83 | if (n >= 2) { 84 | while (n >= 2) { 85 | var t = Math.floor(n / 2); 86 | if (t * 2 !== n) { 87 | accumulator *= x; 88 | } 89 | n = t; 90 | x *= x; 91 | } 92 | accumulator *= x; 93 | } 94 | return accumulator; 95 | }; 96 | BigIntWrapper.signedRightShift = function (a, n) { 97 | return a >> n; 98 | }; 99 | BigIntWrapper.leftShift = function (a, n) { 100 | return a << n; 101 | }; 102 | if (Symbol.hasInstance != undefined) { 103 | Object.defineProperty(BigIntWrapper, Symbol.hasInstance, { 104 | value: function (a) { 105 | return typeof a === 'bigint'; 106 | } 107 | }); 108 | } 109 | 110 | var supportsBigInt = Symbol.hasInstance != undefined && 111 | typeof BigInt !== "undefined" && 112 | BigInt(Number.MAX_SAFE_INTEGER) + BigInt(2) - BigInt(2) === BigInt(Number.MAX_SAFE_INTEGER); 113 | 114 | if (supportsBigInt) { 115 | // https://twitter.com/mild_sunrise/status/1339174371550760961 116 | // Chrome < 87 117 | if (((-BigInt('0xffffffffffffffffffffffffffffffff')) >> BigInt(0x40)).toString() !== '-18446744073709551616') { // ((-(2**128 - 1)) >> 64) !== -1 * 2**64 118 | BigIntWrapper.signedRightShift = function (a, n) { 119 | var b = BigInt(1) << n; 120 | return a >= BigInt(0) ? a / b : (a - b + BigInt(1)) / b; 121 | }; 122 | } 123 | } 124 | if (supportsBigInt) { 125 | try { 126 | BigInt(Number.MAX_SAFE_INTEGER + 1); 127 | } catch (error) { 128 | // Chrome 67 129 | BigIntWrapper.BigInt = function (x) { 130 | if (typeof x === "number") { 131 | var e = 0; 132 | var f = x; 133 | while (f >= Number.MAX_SAFE_INTEGER + 1) { 134 | f /= (Number.MAX_SAFE_INTEGER + 1); 135 | e += Math.round(Math.log2(Number.MAX_SAFE_INTEGER + 1)); 136 | } 137 | if (e !== 0) { 138 | return BigInt(f) << BigInt(e); 139 | } 140 | } 141 | return BigInt(x); 142 | }; 143 | } 144 | } 145 | 146 | var Internal = BigIntWrapper; 147 | 148 | // noinline 149 | var n = function (f) { 150 | return function (x, y) { 151 | return f(x, y); 152 | }; 153 | }; 154 | 155 | var cache = new Array(16 * 2 + 1); 156 | for (var i = 0; i < cache.length; i += 1) { 157 | cache[i] = undefined; 158 | } 159 | function LastTwoMap() { 160 | this.a = undefined; 161 | this.aKey = 0; 162 | this.b = undefined; 163 | this.bKey = 0; 164 | this.last = 0; 165 | } 166 | LastTwoMap.prototype.get = function (key) { 167 | if (this.aKey === key) { 168 | this.last = 0; 169 | return this.a; 170 | } 171 | if (this.bKey === key) { 172 | this.last = 1; 173 | return this.b; 174 | } 175 | return undefined; 176 | }; 177 | LastTwoMap.prototype.set = function (key, value) { 178 | if (this.last === 0) { 179 | this.bKey = key; 180 | this.b = value; 181 | this.last = 1; 182 | } else { 183 | this.aKey = key; 184 | this.a = value; 185 | this.last = 0; 186 | } 187 | }; 188 | var map = new LastTwoMap(); // to optimize when some number is multiplied by few numbers sequencely 189 | var toNumber = n(function (a) { 190 | return Internal.toNumber(a); 191 | }); 192 | var valueOf = function (x) { 193 | if (typeof x === "number") { 194 | if (x >= -16 && x <= +16) { 195 | var value = cache[x + 16]; 196 | if (value == undefined) { 197 | value = Internal.BigInt(x); 198 | cache[x + 16] = value; 199 | } 200 | return value; 201 | } 202 | var value = map.get(x); 203 | if (value == undefined) { 204 | value = Internal.BigInt(x); 205 | map.set(x, value); 206 | } 207 | return value; 208 | } 209 | return x; 210 | }; 211 | var toResult = function (x) { 212 | var value = Internal.toNumber(x); 213 | if (value >= -9007199254740991 && value <= 9007199254740991) { 214 | return value; 215 | } 216 | return x; 217 | }; 218 | var add = n(function (x, y) { 219 | if (typeof x === "string" || typeof y === "string") { 220 | return x + y; 221 | } 222 | if (typeof x === "number" && x === 0) { 223 | return y; 224 | } 225 | if (typeof y === "number" && y === 0) { 226 | return x; 227 | } 228 | var a = valueOf(x); 229 | var b = valueOf(y); 230 | var sum = Internal.add(a, b); 231 | return typeof x === "number" && typeof y === "number" ? sum : toResult(sum); 232 | }); 233 | var subtract = n(function (x, y) { 234 | if (typeof x === "number" && x === 0) { 235 | return unaryMinus(y); 236 | } 237 | // quite good optimization for comparision of big integers 238 | if (typeof y === "number" && y === 0) { 239 | return x; 240 | } 241 | var a = valueOf(x); 242 | var b = valueOf(y); 243 | var difference = Internal.subtract(a, b); 244 | return typeof x === "number" && typeof y === "number" ? difference : toResult(difference); 245 | }); 246 | var multiply = n(function (x, y) { 247 | if (typeof x === "number" && x === 0) { 248 | return 0; 249 | } 250 | if (typeof x === "number" && x === 1) { 251 | return y; 252 | } 253 | if (typeof x === "number" && x === -1) { 254 | return Internal.unaryMinus(y); 255 | } 256 | if (typeof y === "number" && y === 0) { 257 | return 0; 258 | } 259 | if (typeof y === "number" && y === 1) { 260 | return x; 261 | } 262 | if (typeof y === "number" && y === -1) { 263 | return Internal.unaryMinus(x); 264 | } 265 | var a = valueOf(x); 266 | var b = valueOf(y); 267 | return Internal.multiply(a, b); 268 | }); 269 | var divide = n(function (x, y) { 270 | if (typeof x === "number") { 271 | return 0; 272 | } 273 | if (typeof y === "number" && y === 1) { 274 | return x; 275 | } 276 | if (typeof y === "number" && y === -1) { 277 | return Internal.unaryMinus(x); 278 | } 279 | var a = valueOf(x); 280 | var b = valueOf(y); 281 | return toResult(Internal.divide(a, b)); 282 | }); 283 | var remainder = n(function (x, y) { 284 | if (typeof x === "number") { 285 | return x; 286 | } 287 | if (typeof y === "number" && y === 1) { 288 | return 0; 289 | } 290 | if (typeof y === "number" && y === -1) { 291 | return 0; 292 | } 293 | var a = valueOf(x); 294 | var b = valueOf(y); 295 | return toResult(Internal.remainder(a, b)); 296 | }); 297 | var exponentiate = n(function (x, y) { 298 | if (typeof y === "number") { 299 | if (y === 0) { 300 | return 1; 301 | } 302 | if (y === 1) { 303 | return x; 304 | } 305 | if (y === 2) { 306 | return multiply(x, x); 307 | } 308 | if (typeof x === "number" && Math.abs(x) > 2 && y >= 0) { 309 | if (y > 42 && x % 2 === 0) {//TODO: ? 310 | return multiply(exponentiate(2, y), exponentiate(x / 2, y)); 311 | } 312 | var k = Math.floor(Math.log(9007199254740991) / Math.log(Math.abs(x) + 0.5)); 313 | if (k >= 2) { 314 | return multiply(Math.pow(x, y % k), exponentiate(Math.pow(x, k), Math.floor(y / k))); 315 | } 316 | } 317 | } 318 | var a = valueOf(x); 319 | var b = valueOf(y); 320 | var power = Internal.exponentiate(a, b); 321 | return typeof x === "number" && Math.abs(x) <= 1 ? toResult(power) : power; 322 | }); 323 | var unaryMinus = n(function (x) { 324 | var a = valueOf(x); 325 | return Internal.unaryMinus(a); 326 | }); 327 | var equal = n(function (x, y) { 328 | if (typeof x === "number") { 329 | return false; 330 | } 331 | if (typeof y === "number") { 332 | return false; 333 | } 334 | return Internal.equal(x, y); 335 | }); 336 | var lessThan = n(function (x, y) { 337 | if (typeof x === "number") { 338 | return x < Internal.toNumber(y); 339 | } 340 | if (typeof y === "number") { 341 | return Internal.toNumber(x) < y; 342 | } 343 | return Internal.lessThan(x, y); 344 | }); 345 | var greaterThan = n(function (x, y) { 346 | if (typeof x === "number") { 347 | return x > Internal.toNumber(y); 348 | } 349 | if (typeof y === "number") { 350 | return Internal.toNumber(x) > y; 351 | } 352 | return Internal.greaterThan(x, y); 353 | }); 354 | 355 | function SmallBigInt() { 356 | } 357 | 358 | // Conversion from String: 359 | // Conversion from Number: 360 | SmallBigInt.BigInt = function (x) { 361 | if (typeof x === "number" || typeof x === "string" || typeof x === "bigint") { 362 | var value = 0 + (typeof x === "number" ? x : Number(x)); 363 | if (value >= -9007199254740991 && value <= 9007199254740991) { 364 | return value; 365 | } 366 | } 367 | return toResult(Internal.BigInt(x)); 368 | }; 369 | SmallBigInt.asIntN = function (n, x) { 370 | return toResult(Internal.asIntN(n, Internal.BigInt(x))); 371 | }; 372 | SmallBigInt.asUintN = function (n, x) { 373 | if (typeof x === "number" && x >= 0 && n >= 0 && n <= 53) { 374 | var m = Math.pow(2, n); 375 | return x - Math.floor(x / m) * m; 376 | } 377 | return toResult(Internal.asUintN(n, Internal.BigInt(x))); 378 | }; 379 | // Conversion to Number: 380 | SmallBigInt.toNumber = function (x) { 381 | if (typeof x === "number") { 382 | return x; 383 | } 384 | return toNumber(x); 385 | }; 386 | 387 | // Arithmetic: 388 | SmallBigInt.add = function (x, y) { 389 | if (typeof x === "number" && typeof y === "number") { 390 | var value = x + y; 391 | if (value >= -9007199254740991 && value <= 9007199254740991) { 392 | return value; 393 | } 394 | } 395 | return add(x, y); 396 | }; 397 | SmallBigInt.subtract = function (x, y) { 398 | if (typeof x === "number" && typeof y === "number") { 399 | var value = x - y; 400 | if (value >= -9007199254740991 && value <= 9007199254740991) { 401 | return value; 402 | } 403 | } 404 | return subtract(x, y); 405 | }; 406 | SmallBigInt.multiply = function (x, y) { 407 | if (typeof x === "number" && typeof y === "number") { 408 | var value = 0 + x * y; 409 | if (value >= -9007199254740991 && value <= 9007199254740991) { 410 | return value; 411 | } 412 | } 413 | return multiply(x, y); 414 | }; 415 | SmallBigInt.divide = function (x, y) { 416 | if (typeof x === "number" && typeof y === "number") { 417 | if (y !== 0) { 418 | return x === 0 ? 0 : (x > 0 && y > 0) || (x < 0 && y < 0) ? 0 + Math.floor(x / y) : 0 - Math.floor((0 - x) / y); 419 | } 420 | } 421 | return divide(x, y); 422 | }; 423 | SmallBigInt.remainder = function (x, y) { 424 | if (typeof x === "number" && typeof y === "number") { 425 | if (y !== 0) { 426 | return 0 + x % y; 427 | } 428 | } 429 | return remainder(x, y); 430 | }; 431 | SmallBigInt.unaryMinus = function (x) { 432 | if (typeof x === "number") { 433 | return 0 - x; 434 | } 435 | return unaryMinus(x); 436 | }; 437 | 438 | // Comparison: 439 | SmallBigInt.equal = function (x, y) { 440 | if (typeof x === "number" && typeof y === "number") { 441 | return x === y; 442 | } 443 | return equal(x, y); 444 | }; 445 | SmallBigInt.lessThan = function (x, y) { 446 | if (typeof x === "number" && typeof y === "number") { 447 | return x < y; 448 | } 449 | return lessThan(x, y); 450 | }; 451 | SmallBigInt.greaterThan = function (x, y) { 452 | if (typeof x === "number" && typeof y === "number") { 453 | return x > y; 454 | } 455 | return greaterThan(x, y); 456 | }; 457 | SmallBigInt.notEqual = function (x, y) { 458 | return !SmallBigInt.equal(x, y); 459 | }; 460 | SmallBigInt.lessThanOrEqual = function (x, y) { 461 | return !SmallBigInt.greaterThan(x, y); 462 | }; 463 | SmallBigInt.greaterThanOrEqual = function (x, y) { 464 | return !SmallBigInt.lessThan(x, y); 465 | }; 466 | 467 | SmallBigInt.exponentiate = function (x, y) { 468 | if (typeof x === "number" && typeof y === "number") { 469 | if (y >= 0 && (y < 53 || x >= -1 && x <= 1)) { // 53 === log2(9007199254740991 + 1) 470 | var value = 0 + Math.pow(x, y); 471 | if (value >= -9007199254740991 && value <= 9007199254740991) { 472 | return value; 473 | } 474 | } 475 | } 476 | return exponentiate(x, y); 477 | }; 478 | SmallBigInt.signedRightShift = function (x, n) { 479 | return toResult(Internal.signedRightShift(valueOf(x), valueOf(n))); 480 | }; 481 | SmallBigInt.leftShift = function (x, n) { 482 | if (typeof n === "number" && typeof x === "number" && n >= 0) { 483 | var value = n === 0 ? x : x * Math.pow(2, n); 484 | if (value >= -9007199254740991 && value <= 9007199254740991) { 485 | return value; 486 | } 487 | } 488 | return toResult(Internal.leftShift(valueOf(x), valueOf(n))); 489 | }; 490 | if (Symbol.hasInstance != undefined) { 491 | Object.defineProperty(SmallBigInt, Symbol.hasInstance, { 492 | value: function (a) { 493 | return typeof a === 'number' || a instanceof Internal; 494 | } 495 | }); 496 | } 497 | 498 | (global || globalThis).SmallBigInt = SmallBigInt; 499 | 500 | (global || globalThis).JSBI = supportsBigInt ? BigIntWrapper : ((global || globalThis).JSBI || (global || globalThis).BigInteger); 501 | Internal = (global || globalThis).JSBI; 502 | 503 | }(this)); 504 | -------------------------------------------------------------------------------- /benchmark/randomTestsGenerator.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 116 | -------------------------------------------------------------------------------- /benchmark/test-generator.html: -------------------------------------------------------------------------------- 1 | 2 | 122 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js-big-integer", 3 | "description": "Yet another class for arbitrary-precision integers in pure JavaScript. Small. Well tested.", 4 | "version": "3.0.26", 5 | "keywords": [ 6 | "BigInteger", 7 | "BigNumber", 8 | "bigint", 9 | "bignum", 10 | "arbitrary-precision", 11 | "integer" 12 | ], 13 | "files": [ 14 | "./BigInteger.js", 15 | "./SmallBigInt.js" 16 | ], 17 | "main": "BigInteger.js", 18 | "repositories": [ 19 | { 20 | "type": "git", 21 | "url": "https://github.com/Yaffle/BigInteger" 22 | } 23 | ], 24 | "homepage": "https://github.com/Yaffle/BigInteger" 25 | } 26 | --------------------------------------------------------------------------------