UNPKG

@arithmetic-operations-for/naturals-big-endian

Version:

Arbitrary precision arithmetic for integers in big endian order for JavaScript

1 lines 146 kB
{"version":3,"file":"index.cjs","sources":["../src/core/array/_copy.js","../src/core/arithmetic/add/_add.js","../src/api/arithmetic/add/add.js","../src/core/arithmetic/add/_iadd.js","../src/api/arithmetic/add/iadd.js","../src/api/arithmetic/add/increment.js","../src/core/arithmetic/div/_idivmod_limb_with_prefix.js","../src/core/arithmetic/div/_idivmod_limb.js","../src/core/array/_alloc.js","../src/core/array/_fill.js","../src/core/array/_reset.js","../src/core/array/_zeros.js","../src/core/arithmetic/mul/_mul_limb.js","../src/api/compare/jz.js","../src/core/convert/_trim_positive.js","../src/core/compare/_cmp_n.js","../src/core/compare/_cmp.js","../src/api/compare/cmp.js","../src/api/compare/lt.js","../src/core/arithmetic/sub/_isub.js","../src/core/compare/_cmp_half_even_radix.js","../src/core/compare/_cmp_half_odd_radix.js","../src/api/compare/gt.js","../src/core/arithmetic/div/_idivmod_schoolbook_subroutine_do.js","../src/core/arithmetic/div/_idivmod_schoolbook_subroutine.js","../src/core/arithmetic/div/_idivmod_schoolbook_large_divisor.js","../src/core/arithmetic/div/_div_limb_with_prefix.js","../src/core/arithmetic/div/_idivmod_schoolbook.js","../src/core/arithmetic/mul/_imul_limb.js","../src/core/arithmetic/mul/_schoolbook_mul.js","../src/core/arithmetic/mul/_karatsuba_right_op_is_small.js","../src/core/arithmetic/mul/_karatsuba.js","../src/core/arithmetic/mul/_mul.js","../src/core/thresholds/THRESHOLD_MUL_TOOM22.js","../src/api/arithmetic/sub/decrement.js","../src/core/arithmetic/div/_idivmod_dc_32.js","../src/core/arithmetic/div/_idivmod_dc_21.js","../src/core/thresholds/THRESHOLD_DIV_DC.js","../src/core/arithmetic/div/_mod_limb.js","../src/core/arithmetic/div/_idivmod_dc.js","../src/api/arithmetic/div/_idivmod.js","../src/core/arithmetic/div/_imod_limb.js","../src/core/arithmetic/div/_imod_schoolbook_subroutine_do.js","../src/core/arithmetic/div/_imod_schoolbook_subroutine.js","../src/core/arithmetic/div/_imod_schoolbook_large_divisor.js","../src/core/arithmetic/div/_imod_schoolbook.js","../src/api/arithmetic/div/_imod.js","../src/core/arithmetic/gcd/_euclidean_algorithm_loop.js","../src/core/arithmetic/gcd/_extended_euclidean_algorithm_allocate.js","../src/api/arithmetic/mul/mul.js","../src/core/arithmetic/gcd/_extended_euclidean_algorithm_loop.js","../src/core/arithmetic/gcd/_extended_euclidean_algorithm.js","../src/core/convert/_log.js","../src/core/convert/_convert_to_smaller_fast.js","../src/core/convert/_convert_to_smaller_slow.js","../src/core/array/_build.js","../src/core/arithmetic/pow/_pow_double.js","../src/core/arithmetic/add/_iadd_limb.js","../src/core/convert/_convert_to_larger_slow.js","../src/core/convert/_convert_slow.js","../src/core/convert/_convert_dc.js","../src/core/convert/_convert_to_smaller.js","../src/core/thresholds/THRESHOLD_CONVERT_DC.js","../src/core/convert/_convert_to_larger_fast.js","../src/core/convert/_convert_to_larger.js","../src/core/convert/_convert.js","../src/core/convert/convert_keep_zeros.js","../src/core/convert/trim_natural.js","../src/api/convert/convert.js","../src/core/convert/_int.js","../src/core/convert/_from_string.js","../src/core/convert/parse_keep_zeros.js","../src/api/convert/parse.js","../src/core/convert/_chr.js","../src/core/convert/_to_string.js","../src/api/convert/stringify.js","../src/core/arithmetic/sub/_sub.js","../src/core/arithmetic/mul/_toom22.js","../src/core/compare/_cmp_half.js","../src/api/arithmetic/div/_divmod.js","../src/core/arithmetic/div/_idivmod_slow.js","../src/core/arithmetic/pow/_pow_double_recursive.js","../src/core/array/_validate.js","../src/api/compare/eq.js","../src/api/arithmetic/gcd/euclidean_algorithm.js","../src/api/arithmetic/gcd/extended_euclidean_algorithm.js","../src/api/compare/ge.js","../src/api/compare/le.js","../src/api/compare/ne.js","../src/api/convert/translate.js"],"sourcesContent":["import assert from 'assert';\n\n/**\n * Copy a limb array into another limb array.\n *\n * @param {number[]} a The copied limb array.\n * @param {number} ai\n * @param {number} aj\n * @param {number[]} b The destination limb array.\n * @param {number} bi\n */\nexport default function _copy(a, ai, aj, b, bi) {\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0);\n\tassert(b.length - bi >= aj - ai);\n\n\tfor (; ai < aj; ++ai, ++bi) b[bi] = a[ai];\n\t// While ( ai < aj ) b[++bi] = a[++ai] ;\n}\n","import assert from 'assert';\nimport _copy from '../../array/_copy.js';\n\n/**\n * Adds two big endian arrays and puts result in a destination array.\n * Wraps on overflow. |C| >= |A| >= |B|.\n *\n * @param {Number} r base (radix)\n * @param {Array} a first operand\n * @param {Number} ai a left\n * @param {Number} aj a right\n * @param {Array} b second operand\n * @param {Number} bi b left\n * @param {Number} bj b right\n * @param {Array} c result, must be 0 initialized\n * @param {Number} ci c left\n * @param {Number} cj c right\n */\n\nexport default function _add(r, a, ai, aj, b, bi, bj, c, ci, cj) {\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(ci >= 0 && cj <= c.length);\n\tassert(cj - ci >= aj - ai);\n\tassert(aj - ai >= bj - bi);\n\n\tlet C = 0;\n\n\twhile (--bj >= bi) {\n\t\tconst t = a[--aj] + b[bj] + C;\n\t\tc[--cj] = t % r;\n\t\tC = (t >= r) | 0;\n\t}\n\n\tif (C !== 0) {\n\t\twhile (--aj >= ai && a[aj] === r - 1) c[--cj] = 0;\n\t\tif (--cj >= ci) {\n\t\t\tif (aj >= ai) {\n\t\t\t\tc[cj] = a[aj] + 1;\n\t\t\t} else c[cj] = 1;\n\t\t}\n\t}\n\n\t_copy(a, ai, aj, c, cj - aj + ai);\n}\n","import _add from '../../../core/arithmetic/add/_add.js';\n\n/**\n * Adds two big endian arrays and puts result in a destination array.\n * Wraps on overflow. Works with any combination of array sizes.\n *\n * @param {Number} r base (radix)\n * @param {Array} a first operand\n * @param {Number} ai a left\n * @param {Number} aj a right\n * @param {Array} b second operand\n * @param {Number} bi b left\n * @param {Number} bj b right\n * @param {Array} c result, must be 0 initialized\n * @param {Number} ci c left\n * @param {Number} cj c right\n *\n */\nexport default function add(r, a, ai, aj, b, bi, bj, c, ci, cj) {\n\tci = Math.max(0, ci);\n\tconst k = cj - ci;\n\n\tai = Math.max(0, ai, aj - k);\n\tbi = Math.max(0, bi, bj - k);\n\tconst m = aj - ai;\n\tconst n = bj - bi;\n\n\treturn m < n\n\t\t? _add(r, b, bi, bj, a, ai, aj, c, ci, cj)\n\t\t: _add(r, a, ai, aj, b, bi, bj, c, ci, cj);\n}\n","import assert from 'assert';\n\n/**\n * Adds a big endian array to another.\n * Wraps on overflow. |A| >= |B|.\n *\n * @param {Number} r base (radix)\n * @param {Array} a first operand\n * @param {Number} ai a left\n * @param {Number} aj a right\n * @param {Array} b second operand\n * @param {Number} bi b left\n * @param {Number} bj b right\n */\n\nexport default function _iadd(r, a, ai, aj, b, bi, bj) {\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(aj - ai >= bj - bi);\n\n\tlet C = 0;\n\n\twhile (--bj >= bi) {\n\t\tconst T = a[--aj] + b[bj] + C;\n\t\ta[aj] = T % r;\n\t\tC = (T >= r) | 0;\n\t}\n\n\tif (C !== 0) {\n\t\twhile (--aj >= ai && a[aj] === r - 1) a[aj] = 0;\n\t\tif (aj >= ai) ++a[aj];\n\t}\n}\n","import _iadd from '../../../core/arithmetic/add/_iadd.js';\n\n/**\n * Adds a big endian array to another ___in-place___.\n * Wraps on overflow. Works with any combination of array sizes.\n *\n * @param {Number} r base (radix)\n * @param {Array} a first operand (modified in-place)\n * @param {Number} ai a left\n * @param {Number} aj a right\n * @param {Array} b second operand\n * @param {Number} bi b left\n * @param {Number} bj b right\n */\nexport default function iadd(r, a, ai, aj, b, bi, bj) {\n\tconst m = aj - ai;\n\n\treturn _iadd(r, a, ai, aj, b, Math.max(bi, bj - m), bj);\n}\n","import assert from 'assert';\n\n/**\n * Adds 1 to a big endian array.\n *\n * Wraps on overflow. Hence, does nothing if aj <= ai.\n *\n * O(|A|) time in the worst case.\n * O(1) amortized time over any number of successive operations starting with A = O(1).\n * O(1) amortized time over O(|A|) successive operations starting with any A.\n *\n * @param {Number} r radix\n * @param {Array} a first operand\n * @param {Number} ai a left\n * @param {Number} aj a right\n */\nexport default function increment(r, a, ai, aj) {\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\n\tconst _r = r - 1;\n\n\twhile (--aj >= ai) {\n\t\tif (a[aj] < _r) {\n\t\t\t++a[aj];\n\t\t\treturn;\n\t\t}\n\n\t\ta[aj] = 0;\n\t}\n}\n","import assert from 'assert';\n\n/**\n * Divides a big endian number by a single limb number.\n * Can only work with limbs of size at most sqrt( 2^53 ).\n * Allows to prefix the dividend with an intermediate remainder.\n *\n * Input\n * -----\n * - |Q| = |D| >= 1.\n * - NO NEED to reset Q. The loop will set every member of Q.\n *\n * @param {Number} r The radix.\n * @param {Number} tmp Intermediate remainder (MUST be <code>< d</code>).\n * @param {Number} d The divisor >= 1.\n * @param {Array} D The dividend.\n * @param {Number} Di Left of dividend.\n * @param {Number} Dj Right of dividend.\n * @param {Array} Q The quotient.\n * @param {Number} Qi Left of quotient.\n */\nexport default function _idivmod_limb_with_prefix(r, tmp, d, D, Di, Dj, Q, Qi) {\n\tassert(r >= 2);\n\n\tassert(d >= 1 && d <= r - 1);\n\tassert(tmp >= 0 && tmp <= d - 1);\n\n\tassert(Di >= 0 && Dj <= D.length);\n\tassert(Qi >= 0);\n\n\tassert(Dj - Di <= Q.length - Qi);\n\tassert(Dj - Di >= 1);\n\n\twhile (Di < Dj) {\n\t\ttmp *= r;\n\t\ttmp += D[Di];\n\n\t\tQ[Qi] = (tmp / d) | 0;\n\t\ttmp %= d;\n\t\tD[Di] = 0;\n\n\t\t++Qi;\n\t\t++Di;\n\t}\n\n\tD[Dj - 1] = tmp;\n}\n","import _idivmod_limb_with_prefix from './_idivmod_limb_with_prefix.js';\n\n/**\n * Divides a big endian number by a single limb number.\n * Can only work with limbs of size at most sqrt( 2^53 ).\n *\n * @param {Number} r The radix.\n * @param {Number} d The divisor.\n * @param {Array} D The dividend.\n * @param {Number} Di Left of dividend.\n * @param {Number} Dj Right of dividend.\n * @param {Array} Q The quotient.\n * @param {Number} Qi Left of quotient.\n */\nexport default function _idivmod_limb(r, d, D, Di, Dj, Q, Qi) {\n\t// Simply prefix the dividend with 0\n\treturn _idivmod_limb_with_prefix(r, 0, d, D, Di, Dj, Q, Qi);\n}\n","import assert from 'assert';\n\n/**\n * Allocate a new limb array.\n *\n * @param {number} n The size of the array to allocate.\n *\n * @return {number[]} The new limb array.\n */\nexport default function _alloc(n) {\n\tassert(n >= 0);\n\n\treturn new Array(n);\n}\n","import assert from 'assert';\n\n/**\n * Fill the input limb array with a fixed value.\n *\n * @param {number[]} a input limb array\n * @param {number} ai\n * @param {number} aj\n * @param {number} v the value used to fill the input array\n */\nexport default function _fill(a, ai, aj, v) {\n\tassert(ai >= 0);\n\tassert(aj <= a.length);\n\tassert(aj - ai >= 0);\n\tassert(typeof v === 'number');\n\n\tfor (let i = ai; i < aj; ++i) a[i] = v;\n}\n","import assert from 'assert';\nimport _fill from './_fill.js';\n\n/**\n * Fill the input limb array with zeros.\n *\n * @param {number[]} a input limb array\n * @param {number} ai\n * @param {number} aj\n */\nexport default function _reset(a, ai, aj) {\n\tassert(ai >= 0);\n\tassert(aj <= a.length);\n\tassert(aj - ai >= 0);\n\n\t_fill(a, ai, aj, 0);\n}\n","import assert from 'assert';\nimport _alloc from './_alloc.js';\nimport _reset from './_reset.js';\n\n/**\n * Allocate a new limb array filled with zeros.\n *\n * @param {number} n The size of the allocated array.\n *\n * @return {number[]} The newly allocated array.\n */\nexport default function _zeros(n) {\n\tassert(n >= 0);\n\n\tconst a = _alloc(n);\n\n\t_reset(a, 0, n);\n\n\treturn a;\n}\n","import assert from 'assert';\n\n/**\n * Compute x * b where x is a single limb.\n * 0 <= x <= r-1\n * No restriction on operand sizes.\n */\n\nexport default function _mul_limb(r, x, b, bi, bj, c, ci, cj) {\n\tassert(r >= 2);\n\tassert(x >= 0 && x <= r - 1);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(ci >= 0 && cj <= c.length);\n\n\tlet C = 0;\n\n\twhile (true) {\n\t\t--bj;\n\t\t--cj;\n\n\t\tif (bj < bi) {\n\t\t\tif (cj >= ci) c[cj] = C;\n\t\t\treturn;\n\t\t}\n\n\t\tif (cj < ci) return;\n\n\t\tconst t = b[bj] * x + C;\n\n\t\tc[cj] = t % r;\n\n\t\tC = (t / r) | 0;\n\t}\n}\n","import assert from 'assert';\n\n/**\n * Returns true if and only if input number A is 0.\n *\n * Returns true if aj <= ai.\n * O(|A|) time in the worst case.\n * O(1) time if A has no leading zero.\n *\n * @param {number[]} a first operand\n * @param {number} ai a left\n * @param {number} aj a right\n * @return {boolean} true if and only if input number is 0.\n */\n\nexport default function jz(a, ai, aj) {\n\tassert(ai >= 0 && aj <= a.length);\n\n\tfor (; ai < aj; ++ai) if (a[ai] !== 0) return false;\n\n\treturn true;\n}\n","import assert from 'assert';\n\n/**\n * Compute the new inclusive left bound of a limb array by skipping all\n * leading zeros.\n *\n * @param {number[]} a The input limb array.\n * @param {number} ai\n * @param {number} aj\n *\n * @return {number} The new inclusive left bound of the input.\n */\nexport default function _trim_positive(a, ai, aj) {\n\tassert(ai >= 0 && aj <= a.length);\n\n\twhile (ai < aj && a[ai] === 0) ++ai;\n\n\treturn ai;\n}\n","import assert from 'assert';\n\n/**\n * Compares two big endian arrays.\n *\n * Input:\n * - |A| = |B|\n *\n * @param {number[]} a first operand\n * @param {number} ai a left\n * @param {number} aj a right\n * @param {number[]} b second operand\n * @param {number} bi b left\n *\n * @return {number} 1 if a > b; 0 if a = b; -1 otherwise.\n */\n\nexport default function _cmp_n(a, ai, aj, b, bi) {\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0);\n\tassert(b.length - bi >= aj - ai);\n\n\tfor (; ai < aj; ++ai, ++bi) {\n\t\tif (a[ai] > b[bi]) return 1;\n\t\tif (a[ai] < b[bi]) return -1;\n\t}\n\n\treturn 0;\n}\n","import assert from 'assert';\n\nimport _cmp_n from './_cmp_n.js';\n\n/**\n * Compares two big endian arrays. The second operand cannot have more limbs\n * than the first.\n *\n * Input:\n * - |A| >= |B| >= 0\n *\n * @param {number[]} a first operand\n * @param {number} ai a left\n * @param {number} aj a right\n * @param {number[]} b second operand\n * @param {number} bi b left\n * @param {number} bj b right\n *\n * @return {number} result 1 if a > b; 0 if a = b; -1 otherwise.\n */\n\nexport default function _cmp(a, ai, aj, b, bi, bj) {\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(aj - ai >= bj - bi);\n\tassert(bj - bi >= 0);\n\n\tconst tmp = aj - bj + bi;\n\n\tfor (; ai < tmp; ++ai) if (a[ai] > 0) return 1;\n\n\tassert(aj - ai === bj - bi);\n\treturn _cmp_n(a, ai, aj, b, bi);\n}\n","import _cmp from '../../core/compare/_cmp.js';\n\n/**\n * Compares two big endian arrays with little constraints on the operands.\n *\n * Input:\n * - |A| >= 0\n * - |B| >= 0\n *\n * @param {number[]} a first operand\n * @param {number} ai a left\n * @param {number} aj a right\n * @param {number[]} b second operand\n * @param {number} bi b left\n * @param {number} bj b right\n *\n * @return {number} result 1 if a > b; 0 if a = b; -1 otherwise.\n */\n\nexport default function cmp(a, ai, aj, b, bi, bj) {\n\tif (aj - ai < bj - bi) return -_cmp(b, bi, bj, a, ai, aj);\n\treturn _cmp(a, ai, aj, b, bi, bj);\n}\n","import cmp from './cmp.js';\n\n/**\n * Compares two big endian arrays: returns true if the first is less than\n * the second.\n *\n * Input:\n * - |A| >= 0\n * - |B| >= 0\n *\n * @param {number[]} a first operand\n * @param {number} ai a left\n * @param {number} aj a right\n * @param {number[]} b second operand\n * @param {number} bi b left\n * @param {number} bj b right\n *\n * @return {boolean} true iff A < B.\n */\nconst lt = (a, ai, aj, b, bi, bj) => cmp(a, ai, aj, b, bi, bj) < 0;\nexport default lt;\n","import assert from 'assert';\n\n/**\n * Subtracts B from A, |A| >= |B|.\n * Wraps.\n *\n * @param {Number} r base (radix)\n * @param {array} a first operand\n * @param {Number} ai a left\n * @param {Number} aj a right\n * @param {array} b second operand\n * @param {Number} bi b left\n * @param {Number} bj b right\n */\n\nexport default function _isub(r, a, ai, aj, b, bi, bj) {\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(aj - ai >= bj - bi);\n\n\tlet C = 0;\n\n\twhile (--bj >= bi) {\n\t\t--aj;\n\t\tconst T = C;\n\t\tC = (a[aj] < b[bj] + T) | 0;\n\t\ta[aj] = a[aj] - b[bj] + (C * r - T);\n\t}\n\n\tif (C !== 0) {\n\t\twhile (--aj >= ai && a[aj] === 0) a[aj] = r - 1;\n\t\tif (aj >= ai) --a[aj];\n\t}\n}\n","import assert from 'assert';\n\nimport jz from '../../api/compare/jz.js';\n\nexport default function _cmp_half_even_radix(_r, a, ai, aj) {\n\tassert(_r >= 1);\n\tassert(ai >= 0 && aj <= a.length);\n\n\tif (ai >= aj || a[ai] < _r) return -1;\n\tif (a[ai] > _r) return 1;\n\treturn jz(a, ai + 1, aj) ? 0 : 1;\n}\n","import assert from 'assert';\n\nexport default function _cmp_half_odd_radix(_r, a, ai, aj) {\n\tassert(_r >= 1);\n\tassert(ai >= 0 && aj <= a.length);\n\n\tfor (; ai < aj; ++ai) {\n\t\tif (a[ai] > _r) return 1;\n\t\tif (a[ai] < _r) return -1;\n\t}\n\n\treturn -1;\n}\n","import cmp from './cmp.js';\n\n/**\n * Compares two big endian arrays: returns true if the first is greater than\n * the second.\n *\n * Input:\n * - |A| >= 0\n * - |B| >= 0\n *\n * @param {number[]} a first operand\n * @param {number} ai a left\n * @param {number} aj a right\n * @param {number[]} b second operand\n * @param {number} bi b left\n * @param {number} bj b right\n *\n * @return {boolean} true iff A > B.\n */\nconst gt = (a, ai, aj, b, bi, bj) => cmp(a, ai, aj, b, bi, bj) > 0;\nexport default gt;\n","import assert from 'assert';\n\nimport _zeros from '../../array/_zeros.js';\nimport _validate from '../../array/_validate.js';\nimport gt from '../../../api/compare/gt.js';\nimport _isub from '../sub/_isub.js';\nimport _mul_limb from '../mul/_mul_limb.js';\n\nimport _cmp_half from '../../compare/_cmp_half.js';\n\n/**\n * Input\n * -----\n * - Two integers A and B such that 0 <= A < B * β and (β^n)/2 <= B < β^n.\n * (Hence B >= 1).\n * - |A| = |B| + 1\n * - |Q| = |A|\n *\n * Output\n * -----\n * The quotient floor( A/B ) and the remainder A mod B.\n *\n * @param {Number} r The radix.\n * @param {Array} a Dividend.\n * @param {Number} ai Left of dividend.\n * @param {Number} aj Right of dividend.\n * @param {Array} b Divisor.\n * @param {Number} bi Left of divisor.\n * @param {Number} bj Right of divisor.\n * @param {Array} q Quotient.\n * @param {Number} qi Left of quotient.\n */\nexport default function _idivmod_schoolbook_subroutine_do(\n\tr,\n\ta,\n\tai,\n\taj,\n\tb,\n\tbi,\n\tbj,\n\tq,\n\tqi,\n) {\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(qi >= 0);\n\tassert(aj - ai === bj - bi + 1); // |a| = |b| + 1\n\tassert(q.length - qi >= aj - ai); // |q| >= |a|\n\tassert(_cmp_half(r, b, bi, bj) >= 0); // (r^n)/2 <= B < r^n\n\tassert(gt(b, bi, bj, a, ai, aj - 1)); // A < B * β\n\tassert(_validate(r, q, qi, qi + aj - ai));\n\n\tconst m = aj - ai;\n\n\t// Since A < B*β, then A/B < β\n\t// q <- min [ ( β a_0 + a_1 ) / b_0 , β - 1 ]\n\tlet _q = Math.min(r - 1, Math.floor((a[ai] * r + a[ai + 1]) / b[bi]));\n\n\t// Fix _q\n\tconst T = _zeros(m);\n\t_mul_limb(r, _q, b, bi, bj, T, 0, m);\n\n\tif (gt(T, 0, m, a, ai, aj)) {\n\t\t--_q;\n\t\t_isub(r, T, 0, m, b, bi, bj);\n\n\t\tif (gt(T, 0, m, a, ai, aj)) {\n\t\t\t--_q;\n\t\t\t_isub(r, T, 0, m, b, bi, bj);\n\t\t}\n\t}\n\n\tq[qi + m - 1] += _q;\n\n\t_isub(r, a, ai, aj, T, 0, m);\n}\n","import assert from 'assert';\n\nimport _cmp_half from '../../compare/_cmp_half.js';\nimport _cmp_n from '../../compare/_cmp_n.js';\nimport increment from '../../../api/arithmetic/add/increment.js';\nimport _isub from '../sub/_isub.js';\nimport _idivmod_schoolbook_subroutine_do from './_idivmod_schoolbook_subroutine_do.js';\n\n/**\n * Input\n * -----\n * - Two integers A and B such that 0 <= A < β^(n+1) and (β^n)/2 <= B < β^n.\n * - |A| = |B| + 1\n * - |Q| = |A|\n *\n * Output\n * -----\n * The quotient floor( A/B ) and the remainder A mod B.\n *\n * @param {Number} r The radix.\n * @param {Array} a Dividend.\n * @param {Number} ai Left of dividend.\n * @param {Number} aj Right of dividend.\n * @param {Array} b Divisor.\n * @param {Number} bi Left of divisor.\n * @param {Number} bj Right of divisor.\n * @param {Array} q Quotient.\n * @param {Number} qi Left of quotient.\n */\nexport default function _idivmod_schoolbook_subroutine(\n\tr,\n\ta,\n\tai,\n\taj,\n\tb,\n\tbi,\n\tbj,\n\tq,\n\tqi,\n) {\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(qi >= 0);\n\tassert(q.length - qi >= aj - ai);\n\tassert(aj - ai === bj - bi + 1); // |A| = |B| + 1\n\tassert(q.length - qi >= aj - ai); // |Q| >= |A|\n\tassert(_cmp_half(r, b, bi, bj) >= 0); // (β^n)/2 <= B < β^n\n\n\t// If A ≥ B*β, compute the quotient q and remainder r of ( A − B*β ) / B\n\t// and return β + q and r.\n\t// Note that then A − B*β < B*β since A < 2 B*β because of the\n\t// preconditions above. Hence the preconditions hold for\n\t// _idivmod_schoolbook_subroutine_do.\n\tif (_cmp_n(a, ai, aj - 1, b, bi) >= 0) {\n\t\t_isub(r, a, ai, aj - 1, b, bi, bj);\n\t\t_idivmod_schoolbook_subroutine_do(r, a, ai, aj, b, bi, bj, q, qi);\n\t\tincrement(r, q, qi, qi + aj - ai - 1);\n\t} else {\n\t\t_idivmod_schoolbook_subroutine_do(r, a, ai, aj, b, bi, bj, q, qi);\n\t}\n}\n","import assert from 'assert';\n\nimport _trim_positive from '../../convert/_trim_positive.js';\nimport lt from '../../../api/compare/lt.js';\nimport _validate from '../../array/_validate.js';\nimport _isub from '../sub/_isub.js';\nimport _cmp_half from '../../compare/_cmp_half.js';\nimport _idivmod_schoolbook_subroutine from './_idivmod_schoolbook_subroutine.js';\n\n/**\n * Input\n * -----\n * - Two integers A and B such that r^(m-1) <= A < r^m and (r^n)/2 <= B < r^(n).\n * - No leading zeros (ONLY IN B?)\n * - Q is initialized with some limbs.\n *\n * Output\n * -----\n * The quotient floor( A/B ) and the remainder A mod B.\n *\n * @param {Number} r The radix.\n * @param {Array} a Dividend.\n * @param {Number} ai Left of dividend.\n * @param {Number} aj Right of dividend.\n * @param {Array} b Divisor.\n * @param {Number} bi Left of divisor.\n * @param {Number} bj Right of divisor.\n * @param {Array} q Quotient.\n * @param {Number} qi Left of quotient.\n */\nexport default function _idivmod_schoolbook_large_divisor(\n\tr,\n\ta,\n\tai,\n\taj,\n\tb,\n\tbi,\n\tbj,\n\tq,\n\tqi,\n) {\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(qi >= 0);\n\tassert(q.length - qi >= aj - ai);\n\t// Assert(aj - ai <= 0 || a[ai] !== 0); // no leading zero NOT TRUE ?\n\tassert(_cmp_half(r, b, bi, bj) >= 0); // (r^n)/2 <= B < r^n (+ no leading zero)\n\tassert(_validate(r, q, qi, qi + aj - ai));\n\n\twhile (true) {\n\t\t// Non-recursive\n\n\t\tconst m = aj - ai;\n\t\tconst n = bj - bi;\n\n\t\t// If m < n, return the quotient 0 and the remainder A.\n\t\tif (m < n) return;\n\n\t\tif (m === n) {\n\t\t\t// If m = n, then if A < B, return the quotient 0 and the remainder A;\n\t\t\tif (lt(a, ai, aj, b, bi, bj)) return;\n\n\t\t\t// If A ≥ B, return the quotient 1 and the remainder A - B.\n\t\t\t++q[qi + m - 1];\n\t\t\t_isub(r, a, ai, aj, b, bi, bj);\n\t\t\treturn;\n\t\t}\n\n\t\t// If m = n + 1, compute the quotient and remainder of A/B\n\t\t// using algorithm 3.1 and return them.\n\t\tif (m === n + 1)\n\t\t\treturn _idivmod_schoolbook_subroutine(r, a, ai, aj, b, bi, bj, q, qi);\n\n\t\t// 4. A' <- A/β^{m-n-1} and s <- A mod β^{m-n-1}\n\t\tconst _aj = ai + n + 1;\n\n\t\t// 5. Compute the quotient q' and the remainder r' of A'/B using algorithm 3.1.\n\t\t_idivmod_schoolbook_subroutine(r, a, ai, _aj, b, bi, bj, q, qi);\n\n\t\t// 6. Compute the quotient q and remainder r of( β^{m-n-1} r' + s ) / B recursively.\n\t\tconst ak = _trim_positive(a, ai, _aj);\n\t\t// _idivmod_schoolbook_large_divisor( r , a , ak , aj , b , bi , bj , q , qi + ak - ai ) ;\n\t\tqi += ak - ai; // Non recursive because some implementation\n\t\tai = ak; // Do not have tail-call optimization ?\n\n\t\t// 7. Return the quotient Q = β^{m-n-1} q' + q and remainder R = r\n\t}\n}\n","import assert from 'assert';\n\n/**\n * Divides a big endian number by a single limb number.\n * Can only work with limbs of size at most sqrt( 2^53 ).\n * Allows to prefix the dividend with an intermediate remainder.\n *\n * Does not update the remainder.\n *\n * Input\n * -----\n * - 0 <= tmp <= d - 1\n * - 1 <= d <= r - 1\n * - |Q| = |D|\n *\n * @param {Number} r The radix.\n * @param {Number} tmp Intermediate remainder (MUST be <code>< d</code>).\n * @param {Number} d The divisor >= 1.\n * @param {Array} D The dividend (NOT modified).\n * @param {Number} Di Left of dividend.\n * @param {Number} Dj Right of dividend.\n * @param {Array} Q The quotient.\n * @param {Number} Qi Left of quotient.\n */\nexport default function _div_limb_with_prefix(r, tmp, d, D, Di, Dj, Q, Qi) {\n\tassert(r >= 2);\n\tassert(d >= 1 && d <= r - 1);\n\tassert(tmp >= 0 && tmp <= d - 1);\n\tassert(Di >= 0 && Dj <= D.length);\n\tassert(Qi >= 0);\n\tassert(Dj - Di <= Q.length - Qi);\n\n\twhile (Di < Dj) {\n\t\ttmp *= r;\n\t\ttmp += D[Di];\n\n\t\tQ[Qi] = (tmp / d) | 0;\n\t\ttmp %= d;\n\n\t\t++Qi;\n\t\t++Di;\n\t}\n}\n","import assert from 'assert';\n\nimport _zeros from '../../array/_zeros.js';\nimport _copy from '../../array/_copy.js';\nimport _mul_limb from '../mul/_mul_limb.js';\nimport jz from '../../../api/compare/jz.js';\nimport _idivmod_schoolbook_large_divisor from './_idivmod_schoolbook_large_divisor.js';\nimport _div_limb_with_prefix from './_div_limb_with_prefix.js';\n\n/**\n * Computes q <- a / b and a <- a % b.\n * No leading zeros allowed.\n * q has length at least aj - ai\n *\n * @param {Number} r The radix.\n * @param {Array} a Dividend / Remainder.\n * @param {Number} ai\n * @param {Number} aj\n * @param {Array} b Divisor.\n * @param {Number} bi\n * @param {Number} bj\n * @param {Array} q Quotient.\n * @param {Number} qi\n */\nexport default function _idivmod_schoolbook(r, a, ai, aj, b, bi, bj, q, qi) {\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(qi >= 0);\n\tassert(q.length - qi >= aj - ai);\n\tassert(aj - ai <= 0 || a[ai] !== 0); // No leading zero\n\tassert(bj - bi >= 1 && b[bi] !== 0); // No leading zero\n\tassert(jz(q, qi, qi + aj - ai));\n\n\tconst _r = Math.ceil(r / 2);\n\tconst x = b[bi];\n\n\tif (x < _r) {\n\t\t// We need x to be >= _r so we multiply b by ceil( _r / x )\n\t\t// this gives us <= ( 1 + _r / x ) b < r^(bj-bi)\n\t\t// (this can be implemented faster using bit shifts if r = 2^k )\n\t\tconst z = Math.ceil(_r / x);\n\t\tconst m = aj - ai + 1;\n\t\tconst n = bj - bi;\n\n\t\tconst _a = _zeros(m);\n\t\t_mul_limb(r, z, a, ai, aj, _a, 0, m);\n\n\t\tconst _b = _zeros(n);\n\t\t_mul_limb(r, z, b, bi, bj, _b, 0, n);\n\n\t\tconst _q = _zeros(m);\n\t\t_idivmod_schoolbook_large_divisor(r, _a, 0, m, _b, 0, n, _q, 0);\n\t\t_div_limb_with_prefix(r, _a[0], z, _a, 1, m, a, ai);\n\t\t_copy(_q, 1, m, q, qi);\n\t} else _idivmod_schoolbook_large_divisor(r, a, ai, aj, b, bi, bj, q, qi);\n}\n","import assert from 'assert';\n\n/**\n * Multiply b by x where x is a single limb.\n *\n * Also works when x === r (by accident, needed for extensive test of\n * _convert_dc). In that case we check that r*(r-1) <= 2^53 - 1.\n * Maximum possible value for this to work is r = 94906266.\n *\n * TODO define constant. Reuse elsewhere?\n */\nexport default function _imul_limb(r, x, b, bi, bj) {\n\tassert(r >= 2);\n\tassert(r <= 94_906_266);\n\tassert(x >= 0 && x <= r);\n\tassert(bi >= 0 && bj <= b.length);\n\n\tlet C = 0;\n\n\twhile (--bj >= bi) {\n\t\tconst t = b[bj] * x + C;\n\n\t\tb[bj] = t % r;\n\n\t\tC = (t / r) | 0;\n\t}\n}\n","import assert from 'assert';\n\n/**\n * Computes the product of two big endian arrays using schoolbook\n * multiplication. |C| >= |A|+|B|.\n *\n * TODO Can this be optimized if we know that |A| >= |B|?\n * Probably better to do many small passes rather than few large passes ?!\n * This is what this implementation achieves, although it returns correct\n * results even when |A| < |B|.\n */\n\nexport default function _schoolbook_mul(r, a, ai, aj, b, bi, bj, c, ci, cj) {\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(ci >= 0 && cj <= c.length);\n\tassert(cj - ci >= aj - ai + (bj - bi));\n\n\tconst m = aj - ai;\n\tconst n = bj - bi;\n\t--aj;\n\t--bj;\n\t--cj;\n\n\tfor (let i = 0; i < m; ++i) {\n\t\tlet q = 0;\n\n\t\tfor (let j = 0; j < n; ++j) {\n\t\t\t// T will never exceed (r-1) * (r+1) = r^2 - 1\n\t\t\t// We must have r^2 - 1 <= 2^53 - 1\n\t\t\t// Hence r <= 2^{53/2} = 94906265.62425156.\n\t\t\t// Hence r <= 94906265.\n\t\t\tconst t = c[cj - i - j] + q + a[aj - i] * b[bj - j];\n\t\t\tc[cj - i - j] = t % r;\n\t\t\tq = (t / r) | 0; // Will never exceed r-1\n\t\t}\n\n\t\tc[cj - i - n] = q;\n\t}\n}\n","import assert from 'assert';\nimport _zeros from '../../array/_zeros.js';\nimport _iadd from '../add/_iadd.js';\nimport _mul from './_mul.js';\n\n/**\n *\n * Multiply two big endian arrays using karatsuba algorithm,\n * WHEN THE SECOND OPERAND IS SMALL.\n * |A| >= |B| >= 1, |C| >= |A| + |B|, |A| >= 2, Math.ceil(|A|/2) >= |B|.\n *\n * /!\\ BLOCK MULTIPLICATION RESULT MUST HOLD IN THE JAVASCRIPT NUMBER TYPE\n * (DOUBLE i.e. 53 bits)\n *\n * EXPLANATION\n * ###########\n *\n * We consider the numbers a and b0. a has size N = 2n, and b0 has size n.\n *\n * We divide a into its lower and upper parts.\n *\n * a = a1 r^{n} + a0 (1)\n *\n * We express the product of a and b0 using these.\n *\n * a b0 = (a1 r^{n} + a0) b0 (3)\n * = a1 b0 r^{n} + a0 b0 (4)\n *\n * This gives us 2 multiplications with operands of size n.\n *\n * @param {Number} r base (radix)\n * @param {Array} a first operand\n * @param {Number} ai a left\n * @param {Number} aj a right\n * @param {Array} b second operand\n * @param {Number} bi b left\n * @param {Number} bj b right\n * @param {Array} c result, must be 0 initialized\n * @param {Number} ci c left\n * @param {Number} cj c right\n */\n\nexport default function _karatsuba_right_op_is_small(\n\tr,\n\ta,\n\tai,\n\taj,\n\tb,\n\tbi,\n\tbj,\n\tc,\n\tci,\n\tcj,\n) {\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(ci >= 0 && cj <= c.length);\n\tassert(aj - ai >= 2);\n\tassert(bj - bi >= 1);\n\tassert(aj - ai >= bj - bi);\n\tassert(cj - ci >= aj - ai + (bj - bi));\n\n\tconst i = aj - ai;\n\tconst j = bj - bi;\n\n\tconst n = Math.ceil(i / 2);\n\n\tassert(j <= n);\n\n\tconst N = n + j;\n\tconst N_ = i - n + j;\n\tconst i_ = aj - n;\n\n\tconst z = _zeros(N_); // Need tmp variable since _mul overwrites\n\n\t// RECURSIVE CALLS\n\t_mul(r, a, i_, aj, b, bi, bj, c, cj - N, cj); // C += a0.b0\n\tif (j === n) {\n\t\t// NOTE If j === n and i is odd then j === floor(i/2) + 1\n\t\t// which leads to all sorts of problems. If i is even, this is\n\t\t// equivalent to the other branch, but we avoid the use of an extra\n\t\t// conditional.\n\t\t// TODO Find a better way to handle this edge case. Maybe upstream?\n\t\t_mul(r, b, bi, bj, a, ai, i_, z, 0, N_); // Z = a1.b0\n\t} else {\n\t\t_mul(r, a, ai, i_, b, bi, bj, z, 0, N_); // Z = a1.b0\n\t}\n\n\t_iadd(r, c, ci, cj - n, z, 0, N_); // C += a1.b0 . r^{n}\n}\n","import assert from 'assert';\nimport add from '../../../api/arithmetic/add/add.js';\nimport iadd from '../../../api/arithmetic/add/iadd.js';\nimport _zeros from '../../array/_zeros.js';\nimport _copy from '../../array/_copy.js';\nimport _isub from '../sub/_isub.js';\nimport _mul from './_mul.js';\nimport _karatsuba_right_op_is_small from './_karatsuba_right_op_is_small.js';\n\n/**\n *\n * Multiply two big endian arrays using karatsuba algorithm,\n * |A| >= |B| >= 1, |C| >= |A| + |B|, |A| >= 2.\n *\n * /!\\ BLOCK MULTIPLICATION RESULT MUST HOLD IN THE JAVASCRIPT NUMBER TYPE\n * (DOUBLE i.e. 53 bits)\n *\n * EXPLANATION\n * ###########\n *\n * We consider the numbers a and b, both of size N = 2n.\n *\n * We divide a and b into their lower and upper parts.\n *\n * a = a1 r^{n} + a0 (1)\n * b = b1 r^{n} + b0 (2)\n *\n * We express the product of a and b using their lower and upper parts.\n *\n * a b = (a1 r^{n} + a0) (b1 r^{n} + b0) (3)\n * = a1 b1 r^{2n} + (a1 b0 + a0 b1) r^{n} + a0 b0 (4)\n *\n * This gives us 4 multiplications with operands of size n.\n * Using a simple trick, we can reduce this computation to 3 multiplications.\n *\n * We give the 3 terms of (4) the names z0, z1 and z2.\n *\n * z2 = a1 b1\n * z1 = a1 b0 + a0 b1\n * z0 = a0 b0\n *\n * a b = z2 r^{2n} + z1 r^{n} + z0\n *\n * We then express z1 using z0, z2 and one additional multiplication.\n *\n * (a1 + a0)(b1 + b0) = a1 b1 + a0 b0 + (a1 b0 + a0 b1)\n * = z2 + z0 + z1\n *\n * z1 = (a1 + a0)(b1 + b0) - z2 - z0\n *\n * AN ANOTHER WAY AROUND (not used here)\n *\n * (a1 - a0)(b1 - b0) = (a1 b1 + a0 b0) - (a1 b0 + a0 b1)\n * (a0 - a1)(b1 - b0) = (a1 b0 + a0 b1) - (a1 b1 + a0 b0)\n * a b = (r^{2n} + r^{n})a1 b1 + r^{n}(a0 - a1)(b1 - b0) + (r^{n} + 1)a0 b0\n *\n * This algorithm is a specific case of the Toom-Cook algorithm, when m = n =\n * 2.\n *\n * For further reference, see\n * - http://en.wikipedia.org/wiki/Karatsuba_algorithm\n * - http://en.wikipedia.org/wiki/Toom–Cook_multiplication\n *\n * @param {Number} r base (radix)\n * @param {Array} a first operand\n * @param {Number} ai a left\n * @param {Number} aj a right\n * @param {Array} b second operand\n * @param {Number} bi b left\n * @param {Number} bj b right\n * @param {Array} c result, must be 0 initialized\n * @param {Number} ci c left\n * @param {Number} cj c right\n */\n\nexport default function _karatsuba(r, a, ai, aj, b, bi, bj, c, ci, cj) {\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(ci >= 0 && cj <= c.length);\n\tassert(aj - ai >= 2);\n\tassert(bj - bi >= 1);\n\tassert(aj - ai >= bj - bi);\n\tassert(cj - ci >= aj - ai + (bj - bi));\n\n\tconst i = aj - ai;\n\tconst j = bj - bi;\n\n\tconst n = Math.ceil(i / 2);\n\n\tif (j <= n)\n\t\treturn _karatsuba_right_op_is_small(r, a, ai, aj, b, bi, bj, c, ci, cj);\n\n\tconst I = i + j;\n\tconst N = 2 * n;\n\tconst N_ = I - N;\n\tconst i_ = aj - n;\n\tconst j_ = bj - n;\n\n\tconst t1 = _zeros(n + 1); // + 1 to handle addition overflows\n\tconst t2 = _zeros(n + 1); // And guarantee reducing k for the\n\tconst t3 = _zeros(N + 2); // Recursive calls\n\tconst z2 = _zeros(N_);\n\tconst z0 = _zeros(N);\n\n\t// RECURSIVE CALLS\n\t_mul(r, a, ai, i_, b, bi, j_, z2, 0, N_); // Z2 = a1.b1\n\t_mul(r, a, i_, aj, b, j_, bj, z0, 0, N); // Z0 = a0.b0\n\tadd(r, a, ai, i_, a, i_, aj, t1, 0, n + 1); // (a0 + a1)\n\tadd(r, b, bi, j_, b, j_, bj, t2, 0, n + 1); // (b1 + b0)\n\t_mul(r, t1, 1, n + 1, t2, 1, n + 1, t3, 2, N + 2); // (a0 + a1)(b1 + b0)\n\n\t// BUILD OUTPUT\n\t_copy(z2, 0, N_, c, cj - I); // + z2 . r^{2n}\n\t_copy(z0, 0, N, c, cj - N); // + z0\n\n\t// overflow on t1, add t2 . r^{n}\n\tif (t1[0]) iadd(r, t3, 0, n + 2, t2, 0, n + 1);\n\n\t// Overflow on t2, add t1 . r^{n} (except t1[0])\n\tif (t2[0]) iadd(r, t3, 0, n + 2, t1, 1, n + 1);\n\n\tiadd(r, c, ci, cj - n, t3, 0, N + 2); // + (a0 + a1)(b1 + b0) . r^{n}\n\t_isub(r, c, ci, cj - n, z2, 0, N_); // - z2 . r^{n}\n\t_isub(r, c, ci, cj - n, z0, 0, N); // - z1 . r^{n}\n}\n","import assert from 'assert';\nimport THRESHOLD_MUL_TOOM22 from '../../thresholds/THRESHOLD_MUL_TOOM22.js';\nimport _mul_limb from './_mul_limb.js';\nimport _schoolbook_mul from './_schoolbook_mul.js';\nimport _karatsuba from './_karatsuba.js';\n\n/**\n * Computes C = A+B.\n *\n * Constraints:\n * - C is zero initialized,\n * - |A| >= |B| >= 0,\n * - |C| >= |A| + |B|.\n *\n * TODO:\n * - Use schoolbook mul if n = O(log m).\n *\n * @param {Number} r base (radix)\n * @param {Array} a first operand\n * @param {Number} ai a left\n * @param {Number} aj a right\n * @param {Array} b second operand, cannot have more limbs than A\n * @param {Number} bi b left\n * @param {Number} bj b right\n * @param {Array} c result, must be 0 initialized and be able to contain A+B\n * @param {Number} ci c left\n * @param {Number} cj c right\n */\nexport default function _mul(r, a, ai, aj, b, bi, bj, c, ci, cj) {\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(ci >= 0 && cj <= c.length);\n\tassert(bj - bi >= 0);\n\tassert(aj - ai >= bj - bi);\n\tassert(cj - ci >= aj - ai + (bj - bi));\n\tassert(THRESHOLD_MUL_TOOM22 >= 1);\n\n\t// Const m = aj - ai ;\n\tconst n = bj - bi;\n\n\t// TODO then |B| = 1 and could be faster\n\t// if ( m === 1 ) return _mul_limb( r , a[ai] , b , bi , bj , c , ci , cj ) ;\n\n\tif (n === 1) return _mul_limb(r, b[bi], a, ai, aj, c, ci, cj);\n\n\t// If ( m === n ) {\n\n\t// if ( a === b && ai === bi ) return _sqr( r , a , ai , aj , c , ci , cj ) ;\n\n\t// return _mul_n( r , a , ai , aj , b , bi , bj , c , ci , cj ) ;\n\n\t// }\n\n\tif (n < THRESHOLD_MUL_TOOM22) {\n\t\treturn _schoolbook_mul(r, a, ai, aj, b, bi, bj, c, ci, cj);\n\t}\n\n\treturn _karatsuba(r, a, ai, aj, b, bi, bj, c, ci, cj);\n}\n","const THRESHOLD_MUL_TOOM22 = 16;\nexport default THRESHOLD_MUL_TOOM22;\n","import assert from 'assert';\n\n/**\n * Subtracts 1 from a big endian array.\n *\n * Wraps on underflow. Hence, does nothing if aj <= ai.\n *\n * O(|A|) time in the worst case.\n * O(1) amortized time over any number of successive operations starting with A = O(1).\n * O(1) amortized time over O(|A|) successive operations starting with any A.\n *\n * @param {Number} r radix\n * @param {Array} a first operand\n * @param {Number} ai a left\n * @param {Number} aj a right\n */\nexport default function decrement(r, a, ai, aj) {\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\n\twhile (--aj >= ai) {\n\t\tif (a[aj] > 0) {\n\t\t\t--a[aj];\n\t\t\treturn;\n\t\t}\n\n\t\ta[aj] = r - 1;\n\t}\n}\n","import assert from 'assert';\n\nimport _zeros from '../../array/_zeros.js';\nimport _fill from '../../array/_fill.js';\nimport _isub from '../sub/_isub.js';\nimport _mul from '../mul/_mul.js';\nimport lt from '../../../api/compare/lt.js';\nimport iadd from '../../../api/arithmetic/add/iadd.js';\nimport decrement from '../../../api/arithmetic/sub/decrement.js';\nimport _cmp_half from '../../compare/_cmp_half.js';\nimport _idivmod_dc_21 from './_idivmod_dc_21.js';\n\n/**\n * Algorithm 3.4 Divide-and-conquer division (3 by 2)\n * ==================================================\n *\n * Input\n * -----\n * Two nonnegative integers A and B,\n * such that A < β^n B and β^{2n} / 2 ≤ B < β^{2n}.\n * n must be even.\n *\n * -------- -----\n * | | | | | | |\n * -------- -----\n *\n * Output\n * ------\n * The quotient floor( A/B ) and the remainder A mod B.\n *\n * Complexity\n * ----------\n * T'(n) ≤ T(n) + M(n) + Ln\n *\n */\nexport default function _idivmod_dc_32(r, a, ai, aj, b, bi, bj, c, ci, cj) {\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(ci >= 0 && cj <= c.length);\n\tassert(cj - ci === aj - ai);\n\tassert(2 * (aj - ai) === 3 * (bj - bi)); // Implies bj - bi even\n\tassert(_cmp_half(r, b, bi, bj) >= 0);\n\n\t// 1. Let A = A_2 β^{2n} + A_1 β^n + A_0 and\n\t// B = B_1 β^{n} + B_0,\n\t// with 0 ≤ A_i < β^n and 0 ≤ B_i < β^n.\n\n\tconst k = bj - bi;\n\tconst n = k >>> 1;\n\n\t// 2. If A_2 < B_1, compute Q = floor( ( A_2 β^n + A_1 ) / B_1 ) with\n\t// remainder R_1 using algorithm 3.3;\n\n\tif (lt(a, ai, ai + n, b, bi, bi + n)) {\n\t\t_idivmod_dc_21(r, a, ai, aj - n, b, bi, bi + n, c, ci + n, cj);\n\t}\n\n\t// Otherwise let Q = β^n - 1, and R_1 = ( A_2 - B_1 ) β^n + A_1 + B_1\n\t// (note in this case that A_2 = B_1)\n\telse {\n\t\t_fill(c, cj - n, cj, r - 1);\n\t\tiadd(r, a, ai, aj - n, b, bi, bi + n);\n\t\t_isub(r, a, ai, ai + n, b, bi, bi + n);\n\t}\n\n\t// 3. R <- R_1 β^n + A_0 - Q*B_0\n\n\tconst zi = 0;\n\tconst zj = n << 1;\n\tconst z = _zeros(zj);\n\t_mul(r, c, cj - n, cj, b, bi + n, bj, z, zi, zj);\n\t_isub(r, a, ai, aj, z, zi, zj); // TODO optimize when A_2 = B_1\n\n\t// 4. if R < 0 , R <- R + B and Q <- Q - 1\n\n\tif (a[ai] === 0) return;\n\tiadd(r, a, ai, aj, b, bi, bj);\n\tdecrement(r, c, cj - n, cj);\n\n\t// 5. if R < 0 , R <- R + B and Q <- Q - 1\n\n\tif (a[ai] === 0) return;\n\tiadd(r, a, ai, aj, b, bi, bj);\n\tdecrement(r, c, cj - n, cj);\n\n\t// 6. Return Q and R\n}\n","import assert from 'assert';\n\nimport THRESHOLD_DIV_DC from '../../thresholds/THRESHOLD_DIV_DC.js';\nimport _cmp_half from '../../compare/_cmp_half.js';\nimport _idivmod_dc_32 from './_idivmod_dc_32.js';\nimport _idivmod_schoolbook_large_divisor from './_idivmod_schoolbook_large_divisor.js';\n\n/**\n * Algorithm 3.3 Divide-and-conquer division (2 by 1)\n * ==================================================\n *\n * Input\n * -----\n * Two nonnegative integers A and B,\n * such that A < β^n B and β^n / 2 ≤ B < β^n.\n * n must be even if n >= THRESHOLD_DIV_DC.\n *\n * ----------- -----\n * | : | : | | : |\n * ----------- -----\n *\n * Output\n * ------\n * The quotient floor( A/B ) and the remainder A mod B.\n *\n * Complexity\n * ----------\n * T(n) = 2T'(n/2) + K\n *\n */\nexport default function _idivmod_dc_21(r, a, ai, aj, b, bi, bj, c, ci, cj) {\n\tassert(THRESHOLD_DIV_DC >= 2);\n\tassert(r >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(ci >= 0 && cj <= c.length);\n\tassert(cj - ci === aj - ai);\n\tassert(aj - ai === 2 * (bj - bi));\n\tassert(_cmp_half(r, b, bi, bj) >= 0);\n\n\tif (bj - bi < THRESHOLD_DIV_DC) {\n\t\treturn _idivmod_schoolbook_large_divisor(r, a, ai, aj, b, bi, bj, c, ci);\n\t}\n\n\tassert((bj - bi) % 2 === 0);\n\n\t// 1. Let A = A_3 β^{3n/2} + A_2 β^n + A_1 β^{n/2} + A_0 and\n\t// B = B_1 β^{n/2} + B_0,\n\t// with 0 ≤ A_i < β^{n/2} and 0 ≤ B_i < β^{n/2}.\n\n\tconst m = aj - ai;\n\tconst k = m >>> 2;\n\n\t// 2. Compute the high half Q_1 of the quotient as\n\t// Q_1 = ( A_3 β^n + A_2 β^{n/2} + A_1 ) / B\n\t// with remainder R_1 using algorithm 3.4.\n\n\t_idivmod_dc_32(r, a, ai, aj - k, b, bi, bj, c, ci, cj - k);\n\n\t// 3. Compute the low half Q_0 of the quotient as\n\t// Q_0 = ( R_1 β^{n/2} + A_0 ) / B\n\t// with remainder R_0 using algorithm 3.4.\n\n\t_idivmod_dc_32(r, a, ai + k, aj, b, bi, bj, c, ci + k, cj);\n\n\t// 4. Return the quotient Q = Q_1 β^{n/2} + Q_0 and the remainder R = R_0 .\n}\n","import THRESHOLD_MUL_TOOM22 from './THRESHOLD_MUL_TOOM22.js';\n\nconst THRESHOLD_DIV_DC = 8 * THRESHOLD_MUL_TOOM22;\nexport default THRESHOLD_DIV_DC;\n","import assert from 'assert';\n\n/**\n * Divides a big endian number by a single limb number and returns only the\n * remainder.\n *\n * Only works with limbs of size at most sqrt( 2^53 ).\n *\n * @param {Number} r The radix of D.\n * @param {Number} d The divisor >= 1.\n * @param {Array} D The dividend (NOT modified).\n * @param {Number} Di Left of D.\n * @param {Number} Dj Right of D.\n * @returns {Number} The remainder D % d.\n */\nexport default function _mod_limb(r, d, D, Di, Dj) {\n\tassert(r >= 2);\n\tassert(d >= 1 && d <= r - 1);\n\tassert(Di >= 0 && Dj <= D.length);\n\n\tlet R = 0;\n\n\twhile (Di < Dj) {\n\t\tR *= r;\n\t\tR += D[Di];\n\t\tR %= d;\n\t\t++Di;\n\t}\n\n\treturn R;\n}\n","import assert from 'assert';\n\nimport _zeros from '../../array/_zeros.js';\nimport _copy from '../../array/_copy.js';\nimport _cmp_n from '../../compare/_cmp_n.js';\nimport _imul_limb from '../mul/_imul_limb.js';\nimport jz from '../../../api/compare/jz.js';\nimport _idivmod_dc_21 from './_idivmod_dc_21.js';\nimport _div_limb_with_prefix from './_div_limb_with_prefix.js';\nimport _mod_limb from './_mod_limb.js';\n\n/**\n * Input\n * -----\n * - No leading zeros\n * - |A| = |C|\n * - C must be zero-initialized.\n *\n * References\n * ----------\n * - https://gmplib.org/manual/Divide-and-Conquer-Division.html\n *\n * @param {Number} X The radix.\n * @param {Array} a Dividend / Remainder.\n * @param {Number} ai\n * @param {Number} aj\n * @param {Array} b Divisor.\n * @param {Number} bi\n * @param {Number} bj\n * @param {Array} c Quotient.\n * @param {Number} ci\n * @param {Number} cj\n */\nexport default function _idivmod_dc(X, a, ai, aj, b, bi, bj, c, ci, cj) {\n\tassert(X >= 2);\n\tassert(ai >= 0 && aj <= a.length);\n\tassert(bi >= 0 && bj <= b.length);\n\tassert(ci >= 0 && cj <= c.length);\n\tassert(aj - ai <= 0 || a[ai] !== 0);\n\tassert(bj - bi >= 1);\n\tassert(b[bi] !== 0);\n\tassert(cj - ci === aj - ai);\n\n\tassert(jz(c, ci, cj));\n\n\t// [BZ98] Fast Recursive Division\n\n\tconst r = aj - ai;\n\tconst s = bj - bi;\n\n\t// NB: this is the only case where c needs to be zero-initialized.\n\tif (r < s || (r === s && _cmp_n(a, ai, aj, b, bi) < 0)) return;\n\n\t// Shift to get n = 2^k for some k\n\tlet _n = 1;\n\n\twhile (_n < s) _n <<= 1;\n\n\tconst n = _n;\n\n\tconst shift = n - s;\n\n\tconst x = b[bi];\n\tconst _X = X / 2;\n\tconst _normalize = x < _X;\n\tconst z = Math.ceil(_X / x);\n\n\tconst w = r + shift + (_normalize || a[ai] >= _X);\n\tconst t = Math.ceil(w / n);\n\tconst _ai = 0;\n\tconst _aj = t * n; // + 1 if\n\tconst _a = _zeros(_aj); // Potential normalization overflow\n\tconst _ak = _aj - shift - r; // Or if A potentially bigger than B\n\t_copy(a, ai, aj, _a, _ak);\n\n\tconst _bi = 0;\n\tconst _bj = n;\n\tconst _b = _zeros(n);\n\t_copy(b, bi, bj, _b, 0);\n\n\tif (_normalize) {\n\t\t_imul_limb(X, z, _a, _ai, _aj);\n\t\t_imul_limb(X, z, _b, _bi, _bj);\n\t}\n\n\tconst _cj = _aj;\n\tconst _c = _zeros(_cj);\n\n\tfor (let i = 0; i < _aj - n; i += n) {\n\t\t_idivmod_dc_21(X, _a, i, i + (n << 1), _b, _bi, _bj, _c, i, i + (n << 1));\n\t}\n\n\tif (_normalize) {\n\t\tconst p = _mod_limb(X, z, _a, _ai, _ak);\n\t\t_div_limb_with_prefix(X, p, z, _a, _ak, _aj - shift, a, ai);\n\t} else {\n\t\t_copy(_a, _ak, _aj - shift, a, ai);\n\t}\n\n\t// C is completely overwritten here\n\t_copy(_c, _cj - r, _cj, c, ci);\n}\n","import assert from 'assert';\n\nimport _idivmod_limb from '../../../core/arithmetic/div/_idivmod_limb.js';\nimport _idivmod_schoolbook from '../../../core/arithmetic/div/_idivmod_schoolbook.js';\nimport _idivmod_dc from '../../../core/arithmetic/div/_idivmod_dc.js';\nimport THRESHOLD_DIV_DC from '../../../core/thresholds/THRESHOLD_DIV_DC.js';\nimport jz from '../../compare/jz.js';\n\n/**\n * Computes the quotient and remainder of two numbers. Uses the most\n * appropriate algorithm depending on the size of the operands. The remainder\n * is written to the dividend array. There are a few assumptions made on the\n * input.\n *\n * Input\n * -----\n * - |d| >= 1\n * - |D| = |Q| >= 1\n * - No leading zeros in D or d.\n * - Q is zero initialized.\n *\n * @param {Number} r The base to work with.\n * @param {Array} D Dividend / Remainder array (remainder computed in-place).\n * @param {Number} Di Left of dividend.\n * @param {Number} Dj Right of dividend.\n * @param {Array} d Divisor array.\n * @param {Number} di Left of divisor.\n * @param {Number} dj Right of divisor.\n * @param {Array} Q Quotient array (zero initialized).\n * @param {Number} Qi Left of quotient.\n * @param {Number} Qj Right of quotient.\n */\nexport default function _idivmod(r, D, Di, Dj, d, di, dj, Q, Qi, Qj) {\n\tassert(r >= 2);\n\n\tassert(Di >= 0 && Dj <= D.length);\n\tassert(di >= 0 && dj <= d.length);\n\tassert(Qi >= 0 && Qj <= Q.length);\n\n\tassert(dj - di >= 1);\n\tassert(Dj - Di === Qj - Qi);\n\tassert(Qj - Qi >= 1);\n\n\tassert(D[Di] !== 0);\n\tassert(d[di] !== 0);\n\tassert(jz(Q, Qi, Qj));\n\n\tconst dn = dj - di;\n\n\tif (dn === 1) {\n\t\treturn _idivmod_limb(r, d[di], D, Di, Dj, Q, Qi);\n\t}\n\n\tif (dn < THRESHOLD_DIV_DC) {\n\t\treturn _idivmod_schoolbook(r, D, Di, Dj, d, di, dj, Q, Qi);\n\t}\n\n\treturn _idivmod_dc(r, D, Di, Dj, d, di, dj, Q, Qi, Qj);\n}\n","import assert from 'assert';\n\n/**\n * Divides a big endian number by a single limb number and writes the\n * remainder to the dividend array.\n *\n * Computes a <- a % b.\n * Only works with limbs of size at most sqrt( 2^53 ).\n *\n * @param {Number} r The radix of D.\n * @param {Number} d The divisor >= 1.\n * @param {Array} D The dividend.\n * @param {Number} Di Left of D.\n * @param {Number} Dj Right of D.\n */\nexport default function _imod_limb(r, d, D, Di, Dj) {\n\tassert(r >= 2);\n\tassert(d >= 1 && d <= r - 1);\n\tassert(Di >= 0 && Dj <= D.length);\n\tassert(Dj - Di >= 1);\n\n\tlet R = 0;\n\n\twhile (Di < Dj) {\n\t\tR *= r;\n\t\tR += D[Di];\n\t\tR %= d;\n\t\tD[Di] = 0;\n\t\t++Di;\n\t}\n\n\tD[Dj - 1] = R;\n}\n","import assert from 'assert';\n\nimport _zeros from '../../array/_zeros.js';\nimport gt from '../../../api/compare/gt.js';\nimport _isub from '../sub/_isub.js';\nimport _mul_limb from '../mul/_mul_limb.js';\n\nimport _cmp_half from '../../compare/_cmp_half.js';\n\n/**\n * Input\n * -----\n * - Two integers A and B such that 0 <= A < B * β and (β^n)/2 <= B < β^n.\n * (Hence B >= 1).\n * - |A| = |B| + 1\n *\n * Output\n * -----\n * The remainder A mod B.\n *\n * @param {Number} r The radix.\n * @param {Array} a Dividend.\n * @param {Number} ai Left of dividend.\n * @param {Number} aj Right of dividend.\n * @param {Array} b Divisor.\n * @param {Number} bi Left of divisor.\n * @param {Number} bj Right of divisor.\n */\nexport default function _imod_schoolbook_subroutine_do(\n\tr,\n\ta,\n\tai,\n\taj,\n\tb,\n\tbi,\n\tbj,