initial commit
This commit is contained in:
+362
@@ -0,0 +1,362 @@
|
||||
import { at } from "./utilities.js";
|
||||
|
||||
const L = 4;
|
||||
const MAX = 9999;
|
||||
const LIM = 10000;
|
||||
|
||||
const kBuffer = Symbol("buffer");
|
||||
|
||||
export class BigInteger {
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static zero = BigInteger.from("0");
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static one = BigInteger.from("1");
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static two = BigInteger.from("2");
|
||||
|
||||
/**
|
||||
* @param { number[] } buffer
|
||||
* @param {boolean} [negative]
|
||||
*/
|
||||
constructor(buffer, negative = false) {
|
||||
this[kBuffer] = buffer;
|
||||
this.negative = negative;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param { string } str
|
||||
*/
|
||||
static from(str) {
|
||||
const negative = str[0] === "-";
|
||||
if (negative) str = str.substring(1);
|
||||
/**@type { number[] } */
|
||||
const buffer = [];
|
||||
let i = str.length;
|
||||
let j = i - L;
|
||||
while (j > 0) {
|
||||
buffer.push(Number.parseInt(str.substring(j, i)));
|
||||
j -= L;
|
||||
i -= L;
|
||||
}
|
||||
buffer.push(Number.parseInt(str.substring(0, i)));
|
||||
return new BigInteger(buffer, negative);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param { BigInteger } a
|
||||
* @param { BigInteger } b
|
||||
*/
|
||||
static ucmp(a, b) {
|
||||
const l = a[kBuffer].length;
|
||||
if (l !== b[kBuffer].length) return l > b[kBuffer].length ? 1 : -1;
|
||||
for (let i = l - 1; i >= 0; i--) {
|
||||
if (a[kBuffer][i] !== b[kBuffer][i]) return a[kBuffer][i] > b[kBuffer][i] ? 1 : -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param { BigInteger } num
|
||||
*/
|
||||
static isZero(num) {
|
||||
return num[kBuffer].length === 1 && num[kBuffer][0] === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param { boolean } [negative]
|
||||
* @returns { BigInteger }
|
||||
*/
|
||||
copy(negative = this.negative) {
|
||||
return new BigInteger(Array.from(this[kBuffer]), negative);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns { BigInteger }
|
||||
*/
|
||||
shallowCopy() {
|
||||
return new BigInteger(this[kBuffer], this.negative);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param { BigInteger } num
|
||||
* @param { boolean } [negative]
|
||||
* @returns { this }
|
||||
*/
|
||||
assign(num, negative = num.negative) {
|
||||
this[kBuffer] = Array.from(num[kBuffer]);
|
||||
this.negative = negative;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns { this }
|
||||
*/
|
||||
toggleSign() {
|
||||
this.negative = !this.negative;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param { boolean } negative
|
||||
* @returns { this }
|
||||
*/
|
||||
setSign(negative) {
|
||||
this.negative = negative;
|
||||
return this;
|
||||
}
|
||||
|
||||
toString() {
|
||||
const buff = this[kBuffer];
|
||||
let accum = this.negative ? "-" : "";
|
||||
accum += buff[buff.length - 1].toString();
|
||||
for (let i = buff.length - 2; i >= 0; i--) accum += buff[i].toString().padStart(4, "0");
|
||||
return accum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param { BigInteger } num
|
||||
* @param { boolean } [negative]
|
||||
* @returns { this }
|
||||
*/
|
||||
add(num, negative = num.negative) {
|
||||
if (this.negative !== negative) return this.negative ? this.sub(num, true) : this.sub(num, false);
|
||||
const buffA = this[kBuffer];
|
||||
const buffB = num[kBuffer];
|
||||
let carry = 0;
|
||||
for (let i = 0; i < buffB.length; i++) {
|
||||
while (buffA.length <= i) buffA.push(0);
|
||||
buffA[i] += buffB[i] + carry;
|
||||
carry = Number(buffA[i] > MAX);
|
||||
if (carry) buffA[i] %= LIM;
|
||||
}
|
||||
if (carry) {
|
||||
let i = buffB.length;
|
||||
while (buffA.length <= i) buffA.push(0);
|
||||
while (buffA[i] === MAX) {
|
||||
buffA[i++] = 0;
|
||||
while (buffA.length <= i) buffA.push(0);
|
||||
}
|
||||
buffA[i] += carry;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @param { BigInteger } num
|
||||
// * @param { boolean } [negative]
|
||||
// * @returns { this }
|
||||
// */
|
||||
// add(num, negative = num.negative) {
|
||||
// if (this.negative !== negative) return this.sub(num, this.negative);
|
||||
// return this.uadd(num);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @param { BigInteger } num
|
||||
// * @returns { this }
|
||||
// */
|
||||
// uadd(num) {
|
||||
// const buffA = this[kBuffer];
|
||||
// const buffB = num[kBuffer];
|
||||
// let carry = 0;
|
||||
// let i = 0;
|
||||
// while (buffA.length < buffB.length) buffA.push(0);
|
||||
// for (; i < buffB.length; i++) {
|
||||
// buffA[i] += buffB[i] + carry;
|
||||
// carry = Number(buffA[i] > MAX);
|
||||
// if (carry) buffA[i] %= LIM;
|
||||
// }
|
||||
// if (carry === 1) {
|
||||
// while (at(buffA, i, 0) === MAX) buffA[i++] = 0;
|
||||
// buffA[i] += carry;
|
||||
// }
|
||||
// return this;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @param { BigInteger } num
|
||||
* @param { boolean } [negative]
|
||||
* @returns { this }
|
||||
*/
|
||||
sub(num, negative = num.negative) {
|
||||
if (this.negative !== negative) return this.negative ? this.add(num, true) : this.add(num, false);
|
||||
if (BigInteger.ucmp(num, this) == 1) {
|
||||
const self = this.shallowCopy();
|
||||
return this.assign(num, negative).sub(self).toggleSign();
|
||||
}
|
||||
const buffA = this[kBuffer];
|
||||
const buffB = num[kBuffer];
|
||||
let carry = 0;
|
||||
for (let i = 0; i < buffB.length; i++) {
|
||||
buffA[i] -= buffB[i] + carry;
|
||||
carry = Number(buffA[i] < 0);
|
||||
if (carry) buffA[i] += LIM;
|
||||
}
|
||||
if (carry) {
|
||||
let i = buffB.length;
|
||||
while (buffA[i] === 0) buffA[i++] = MAX;
|
||||
buffA[i] -= carry;
|
||||
}
|
||||
while (buffA.length > 1 && buffA[buffA.length - 1] == 0) buffA.pop();
|
||||
return this;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @param { BigInteger } num
|
||||
// * @param { boolean } [negative]
|
||||
// * @returns { this }
|
||||
// */
|
||||
// sub(num, negative = num.negative) {
|
||||
// if (this.negative !== negative) return this.add(num, this.negative);
|
||||
// return this.usub(num);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @param { BigInteger } num
|
||||
// * @returns { this }
|
||||
// */
|
||||
// usub(num) {
|
||||
// if (BigInteger.ucmp(num, this) == 1) {
|
||||
// const self = this.shallowCopy();
|
||||
// return this.assign(num, !this.negative).usub(self)
|
||||
// }
|
||||
// const buffA = this[kBuffer];
|
||||
// const buffB = num[kBuffer];
|
||||
// let carry = 0;
|
||||
// let i = 0;
|
||||
// for (; i < buffB.length; i++) {
|
||||
// buffA[i] -= buffB[i] + carry;
|
||||
// carry = Number(buffA[i] < 0);
|
||||
// if (carry) buffA[i] += LIM;
|
||||
// }
|
||||
// if (carry == 1) {
|
||||
// while (buffA[i] === 0) buffA[i++] = MAX;
|
||||
// buffA[i] -= carry;
|
||||
// }
|
||||
// for (let i = buffA.length - 1; i > 0 && buffA[i] === 0; i--) buffA.pop();
|
||||
// return this;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @param { BigInteger } num
|
||||
* @returns { this }
|
||||
*/
|
||||
mul(num) {
|
||||
/**@type { number[] } */
|
||||
const buff = [];
|
||||
for (let i = 0; i < this[kBuffer].length; i++) {
|
||||
const a = this[kBuffer][i];
|
||||
for (let j = 0; j < num[kBuffer].length; j++) {
|
||||
const b = num[kBuffer][j];
|
||||
let k = i + j;
|
||||
while (buff.length <= k) buff.push(0);
|
||||
buff[k] += a * b;
|
||||
while (buff[k] > MAX) {
|
||||
const carry = Math.trunc(buff[k] / LIM)
|
||||
buff[k++] %= LIM;
|
||||
while (buff.length <= k) buff.push(0);
|
||||
buff[k] += carry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this[kBuffer] = buff;
|
||||
this.negative = this.negative !== num.negative;
|
||||
return this;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @param { BigInteger } num
|
||||
// * @returns { this }
|
||||
// */
|
||||
// mul(num) {
|
||||
// return this.umul(num).setSign(this.negative !== num.negative);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @param { BigInteger } num
|
||||
// * @returns { this }
|
||||
// */
|
||||
// umul(num) {
|
||||
// /**@type { number[] } */
|
||||
// const buff = [];
|
||||
// for (let i = 0; i < this[kBuffer].length; i++) {
|
||||
// const a = this[kBuffer][i];
|
||||
// for (let j = 0; j < num[kBuffer].length; j++) {
|
||||
// const b = num[kBuffer][j];
|
||||
// let k = i + j;
|
||||
// while (buff.length <= k) buff.push(0);
|
||||
// buff[k] += a * b;
|
||||
// while (buff[k] > MAX) {
|
||||
// const carry = Math.trunc(buff[k] / LIM)
|
||||
// buff[k++] %= LIM;
|
||||
// while (buff.length <= k) buff.push(0);
|
||||
// buff[k] += carry;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// this[kBuffer] = buff;
|
||||
// return this;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @param { BigInteger } num
|
||||
* @returns { this }
|
||||
*/
|
||||
div(num) {
|
||||
const buffB = num[kBuffer];
|
||||
const l = buffB.length - 1;
|
||||
let quick = true;
|
||||
for (let i = 0; i < l && quick; i++) quick = (buffB[i] == 0);
|
||||
if (quick) {
|
||||
const D = buffB[l];
|
||||
const N = this[kBuffer].slice(l);
|
||||
let carry = 0;
|
||||
for (let i = N.length - 1; i >= 0; i--) {
|
||||
N[i] += (carry * LIM);
|
||||
carry = N[i] % D;
|
||||
N[i] = Math.trunc(N[i] / D);
|
||||
}
|
||||
if (N.length < 1) N.push(0);
|
||||
while (N.length > 1 && N[N.length - 1] == 0) N.pop();
|
||||
this[kBuffer] = N;
|
||||
this.negative = this.negative !== num.negative;
|
||||
return this;
|
||||
}
|
||||
|
||||
const A = num.copy();
|
||||
for (let i = 0; i < l; i++) A[kBuffer][i] = 0;
|
||||
const Q = this.copy().div(A);
|
||||
const R = num.copy().add(BigInteger.one, num.negative);
|
||||
const TMP = BigInteger.zero.copy();
|
||||
while (BigInteger.ucmp(R, num) != -1) {
|
||||
TMP.assign(Q).mul(num);
|
||||
R.assign(this).sub(TMP);
|
||||
TMP.assign(R).div(A).add(Q);
|
||||
Q.add(TMP).div(BigInteger.two);
|
||||
}
|
||||
TMP.assign(Q).mul(num);
|
||||
R.assign(this).sub(TMP);
|
||||
if (this.negative !== R.negative && !BigInteger.isZero(R)) {
|
||||
Q.sub(BigInteger.one, Q.negative);
|
||||
R.add(num);
|
||||
}
|
||||
this[kBuffer] = Q[kBuffer];
|
||||
this.negative = Q.negative;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param { BigInteger } num
|
||||
* @returns { this }
|
||||
*/
|
||||
udiv(num) {
|
||||
throw new Error("Not Implemented");
|
||||
}
|
||||
}
|
||||
+261
@@ -0,0 +1,261 @@
|
||||
import { BigInteger } from "./index.js"
|
||||
|
||||
console.group("Addition and subtraction")
|
||||
console.group("by 0 is the identity")
|
||||
|
||||
console.assert(BigInteger.from("1").add(BigInteger.from("0")).toString() === "1");
|
||||
console.assert(BigInteger.from("-1").add(BigInteger.from("0")).toString() === "-1");
|
||||
console.assert(BigInteger.from("0").add(BigInteger.from("-1")).toString() === "-1");
|
||||
console.assert(BigInteger.from("0").add(BigInteger.from("153")).toString() === "153");
|
||||
console.assert(BigInteger.from("153").add(BigInteger.from("0")).toString() === "153");
|
||||
console.assert(BigInteger.from("0").add(BigInteger.from("-153")).toString() === "-153");
|
||||
console.assert(BigInteger.from("-153").add(BigInteger.from("0")).toString() === "-153");
|
||||
console.assert(BigInteger.from("0").add(BigInteger.from("9844190321790980841789")).toString() === "9844190321790980841789");
|
||||
console.assert(BigInteger.from("9844190321790980841789").add(BigInteger.from("0")).toString() ==="9844190321790980841789");
|
||||
|
||||
console.assert(BigInteger.from("0").add(BigInteger.from("-9844190321790980841789")).toString() ==="-9844190321790980841789");
|
||||
console.assert(BigInteger.from("-9844190321790980841789").add(BigInteger.from("0")).toString() === "-9844190321790980841789");
|
||||
console.assert(BigInteger.from("1").sub(BigInteger.from("0")).toString() === "1");
|
||||
console.assert(BigInteger.from("-1").sub(BigInteger.from("0")).toString() === "-1");
|
||||
console.assert(BigInteger.from("153").sub(BigInteger.from("0")).toString() === "153");
|
||||
console.assert(BigInteger.from("-153").sub(BigInteger.from("0")).toString() === "-153");
|
||||
console.assert(BigInteger.from("9844190321790980841789").sub(BigInteger.from("0")).toString() === "9844190321790980841789");
|
||||
console.assert(BigInteger.from("-9844190321790980841789").sub(BigInteger.from("0")).toString() === "-9844190321790980841789");
|
||||
|
||||
console.groupEnd();
|
||||
console.group("addition by inverse is 0, subtraction by self is 0");
|
||||
|
||||
console.assert(BigInteger.from("5").sub(BigInteger.from("5")).toString() === "0");
|
||||
console.assert(BigInteger.from("5").add(BigInteger.from("-5")).toString() === "0");
|
||||
console.assert(BigInteger.from("10000000000000000").sub(BigInteger.from("10000000000000000")).toString() === "0");
|
||||
console.assert(BigInteger.from("10000000000000000").add(BigInteger.from("-10000000000000000")).toString() === "0");
|
||||
|
||||
console.groupEnd();
|
||||
console.group("handles signs correctly");
|
||||
|
||||
console.assert(BigInteger.from("1").add(BigInteger.from("1")).toString() === "2");
|
||||
console.assert(BigInteger.from("1").add(BigInteger.from("-5")).toString() === "-4");
|
||||
console.assert(BigInteger.from("-1").add(BigInteger.from("5")).toString() === "4");
|
||||
console.assert(BigInteger.from("-1").add(BigInteger.from("-5")).toString() === "-6");
|
||||
console.assert(BigInteger.from("5").add(BigInteger.from("1")).toString() === "6");
|
||||
console.assert(BigInteger.from("5").add(BigInteger.from("-1")).toString() === "4");
|
||||
console.assert(BigInteger.from("-5").add(BigInteger.from("1")).toString() === "-4");
|
||||
console.assert(BigInteger.from("-5").add(BigInteger.from("-1")).toString() === "-6");
|
||||
|
||||
console.assert(BigInteger.from("1").sub(BigInteger.from("1")).toString() === "0");
|
||||
console.assert(BigInteger.from("1").sub(BigInteger.from("-5")).toString() === "6");
|
||||
console.assert(BigInteger.from("-1").sub(BigInteger.from("5")).toString() === "-6");
|
||||
console.assert(BigInteger.from("-1").sub(BigInteger.from("-5")).toString() === "4");
|
||||
console.assert(BigInteger.from("5").sub(BigInteger.from("1")).toString() === "4");
|
||||
console.assert(BigInteger.from("5").sub(BigInteger.from("-1")).toString() === "6");
|
||||
console.assert(BigInteger.from("-5").sub(BigInteger.from("1")).toString() === "-6");
|
||||
console.assert(BigInteger.from("-5").sub(BigInteger.from("-1")).toString() === "-4");
|
||||
|
||||
console.assert(BigInteger.from("1234698764971301").add(BigInteger.from("5")).toString() === "1234698764971306");
|
||||
console.assert(BigInteger.from("1234698764971301").add(BigInteger.from("-5")).toString() === "1234698764971296");
|
||||
console.assert(BigInteger.from("-1234698764971301").add(BigInteger.from("5")).toString() === "-1234698764971296");
|
||||
console.assert(BigInteger.from("-1234698764971301").add(BigInteger.from("-5")).toString() === "-1234698764971306");
|
||||
console.assert(BigInteger.from("5").add(BigInteger.from("1234698764971301")).toString() === "1234698764971306");
|
||||
console.assert(BigInteger.from("5").add(BigInteger.from("-1234698764971301")).toString() === "-1234698764971296");
|
||||
console.assert(BigInteger.from("-5").add(BigInteger.from("1234698764971301")).toString() === "1234698764971296");
|
||||
console.assert(BigInteger.from("-5").add(BigInteger.from("-1234698764971301")).toString() === "-1234698764971306");
|
||||
|
||||
console.assert(BigInteger.from("1234698764971301").sub(BigInteger.from("5")).toString() === "1234698764971296");
|
||||
console.assert(BigInteger.from("1234698764971301").sub(BigInteger.from("-5")).toString() === "1234698764971306");
|
||||
console.assert(BigInteger.from("-1234698764971301").sub(BigInteger.from("5")).toString() === "-1234698764971306");
|
||||
console.assert(BigInteger.from("-1234698764971301").sub(BigInteger.from("-5")).toString() === "-1234698764971296");
|
||||
console.assert(BigInteger.from("5").sub(BigInteger.from("1234698764971301")).toString() === "-1234698764971296");
|
||||
console.assert(BigInteger.from("5").sub(BigInteger.from("-1234698764971301")).toString() === "1234698764971306");
|
||||
console.assert(BigInteger.from("-5").sub(BigInteger.from("1234698764971301")).toString() === "-1234698764971306");
|
||||
console.assert(BigInteger.from("-5").sub(BigInteger.from("-1234698764971301")).toString() === "1234698764971296");
|
||||
|
||||
console.assert(BigInteger.from("1234567890987654321").add(BigInteger.from("9876543210123456789")).toString() === "11111111101111111110");
|
||||
console.assert(BigInteger.from("1234567890987654321").add(BigInteger.from("-9876543210123456789")).toString() === "-8641975319135802468");
|
||||
console.assert(BigInteger.from("-1234567890987654321").add(BigInteger.from("9876543210123456789")).toString() === "8641975319135802468");
|
||||
console.assert(BigInteger.from("-1234567890987654321").add(BigInteger.from("-9876543210123456789")).toString() === "-11111111101111111110");
|
||||
console.assert(BigInteger.from("9876543210123456789").add(BigInteger.from("1234567890987654321")).toString() === "11111111101111111110");
|
||||
console.assert(BigInteger.from("9876543210123456789").add(BigInteger.from("-1234567890987654321")).toString() === "8641975319135802468");
|
||||
console.assert(BigInteger.from("-9876543210123456789").add(BigInteger.from("1234567890987654321")).toString() === "-8641975319135802468");
|
||||
console.assert(BigInteger.from("-9876543210123456789").add(BigInteger.from("-1234567890987654321")).toString() === "-11111111101111111110");
|
||||
|
||||
console.assert(BigInteger.from("1234567890987654321").sub(BigInteger.from("9876543210123456789")).toString() === "-8641975319135802468");
|
||||
console.assert(BigInteger.from("1234567890987654321").sub(BigInteger.from("-9876543210123456789")).toString() === "11111111101111111110");
|
||||
console.assert(BigInteger.from("-1234567890987654321").sub(BigInteger.from("9876543210123456789")).toString() === "-11111111101111111110");
|
||||
console.assert(BigInteger.from("-1234567890987654321").sub(BigInteger.from("-9876543210123456789")).toString() === "8641975319135802468");
|
||||
console.assert(BigInteger.from("9876543210123456789").sub(BigInteger.from("1234567890987654321")).toString() === "8641975319135802468");
|
||||
console.assert(BigInteger.from("9876543210123456789").sub(BigInteger.from("-1234567890987654321")).toString() === "11111111101111111110");
|
||||
console.assert(BigInteger.from("-9876543210123456789").sub(BigInteger.from("1234567890987654321")).toString() === "-11111111101111111110");
|
||||
console.assert(BigInteger.from("-9876543210123456789").sub(BigInteger.from("-1234567890987654321")).toString() === "-8641975319135802468");
|
||||
|
||||
console.assert(BigInteger.from("-9007199254740991").add(BigInteger.from("-1")).toString() === "-9007199254740992");
|
||||
console.assert(BigInteger.from("-5616421592529327000000000000000").sub(BigInteger.from("987682355516543")).toString() === "-5616421592529327987682355516543")
|
||||
|
||||
console.assert(BigInteger.from("-0").add(BigInteger.from("10000000000000000")).toString() === "10000000000000000");
|
||||
console.assert(BigInteger.from("-0").add(BigInteger.from("-1")).toString() ==="-1");
|
||||
|
||||
console.groupEnd();
|
||||
console.group("carries over correctly");
|
||||
{
|
||||
const fibs = ["1", "1", "2", "3", "5", "8", "13", "21", "34", "55", "89", "144", "233", "377", "610", "987", "1597", "2584", "4181", "6765", "10946", "17711", "28657", "46368", "75025", "121393", "196418", "317811", "514229", "832040", "1346269", "2178309", "3524578", "5702887", "9227465", "14930352", "24157817", "39088169", "63245986", "102334155", "165580141", "267914296", "433494437", "701408733", "1134903170", "1836311903", "2971215073", "4807526976", "7778742049", "12586269025"];
|
||||
const number = BigInteger.from("1");
|
||||
const last = BigInteger.from("1");
|
||||
|
||||
for (let i = 2; i < 50; i++) {
|
||||
number.add(last);
|
||||
last.assign(number.copy().sub(last));
|
||||
|
||||
console.assert(number.toString() === fibs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
console.assert(BigInteger.from("9007199254740991").add(BigInteger.from("1")).toString() === "9007199254740992");
|
||||
console.assert(BigInteger.from("999999999999999999999000000000000000000000").add(BigInteger.from("1000000000000000000000")).toString() === "1000000000000000000000000000000000000000000");
|
||||
console.assert(BigInteger.from("100000000000000000000").add(BigInteger.from("9007199254740972")).toString() === "100009007199254740972");
|
||||
console.assert(BigInteger.from("-9007199254740983").add(BigInteger.from("-9999999999999998")).toString() === "-19007199254740981");
|
||||
|
||||
console.assert(BigInteger.from("100000000000000000000000000000000000").sub(BigInteger.from("999999999999999999")).toString() === "99999999999999999000000000000000001");
|
||||
|
||||
console.assert(BigInteger.from("10000000010000000").sub(BigInteger.from("10000000")).toString() === "10000000000000000");
|
||||
|
||||
console.groupEnd();
|
||||
console.group("work");
|
||||
|
||||
console.assert(BigInteger.from("10").add(BigInteger.from("10")).toString() === "20");
|
||||
console.assert(BigInteger.from("-10000000000000000").add(BigInteger.from("0")).toString() === "-10000000000000000");
|
||||
console.assert(BigInteger.from("0").add(BigInteger.from("10000000000000000")).toString() === "10000000000000000");
|
||||
console.assert(BigInteger.from("9999999").add(BigInteger.from("1")).toString() === "10000000");
|
||||
console.assert(BigInteger.from("10000000").sub(BigInteger.from("1")).toString() === "9999999");
|
||||
console.assert(BigInteger.from("-1000000000000000000000000000000000001").add(BigInteger.from("1000000000000000000000000000000000000")).toString() === "-1");
|
||||
console.assert(BigInteger.from("100000000000000000002222222222222222222").sub(BigInteger.from("100000000000000000001111111111111111111")).toString() === "1111111111111111111");
|
||||
console.assert(BigInteger.from("1").add(BigInteger.from("0")).toString() === "1");
|
||||
console.assert(BigInteger.from("10").add(BigInteger.from("10000000000000000")).toString() === "10000000000000010");
|
||||
console.assert(BigInteger.from("10000000000000000").add(BigInteger.from("10")).toString() === "10000000000000010");
|
||||
console.assert(BigInteger.from("10000000000000000").add(BigInteger.from("10000000000000000")).toString() === "20000000000000000");
|
||||
|
||||
console.groupEnd();
|
||||
console.groupEnd();
|
||||
|
||||
console.group("Multiplication")
|
||||
console.group("by 0 equals 0");
|
||||
|
||||
// console.assert(BigInteger.from("0").mul(BigInteger.from("0")).toString() === "0");
|
||||
// console.assert(BigInteger.from("0").mul(BigInteger.from("-0")).toString() === "0");
|
||||
// console.assert(BigInteger.from("1").mul(BigInteger.from("0")).toString() === "-0");
|
||||
// console.assert(BigInteger.from("-0").mul(BigInteger.from("1")).toString() === "0");
|
||||
// console.assert(BigInteger.from("1234567890987654321").mul(BigInteger.from("0")).toString() ==="-0");
|
||||
// console.assert(BigInteger.from("-0").mul(BigInteger.from("1234567890987654321")).toString() === "0");
|
||||
// console.assert(BigInteger.from("0").mul(BigInteger.from("-1234567890987654321")).toString() === "0");
|
||||
|
||||
console.groupEnd();
|
||||
console.group("by 1 is the identity")
|
||||
|
||||
console.assert(BigInteger.from("1").mul(BigInteger.from("1")).toString() === "1");
|
||||
console.assert(BigInteger.from("-1").mul(BigInteger.from("1")).toString() === "-1");
|
||||
console.assert(BigInteger.from("1").mul(BigInteger.from("-1")).toString() === "-1");
|
||||
console.assert(BigInteger.from("1").mul(BigInteger.from("153")).toString() === "153");
|
||||
console.assert(BigInteger.from("153").mul(BigInteger.from("1")).toString() === "153");
|
||||
console.assert(BigInteger.from("1").mul(BigInteger.from("-153")).toString() === "-153");
|
||||
console.assert(BigInteger.from("-153").mul(BigInteger.from("1")).toString() === "-153");
|
||||
console.assert(BigInteger.from("1").mul(BigInteger.from("9844190321790980841789")).toString() === "9844190321790980841789");
|
||||
console.assert(BigInteger.from("9844190321790980841789").mul(BigInteger.from("1")).toString() === "9844190321790980841789");
|
||||
console.assert(BigInteger.from("1").mul(BigInteger.from("-9844190321790980841789")).toString() === "-9844190321790980841789");
|
||||
console.assert(BigInteger.from("-9844190321790980841789").mul(BigInteger.from("1")).toString() === "-9844190321790980841789");
|
||||
|
||||
console.groupEnd();
|
||||
console.group("handles signs correctly");
|
||||
|
||||
console.assert(BigInteger.from("100").mul(BigInteger.from("100")).toString() === "10000");
|
||||
console.assert(BigInteger.from("100").mul(BigInteger.from("-100")).toString() === "-10000");
|
||||
console.assert(BigInteger.from("-100").mul(BigInteger.from("100")).toString() === "-10000");
|
||||
console.assert(BigInteger.from("-100").mul(BigInteger.from("-100")).toString() === "10000");
|
||||
|
||||
console.assert(BigInteger.from("13579").mul(BigInteger.from("163500573666152634716420931676158")).toString() === "2220174289812686626814279831230549482");
|
||||
console.assert(BigInteger.from("13579").mul(BigInteger.from("-163500573666152634716420931676158")).toString() === "-2220174289812686626814279831230549482");
|
||||
console.assert(BigInteger.from("-13579").mul(BigInteger.from("163500573666152634716420931676158")).toString() === "-2220174289812686626814279831230549482");
|
||||
console.assert(BigInteger.from("-13579").mul(BigInteger.from("-163500573666152634716420931676158")).toString() === "2220174289812686626814279831230549482");
|
||||
console.assert(BigInteger.from("163500573666152634716420931676158").mul(BigInteger.from("13579")).toString() === "2220174289812686626814279831230549482");
|
||||
console.assert(BigInteger.from("163500573666152634716420931676158").mul(BigInteger.from("-13579")).toString() === "-2220174289812686626814279831230549482");
|
||||
console.assert(BigInteger.from("-163500573666152634716420931676158").mul(BigInteger.from("13579")).toString() === "-2220174289812686626814279831230549482");
|
||||
console.assert(BigInteger.from("-163500573666152634716420931676158").mul(BigInteger.from("-13579")).toString() === "2220174289812686626814279831230549482");
|
||||
console.assert(BigInteger.from("163500573666152634716420931676158").mul(BigInteger.from("-1")).toString() === "-163500573666152634716420931676158");
|
||||
|
||||
console.assert(BigInteger.from("1234567890987654321").mul(BigInteger.from("132435465768798")).toString() === "163500573666152634716420931676158");
|
||||
console.assert(BigInteger.from("1234567890987654321").mul(BigInteger.from("-132435465768798")).toString() === "-163500573666152634716420931676158");
|
||||
console.assert(BigInteger.from("-1234567890987654321").mul(BigInteger.from("132435465768798")).toString() === "-163500573666152634716420931676158");
|
||||
console.assert(BigInteger.from("-1234567890987654321").mul(BigInteger.from("-132435465768798")).toString() === "163500573666152634716420931676158");
|
||||
|
||||
console.groupEnd();
|
||||
console.group("carries over correctly");
|
||||
|
||||
console.assert(BigInteger.from("50000005000000").mul(BigInteger.from("10000001")).toString() === "500000100000005000000");
|
||||
console.assert(BigInteger.from("50000005000000").mul(BigInteger.from("10000001")).toString() === "500000100000005000000");
|
||||
|
||||
console.groupEnd();
|
||||
console.groupEnd();
|
||||
|
||||
console.group("Division")
|
||||
console.group("by 1 is the identity");
|
||||
|
||||
console.assert(BigInteger.from("1").div(BigInteger.from("1")).toString() === "1");
|
||||
console.assert(BigInteger.from("-1").div(BigInteger.from("1")).toString() === "-1");
|
||||
console.assert(BigInteger.from("1").div(BigInteger.from("-1")).toString() === "-1");
|
||||
console.assert(BigInteger.from("153").div(BigInteger.from("1")).toString() === "153");
|
||||
console.assert(BigInteger.from("-153").div(BigInteger.from("1")).toString() === "-153");
|
||||
console.assert(BigInteger.from("9844190321790980841789").div(BigInteger.from("1")).toString() === "9844190321790980841789");
|
||||
console.assert(BigInteger.from("-9844190321790980841789").div(BigInteger.from("1")).toString() === "-9844190321790980841789");
|
||||
|
||||
console.groupEnd();
|
||||
console.group("by self is 1");
|
||||
|
||||
console.assert(BigInteger.from("5").div(BigInteger.from("5")).toString() === "1");
|
||||
console.assert(BigInteger.from("-5").div(BigInteger.from("-5")).toString() === "1");
|
||||
console.assert(BigInteger.from("20194965098495006574").div(BigInteger.from("20194965098495006574")).toString() === "1");
|
||||
console.assert(BigInteger.from("-20194965098495006574").div(BigInteger.from("-20194965098495006574")).toString() === "1");
|
||||
|
||||
console.groupEnd();
|
||||
console.group("of 0 equals 0");
|
||||
|
||||
console.assert(BigInteger.from("0").div(BigInteger.from("1")).toString() === "0");
|
||||
console.assert(BigInteger.from("-0").div(BigInteger.from("1")).toString() === "-0");
|
||||
console.assert(BigInteger.from("-0").div(BigInteger.from("1234567890987654321")).toString() === "-0");
|
||||
console.assert(BigInteger.from("0").div(BigInteger.from("-1234567890987654321")).toString() === "-0");
|
||||
|
||||
console.groupEnd();
|
||||
console.group("handles signs correctly");
|
||||
|
||||
console.assert(BigInteger.from("10000").div(BigInteger.from("100")).toString() === "100");
|
||||
console.assert(BigInteger.from("10000").div(BigInteger.from("-100")).toString() === "-100");
|
||||
console.assert(BigInteger.from("-10000").div(BigInteger.from("100")).toString() === "-100");
|
||||
console.assert(BigInteger.from("-10000").div(BigInteger.from("-100")).toString() === "100");
|
||||
console.assert(BigInteger.from("100").div(BigInteger.from("-1000")).toString() === "-0");
|
||||
|
||||
console.assert(BigInteger.from("163500573666152634716420931676158").div(BigInteger.from("13579")).toString() === "12040693251797086288859336598");
|
||||
console.assert(BigInteger.from("163500573666152634716420931676158").div(BigInteger.from("-13579")).toString() === "-12040693251797086288859336598");
|
||||
|
||||
console.assert(BigInteger.from("-163500573666152634716420931676158").div(BigInteger.from("13579")).toString() === "-12040693251797086288859336598");
|
||||
console.assert(BigInteger.from("-163500573666152634716420931676158").div(BigInteger.from("-13579")).toString() === "12040693251797086288859336598");
|
||||
|
||||
console.assert(BigInteger.from("1234567890987654321").div(BigInteger.from("132435465768798")).toString() === "9322");
|
||||
console.assert(BigInteger.from("1234567890987654321").div(BigInteger.from("-132435465768798")).toString() === "-9322");
|
||||
console.assert(BigInteger.from("-1234567890987654321").div(BigInteger.from("132435465768798")).toString() === "-9322");
|
||||
console.assert(BigInteger.from("-1234567890987654321").div(BigInteger.from("-132435465768798")).toString() === "9322");
|
||||
|
||||
console.assert(BigInteger.from("786456456335437356436").div(BigInteger.from("-5423424653")).toString() === "-145011041298");
|
||||
console.assert(BigInteger.from("-93453764643534523").div(BigInteger.from("-2342")).toString() === "39903400787162");
|
||||
console.assert(BigInteger.from("10000000000000000").div(BigInteger.from("-10000000000000000")).toString() === "-1");
|
||||
|
||||
console.assert(BigInteger.from("98789789419609840614360398703968368740365403650364036403645046").div(BigInteger.from("-1")).toString() === "-98789789419609840614360398703968368740365403650364036403645046");
|
||||
|
||||
console.groupEnd();
|
||||
console.group("works");
|
||||
|
||||
console.assert(BigInteger.from("98109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241981098409840984091564810684565416840659648198410651068657103974645132104164354016450306480360340639740650049510942094209420974219704902741950491209742109742097421902740927404920974209298924909742022419810984098409840915648106845654168406596481984106510686571039746451321041643540164503064803603406397406500495109420942094209742197049027419504912097421097420974219027409274049209742092989249097420224198109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241981098409840984091564810684565416840659648198410651068657103974645132104164354016450306480360340639740650049510942094209420974219704902741950491209742109742097421902740927404920974209298924909742022419810984098409840915648106845654168406596481984106510686571039746451321041643540164503064803603406397406500495109420942094209742197049027419504912097421097420974219027409274049209742092989249097420224198109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241981098409840984091564810684565416840659648198410651068657103974645132104164354016450306480360340639740650049510942094209420974219704902741950491209742109742097421902740927404920974209298924909742022419810984098409840915648106845654168406596481984106510686571039746451321041643540164503064803603406397406500495109420942094209742197049027419504912097421097420974219027409274049209742092989249097420224198109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241").div(BigInteger.from("98109840984098409156481068456541684065964819841065106865710397464513210416435401645030648036034063974065004951094209420942097421970490274195049120974210974209742190274092740492097420929892490974202241")).toString() === "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
|
||||
console.assert(BigInteger.from("650891045068740450350436540352434350243346254305240433565403624570436542564034355230360437856406345450735366803660233645540323657640436735034636550432635454032364560324366403643455063652403346540263364032643454530236455402336455640363263405423565405623454062354540326564062306456432664546654436564364556406435460643646363545606345066534456065340165344065234064564").div(BigInteger.from("2634565230452364554234565062345452365450236455423654456253445652344565423655423655462534506253450462354056523445062535462534052654350426355023654540625344056203455402635454026435501635446643754664546780646476442344654465764466744566754436556406235454066354570657548036545465")).toString() === "247058238507527885509216194910087226997858456323482112332514020694766925604284002588230023");
|
||||
console.assert(BigInteger.from("650891045068740450350436540352434350243346254305240433565403624570436542564034355230360437856406345450735366803660233645540323657640436735034636550432635454032364560324366403643455063652403346540263364032643454530236455402336455640363263405423565405623454062354540326564062306456432664546654436564364556406435460643646363545606345066534456065340165344065234064564000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").div(BigInteger.from("2634565230452364554234565062345452365450236455423654456253445652344565423655423655462534506253450462354056523445062535462534052654350426355023654540625344056203455402635454026435501635446643754664546780646476442344654465764466744566754436556406235454066354570657548036545465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")).toString() === "247058238507527885509216194910087226997858456323482112332514020694766925604284002588230023");
|
||||
console.assert(BigInteger.from("9999999999999900000000000000").div(BigInteger.from("999999999999990000001")).toString() === "9999999");
|
||||
|
||||
console.groupEnd();
|
||||
console.groupEnd();
|
||||
console.groupEnd();
|
||||
|
||||
console.log("done");
|
||||
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @param { number[] } array
|
||||
* @param { number } index
|
||||
* @param { number } init
|
||||
*/
|
||||
export function at(array, index, init) {
|
||||
while (array.length <= index) array.push(init);
|
||||
return array[index];
|
||||
}
|
||||
Reference in New Issue
Block a user