@danielsimonjr/mathts-core 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-BDNTTHO4.js → chunk-AMOHH5MP.js} +2298 -2297
- package/dist/{index-DpOizJsa.d.ts → index-zKEDY9aj.d.ts} +29 -1
- package/dist/index.d.ts +784 -2
- package/dist/index.js +415 -41
- package/dist/internal.d.ts +2 -30
- package/dist/internal.js +3 -3
- package/package.json +59 -59
|
@@ -553,2631 +553,2631 @@ var COMPLEX_ZERO = new Complex(0, 0);
|
|
|
553
553
|
var COMPLEX_ONE = new Complex(1, 0);
|
|
554
554
|
var COMPLEX_NEG_ONE = new Complex(-1, 0);
|
|
555
555
|
|
|
556
|
-
// src/
|
|
557
|
-
function
|
|
558
|
-
return
|
|
556
|
+
// src/is.ts
|
|
557
|
+
function hasPrototypeFlag(x, flag) {
|
|
558
|
+
return !!x && x.constructor.prototype[flag] === true;
|
|
559
559
|
}
|
|
560
|
-
function
|
|
561
|
-
|
|
562
|
-
b = b < 0n ? -b : b;
|
|
563
|
-
while (b !== 0n) {
|
|
564
|
-
const t = b;
|
|
565
|
-
b = a % b;
|
|
566
|
-
a = t;
|
|
567
|
-
}
|
|
568
|
-
return a;
|
|
560
|
+
function hasOwnAndPrototypeFlag(x, ownFlag, protoFlag) {
|
|
561
|
+
return !!x && x[ownFlag] === true && x.constructor.prototype[protoFlag] === true;
|
|
569
562
|
}
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
if (isFraction(x)) {
|
|
577
|
-
return [x.numerator, x.denominator];
|
|
578
|
-
}
|
|
579
|
-
if (typeof x === "number" && !Number.isInteger(x)) {
|
|
580
|
-
const f = _Fraction.fromNumber(x);
|
|
581
|
-
return [f.numerator, f.denominator];
|
|
582
|
-
}
|
|
583
|
-
return [typeof x === "bigint" ? x : BigInt(x), 1n];
|
|
584
|
-
};
|
|
585
|
-
const [pn, qn] = toRatio(numerator);
|
|
586
|
-
const [pd, qd] = toRatio(denominator);
|
|
587
|
-
let num = pn * qd;
|
|
588
|
-
let den = qn * pd;
|
|
589
|
-
if (den === 0n) {
|
|
590
|
-
throw new Error("Fraction denominator cannot be zero");
|
|
591
|
-
}
|
|
592
|
-
if (den < 0n) {
|
|
593
|
-
num = -num;
|
|
594
|
-
den = -den;
|
|
595
|
-
}
|
|
596
|
-
const g = gcd(num, den);
|
|
597
|
-
this.numerator = num / g;
|
|
598
|
-
this.denominator = den / g;
|
|
599
|
-
}
|
|
600
|
-
// ============================================================
|
|
601
|
-
// Static Factory Methods
|
|
602
|
-
// ============================================================
|
|
603
|
-
/**
|
|
604
|
-
* Create a Fraction from a number (with optional precision)
|
|
605
|
-
*/
|
|
606
|
-
static fromNumber(n, maxDenominator = 1000000n) {
|
|
607
|
-
if (!Number.isFinite(n)) {
|
|
608
|
-
throw new Error("Cannot create fraction from non-finite number");
|
|
609
|
-
}
|
|
610
|
-
if (Number.isInteger(n)) {
|
|
611
|
-
return new _Fraction(BigInt(n), 1n);
|
|
612
|
-
}
|
|
613
|
-
const sign2 = n < 0 ? -1n : 1n;
|
|
614
|
-
n = Math.abs(n);
|
|
615
|
-
let h1 = 1n, h2 = 0n;
|
|
616
|
-
let k1 = 0n, k2 = 1n;
|
|
617
|
-
let b = n;
|
|
618
|
-
do {
|
|
619
|
-
const a = BigInt(Math.floor(b));
|
|
620
|
-
let aux = h1;
|
|
621
|
-
h1 = a * h1 + h2;
|
|
622
|
-
h2 = aux;
|
|
623
|
-
aux = k1;
|
|
624
|
-
k1 = a * k1 + k2;
|
|
625
|
-
k2 = aux;
|
|
626
|
-
b = 1 / (b - Number(a));
|
|
627
|
-
} while (Math.abs(n - Number(h1) / Number(k1)) > Number.EPSILON && k1 < maxDenominator);
|
|
628
|
-
return new _Fraction(sign2 * h1, k1);
|
|
563
|
+
function isNumber(x) {
|
|
564
|
+
return typeof x === "number";
|
|
565
|
+
}
|
|
566
|
+
function isBigNumber(x) {
|
|
567
|
+
if (!x || typeof x !== "object" || typeof x.constructor !== "function") {
|
|
568
|
+
return false;
|
|
629
569
|
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
static fromDecimalString(str) {
|
|
634
|
-
str = str.trim();
|
|
635
|
-
const repeatingMatch = str.match(/^(-?\d*)\.(\d*)\((\d+)\)$/);
|
|
636
|
-
if (repeatingMatch) {
|
|
637
|
-
const sign3 = str.startsWith("-") ? -1n : 1n;
|
|
638
|
-
const intPart2 = repeatingMatch[1] === "-" ? "0" : repeatingMatch[1] || "0";
|
|
639
|
-
const nonRepeating = repeatingMatch[2] || "";
|
|
640
|
-
const repeating = repeatingMatch[3];
|
|
641
|
-
const fullDigits = intPart2 + nonRepeating + repeating;
|
|
642
|
-
const nonRepDigits = intPart2 + nonRepeating;
|
|
643
|
-
const fullNum = BigInt(fullDigits.replace("-", ""));
|
|
644
|
-
const nonRepNum = BigInt(nonRepDigits.replace("-", "") || "0");
|
|
645
|
-
const nines = BigInt("9".repeat(repeating.length));
|
|
646
|
-
const zeros2 = BigInt("1" + "0".repeat(nonRepeating.length));
|
|
647
|
-
const num2 = fullNum - nonRepNum;
|
|
648
|
-
const den2 = nines * zeros2;
|
|
649
|
-
return new _Fraction(sign3 * num2, den2);
|
|
650
|
-
}
|
|
651
|
-
const [intPart, decPart = ""] = str.split(".");
|
|
652
|
-
const sign2 = str.startsWith("-") ? -1n : 1n;
|
|
653
|
-
const absInt = intPart.replace("-", "") || "0";
|
|
654
|
-
const combined = absInt + decPart;
|
|
655
|
-
const num = BigInt(combined);
|
|
656
|
-
const den = BigInt("1" + "0".repeat(decPart.length));
|
|
657
|
-
return new _Fraction(sign2 * num, den);
|
|
570
|
+
const obj = x;
|
|
571
|
+
if (obj.isBigNumber === true && typeof obj.constructor.prototype === "object" && obj.constructor.prototype.isBigNumber === true) {
|
|
572
|
+
return true;
|
|
658
573
|
}
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
* Supports formats: "3/4", "-3/4", "3", "3.14", "0.(3)"
|
|
662
|
-
*/
|
|
663
|
-
static parse(str) {
|
|
664
|
-
str = str.trim();
|
|
665
|
-
if (str.includes("/")) {
|
|
666
|
-
const [numStr, denStr] = str.split("/");
|
|
667
|
-
return new _Fraction(BigInt(numStr.trim()), BigInt(denStr.trim()));
|
|
668
|
-
}
|
|
669
|
-
if (str.includes(".") || str.includes("(")) {
|
|
670
|
-
return _Fraction.fromDecimalString(str);
|
|
671
|
-
}
|
|
672
|
-
return new _Fraction(BigInt(str), 1n);
|
|
574
|
+
if (typeof obj.constructor.isDecimal === "function" && obj.constructor.isDecimal(obj) === true) {
|
|
575
|
+
return true;
|
|
673
576
|
}
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
577
|
+
return false;
|
|
578
|
+
}
|
|
579
|
+
function isBigInt(x) {
|
|
580
|
+
return typeof x === "bigint";
|
|
581
|
+
}
|
|
582
|
+
function isComplex2(x) {
|
|
583
|
+
return !!(x && typeof x === "object" && Object.getPrototypeOf(x).isComplex === true);
|
|
584
|
+
}
|
|
585
|
+
function isFraction(x) {
|
|
586
|
+
return !!(x && typeof x === "object" && Object.getPrototypeOf(x).isFraction === true);
|
|
587
|
+
}
|
|
588
|
+
function isUnit(x) {
|
|
589
|
+
return hasPrototypeFlag(x, "isUnit");
|
|
590
|
+
}
|
|
591
|
+
function isString(x) {
|
|
592
|
+
return typeof x === "string";
|
|
593
|
+
}
|
|
594
|
+
var isArray = Array.isArray;
|
|
595
|
+
function isMatrix(x) {
|
|
596
|
+
return hasPrototypeFlag(x, "isMatrix");
|
|
597
|
+
}
|
|
598
|
+
function isCollection(x) {
|
|
599
|
+
return Array.isArray(x) || isMatrix(x);
|
|
600
|
+
}
|
|
601
|
+
function isDenseMatrix(x) {
|
|
602
|
+
return hasOwnAndPrototypeFlag(x, "isDenseMatrix", "isMatrix");
|
|
603
|
+
}
|
|
604
|
+
function isSparseMatrix(x) {
|
|
605
|
+
return hasOwnAndPrototypeFlag(x, "isSparseMatrix", "isMatrix");
|
|
606
|
+
}
|
|
607
|
+
function isRange(x) {
|
|
608
|
+
return hasPrototypeFlag(x, "isRange");
|
|
609
|
+
}
|
|
610
|
+
function isIndex(x) {
|
|
611
|
+
return hasPrototypeFlag(x, "isIndex");
|
|
612
|
+
}
|
|
613
|
+
function isBoolean(x) {
|
|
614
|
+
return typeof x === "boolean";
|
|
615
|
+
}
|
|
616
|
+
function isFunction(x) {
|
|
617
|
+
return typeof x === "function";
|
|
618
|
+
}
|
|
619
|
+
function isDate(x) {
|
|
620
|
+
return x instanceof Date;
|
|
621
|
+
}
|
|
622
|
+
function isRegExp(x) {
|
|
623
|
+
return x instanceof RegExp;
|
|
624
|
+
}
|
|
625
|
+
function isObject(x) {
|
|
626
|
+
return !!(x && typeof x === "object" && x.constructor === Object && !isComplex2(x) && !isFraction(x));
|
|
627
|
+
}
|
|
628
|
+
function isMap(object) {
|
|
629
|
+
if (!object) {
|
|
630
|
+
return false;
|
|
682
631
|
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
632
|
+
const o = object;
|
|
633
|
+
return object instanceof Map || typeof o.set === "function" && typeof o.get === "function" && typeof o.keys === "function" && typeof o.has === "function";
|
|
634
|
+
}
|
|
635
|
+
function isNull(x) {
|
|
636
|
+
return x === null;
|
|
637
|
+
}
|
|
638
|
+
function isUndefined(x) {
|
|
639
|
+
return x === void 0;
|
|
640
|
+
}
|
|
641
|
+
function typeOf(x) {
|
|
642
|
+
const t = typeof x;
|
|
643
|
+
if (t === "object") {
|
|
644
|
+
if (x === null) return "null";
|
|
645
|
+
if (isBigNumber(x)) return "BigNumber";
|
|
646
|
+
if (isComplex2(x)) return "Complex";
|
|
647
|
+
if (isFraction(x)) return "Fraction";
|
|
648
|
+
const ctor = x.constructor;
|
|
649
|
+
if (ctor && ctor.name) return ctor.name;
|
|
650
|
+
return "Object";
|
|
692
651
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
652
|
+
return t;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// src/number.ts
|
|
656
|
+
function isInteger(value) {
|
|
657
|
+
if (typeof value === "boolean") {
|
|
658
|
+
return true;
|
|
698
659
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
660
|
+
return isFinite(value) ? value === Math.round(value) : false;
|
|
661
|
+
}
|
|
662
|
+
function safeNumberType(numberStr, config2) {
|
|
663
|
+
if (config2.number === "bigint") {
|
|
664
|
+
try {
|
|
665
|
+
BigInt(numberStr);
|
|
666
|
+
} catch {
|
|
667
|
+
return config2.numberFallback;
|
|
702
668
|
}
|
|
703
|
-
return `${this.numerator}/${this.denominator}`;
|
|
704
669
|
}
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
670
|
+
return config2.number;
|
|
671
|
+
}
|
|
672
|
+
var sign = Math.sign || function(x) {
|
|
673
|
+
if (x > 0) {
|
|
674
|
+
return 1;
|
|
675
|
+
} else if (x < 0) {
|
|
676
|
+
return -1;
|
|
677
|
+
} else {
|
|
678
|
+
return 0;
|
|
711
679
|
}
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
680
|
+
};
|
|
681
|
+
var log2 = Math.log2 || function log22(x) {
|
|
682
|
+
return Math.log(x) / Math.LN2;
|
|
683
|
+
};
|
|
684
|
+
var log10 = Math.log10 || function log102(x) {
|
|
685
|
+
return Math.log(x) / Math.LN10;
|
|
686
|
+
};
|
|
687
|
+
var log1p = Math.log1p || function(x) {
|
|
688
|
+
return Math.log(x + 1);
|
|
689
|
+
};
|
|
690
|
+
var cbrt = Math.cbrt || function cbrt2(x) {
|
|
691
|
+
if (x === 0) {
|
|
692
|
+
return x;
|
|
717
693
|
}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
694
|
+
const negate = x < 0;
|
|
695
|
+
let result;
|
|
696
|
+
if (negate) {
|
|
697
|
+
x = -x;
|
|
698
|
+
}
|
|
699
|
+
if (isFinite(x)) {
|
|
700
|
+
result = Math.exp(Math.log(x) / 3);
|
|
701
|
+
result = (x / (result * result) + 2 * result) / 3;
|
|
702
|
+
} else {
|
|
703
|
+
result = x;
|
|
704
|
+
}
|
|
705
|
+
return negate ? -result : result;
|
|
706
|
+
};
|
|
707
|
+
var expm1 = Math.expm1 || function expm12(x) {
|
|
708
|
+
return x >= 2e-4 || x <= -2e-4 ? Math.exp(x) - 1 : x + x * x / 2 + x * x * x / 6;
|
|
709
|
+
};
|
|
710
|
+
function formatNumberToBase(n, base, size) {
|
|
711
|
+
const prefixes = { 2: "0b", 8: "0o", 16: "0x" };
|
|
712
|
+
const prefix = prefixes[base];
|
|
713
|
+
let suffix = "";
|
|
714
|
+
if (size) {
|
|
715
|
+
if (size < 1) {
|
|
716
|
+
throw new Error("size must be in greater than 0");
|
|
729
717
|
}
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
num *= 10n;
|
|
733
|
-
decPart += (num / den).toString();
|
|
734
|
-
num = num % den;
|
|
718
|
+
if (!isInteger(size)) {
|
|
719
|
+
throw new Error("size must be an integer");
|
|
735
720
|
}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
/**
|
|
739
|
-
* Convert to LaTeX string
|
|
740
|
-
*/
|
|
741
|
-
toLatex() {
|
|
742
|
-
if (this.denominator === 1n) {
|
|
743
|
-
return this.numerator.toString();
|
|
721
|
+
if (n > 2 ** (size - 1) - 1 || n < -(2 ** (size - 1))) {
|
|
722
|
+
throw new Error(`Value must be in range [-2^${size - 1}, 2^${size - 1}-1]`);
|
|
744
723
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
724
|
+
if (!isInteger(n)) {
|
|
725
|
+
throw new Error("Value must be an integer");
|
|
726
|
+
}
|
|
727
|
+
if (n < 0) {
|
|
728
|
+
n = n + 2 ** size;
|
|
729
|
+
}
|
|
730
|
+
suffix = `i${size}`;
|
|
748
731
|
}
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
const sign2 = this.numerator < 0n ? -1n : 1n;
|
|
754
|
-
const absNum = this.numerator < 0n ? -this.numerator : this.numerator;
|
|
755
|
-
const whole = sign2 * (absNum / this.denominator);
|
|
756
|
-
const remainder = absNum % this.denominator;
|
|
757
|
-
return {
|
|
758
|
-
whole,
|
|
759
|
-
numerator: remainder,
|
|
760
|
-
denominator: this.denominator
|
|
761
|
-
};
|
|
732
|
+
let sign2 = "";
|
|
733
|
+
if (n < 0) {
|
|
734
|
+
n = -n;
|
|
735
|
+
sign2 = "-";
|
|
762
736
|
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
*/
|
|
769
|
-
add(other) {
|
|
770
|
-
if (other instanceof _Fraction) {
|
|
771
|
-
const num = this.numerator * other.denominator + other.numerator * this.denominator;
|
|
772
|
-
const den = this.denominator * other.denominator;
|
|
773
|
-
return new _Fraction(num, den);
|
|
774
|
-
}
|
|
775
|
-
return this.add(_Fraction.fromNumber(Number(other.valueOf())));
|
|
737
|
+
return `${sign2}${prefix}${n.toString(base)}${suffix}`;
|
|
738
|
+
}
|
|
739
|
+
function format(value, options) {
|
|
740
|
+
if (typeof options === "function") {
|
|
741
|
+
return options(value);
|
|
776
742
|
}
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
const den = this.denominator * other.denominator;
|
|
784
|
-
return new _Fraction(num, den);
|
|
785
|
-
}
|
|
786
|
-
return this.subtract(_Fraction.fromNumber(Number(other.valueOf())));
|
|
743
|
+
if (value === Infinity) {
|
|
744
|
+
return "Infinity";
|
|
745
|
+
} else if (value === -Infinity) {
|
|
746
|
+
return "-Infinity";
|
|
747
|
+
} else if (isNaN(value)) {
|
|
748
|
+
return "NaN";
|
|
787
749
|
}
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
return
|
|
794
|
-
|
|
795
|
-
|
|
750
|
+
const { notation, precision, wordSize } = normalizeFormatOptions(options);
|
|
751
|
+
switch (notation) {
|
|
752
|
+
case "fixed":
|
|
753
|
+
return toFixed(value, precision);
|
|
754
|
+
case "exponential":
|
|
755
|
+
return toExponential(value, precision);
|
|
756
|
+
case "engineering":
|
|
757
|
+
return toEngineering(value, precision);
|
|
758
|
+
case "bin":
|
|
759
|
+
return formatNumberToBase(value, 2, wordSize);
|
|
760
|
+
case "oct":
|
|
761
|
+
return formatNumberToBase(value, 8, wordSize);
|
|
762
|
+
case "hex":
|
|
763
|
+
return formatNumberToBase(value, 16, wordSize);
|
|
764
|
+
case "auto":
|
|
765
|
+
return toPrecision(value, precision, options).replace(
|
|
766
|
+
/((\.\d*?)(0+))($|e)/,
|
|
767
|
+
function(_match, _all, digits2, _zeros, e) {
|
|
768
|
+
return digits2 !== "." ? digits2 + e : e;
|
|
769
|
+
}
|
|
770
|
+
);
|
|
771
|
+
default:
|
|
772
|
+
throw new Error(
|
|
773
|
+
'Unknown notation "' + notation + '". Choose "auto", "exponential", "fixed", "bin", "oct", or "hex.'
|
|
774
|
+
);
|
|
796
775
|
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
776
|
+
}
|
|
777
|
+
function normalizeFormatOptions(options) {
|
|
778
|
+
let notation = "auto";
|
|
779
|
+
let precision;
|
|
780
|
+
let wordSize;
|
|
781
|
+
if (options !== void 0) {
|
|
782
|
+
if (isNumber(options)) {
|
|
783
|
+
precision = options;
|
|
784
|
+
} else if (isBigNumber(options)) {
|
|
785
|
+
precision = options.toNumber();
|
|
786
|
+
} else if (isObject(options)) {
|
|
787
|
+
if (options.precision !== void 0) {
|
|
788
|
+
precision = _toNumberOrThrow(options.precision, () => {
|
|
789
|
+
throw new Error('Option "precision" must be a number or BigNumber');
|
|
790
|
+
});
|
|
804
791
|
}
|
|
805
|
-
|
|
792
|
+
if (options.wordSize !== void 0) {
|
|
793
|
+
wordSize = _toNumberOrThrow(options.wordSize, () => {
|
|
794
|
+
throw new Error('Option "wordSize" must be a number or BigNumber');
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
if (options.notation) {
|
|
798
|
+
notation = options.notation;
|
|
799
|
+
}
|
|
800
|
+
} else {
|
|
801
|
+
throw new Error("Unsupported type of options, number, BigNumber, or object expected");
|
|
806
802
|
}
|
|
807
|
-
return this.divide(_Fraction.fromNumber(Number(other.valueOf())));
|
|
808
803
|
}
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
804
|
+
return { notation, precision, wordSize };
|
|
805
|
+
}
|
|
806
|
+
function splitNumber(value) {
|
|
807
|
+
const match = String(value).toLowerCase().match(/^(-?)(\d+\.?\d*)(e([+-]?\d+))?$/);
|
|
808
|
+
if (!match) {
|
|
809
|
+
throw new SyntaxError("Invalid number " + value);
|
|
815
810
|
}
|
|
816
|
-
|
|
817
|
-
|
|
811
|
+
const sign2 = match[1];
|
|
812
|
+
const digits2 = match[2];
|
|
813
|
+
let exponent = parseFloat(match[4] || "0");
|
|
814
|
+
const dot = digits2.indexOf(".");
|
|
815
|
+
exponent += dot !== -1 ? dot - 1 : digits2.length - 1;
|
|
816
|
+
const coefficients = digits2.replace(".", "").replace(/^0*/, function(zeros2) {
|
|
817
|
+
exponent -= zeros2.length;
|
|
818
|
+
return "";
|
|
819
|
+
}).replace(/0*$/, "").split("").map(function(d) {
|
|
820
|
+
return parseInt(d);
|
|
821
|
+
});
|
|
822
|
+
if (coefficients.length === 0) {
|
|
823
|
+
coefficients.push(0);
|
|
824
|
+
exponent++;
|
|
818
825
|
}
|
|
819
|
-
|
|
820
|
-
|
|
826
|
+
return { sign: sign2, coefficients, exponent };
|
|
827
|
+
}
|
|
828
|
+
function toEngineering(value, precision) {
|
|
829
|
+
if (isNaN(value) || !isFinite(value)) {
|
|
830
|
+
return String(value);
|
|
821
831
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
832
|
+
const split = splitNumber(value);
|
|
833
|
+
const rounded = roundDigits(split, precision);
|
|
834
|
+
const e = rounded.exponent;
|
|
835
|
+
const c = rounded.coefficients;
|
|
836
|
+
const newExp = e % 3 === 0 ? e : e < 0 ? e - 3 - e % 3 : e - e % 3;
|
|
837
|
+
if (isNumber(precision)) {
|
|
838
|
+
while (precision > c.length || e - newExp + 1 > c.length) {
|
|
839
|
+
c.push(0);
|
|
840
|
+
}
|
|
841
|
+
} else {
|
|
842
|
+
const missingZeros = Math.abs(e - newExp) - (c.length - 1);
|
|
843
|
+
for (let i = 0; i < missingZeros; i++) {
|
|
844
|
+
c.push(0);
|
|
845
|
+
}
|
|
827
846
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
847
|
+
let expDiff = Math.abs(e - newExp);
|
|
848
|
+
let decimalIdx = 1;
|
|
849
|
+
while (expDiff > 0) {
|
|
850
|
+
decimalIdx++;
|
|
851
|
+
expDiff--;
|
|
833
852
|
}
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
return
|
|
853
|
+
const decimals = c.slice(decimalIdx).join("");
|
|
854
|
+
const decimalVal = isNumber(precision) && decimals.length || decimals.match(/[1-9]/) ? "." + decimals : "";
|
|
855
|
+
const str = c.slice(0, decimalIdx).join("") + decimalVal + "e" + (e >= 0 ? "+" : "") + newExp.toString();
|
|
856
|
+
return rounded.sign + str;
|
|
857
|
+
}
|
|
858
|
+
function toFixed(value, precision) {
|
|
859
|
+
if (isNaN(value) || !isFinite(value)) {
|
|
860
|
+
return String(value);
|
|
842
861
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
}
|
|
851
|
-
if (exp < 0n) {
|
|
852
|
-
return this.inverse().pow(-exp);
|
|
853
|
-
}
|
|
854
|
-
let result = new _Fraction(1n, 1n);
|
|
855
|
-
let base = this.clone();
|
|
856
|
-
let e = exp;
|
|
857
|
-
while (e > 0n) {
|
|
858
|
-
if (e % 2n === 1n) {
|
|
859
|
-
result = result.multiply(base);
|
|
860
|
-
}
|
|
861
|
-
base = base.multiply(base);
|
|
862
|
-
e = e / 2n;
|
|
863
|
-
}
|
|
864
|
-
return result;
|
|
862
|
+
const splitValue = splitNumber(value);
|
|
863
|
+
const rounded = typeof precision === "number" ? roundDigits(splitValue, splitValue.exponent + 1 + precision) : splitValue;
|
|
864
|
+
let c = rounded.coefficients;
|
|
865
|
+
let p = rounded.exponent + 1;
|
|
866
|
+
const pp = p + (precision || 0);
|
|
867
|
+
if (c.length < pp) {
|
|
868
|
+
c = c.concat(zeros(pp - c.length));
|
|
865
869
|
}
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
mod(other) {
|
|
870
|
-
const quotient = this.divide(other);
|
|
871
|
-
const floorQuot = quotient.floor();
|
|
872
|
-
return this.subtract(other.multiply(floorQuot));
|
|
870
|
+
if (p < 0) {
|
|
871
|
+
c = zeros(-p + 1).concat(c);
|
|
872
|
+
p = 1;
|
|
873
873
|
}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
// ============================================================
|
|
877
|
-
/**
|
|
878
|
-
* Check equality
|
|
879
|
-
*/
|
|
880
|
-
equals(other) {
|
|
881
|
-
return this.numerator === other.numerator && this.denominator === other.denominator;
|
|
874
|
+
if (p < c.length) {
|
|
875
|
+
c.splice(p, 0, p === 0 ? "0." : ".");
|
|
882
876
|
}
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
return
|
|
877
|
+
return rounded.sign + c.join("");
|
|
878
|
+
}
|
|
879
|
+
function toExponential(value, precision) {
|
|
880
|
+
if (isNaN(value) || !isFinite(value)) {
|
|
881
|
+
return String(value);
|
|
888
882
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
883
|
+
const split = splitNumber(value);
|
|
884
|
+
const rounded = precision ? roundDigits(split, precision) : split;
|
|
885
|
+
let c = rounded.coefficients;
|
|
886
|
+
const e = rounded.exponent;
|
|
887
|
+
if (precision && c.length < precision) {
|
|
888
|
+
c = c.concat(zeros(precision - c.length));
|
|
894
889
|
}
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
890
|
+
const first = c.shift();
|
|
891
|
+
return rounded.sign + first + (c.length > 0 ? "." + c.join("") : "") + "e" + (e >= 0 ? "+" : "") + e;
|
|
892
|
+
}
|
|
893
|
+
function toPrecision(value, precision, options) {
|
|
894
|
+
if (isNaN(value) || !isFinite(value)) {
|
|
895
|
+
return String(value);
|
|
900
896
|
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
897
|
+
const lowerExp = _toNumberOrDefault(options?.lowerExp, -3);
|
|
898
|
+
const upperExp = _toNumberOrDefault(options?.upperExp, 5);
|
|
899
|
+
const split = splitNumber(value);
|
|
900
|
+
const rounded = precision ? roundDigits(split, precision) : split;
|
|
901
|
+
if (rounded.exponent < lowerExp || rounded.exponent >= upperExp) {
|
|
902
|
+
return toExponential(value, precision);
|
|
903
|
+
} else {
|
|
904
|
+
let c = rounded.coefficients;
|
|
905
|
+
const e = rounded.exponent;
|
|
906
|
+
if (precision && c.length < precision) {
|
|
907
|
+
c = c.concat(zeros(precision - c.length));
|
|
908
|
+
}
|
|
909
|
+
c = c.concat(
|
|
910
|
+
zeros(e - c.length + 1 + (precision && c.length < precision ? precision - c.length : 0))
|
|
911
|
+
);
|
|
912
|
+
c = zeros(-e).concat(c);
|
|
913
|
+
const dot = e > 0 ? e : 0;
|
|
914
|
+
if (dot < c.length - 1) {
|
|
915
|
+
c.splice(dot + 1, 0, ".");
|
|
916
|
+
}
|
|
917
|
+
return rounded.sign + c.join("");
|
|
906
918
|
}
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
919
|
+
}
|
|
920
|
+
function roundDigits(split, precision) {
|
|
921
|
+
const rounded = {
|
|
922
|
+
sign: split.sign,
|
|
923
|
+
coefficients: split.coefficients.slice(),
|
|
924
|
+
exponent: split.exponent
|
|
925
|
+
};
|
|
926
|
+
const c = rounded.coefficients;
|
|
927
|
+
if (precision !== void 0) {
|
|
928
|
+
while (precision <= 0) {
|
|
929
|
+
c.unshift(0);
|
|
930
|
+
rounded.exponent++;
|
|
931
|
+
precision++;
|
|
932
|
+
}
|
|
933
|
+
if (c.length > precision) {
|
|
934
|
+
const removed = c.splice(precision, c.length - precision);
|
|
935
|
+
if (removed[0] >= 5) {
|
|
936
|
+
let i = precision - 1;
|
|
937
|
+
c[i]++;
|
|
938
|
+
while (c[i] === 10) {
|
|
939
|
+
c.pop();
|
|
940
|
+
if (i === 0) {
|
|
941
|
+
c.unshift(0);
|
|
942
|
+
rounded.exponent++;
|
|
943
|
+
i++;
|
|
944
|
+
}
|
|
945
|
+
i--;
|
|
946
|
+
c[i]++;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
}
|
|
913
950
|
}
|
|
914
|
-
|
|
915
|
-
|
|
951
|
+
return rounded;
|
|
952
|
+
}
|
|
953
|
+
function zeros(length) {
|
|
954
|
+
const arr = [];
|
|
955
|
+
for (let i = 0; i < length; i++) {
|
|
956
|
+
arr.push(0);
|
|
916
957
|
}
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
958
|
+
return arr;
|
|
959
|
+
}
|
|
960
|
+
function digits(value) {
|
|
961
|
+
return value.toExponential().replace(/e.*$/, "").replace(/^0\.?0*|\./, "").length;
|
|
962
|
+
}
|
|
963
|
+
function nearlyEqual(a, b, relTol = 1e-8, absTol = 0) {
|
|
964
|
+
if (relTol <= 0) {
|
|
965
|
+
throw new Error("Relative tolerance must be greater than 0");
|
|
925
966
|
}
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
*/
|
|
929
|
-
isZero() {
|
|
930
|
-
return this.numerator === 0n;
|
|
967
|
+
if (absTol < 0) {
|
|
968
|
+
throw new Error("Absolute tolerance must be at least 0");
|
|
931
969
|
}
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
*/
|
|
935
|
-
isPositive() {
|
|
936
|
-
return this.numerator > 0n;
|
|
970
|
+
if (isNaN(a) || isNaN(b)) {
|
|
971
|
+
return false;
|
|
937
972
|
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
*/
|
|
941
|
-
isNegative() {
|
|
942
|
-
return this.numerator < 0n;
|
|
973
|
+
if (!isFinite(a) || !isFinite(b)) {
|
|
974
|
+
return a === b;
|
|
943
975
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
*/
|
|
947
|
-
isInteger() {
|
|
948
|
-
return this.denominator === 1n;
|
|
976
|
+
if (a === b) {
|
|
977
|
+
return true;
|
|
949
978
|
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
979
|
+
return Math.abs(a - b) <= Math.max(relTol * Math.max(Math.abs(a), Math.abs(b)), absTol);
|
|
980
|
+
}
|
|
981
|
+
var acosh = Math.acosh || function(x) {
|
|
982
|
+
return Math.log(Math.sqrt(x * x - 1) + x);
|
|
983
|
+
};
|
|
984
|
+
var asinh = Math.asinh || function(x) {
|
|
985
|
+
return Math.log(Math.sqrt(x * x + 1) + x);
|
|
986
|
+
};
|
|
987
|
+
var atanh = Math.atanh || function(x) {
|
|
988
|
+
return Math.log((1 + x) / (1 - x)) / 2;
|
|
989
|
+
};
|
|
990
|
+
var cosh = Math.cosh || function(x) {
|
|
991
|
+
return (Math.exp(x) + Math.exp(-x)) / 2;
|
|
992
|
+
};
|
|
993
|
+
var sinh = Math.sinh || function(x) {
|
|
994
|
+
return (Math.exp(x) - Math.exp(-x)) / 2;
|
|
995
|
+
};
|
|
996
|
+
var tanh = Math.tanh || function(x) {
|
|
997
|
+
const e = Math.exp(2 * x);
|
|
998
|
+
return (e - 1) / (e + 1);
|
|
999
|
+
};
|
|
1000
|
+
function copysign(x, y) {
|
|
1001
|
+
const signx = x > 0 ? true : x < 0 ? false : 1 / x === Infinity;
|
|
1002
|
+
const signy = y > 0 ? true : y < 0 ? false : 1 / y === Infinity;
|
|
1003
|
+
return signx !== signy ? -x : x;
|
|
1004
|
+
}
|
|
1005
|
+
function isPowZeroAtInfinity(x, y) {
|
|
1006
|
+
return x * x < 1 && y === Infinity || x * x > 1 && y === -Infinity;
|
|
1007
|
+
}
|
|
1008
|
+
function _toNumberOrThrow(value, onError) {
|
|
1009
|
+
if (isNumber(value)) {
|
|
1010
|
+
return value;
|
|
1011
|
+
} else if (isBigNumber(value)) {
|
|
1012
|
+
return value.toNumber();
|
|
1013
|
+
} else {
|
|
1014
|
+
onError();
|
|
1015
|
+
return 0;
|
|
955
1016
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
if (this.numerator >= 0n || this.numerator % this.denominator === 0n) {
|
|
965
|
-
return new _Fraction(quot, 1n);
|
|
966
|
-
}
|
|
967
|
-
return new _Fraction(quot - 1n, 1n);
|
|
1017
|
+
}
|
|
1018
|
+
function _toNumberOrDefault(value, defaultValue) {
|
|
1019
|
+
if (isNumber(value)) {
|
|
1020
|
+
return value;
|
|
1021
|
+
} else if (isBigNumber(value)) {
|
|
1022
|
+
return value.toNumber();
|
|
1023
|
+
} else {
|
|
1024
|
+
return defaultValue;
|
|
968
1025
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
// src/shared.ts
|
|
1029
|
+
function hasOwnProperty(object, property) {
|
|
1030
|
+
return !!object && Object.hasOwnProperty.call(object, property);
|
|
1031
|
+
}
|
|
1032
|
+
function endsWith(text, search) {
|
|
1033
|
+
const start = text.length - search.length;
|
|
1034
|
+
return text.substring(start, text.length) === search;
|
|
1035
|
+
}
|
|
1036
|
+
var warnOnce = /* @__PURE__ */ (() => {
|
|
1037
|
+
const seen = {};
|
|
1038
|
+
return function warnOnce2(...args) {
|
|
1039
|
+
const message = args.join(", ");
|
|
1040
|
+
if (!seen[message]) {
|
|
1041
|
+
seen[message] = true;
|
|
1042
|
+
console.warn("Warning:", ...args);
|
|
975
1043
|
}
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1044
|
+
};
|
|
1045
|
+
})();
|
|
1046
|
+
function memoize(fn, { hasher, limit } = {}) {
|
|
1047
|
+
const hash = hasher ?? ((args) => JSON.stringify(args));
|
|
1048
|
+
const maxSize = limit == null ? Number.POSITIVE_INFINITY : limit;
|
|
1049
|
+
const memoized = function(...args) {
|
|
1050
|
+
if (!(memoized.cache instanceof Map)) {
|
|
1051
|
+
memoized.cache = /* @__PURE__ */ new Map();
|
|
979
1052
|
}
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
const diff = this.subtract(floor);
|
|
988
|
-
const half = new _Fraction(1n, 2n);
|
|
989
|
-
if (diff.greaterThanOrEqual(half)) {
|
|
990
|
-
return floor.add(new _Fraction(1n, 1n));
|
|
1053
|
+
const cache = memoized.cache;
|
|
1054
|
+
const key = hash(args);
|
|
1055
|
+
if (cache.has(key)) {
|
|
1056
|
+
const value2 = cache.get(key);
|
|
1057
|
+
cache.delete(key);
|
|
1058
|
+
cache.set(key, value2);
|
|
1059
|
+
return value2;
|
|
991
1060
|
}
|
|
992
|
-
|
|
1061
|
+
const value = fn.apply(fn, args);
|
|
1062
|
+
cache.set(key, value);
|
|
1063
|
+
if (cache.size > maxSize) {
|
|
1064
|
+
cache.delete(cache.keys().next().value);
|
|
1065
|
+
}
|
|
1066
|
+
return value;
|
|
1067
|
+
};
|
|
1068
|
+
return memoized;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
// src/object.ts
|
|
1072
|
+
function clone(x) {
|
|
1073
|
+
const type = typeof x;
|
|
1074
|
+
if (type === "number" || type === "bigint" || type === "string" || type === "boolean" || x === null || x === void 0) {
|
|
1075
|
+
return x;
|
|
993
1076
|
}
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
trunc() {
|
|
998
|
-
return new _Fraction(this.numerator / this.denominator, 1n);
|
|
1077
|
+
const cloneable = x;
|
|
1078
|
+
if (typeof cloneable.clone === "function") {
|
|
1079
|
+
return cloneable.clone();
|
|
999
1080
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
*/
|
|
1003
|
-
sign() {
|
|
1004
|
-
if (this.numerator < 0n) return -1;
|
|
1005
|
-
if (this.numerator > 0n) return 1;
|
|
1006
|
-
return 0;
|
|
1081
|
+
if (Array.isArray(x)) {
|
|
1082
|
+
return x.map((value) => clone(value));
|
|
1007
1083
|
}
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
return new _Fraction(this.numerator, this.denominator);
|
|
1084
|
+
if (x instanceof Date) return new Date(x.valueOf());
|
|
1085
|
+
if (isBigNumber(x)) return x;
|
|
1086
|
+
if (isObject(x)) {
|
|
1087
|
+
return mapObject(x, clone);
|
|
1013
1088
|
}
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
*/
|
|
1017
|
-
gcd() {
|
|
1018
|
-
return 1n;
|
|
1089
|
+
if (type === "function") {
|
|
1090
|
+
return x;
|
|
1019
1091
|
}
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
while (den !== 0n) {
|
|
1028
|
-
result.push(num / den);
|
|
1029
|
-
const temp = num % den;
|
|
1030
|
-
num = den;
|
|
1031
|
-
den = temp;
|
|
1032
|
-
}
|
|
1033
|
-
if (this.numerator < 0n && result.length > 0) {
|
|
1034
|
-
result[0] = -result[0];
|
|
1092
|
+
throw new TypeError(`Cannot clone: unknown type of value (value: ${x})`);
|
|
1093
|
+
}
|
|
1094
|
+
function mapObject(object, callback) {
|
|
1095
|
+
const clone2 = {};
|
|
1096
|
+
for (const key in object) {
|
|
1097
|
+
if (hasOwnProperty(object, key)) {
|
|
1098
|
+
clone2[key] = callback(object[key]);
|
|
1035
1099
|
}
|
|
1036
|
-
return result;
|
|
1037
1100
|
}
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
let num = cf[cf.length - 1];
|
|
1046
|
-
let den = 1n;
|
|
1047
|
-
for (let i = cf.length - 2; i >= 0; i--) {
|
|
1048
|
-
const temp = num;
|
|
1049
|
-
num = cf[i] * num + den;
|
|
1050
|
-
den = temp;
|
|
1101
|
+
return clone2;
|
|
1102
|
+
}
|
|
1103
|
+
function extend(a, b) {
|
|
1104
|
+
const target = a;
|
|
1105
|
+
for (const prop in b) {
|
|
1106
|
+
if (hasOwnProperty(b, prop)) {
|
|
1107
|
+
target[prop] = b[prop];
|
|
1051
1108
|
}
|
|
1052
|
-
return new _Fraction(num, den);
|
|
1053
|
-
}
|
|
1054
|
-
/**
|
|
1055
|
-
* Mediant of two fractions: (a+c)/(b+d)
|
|
1056
|
-
* Used in Stern-Brocot tree and Farey sequences
|
|
1057
|
-
*/
|
|
1058
|
-
mediant(other) {
|
|
1059
|
-
return new _Fraction(this.numerator + other.numerator, this.denominator + other.denominator);
|
|
1060
1109
|
}
|
|
1061
|
-
|
|
1062
|
-
var FRACTION_ZERO = new Fraction(0n, 1n);
|
|
1063
|
-
var FRACTION_ONE = new Fraction(1n, 1n);
|
|
1064
|
-
var FRACTION_NEG_ONE = new Fraction(-1n, 1n);
|
|
1065
|
-
var FRACTION_HALF = new Fraction(1n, 2n);
|
|
1066
|
-
var FRACTION_THIRD = new Fraction(1n, 3n);
|
|
1067
|
-
var FRACTION_QUARTER = new Fraction(1n, 4n);
|
|
1068
|
-
|
|
1069
|
-
// src/types/bignumber.ts
|
|
1070
|
-
function isBigNumber(value) {
|
|
1071
|
-
return value instanceof BigNumber;
|
|
1110
|
+
return a;
|
|
1072
1111
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
maxExponent: 1e9
|
|
1078
|
-
};
|
|
1079
|
-
var globalConfig = { ...defaultConfig };
|
|
1080
|
-
var BigNumber = class _BigNumber {
|
|
1081
|
-
type = "BigNumber";
|
|
1082
|
-
/**
|
|
1083
|
-
* Duck-typing marker for Decimal.js / mathjs formatter compatibility.
|
|
1084
|
-
* Allows external code that checks `obj.isBigNumber === true` to identify
|
|
1085
|
-
* this class without an `instanceof` check.
|
|
1086
|
-
*/
|
|
1087
|
-
isBigNumber = true;
|
|
1088
|
-
// Internal representation: sign * coefficient * 10^exponent
|
|
1089
|
-
_sign;
|
|
1090
|
-
_coefficient;
|
|
1091
|
-
// Absolute value, normalized
|
|
1092
|
-
_exponent;
|
|
1093
|
-
// Power of 10
|
|
1094
|
-
// Special values
|
|
1095
|
-
_isNaN = false;
|
|
1096
|
-
_isInfinite = false;
|
|
1097
|
-
constructor(sign2, coefficient, exponent, isNaN2 = false, isInfinite = false) {
|
|
1098
|
-
this._sign = sign2;
|
|
1099
|
-
this._coefficient = coefficient;
|
|
1100
|
-
this._exponent = exponent;
|
|
1101
|
-
this._isNaN = isNaN2;
|
|
1102
|
-
this._isInfinite = isInfinite;
|
|
1103
|
-
}
|
|
1104
|
-
// ============================================================
|
|
1105
|
-
// Static Factory Methods
|
|
1106
|
-
// ============================================================
|
|
1107
|
-
/**
|
|
1108
|
-
* Create a BigNumber from a number
|
|
1109
|
-
*/
|
|
1110
|
-
static fromNumber(n) {
|
|
1111
|
-
if (Number.isNaN(n)) {
|
|
1112
|
-
return new _BigNumber(0, 0n, 0, true, false);
|
|
1113
|
-
}
|
|
1114
|
-
if (!Number.isFinite(n)) {
|
|
1115
|
-
return new _BigNumber(n > 0 ? 1 : -1, 0n, 0, false, true);
|
|
1112
|
+
function deepExtend(a, b) {
|
|
1113
|
+
if (Array.isArray(b)) {
|
|
1114
|
+
if (!Array.isArray(a)) {
|
|
1115
|
+
throw new TypeError("Cannot extend an object with an array");
|
|
1116
1116
|
}
|
|
1117
|
-
|
|
1118
|
-
|
|
1117
|
+
for (let i = 0; i < b.length; i++) {
|
|
1118
|
+
const bValue = b[i];
|
|
1119
|
+
if (bValue && bValue.constructor === Object) {
|
|
1120
|
+
if (a[i] === void 0) {
|
|
1121
|
+
a[i] = {};
|
|
1122
|
+
}
|
|
1123
|
+
if (a[i] && a[i].constructor === Object) {
|
|
1124
|
+
deepExtend(a[i], bValue);
|
|
1125
|
+
} else {
|
|
1126
|
+
a[i] = bValue;
|
|
1127
|
+
}
|
|
1128
|
+
} else if (Array.isArray(bValue)) {
|
|
1129
|
+
if (a[i] === void 0) {
|
|
1130
|
+
a[i] = [];
|
|
1131
|
+
}
|
|
1132
|
+
if (Array.isArray(a[i])) {
|
|
1133
|
+
deepExtend(a[i], bValue);
|
|
1134
|
+
} else {
|
|
1135
|
+
a[i] = clone(bValue);
|
|
1136
|
+
}
|
|
1137
|
+
} else {
|
|
1138
|
+
a[i] = bValue;
|
|
1139
|
+
}
|
|
1119
1140
|
}
|
|
1120
|
-
return
|
|
1141
|
+
return a;
|
|
1121
1142
|
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1143
|
+
for (const prop in b) {
|
|
1144
|
+
if (hasOwnProperty(b, prop) && !(prop in Object.prototype) && !(prop in Function.prototype)) {
|
|
1145
|
+
const bValue = b[prop];
|
|
1146
|
+
const aValue = a[prop];
|
|
1147
|
+
if (bValue && bValue.constructor === Object) {
|
|
1148
|
+
if (aValue === void 0) {
|
|
1149
|
+
a[prop] = {};
|
|
1150
|
+
}
|
|
1151
|
+
if (aValue && aValue.constructor === Object) {
|
|
1152
|
+
deepExtend(aValue, bValue);
|
|
1153
|
+
} else {
|
|
1154
|
+
a[prop] = bValue;
|
|
1155
|
+
}
|
|
1156
|
+
} else if (Array.isArray(bValue)) {
|
|
1157
|
+
if (aValue === void 0) {
|
|
1158
|
+
a[prop] = [];
|
|
1159
|
+
}
|
|
1160
|
+
if (Array.isArray(aValue)) {
|
|
1161
|
+
deepExtend(aValue, bValue);
|
|
1162
|
+
} else {
|
|
1163
|
+
a[prop] = clone(bValue);
|
|
1164
|
+
}
|
|
1165
|
+
} else {
|
|
1166
|
+
a[prop] = bValue;
|
|
1167
|
+
}
|
|
1135
1168
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1169
|
+
}
|
|
1170
|
+
return a;
|
|
1171
|
+
}
|
|
1172
|
+
function deepStrictEqual(a, b) {
|
|
1173
|
+
let prop;
|
|
1174
|
+
let i;
|
|
1175
|
+
let len;
|
|
1176
|
+
if (Array.isArray(a)) {
|
|
1177
|
+
if (!Array.isArray(b)) {
|
|
1178
|
+
return false;
|
|
1142
1179
|
}
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
if (eIndex !== -1) {
|
|
1146
|
-
exponentPart = parseInt(str.slice(eIndex + 1), 10);
|
|
1147
|
-
str = str.slice(0, eIndex);
|
|
1180
|
+
if (a.length !== b.length) {
|
|
1181
|
+
return false;
|
|
1148
1182
|
}
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
coefficient = str.slice(0, dotIndex) + str.slice(dotIndex + 1);
|
|
1154
|
-
decimalPlaces = str.length - dotIndex - 1;
|
|
1155
|
-
} else {
|
|
1156
|
-
coefficient = str;
|
|
1183
|
+
for (i = 0, len = a.length; i < len; i++) {
|
|
1184
|
+
if (!deepStrictEqual(a[i], b[i])) {
|
|
1185
|
+
return false;
|
|
1186
|
+
}
|
|
1157
1187
|
}
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1188
|
+
return true;
|
|
1189
|
+
} else if (typeof a === "function") {
|
|
1190
|
+
return a === b;
|
|
1191
|
+
} else if (a instanceof Object) {
|
|
1192
|
+
if (Array.isArray(b) || !(b instanceof Object)) {
|
|
1193
|
+
return false;
|
|
1161
1194
|
}
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
break;
|
|
1195
|
+
const aObj = a;
|
|
1196
|
+
const bObj = b;
|
|
1197
|
+
for (prop in aObj) {
|
|
1198
|
+
if (!(prop in bObj) || !deepStrictEqual(aObj[prop], bObj[prop])) {
|
|
1199
|
+
return false;
|
|
1168
1200
|
}
|
|
1169
1201
|
}
|
|
1170
|
-
|
|
1171
|
-
|
|
1202
|
+
for (prop in bObj) {
|
|
1203
|
+
if (!(prop in aObj)) {
|
|
1204
|
+
return false;
|
|
1205
|
+
}
|
|
1172
1206
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1207
|
+
return true;
|
|
1208
|
+
} else {
|
|
1209
|
+
return a === b;
|
|
1175
1210
|
}
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
trailingZeros++;
|
|
1211
|
+
}
|
|
1212
|
+
function deepFlatten(nestedObject) {
|
|
1213
|
+
const flattenedObject = {};
|
|
1214
|
+
_deepFlatten(nestedObject, flattenedObject);
|
|
1215
|
+
return flattenedObject;
|
|
1216
|
+
}
|
|
1217
|
+
function _deepFlatten(nestedObject, flattenedObject) {
|
|
1218
|
+
for (const prop in nestedObject) {
|
|
1219
|
+
if (hasOwnProperty(nestedObject, prop)) {
|
|
1220
|
+
const value = nestedObject[prop];
|
|
1221
|
+
if (typeof value === "object" && value !== null) {
|
|
1222
|
+
_deepFlatten(value, flattenedObject);
|
|
1189
1223
|
} else {
|
|
1190
|
-
|
|
1224
|
+
flattenedObject[prop] = value;
|
|
1191
1225
|
}
|
|
1192
1226
|
}
|
|
1193
|
-
|
|
1194
|
-
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
function canDefineProperty() {
|
|
1230
|
+
try {
|
|
1231
|
+
if (Object.defineProperty) {
|
|
1232
|
+
Object.defineProperty({}, "x", {
|
|
1233
|
+
get: function() {
|
|
1234
|
+
return null;
|
|
1235
|
+
}
|
|
1236
|
+
});
|
|
1237
|
+
return true;
|
|
1195
1238
|
}
|
|
1196
|
-
|
|
1239
|
+
} catch {
|
|
1197
1240
|
}
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1241
|
+
return false;
|
|
1242
|
+
}
|
|
1243
|
+
function lazy(object, prop, valueResolver) {
|
|
1244
|
+
let _uninitialized = true;
|
|
1245
|
+
let _value;
|
|
1246
|
+
Object.defineProperty(object, prop, {
|
|
1247
|
+
get: function() {
|
|
1248
|
+
if (_uninitialized) {
|
|
1249
|
+
_value = valueResolver();
|
|
1250
|
+
_uninitialized = false;
|
|
1251
|
+
}
|
|
1252
|
+
return _value;
|
|
1253
|
+
},
|
|
1254
|
+
set: function(value) {
|
|
1255
|
+
_value = value;
|
|
1256
|
+
_uninitialized = false;
|
|
1257
|
+
},
|
|
1258
|
+
configurable: true,
|
|
1259
|
+
enumerable: true
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
function traverse(object, path) {
|
|
1263
|
+
if (path && typeof path === "string") {
|
|
1264
|
+
return traverse(object, path.split("."));
|
|
1203
1265
|
}
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1266
|
+
let obj = object;
|
|
1267
|
+
if (path) {
|
|
1268
|
+
for (let i = 0; i < path.length; i++) {
|
|
1269
|
+
const key = path[i];
|
|
1270
|
+
if (!(key in obj)) {
|
|
1271
|
+
obj[key] = {};
|
|
1272
|
+
}
|
|
1273
|
+
obj = obj[key];
|
|
1210
1274
|
}
|
|
1211
|
-
return { ...globalConfig };
|
|
1212
1275
|
}
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1276
|
+
return obj;
|
|
1277
|
+
}
|
|
1278
|
+
function isLegacyFactory(object) {
|
|
1279
|
+
return !!object && typeof object.factory === "function";
|
|
1280
|
+
}
|
|
1281
|
+
function get(object, path) {
|
|
1282
|
+
if (typeof path === "string") {
|
|
1283
|
+
if (isPath(path)) {
|
|
1284
|
+
return get(object, path.split("."));
|
|
1285
|
+
} else {
|
|
1286
|
+
return object[path];
|
|
1287
|
+
}
|
|
1218
1288
|
}
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1289
|
+
let child = object;
|
|
1290
|
+
for (let i = 0; i < path.length; i++) {
|
|
1291
|
+
const key = path[i];
|
|
1292
|
+
child = child ? child[key] : void 0;
|
|
1293
|
+
}
|
|
1294
|
+
return child;
|
|
1295
|
+
}
|
|
1296
|
+
function set(object, path, value) {
|
|
1297
|
+
if (typeof path === "string") {
|
|
1298
|
+
if (isPath(path)) {
|
|
1299
|
+
return set(object, path.split("."), value);
|
|
1300
|
+
} else {
|
|
1301
|
+
object[path] = value;
|
|
1302
|
+
return object;
|
|
1228
1303
|
}
|
|
1229
|
-
if (a._isInfinite) return a._sign;
|
|
1230
|
-
if (b._isInfinite) return -b._sign;
|
|
1231
|
-
if (a._sign === 0 && b._sign === 0) return 0;
|
|
1232
|
-
if (a._sign === 0) return -b._sign;
|
|
1233
|
-
if (b._sign === 0) return a._sign;
|
|
1234
|
-
if (a._sign !== b._sign) return a._sign > b._sign ? 1 : -1;
|
|
1235
|
-
const result = _BigNumber.compareMagnitude(a, b);
|
|
1236
|
-
return a._sign === 1 ? result : -result;
|
|
1237
1304
|
}
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
const
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
if (aOrder !== bOrder) {
|
|
1244
|
-
return aOrder > bOrder ? 1 : -1;
|
|
1305
|
+
let child = object;
|
|
1306
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
1307
|
+
const key = path[i];
|
|
1308
|
+
if (child[key] === void 0) {
|
|
1309
|
+
child[key] = {};
|
|
1245
1310
|
}
|
|
1246
|
-
|
|
1247
|
-
const bFull = bDigits + "0".repeat(Math.max(0, b._exponent));
|
|
1248
|
-
if (aFull === bFull) return 0;
|
|
1249
|
-
return aFull > bFull ? 1 : -1;
|
|
1311
|
+
child = child[key];
|
|
1250
1312
|
}
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
valueOf() {
|
|
1255
|
-
if (this._isNaN) return NaN;
|
|
1256
|
-
if (this._isInfinite) return this._sign === 1 ? Infinity : -Infinity;
|
|
1257
|
-
if (this._sign === 0) return 0;
|
|
1258
|
-
const str = this.toString();
|
|
1259
|
-
return parseFloat(str);
|
|
1260
|
-
}
|
|
1261
|
-
/**
|
|
1262
|
-
* Convert to a JS number.
|
|
1263
|
-
* Alias for `valueOf()` — provided for Decimal.js / mathjs formatter
|
|
1264
|
-
* duck-typing compatibility.
|
|
1265
|
-
*/
|
|
1266
|
-
toNumber() {
|
|
1267
|
-
return this.valueOf();
|
|
1313
|
+
if (path.length > 0) {
|
|
1314
|
+
const lastKey = path[path.length - 1];
|
|
1315
|
+
child[lastKey] = value;
|
|
1268
1316
|
}
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
const
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
const insertPos = digits2.length + this._exponent;
|
|
1279
|
-
return sign2 + digits2.slice(0, insertPos) + "." + digits2.slice(insertPos);
|
|
1280
|
-
} else {
|
|
1281
|
-
return sign2 + "0." + "0".repeat(-this._exponent - digits2.length) + digits2;
|
|
1317
|
+
return object;
|
|
1318
|
+
}
|
|
1319
|
+
function pick(object, properties, transform) {
|
|
1320
|
+
const copy = {};
|
|
1321
|
+
for (let i = 0; i < properties.length; i++) {
|
|
1322
|
+
const key = properties[i];
|
|
1323
|
+
const value = get(object, key);
|
|
1324
|
+
if (value !== void 0) {
|
|
1325
|
+
set(copy, key, transform ? transform(value, key) : value);
|
|
1282
1326
|
}
|
|
1283
1327
|
}
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
* When called with no argument (or `undefined`) returns the full fixed-point
|
|
1294
|
-
* string representation without rounding — matching Decimal.js semantics where
|
|
1295
|
-
* `toFixed()` is equivalent to a lossless fixed-point stringify.
|
|
1296
|
-
* When called with a non-negative integer `decimalPlaces`, rounds and formats
|
|
1297
|
-
* to exactly that many digits after the decimal point.
|
|
1298
|
-
*/
|
|
1299
|
-
toFixed(decimalPlaces) {
|
|
1300
|
-
if (decimalPlaces === void 0) {
|
|
1301
|
-
return this.toFixedInternal(void 0);
|
|
1328
|
+
return copy;
|
|
1329
|
+
}
|
|
1330
|
+
function pickShallow(object, properties) {
|
|
1331
|
+
const copy = {};
|
|
1332
|
+
for (let i = 0; i < properties.length; i++) {
|
|
1333
|
+
const key = properties[i];
|
|
1334
|
+
const value = object[key];
|
|
1335
|
+
if (value !== void 0) {
|
|
1336
|
+
copy[key] = value;
|
|
1302
1337
|
}
|
|
1303
|
-
return this.round(decimalPlaces).toFixedInternal(decimalPlaces);
|
|
1304
1338
|
}
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
return sign2 + "0." + decPart;
|
|
1339
|
+
return copy;
|
|
1340
|
+
}
|
|
1341
|
+
function isPath(str) {
|
|
1342
|
+
return str.includes(".");
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
// src/types/fraction.ts
|
|
1346
|
+
function isFraction2(value) {
|
|
1347
|
+
return value instanceof Fraction;
|
|
1348
|
+
}
|
|
1349
|
+
function gcd(a, b) {
|
|
1350
|
+
a = a < 0n ? -a : a;
|
|
1351
|
+
b = b < 0n ? -b : b;
|
|
1352
|
+
while (b !== 0n) {
|
|
1353
|
+
const t = b;
|
|
1354
|
+
b = a % b;
|
|
1355
|
+
a = t;
|
|
1356
|
+
}
|
|
1357
|
+
return a;
|
|
1358
|
+
}
|
|
1359
|
+
var Fraction = class _Fraction {
|
|
1360
|
+
type = "Fraction";
|
|
1361
|
+
numerator;
|
|
1362
|
+
denominator;
|
|
1363
|
+
constructor(numerator, denominator = 1n) {
|
|
1364
|
+
const toRatio = (x) => {
|
|
1365
|
+
if (isFraction2(x)) {
|
|
1366
|
+
return [x.numerator, x.denominator];
|
|
1334
1367
|
}
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1368
|
+
if (typeof x === "number" && !Number.isInteger(x)) {
|
|
1369
|
+
const f = _Fraction.fromNumber(x);
|
|
1370
|
+
return [f.numerator, f.denominator];
|
|
1338
1371
|
}
|
|
1339
|
-
return
|
|
1372
|
+
return [typeof x === "bigint" ? x : BigInt(x), 1n];
|
|
1373
|
+
};
|
|
1374
|
+
const [pn, qn] = toRatio(numerator);
|
|
1375
|
+
const [pd, qd] = toRatio(denominator);
|
|
1376
|
+
let num = pn * qd;
|
|
1377
|
+
let den = qn * pd;
|
|
1378
|
+
if (den === 0n) {
|
|
1379
|
+
throw new Error("Fraction denominator cannot be zero");
|
|
1380
|
+
}
|
|
1381
|
+
if (den < 0n) {
|
|
1382
|
+
num = -num;
|
|
1383
|
+
den = -den;
|
|
1340
1384
|
}
|
|
1385
|
+
const g = gcd(num, den);
|
|
1386
|
+
this.numerator = num / g;
|
|
1387
|
+
this.denominator = den / g;
|
|
1341
1388
|
}
|
|
1389
|
+
// ============================================================
|
|
1390
|
+
// Static Factory Methods
|
|
1391
|
+
// ============================================================
|
|
1342
1392
|
/**
|
|
1343
|
-
*
|
|
1393
|
+
* Create a Fraction from a number (with optional precision)
|
|
1344
1394
|
*/
|
|
1345
|
-
|
|
1346
|
-
if (
|
|
1347
|
-
|
|
1348
|
-
if (this._sign === 0) {
|
|
1349
|
-
const dp = decimalPlaces ?? 0;
|
|
1350
|
-
return dp > 0 ? "0." + "0".repeat(dp) + "e+0" : "0e+0";
|
|
1351
|
-
}
|
|
1352
|
-
const sign2 = this._sign === -1 ? "-" : "";
|
|
1353
|
-
const digits2 = this._coefficient.toString();
|
|
1354
|
-
const exp = digits2.length - 1 + this._exponent;
|
|
1355
|
-
const expSign = exp >= 0 ? "+" : "";
|
|
1356
|
-
if (decimalPlaces === void 0) {
|
|
1357
|
-
if (digits2.length === 1) {
|
|
1358
|
-
return `${sign2}${digits2}e${expSign}${exp}`;
|
|
1359
|
-
}
|
|
1360
|
-
return `${sign2}${digits2[0]}.${digits2.slice(1)}e${expSign}${exp}`;
|
|
1361
|
-
}
|
|
1362
|
-
if (decimalPlaces === 0) {
|
|
1363
|
-
return `${sign2}${digits2[0]}e${expSign}${exp}`;
|
|
1395
|
+
static fromNumber(n, maxDenominator = 1000000n) {
|
|
1396
|
+
if (!Number.isFinite(n)) {
|
|
1397
|
+
throw new Error("Cannot create fraction from non-finite number");
|
|
1364
1398
|
}
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
decPart += "0".repeat(decimalPlaces - decPart.length);
|
|
1368
|
-
} else {
|
|
1369
|
-
decPart = decPart.slice(0, decimalPlaces);
|
|
1399
|
+
if (Number.isInteger(n)) {
|
|
1400
|
+
return new _Fraction(BigInt(n), 1n);
|
|
1370
1401
|
}
|
|
1371
|
-
|
|
1402
|
+
const sign2 = n < 0 ? -1n : 1n;
|
|
1403
|
+
n = Math.abs(n);
|
|
1404
|
+
let h1 = 1n, h2 = 0n;
|
|
1405
|
+
let k1 = 0n, k2 = 1n;
|
|
1406
|
+
let b = n;
|
|
1407
|
+
do {
|
|
1408
|
+
const a = BigInt(Math.floor(b));
|
|
1409
|
+
let aux = h1;
|
|
1410
|
+
h1 = a * h1 + h2;
|
|
1411
|
+
h2 = aux;
|
|
1412
|
+
aux = k1;
|
|
1413
|
+
k1 = a * k1 + k2;
|
|
1414
|
+
k2 = aux;
|
|
1415
|
+
b = 1 / (b - Number(a));
|
|
1416
|
+
} while (Math.abs(n - Number(h1) / Number(k1)) > Number.EPSILON && k1 < maxDenominator);
|
|
1417
|
+
return new _Fraction(sign2 * h1, k1);
|
|
1372
1418
|
}
|
|
1373
1419
|
/**
|
|
1374
|
-
*
|
|
1420
|
+
* Create a Fraction from a decimal string
|
|
1375
1421
|
*/
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1422
|
+
static fromDecimalString(str) {
|
|
1423
|
+
str = str.trim();
|
|
1424
|
+
const repeatingMatch = str.match(/^(-?\d*)\.(\d*)\((\d+)\)$/);
|
|
1425
|
+
if (repeatingMatch) {
|
|
1426
|
+
const sign3 = str.startsWith("-") ? -1n : 1n;
|
|
1427
|
+
const intPart2 = repeatingMatch[1] === "-" ? "0" : repeatingMatch[1] || "0";
|
|
1428
|
+
const nonRepeating = repeatingMatch[2] || "";
|
|
1429
|
+
const repeating = repeatingMatch[3];
|
|
1430
|
+
const fullDigits = intPart2 + nonRepeating + repeating;
|
|
1431
|
+
const nonRepDigits = intPart2 + nonRepeating;
|
|
1432
|
+
const fullNum = BigInt(fullDigits.replace("-", ""));
|
|
1433
|
+
const nonRepNum = BigInt(nonRepDigits.replace("-", "") || "0");
|
|
1434
|
+
const nines = BigInt("9".repeat(repeating.length));
|
|
1435
|
+
const zeros2 = BigInt("1" + "0".repeat(nonRepeating.length));
|
|
1436
|
+
const num2 = fullNum - nonRepNum;
|
|
1437
|
+
const den2 = nines * zeros2;
|
|
1438
|
+
return new _Fraction(sign3 * num2, den2);
|
|
1389
1439
|
}
|
|
1390
|
-
|
|
1440
|
+
const [intPart, decPart = ""] = str.split(".");
|
|
1441
|
+
const sign2 = str.startsWith("-") ? -1n : 1n;
|
|
1442
|
+
const absInt = intPart.replace("-", "") || "0";
|
|
1443
|
+
const combined = absInt + decPart;
|
|
1444
|
+
const num = BigInt(combined);
|
|
1445
|
+
const den = BigInt("1" + "0".repeat(decPart.length));
|
|
1446
|
+
return new _Fraction(sign2 * num, den);
|
|
1391
1447
|
}
|
|
1392
1448
|
/**
|
|
1393
|
-
*
|
|
1449
|
+
* Parse a fraction from a string
|
|
1450
|
+
* Supports formats: "3/4", "-3/4", "3", "3.14", "0.(3)"
|
|
1394
1451
|
*/
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1452
|
+
static parse(str) {
|
|
1453
|
+
str = str.trim();
|
|
1454
|
+
if (str.includes("/")) {
|
|
1455
|
+
const [numStr, denStr] = str.split("/");
|
|
1456
|
+
return new _Fraction(BigInt(numStr.trim()), BigInt(denStr.trim()));
|
|
1398
1457
|
}
|
|
1399
|
-
if (
|
|
1400
|
-
|
|
1401
|
-
if (this._exponent >= 0) {
|
|
1402
|
-
return BigInt(this._sign) * BigInt(digits2 + "0".repeat(this._exponent));
|
|
1403
|
-
} else if (-this._exponent < digits2.length) {
|
|
1404
|
-
return BigInt(this._sign) * BigInt(digits2.slice(0, digits2.length + this._exponent));
|
|
1458
|
+
if (str.includes(".") || str.includes("(")) {
|
|
1459
|
+
return _Fraction.fromDecimalString(str);
|
|
1405
1460
|
}
|
|
1406
|
-
return
|
|
1461
|
+
return new _Fraction(BigInt(str), 1n);
|
|
1407
1462
|
}
|
|
1408
1463
|
/**
|
|
1409
|
-
*
|
|
1410
|
-
* Mirrors Decimal.js `toBinary()`. Negatives carry a leading `-`.
|
|
1464
|
+
* Create a Fraction from a JSON object
|
|
1411
1465
|
*/
|
|
1412
|
-
|
|
1413
|
-
|
|
1466
|
+
static fromJSON(json) {
|
|
1467
|
+
if ("n" in json) {
|
|
1468
|
+
return new _Fraction(BigInt(json.n), BigInt(json.d));
|
|
1469
|
+
}
|
|
1470
|
+
return new _Fraction(BigInt(json.numerator), BigInt(json.denominator));
|
|
1414
1471
|
}
|
|
1415
1472
|
/**
|
|
1416
|
-
*
|
|
1417
|
-
*
|
|
1473
|
+
* Compare two fractions
|
|
1474
|
+
* @returns -1, 0, or 1
|
|
1418
1475
|
*/
|
|
1419
|
-
|
|
1420
|
-
|
|
1476
|
+
static compare(a, b) {
|
|
1477
|
+
const diff = a.numerator * b.denominator - b.numerator * a.denominator;
|
|
1478
|
+
if (diff < 0n) return -1;
|
|
1479
|
+
if (diff > 0n) return 1;
|
|
1480
|
+
return 0;
|
|
1421
1481
|
}
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1482
|
+
// ============================================================
|
|
1483
|
+
// Conversion Methods
|
|
1484
|
+
// ============================================================
|
|
1485
|
+
valueOf() {
|
|
1486
|
+
return Number(this.numerator) / Number(this.denominator);
|
|
1487
|
+
}
|
|
1488
|
+
toString() {
|
|
1489
|
+
if (this.denominator === 1n) {
|
|
1490
|
+
return this.numerator.toString();
|
|
1491
|
+
}
|
|
1492
|
+
return `${this.numerator}/${this.denominator}`;
|
|
1493
|
+
}
|
|
1494
|
+
toJSON() {
|
|
1495
|
+
return {
|
|
1496
|
+
mathjs: "Fraction",
|
|
1497
|
+
n: this.numerator.toString(),
|
|
1498
|
+
d: this.denominator.toString()
|
|
1499
|
+
};
|
|
1428
1500
|
}
|
|
1429
1501
|
/**
|
|
1430
|
-
*
|
|
1431
|
-
* Integers and terminating fractions are exact; a non-terminating fraction is
|
|
1432
|
-
* truncated at `maxFractionDigits` radix digits (a safety bound — the common
|
|
1433
|
-
* use is integer formatting).
|
|
1502
|
+
* Convert to number
|
|
1434
1503
|
*/
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
if (this._isInfinite) return (this._sign < 0 ? "-" : "") + "Infinity";
|
|
1438
|
-
if (this._sign === 0) return prefix + "0";
|
|
1439
|
-
const negative = this._sign < 0;
|
|
1440
|
-
const absVal = this.abs();
|
|
1441
|
-
const intPart = absVal.toBigInt();
|
|
1442
|
-
let out = prefix + intPart.toString(radix);
|
|
1443
|
-
let frac = absVal.subtract(_BigNumber.fromBigInt(intPart));
|
|
1444
|
-
if (!frac.isZero()) {
|
|
1445
|
-
const radixBN = _BigNumber.fromNumber(radix);
|
|
1446
|
-
let digits2 = "";
|
|
1447
|
-
for (let i = 0; i < maxFractionDigits && !frac.isZero(); i++) {
|
|
1448
|
-
frac = frac.multiply(radixBN);
|
|
1449
|
-
const digit = frac.toBigInt();
|
|
1450
|
-
digits2 += Number(digit).toString(radix);
|
|
1451
|
-
frac = frac.subtract(_BigNumber.fromBigInt(digit));
|
|
1452
|
-
}
|
|
1453
|
-
out += "." + digits2;
|
|
1454
|
-
}
|
|
1455
|
-
return (negative ? "-" : "") + out;
|
|
1504
|
+
toNumber() {
|
|
1505
|
+
return this.valueOf();
|
|
1456
1506
|
}
|
|
1457
|
-
// ============================================================
|
|
1458
|
-
// Arithmetic Operations
|
|
1459
|
-
// ============================================================
|
|
1460
1507
|
/**
|
|
1461
|
-
*
|
|
1508
|
+
* Convert to decimal string with specified precision
|
|
1462
1509
|
*/
|
|
1463
|
-
|
|
1464
|
-
const
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1510
|
+
toDecimal(precision = 10) {
|
|
1511
|
+
const sign2 = this.numerator < 0n ? "-" : "";
|
|
1512
|
+
let num = this.numerator < 0n ? -this.numerator : this.numerator;
|
|
1513
|
+
const den = this.denominator;
|
|
1514
|
+
const intPart = num / den;
|
|
1515
|
+
num = num % den;
|
|
1516
|
+
if (num === 0n || precision === 0) {
|
|
1517
|
+
return sign2 + intPart.toString();
|
|
1469
1518
|
}
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
if (this._sign === b._sign) {
|
|
1476
|
-
return this.normalize(this._sign, aCoef + bCoef, exp);
|
|
1477
|
-
} else {
|
|
1478
|
-
if (aCoef >= bCoef) {
|
|
1479
|
-
const diff = aCoef - bCoef;
|
|
1480
|
-
return this.normalize(diff === 0n ? 0 : this._sign, diff, exp);
|
|
1481
|
-
} else {
|
|
1482
|
-
return this.normalize(b._sign, bCoef - aCoef, exp);
|
|
1483
|
-
}
|
|
1519
|
+
let decPart = "";
|
|
1520
|
+
for (let i = 0; i < precision && num !== 0n; i++) {
|
|
1521
|
+
num *= 10n;
|
|
1522
|
+
decPart += (num / den).toString();
|
|
1523
|
+
num = num % den;
|
|
1484
1524
|
}
|
|
1525
|
+
return sign2 + intPart.toString() + "." + decPart;
|
|
1485
1526
|
}
|
|
1486
1527
|
/**
|
|
1487
|
-
*
|
|
1528
|
+
* Convert to LaTeX string
|
|
1488
1529
|
*/
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1530
|
+
toLatex() {
|
|
1531
|
+
if (this.denominator === 1n) {
|
|
1532
|
+
return this.numerator.toString();
|
|
1533
|
+
}
|
|
1534
|
+
const sign2 = this.numerator < 0n ? "-" : "";
|
|
1535
|
+
const absNum = this.numerator < 0n ? -this.numerator : this.numerator;
|
|
1536
|
+
return `${sign2}\\frac{${absNum}}{${this.denominator}}`;
|
|
1492
1537
|
}
|
|
1493
1538
|
/**
|
|
1494
|
-
*
|
|
1539
|
+
* Convert to mixed number representation
|
|
1495
1540
|
*/
|
|
1496
|
-
|
|
1497
|
-
|
|
1541
|
+
toMixed() {
|
|
1542
|
+
const sign2 = this.numerator < 0n ? -1n : 1n;
|
|
1543
|
+
const absNum = this.numerator < 0n ? -this.numerator : this.numerator;
|
|
1544
|
+
const whole = sign2 * (absNum / this.denominator);
|
|
1545
|
+
const remainder = absNum % this.denominator;
|
|
1546
|
+
return {
|
|
1547
|
+
whole,
|
|
1548
|
+
numerator: remainder,
|
|
1549
|
+
denominator: this.denominator
|
|
1550
|
+
};
|
|
1498
1551
|
}
|
|
1552
|
+
// ============================================================
|
|
1553
|
+
// Arithmetic Operations (Scalar interface)
|
|
1554
|
+
// ============================================================
|
|
1499
1555
|
/**
|
|
1500
|
-
*
|
|
1556
|
+
* Addition: a/b + c/d = (ad + bc) / bd
|
|
1501
1557
|
*/
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
const sign3 = this._sign * b._sign;
|
|
1508
|
-
return new _BigNumber(sign3, 0n, 0, false, true);
|
|
1558
|
+
add(other) {
|
|
1559
|
+
if (other instanceof _Fraction) {
|
|
1560
|
+
const num = this.numerator * other.denominator + other.numerator * this.denominator;
|
|
1561
|
+
const den = this.denominator * other.denominator;
|
|
1562
|
+
return new _Fraction(num, den);
|
|
1509
1563
|
}
|
|
1510
|
-
|
|
1511
|
-
const sign2 = this._sign * b._sign;
|
|
1512
|
-
const coefficient = this._coefficient * b._coefficient;
|
|
1513
|
-
const exponent = this._exponent + b._exponent;
|
|
1514
|
-
return this.normalize(sign2, coefficient, exponent);
|
|
1564
|
+
return this.add(_Fraction.fromNumber(Number(other.valueOf())));
|
|
1515
1565
|
}
|
|
1516
1566
|
/**
|
|
1517
|
-
*
|
|
1567
|
+
* Subtraction: a/b - c/d = (ad - bc) / bd
|
|
1518
1568
|
*/
|
|
1519
|
-
|
|
1520
|
-
|
|
1569
|
+
subtract(other) {
|
|
1570
|
+
if (other instanceof _Fraction) {
|
|
1571
|
+
const num = this.numerator * other.denominator - other.numerator * this.denominator;
|
|
1572
|
+
const den = this.denominator * other.denominator;
|
|
1573
|
+
return new _Fraction(num, den);
|
|
1574
|
+
}
|
|
1575
|
+
return this.subtract(_Fraction.fromNumber(Number(other.valueOf())));
|
|
1521
1576
|
}
|
|
1522
1577
|
/**
|
|
1523
|
-
*
|
|
1578
|
+
* Multiplication: a/b * c/d = ac / bd
|
|
1524
1579
|
*/
|
|
1525
|
-
|
|
1526
|
-
|
|
1580
|
+
multiply(other) {
|
|
1581
|
+
if (other instanceof _Fraction) {
|
|
1582
|
+
return new _Fraction(this.numerator * other.numerator, this.denominator * other.denominator);
|
|
1583
|
+
}
|
|
1584
|
+
return this.multiply(_Fraction.fromNumber(Number(other.valueOf())));
|
|
1527
1585
|
}
|
|
1528
1586
|
/**
|
|
1529
|
-
* Division
|
|
1587
|
+
* Division: a/b ÷ c/d = ad / bc
|
|
1530
1588
|
*/
|
|
1531
1589
|
divide(other) {
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
return new _BigNumber(this._sign, 0n, 0, false, true);
|
|
1538
|
-
}
|
|
1539
|
-
if (this._isInfinite) {
|
|
1540
|
-
const sign3 = this._sign * b._sign;
|
|
1541
|
-
return new _BigNumber(sign3, 0n, 0, false, true);
|
|
1590
|
+
if (other instanceof _Fraction) {
|
|
1591
|
+
if (other.numerator === 0n) {
|
|
1592
|
+
throw new Error("Division by zero");
|
|
1593
|
+
}
|
|
1594
|
+
return new _Fraction(this.numerator * other.denominator, this.denominator * other.numerator);
|
|
1542
1595
|
}
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1596
|
+
return this.divide(_Fraction.fromNumber(Number(other.valueOf())));
|
|
1597
|
+
}
|
|
1598
|
+
// Short-name aliases (mathjs Fraction API). Ported mathjs functions such as
|
|
1599
|
+
// multiplyScalar/subtractScalar/divideScalar call x.mul/x.sub/x.div; without
|
|
1600
|
+
// these, mixed number/Fraction dispatch (e.g. affine unit conversion like
|
|
1601
|
+
// celsius→fahrenheit) threw "x.mul is not a function".
|
|
1602
|
+
mul(other) {
|
|
1603
|
+
return this.multiply(other);
|
|
1604
|
+
}
|
|
1605
|
+
sub(other) {
|
|
1606
|
+
return this.subtract(other);
|
|
1552
1607
|
}
|
|
1553
|
-
/**
|
|
1554
|
-
* Alias for divide — Decimal.js calling convention (used by the Unit).
|
|
1555
|
-
*/
|
|
1556
1608
|
div(other) {
|
|
1557
1609
|
return this.divide(other);
|
|
1558
1610
|
}
|
|
1559
1611
|
/**
|
|
1560
|
-
* Negation
|
|
1612
|
+
* Negation: -(a/b) = -a/b
|
|
1561
1613
|
*/
|
|
1562
1614
|
negate() {
|
|
1563
|
-
|
|
1564
|
-
if (this._sign === 0) return this;
|
|
1565
|
-
const newSign = this._sign === 1 ? -1 : 1;
|
|
1566
|
-
return new _BigNumber(newSign, this._coefficient, this._exponent, false, this._isInfinite);
|
|
1615
|
+
return new _Fraction(-this.numerator, this.denominator);
|
|
1567
1616
|
}
|
|
1568
1617
|
/**
|
|
1569
|
-
* Absolute value
|
|
1618
|
+
* Absolute value: |a/b|
|
|
1570
1619
|
*/
|
|
1571
1620
|
abs() {
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1621
|
+
return new _Fraction(this.numerator < 0n ? -this.numerator : this.numerator, this.denominator);
|
|
1622
|
+
}
|
|
1623
|
+
/**
|
|
1624
|
+
* Reciprocal: b/a
|
|
1625
|
+
*/
|
|
1626
|
+
inverse() {
|
|
1627
|
+
if (this.numerator === 0n) {
|
|
1628
|
+
throw new Error("Cannot invert zero");
|
|
1629
|
+
}
|
|
1630
|
+
return new _Fraction(this.denominator, this.numerator);
|
|
1575
1631
|
}
|
|
1576
1632
|
/**
|
|
1577
1633
|
* Power (integer exponent)
|
|
1578
1634
|
*/
|
|
1579
1635
|
pow(n) {
|
|
1580
|
-
const exp = typeof n === "bigint" ?
|
|
1581
|
-
if (
|
|
1582
|
-
|
|
1583
|
-
if (this._sign === 0) {
|
|
1584
|
-
if (exp < 0) return new _BigNumber(1, 0n, 0, false, true);
|
|
1585
|
-
return this;
|
|
1636
|
+
const exp = typeof n === "bigint" ? n : BigInt(n);
|
|
1637
|
+
if (exp === 0n) {
|
|
1638
|
+
return new _Fraction(1n, 1n);
|
|
1586
1639
|
}
|
|
1587
|
-
if (exp <
|
|
1588
|
-
return
|
|
1640
|
+
if (exp < 0n) {
|
|
1641
|
+
return this.inverse().pow(-exp);
|
|
1589
1642
|
}
|
|
1590
|
-
let result =
|
|
1643
|
+
let result = new _Fraction(1n, 1n);
|
|
1591
1644
|
let base = this.clone();
|
|
1592
1645
|
let e = exp;
|
|
1593
|
-
while (e >
|
|
1594
|
-
if (e %
|
|
1646
|
+
while (e > 0n) {
|
|
1647
|
+
if (e % 2n === 1n) {
|
|
1595
1648
|
result = result.multiply(base);
|
|
1596
1649
|
}
|
|
1597
1650
|
base = base.multiply(base);
|
|
1598
|
-
e =
|
|
1651
|
+
e = e / 2n;
|
|
1599
1652
|
}
|
|
1600
|
-
return result
|
|
1653
|
+
return result;
|
|
1601
1654
|
}
|
|
1602
1655
|
/**
|
|
1603
|
-
*
|
|
1656
|
+
* Modulo operation
|
|
1604
1657
|
*/
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
if (this._isInfinite) return this;
|
|
1610
|
-
const precision = globalConfig.precision;
|
|
1611
|
-
let guess = _BigNumber.fromNumber(Math.sqrt(this.valueOf()));
|
|
1612
|
-
for (let i = 0; i < 100; i++) {
|
|
1613
|
-
const newGuess = guess.add(this.divide(guess)).divide(_BigNumber.fromNumber(2));
|
|
1614
|
-
if (guess.subtract(newGuess).abs().compareTo(guess.multiply(_BigNumber.parse("1e-" + (precision + 5)))) <= 0) {
|
|
1615
|
-
return newGuess.roundToPrecision(precision);
|
|
1616
|
-
}
|
|
1617
|
-
guess = newGuess;
|
|
1618
|
-
}
|
|
1619
|
-
return guess.roundToPrecision(precision);
|
|
1658
|
+
mod(other) {
|
|
1659
|
+
const quotient = this.divide(other);
|
|
1660
|
+
const floorQuot = quotient.floor();
|
|
1661
|
+
return this.subtract(other.multiply(floorQuot));
|
|
1620
1662
|
}
|
|
1621
1663
|
// ============================================================
|
|
1622
1664
|
// Comparison Methods
|
|
1623
1665
|
// ============================================================
|
|
1666
|
+
/**
|
|
1667
|
+
* Check equality
|
|
1668
|
+
*/
|
|
1624
1669
|
equals(other) {
|
|
1625
|
-
return
|
|
1670
|
+
return this.numerator === other.numerator && this.denominator === other.denominator;
|
|
1626
1671
|
}
|
|
1672
|
+
/**
|
|
1673
|
+
* Check if less than
|
|
1674
|
+
*/
|
|
1627
1675
|
lessThan(other) {
|
|
1628
|
-
return
|
|
1676
|
+
return _Fraction.compare(this, other) < 0;
|
|
1629
1677
|
}
|
|
1678
|
+
/**
|
|
1679
|
+
* Check if less than or equal
|
|
1680
|
+
*/
|
|
1630
1681
|
lessThanOrEqual(other) {
|
|
1631
|
-
return
|
|
1682
|
+
return _Fraction.compare(this, other) <= 0;
|
|
1632
1683
|
}
|
|
1684
|
+
/**
|
|
1685
|
+
* Check if greater than
|
|
1686
|
+
*/
|
|
1633
1687
|
greaterThan(other) {
|
|
1634
|
-
return
|
|
1688
|
+
return _Fraction.compare(this, other) > 0;
|
|
1635
1689
|
}
|
|
1690
|
+
/**
|
|
1691
|
+
* Check if greater than or equal
|
|
1692
|
+
*/
|
|
1636
1693
|
greaterThanOrEqual(other) {
|
|
1637
|
-
return
|
|
1694
|
+
return _Fraction.compare(this, other) >= 0;
|
|
1638
1695
|
}
|
|
1696
|
+
/**
|
|
1697
|
+
* Compare with another fraction
|
|
1698
|
+
* @returns -1, 0, or 1
|
|
1699
|
+
*/
|
|
1639
1700
|
compareTo(other) {
|
|
1640
|
-
return
|
|
1701
|
+
return _Fraction.compare(this, other);
|
|
1641
1702
|
}
|
|
1642
1703
|
compare(other) {
|
|
1643
1704
|
return this.compareTo(other);
|
|
1644
1705
|
}
|
|
1645
|
-
/**
|
|
1646
|
-
* Returns true iff this > other.
|
|
1647
|
-
* Accepts the same argument types as `add`/`multiply` (BigNumber, number, or string).
|
|
1648
|
-
* Named `gt` for Decimal.js / mathjs formatter compatibility.
|
|
1649
|
-
*/
|
|
1650
|
-
gt(other) {
|
|
1651
|
-
return this.greaterThan(this.ensureBigNumber(other));
|
|
1652
|
-
}
|
|
1653
1706
|
// ============================================================
|
|
1654
|
-
//
|
|
1707
|
+
// Utility Methods
|
|
1655
1708
|
// ============================================================
|
|
1656
1709
|
/**
|
|
1657
|
-
*
|
|
1710
|
+
* Return fraction already in lowest terms (no-op since constructor reduces)
|
|
1658
1711
|
*/
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
const targetExp = -decimalPlaces;
|
|
1662
|
-
if (this._exponent >= targetExp) return this;
|
|
1663
|
-
const shift = targetExp - this._exponent;
|
|
1664
|
-
const divisor = BigInt(10) ** BigInt(shift);
|
|
1665
|
-
const quotient = this._coefficient / divisor;
|
|
1666
|
-
const remainder = this._coefficient % divisor;
|
|
1667
|
-
let rounded = quotient;
|
|
1668
|
-
const halfDivisor = divisor / 2n;
|
|
1669
|
-
const shouldRoundUp = this.shouldRound(remainder, halfDivisor, divisor, quotient, mode);
|
|
1670
|
-
if (shouldRoundUp) {
|
|
1671
|
-
rounded += 1n;
|
|
1672
|
-
}
|
|
1673
|
-
return this.normalize(rounded === 0n ? 0 : this._sign, rounded, targetExp);
|
|
1674
|
-
}
|
|
1675
|
-
shouldRound(remainder, halfDivisor, divisor, quotient, mode) {
|
|
1676
|
-
const isPositive = this._sign === 1;
|
|
1677
|
-
const isExactlyHalf = remainder === halfDivisor && divisor % 2n === 0n;
|
|
1678
|
-
const isMoreThanHalf = remainder > halfDivisor;
|
|
1679
|
-
switch (mode) {
|
|
1680
|
-
case "up":
|
|
1681
|
-
return remainder > 0n;
|
|
1682
|
-
case "down":
|
|
1683
|
-
return false;
|
|
1684
|
-
case "ceil":
|
|
1685
|
-
return isPositive && remainder > 0n;
|
|
1686
|
-
case "floor":
|
|
1687
|
-
return !isPositive && remainder > 0n;
|
|
1688
|
-
case "halfUp":
|
|
1689
|
-
return isMoreThanHalf || isExactlyHalf;
|
|
1690
|
-
case "halfDown":
|
|
1691
|
-
return isMoreThanHalf;
|
|
1692
|
-
case "halfEven":
|
|
1693
|
-
return isMoreThanHalf || isExactlyHalf && quotient % 2n !== 0n;
|
|
1694
|
-
case "halfCeil":
|
|
1695
|
-
return isMoreThanHalf || isExactlyHalf && isPositive;
|
|
1696
|
-
case "halfFloor":
|
|
1697
|
-
return isMoreThanHalf || isExactlyHalf && !isPositive;
|
|
1698
|
-
default:
|
|
1699
|
-
return isMoreThanHalf || isExactlyHalf;
|
|
1700
|
-
}
|
|
1712
|
+
simplify() {
|
|
1713
|
+
return this;
|
|
1701
1714
|
}
|
|
1702
1715
|
/**
|
|
1703
|
-
*
|
|
1716
|
+
* Check if this is zero
|
|
1704
1717
|
*/
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
const digits2 = this._coefficient.toString();
|
|
1708
|
-
if (digits2.length <= precision) return this;
|
|
1709
|
-
const digitsToRemove = digits2.length - precision;
|
|
1710
|
-
const divisor = BigInt(10) ** BigInt(digitsToRemove);
|
|
1711
|
-
const quotient = this._coefficient / divisor;
|
|
1712
|
-
const remainder = this._coefficient % divisor;
|
|
1713
|
-
const halfDivisor = divisor / 2n;
|
|
1714
|
-
let rounded = quotient;
|
|
1715
|
-
const shouldRoundUp = this.shouldRound(remainder, halfDivisor, divisor, quotient, mode);
|
|
1716
|
-
if (shouldRoundUp) {
|
|
1717
|
-
rounded += 1n;
|
|
1718
|
-
}
|
|
1719
|
-
const newExponent = this._exponent + digitsToRemove;
|
|
1720
|
-
return this.normalize(rounded === 0n ? 0 : this._sign, rounded, newExponent);
|
|
1721
|
-
}
|
|
1722
|
-
floor() {
|
|
1723
|
-
return this.round(0, "floor");
|
|
1724
|
-
}
|
|
1725
|
-
ceil() {
|
|
1726
|
-
return this.round(0, "ceil");
|
|
1718
|
+
isZero() {
|
|
1719
|
+
return this.numerator === 0n;
|
|
1727
1720
|
}
|
|
1728
|
-
|
|
1729
|
-
|
|
1721
|
+
/**
|
|
1722
|
+
* Check if this is positive
|
|
1723
|
+
*/
|
|
1724
|
+
isPositive() {
|
|
1725
|
+
return this.numerator > 0n;
|
|
1730
1726
|
}
|
|
1731
1727
|
/**
|
|
1732
|
-
*
|
|
1733
|
-
* Delegates to `roundToPrecision`, using the global rounding mode unless
|
|
1734
|
-
* an explicit `roundingMode` is supplied.
|
|
1735
|
-
*
|
|
1736
|
-
* Named `toSignificantDigits` for Decimal.js / mathjs formatter compatibility.
|
|
1737
|
-
* When `n` is undefined the value is returned unchanged (no rounding).
|
|
1728
|
+
* Check if this is negative
|
|
1738
1729
|
*/
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
return this.roundToPrecision(n, roundingMode ?? globalConfig.rounding);
|
|
1730
|
+
isNegative() {
|
|
1731
|
+
return this.numerator < 0n;
|
|
1742
1732
|
}
|
|
1743
1733
|
/**
|
|
1744
|
-
*
|
|
1745
|
-
*
|
|
1746
|
-
* Matches Decimal.js semantics:
|
|
1747
|
-
* - `12345` → `4` (5 digits → the most-significant place is 10^4)
|
|
1748
|
-
* - `0.0123` → `-2` (first significant digit is at 10^-2)
|
|
1749
|
-
* - `100` → `2`
|
|
1750
|
-
* - `0.01` → `-2`
|
|
1751
|
-
* - `0` → `0` (by convention; `isZero()` can be used to distinguish)
|
|
1752
|
-
*
|
|
1753
|
-
* For special values (NaN, ±Infinity) returns 0 — callers check
|
|
1754
|
-
* `isFinite()` / `isNaN()` before using `.e`.
|
|
1734
|
+
* Check if this is an integer
|
|
1755
1735
|
*/
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
const d = this._coefficient.toString().length;
|
|
1759
|
-
return d - 1 + this._exponent;
|
|
1736
|
+
isInteger() {
|
|
1737
|
+
return this.denominator === 1n;
|
|
1760
1738
|
}
|
|
1761
|
-
// ============================================================
|
|
1762
|
-
// Modular Arithmetic
|
|
1763
|
-
// ============================================================
|
|
1764
1739
|
/**
|
|
1765
|
-
*
|
|
1766
|
-
* Result has the same sign as the dividend (this).
|
|
1740
|
+
* Check if this is a unit fraction (1/n)
|
|
1767
1741
|
*/
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
if (this._isNaN || b._isNaN || b._sign === 0) return new _BigNumber(0, 0n, 0, true);
|
|
1771
|
-
if (this._isInfinite) return new _BigNumber(0, 0n, 0, true);
|
|
1772
|
-
if (b._isInfinite) return this;
|
|
1773
|
-
if (this._sign === 0) return this;
|
|
1774
|
-
const quotient = this.divide(b).trunc();
|
|
1775
|
-
return this.subtract(b.multiply(quotient));
|
|
1742
|
+
isUnit() {
|
|
1743
|
+
return this.numerator === 1n || this.numerator === -1n;
|
|
1776
1744
|
}
|
|
1777
|
-
// ============================================================
|
|
1778
|
-
// Trigonometric Functions
|
|
1779
|
-
// ============================================================
|
|
1780
1745
|
/**
|
|
1781
|
-
*
|
|
1782
|
-
* Uses Taylor series: sin(x) = x - x^3/3! + x^5/5! - ...
|
|
1746
|
+
* Floor: largest integer ≤ this
|
|
1783
1747
|
*/
|
|
1784
|
-
|
|
1785
|
-
if (this.
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
const
|
|
1789
|
-
|
|
1748
|
+
floor() {
|
|
1749
|
+
if (this.denominator === 1n) {
|
|
1750
|
+
return this;
|
|
1751
|
+
}
|
|
1752
|
+
const quot = this.numerator / this.denominator;
|
|
1753
|
+
if (this.numerator >= 0n || this.numerator % this.denominator === 0n) {
|
|
1754
|
+
return new _Fraction(quot, 1n);
|
|
1755
|
+
}
|
|
1756
|
+
return new _Fraction(quot - 1n, 1n);
|
|
1790
1757
|
}
|
|
1791
1758
|
/**
|
|
1792
|
-
*
|
|
1793
|
-
* Uses Taylor series: cos(x) = 1 - x^2/2! + x^4/4! - ...
|
|
1759
|
+
* Ceiling: smallest integer ≥ this
|
|
1794
1760
|
*/
|
|
1795
|
-
|
|
1796
|
-
if (this.
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
const
|
|
1800
|
-
|
|
1761
|
+
ceil() {
|
|
1762
|
+
if (this.denominator === 1n) {
|
|
1763
|
+
return this;
|
|
1764
|
+
}
|
|
1765
|
+
const quot = this.numerator / this.denominator;
|
|
1766
|
+
if (this.numerator <= 0n || this.numerator % this.denominator === 0n) {
|
|
1767
|
+
return new _Fraction(quot, 1n);
|
|
1768
|
+
}
|
|
1769
|
+
return new _Fraction(quot + 1n, 1n);
|
|
1801
1770
|
}
|
|
1802
1771
|
/**
|
|
1803
|
-
*
|
|
1804
|
-
* tan(x) = sin(x) / cos(x)
|
|
1772
|
+
* Round to nearest integer
|
|
1805
1773
|
*/
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1774
|
+
round() {
|
|
1775
|
+
const floor = this.floor();
|
|
1776
|
+
const diff = this.subtract(floor);
|
|
1777
|
+
const half = new _Fraction(1n, 2n);
|
|
1778
|
+
if (diff.greaterThanOrEqual(half)) {
|
|
1779
|
+
return floor.add(new _Fraction(1n, 1n));
|
|
1780
|
+
}
|
|
1781
|
+
return floor;
|
|
1812
1782
|
}
|
|
1813
1783
|
/**
|
|
1814
|
-
*
|
|
1815
|
-
* Returns value in [-PI/2, PI/2]
|
|
1784
|
+
* Truncate (round toward zero)
|
|
1816
1785
|
*/
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
const one = _BigNumber.fromNumber(1);
|
|
1820
|
-
if (this.abs().compareTo(one) > 0) return new _BigNumber(0, 0n, 0, true);
|
|
1821
|
-
if (this._sign === 0) return this;
|
|
1822
|
-
const xSquared = this.multiply(this);
|
|
1823
|
-
const denominator = one.subtract(xSquared).sqrt();
|
|
1824
|
-
if (denominator.isZero()) {
|
|
1825
|
-
return this._sign === 1 ? BIGNUMBER_PI.divide(2) : BIGNUMBER_PI.divide(-2);
|
|
1826
|
-
}
|
|
1827
|
-
return this.divide(denominator).atan();
|
|
1828
|
-
}
|
|
1829
|
-
/**
|
|
1830
|
-
* Arccosine of this BigNumber
|
|
1831
|
-
* Returns value in [0, PI]
|
|
1832
|
-
*/
|
|
1833
|
-
acos() {
|
|
1834
|
-
if (this._isNaN) return this;
|
|
1835
|
-
const one = _BigNumber.fromNumber(1);
|
|
1836
|
-
if (this.abs().compareTo(one) > 0) return new _BigNumber(0, 0n, 0, true);
|
|
1837
|
-
return BIGNUMBER_PI.divide(2).subtract(this.asin());
|
|
1838
|
-
}
|
|
1839
|
-
/**
|
|
1840
|
-
* Arctangent of this BigNumber
|
|
1841
|
-
* Returns value in (-PI/2, PI/2)
|
|
1842
|
-
* Uses Taylor series with argument reduction for convergence.
|
|
1843
|
-
*/
|
|
1844
|
-
atan() {
|
|
1845
|
-
if (this._isNaN) return this;
|
|
1846
|
-
if (this._sign === 0) return this;
|
|
1847
|
-
if (this._isInfinite) {
|
|
1848
|
-
return this._sign === 1 ? BIGNUMBER_PI.divide(2) : BIGNUMBER_PI.divide(-2);
|
|
1849
|
-
}
|
|
1850
|
-
const one = _BigNumber.fromNumber(1);
|
|
1851
|
-
if (this.abs().compareTo(one) > 0) {
|
|
1852
|
-
const reciprocal = one.divide(this);
|
|
1853
|
-
const piHalf = BIGNUMBER_PI.divide(2);
|
|
1854
|
-
return this._sign === 1 ? piHalf.subtract(reciprocal.atan()) : piHalf.negate().subtract(reciprocal.atan());
|
|
1855
|
-
}
|
|
1856
|
-
const half = _BigNumber.fromNumber(0.5);
|
|
1857
|
-
if (this.abs().compareTo(half) > 0) {
|
|
1858
|
-
const xSq = this.multiply(this);
|
|
1859
|
-
const reduced = this.divide(one.add(one.add(xSq).sqrt()));
|
|
1860
|
-
return reduced.atan().multiply(_BigNumber.fromNumber(2));
|
|
1861
|
-
}
|
|
1862
|
-
return this._atanTaylor();
|
|
1786
|
+
trunc() {
|
|
1787
|
+
return new _Fraction(this.numerator / this.denominator, 1n);
|
|
1863
1788
|
}
|
|
1864
1789
|
/**
|
|
1865
|
-
*
|
|
1866
|
-
* this = y, argument = x
|
|
1867
|
-
* Returns angle in (-PI, PI]
|
|
1790
|
+
* Get the sign: -1, 0, or 1
|
|
1868
1791
|
*/
|
|
1869
|
-
|
|
1870
|
-
if (this.
|
|
1871
|
-
if (this.
|
|
1872
|
-
|
|
1873
|
-
return this._sign === 1 ? BIGNUMBER_PI.divide(2) : BIGNUMBER_PI.divide(-2);
|
|
1874
|
-
}
|
|
1875
|
-
const angle = this.divide(x).atan();
|
|
1876
|
-
if (x.isPositive()) {
|
|
1877
|
-
return angle;
|
|
1878
|
-
} else if (this.isNegative()) {
|
|
1879
|
-
return angle.subtract(BIGNUMBER_PI);
|
|
1880
|
-
} else {
|
|
1881
|
-
return angle.add(BIGNUMBER_PI);
|
|
1882
|
-
}
|
|
1792
|
+
sign() {
|
|
1793
|
+
if (this.numerator < 0n) return -1;
|
|
1794
|
+
if (this.numerator > 0n) return 1;
|
|
1795
|
+
return 0;
|
|
1883
1796
|
}
|
|
1884
|
-
// ============================================================
|
|
1885
|
-
// Hyperbolic Functions
|
|
1886
|
-
// ============================================================
|
|
1887
1797
|
/**
|
|
1888
|
-
*
|
|
1798
|
+
* Clone this fraction
|
|
1889
1799
|
*/
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
if (this._isInfinite) return this;
|
|
1893
|
-
if (this._sign === 0) return this;
|
|
1894
|
-
const ex = this.exp();
|
|
1895
|
-
const enx = this.negate().exp();
|
|
1896
|
-
return ex.subtract(enx).divide(_BigNumber.fromNumber(2));
|
|
1800
|
+
clone() {
|
|
1801
|
+
return new _Fraction(this.numerator, this.denominator);
|
|
1897
1802
|
}
|
|
1898
1803
|
/**
|
|
1899
|
-
*
|
|
1804
|
+
* Get the GCD of numerator and denominator (always 1 since we reduce)
|
|
1900
1805
|
*/
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
if (this._isInfinite) return new _BigNumber(1, 0n, 0, false, true);
|
|
1904
|
-
if (this._sign === 0) return _BigNumber.fromNumber(1);
|
|
1905
|
-
const ex = this.exp();
|
|
1906
|
-
const enx = this.negate().exp();
|
|
1907
|
-
return ex.add(enx).divide(_BigNumber.fromNumber(2));
|
|
1806
|
+
gcd() {
|
|
1807
|
+
return 1n;
|
|
1908
1808
|
}
|
|
1909
1809
|
/**
|
|
1910
|
-
*
|
|
1810
|
+
* Get continued fraction representation
|
|
1911
1811
|
*/
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1812
|
+
toContinuedFraction() {
|
|
1813
|
+
const result = [];
|
|
1814
|
+
let num = this.numerator < 0n ? -this.numerator : this.numerator;
|
|
1815
|
+
let den = this.denominator;
|
|
1816
|
+
while (den !== 0n) {
|
|
1817
|
+
result.push(num / den);
|
|
1818
|
+
const temp = num % den;
|
|
1819
|
+
num = den;
|
|
1820
|
+
den = temp;
|
|
1821
|
+
}
|
|
1822
|
+
if (this.numerator < 0n && result.length > 0) {
|
|
1823
|
+
result[0] = -result[0];
|
|
1824
|
+
}
|
|
1825
|
+
return result;
|
|
1919
1826
|
}
|
|
1920
1827
|
/**
|
|
1921
|
-
*
|
|
1828
|
+
* Create fraction from continued fraction
|
|
1922
1829
|
*/
|
|
1923
|
-
|
|
1924
|
-
if (
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1830
|
+
static fromContinuedFraction(cf) {
|
|
1831
|
+
if (cf.length === 0) {
|
|
1832
|
+
return new _Fraction(0n, 1n);
|
|
1833
|
+
}
|
|
1834
|
+
let num = cf[cf.length - 1];
|
|
1835
|
+
let den = 1n;
|
|
1836
|
+
for (let i = cf.length - 2; i >= 0; i--) {
|
|
1837
|
+
const temp = num;
|
|
1838
|
+
num = cf[i] * num + den;
|
|
1839
|
+
den = temp;
|
|
1840
|
+
}
|
|
1841
|
+
return new _Fraction(num, den);
|
|
1929
1842
|
}
|
|
1930
1843
|
/**
|
|
1931
|
-
*
|
|
1932
|
-
*
|
|
1844
|
+
* Mediant of two fractions: (a+c)/(b+d)
|
|
1845
|
+
* Used in Stern-Brocot tree and Farey sequences
|
|
1933
1846
|
*/
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
const one = _BigNumber.fromNumber(1);
|
|
1937
|
-
if (this.compareTo(one) < 0) return new _BigNumber(0, 0n, 0, true);
|
|
1938
|
-
if (this._isInfinite) return this;
|
|
1939
|
-
return this.add(this.multiply(this).subtract(one).sqrt()).ln();
|
|
1847
|
+
mediant(other) {
|
|
1848
|
+
return new _Fraction(this.numerator + other.numerator, this.denominator + other.denominator);
|
|
1940
1849
|
}
|
|
1850
|
+
};
|
|
1851
|
+
var FRACTION_ZERO = new Fraction(0n, 1n);
|
|
1852
|
+
var FRACTION_ONE = new Fraction(1n, 1n);
|
|
1853
|
+
var FRACTION_NEG_ONE = new Fraction(-1n, 1n);
|
|
1854
|
+
var FRACTION_HALF = new Fraction(1n, 2n);
|
|
1855
|
+
var FRACTION_THIRD = new Fraction(1n, 3n);
|
|
1856
|
+
var FRACTION_QUARTER = new Fraction(1n, 4n);
|
|
1857
|
+
|
|
1858
|
+
// src/types/bignumber.ts
|
|
1859
|
+
function isBigNumber2(value) {
|
|
1860
|
+
return value instanceof BigNumber;
|
|
1861
|
+
}
|
|
1862
|
+
var defaultConfig = {
|
|
1863
|
+
precision: 64,
|
|
1864
|
+
rounding: "halfUp",
|
|
1865
|
+
minExponent: -1e9,
|
|
1866
|
+
maxExponent: 1e9
|
|
1867
|
+
};
|
|
1868
|
+
var globalConfig = { ...defaultConfig };
|
|
1869
|
+
var BigNumber = class _BigNumber {
|
|
1870
|
+
type = "BigNumber";
|
|
1941
1871
|
/**
|
|
1942
|
-
*
|
|
1943
|
-
*
|
|
1872
|
+
* Duck-typing marker for Decimal.js / mathjs formatter compatibility.
|
|
1873
|
+
* Allows external code that checks `obj.isBigNumber === true` to identify
|
|
1874
|
+
* this class without an `instanceof` check.
|
|
1944
1875
|
*/
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1876
|
+
isBigNumber = true;
|
|
1877
|
+
// Internal representation: sign * coefficient * 10^exponent
|
|
1878
|
+
_sign;
|
|
1879
|
+
_coefficient;
|
|
1880
|
+
// Absolute value, normalized
|
|
1881
|
+
_exponent;
|
|
1882
|
+
// Power of 10
|
|
1883
|
+
// Special values
|
|
1884
|
+
_isNaN = false;
|
|
1885
|
+
_isInfinite = false;
|
|
1886
|
+
constructor(sign2, coefficient, exponent, isNaN2 = false, isInfinite = false) {
|
|
1887
|
+
this._sign = sign2;
|
|
1888
|
+
this._coefficient = coefficient;
|
|
1889
|
+
this._exponent = exponent;
|
|
1890
|
+
this._isNaN = isNaN2;
|
|
1891
|
+
this._isInfinite = isInfinite;
|
|
1956
1892
|
}
|
|
1957
1893
|
// ============================================================
|
|
1958
|
-
//
|
|
1894
|
+
// Static Factory Methods
|
|
1959
1895
|
// ============================================================
|
|
1960
1896
|
/**
|
|
1961
|
-
*
|
|
1962
|
-
* Uses Taylor series: e^x = 1 + x + x^2/2! + x^3/3! + ...
|
|
1963
|
-
* With argument reduction: e^x = (e^(x/2^k))^(2^k) for faster convergence.
|
|
1897
|
+
* Create a BigNumber from a number
|
|
1964
1898
|
*/
|
|
1965
|
-
|
|
1966
|
-
if (
|
|
1967
|
-
|
|
1968
|
-
if (this._isInfinite) {
|
|
1969
|
-
return this._sign === 1 ? this : _BigNumber.fromNumber(0);
|
|
1970
|
-
}
|
|
1971
|
-
const precision = globalConfig.precision;
|
|
1972
|
-
const val = Math.abs(this.valueOf());
|
|
1973
|
-
let k = 0;
|
|
1974
|
-
if (val > 0.5) {
|
|
1975
|
-
k = Math.ceil(Math.log2(val * 2));
|
|
1899
|
+
static fromNumber(n) {
|
|
1900
|
+
if (Number.isNaN(n)) {
|
|
1901
|
+
return new _BigNumber(0, 0n, 0, true, false);
|
|
1976
1902
|
}
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
let sum = _BigNumber.fromNumber(1);
|
|
1980
|
-
let term = _BigNumber.fromNumber(1);
|
|
1981
|
-
const maxIter = precision + 20;
|
|
1982
|
-
for (let n = 1; n <= maxIter; n++) {
|
|
1983
|
-
term = term.multiply(reduced).divide(_BigNumber.fromNumber(n));
|
|
1984
|
-
const newSum = sum.add(term);
|
|
1985
|
-
if (sum.equals(newSum)) break;
|
|
1986
|
-
sum = newSum;
|
|
1903
|
+
if (!Number.isFinite(n)) {
|
|
1904
|
+
return new _BigNumber(n > 0 ? 1 : -1, 0n, 0, false, true);
|
|
1987
1905
|
}
|
|
1988
|
-
|
|
1989
|
-
|
|
1906
|
+
if (n === 0) {
|
|
1907
|
+
return new _BigNumber(0, 0n, 0);
|
|
1990
1908
|
}
|
|
1991
|
-
return
|
|
1909
|
+
return _BigNumber.parse(n.toString());
|
|
1992
1910
|
}
|
|
1993
1911
|
/**
|
|
1994
|
-
*
|
|
1995
|
-
* Uses the AGM (arithmetic-geometric mean) method for fast convergence.
|
|
1996
|
-
* Fallback: series ln((1+y)/(1-y)) = 2*(y + y^3/3 + y^5/5 + ...) where y = (x-1)/(x+1)
|
|
1912
|
+
* Create a BigNumber from a string
|
|
1997
1913
|
*/
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
if (
|
|
2001
|
-
|
|
2002
|
-
if (this._isInfinite) return this;
|
|
2003
|
-
const one = _BigNumber.fromNumber(1);
|
|
2004
|
-
if (this.equals(one)) return _BigNumber.fromNumber(0);
|
|
2005
|
-
const precision = globalConfig.precision;
|
|
2006
|
-
let x = this.clone();
|
|
2007
|
-
let k = 0;
|
|
2008
|
-
const two = _BigNumber.fromNumber(2);
|
|
2009
|
-
const half = _BigNumber.fromNumber(0.5);
|
|
2010
|
-
while (x.compareTo(two) > 0) {
|
|
2011
|
-
x = x.divide(two);
|
|
2012
|
-
k++;
|
|
1914
|
+
static parse(str) {
|
|
1915
|
+
str = str.trim().toLowerCase();
|
|
1916
|
+
if (str === "nan") {
|
|
1917
|
+
return new _BigNumber(0, 0n, 0, true, false);
|
|
2013
1918
|
}
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
k--;
|
|
1919
|
+
if (str === "infinity" || str === "+infinity") {
|
|
1920
|
+
return new _BigNumber(1, 0n, 0, false, true);
|
|
2017
1921
|
}
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
let term = y;
|
|
2021
|
-
let sum = y;
|
|
2022
|
-
const maxIter = precision + 20;
|
|
2023
|
-
for (let n = 1; n <= maxIter; n++) {
|
|
2024
|
-
term = term.multiply(ySq);
|
|
2025
|
-
const contribution = term.divide(_BigNumber.fromNumber(2 * n + 1));
|
|
2026
|
-
const newSum = sum.add(contribution);
|
|
2027
|
-
if (sum.equals(newSum)) break;
|
|
2028
|
-
sum = newSum;
|
|
1922
|
+
if (str === "-infinity") {
|
|
1923
|
+
return new _BigNumber(-1, 0n, 0, false, true);
|
|
2029
1924
|
}
|
|
2030
|
-
|
|
2031
|
-
if (
|
|
2032
|
-
|
|
1925
|
+
let sign2 = 1;
|
|
1926
|
+
if (str.startsWith("-")) {
|
|
1927
|
+
sign2 = -1;
|
|
1928
|
+
str = str.slice(1);
|
|
1929
|
+
} else if (str.startsWith("+")) {
|
|
1930
|
+
str = str.slice(1);
|
|
2033
1931
|
}
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
log10() {
|
|
2040
|
-
return this.ln().divide(BIGNUMBER_LN10);
|
|
2041
|
-
}
|
|
2042
|
-
/**
|
|
2043
|
-
* Base-2 logarithm: log2(x) = ln(x) / ln(2)
|
|
2044
|
-
*/
|
|
2045
|
-
log2() {
|
|
2046
|
-
return this.ln().divide(BIGNUMBER_LN2);
|
|
2047
|
-
}
|
|
2048
|
-
/**
|
|
2049
|
-
* Cube root
|
|
2050
|
-
* Uses Newton-Raphson iteration.
|
|
2051
|
-
*/
|
|
2052
|
-
cbrt() {
|
|
2053
|
-
if (this._isNaN) return this;
|
|
2054
|
-
if (this._sign === 0) return this;
|
|
2055
|
-
if (this._isInfinite) return this;
|
|
2056
|
-
if (this._sign === -1) {
|
|
2057
|
-
return this.negate().cbrt().negate();
|
|
1932
|
+
let exponentPart = 0;
|
|
1933
|
+
const eIndex = str.indexOf("e");
|
|
1934
|
+
if (eIndex !== -1) {
|
|
1935
|
+
exponentPart = parseInt(str.slice(eIndex + 1), 10);
|
|
1936
|
+
str = str.slice(0, eIndex);
|
|
2058
1937
|
}
|
|
2059
|
-
const
|
|
2060
|
-
|
|
2061
|
-
let
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
1938
|
+
const dotIndex = str.indexOf(".");
|
|
1939
|
+
let coefficient;
|
|
1940
|
+
let decimalPlaces = 0;
|
|
1941
|
+
if (dotIndex !== -1) {
|
|
1942
|
+
coefficient = str.slice(0, dotIndex) + str.slice(dotIndex + 1);
|
|
1943
|
+
decimalPlaces = str.length - dotIndex - 1;
|
|
1944
|
+
} else {
|
|
1945
|
+
coefficient = str;
|
|
1946
|
+
}
|
|
1947
|
+
coefficient = coefficient.replace(/^0+/, "") || "0";
|
|
1948
|
+
if (coefficient === "0") {
|
|
1949
|
+
return new _BigNumber(0, 0n, 0);
|
|
1950
|
+
}
|
|
1951
|
+
let trailingZeros = 0;
|
|
1952
|
+
for (let i = coefficient.length - 1; i >= 0; i--) {
|
|
1953
|
+
if (coefficient[i] === "0") {
|
|
1954
|
+
trailingZeros++;
|
|
1955
|
+
} else {
|
|
1956
|
+
break;
|
|
2067
1957
|
}
|
|
2068
|
-
guess = newGuess;
|
|
2069
1958
|
}
|
|
2070
|
-
|
|
1959
|
+
if (trailingZeros > 0) {
|
|
1960
|
+
coefficient = coefficient.slice(0, -trailingZeros);
|
|
1961
|
+
}
|
|
1962
|
+
const finalExponent = exponentPart - decimalPlaces + trailingZeros;
|
|
1963
|
+
return new _BigNumber(sign2, BigInt(coefficient), finalExponent);
|
|
2071
1964
|
}
|
|
2072
1965
|
/**
|
|
2073
|
-
*
|
|
2074
|
-
* Uses Taylor series directly: expm1(x) = x + x^2/2! + x^3/3! + ...
|
|
1966
|
+
* Create from bigint
|
|
2075
1967
|
*/
|
|
2076
|
-
|
|
2077
|
-
if (
|
|
2078
|
-
|
|
2079
|
-
if (this._isInfinite) {
|
|
2080
|
-
return this._sign === 1 ? this : _BigNumber.fromNumber(-1);
|
|
1968
|
+
static fromBigInt(n) {
|
|
1969
|
+
if (n === 0n) {
|
|
1970
|
+
return new _BigNumber(0, 0n, 0);
|
|
2081
1971
|
}
|
|
2082
|
-
|
|
2083
|
-
|
|
1972
|
+
const sign2 = n < 0n ? -1 : 1;
|
|
1973
|
+
let str = (n < 0n ? -n : n).toString();
|
|
1974
|
+
let trailingZeros = 0;
|
|
1975
|
+
for (let i = str.length - 1; i >= 0; i--) {
|
|
1976
|
+
if (str[i] === "0") {
|
|
1977
|
+
trailingZeros++;
|
|
1978
|
+
} else {
|
|
1979
|
+
break;
|
|
1980
|
+
}
|
|
2084
1981
|
}
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
let sum = this.clone();
|
|
2088
|
-
const maxIter = precision + 20;
|
|
2089
|
-
for (let n = 2; n <= maxIter; n++) {
|
|
2090
|
-
term = term.multiply(this).divide(_BigNumber.fromNumber(n));
|
|
2091
|
-
const newSum = sum.add(term);
|
|
2092
|
-
if (sum.equals(newSum)) break;
|
|
2093
|
-
sum = newSum;
|
|
1982
|
+
if (trailingZeros > 0) {
|
|
1983
|
+
str = str.slice(0, -trailingZeros);
|
|
2094
1984
|
}
|
|
2095
|
-
return
|
|
1985
|
+
return new _BigNumber(sign2, BigInt(str), trailingZeros);
|
|
2096
1986
|
}
|
|
2097
1987
|
/**
|
|
2098
|
-
*
|
|
1988
|
+
* Create a BigNumber from a JSON object
|
|
2099
1989
|
*/
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
const one = _BigNumber.fromNumber(1);
|
|
2103
|
-
const negOne = _BigNumber.fromNumber(-1);
|
|
2104
|
-
if (this.compareTo(negOne) < 0) return new _BigNumber(0, 0n, 0, true);
|
|
2105
|
-
if (this.equals(negOne)) return new _BigNumber(-1, 0n, 0, false, true);
|
|
2106
|
-
if (this._sign === 0) return this;
|
|
2107
|
-
return one.add(this).ln();
|
|
1990
|
+
static fromJSON(json) {
|
|
1991
|
+
return _BigNumber.parse(json.value);
|
|
2108
1992
|
}
|
|
2109
1993
|
/**
|
|
2110
|
-
*
|
|
1994
|
+
* Get/set global configuration
|
|
2111
1995
|
*/
|
|
2112
|
-
|
|
2113
|
-
if (
|
|
2114
|
-
|
|
2115
|
-
return this.multiply(this).add(other.multiply(other)).sqrt();
|
|
2116
|
-
}
|
|
2117
|
-
// ============================================================
|
|
2118
|
-
// Private Taylor Series Helpers
|
|
2119
|
-
// ============================================================
|
|
2120
|
-
/** Reduce angle to [-PI, PI] range */
|
|
2121
|
-
_reduceAngle() {
|
|
2122
|
-
const twoPi = BIGNUMBER_PI.multiply(_BigNumber.fromNumber(2));
|
|
2123
|
-
if (this.abs().compareTo(BIGNUMBER_PI) <= 0) {
|
|
2124
|
-
return this;
|
|
2125
|
-
}
|
|
2126
|
-
const quotient = this.divide(twoPi).round(0, "halfUp");
|
|
2127
|
-
let reduced = this.subtract(twoPi.multiply(quotient));
|
|
2128
|
-
if (reduced.compareTo(BIGNUMBER_PI) > 0) {
|
|
2129
|
-
reduced = reduced.subtract(twoPi);
|
|
2130
|
-
} else if (reduced.compareTo(BIGNUMBER_PI.negate()) < 0) {
|
|
2131
|
-
reduced = reduced.add(twoPi);
|
|
1996
|
+
static config(newConfig) {
|
|
1997
|
+
if (newConfig) {
|
|
1998
|
+
globalConfig = { ...globalConfig, ...newConfig };
|
|
2132
1999
|
}
|
|
2133
|
-
return
|
|
2000
|
+
return { ...globalConfig };
|
|
2134
2001
|
}
|
|
2135
|
-
/**
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
const xSquared = this.multiply(this);
|
|
2141
|
-
const maxIter = precision + 20;
|
|
2142
|
-
for (let n = 1; n <= maxIter; n++) {
|
|
2143
|
-
term = term.multiply(xSquared).divide(_BigNumber.fromNumber(2 * n * (2 * n + 1))).negate();
|
|
2144
|
-
const newSum = sum.add(term);
|
|
2145
|
-
if (sum.equals(newSum)) break;
|
|
2146
|
-
sum = newSum;
|
|
2147
|
-
}
|
|
2148
|
-
return sum.roundToPrecision(precision);
|
|
2002
|
+
/**
|
|
2003
|
+
* Reset configuration to defaults
|
|
2004
|
+
*/
|
|
2005
|
+
static resetConfig() {
|
|
2006
|
+
globalConfig = { ...defaultConfig };
|
|
2149
2007
|
}
|
|
2150
|
-
/**
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
const newSum = sum.add(term);
|
|
2160
|
-
if (sum.equals(newSum)) break;
|
|
2161
|
-
sum = newSum;
|
|
2008
|
+
/**
|
|
2009
|
+
* Compare two BigNumbers
|
|
2010
|
+
* @returns -1, 0, or 1
|
|
2011
|
+
*/
|
|
2012
|
+
static compare(a, b) {
|
|
2013
|
+
if (a._isNaN || b._isNaN) return NaN;
|
|
2014
|
+
if (a._isInfinite && b._isInfinite) {
|
|
2015
|
+
if (a._sign === b._sign) return 0;
|
|
2016
|
+
return a._sign > b._sign ? 1 : -1;
|
|
2162
2017
|
}
|
|
2163
|
-
return
|
|
2018
|
+
if (a._isInfinite) return a._sign;
|
|
2019
|
+
if (b._isInfinite) return -b._sign;
|
|
2020
|
+
if (a._sign === 0 && b._sign === 0) return 0;
|
|
2021
|
+
if (a._sign === 0) return -b._sign;
|
|
2022
|
+
if (b._sign === 0) return a._sign;
|
|
2023
|
+
if (a._sign !== b._sign) return a._sign > b._sign ? 1 : -1;
|
|
2024
|
+
const result = _BigNumber.compareMagnitude(a, b);
|
|
2025
|
+
return a._sign === 1 ? result : -result;
|
|
2164
2026
|
}
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
const
|
|
2168
|
-
const
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
for (let n = 1; n <= maxIter; n++) {
|
|
2173
|
-
term = term.multiply(xSquared).negate();
|
|
2174
|
-
const contribution = term.divide(_BigNumber.fromNumber(2 * n + 1));
|
|
2175
|
-
const newSum = sum.add(contribution);
|
|
2176
|
-
if (sum.equals(newSum)) break;
|
|
2177
|
-
sum = newSum;
|
|
2027
|
+
static compareMagnitude(a, b) {
|
|
2028
|
+
const aDigits = a._coefficient.toString();
|
|
2029
|
+
const bDigits = b._coefficient.toString();
|
|
2030
|
+
const aOrder = aDigits.length + a._exponent;
|
|
2031
|
+
const bOrder = bDigits.length + b._exponent;
|
|
2032
|
+
if (aOrder !== bOrder) {
|
|
2033
|
+
return aOrder > bOrder ? 1 : -1;
|
|
2178
2034
|
}
|
|
2179
|
-
|
|
2035
|
+
const aFull = aDigits + "0".repeat(Math.max(0, a._exponent));
|
|
2036
|
+
const bFull = bDigits + "0".repeat(Math.max(0, b._exponent));
|
|
2037
|
+
if (aFull === bFull) return 0;
|
|
2038
|
+
return aFull > bFull ? 1 : -1;
|
|
2180
2039
|
}
|
|
2181
2040
|
// ============================================================
|
|
2182
|
-
//
|
|
2041
|
+
// Conversion Methods
|
|
2183
2042
|
// ============================================================
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2043
|
+
valueOf() {
|
|
2044
|
+
if (this._isNaN) return NaN;
|
|
2045
|
+
if (this._isInfinite) return this._sign === 1 ? Infinity : -Infinity;
|
|
2046
|
+
if (this._sign === 0) return 0;
|
|
2047
|
+
const str = this.toString();
|
|
2048
|
+
return parseFloat(str);
|
|
2189
2049
|
}
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
return this._sign === 1;
|
|
2050
|
+
/**
|
|
2051
|
+
* Convert to a JS number.
|
|
2052
|
+
* Alias for `valueOf()` — provided for Decimal.js / mathjs formatter
|
|
2053
|
+
* duck-typing compatibility.
|
|
2054
|
+
*/
|
|
2055
|
+
toNumber() {
|
|
2056
|
+
return this.valueOf();
|
|
2198
2057
|
}
|
|
2199
|
-
|
|
2200
|
-
|
|
2058
|
+
toString() {
|
|
2059
|
+
if (this._isNaN) return "NaN";
|
|
2060
|
+
if (this._isInfinite) return this._sign === 1 ? "Infinity" : "-Infinity";
|
|
2061
|
+
if (this._sign === 0) return "0";
|
|
2062
|
+
const sign2 = this._sign === -1 ? "-" : "";
|
|
2063
|
+
const digits2 = this._coefficient.toString();
|
|
2064
|
+
if (this._exponent >= 0) {
|
|
2065
|
+
return sign2 + digits2 + "0".repeat(this._exponent);
|
|
2066
|
+
} else if (-this._exponent < digits2.length) {
|
|
2067
|
+
const insertPos = digits2.length + this._exponent;
|
|
2068
|
+
return sign2 + digits2.slice(0, insertPos) + "." + digits2.slice(insertPos);
|
|
2069
|
+
} else {
|
|
2070
|
+
return sign2 + "0." + "0".repeat(-this._exponent - digits2.length) + digits2;
|
|
2071
|
+
}
|
|
2201
2072
|
}
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2073
|
+
toJSON() {
|
|
2074
|
+
return {
|
|
2075
|
+
mathjs: "BigNumber",
|
|
2076
|
+
value: this.toString()
|
|
2077
|
+
};
|
|
2205
2078
|
}
|
|
2206
|
-
|
|
2207
|
-
|
|
2079
|
+
/**
|
|
2080
|
+
* Convert to fixed-point notation.
|
|
2081
|
+
*
|
|
2082
|
+
* When called with no argument (or `undefined`) returns the full fixed-point
|
|
2083
|
+
* string representation without rounding — matching Decimal.js semantics where
|
|
2084
|
+
* `toFixed()` is equivalent to a lossless fixed-point stringify.
|
|
2085
|
+
* When called with a non-negative integer `decimalPlaces`, rounds and formats
|
|
2086
|
+
* to exactly that many digits after the decimal point.
|
|
2087
|
+
*/
|
|
2088
|
+
toFixed(decimalPlaces) {
|
|
2089
|
+
if (decimalPlaces === void 0) {
|
|
2090
|
+
return this.toFixedInternal(void 0);
|
|
2091
|
+
}
|
|
2092
|
+
return this.round(decimalPlaces).toFixedInternal(decimalPlaces);
|
|
2208
2093
|
}
|
|
2209
|
-
|
|
2210
|
-
return
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
);
|
|
2094
|
+
toFixedInternal(decimalPlaces) {
|
|
2095
|
+
if (this._isNaN) return "NaN";
|
|
2096
|
+
if (this._isInfinite) return this._sign === 1 ? "Infinity" : "-Infinity";
|
|
2097
|
+
const dp = decimalPlaces ?? -1;
|
|
2098
|
+
const allDigits = dp < 0;
|
|
2099
|
+
if (this._sign === 0) return allDigits ? "0" : dp > 0 ? "0." + "0".repeat(dp) : "0";
|
|
2100
|
+
const sign2 = this._sign === -1 ? "-" : "";
|
|
2101
|
+
const digits2 = this._coefficient.toString();
|
|
2102
|
+
if (this._exponent >= 0) {
|
|
2103
|
+
const intPart = digits2 + "0".repeat(this._exponent);
|
|
2104
|
+
if (allDigits) return sign2 + intPart;
|
|
2105
|
+
return sign2 + intPart + (dp > 0 ? "." + "0".repeat(dp) : "");
|
|
2106
|
+
} else if (-this._exponent <= digits2.length) {
|
|
2107
|
+
const insertPos = digits2.length + this._exponent;
|
|
2108
|
+
const intPart = digits2.slice(0, insertPos) || "0";
|
|
2109
|
+
const decPart = digits2.slice(insertPos);
|
|
2110
|
+
if (allDigits) {
|
|
2111
|
+
return sign2 + intPart + (decPart.length > 0 ? "." + decPart : "");
|
|
2112
|
+
}
|
|
2113
|
+
let paddedDec = decPart;
|
|
2114
|
+
if (paddedDec.length < dp) {
|
|
2115
|
+
paddedDec += "0".repeat(dp - paddedDec.length);
|
|
2116
|
+
}
|
|
2117
|
+
return sign2 + intPart + (dp > 0 ? "." + paddedDec.slice(0, dp) : "");
|
|
2118
|
+
} else {
|
|
2119
|
+
const leadingZeros = -this._exponent - digits2.length;
|
|
2120
|
+
const decPart = "0".repeat(leadingZeros) + digits2;
|
|
2121
|
+
if (allDigits) {
|
|
2122
|
+
return sign2 + "0." + decPart;
|
|
2123
|
+
}
|
|
2124
|
+
let paddedDec = decPart;
|
|
2125
|
+
if (paddedDec.length < dp) {
|
|
2126
|
+
paddedDec += "0".repeat(dp - paddedDec.length);
|
|
2127
|
+
}
|
|
2128
|
+
return sign2 + "0" + (dp > 0 ? "." + paddedDec.slice(0, dp) : "");
|
|
2129
|
+
}
|
|
2217
2130
|
}
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
if (
|
|
2223
|
-
if (
|
|
2224
|
-
if (
|
|
2225
|
-
|
|
2131
|
+
/**
|
|
2132
|
+
* Convert to exponential notation
|
|
2133
|
+
*/
|
|
2134
|
+
toExponential(decimalPlaces) {
|
|
2135
|
+
if (this._isNaN) return "NaN";
|
|
2136
|
+
if (this._isInfinite) return this._sign === 1 ? "Infinity" : "-Infinity";
|
|
2137
|
+
if (this._sign === 0) {
|
|
2138
|
+
const dp = decimalPlaces ?? 0;
|
|
2139
|
+
return dp > 0 ? "0." + "0".repeat(dp) + "e+0" : "0e+0";
|
|
2140
|
+
}
|
|
2141
|
+
const sign2 = this._sign === -1 ? "-" : "";
|
|
2142
|
+
const digits2 = this._coefficient.toString();
|
|
2143
|
+
const exp = digits2.length - 1 + this._exponent;
|
|
2144
|
+
const expSign = exp >= 0 ? "+" : "";
|
|
2145
|
+
if (decimalPlaces === void 0) {
|
|
2146
|
+
if (digits2.length === 1) {
|
|
2147
|
+
return `${sign2}${digits2}e${expSign}${exp}`;
|
|
2148
|
+
}
|
|
2149
|
+
return `${sign2}${digits2[0]}.${digits2.slice(1)}e${expSign}${exp}`;
|
|
2150
|
+
}
|
|
2151
|
+
if (decimalPlaces === 0) {
|
|
2152
|
+
return `${sign2}${digits2[0]}e${expSign}${exp}`;
|
|
2153
|
+
}
|
|
2154
|
+
let decPart = digits2.slice(1);
|
|
2155
|
+
if (decPart.length < decimalPlaces) {
|
|
2156
|
+
decPart += "0".repeat(decimalPlaces - decPart.length);
|
|
2157
|
+
} else {
|
|
2158
|
+
decPart = decPart.slice(0, decimalPlaces);
|
|
2159
|
+
}
|
|
2160
|
+
return `${sign2}${digits2[0]}.${decPart}e${expSign}${exp}`;
|
|
2226
2161
|
}
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2162
|
+
/**
|
|
2163
|
+
* Convert to precision
|
|
2164
|
+
*/
|
|
2165
|
+
toPrecision(significantDigits) {
|
|
2166
|
+
if (significantDigits === void 0) {
|
|
2167
|
+
return this.toString();
|
|
2168
|
+
}
|
|
2169
|
+
if (this._isNaN) return "NaN";
|
|
2170
|
+
if (this._isInfinite) return this._sign === 1 ? "Infinity" : "-Infinity";
|
|
2171
|
+
if (this._sign === 0) {
|
|
2172
|
+
return significantDigits > 1 ? "0." + "0".repeat(significantDigits - 1) : "0";
|
|
2173
|
+
}
|
|
2174
|
+
const digits2 = this._coefficient.toString();
|
|
2175
|
+
const order = digits2.length + this._exponent;
|
|
2176
|
+
if (order > significantDigits || order < -6) {
|
|
2177
|
+
return this.toExponential(significantDigits - 1);
|
|
2178
|
+
}
|
|
2179
|
+
return this.toFixed(significantDigits - order);
|
|
2234
2180
|
}
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2181
|
+
/**
|
|
2182
|
+
* Convert to bigint (truncated)
|
|
2183
|
+
*/
|
|
2184
|
+
toBigInt() {
|
|
2185
|
+
if (this._isNaN || this._isInfinite) {
|
|
2186
|
+
throw new Error("Cannot convert NaN or Infinity to bigint");
|
|
2238
2187
|
}
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2188
|
+
if (this._sign === 0) return 0n;
|
|
2189
|
+
const digits2 = this._coefficient.toString();
|
|
2190
|
+
if (this._exponent >= 0) {
|
|
2191
|
+
return BigInt(this._sign) * BigInt(digits2 + "0".repeat(this._exponent));
|
|
2192
|
+
} else if (-this._exponent < digits2.length) {
|
|
2193
|
+
return BigInt(this._sign) * BigInt(digits2.slice(0, digits2.length + this._exponent));
|
|
2244
2194
|
}
|
|
2245
|
-
return
|
|
2195
|
+
return 0n;
|
|
2246
2196
|
}
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
var BIGNUMBER_E = BigNumber.parse("2.71828182845904523536028747135266249775724709369995");
|
|
2254
|
-
var BIGNUMBER_LN2 = BigNumber.parse(
|
|
2255
|
-
"0.69314718055994530941723212145817656807550013436026"
|
|
2256
|
-
);
|
|
2257
|
-
var BIGNUMBER_LN10 = BigNumber.parse(
|
|
2258
|
-
"2.30258509299404568401799145468436420760110148862877"
|
|
2259
|
-
);
|
|
2260
|
-
|
|
2261
|
-
// src/is.ts
|
|
2262
|
-
function hasPrototypeFlag(x, flag) {
|
|
2263
|
-
return !!x && x.constructor.prototype[flag] === true;
|
|
2264
|
-
}
|
|
2265
|
-
function hasOwnAndPrototypeFlag(x, ownFlag, protoFlag) {
|
|
2266
|
-
return !!x && x[ownFlag] === true && x.constructor.prototype[protoFlag] === true;
|
|
2267
|
-
}
|
|
2268
|
-
function isNumber(x) {
|
|
2269
|
-
return typeof x === "number";
|
|
2270
|
-
}
|
|
2271
|
-
function isBigNumber2(x) {
|
|
2272
|
-
if (!x || typeof x !== "object" || typeof x.constructor !== "function") {
|
|
2273
|
-
return false;
|
|
2197
|
+
/**
|
|
2198
|
+
* Binary string representation, e.g. `255 -> '0b11111111'`, `0.5 -> '0b0.1'`.
|
|
2199
|
+
* Mirrors Decimal.js `toBinary()`. Negatives carry a leading `-`.
|
|
2200
|
+
*/
|
|
2201
|
+
toBinary() {
|
|
2202
|
+
return this.toRadixString(2, "0b");
|
|
2274
2203
|
}
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2204
|
+
/**
|
|
2205
|
+
* Octal string representation, e.g. `8 -> '0o10'`.
|
|
2206
|
+
* Mirrors Decimal.js `toOctal()`.
|
|
2207
|
+
*/
|
|
2208
|
+
toOctal() {
|
|
2209
|
+
return this.toRadixString(8, "0o");
|
|
2278
2210
|
}
|
|
2279
|
-
|
|
2280
|
-
|
|
2211
|
+
/**
|
|
2212
|
+
* Hexadecimal string representation, e.g. `255 -> '0xff'`, `10.5 -> '0xa.8'`.
|
|
2213
|
+
* Mirrors Decimal.js `toHexadecimal()`.
|
|
2214
|
+
*/
|
|
2215
|
+
toHexadecimal() {
|
|
2216
|
+
return this.toRadixString(16, "0x");
|
|
2281
2217
|
}
|
|
2282
|
-
|
|
2283
|
-
}
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
}
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
function isSparseMatrix(x) {
|
|
2310
|
-
return hasOwnAndPrototypeFlag(x, "isSparseMatrix", "isMatrix");
|
|
2311
|
-
}
|
|
2312
|
-
function isRange(x) {
|
|
2313
|
-
return hasPrototypeFlag(x, "isRange");
|
|
2314
|
-
}
|
|
2315
|
-
function isIndex(x) {
|
|
2316
|
-
return hasPrototypeFlag(x, "isIndex");
|
|
2317
|
-
}
|
|
2318
|
-
function isBoolean(x) {
|
|
2319
|
-
return typeof x === "boolean";
|
|
2320
|
-
}
|
|
2321
|
-
function isFunction(x) {
|
|
2322
|
-
return typeof x === "function";
|
|
2323
|
-
}
|
|
2324
|
-
function isDate(x) {
|
|
2325
|
-
return x instanceof Date;
|
|
2326
|
-
}
|
|
2327
|
-
function isRegExp(x) {
|
|
2328
|
-
return x instanceof RegExp;
|
|
2329
|
-
}
|
|
2330
|
-
function isObject(x) {
|
|
2331
|
-
return !!(x && typeof x === "object" && x.constructor === Object && !isComplex2(x) && !isFraction2(x));
|
|
2332
|
-
}
|
|
2333
|
-
function isMap(object) {
|
|
2334
|
-
if (!object) {
|
|
2335
|
-
return false;
|
|
2336
|
-
}
|
|
2337
|
-
const o = object;
|
|
2338
|
-
return object instanceof Map || typeof o.set === "function" && typeof o.get === "function" && typeof o.keys === "function" && typeof o.has === "function";
|
|
2339
|
-
}
|
|
2340
|
-
function isNull(x) {
|
|
2341
|
-
return x === null;
|
|
2342
|
-
}
|
|
2343
|
-
function isUndefined(x) {
|
|
2344
|
-
return x === void 0;
|
|
2345
|
-
}
|
|
2346
|
-
function typeOf(x) {
|
|
2347
|
-
const t = typeof x;
|
|
2348
|
-
if (t === "object") {
|
|
2349
|
-
if (x === null) return "null";
|
|
2350
|
-
if (isBigNumber2(x)) return "BigNumber";
|
|
2351
|
-
if (isComplex2(x)) return "Complex";
|
|
2352
|
-
if (isFraction2(x)) return "Fraction";
|
|
2353
|
-
const ctor = x.constructor;
|
|
2354
|
-
if (ctor && ctor.name) return ctor.name;
|
|
2355
|
-
return "Object";
|
|
2356
|
-
}
|
|
2357
|
-
return t;
|
|
2358
|
-
}
|
|
2359
|
-
|
|
2360
|
-
// src/number.ts
|
|
2361
|
-
function isInteger(value) {
|
|
2362
|
-
if (typeof value === "boolean") {
|
|
2363
|
-
return true;
|
|
2218
|
+
/**
|
|
2219
|
+
* Shared radix formatter for {@link toBinary}/{@link toOctal}/{@link toHexadecimal}.
|
|
2220
|
+
* Integers and terminating fractions are exact; a non-terminating fraction is
|
|
2221
|
+
* truncated at `maxFractionDigits` radix digits (a safety bound — the common
|
|
2222
|
+
* use is integer formatting).
|
|
2223
|
+
*/
|
|
2224
|
+
toRadixString(radix, prefix, maxFractionDigits = 1100) {
|
|
2225
|
+
if (this._isNaN) return "NaN";
|
|
2226
|
+
if (this._isInfinite) return (this._sign < 0 ? "-" : "") + "Infinity";
|
|
2227
|
+
if (this._sign === 0) return prefix + "0";
|
|
2228
|
+
const negative = this._sign < 0;
|
|
2229
|
+
const absVal = this.abs();
|
|
2230
|
+
const intPart = absVal.toBigInt();
|
|
2231
|
+
let out = prefix + intPart.toString(radix);
|
|
2232
|
+
let frac = absVal.subtract(_BigNumber.fromBigInt(intPart));
|
|
2233
|
+
if (!frac.isZero()) {
|
|
2234
|
+
const radixBN = _BigNumber.fromNumber(radix);
|
|
2235
|
+
let digits2 = "";
|
|
2236
|
+
for (let i = 0; i < maxFractionDigits && !frac.isZero(); i++) {
|
|
2237
|
+
frac = frac.multiply(radixBN);
|
|
2238
|
+
const digit = frac.toBigInt();
|
|
2239
|
+
digits2 += Number(digit).toString(radix);
|
|
2240
|
+
frac = frac.subtract(_BigNumber.fromBigInt(digit));
|
|
2241
|
+
}
|
|
2242
|
+
out += "." + digits2;
|
|
2243
|
+
}
|
|
2244
|
+
return (negative ? "-" : "") + out;
|
|
2364
2245
|
}
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2246
|
+
// ============================================================
|
|
2247
|
+
// Arithmetic Operations
|
|
2248
|
+
// ============================================================
|
|
2249
|
+
/**
|
|
2250
|
+
* Addition
|
|
2251
|
+
*/
|
|
2252
|
+
add(other) {
|
|
2253
|
+
const b = this.ensureBigNumber(other);
|
|
2254
|
+
if (this._isNaN || b._isNaN) return new _BigNumber(0, 0n, 0, true);
|
|
2255
|
+
if (this._isInfinite && b._isInfinite) {
|
|
2256
|
+
if (this._sign === b._sign) return this;
|
|
2257
|
+
return new _BigNumber(0, 0n, 0, true);
|
|
2258
|
+
}
|
|
2259
|
+
if (this._isInfinite) return this;
|
|
2260
|
+
if (b._isInfinite) return b;
|
|
2261
|
+
if (this._sign === 0) return b;
|
|
2262
|
+
if (b._sign === 0) return this;
|
|
2263
|
+
const [aCoef, bCoef, exp] = this.alignExponents(this, b);
|
|
2264
|
+
if (this._sign === b._sign) {
|
|
2265
|
+
return this.normalize(this._sign, aCoef + bCoef, exp);
|
|
2266
|
+
} else {
|
|
2267
|
+
if (aCoef >= bCoef) {
|
|
2268
|
+
const diff = aCoef - bCoef;
|
|
2269
|
+
return this.normalize(diff === 0n ? 0 : this._sign, diff, exp);
|
|
2270
|
+
} else {
|
|
2271
|
+
return this.normalize(b._sign, bCoef - aCoef, exp);
|
|
2272
|
+
}
|
|
2373
2273
|
}
|
|
2374
2274
|
}
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
return -1;
|
|
2382
|
-
} else {
|
|
2383
|
-
return 0;
|
|
2275
|
+
/**
|
|
2276
|
+
* Subtraction
|
|
2277
|
+
*/
|
|
2278
|
+
subtract(other) {
|
|
2279
|
+
const b = this.ensureBigNumber(other);
|
|
2280
|
+
return this.add(b.negate());
|
|
2384
2281
|
}
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
return Math.log(x) / Math.LN10;
|
|
2391
|
-
};
|
|
2392
|
-
var log1p = Math.log1p || function(x) {
|
|
2393
|
-
return Math.log(x + 1);
|
|
2394
|
-
};
|
|
2395
|
-
var cbrt = Math.cbrt || function cbrt2(x) {
|
|
2396
|
-
if (x === 0) {
|
|
2397
|
-
return x;
|
|
2282
|
+
/**
|
|
2283
|
+
* Alias for subtract — mathjs / Decimal.js compatibility.
|
|
2284
|
+
*/
|
|
2285
|
+
sub(other) {
|
|
2286
|
+
return this.subtract(other);
|
|
2398
2287
|
}
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2288
|
+
/**
|
|
2289
|
+
* Multiplication
|
|
2290
|
+
*/
|
|
2291
|
+
multiply(other) {
|
|
2292
|
+
const b = this.ensureBigNumber(other);
|
|
2293
|
+
if (this._isNaN || b._isNaN) return new _BigNumber(0, 0n, 0, true);
|
|
2294
|
+
if (this._isInfinite || b._isInfinite) {
|
|
2295
|
+
if (this._sign === 0 || b._sign === 0) return new _BigNumber(0, 0n, 0, true);
|
|
2296
|
+
const sign3 = this._sign * b._sign;
|
|
2297
|
+
return new _BigNumber(sign3, 0n, 0, false, true);
|
|
2298
|
+
}
|
|
2299
|
+
if (this._sign === 0 || b._sign === 0) return new _BigNumber(0, 0n, 0);
|
|
2300
|
+
const sign2 = this._sign * b._sign;
|
|
2301
|
+
const coefficient = this._coefficient * b._coefficient;
|
|
2302
|
+
const exponent = this._exponent + b._exponent;
|
|
2303
|
+
return this.normalize(sign2, coefficient, exponent);
|
|
2403
2304
|
}
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2305
|
+
/**
|
|
2306
|
+
* Alias for multiply — mathjs / Decimal.js compatibility.
|
|
2307
|
+
*/
|
|
2308
|
+
mul(other) {
|
|
2309
|
+
return this.multiply(other);
|
|
2409
2310
|
}
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
if (
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
if (n > 2 ** (size - 1) - 1 || n < -(2 ** (size - 1))) {
|
|
2427
|
-
throw new Error(`Value must be in range [-2^${size - 1}, 2^${size - 1}-1]`);
|
|
2428
|
-
}
|
|
2429
|
-
if (!isInteger(n)) {
|
|
2430
|
-
throw new Error("Value must be an integer");
|
|
2311
|
+
/**
|
|
2312
|
+
* Alias for multiply — Decimal.js calling convention (used by the Unit).
|
|
2313
|
+
*/
|
|
2314
|
+
times(other) {
|
|
2315
|
+
return this.multiply(other);
|
|
2316
|
+
}
|
|
2317
|
+
/**
|
|
2318
|
+
* Division
|
|
2319
|
+
*/
|
|
2320
|
+
divide(other) {
|
|
2321
|
+
const b = this.ensureBigNumber(other);
|
|
2322
|
+
if (this._isNaN || b._isNaN) return new _BigNumber(0, 0n, 0, true);
|
|
2323
|
+
if (this._isInfinite && b._isInfinite) return new _BigNumber(0, 0n, 0, true);
|
|
2324
|
+
if (b._sign === 0) {
|
|
2325
|
+
if (this._sign === 0) return new _BigNumber(0, 0n, 0, true);
|
|
2326
|
+
return new _BigNumber(this._sign, 0n, 0, false, true);
|
|
2431
2327
|
}
|
|
2432
|
-
if (
|
|
2433
|
-
|
|
2328
|
+
if (this._isInfinite) {
|
|
2329
|
+
const sign3 = this._sign * b._sign;
|
|
2330
|
+
return new _BigNumber(sign3, 0n, 0, false, true);
|
|
2434
2331
|
}
|
|
2435
|
-
|
|
2332
|
+
if (b._isInfinite) return new _BigNumber(0, 0n, 0);
|
|
2333
|
+
if (this._sign === 0) return new _BigNumber(0, 0n, 0);
|
|
2334
|
+
const sign2 = this._sign * b._sign;
|
|
2335
|
+
const precision = globalConfig.precision;
|
|
2336
|
+
const scale = BigInt(10) ** BigInt(precision + 10);
|
|
2337
|
+
const scaledDividend = this._coefficient * scale;
|
|
2338
|
+
const quotient = scaledDividend / b._coefficient;
|
|
2339
|
+
const exponent = this._exponent - b._exponent - precision - 10;
|
|
2340
|
+
return this.normalize(sign2, quotient, exponent).roundToPrecision(precision);
|
|
2436
2341
|
}
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2342
|
+
/**
|
|
2343
|
+
* Alias for divide — Decimal.js calling convention (used by the Unit).
|
|
2344
|
+
*/
|
|
2345
|
+
div(other) {
|
|
2346
|
+
return this.divide(other);
|
|
2441
2347
|
}
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2348
|
+
/**
|
|
2349
|
+
* Negation
|
|
2350
|
+
*/
|
|
2351
|
+
negate() {
|
|
2352
|
+
if (this._isNaN) return this;
|
|
2353
|
+
if (this._sign === 0) return this;
|
|
2354
|
+
const newSign = this._sign === 1 ? -1 : 1;
|
|
2355
|
+
return new _BigNumber(newSign, this._coefficient, this._exponent, false, this._isInfinite);
|
|
2447
2356
|
}
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
return
|
|
2454
|
-
|
|
2455
|
-
const { notation, precision, wordSize } = normalizeFormatOptions(options);
|
|
2456
|
-
switch (notation) {
|
|
2457
|
-
case "fixed":
|
|
2458
|
-
return toFixed(value, precision);
|
|
2459
|
-
case "exponential":
|
|
2460
|
-
return toExponential(value, precision);
|
|
2461
|
-
case "engineering":
|
|
2462
|
-
return toEngineering(value, precision);
|
|
2463
|
-
case "bin":
|
|
2464
|
-
return formatNumberToBase(value, 2, wordSize);
|
|
2465
|
-
case "oct":
|
|
2466
|
-
return formatNumberToBase(value, 8, wordSize);
|
|
2467
|
-
case "hex":
|
|
2468
|
-
return formatNumberToBase(value, 16, wordSize);
|
|
2469
|
-
case "auto":
|
|
2470
|
-
return toPrecision(value, precision, options).replace(
|
|
2471
|
-
/((\.\d*?)(0+))($|e)/,
|
|
2472
|
-
function(_match, _all, digits2, _zeros, e) {
|
|
2473
|
-
return digits2 !== "." ? digits2 + e : e;
|
|
2474
|
-
}
|
|
2475
|
-
);
|
|
2476
|
-
default:
|
|
2477
|
-
throw new Error(
|
|
2478
|
-
'Unknown notation "' + notation + '". Choose "auto", "exponential", "fixed", "bin", "oct", or "hex.'
|
|
2479
|
-
);
|
|
2357
|
+
/**
|
|
2358
|
+
* Absolute value
|
|
2359
|
+
*/
|
|
2360
|
+
abs() {
|
|
2361
|
+
if (this._isNaN) return this;
|
|
2362
|
+
if (this._sign === 0) return this;
|
|
2363
|
+
return new _BigNumber(1, this._coefficient, this._exponent, false, this._isInfinite);
|
|
2480
2364
|
}
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
if (
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
}
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
}
|
|
2502
|
-
if (options.notation) {
|
|
2503
|
-
notation = options.notation;
|
|
2365
|
+
/**
|
|
2366
|
+
* Power (integer exponent)
|
|
2367
|
+
*/
|
|
2368
|
+
pow(n) {
|
|
2369
|
+
const exp = typeof n === "bigint" ? Number(n) : n;
|
|
2370
|
+
if (this._isNaN) return this;
|
|
2371
|
+
if (exp === 0) return _BigNumber.fromNumber(1);
|
|
2372
|
+
if (this._sign === 0) {
|
|
2373
|
+
if (exp < 0) return new _BigNumber(1, 0n, 0, false, true);
|
|
2374
|
+
return this;
|
|
2375
|
+
}
|
|
2376
|
+
if (exp < 0) {
|
|
2377
|
+
return _BigNumber.fromNumber(1).divide(this.pow(-exp));
|
|
2378
|
+
}
|
|
2379
|
+
let result = _BigNumber.fromNumber(1);
|
|
2380
|
+
let base = this.clone();
|
|
2381
|
+
let e = exp;
|
|
2382
|
+
while (e > 0) {
|
|
2383
|
+
if (e % 2 === 1) {
|
|
2384
|
+
result = result.multiply(base);
|
|
2504
2385
|
}
|
|
2505
|
-
|
|
2506
|
-
|
|
2386
|
+
base = base.multiply(base);
|
|
2387
|
+
e = Math.floor(e / 2);
|
|
2507
2388
|
}
|
|
2389
|
+
return result.roundToPrecision(globalConfig.precision);
|
|
2508
2390
|
}
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
return parseInt(d);
|
|
2526
|
-
});
|
|
2527
|
-
if (coefficients.length === 0) {
|
|
2528
|
-
coefficients.push(0);
|
|
2529
|
-
exponent++;
|
|
2530
|
-
}
|
|
2531
|
-
return { sign: sign2, coefficients, exponent };
|
|
2532
|
-
}
|
|
2533
|
-
function toEngineering(value, precision) {
|
|
2534
|
-
if (isNaN(value) || !isFinite(value)) {
|
|
2535
|
-
return String(value);
|
|
2536
|
-
}
|
|
2537
|
-
const split = splitNumber(value);
|
|
2538
|
-
const rounded = roundDigits(split, precision);
|
|
2539
|
-
const e = rounded.exponent;
|
|
2540
|
-
const c = rounded.coefficients;
|
|
2541
|
-
const newExp = e % 3 === 0 ? e : e < 0 ? e - 3 - e % 3 : e - e % 3;
|
|
2542
|
-
if (isNumber(precision)) {
|
|
2543
|
-
while (precision > c.length || e - newExp + 1 > c.length) {
|
|
2544
|
-
c.push(0);
|
|
2545
|
-
}
|
|
2546
|
-
} else {
|
|
2547
|
-
const missingZeros = Math.abs(e - newExp) - (c.length - 1);
|
|
2548
|
-
for (let i = 0; i < missingZeros; i++) {
|
|
2549
|
-
c.push(0);
|
|
2391
|
+
/**
|
|
2392
|
+
* Square root
|
|
2393
|
+
*/
|
|
2394
|
+
sqrt() {
|
|
2395
|
+
if (this._isNaN) return this;
|
|
2396
|
+
if (this._sign === -1) return new _BigNumber(0, 0n, 0, true);
|
|
2397
|
+
if (this._sign === 0) return this;
|
|
2398
|
+
if (this._isInfinite) return this;
|
|
2399
|
+
const precision = globalConfig.precision;
|
|
2400
|
+
let guess = _BigNumber.fromNumber(Math.sqrt(this.valueOf()));
|
|
2401
|
+
for (let i = 0; i < 100; i++) {
|
|
2402
|
+
const newGuess = guess.add(this.divide(guess)).divide(_BigNumber.fromNumber(2));
|
|
2403
|
+
if (guess.subtract(newGuess).abs().compareTo(guess.multiply(_BigNumber.parse("1e-" + (precision + 5)))) <= 0) {
|
|
2404
|
+
return newGuess.roundToPrecision(precision);
|
|
2405
|
+
}
|
|
2406
|
+
guess = newGuess;
|
|
2550
2407
|
}
|
|
2408
|
+
return guess.roundToPrecision(precision);
|
|
2551
2409
|
}
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2410
|
+
// ============================================================
|
|
2411
|
+
// Comparison Methods
|
|
2412
|
+
// ============================================================
|
|
2413
|
+
equals(other) {
|
|
2414
|
+
return _BigNumber.compare(this, other) === 0;
|
|
2557
2415
|
}
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
const str = c.slice(0, decimalIdx).join("") + decimalVal + "e" + (e >= 0 ? "+" : "") + newExp.toString();
|
|
2561
|
-
return rounded.sign + str;
|
|
2562
|
-
}
|
|
2563
|
-
function toFixed(value, precision) {
|
|
2564
|
-
if (isNaN(value) || !isFinite(value)) {
|
|
2565
|
-
return String(value);
|
|
2416
|
+
lessThan(other) {
|
|
2417
|
+
return _BigNumber.compare(this, other) < 0;
|
|
2566
2418
|
}
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
let c = rounded.coefficients;
|
|
2570
|
-
let p = rounded.exponent + 1;
|
|
2571
|
-
const pp = p + (precision || 0);
|
|
2572
|
-
if (c.length < pp) {
|
|
2573
|
-
c = c.concat(zeros(pp - c.length));
|
|
2419
|
+
lessThanOrEqual(other) {
|
|
2420
|
+
return _BigNumber.compare(this, other) <= 0;
|
|
2574
2421
|
}
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
p = 1;
|
|
2422
|
+
greaterThan(other) {
|
|
2423
|
+
return _BigNumber.compare(this, other) > 0;
|
|
2578
2424
|
}
|
|
2579
|
-
|
|
2580
|
-
|
|
2425
|
+
greaterThanOrEqual(other) {
|
|
2426
|
+
return _BigNumber.compare(this, other) >= 0;
|
|
2581
2427
|
}
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
function toExponential(value, precision) {
|
|
2585
|
-
if (isNaN(value) || !isFinite(value)) {
|
|
2586
|
-
return String(value);
|
|
2428
|
+
compareTo(other) {
|
|
2429
|
+
return _BigNumber.compare(this, other);
|
|
2587
2430
|
}
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
let c = rounded.coefficients;
|
|
2591
|
-
const e = rounded.exponent;
|
|
2592
|
-
if (precision && c.length < precision) {
|
|
2593
|
-
c = c.concat(zeros(precision - c.length));
|
|
2431
|
+
compare(other) {
|
|
2432
|
+
return this.compareTo(other);
|
|
2594
2433
|
}
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2434
|
+
/**
|
|
2435
|
+
* Returns true iff this > other.
|
|
2436
|
+
* Accepts the same argument types as `add`/`multiply` (BigNumber, number, or string).
|
|
2437
|
+
* Named `gt` for Decimal.js / mathjs formatter compatibility.
|
|
2438
|
+
*/
|
|
2439
|
+
gt(other) {
|
|
2440
|
+
return this.greaterThan(this.ensureBigNumber(other));
|
|
2601
2441
|
}
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
const
|
|
2611
|
-
if (
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
const
|
|
2619
|
-
if (
|
|
2620
|
-
|
|
2442
|
+
// ============================================================
|
|
2443
|
+
// Rounding Methods
|
|
2444
|
+
// ============================================================
|
|
2445
|
+
/**
|
|
2446
|
+
* Round to specified decimal places
|
|
2447
|
+
*/
|
|
2448
|
+
round(decimalPlaces = 0, mode = globalConfig.rounding) {
|
|
2449
|
+
if (this._isNaN || this._isInfinite || this._sign === 0) return this;
|
|
2450
|
+
const targetExp = -decimalPlaces;
|
|
2451
|
+
if (this._exponent >= targetExp) return this;
|
|
2452
|
+
const shift = targetExp - this._exponent;
|
|
2453
|
+
const divisor = BigInt(10) ** BigInt(shift);
|
|
2454
|
+
const quotient = this._coefficient / divisor;
|
|
2455
|
+
const remainder = this._coefficient % divisor;
|
|
2456
|
+
let rounded = quotient;
|
|
2457
|
+
const halfDivisor = divisor / 2n;
|
|
2458
|
+
const shouldRoundUp = this.shouldRound(remainder, halfDivisor, divisor, quotient, mode);
|
|
2459
|
+
if (shouldRoundUp) {
|
|
2460
|
+
rounded += 1n;
|
|
2621
2461
|
}
|
|
2622
|
-
return rounded.
|
|
2462
|
+
return this.normalize(rounded === 0n ? 0 : this._sign, rounded, targetExp);
|
|
2623
2463
|
}
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2464
|
+
shouldRound(remainder, halfDivisor, divisor, quotient, mode) {
|
|
2465
|
+
const isPositive = this._sign === 1;
|
|
2466
|
+
const isExactlyHalf = remainder === halfDivisor && divisor % 2n === 0n;
|
|
2467
|
+
const isMoreThanHalf = remainder > halfDivisor;
|
|
2468
|
+
switch (mode) {
|
|
2469
|
+
case "up":
|
|
2470
|
+
return remainder > 0n;
|
|
2471
|
+
case "down":
|
|
2472
|
+
return false;
|
|
2473
|
+
case "ceil":
|
|
2474
|
+
return isPositive && remainder > 0n;
|
|
2475
|
+
case "floor":
|
|
2476
|
+
return !isPositive && remainder > 0n;
|
|
2477
|
+
case "halfUp":
|
|
2478
|
+
return isMoreThanHalf || isExactlyHalf;
|
|
2479
|
+
case "halfDown":
|
|
2480
|
+
return isMoreThanHalf;
|
|
2481
|
+
case "halfEven":
|
|
2482
|
+
return isMoreThanHalf || isExactlyHalf && quotient % 2n !== 0n;
|
|
2483
|
+
case "halfCeil":
|
|
2484
|
+
return isMoreThanHalf || isExactlyHalf && isPositive;
|
|
2485
|
+
case "halfFloor":
|
|
2486
|
+
return isMoreThanHalf || isExactlyHalf && !isPositive;
|
|
2487
|
+
default:
|
|
2488
|
+
return isMoreThanHalf || isExactlyHalf;
|
|
2637
2489
|
}
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2490
|
+
}
|
|
2491
|
+
/**
|
|
2492
|
+
* Round to specified precision (significant digits)
|
|
2493
|
+
*/
|
|
2494
|
+
roundToPrecision(precision, mode = globalConfig.rounding) {
|
|
2495
|
+
if (this._isNaN || this._isInfinite || this._sign === 0) return this;
|
|
2496
|
+
const digits2 = this._coefficient.toString();
|
|
2497
|
+
if (digits2.length <= precision) return this;
|
|
2498
|
+
const digitsToRemove = digits2.length - precision;
|
|
2499
|
+
const divisor = BigInt(10) ** BigInt(digitsToRemove);
|
|
2500
|
+
const quotient = this._coefficient / divisor;
|
|
2501
|
+
const remainder = this._coefficient % divisor;
|
|
2502
|
+
const halfDivisor = divisor / 2n;
|
|
2503
|
+
let rounded = quotient;
|
|
2504
|
+
const shouldRoundUp = this.shouldRound(remainder, halfDivisor, divisor, quotient, mode);
|
|
2505
|
+
if (shouldRoundUp) {
|
|
2506
|
+
rounded += 1n;
|
|
2654
2507
|
}
|
|
2508
|
+
const newExponent = this._exponent + digitsToRemove;
|
|
2509
|
+
return this.normalize(rounded === 0n ? 0 : this._sign, rounded, newExponent);
|
|
2655
2510
|
}
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
function zeros(length) {
|
|
2659
|
-
const arr = [];
|
|
2660
|
-
for (let i = 0; i < length; i++) {
|
|
2661
|
-
arr.push(0);
|
|
2511
|
+
floor() {
|
|
2512
|
+
return this.round(0, "floor");
|
|
2662
2513
|
}
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
function digits(value) {
|
|
2666
|
-
return value.toExponential().replace(/e.*$/, "").replace(/^0\.?0*|\./, "").length;
|
|
2667
|
-
}
|
|
2668
|
-
function nearlyEqual(a, b, relTol = 1e-8, absTol = 0) {
|
|
2669
|
-
if (relTol <= 0) {
|
|
2670
|
-
throw new Error("Relative tolerance must be greater than 0");
|
|
2514
|
+
ceil() {
|
|
2515
|
+
return this.round(0, "ceil");
|
|
2671
2516
|
}
|
|
2672
|
-
|
|
2673
|
-
|
|
2517
|
+
trunc() {
|
|
2518
|
+
return this.round(0, "down");
|
|
2674
2519
|
}
|
|
2675
|
-
|
|
2676
|
-
|
|
2520
|
+
/**
|
|
2521
|
+
* Round to `n` significant decimal digits and return a new BigNumber.
|
|
2522
|
+
* Delegates to `roundToPrecision`, using the global rounding mode unless
|
|
2523
|
+
* an explicit `roundingMode` is supplied.
|
|
2524
|
+
*
|
|
2525
|
+
* Named `toSignificantDigits` for Decimal.js / mathjs formatter compatibility.
|
|
2526
|
+
* When `n` is undefined the value is returned unchanged (no rounding).
|
|
2527
|
+
*/
|
|
2528
|
+
toSignificantDigits(n, roundingMode) {
|
|
2529
|
+
if (n === void 0) return this.clone();
|
|
2530
|
+
return this.roundToPrecision(n, roundingMode ?? globalConfig.rounding);
|
|
2677
2531
|
}
|
|
2678
|
-
|
|
2679
|
-
|
|
2532
|
+
/**
|
|
2533
|
+
* The decimal exponent of this number: `floor(log10(|x|))`.
|
|
2534
|
+
*
|
|
2535
|
+
* Matches Decimal.js semantics:
|
|
2536
|
+
* - `12345` → `4` (5 digits → the most-significant place is 10^4)
|
|
2537
|
+
* - `0.0123` → `-2` (first significant digit is at 10^-2)
|
|
2538
|
+
* - `100` → `2`
|
|
2539
|
+
* - `0.01` → `-2`
|
|
2540
|
+
* - `0` → `0` (by convention; `isZero()` can be used to distinguish)
|
|
2541
|
+
*
|
|
2542
|
+
* For special values (NaN, ±Infinity) returns 0 — callers check
|
|
2543
|
+
* `isFinite()` / `isNaN()` before using `.e`.
|
|
2544
|
+
*/
|
|
2545
|
+
get e() {
|
|
2546
|
+
if (this._isNaN || this._isInfinite || this._sign === 0) return 0;
|
|
2547
|
+
const d = this._coefficient.toString().length;
|
|
2548
|
+
return d - 1 + this._exponent;
|
|
2680
2549
|
}
|
|
2681
|
-
|
|
2682
|
-
|
|
2550
|
+
// ============================================================
|
|
2551
|
+
// Modular Arithmetic
|
|
2552
|
+
// ============================================================
|
|
2553
|
+
/**
|
|
2554
|
+
* Modulo (remainder after division)
|
|
2555
|
+
* Result has the same sign as the dividend (this).
|
|
2556
|
+
*/
|
|
2557
|
+
mod(other) {
|
|
2558
|
+
const b = this.ensureBigNumber(other);
|
|
2559
|
+
if (this._isNaN || b._isNaN || b._sign === 0) return new _BigNumber(0, 0n, 0, true);
|
|
2560
|
+
if (this._isInfinite) return new _BigNumber(0, 0n, 0, true);
|
|
2561
|
+
if (b._isInfinite) return this;
|
|
2562
|
+
if (this._sign === 0) return this;
|
|
2563
|
+
const quotient = this.divide(b).trunc();
|
|
2564
|
+
return this.subtract(b.multiply(quotient));
|
|
2683
2565
|
}
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
};
|
|
2698
|
-
var sinh = Math.sinh || function(x) {
|
|
2699
|
-
return (Math.exp(x) - Math.exp(-x)) / 2;
|
|
2700
|
-
};
|
|
2701
|
-
var tanh = Math.tanh || function(x) {
|
|
2702
|
-
const e = Math.exp(2 * x);
|
|
2703
|
-
return (e - 1) / (e + 1);
|
|
2704
|
-
};
|
|
2705
|
-
function copysign(x, y) {
|
|
2706
|
-
const signx = x > 0 ? true : x < 0 ? false : 1 / x === Infinity;
|
|
2707
|
-
const signy = y > 0 ? true : y < 0 ? false : 1 / y === Infinity;
|
|
2708
|
-
return signx !== signy ? -x : x;
|
|
2709
|
-
}
|
|
2710
|
-
function isPowZeroAtInfinity(x, y) {
|
|
2711
|
-
return x * x < 1 && y === Infinity || x * x > 1 && y === -Infinity;
|
|
2712
|
-
}
|
|
2713
|
-
function _toNumberOrThrow(value, onError) {
|
|
2714
|
-
if (isNumber(value)) {
|
|
2715
|
-
return value;
|
|
2716
|
-
} else if (isBigNumber2(value)) {
|
|
2717
|
-
return value.toNumber();
|
|
2718
|
-
} else {
|
|
2719
|
-
onError();
|
|
2720
|
-
return 0;
|
|
2566
|
+
// ============================================================
|
|
2567
|
+
// Trigonometric Functions
|
|
2568
|
+
// ============================================================
|
|
2569
|
+
/**
|
|
2570
|
+
* Sine of this BigNumber (in radians)
|
|
2571
|
+
* Uses Taylor series: sin(x) = x - x^3/3! + x^5/5! - ...
|
|
2572
|
+
*/
|
|
2573
|
+
sin() {
|
|
2574
|
+
if (this._isNaN) return this;
|
|
2575
|
+
if (this._isInfinite) return new _BigNumber(0, 0n, 0, true);
|
|
2576
|
+
if (this._sign === 0) return this;
|
|
2577
|
+
const x = this._reduceAngle();
|
|
2578
|
+
return x._sinTaylor();
|
|
2721
2579
|
}
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
return
|
|
2580
|
+
/**
|
|
2581
|
+
* Cosine of this BigNumber (in radians)
|
|
2582
|
+
* Uses Taylor series: cos(x) = 1 - x^2/2! + x^4/4! - ...
|
|
2583
|
+
*/
|
|
2584
|
+
cos() {
|
|
2585
|
+
if (this._isNaN) return this;
|
|
2586
|
+
if (this._isInfinite) return new _BigNumber(0, 0n, 0, true);
|
|
2587
|
+
if (this._sign === 0) return _BigNumber.fromNumber(1);
|
|
2588
|
+
const x = this._reduceAngle();
|
|
2589
|
+
return x._cosTaylor();
|
|
2730
2590
|
}
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
// type of default matrix output. Choose 'matrix' (default) or 'array'
|
|
2742
|
-
matrix: "Matrix",
|
|
2743
|
-
// type of default number output. Choose 'number' (default) 'BigNumber', 'bigint', or 'Fraction'
|
|
2744
|
-
number: "number",
|
|
2745
|
-
// type of fallback used for config { number: 'bigint' } when a value cannot be represented
|
|
2746
|
-
// in the configured numeric type. Choose 'number' (default) or 'BigNumber'.
|
|
2747
|
-
numberFallback: "number",
|
|
2748
|
-
// number of significant digits in BigNumbers
|
|
2749
|
-
precision: 64,
|
|
2750
|
-
// predictable output type of functions. When true, output type depends only
|
|
2751
|
-
// on the input types. When false (default), output type can vary depending
|
|
2752
|
-
// on input values. For example `math.sqrt(-4)` returns `complex('2i')` when
|
|
2753
|
-
// predictable is false, and returns `NaN` when true.
|
|
2754
|
-
predictable: false,
|
|
2755
|
-
// random seed for seeded pseudo random number generation
|
|
2756
|
-
// null = randomly seed
|
|
2757
|
-
randomSeed: null,
|
|
2758
|
-
// legacy behavior for matrix subset. When true, the subset function
|
|
2759
|
-
// returns a matrix or array with the same size as the index (except for scalars).
|
|
2760
|
-
// When false, it returns a matrix or array with a size depending on the type of index.
|
|
2761
|
-
legacySubset: false
|
|
2762
|
-
};
|
|
2763
|
-
|
|
2764
|
-
// src/arithmetic/scalar.ts
|
|
2765
|
-
function isPrimitive(v) {
|
|
2766
|
-
return typeof v === "number" || typeof v === "bigint";
|
|
2767
|
-
}
|
|
2768
|
-
function asComplex(v) {
|
|
2769
|
-
return v instanceof Complex ? v : new Complex(number(v), 0);
|
|
2770
|
-
}
|
|
2771
|
-
function asBigNumber(v) {
|
|
2772
|
-
if (v instanceof BigNumber) return v;
|
|
2773
|
-
if (typeof v === "bigint") return BigNumber.fromBigInt(v);
|
|
2774
|
-
return BigNumber.fromNumber(number(v));
|
|
2775
|
-
}
|
|
2776
|
-
function asFraction(v) {
|
|
2777
|
-
if (v instanceof Fraction) return v;
|
|
2778
|
-
if (typeof v === "number" || typeof v === "bigint") return new Fraction(v);
|
|
2779
|
-
return new Fraction(number(v));
|
|
2780
|
-
}
|
|
2781
|
-
function addScalar(x, y) {
|
|
2782
|
-
if (typeof x === "number" && typeof y === "number") return x + y;
|
|
2783
|
-
if (typeof x === "bigint" && typeof y === "bigint") return x + y;
|
|
2784
|
-
if (isPrimitive(x) && isPrimitive(y)) return Number(x) + Number(y);
|
|
2785
|
-
if (x instanceof Complex || y instanceof Complex) return asComplex(x).add(asComplex(y));
|
|
2786
|
-
if (x instanceof BigNumber || y instanceof BigNumber) return asBigNumber(x).add(asBigNumber(y));
|
|
2787
|
-
return asFraction(x).add(asFraction(y));
|
|
2788
|
-
}
|
|
2789
|
-
function subtractScalar(x, y) {
|
|
2790
|
-
if (typeof x === "number" && typeof y === "number") return x - y;
|
|
2791
|
-
if (typeof x === "bigint" && typeof y === "bigint") return x - y;
|
|
2792
|
-
if (isPrimitive(x) && isPrimitive(y)) return Number(x) - Number(y);
|
|
2793
|
-
if (x instanceof Complex || y instanceof Complex) return asComplex(x).subtract(asComplex(y));
|
|
2794
|
-
if (x instanceof BigNumber || y instanceof BigNumber)
|
|
2795
|
-
return asBigNumber(x).subtract(asBigNumber(y));
|
|
2796
|
-
return asFraction(x).subtract(asFraction(y));
|
|
2797
|
-
}
|
|
2798
|
-
function multiplyScalar(x, y) {
|
|
2799
|
-
if (typeof x === "number" && typeof y === "number") return x * y;
|
|
2800
|
-
if (typeof x === "bigint" && typeof y === "bigint") return x * y;
|
|
2801
|
-
if (isPrimitive(x) && isPrimitive(y)) return Number(x) * Number(y);
|
|
2802
|
-
if (x instanceof Complex || y instanceof Complex) return asComplex(x).multiply(asComplex(y));
|
|
2803
|
-
if (x instanceof BigNumber || y instanceof BigNumber)
|
|
2804
|
-
return asBigNumber(x).multiply(asBigNumber(y));
|
|
2805
|
-
return asFraction(x).multiply(asFraction(y));
|
|
2806
|
-
}
|
|
2807
|
-
function divideScalar(x, y) {
|
|
2808
|
-
if (typeof x === "number" && typeof y === "number") return x / y;
|
|
2809
|
-
if (typeof x === "bigint" && typeof y === "bigint") return x / y;
|
|
2810
|
-
if (isPrimitive(x) && isPrimitive(y)) return Number(x) / Number(y);
|
|
2811
|
-
if (x instanceof Complex || y instanceof Complex) return asComplex(x).divide(asComplex(y));
|
|
2812
|
-
if (x instanceof BigNumber || y instanceof BigNumber)
|
|
2813
|
-
return asBigNumber(x).divide(asBigNumber(y));
|
|
2814
|
-
return asFraction(x).divide(asFraction(y));
|
|
2815
|
-
}
|
|
2816
|
-
function pow(base, exp) {
|
|
2817
|
-
if (base instanceof Complex) return base.pow(exp instanceof Complex ? exp : number(exp));
|
|
2818
|
-
if (base instanceof BigNumber || base instanceof Fraction) {
|
|
2819
|
-
const n = typeof exp === "bigint" ? exp : number(exp);
|
|
2820
|
-
if (typeof n === "bigint" || Number.isInteger(n)) return base.pow(n);
|
|
2821
|
-
return Math.pow(number(base), n);
|
|
2591
|
+
/**
|
|
2592
|
+
* Tangent of this BigNumber (in radians)
|
|
2593
|
+
* tan(x) = sin(x) / cos(x)
|
|
2594
|
+
*/
|
|
2595
|
+
tan() {
|
|
2596
|
+
if (this._isNaN) return this;
|
|
2597
|
+
if (this._isInfinite) return new _BigNumber(0, 0n, 0, true);
|
|
2598
|
+
if (this._sign === 0) return this;
|
|
2599
|
+
const x = this._reduceAngle();
|
|
2600
|
+
return x._sinTaylor().divide(x._cosTaylor());
|
|
2822
2601
|
}
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
}
|
|
2837
|
-
|
|
2838
|
-
if (typeof x === "number") return Math.round(x);
|
|
2839
|
-
if (typeof x === "bigint") return x;
|
|
2840
|
-
if (x instanceof Complex) return new Complex(Math.round(x.re), Math.round(x.im));
|
|
2841
|
-
if (x instanceof BigNumber) return x.round(0, "halfCeil");
|
|
2842
|
-
return x.round();
|
|
2843
|
-
}
|
|
2844
|
-
function equal(x, y, relTol = DEFAULT_CONFIG.relTol, absTol = DEFAULT_CONFIG.absTol) {
|
|
2845
|
-
if (typeof x === "bigint" && typeof y === "bigint") return x === y;
|
|
2846
|
-
if (isPrimitive(x) && isPrimitive(y)) return nearlyEqual(Number(x), Number(y), relTol, absTol);
|
|
2847
|
-
if (x instanceof Complex || y instanceof Complex) return asComplex(x).equals(asComplex(y));
|
|
2848
|
-
if (x instanceof Fraction && y instanceof Fraction) return x.equals(y);
|
|
2849
|
-
if (x instanceof BigNumber && y instanceof BigNumber) return x.equals(y);
|
|
2850
|
-
return nearlyEqual(number(x), number(y), relTol, absTol);
|
|
2851
|
-
}
|
|
2852
|
-
function isNumeric(x) {
|
|
2853
|
-
return typeof x === "number" || typeof x === "bigint" || typeof x === "boolean" || x instanceof Fraction || x instanceof BigNumber;
|
|
2854
|
-
}
|
|
2855
|
-
function number(x) {
|
|
2856
|
-
if (typeof x === "number") return x;
|
|
2857
|
-
if (typeof x === "bigint") return Number(x);
|
|
2858
|
-
if (x instanceof Fraction) return x.toNumber();
|
|
2859
|
-
if (x instanceof BigNumber) return x.toNumber();
|
|
2860
|
-
if (x.im !== 0) {
|
|
2861
|
-
throw new TypeError(`Cannot convert ${x.toString()} to a number: imaginary part is nonzero`);
|
|
2602
|
+
/**
|
|
2603
|
+
* Arcsine of this BigNumber
|
|
2604
|
+
* Returns value in [-PI/2, PI/2]
|
|
2605
|
+
*/
|
|
2606
|
+
asin() {
|
|
2607
|
+
if (this._isNaN) return this;
|
|
2608
|
+
const one = _BigNumber.fromNumber(1);
|
|
2609
|
+
if (this.abs().compareTo(one) > 0) return new _BigNumber(0, 0n, 0, true);
|
|
2610
|
+
if (this._sign === 0) return this;
|
|
2611
|
+
const xSquared = this.multiply(this);
|
|
2612
|
+
const denominator = one.subtract(xSquared).sqrt();
|
|
2613
|
+
if (denominator.isZero()) {
|
|
2614
|
+
return this._sign === 1 ? BIGNUMBER_PI.divide(2) : BIGNUMBER_PI.divide(-2);
|
|
2615
|
+
}
|
|
2616
|
+
return this.divide(denominator).atan();
|
|
2862
2617
|
}
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2618
|
+
/**
|
|
2619
|
+
* Arccosine of this BigNumber
|
|
2620
|
+
* Returns value in [0, PI]
|
|
2621
|
+
*/
|
|
2622
|
+
acos() {
|
|
2623
|
+
if (this._isNaN) return this;
|
|
2624
|
+
const one = _BigNumber.fromNumber(1);
|
|
2625
|
+
if (this.abs().compareTo(one) > 0) return new _BigNumber(0, 0n, 0, true);
|
|
2626
|
+
return BIGNUMBER_PI.divide(2).subtract(this.asin());
|
|
2627
|
+
}
|
|
2628
|
+
/**
|
|
2629
|
+
* Arctangent of this BigNumber
|
|
2630
|
+
* Returns value in (-PI/2, PI/2)
|
|
2631
|
+
* Uses Taylor series with argument reduction for convergence.
|
|
2632
|
+
*/
|
|
2633
|
+
atan() {
|
|
2634
|
+
if (this._isNaN) return this;
|
|
2635
|
+
if (this._sign === 0) return this;
|
|
2636
|
+
if (this._isInfinite) {
|
|
2637
|
+
return this._sign === 1 ? BIGNUMBER_PI.divide(2) : BIGNUMBER_PI.divide(-2);
|
|
2881
2638
|
}
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
const memoized = function(...args) {
|
|
2888
|
-
if (!(memoized.cache instanceof Map)) {
|
|
2889
|
-
memoized.cache = /* @__PURE__ */ new Map();
|
|
2639
|
+
const one = _BigNumber.fromNumber(1);
|
|
2640
|
+
if (this.abs().compareTo(one) > 0) {
|
|
2641
|
+
const reciprocal = one.divide(this);
|
|
2642
|
+
const piHalf = BIGNUMBER_PI.divide(2);
|
|
2643
|
+
return this._sign === 1 ? piHalf.subtract(reciprocal.atan()) : piHalf.negate().subtract(reciprocal.atan());
|
|
2890
2644
|
}
|
|
2891
|
-
const
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
const
|
|
2895
|
-
|
|
2896
|
-
cache.set(key, value2);
|
|
2897
|
-
return value2;
|
|
2645
|
+
const half = _BigNumber.fromNumber(0.5);
|
|
2646
|
+
if (this.abs().compareTo(half) > 0) {
|
|
2647
|
+
const xSq = this.multiply(this);
|
|
2648
|
+
const reduced = this.divide(one.add(one.add(xSq).sqrt()));
|
|
2649
|
+
return reduced.atan().multiply(_BigNumber.fromNumber(2));
|
|
2898
2650
|
}
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2651
|
+
return this._atanTaylor();
|
|
2652
|
+
}
|
|
2653
|
+
/**
|
|
2654
|
+
* Two-argument arctangent: atan2(y, x)
|
|
2655
|
+
* this = y, argument = x
|
|
2656
|
+
* Returns angle in (-PI, PI]
|
|
2657
|
+
*/
|
|
2658
|
+
atan2(x) {
|
|
2659
|
+
if (this._isNaN || x._isNaN) return new _BigNumber(0, 0n, 0, true);
|
|
2660
|
+
if (this._sign === 0 && x._sign === 0) return _BigNumber.fromNumber(0);
|
|
2661
|
+
if (x._sign === 0) {
|
|
2662
|
+
return this._sign === 1 ? BIGNUMBER_PI.divide(2) : BIGNUMBER_PI.divide(-2);
|
|
2663
|
+
}
|
|
2664
|
+
const angle = this.divide(x).atan();
|
|
2665
|
+
if (x.isPositive()) {
|
|
2666
|
+
return angle;
|
|
2667
|
+
} else if (this.isNegative()) {
|
|
2668
|
+
return angle.subtract(BIGNUMBER_PI);
|
|
2669
|
+
} else {
|
|
2670
|
+
return angle.add(BIGNUMBER_PI);
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
// ============================================================
|
|
2674
|
+
// Hyperbolic Functions
|
|
2675
|
+
// ============================================================
|
|
2676
|
+
/**
|
|
2677
|
+
* Hyperbolic sine: sinh(x) = (e^x - e^(-x)) / 2
|
|
2678
|
+
*/
|
|
2679
|
+
sinh() {
|
|
2680
|
+
if (this._isNaN) return this;
|
|
2681
|
+
if (this._isInfinite) return this;
|
|
2682
|
+
if (this._sign === 0) return this;
|
|
2683
|
+
const ex = this.exp();
|
|
2684
|
+
const enx = this.negate().exp();
|
|
2685
|
+
return ex.subtract(enx).divide(_BigNumber.fromNumber(2));
|
|
2686
|
+
}
|
|
2687
|
+
/**
|
|
2688
|
+
* Hyperbolic cosine: cosh(x) = (e^x + e^(-x)) / 2
|
|
2689
|
+
*/
|
|
2690
|
+
cosh() {
|
|
2691
|
+
if (this._isNaN) return this;
|
|
2692
|
+
if (this._isInfinite) return new _BigNumber(1, 0n, 0, false, true);
|
|
2693
|
+
if (this._sign === 0) return _BigNumber.fromNumber(1);
|
|
2694
|
+
const ex = this.exp();
|
|
2695
|
+
const enx = this.negate().exp();
|
|
2696
|
+
return ex.add(enx).divide(_BigNumber.fromNumber(2));
|
|
2697
|
+
}
|
|
2698
|
+
/**
|
|
2699
|
+
* Hyperbolic tangent: tanh(x) = sinh(x) / cosh(x)
|
|
2700
|
+
*/
|
|
2701
|
+
tanh() {
|
|
2702
|
+
if (this._isNaN) return this;
|
|
2703
|
+
if (this._sign === 0) return this;
|
|
2704
|
+
if (this._isInfinite) return _BigNumber.fromNumber(this._sign);
|
|
2705
|
+
const ex = this.exp();
|
|
2706
|
+
const enx = this.negate().exp();
|
|
2707
|
+
return ex.subtract(enx).divide(ex.add(enx));
|
|
2708
|
+
}
|
|
2709
|
+
/**
|
|
2710
|
+
* Inverse hyperbolic sine: asinh(x) = ln(x + sqrt(x^2 + 1))
|
|
2711
|
+
*/
|
|
2712
|
+
asinh() {
|
|
2713
|
+
if (this._isNaN) return this;
|
|
2714
|
+
if (this._isInfinite) return this;
|
|
2715
|
+
if (this._sign === 0) return this;
|
|
2716
|
+
const one = _BigNumber.fromNumber(1);
|
|
2717
|
+
return this.add(this.multiply(this).add(one).sqrt()).ln();
|
|
2718
|
+
}
|
|
2719
|
+
/**
|
|
2720
|
+
* Inverse hyperbolic cosine: acosh(x) = ln(x + sqrt(x^2 - 1))
|
|
2721
|
+
* Domain: x >= 1
|
|
2722
|
+
*/
|
|
2723
|
+
acosh() {
|
|
2724
|
+
if (this._isNaN) return this;
|
|
2725
|
+
const one = _BigNumber.fromNumber(1);
|
|
2726
|
+
if (this.compareTo(one) < 0) return new _BigNumber(0, 0n, 0, true);
|
|
2727
|
+
if (this._isInfinite) return this;
|
|
2728
|
+
return this.add(this.multiply(this).subtract(one).sqrt()).ln();
|
|
2729
|
+
}
|
|
2730
|
+
/**
|
|
2731
|
+
* Inverse hyperbolic tangent: atanh(x) = 0.5 * ln((1+x)/(1-x))
|
|
2732
|
+
* Domain: -1 < x < 1
|
|
2733
|
+
*/
|
|
2734
|
+
atanh() {
|
|
2735
|
+
if (this._isNaN) return this;
|
|
2736
|
+
const one = _BigNumber.fromNumber(1);
|
|
2737
|
+
const absVal = this.abs();
|
|
2738
|
+
if (absVal.compareTo(one) > 0) return new _BigNumber(0, 0n, 0, true);
|
|
2739
|
+
if (absVal.equals(one)) {
|
|
2740
|
+
return this._sign === 1 ? new _BigNumber(1, 0n, 0, false, true) : new _BigNumber(-1, 0n, 0, false, true);
|
|
2741
|
+
}
|
|
2742
|
+
if (this._sign === 0) return this;
|
|
2743
|
+
const half = _BigNumber.fromNumber(0.5);
|
|
2744
|
+
return one.add(this).divide(one.subtract(this)).ln().multiply(half);
|
|
2745
|
+
}
|
|
2746
|
+
// ============================================================
|
|
2747
|
+
// Transcendental Functions
|
|
2748
|
+
// ============================================================
|
|
2749
|
+
/**
|
|
2750
|
+
* Exponential function: e^x
|
|
2751
|
+
* Uses Taylor series: e^x = 1 + x + x^2/2! + x^3/3! + ...
|
|
2752
|
+
* With argument reduction: e^x = (e^(x/2^k))^(2^k) for faster convergence.
|
|
2753
|
+
*/
|
|
2754
|
+
exp() {
|
|
2755
|
+
if (this._isNaN) return this;
|
|
2756
|
+
if (this._sign === 0) return _BigNumber.fromNumber(1);
|
|
2757
|
+
if (this._isInfinite) {
|
|
2758
|
+
return this._sign === 1 ? this : _BigNumber.fromNumber(0);
|
|
2759
|
+
}
|
|
2760
|
+
const precision = globalConfig.precision;
|
|
2761
|
+
const val = Math.abs(this.valueOf());
|
|
2762
|
+
let k = 0;
|
|
2763
|
+
if (val > 0.5) {
|
|
2764
|
+
k = Math.ceil(Math.log2(val * 2));
|
|
2765
|
+
}
|
|
2766
|
+
const divisor = _BigNumber.fromNumber(2).pow(k);
|
|
2767
|
+
const reduced = this.divide(divisor);
|
|
2768
|
+
let sum = _BigNumber.fromNumber(1);
|
|
2769
|
+
let term = _BigNumber.fromNumber(1);
|
|
2770
|
+
const maxIter = precision + 20;
|
|
2771
|
+
for (let n = 1; n <= maxIter; n++) {
|
|
2772
|
+
term = term.multiply(reduced).divide(_BigNumber.fromNumber(n));
|
|
2773
|
+
const newSum = sum.add(term);
|
|
2774
|
+
if (sum.equals(newSum)) break;
|
|
2775
|
+
sum = newSum;
|
|
2776
|
+
}
|
|
2777
|
+
for (let i = 0; i < k; i++) {
|
|
2778
|
+
sum = sum.multiply(sum);
|
|
2779
|
+
}
|
|
2780
|
+
return sum.roundToPrecision(precision);
|
|
2781
|
+
}
|
|
2782
|
+
/**
|
|
2783
|
+
* Natural logarithm: ln(x)
|
|
2784
|
+
* Uses the AGM (arithmetic-geometric mean) method for fast convergence.
|
|
2785
|
+
* Fallback: series ln((1+y)/(1-y)) = 2*(y + y^3/3 + y^5/5 + ...) where y = (x-1)/(x+1)
|
|
2786
|
+
*/
|
|
2787
|
+
ln() {
|
|
2788
|
+
if (this._isNaN) return this;
|
|
2789
|
+
if (this._sign === -1) return new _BigNumber(0, 0n, 0, true);
|
|
2790
|
+
if (this._sign === 0) return new _BigNumber(-1, 0n, 0, false, true);
|
|
2791
|
+
if (this._isInfinite) return this;
|
|
2792
|
+
const one = _BigNumber.fromNumber(1);
|
|
2793
|
+
if (this.equals(one)) return _BigNumber.fromNumber(0);
|
|
2794
|
+
const precision = globalConfig.precision;
|
|
2795
|
+
let x = this.clone();
|
|
2796
|
+
let k = 0;
|
|
2797
|
+
const two = _BigNumber.fromNumber(2);
|
|
2798
|
+
const half = _BigNumber.fromNumber(0.5);
|
|
2799
|
+
while (x.compareTo(two) > 0) {
|
|
2800
|
+
x = x.divide(two);
|
|
2801
|
+
k++;
|
|
2802
|
+
}
|
|
2803
|
+
while (x.compareTo(half) < 0) {
|
|
2804
|
+
x = x.multiply(two);
|
|
2805
|
+
k--;
|
|
2806
|
+
}
|
|
2807
|
+
const y = x.subtract(one).divide(x.add(one));
|
|
2808
|
+
const ySq = y.multiply(y);
|
|
2809
|
+
let term = y;
|
|
2810
|
+
let sum = y;
|
|
2811
|
+
const maxIter = precision + 20;
|
|
2812
|
+
for (let n = 1; n <= maxIter; n++) {
|
|
2813
|
+
term = term.multiply(ySq);
|
|
2814
|
+
const contribution = term.divide(_BigNumber.fromNumber(2 * n + 1));
|
|
2815
|
+
const newSum = sum.add(contribution);
|
|
2816
|
+
if (sum.equals(newSum)) break;
|
|
2817
|
+
sum = newSum;
|
|
2818
|
+
}
|
|
2819
|
+
sum = sum.multiply(two);
|
|
2820
|
+
if (k !== 0) {
|
|
2821
|
+
sum = sum.add(BIGNUMBER_LN2.multiply(_BigNumber.fromNumber(k)));
|
|
2822
|
+
}
|
|
2823
|
+
return sum.roundToPrecision(precision);
|
|
2824
|
+
}
|
|
2825
|
+
/**
|
|
2826
|
+
* Base-10 logarithm: log10(x) = ln(x) / ln(10)
|
|
2827
|
+
*/
|
|
2828
|
+
log10() {
|
|
2829
|
+
return this.ln().divide(BIGNUMBER_LN10);
|
|
2830
|
+
}
|
|
2831
|
+
/**
|
|
2832
|
+
* Base-2 logarithm: log2(x) = ln(x) / ln(2)
|
|
2833
|
+
*/
|
|
2834
|
+
log2() {
|
|
2835
|
+
return this.ln().divide(BIGNUMBER_LN2);
|
|
2836
|
+
}
|
|
2837
|
+
/**
|
|
2838
|
+
* Cube root
|
|
2839
|
+
* Uses Newton-Raphson iteration.
|
|
2840
|
+
*/
|
|
2841
|
+
cbrt() {
|
|
2842
|
+
if (this._isNaN) return this;
|
|
2843
|
+
if (this._sign === 0) return this;
|
|
2844
|
+
if (this._isInfinite) return this;
|
|
2845
|
+
if (this._sign === -1) {
|
|
2846
|
+
return this.negate().cbrt().negate();
|
|
2847
|
+
}
|
|
2848
|
+
const precision = globalConfig.precision;
|
|
2849
|
+
const three = _BigNumber.fromNumber(3);
|
|
2850
|
+
let guess = _BigNumber.fromNumber(Math.cbrt(this.valueOf()));
|
|
2851
|
+
for (let i = 0; i < 100; i++) {
|
|
2852
|
+
const guessSquared = guess.multiply(guess);
|
|
2853
|
+
const newGuess = guess.multiply(_BigNumber.fromNumber(2)).add(this.divide(guessSquared)).divide(three);
|
|
2854
|
+
if (guess.subtract(newGuess).abs().compareTo(guess.abs().multiply(_BigNumber.parse("1e-" + (precision + 5)))) <= 0) {
|
|
2855
|
+
return newGuess.roundToPrecision(precision);
|
|
2856
|
+
}
|
|
2857
|
+
guess = newGuess;
|
|
2858
|
+
}
|
|
2859
|
+
return guess.roundToPrecision(precision);
|
|
2860
|
+
}
|
|
2861
|
+
/**
|
|
2862
|
+
* e^x - 1 (more precise than exp(x) - 1 for small x)
|
|
2863
|
+
* Uses Taylor series directly: expm1(x) = x + x^2/2! + x^3/3! + ...
|
|
2864
|
+
*/
|
|
2865
|
+
expm1() {
|
|
2866
|
+
if (this._isNaN) return this;
|
|
2867
|
+
if (this._sign === 0) return this;
|
|
2868
|
+
if (this._isInfinite) {
|
|
2869
|
+
return this._sign === 1 ? this : _BigNumber.fromNumber(-1);
|
|
2870
|
+
}
|
|
2871
|
+
if (Math.abs(this.valueOf()) > 0.5) {
|
|
2872
|
+
return this.exp().subtract(_BigNumber.fromNumber(1));
|
|
2873
|
+
}
|
|
2874
|
+
const precision = globalConfig.precision;
|
|
2875
|
+
let term = this.clone();
|
|
2876
|
+
let sum = this.clone();
|
|
2877
|
+
const maxIter = precision + 20;
|
|
2878
|
+
for (let n = 2; n <= maxIter; n++) {
|
|
2879
|
+
term = term.multiply(this).divide(_BigNumber.fromNumber(n));
|
|
2880
|
+
const newSum = sum.add(term);
|
|
2881
|
+
if (sum.equals(newSum)) break;
|
|
2882
|
+
sum = newSum;
|
|
2883
|
+
}
|
|
2884
|
+
return sum.roundToPrecision(precision);
|
|
2885
|
+
}
|
|
2886
|
+
/**
|
|
2887
|
+
* ln(1 + x) (more precise than ln(1 + x) for small x)
|
|
2888
|
+
*/
|
|
2889
|
+
log1p() {
|
|
2890
|
+
if (this._isNaN) return this;
|
|
2891
|
+
const one = _BigNumber.fromNumber(1);
|
|
2892
|
+
const negOne = _BigNumber.fromNumber(-1);
|
|
2893
|
+
if (this.compareTo(negOne) < 0) return new _BigNumber(0, 0n, 0, true);
|
|
2894
|
+
if (this.equals(negOne)) return new _BigNumber(-1, 0n, 0, false, true);
|
|
2895
|
+
if (this._sign === 0) return this;
|
|
2896
|
+
return one.add(this).ln();
|
|
2897
|
+
}
|
|
2898
|
+
/**
|
|
2899
|
+
* Hypotenuse: sqrt(this^2 + other^2)
|
|
2900
|
+
*/
|
|
2901
|
+
hypot(other) {
|
|
2902
|
+
if (this._isNaN || other._isNaN) return new _BigNumber(0, 0n, 0, true);
|
|
2903
|
+
if (this._isInfinite || other._isInfinite) return new _BigNumber(1, 0n, 0, false, true);
|
|
2904
|
+
return this.multiply(this).add(other.multiply(other)).sqrt();
|
|
2905
|
+
}
|
|
2906
|
+
// ============================================================
|
|
2907
|
+
// Private Taylor Series Helpers
|
|
2908
|
+
// ============================================================
|
|
2909
|
+
/** Reduce angle to [-PI, PI] range */
|
|
2910
|
+
_reduceAngle() {
|
|
2911
|
+
const twoPi = BIGNUMBER_PI.multiply(_BigNumber.fromNumber(2));
|
|
2912
|
+
if (this.abs().compareTo(BIGNUMBER_PI) <= 0) {
|
|
2913
|
+
return this;
|
|
2914
|
+
}
|
|
2915
|
+
const quotient = this.divide(twoPi).round(0, "halfUp");
|
|
2916
|
+
let reduced = this.subtract(twoPi.multiply(quotient));
|
|
2917
|
+
if (reduced.compareTo(BIGNUMBER_PI) > 0) {
|
|
2918
|
+
reduced = reduced.subtract(twoPi);
|
|
2919
|
+
} else if (reduced.compareTo(BIGNUMBER_PI.negate()) < 0) {
|
|
2920
|
+
reduced = reduced.add(twoPi);
|
|
2921
|
+
}
|
|
2922
|
+
return reduced;
|
|
2923
|
+
}
|
|
2924
|
+
/** Taylor series for sin(x), assumes x is in [-PI, PI] */
|
|
2925
|
+
_sinTaylor() {
|
|
2926
|
+
const precision = globalConfig.precision;
|
|
2927
|
+
let term = this.clone();
|
|
2928
|
+
let sum = this.clone();
|
|
2929
|
+
const xSquared = this.multiply(this);
|
|
2930
|
+
const maxIter = precision + 20;
|
|
2931
|
+
for (let n = 1; n <= maxIter; n++) {
|
|
2932
|
+
term = term.multiply(xSquared).divide(_BigNumber.fromNumber(2 * n * (2 * n + 1))).negate();
|
|
2933
|
+
const newSum = sum.add(term);
|
|
2934
|
+
if (sum.equals(newSum)) break;
|
|
2935
|
+
sum = newSum;
|
|
2936
|
+
}
|
|
2937
|
+
return sum.roundToPrecision(precision);
|
|
2938
|
+
}
|
|
2939
|
+
/** Taylor series for cos(x), assumes x is in [-PI, PI] */
|
|
2940
|
+
_cosTaylor() {
|
|
2941
|
+
const precision = globalConfig.precision;
|
|
2942
|
+
let term = _BigNumber.fromNumber(1);
|
|
2943
|
+
let sum = _BigNumber.fromNumber(1);
|
|
2944
|
+
const xSquared = this.multiply(this);
|
|
2945
|
+
const maxIter = precision + 20;
|
|
2946
|
+
for (let n = 1; n <= maxIter; n++) {
|
|
2947
|
+
term = term.multiply(xSquared).divide(_BigNumber.fromNumber((2 * n - 1) * (2 * n))).negate();
|
|
2948
|
+
const newSum = sum.add(term);
|
|
2949
|
+
if (sum.equals(newSum)) break;
|
|
2950
|
+
sum = newSum;
|
|
2951
|
+
}
|
|
2952
|
+
return sum.roundToPrecision(precision);
|
|
2953
|
+
}
|
|
2954
|
+
/** Taylor series for atan(x), assumes |x| <= 0.5 */
|
|
2955
|
+
_atanTaylor() {
|
|
2956
|
+
const precision = globalConfig.precision;
|
|
2957
|
+
const xSquared = this.multiply(this);
|
|
2958
|
+
let term = this.clone();
|
|
2959
|
+
let sum = this.clone();
|
|
2960
|
+
const maxIter = precision + 20;
|
|
2961
|
+
for (let n = 1; n <= maxIter; n++) {
|
|
2962
|
+
term = term.multiply(xSquared).negate();
|
|
2963
|
+
const contribution = term.divide(_BigNumber.fromNumber(2 * n + 1));
|
|
2964
|
+
const newSum = sum.add(contribution);
|
|
2965
|
+
if (sum.equals(newSum)) break;
|
|
2966
|
+
sum = newSum;
|
|
2903
2967
|
}
|
|
2904
|
-
return
|
|
2905
|
-
};
|
|
2906
|
-
return memoized;
|
|
2907
|
-
}
|
|
2908
|
-
|
|
2909
|
-
// src/object.ts
|
|
2910
|
-
function clone(x) {
|
|
2911
|
-
const type = typeof x;
|
|
2912
|
-
if (type === "number" || type === "bigint" || type === "string" || type === "boolean" || x === null || x === void 0) {
|
|
2913
|
-
return x;
|
|
2968
|
+
return sum.roundToPrecision(precision);
|
|
2914
2969
|
}
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2970
|
+
// ============================================================
|
|
2971
|
+
// Utility Methods
|
|
2972
|
+
// ============================================================
|
|
2973
|
+
isNaN() {
|
|
2974
|
+
return this._isNaN;
|
|
2918
2975
|
}
|
|
2919
|
-
|
|
2920
|
-
return
|
|
2976
|
+
isFinite() {
|
|
2977
|
+
return !this._isNaN && !this._isInfinite;
|
|
2921
2978
|
}
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
if (isObject(x)) {
|
|
2925
|
-
return mapObject(x, clone);
|
|
2979
|
+
isInfinite() {
|
|
2980
|
+
return this._isInfinite;
|
|
2926
2981
|
}
|
|
2927
|
-
|
|
2928
|
-
return
|
|
2982
|
+
isZero() {
|
|
2983
|
+
return this._sign === 0 && !this._isNaN;
|
|
2929
2984
|
}
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
function mapObject(object, callback) {
|
|
2933
|
-
const clone2 = {};
|
|
2934
|
-
for (const key in object) {
|
|
2935
|
-
if (hasOwnProperty(object, key)) {
|
|
2936
|
-
clone2[key] = callback(object[key]);
|
|
2937
|
-
}
|
|
2985
|
+
isPositive() {
|
|
2986
|
+
return this._sign === 1;
|
|
2938
2987
|
}
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
function extend(a, b) {
|
|
2942
|
-
const target = a;
|
|
2943
|
-
for (const prop in b) {
|
|
2944
|
-
if (hasOwnProperty(b, prop)) {
|
|
2945
|
-
target[prop] = b[prop];
|
|
2946
|
-
}
|
|
2988
|
+
isNegative() {
|
|
2989
|
+
return this._sign === -1;
|
|
2947
2990
|
}
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
if (Array.isArray(b)) {
|
|
2952
|
-
if (!Array.isArray(a)) {
|
|
2953
|
-
throw new TypeError("Cannot extend an object with an array");
|
|
2954
|
-
}
|
|
2955
|
-
for (let i = 0; i < b.length; i++) {
|
|
2956
|
-
const bValue = b[i];
|
|
2957
|
-
if (bValue && bValue.constructor === Object) {
|
|
2958
|
-
if (a[i] === void 0) {
|
|
2959
|
-
a[i] = {};
|
|
2960
|
-
}
|
|
2961
|
-
if (a[i] && a[i].constructor === Object) {
|
|
2962
|
-
deepExtend(a[i], bValue);
|
|
2963
|
-
} else {
|
|
2964
|
-
a[i] = bValue;
|
|
2965
|
-
}
|
|
2966
|
-
} else if (Array.isArray(bValue)) {
|
|
2967
|
-
if (a[i] === void 0) {
|
|
2968
|
-
a[i] = [];
|
|
2969
|
-
}
|
|
2970
|
-
if (Array.isArray(a[i])) {
|
|
2971
|
-
deepExtend(a[i], bValue);
|
|
2972
|
-
} else {
|
|
2973
|
-
a[i] = clone(bValue);
|
|
2974
|
-
}
|
|
2975
|
-
} else {
|
|
2976
|
-
a[i] = bValue;
|
|
2977
|
-
}
|
|
2978
|
-
}
|
|
2979
|
-
return a;
|
|
2991
|
+
isInteger() {
|
|
2992
|
+
if (this._isNaN || this._isInfinite || this._sign === 0) return this._sign === 0;
|
|
2993
|
+
return this._exponent >= 0;
|
|
2980
2994
|
}
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
const bValue = b[prop];
|
|
2984
|
-
const aValue = a[prop];
|
|
2985
|
-
if (bValue && bValue.constructor === Object) {
|
|
2986
|
-
if (aValue === void 0) {
|
|
2987
|
-
a[prop] = {};
|
|
2988
|
-
}
|
|
2989
|
-
if (aValue && aValue.constructor === Object) {
|
|
2990
|
-
deepExtend(aValue, bValue);
|
|
2991
|
-
} else {
|
|
2992
|
-
a[prop] = bValue;
|
|
2993
|
-
}
|
|
2994
|
-
} else if (Array.isArray(bValue)) {
|
|
2995
|
-
if (aValue === void 0) {
|
|
2996
|
-
a[prop] = [];
|
|
2997
|
-
}
|
|
2998
|
-
if (Array.isArray(aValue)) {
|
|
2999
|
-
deepExtend(aValue, bValue);
|
|
3000
|
-
} else {
|
|
3001
|
-
a[prop] = clone(bValue);
|
|
3002
|
-
}
|
|
3003
|
-
} else {
|
|
3004
|
-
a[prop] = bValue;
|
|
3005
|
-
}
|
|
3006
|
-
}
|
|
2995
|
+
sign() {
|
|
2996
|
+
return this._sign;
|
|
3007
2997
|
}
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
return false;
|
|
3038
|
-
}
|
|
2998
|
+
clone() {
|
|
2999
|
+
return new _BigNumber(
|
|
3000
|
+
this._sign,
|
|
3001
|
+
this._coefficient,
|
|
3002
|
+
this._exponent,
|
|
3003
|
+
this._isNaN,
|
|
3004
|
+
this._isInfinite
|
|
3005
|
+
);
|
|
3006
|
+
}
|
|
3007
|
+
// ============================================================
|
|
3008
|
+
// Private Helper Methods
|
|
3009
|
+
// ============================================================
|
|
3010
|
+
ensureBigNumber(value) {
|
|
3011
|
+
if (value instanceof _BigNumber) return value;
|
|
3012
|
+
if (typeof value === "number") return _BigNumber.fromNumber(value);
|
|
3013
|
+
if (typeof value === "string") return _BigNumber.parse(value);
|
|
3014
|
+
return _BigNumber.fromNumber(Number(value.valueOf()));
|
|
3015
|
+
}
|
|
3016
|
+
alignExponents(a, b) {
|
|
3017
|
+
const minExp = Math.min(a._exponent, b._exponent);
|
|
3018
|
+
const aShift = a._exponent - minExp;
|
|
3019
|
+
const bShift = b._exponent - minExp;
|
|
3020
|
+
const aCoef = aShift > 0 ? a._coefficient * BigInt(10) ** BigInt(aShift) : a._coefficient;
|
|
3021
|
+
const bCoef = bShift > 0 ? b._coefficient * BigInt(10) ** BigInt(bShift) : b._coefficient;
|
|
3022
|
+
return [aCoef, bCoef, minExp];
|
|
3023
|
+
}
|
|
3024
|
+
normalize(sign2, coefficient, exponent) {
|
|
3025
|
+
if (coefficient === 0n) {
|
|
3026
|
+
return new _BigNumber(0, 0n, 0);
|
|
3039
3027
|
}
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3028
|
+
let coef = coefficient;
|
|
3029
|
+
let exp = exponent;
|
|
3030
|
+
while (coef % 10n === 0n && coef !== 0n) {
|
|
3031
|
+
coef = coef / 10n;
|
|
3032
|
+
exp++;
|
|
3044
3033
|
}
|
|
3045
|
-
return
|
|
3046
|
-
} else {
|
|
3047
|
-
return a === b;
|
|
3034
|
+
return new _BigNumber(sign2, coef, exp);
|
|
3048
3035
|
}
|
|
3036
|
+
};
|
|
3037
|
+
var BIGNUMBER_ZERO = BigNumber.fromNumber(0);
|
|
3038
|
+
var BIGNUMBER_ONE = BigNumber.fromNumber(1);
|
|
3039
|
+
var BIGNUMBER_NEG_ONE = BigNumber.fromNumber(-1);
|
|
3040
|
+
var BIGNUMBER_TEN = BigNumber.fromNumber(10);
|
|
3041
|
+
var BIGNUMBER_PI = BigNumber.parse("3.14159265358979323846264338327950288419716939937510");
|
|
3042
|
+
var BIGNUMBER_E = BigNumber.parse("2.71828182845904523536028747135266249775724709369995");
|
|
3043
|
+
var BIGNUMBER_LN2 = BigNumber.parse(
|
|
3044
|
+
"0.69314718055994530941723212145817656807550013436026"
|
|
3045
|
+
);
|
|
3046
|
+
var BIGNUMBER_LN10 = BigNumber.parse(
|
|
3047
|
+
"2.30258509299404568401799145468436420760110148862877"
|
|
3048
|
+
);
|
|
3049
|
+
|
|
3050
|
+
// src/config.ts
|
|
3051
|
+
var DEFAULT_CONFIG = {
|
|
3052
|
+
// minimum relative difference between two compared values,
|
|
3053
|
+
// used by all comparison functions
|
|
3054
|
+
relTol: 1e-12,
|
|
3055
|
+
// minimum absolute difference between two compared values,
|
|
3056
|
+
// used by all comparison functions
|
|
3057
|
+
absTol: 1e-15,
|
|
3058
|
+
// type of default matrix output. Choose 'matrix' (default) or 'array'
|
|
3059
|
+
matrix: "Matrix",
|
|
3060
|
+
// type of default number output. Choose 'number' (default) 'BigNumber', 'bigint', or 'Fraction'
|
|
3061
|
+
number: "number",
|
|
3062
|
+
// type of fallback used for config { number: 'bigint' } when a value cannot be represented
|
|
3063
|
+
// in the configured numeric type. Choose 'number' (default) or 'BigNumber'.
|
|
3064
|
+
numberFallback: "number",
|
|
3065
|
+
// number of significant digits in BigNumbers
|
|
3066
|
+
precision: 64,
|
|
3067
|
+
// predictable output type of functions. When true, output type depends only
|
|
3068
|
+
// on the input types. When false (default), output type can vary depending
|
|
3069
|
+
// on input values. For example `math.sqrt(-4)` returns `complex('2i')` when
|
|
3070
|
+
// predictable is false, and returns `NaN` when true.
|
|
3071
|
+
predictable: false,
|
|
3072
|
+
// random seed for seeded pseudo random number generation
|
|
3073
|
+
// null = randomly seed
|
|
3074
|
+
randomSeed: null,
|
|
3075
|
+
// legacy behavior for matrix subset. When true, the subset function
|
|
3076
|
+
// returns a matrix or array with the same size as the index (except for scalars).
|
|
3077
|
+
// When false, it returns a matrix or array with a size depending on the type of index.
|
|
3078
|
+
legacySubset: false
|
|
3079
|
+
};
|
|
3080
|
+
|
|
3081
|
+
// src/arithmetic/scalar.ts
|
|
3082
|
+
function isPrimitive(v) {
|
|
3083
|
+
return typeof v === "number" || typeof v === "bigint";
|
|
3084
|
+
}
|
|
3085
|
+
function asComplex(v) {
|
|
3086
|
+
return v instanceof Complex ? v : new Complex(number(v), 0);
|
|
3087
|
+
}
|
|
3088
|
+
function asBigNumber(v) {
|
|
3089
|
+
if (v instanceof BigNumber) return v;
|
|
3090
|
+
if (typeof v === "bigint") return BigNumber.fromBigInt(v);
|
|
3091
|
+
return BigNumber.fromNumber(number(v));
|
|
3092
|
+
}
|
|
3093
|
+
function asFraction(v) {
|
|
3094
|
+
if (v instanceof Fraction) return v;
|
|
3095
|
+
if (typeof v === "number" || typeof v === "bigint") return new Fraction(v);
|
|
3096
|
+
return new Fraction(number(v));
|
|
3049
3097
|
}
|
|
3050
|
-
function
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
return
|
|
3098
|
+
function addScalar(x, y) {
|
|
3099
|
+
if (typeof x === "number" && typeof y === "number") return x + y;
|
|
3100
|
+
if (typeof x === "bigint" && typeof y === "bigint") return x + y;
|
|
3101
|
+
if (isPrimitive(x) && isPrimitive(y)) return Number(x) + Number(y);
|
|
3102
|
+
if (x instanceof Complex || y instanceof Complex) return asComplex(x).add(asComplex(y));
|
|
3103
|
+
if (x instanceof BigNumber || y instanceof BigNumber) return asBigNumber(x).add(asBigNumber(y));
|
|
3104
|
+
return asFraction(x).add(asFraction(y));
|
|
3054
3105
|
}
|
|
3055
|
-
function
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
}
|
|
3064
|
-
}
|
|
3065
|
-
}
|
|
3106
|
+
function subtractScalar(x, y) {
|
|
3107
|
+
if (typeof x === "number" && typeof y === "number") return x - y;
|
|
3108
|
+
if (typeof x === "bigint" && typeof y === "bigint") return x - y;
|
|
3109
|
+
if (isPrimitive(x) && isPrimitive(y)) return Number(x) - Number(y);
|
|
3110
|
+
if (x instanceof Complex || y instanceof Complex) return asComplex(x).subtract(asComplex(y));
|
|
3111
|
+
if (x instanceof BigNumber || y instanceof BigNumber)
|
|
3112
|
+
return asBigNumber(x).subtract(asBigNumber(y));
|
|
3113
|
+
return asFraction(x).subtract(asFraction(y));
|
|
3066
3114
|
}
|
|
3067
|
-
function
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
return true;
|
|
3076
|
-
}
|
|
3077
|
-
} catch {
|
|
3078
|
-
}
|
|
3079
|
-
return false;
|
|
3115
|
+
function multiplyScalar(x, y) {
|
|
3116
|
+
if (typeof x === "number" && typeof y === "number") return x * y;
|
|
3117
|
+
if (typeof x === "bigint" && typeof y === "bigint") return x * y;
|
|
3118
|
+
if (isPrimitive(x) && isPrimitive(y)) return Number(x) * Number(y);
|
|
3119
|
+
if (x instanceof Complex || y instanceof Complex) return asComplex(x).multiply(asComplex(y));
|
|
3120
|
+
if (x instanceof BigNumber || y instanceof BigNumber)
|
|
3121
|
+
return asBigNumber(x).multiply(asBigNumber(y));
|
|
3122
|
+
return asFraction(x).multiply(asFraction(y));
|
|
3080
3123
|
}
|
|
3081
|
-
function
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
}
|
|
3090
|
-
return _value;
|
|
3091
|
-
},
|
|
3092
|
-
set: function(value) {
|
|
3093
|
-
_value = value;
|
|
3094
|
-
_uninitialized = false;
|
|
3095
|
-
},
|
|
3096
|
-
configurable: true,
|
|
3097
|
-
enumerable: true
|
|
3098
|
-
});
|
|
3124
|
+
function divideScalar(x, y) {
|
|
3125
|
+
if (typeof x === "number" && typeof y === "number") return x / y;
|
|
3126
|
+
if (typeof x === "bigint" && typeof y === "bigint") return x / y;
|
|
3127
|
+
if (isPrimitive(x) && isPrimitive(y)) return Number(x) / Number(y);
|
|
3128
|
+
if (x instanceof Complex || y instanceof Complex) return asComplex(x).divide(asComplex(y));
|
|
3129
|
+
if (x instanceof BigNumber || y instanceof BigNumber)
|
|
3130
|
+
return asBigNumber(x).divide(asBigNumber(y));
|
|
3131
|
+
return asFraction(x).divide(asFraction(y));
|
|
3099
3132
|
}
|
|
3100
|
-
function
|
|
3101
|
-
if (
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
for (let i = 0; i < path.length; i++) {
|
|
3107
|
-
const key = path[i];
|
|
3108
|
-
if (!(key in obj)) {
|
|
3109
|
-
obj[key] = {};
|
|
3110
|
-
}
|
|
3111
|
-
obj = obj[key];
|
|
3112
|
-
}
|
|
3133
|
+
function pow(base, exp) {
|
|
3134
|
+
if (base instanceof Complex) return base.pow(exp instanceof Complex ? exp : number(exp));
|
|
3135
|
+
if (base instanceof BigNumber || base instanceof Fraction) {
|
|
3136
|
+
const n = typeof exp === "bigint" ? exp : number(exp);
|
|
3137
|
+
if (typeof n === "bigint" || Number.isInteger(n)) return base.pow(n);
|
|
3138
|
+
return Math.pow(number(base), n);
|
|
3113
3139
|
}
|
|
3114
|
-
return
|
|
3140
|
+
if (typeof base === "bigint" && typeof exp === "bigint") return base ** exp;
|
|
3141
|
+
return Math.pow(number(base), number(exp));
|
|
3115
3142
|
}
|
|
3116
|
-
function
|
|
3117
|
-
|
|
3143
|
+
function abs(x) {
|
|
3144
|
+
if (typeof x === "number") return Math.abs(x);
|
|
3145
|
+
if (typeof x === "bigint") return x < 0n ? -x : x;
|
|
3146
|
+
return x.abs();
|
|
3118
3147
|
}
|
|
3119
|
-
function
|
|
3120
|
-
if (typeof
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
return object[path];
|
|
3125
|
-
}
|
|
3126
|
-
}
|
|
3127
|
-
let child = object;
|
|
3128
|
-
for (let i = 0; i < path.length; i++) {
|
|
3129
|
-
const key = path[i];
|
|
3130
|
-
child = child ? child[key] : void 0;
|
|
3131
|
-
}
|
|
3132
|
-
return child;
|
|
3148
|
+
function fix(x) {
|
|
3149
|
+
if (typeof x === "number") return Math.trunc(x);
|
|
3150
|
+
if (typeof x === "bigint") return x;
|
|
3151
|
+
if (x instanceof Complex) return new Complex(Math.trunc(x.re), Math.trunc(x.im));
|
|
3152
|
+
return x.sign() >= 0 ? x.floor() : x.ceil();
|
|
3133
3153
|
}
|
|
3134
|
-
function
|
|
3135
|
-
if (typeof
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
return object;
|
|
3141
|
-
}
|
|
3142
|
-
}
|
|
3143
|
-
let child = object;
|
|
3144
|
-
for (let i = 0; i < path.length - 1; i++) {
|
|
3145
|
-
const key = path[i];
|
|
3146
|
-
if (child[key] === void 0) {
|
|
3147
|
-
child[key] = {};
|
|
3148
|
-
}
|
|
3149
|
-
child = child[key];
|
|
3150
|
-
}
|
|
3151
|
-
if (path.length > 0) {
|
|
3152
|
-
const lastKey = path[path.length - 1];
|
|
3153
|
-
child[lastKey] = value;
|
|
3154
|
-
}
|
|
3155
|
-
return object;
|
|
3154
|
+
function round(x) {
|
|
3155
|
+
if (typeof x === "number") return Math.round(x);
|
|
3156
|
+
if (typeof x === "bigint") return x;
|
|
3157
|
+
if (x instanceof Complex) return new Complex(Math.round(x.re), Math.round(x.im));
|
|
3158
|
+
if (x instanceof BigNumber) return x.round(0, "halfCeil");
|
|
3159
|
+
return x.round();
|
|
3156
3160
|
}
|
|
3157
|
-
function
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
}
|
|
3165
|
-
}
|
|
3166
|
-
return copy;
|
|
3161
|
+
function equal(x, y, relTol = DEFAULT_CONFIG.relTol, absTol = DEFAULT_CONFIG.absTol) {
|
|
3162
|
+
if (typeof x === "bigint" && typeof y === "bigint") return x === y;
|
|
3163
|
+
if (isPrimitive(x) && isPrimitive(y)) return nearlyEqual(Number(x), Number(y), relTol, absTol);
|
|
3164
|
+
if (x instanceof Complex || y instanceof Complex) return asComplex(x).equals(asComplex(y));
|
|
3165
|
+
if (x instanceof Fraction && y instanceof Fraction) return x.equals(y);
|
|
3166
|
+
if (x instanceof BigNumber && y instanceof BigNumber) return x.equals(y);
|
|
3167
|
+
return nearlyEqual(number(x), number(y), relTol, absTol);
|
|
3167
3168
|
}
|
|
3168
|
-
function
|
|
3169
|
-
|
|
3170
|
-
for (let i = 0; i < properties.length; i++) {
|
|
3171
|
-
const key = properties[i];
|
|
3172
|
-
const value = object[key];
|
|
3173
|
-
if (value !== void 0) {
|
|
3174
|
-
copy[key] = value;
|
|
3175
|
-
}
|
|
3176
|
-
}
|
|
3177
|
-
return copy;
|
|
3169
|
+
function isNumeric(x) {
|
|
3170
|
+
return typeof x === "number" || typeof x === "bigint" || typeof x === "boolean" || x instanceof Fraction || x instanceof BigNumber;
|
|
3178
3171
|
}
|
|
3179
|
-
function
|
|
3180
|
-
|
|
3172
|
+
function number(x) {
|
|
3173
|
+
if (typeof x === "number") return x;
|
|
3174
|
+
if (typeof x === "bigint") return Number(x);
|
|
3175
|
+
if (x instanceof Fraction) return x.toNumber();
|
|
3176
|
+
if (x instanceof BigNumber) return x.toNumber();
|
|
3177
|
+
if (x.im !== 0) {
|
|
3178
|
+
throw new TypeError(`Cannot convert ${x.toString()} to a number: imaginary part is nonzero`);
|
|
3179
|
+
}
|
|
3180
|
+
return x.re;
|
|
3181
3181
|
}
|
|
3182
3182
|
|
|
3183
3183
|
// src/types/unit/errors.ts
|
|
@@ -6263,29 +6263,11 @@ export {
|
|
|
6263
6263
|
COMPLEX_ZERO,
|
|
6264
6264
|
COMPLEX_ONE,
|
|
6265
6265
|
COMPLEX_NEG_ONE,
|
|
6266
|
-
isFraction,
|
|
6267
|
-
Fraction,
|
|
6268
|
-
FRACTION_ZERO,
|
|
6269
|
-
FRACTION_ONE,
|
|
6270
|
-
FRACTION_NEG_ONE,
|
|
6271
|
-
FRACTION_HALF,
|
|
6272
|
-
FRACTION_THIRD,
|
|
6273
|
-
FRACTION_QUARTER,
|
|
6274
|
-
isBigNumber,
|
|
6275
|
-
BigNumber,
|
|
6276
|
-
BIGNUMBER_ZERO,
|
|
6277
|
-
BIGNUMBER_ONE,
|
|
6278
|
-
BIGNUMBER_NEG_ONE,
|
|
6279
|
-
BIGNUMBER_TEN,
|
|
6280
|
-
BIGNUMBER_PI,
|
|
6281
|
-
BIGNUMBER_E,
|
|
6282
|
-
BIGNUMBER_LN2,
|
|
6283
|
-
BIGNUMBER_LN10,
|
|
6284
6266
|
isNumber,
|
|
6285
|
-
|
|
6267
|
+
isBigNumber,
|
|
6286
6268
|
isBigInt,
|
|
6287
6269
|
isComplex2,
|
|
6288
|
-
|
|
6270
|
+
isFraction,
|
|
6289
6271
|
isUnit,
|
|
6290
6272
|
isString,
|
|
6291
6273
|
isArray,
|
|
@@ -6330,17 +6312,6 @@ export {
|
|
|
6330
6312
|
tanh,
|
|
6331
6313
|
copysign,
|
|
6332
6314
|
isPowZeroAtInfinity,
|
|
6333
|
-
addScalar,
|
|
6334
|
-
subtractScalar,
|
|
6335
|
-
multiplyScalar,
|
|
6336
|
-
divideScalar,
|
|
6337
|
-
pow,
|
|
6338
|
-
abs,
|
|
6339
|
-
fix,
|
|
6340
|
-
round,
|
|
6341
|
-
equal,
|
|
6342
|
-
isNumeric,
|
|
6343
|
-
number,
|
|
6344
6315
|
hasOwnProperty,
|
|
6345
6316
|
endsWith,
|
|
6346
6317
|
warnOnce,
|
|
@@ -6359,6 +6330,36 @@ export {
|
|
|
6359
6330
|
set,
|
|
6360
6331
|
pick,
|
|
6361
6332
|
pickShallow,
|
|
6333
|
+
factory,
|
|
6334
|
+
isFraction2,
|
|
6335
|
+
Fraction,
|
|
6336
|
+
FRACTION_ZERO,
|
|
6337
|
+
FRACTION_ONE,
|
|
6338
|
+
FRACTION_NEG_ONE,
|
|
6339
|
+
FRACTION_HALF,
|
|
6340
|
+
FRACTION_THIRD,
|
|
6341
|
+
FRACTION_QUARTER,
|
|
6342
|
+
isBigNumber2,
|
|
6343
|
+
BigNumber,
|
|
6344
|
+
BIGNUMBER_ZERO,
|
|
6345
|
+
BIGNUMBER_ONE,
|
|
6346
|
+
BIGNUMBER_NEG_ONE,
|
|
6347
|
+
BIGNUMBER_TEN,
|
|
6348
|
+
BIGNUMBER_PI,
|
|
6349
|
+
BIGNUMBER_E,
|
|
6350
|
+
BIGNUMBER_LN2,
|
|
6351
|
+
BIGNUMBER_LN10,
|
|
6352
|
+
addScalar,
|
|
6353
|
+
subtractScalar,
|
|
6354
|
+
multiplyScalar,
|
|
6355
|
+
divideScalar,
|
|
6356
|
+
pow,
|
|
6357
|
+
abs,
|
|
6358
|
+
fix,
|
|
6359
|
+
round,
|
|
6360
|
+
equal,
|
|
6361
|
+
isNumeric,
|
|
6362
|
+
number,
|
|
6362
6363
|
UnitParseError,
|
|
6363
6364
|
DimensionMismatchError,
|
|
6364
6365
|
createUnitClass,
|