@danielsimonjr/mathts-core 0.5.0 → 0.6.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.
@@ -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/types/fraction.ts
557
- function isFraction(value) {
558
- return value instanceof Fraction;
556
+ // src/is.ts
557
+ function hasPrototypeFlag(x, flag) {
558
+ return !!x && x.constructor.prototype[flag] === true;
559
559
  }
560
- function gcd(a, b) {
561
- a = a < 0n ? -a : a;
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
- var Fraction = class _Fraction {
571
- type = "Fraction";
572
- numerator;
573
- denominator;
574
- constructor(numerator, denominator = 1n) {
575
- const toRatio = (x) => {
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
- * Create a Fraction from a decimal string
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
- * Parse a fraction from a string
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
- * Create a Fraction from a JSON object
676
- */
677
- static fromJSON(json) {
678
- if ("n" in json) {
679
- return new _Fraction(BigInt(json.n), BigInt(json.d));
680
- }
681
- return new _Fraction(BigInt(json.numerator), BigInt(json.denominator));
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
- * Compare two fractions
685
- * @returns -1, 0, or 1
686
- */
687
- static compare(a, b) {
688
- const diff = a.numerator * b.denominator - b.numerator * a.denominator;
689
- if (diff < 0n) return -1;
690
- if (diff > 0n) return 1;
691
- return 0;
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
- // Conversion Methods
695
- // ============================================================
696
- valueOf() {
697
- return Number(this.numerator) / Number(this.denominator);
652
+ return t;
653
+ }
654
+
655
+ // src/number.ts
656
+ function isInteger(value) {
657
+ if (typeof value === "boolean") {
658
+ return true;
698
659
  }
699
- toString() {
700
- if (this.denominator === 1n) {
701
- return this.numerator.toString();
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
- toJSON() {
706
- return {
707
- mathjs: "Fraction",
708
- n: this.numerator.toString(),
709
- d: this.denominator.toString()
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
- * Convert to number
714
- */
715
- toNumber() {
716
- return this.valueOf();
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
- * Convert to decimal string with specified precision
720
- */
721
- toDecimal(precision = 10) {
722
- const sign2 = this.numerator < 0n ? "-" : "";
723
- let num = this.numerator < 0n ? -this.numerator : this.numerator;
724
- const den = this.denominator;
725
- const intPart = num / den;
726
- num = num % den;
727
- if (num === 0n || precision === 0) {
728
- return sign2 + intPart.toString();
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
- let decPart = "";
731
- for (let i = 0; i < precision && num !== 0n; i++) {
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
- return sign2 + intPart.toString() + "." + decPart;
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
- const sign2 = this.numerator < 0n ? "-" : "";
746
- const absNum = this.numerator < 0n ? -this.numerator : this.numerator;
747
- return `${sign2}\\frac{${absNum}}{${this.denominator}}`;
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
- * Convert to mixed number representation
751
- */
752
- toMixed() {
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
- // Arithmetic Operations (Scalar interface)
765
- // ============================================================
766
- /**
767
- * Addition: a/b + c/d = (ad + bc) / bd
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
- * Subtraction: a/b - c/d = (ad - bc) / bd
779
- */
780
- subtract(other) {
781
- if (other instanceof _Fraction) {
782
- const num = this.numerator * other.denominator - other.numerator * this.denominator;
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
- * Multiplication: a/b * c/d = ac / bd
790
- */
791
- multiply(other) {
792
- if (other instanceof _Fraction) {
793
- return new _Fraction(this.numerator * other.numerator, this.denominator * other.denominator);
794
- }
795
- return this.multiply(_Fraction.fromNumber(Number(other.valueOf())));
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
- * Division: a/b ÷ c/d = ad / bc
799
- */
800
- divide(other) {
801
- if (other instanceof _Fraction) {
802
- if (other.numerator === 0n) {
803
- throw new Error("Division by zero");
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
- return new _Fraction(this.numerator * other.denominator, this.denominator * other.numerator);
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
- // Short-name aliases (mathjs Fraction API). Ported mathjs functions such as
810
- // multiplyScalar/subtractScalar/divideScalar call x.mul/x.sub/x.div; without
811
- // these, mixed number/Fraction dispatch (e.g. affine unit conversion like
812
- // celsius→fahrenheit) threw "x.mul is not a function".
813
- mul(other) {
814
- return this.multiply(other);
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
- sub(other) {
817
- return this.subtract(other);
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
- div(other) {
820
- return this.divide(other);
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
- * Negation: -(a/b) = -a/b
824
- */
825
- negate() {
826
- return new _Fraction(-this.numerator, this.denominator);
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
- * Absolute value: |a/b|
830
- */
831
- abs() {
832
- return new _Fraction(this.numerator < 0n ? -this.numerator : this.numerator, this.denominator);
847
+ let expDiff = Math.abs(e - newExp);
848
+ let decimalIdx = 1;
849
+ while (expDiff > 0) {
850
+ decimalIdx++;
851
+ expDiff--;
833
852
  }
834
- /**
835
- * Reciprocal: b/a
836
- */
837
- inverse() {
838
- if (this.numerator === 0n) {
839
- throw new Error("Cannot invert zero");
840
- }
841
- return new _Fraction(this.denominator, this.numerator);
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
- * Power (integer exponent)
845
- */
846
- pow(n) {
847
- const exp = typeof n === "bigint" ? n : BigInt(n);
848
- if (exp === 0n) {
849
- return new _Fraction(1n, 1n);
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
- * Modulo operation
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
- // Comparison Methods
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
- * Check if less than
885
- */
886
- lessThan(other) {
887
- return _Fraction.compare(this, other) < 0;
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
- * Check if less than or equal
891
- */
892
- lessThanOrEqual(other) {
893
- return _Fraction.compare(this, other) <= 0;
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
- * Check if greater than
897
- */
898
- greaterThan(other) {
899
- return _Fraction.compare(this, other) > 0;
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
- * Check if greater than or equal
903
- */
904
- greaterThanOrEqual(other) {
905
- return _Fraction.compare(this, other) >= 0;
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
- * Compare with another fraction
909
- * @returns -1, 0, or 1
910
- */
911
- compareTo(other) {
912
- return _Fraction.compare(this, other);
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
- compare(other) {
915
- return this.compareTo(other);
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
- // Utility Methods
919
- // ============================================================
920
- /**
921
- * Return fraction already in lowest terms (no-op since constructor reduces)
922
- */
923
- simplify() {
924
- return this;
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
- * Check if this is zero
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
- * Check if this is positive
934
- */
935
- isPositive() {
936
- return this.numerator > 0n;
970
+ if (isNaN(a) || isNaN(b)) {
971
+ return false;
937
972
  }
938
- /**
939
- * Check if this is negative
940
- */
941
- isNegative() {
942
- return this.numerator < 0n;
973
+ if (!isFinite(a) || !isFinite(b)) {
974
+ return a === b;
943
975
  }
944
- /**
945
- * Check if this is an integer
946
- */
947
- isInteger() {
948
- return this.denominator === 1n;
976
+ if (a === b) {
977
+ return true;
949
978
  }
950
- /**
951
- * Check if this is a unit fraction (1/n)
952
- */
953
- isUnit() {
954
- return this.numerator === 1n || this.numerator === -1n;
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
- * Floor: largest integer ≤ this
958
- */
959
- floor() {
960
- if (this.denominator === 1n) {
961
- return this;
962
- }
963
- const quot = this.numerator / this.denominator;
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
- * Ceiling: smallest integer ≥ this
971
- */
972
- ceil() {
973
- if (this.denominator === 1n) {
974
- return this;
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
- const quot = this.numerator / this.denominator;
977
- if (this.numerator <= 0n || this.numerator % this.denominator === 0n) {
978
- return new _Fraction(quot, 1n);
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
- return new _Fraction(quot + 1n, 1n);
981
- }
982
- /**
983
- * Round to nearest integer
984
- */
985
- round() {
986
- const floor = this.floor();
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
- return floor;
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
- * Truncate (round toward zero)
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
- * Get the sign: -1, 0, or 1
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
- * Clone this fraction
1010
- */
1011
- clone() {
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
- * Get the GCD of numerator and denominator (always 1 since we reduce)
1016
- */
1017
- gcd() {
1018
- return 1n;
1089
+ if (type === "function") {
1090
+ return x;
1019
1091
  }
1020
- /**
1021
- * Get continued fraction representation
1022
- */
1023
- toContinuedFraction() {
1024
- const result = [];
1025
- let num = this.numerator < 0n ? -this.numerator : this.numerator;
1026
- let den = this.denominator;
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
- * Create fraction from continued fraction
1040
- */
1041
- static fromContinuedFraction(cf) {
1042
- if (cf.length === 0) {
1043
- return new _Fraction(0n, 1n);
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
- var defaultConfig = {
1074
- precision: 64,
1075
- rounding: "halfUp",
1076
- minExponent: -1e9,
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
- if (n === 0) {
1118
- return new _BigNumber(0, 0n, 0);
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 _BigNumber.parse(n.toString());
1141
+ return a;
1121
1142
  }
1122
- /**
1123
- * Create a BigNumber from a string
1124
- */
1125
- static parse(str) {
1126
- str = str.trim().toLowerCase();
1127
- if (str === "nan") {
1128
- return new _BigNumber(0, 0n, 0, true, false);
1129
- }
1130
- if (str === "infinity" || str === "+infinity") {
1131
- return new _BigNumber(1, 0n, 0, false, true);
1132
- }
1133
- if (str === "-infinity") {
1134
- return new _BigNumber(-1, 0n, 0, false, true);
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
- let sign2 = 1;
1137
- if (str.startsWith("-")) {
1138
- sign2 = -1;
1139
- str = str.slice(1);
1140
- } else if (str.startsWith("+")) {
1141
- str = str.slice(1);
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
- let exponentPart = 0;
1144
- const eIndex = str.indexOf("e");
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
- const dotIndex = str.indexOf(".");
1150
- let coefficient;
1151
- let decimalPlaces = 0;
1152
- if (dotIndex !== -1) {
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
- coefficient = coefficient.replace(/^0+/, "") || "0";
1159
- if (coefficient === "0") {
1160
- return new _BigNumber(0, 0n, 0);
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
- let trailingZeros = 0;
1163
- for (let i = coefficient.length - 1; i >= 0; i--) {
1164
- if (coefficient[i] === "0") {
1165
- trailingZeros++;
1166
- } else {
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
- if (trailingZeros > 0) {
1171
- coefficient = coefficient.slice(0, -trailingZeros);
1202
+ for (prop in bObj) {
1203
+ if (!(prop in aObj)) {
1204
+ return false;
1205
+ }
1172
1206
  }
1173
- const finalExponent = exponentPart - decimalPlaces + trailingZeros;
1174
- return new _BigNumber(sign2, BigInt(coefficient), finalExponent);
1207
+ return true;
1208
+ } else {
1209
+ return a === b;
1175
1210
  }
1176
- /**
1177
- * Create from bigint
1178
- */
1179
- static fromBigInt(n) {
1180
- if (n === 0n) {
1181
- return new _BigNumber(0, 0n, 0);
1182
- }
1183
- const sign2 = n < 0n ? -1 : 1;
1184
- let str = (n < 0n ? -n : n).toString();
1185
- let trailingZeros = 0;
1186
- for (let i = str.length - 1; i >= 0; i--) {
1187
- if (str[i] === "0") {
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
- break;
1224
+ flattenedObject[prop] = value;
1191
1225
  }
1192
1226
  }
1193
- if (trailingZeros > 0) {
1194
- str = str.slice(0, -trailingZeros);
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
- return new _BigNumber(sign2, BigInt(str), trailingZeros);
1239
+ } catch {
1197
1240
  }
1198
- /**
1199
- * Create a BigNumber from a JSON object
1200
- */
1201
- static fromJSON(json) {
1202
- return _BigNumber.parse(json.value);
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
- * Get/set global configuration
1206
- */
1207
- static config(newConfig) {
1208
- if (newConfig) {
1209
- globalConfig = { ...globalConfig, ...newConfig };
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
- * Reset configuration to defaults
1215
- */
1216
- static resetConfig() {
1217
- globalConfig = { ...defaultConfig };
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
- * Compare two BigNumbers
1221
- * @returns -1, 0, or 1
1222
- */
1223
- static compare(a, b) {
1224
- if (a._isNaN || b._isNaN) return NaN;
1225
- if (a._isInfinite && b._isInfinite) {
1226
- if (a._sign === b._sign) return 0;
1227
- return a._sign > b._sign ? 1 : -1;
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
- static compareMagnitude(a, b) {
1239
- const aDigits = a._coefficient.toString();
1240
- const bDigits = b._coefficient.toString();
1241
- const aOrder = aDigits.length + a._exponent;
1242
- const bOrder = bDigits.length + b._exponent;
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
- const aFull = aDigits + "0".repeat(Math.max(0, a._exponent));
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
- // Conversion Methods
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
- toString() {
1270
- if (this._isNaN) return "NaN";
1271
- if (this._isInfinite) return this._sign === 1 ? "Infinity" : "-Infinity";
1272
- if (this._sign === 0) return "0";
1273
- const sign2 = this._sign === -1 ? "-" : "";
1274
- const digits2 = this._coefficient.toString();
1275
- if (this._exponent >= 0) {
1276
- return sign2 + digits2 + "0".repeat(this._exponent);
1277
- } else if (-this._exponent < digits2.length) {
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
- toJSON() {
1285
- return {
1286
- mathjs: "BigNumber",
1287
- value: this.toString()
1288
- };
1289
- }
1290
- /**
1291
- * Convert to fixed-point notation.
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
- toFixedInternal(decimalPlaces) {
1306
- if (this._isNaN) return "NaN";
1307
- if (this._isInfinite) return this._sign === 1 ? "Infinity" : "-Infinity";
1308
- const dp = decimalPlaces ?? -1;
1309
- const allDigits = dp < 0;
1310
- if (this._sign === 0) return allDigits ? "0" : dp > 0 ? "0." + "0".repeat(dp) : "0";
1311
- const sign2 = this._sign === -1 ? "-" : "";
1312
- const digits2 = this._coefficient.toString();
1313
- if (this._exponent >= 0) {
1314
- const intPart = digits2 + "0".repeat(this._exponent);
1315
- if (allDigits) return sign2 + intPart;
1316
- return sign2 + intPart + (dp > 0 ? "." + "0".repeat(dp) : "");
1317
- } else if (-this._exponent <= digits2.length) {
1318
- const insertPos = digits2.length + this._exponent;
1319
- const intPart = digits2.slice(0, insertPos) || "0";
1320
- const decPart = digits2.slice(insertPos);
1321
- if (allDigits) {
1322
- return sign2 + intPart + (decPart.length > 0 ? "." + decPart : "");
1323
- }
1324
- let paddedDec = decPart;
1325
- if (paddedDec.length < dp) {
1326
- paddedDec += "0".repeat(dp - paddedDec.length);
1327
- }
1328
- return sign2 + intPart + (dp > 0 ? "." + paddedDec.slice(0, dp) : "");
1329
- } else {
1330
- const leadingZeros = -this._exponent - digits2.length;
1331
- const decPart = "0".repeat(leadingZeros) + digits2;
1332
- if (allDigits) {
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
- let paddedDec = decPart;
1336
- if (paddedDec.length < dp) {
1337
- paddedDec += "0".repeat(dp - paddedDec.length);
1368
+ if (typeof x === "number" && !Number.isInteger(x)) {
1369
+ const f = _Fraction.fromNumber(x);
1370
+ return [f.numerator, f.denominator];
1338
1371
  }
1339
- return sign2 + "0" + (dp > 0 ? "." + paddedDec.slice(0, dp) : "");
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
- * Convert to exponential notation
1393
+ * Create a Fraction from a number (with optional precision)
1344
1394
  */
1345
- toExponential(decimalPlaces) {
1346
- if (this._isNaN) return "NaN";
1347
- if (this._isInfinite) return this._sign === 1 ? "Infinity" : "-Infinity";
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
- let decPart = digits2.slice(1);
1366
- if (decPart.length < decimalPlaces) {
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
- return `${sign2}${digits2[0]}.${decPart}e${expSign}${exp}`;
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
- * Convert to precision
1420
+ * Create a Fraction from a decimal string
1375
1421
  */
1376
- toPrecision(significantDigits) {
1377
- if (significantDigits === void 0) {
1378
- return this.toString();
1379
- }
1380
- if (this._isNaN) return "NaN";
1381
- if (this._isInfinite) return this._sign === 1 ? "Infinity" : "-Infinity";
1382
- if (this._sign === 0) {
1383
- return significantDigits > 1 ? "0." + "0".repeat(significantDigits - 1) : "0";
1384
- }
1385
- const digits2 = this._coefficient.toString();
1386
- const order = digits2.length + this._exponent;
1387
- if (order > significantDigits || order < -6) {
1388
- return this.toExponential(significantDigits - 1);
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
- return this.toFixed(significantDigits - order);
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
- * Convert to bigint (truncated)
1449
+ * Parse a fraction from a string
1450
+ * Supports formats: "3/4", "-3/4", "3", "3.14", "0.(3)"
1394
1451
  */
1395
- toBigInt() {
1396
- if (this._isNaN || this._isInfinite) {
1397
- throw new Error("Cannot convert NaN or Infinity to bigint");
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 (this._sign === 0) return 0n;
1400
- const digits2 = this._coefficient.toString();
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 0n;
1461
+ return new _Fraction(BigInt(str), 1n);
1407
1462
  }
1408
1463
  /**
1409
- * Binary string representation, e.g. `255 -> '0b11111111'`, `0.5 -> '0b0.1'`.
1410
- * Mirrors Decimal.js `toBinary()`. Negatives carry a leading `-`.
1464
+ * Create a Fraction from a JSON object
1411
1465
  */
1412
- toBinary() {
1413
- return this.toRadixString(2, "0b");
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
- * Octal string representation, e.g. `8 -> '0o10'`.
1417
- * Mirrors Decimal.js `toOctal()`.
1473
+ * Compare two fractions
1474
+ * @returns -1, 0, or 1
1418
1475
  */
1419
- toOctal() {
1420
- return this.toRadixString(8, "0o");
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
- * Hexadecimal string representation, e.g. `255 -> '0xff'`, `10.5 -> '0xa.8'`.
1424
- * Mirrors Decimal.js `toHexadecimal()`.
1425
- */
1426
- toHexadecimal() {
1427
- return this.toRadixString(16, "0x");
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
- * Shared radix formatter for {@link toBinary}/{@link toOctal}/{@link toHexadecimal}.
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
- toRadixString(radix, prefix, maxFractionDigits = 1100) {
1436
- if (this._isNaN) return "NaN";
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
- * Addition
1508
+ * Convert to decimal string with specified precision
1462
1509
  */
1463
- add(other) {
1464
- const b = this.ensureBigNumber(other);
1465
- if (this._isNaN || b._isNaN) return new _BigNumber(0, 0n, 0, true);
1466
- if (this._isInfinite && b._isInfinite) {
1467
- if (this._sign === b._sign) return this;
1468
- return new _BigNumber(0, 0n, 0, true);
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
- if (this._isInfinite) return this;
1471
- if (b._isInfinite) return b;
1472
- if (this._sign === 0) return b;
1473
- if (b._sign === 0) return this;
1474
- const [aCoef, bCoef, exp] = this.alignExponents(this, b);
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
- * Subtraction
1528
+ * Convert to LaTeX string
1488
1529
  */
1489
- subtract(other) {
1490
- const b = this.ensureBigNumber(other);
1491
- return this.add(b.negate());
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
- * Alias for subtract — mathjs / Decimal.js compatibility.
1539
+ * Convert to mixed number representation
1495
1540
  */
1496
- sub(other) {
1497
- return this.subtract(other);
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
- * Multiplication
1556
+ * Addition: a/b + c/d = (ad + bc) / bd
1501
1557
  */
1502
- multiply(other) {
1503
- const b = this.ensureBigNumber(other);
1504
- if (this._isNaN || b._isNaN) return new _BigNumber(0, 0n, 0, true);
1505
- if (this._isInfinite || b._isInfinite) {
1506
- if (this._sign === 0 || b._sign === 0) return new _BigNumber(0, 0n, 0, true);
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
- if (this._sign === 0 || b._sign === 0) return new _BigNumber(0, 0n, 0);
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
- * Alias for multiply — mathjs / Decimal.js compatibility.
1567
+ * Subtraction: a/b - c/d = (ad - bc) / bd
1518
1568
  */
1519
- mul(other) {
1520
- return this.multiply(other);
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
- * Alias for multiply — Decimal.js calling convention (used by the Unit).
1578
+ * Multiplication: a/b * c/d = ac / bd
1524
1579
  */
1525
- times(other) {
1526
- return this.multiply(other);
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
- const b = this.ensureBigNumber(other);
1533
- if (this._isNaN || b._isNaN) return new _BigNumber(0, 0n, 0, true);
1534
- if (this._isInfinite && b._isInfinite) return new _BigNumber(0, 0n, 0, true);
1535
- if (b._sign === 0) {
1536
- if (this._sign === 0) return new _BigNumber(0, 0n, 0, true);
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
- if (b._isInfinite) return new _BigNumber(0, 0n, 0);
1544
- if (this._sign === 0) return new _BigNumber(0, 0n, 0);
1545
- const sign2 = this._sign * b._sign;
1546
- const precision = globalConfig.precision;
1547
- const scale = BigInt(10) ** BigInt(precision + 10);
1548
- const scaledDividend = this._coefficient * scale;
1549
- const quotient = scaledDividend / b._coefficient;
1550
- const exponent = this._exponent - b._exponent - precision - 10;
1551
- return this.normalize(sign2, quotient, exponent).roundToPrecision(precision);
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
- if (this._isNaN) return this;
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
- if (this._isNaN) return this;
1573
- if (this._sign === 0) return this;
1574
- return new _BigNumber(1, this._coefficient, this._exponent, false, this._isInfinite);
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" ? Number(n) : n;
1581
- if (this._isNaN) return this;
1582
- if (exp === 0) return _BigNumber.fromNumber(1);
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 < 0) {
1588
- return _BigNumber.fromNumber(1).divide(this.pow(-exp));
1640
+ if (exp < 0n) {
1641
+ return this.inverse().pow(-exp);
1589
1642
  }
1590
- let result = _BigNumber.fromNumber(1);
1643
+ let result = new _Fraction(1n, 1n);
1591
1644
  let base = this.clone();
1592
1645
  let e = exp;
1593
- while (e > 0) {
1594
- if (e % 2 === 1) {
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 = Math.floor(e / 2);
1651
+ e = e / 2n;
1599
1652
  }
1600
- return result.roundToPrecision(globalConfig.precision);
1653
+ return result;
1601
1654
  }
1602
1655
  /**
1603
- * Square root
1656
+ * Modulo operation
1604
1657
  */
1605
- sqrt() {
1606
- if (this._isNaN) return this;
1607
- if (this._sign === -1) return new _BigNumber(0, 0n, 0, true);
1608
- if (this._sign === 0) return this;
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 _BigNumber.compare(this, other) === 0;
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 _BigNumber.compare(this, other) < 0;
1676
+ return _Fraction.compare(this, other) < 0;
1629
1677
  }
1678
+ /**
1679
+ * Check if less than or equal
1680
+ */
1630
1681
  lessThanOrEqual(other) {
1631
- return _BigNumber.compare(this, other) <= 0;
1682
+ return _Fraction.compare(this, other) <= 0;
1632
1683
  }
1684
+ /**
1685
+ * Check if greater than
1686
+ */
1633
1687
  greaterThan(other) {
1634
- return _BigNumber.compare(this, other) > 0;
1688
+ return _Fraction.compare(this, other) > 0;
1635
1689
  }
1690
+ /**
1691
+ * Check if greater than or equal
1692
+ */
1636
1693
  greaterThanOrEqual(other) {
1637
- return _BigNumber.compare(this, other) >= 0;
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 _BigNumber.compare(this, other);
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
- // Rounding Methods
1707
+ // Utility Methods
1655
1708
  // ============================================================
1656
1709
  /**
1657
- * Round to specified decimal places
1710
+ * Return fraction already in lowest terms (no-op since constructor reduces)
1658
1711
  */
1659
- round(decimalPlaces = 0, mode = globalConfig.rounding) {
1660
- if (this._isNaN || this._isInfinite || this._sign === 0) return this;
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
- * Round to specified precision (significant digits)
1716
+ * Check if this is zero
1704
1717
  */
1705
- roundToPrecision(precision, mode = globalConfig.rounding) {
1706
- if (this._isNaN || this._isInfinite || this._sign === 0) return this;
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
- trunc() {
1729
- return this.round(0, "down");
1721
+ /**
1722
+ * Check if this is positive
1723
+ */
1724
+ isPositive() {
1725
+ return this.numerator > 0n;
1730
1726
  }
1731
1727
  /**
1732
- * Round to `n` significant decimal digits and return a new BigNumber.
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
- toSignificantDigits(n, roundingMode) {
1740
- if (n === void 0) return this.clone();
1741
- return this.roundToPrecision(n, roundingMode ?? globalConfig.rounding);
1730
+ isNegative() {
1731
+ return this.numerator < 0n;
1742
1732
  }
1743
1733
  /**
1744
- * The decimal exponent of this number: `floor(log10(|x|))`.
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
- get e() {
1757
- if (this._isNaN || this._isInfinite || this._sign === 0) return 0;
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
- * Modulo (remainder after division)
1766
- * Result has the same sign as the dividend (this).
1740
+ * Check if this is a unit fraction (1/n)
1767
1741
  */
1768
- mod(other) {
1769
- const b = this.ensureBigNumber(other);
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
- * Sine of this BigNumber (in radians)
1782
- * Uses Taylor series: sin(x) = x - x^3/3! + x^5/5! - ...
1746
+ * Floor: largest integer ≤ this
1783
1747
  */
1784
- sin() {
1785
- if (this._isNaN) return this;
1786
- if (this._isInfinite) return new _BigNumber(0, 0n, 0, true);
1787
- if (this._sign === 0) return this;
1788
- const x = this._reduceAngle();
1789
- return x._sinTaylor();
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
- * Cosine of this BigNumber (in radians)
1793
- * Uses Taylor series: cos(x) = 1 - x^2/2! + x^4/4! - ...
1759
+ * Ceiling: smallest integer ≥ this
1794
1760
  */
1795
- cos() {
1796
- if (this._isNaN) return this;
1797
- if (this._isInfinite) return new _BigNumber(0, 0n, 0, true);
1798
- if (this._sign === 0) return _BigNumber.fromNumber(1);
1799
- const x = this._reduceAngle();
1800
- return x._cosTaylor();
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
- * Tangent of this BigNumber (in radians)
1804
- * tan(x) = sin(x) / cos(x)
1772
+ * Round to nearest integer
1805
1773
  */
1806
- tan() {
1807
- if (this._isNaN) return this;
1808
- if (this._isInfinite) return new _BigNumber(0, 0n, 0, true);
1809
- if (this._sign === 0) return this;
1810
- const x = this._reduceAngle();
1811
- return x._sinTaylor().divide(x._cosTaylor());
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
- * Arcsine of this BigNumber
1815
- * Returns value in [-PI/2, PI/2]
1784
+ * Truncate (round toward zero)
1816
1785
  */
1817
- asin() {
1818
- if (this._isNaN) return this;
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
- * Two-argument arctangent: atan2(y, x)
1866
- * this = y, argument = x
1867
- * Returns angle in (-PI, PI]
1790
+ * Get the sign: -1, 0, or 1
1868
1791
  */
1869
- atan2(x) {
1870
- if (this._isNaN || x._isNaN) return new _BigNumber(0, 0n, 0, true);
1871
- if (this._sign === 0 && x._sign === 0) return _BigNumber.fromNumber(0);
1872
- if (x._sign === 0) {
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
- * Hyperbolic sine: sinh(x) = (e^x - e^(-x)) / 2
1798
+ * Clone this fraction
1889
1799
  */
1890
- sinh() {
1891
- if (this._isNaN) return this;
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
- * Hyperbolic cosine: cosh(x) = (e^x + e^(-x)) / 2
1804
+ * Get the GCD of numerator and denominator (always 1 since we reduce)
1900
1805
  */
1901
- cosh() {
1902
- if (this._isNaN) return this;
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
- * Hyperbolic tangent: tanh(x) = sinh(x) / cosh(x)
1810
+ * Get continued fraction representation
1911
1811
  */
1912
- tanh() {
1913
- if (this._isNaN) return this;
1914
- if (this._sign === 0) return this;
1915
- if (this._isInfinite) return _BigNumber.fromNumber(this._sign);
1916
- const ex = this.exp();
1917
- const enx = this.negate().exp();
1918
- return ex.subtract(enx).divide(ex.add(enx));
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
- * Inverse hyperbolic sine: asinh(x) = ln(x + sqrt(x^2 + 1))
1828
+ * Create fraction from continued fraction
1922
1829
  */
1923
- asinh() {
1924
- if (this._isNaN) return this;
1925
- if (this._isInfinite) return this;
1926
- if (this._sign === 0) return this;
1927
- const one = _BigNumber.fromNumber(1);
1928
- return this.add(this.multiply(this).add(one).sqrt()).ln();
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
- * Inverse hyperbolic cosine: acosh(x) = ln(x + sqrt(x^2 - 1))
1932
- * Domain: x >= 1
1844
+ * Mediant of two fractions: (a+c)/(b+d)
1845
+ * Used in Stern-Brocot tree and Farey sequences
1933
1846
  */
1934
- acosh() {
1935
- if (this._isNaN) return this;
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
- * Inverse hyperbolic tangent: atanh(x) = 0.5 * ln((1+x)/(1-x))
1943
- * Domain: -1 < x < 1
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
- atanh() {
1946
- if (this._isNaN) return this;
1947
- const one = _BigNumber.fromNumber(1);
1948
- const absVal = this.abs();
1949
- if (absVal.compareTo(one) > 0) return new _BigNumber(0, 0n, 0, true);
1950
- if (absVal.equals(one)) {
1951
- return this._sign === 1 ? new _BigNumber(1, 0n, 0, false, true) : new _BigNumber(-1, 0n, 0, false, true);
1952
- }
1953
- if (this._sign === 0) return this;
1954
- const half = _BigNumber.fromNumber(0.5);
1955
- return one.add(this).divide(one.subtract(this)).ln().multiply(half);
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
- // Transcendental Functions
1894
+ // Static Factory Methods
1959
1895
  // ============================================================
1960
1896
  /**
1961
- * Exponential function: e^x
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
- exp() {
1966
- if (this._isNaN) return this;
1967
- if (this._sign === 0) return _BigNumber.fromNumber(1);
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
- const divisor = _BigNumber.fromNumber(2).pow(k);
1978
- const reduced = this.divide(divisor);
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
- for (let i = 0; i < k; i++) {
1989
- sum = sum.multiply(sum);
1906
+ if (n === 0) {
1907
+ return new _BigNumber(0, 0n, 0);
1990
1908
  }
1991
- return sum.roundToPrecision(precision);
1909
+ return _BigNumber.parse(n.toString());
1992
1910
  }
1993
1911
  /**
1994
- * Natural logarithm: ln(x)
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
- ln() {
1999
- if (this._isNaN) return this;
2000
- if (this._sign === -1) return new _BigNumber(0, 0n, 0, true);
2001
- if (this._sign === 0) return new _BigNumber(-1, 0n, 0, false, true);
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
- while (x.compareTo(half) < 0) {
2015
- x = x.multiply(two);
2016
- k--;
1919
+ if (str === "infinity" || str === "+infinity") {
1920
+ return new _BigNumber(1, 0n, 0, false, true);
2017
1921
  }
2018
- const y = x.subtract(one).divide(x.add(one));
2019
- const ySq = y.multiply(y);
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
- sum = sum.multiply(two);
2031
- if (k !== 0) {
2032
- sum = sum.add(BIGNUMBER_LN2.multiply(_BigNumber.fromNumber(k)));
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
- return sum.roundToPrecision(precision);
2035
- }
2036
- /**
2037
- * Base-10 logarithm: log10(x) = ln(x) / ln(10)
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 precision = globalConfig.precision;
2060
- const three = _BigNumber.fromNumber(3);
2061
- let guess = _BigNumber.fromNumber(Math.cbrt(this.valueOf()));
2062
- for (let i = 0; i < 100; i++) {
2063
- const guessSquared = guess.multiply(guess);
2064
- const newGuess = guess.multiply(_BigNumber.fromNumber(2)).add(this.divide(guessSquared)).divide(three);
2065
- if (guess.subtract(newGuess).abs().compareTo(guess.abs().multiply(_BigNumber.parse("1e-" + (precision + 5)))) <= 0) {
2066
- return newGuess.roundToPrecision(precision);
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
- return guess.roundToPrecision(precision);
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
- * e^x - 1 (more precise than exp(x) - 1 for small x)
2074
- * Uses Taylor series directly: expm1(x) = x + x^2/2! + x^3/3! + ...
1966
+ * Create from bigint
2075
1967
  */
2076
- expm1() {
2077
- if (this._isNaN) return this;
2078
- if (this._sign === 0) return this;
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
- if (Math.abs(this.valueOf()) > 0.5) {
2083
- return this.exp().subtract(_BigNumber.fromNumber(1));
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
- const precision = globalConfig.precision;
2086
- let term = this.clone();
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 sum.roundToPrecision(precision);
1985
+ return new _BigNumber(sign2, BigInt(str), trailingZeros);
2096
1986
  }
2097
1987
  /**
2098
- * ln(1 + x) (more precise than ln(1 + x) for small x)
1988
+ * Create a BigNumber from a JSON object
2099
1989
  */
2100
- log1p() {
2101
- if (this._isNaN) return this;
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
- * Hypotenuse: sqrt(this^2 + other^2)
1994
+ * Get/set global configuration
2111
1995
  */
2112
- hypot(other) {
2113
- if (this._isNaN || other._isNaN) return new _BigNumber(0, 0n, 0, true);
2114
- if (this._isInfinite || other._isInfinite) return new _BigNumber(1, 0n, 0, false, true);
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 reduced;
2000
+ return { ...globalConfig };
2134
2001
  }
2135
- /** Taylor series for sin(x), assumes x is in [-PI, PI] */
2136
- _sinTaylor() {
2137
- const precision = globalConfig.precision;
2138
- let term = this.clone();
2139
- let sum = this.clone();
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
- /** Taylor series for cos(x), assumes x is in [-PI, PI] */
2151
- _cosTaylor() {
2152
- const precision = globalConfig.precision;
2153
- let term = _BigNumber.fromNumber(1);
2154
- let sum = _BigNumber.fromNumber(1);
2155
- const xSquared = this.multiply(this);
2156
- const maxIter = precision + 20;
2157
- for (let n = 1; n <= maxIter; n++) {
2158
- term = term.multiply(xSquared).divide(_BigNumber.fromNumber((2 * n - 1) * (2 * n))).negate();
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 sum.roundToPrecision(precision);
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
- /** Taylor series for atan(x), assumes |x| <= 0.5 */
2166
- _atanTaylor() {
2167
- const precision = globalConfig.precision;
2168
- const xSquared = this.multiply(this);
2169
- let term = this.clone();
2170
- let sum = this.clone();
2171
- const maxIter = precision + 20;
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
- return sum.roundToPrecision(precision);
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
- // Utility Methods
2041
+ // Conversion Methods
2183
2042
  // ============================================================
2184
- isNaN() {
2185
- return this._isNaN;
2186
- }
2187
- isFinite() {
2188
- return !this._isNaN && !this._isInfinite;
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
- isInfinite() {
2191
- return this._isInfinite;
2192
- }
2193
- isZero() {
2194
- return this._sign === 0 && !this._isNaN;
2195
- }
2196
- isPositive() {
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
- isNegative() {
2200
- return this._sign === -1;
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
- isInteger() {
2203
- if (this._isNaN || this._isInfinite || this._sign === 0) return this._sign === 0;
2204
- return this._exponent >= 0;
2073
+ toJSON() {
2074
+ return {
2075
+ mathjs: "BigNumber",
2076
+ value: this.toString()
2077
+ };
2205
2078
  }
2206
- sign() {
2207
- return this._sign;
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
- clone() {
2210
- return new _BigNumber(
2211
- this._sign,
2212
- this._coefficient,
2213
- this._exponent,
2214
- this._isNaN,
2215
- this._isInfinite
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
- // Private Helper Methods
2220
- // ============================================================
2221
- ensureBigNumber(value) {
2222
- if (value instanceof _BigNumber) return value;
2223
- if (typeof value === "number") return _BigNumber.fromNumber(value);
2224
- if (typeof value === "string") return _BigNumber.parse(value);
2225
- return _BigNumber.fromNumber(Number(value.valueOf()));
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
- alignExponents(a, b) {
2228
- const minExp = Math.min(a._exponent, b._exponent);
2229
- const aShift = a._exponent - minExp;
2230
- const bShift = b._exponent - minExp;
2231
- const aCoef = aShift > 0 ? a._coefficient * BigInt(10) ** BigInt(aShift) : a._coefficient;
2232
- const bCoef = bShift > 0 ? b._coefficient * BigInt(10) ** BigInt(bShift) : b._coefficient;
2233
- return [aCoef, bCoef, minExp];
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
- normalize(sign2, coefficient, exponent) {
2236
- if (coefficient === 0n) {
2237
- return new _BigNumber(0, 0n, 0);
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
- let coef = coefficient;
2240
- let exp = exponent;
2241
- while (coef % 10n === 0n && coef !== 0n) {
2242
- coef = coef / 10n;
2243
- exp++;
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 new _BigNumber(sign2, coef, exp);
2195
+ return 0n;
2246
2196
  }
2247
- };
2248
- var BIGNUMBER_ZERO = BigNumber.fromNumber(0);
2249
- var BIGNUMBER_ONE = BigNumber.fromNumber(1);
2250
- var BIGNUMBER_NEG_ONE = BigNumber.fromNumber(-1);
2251
- var BIGNUMBER_TEN = BigNumber.fromNumber(10);
2252
- var BIGNUMBER_PI = BigNumber.parse("3.14159265358979323846264338327950288419716939937510");
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
- const obj = x;
2276
- if (obj.isBigNumber === true && typeof obj.constructor.prototype === "object" && obj.constructor.prototype.isBigNumber === true) {
2277
- return true;
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
- if (typeof obj.constructor.isDecimal === "function" && obj.constructor.isDecimal(obj) === true) {
2280
- return true;
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
- return false;
2283
- }
2284
- function isBigInt(x) {
2285
- return typeof x === "bigint";
2286
- }
2287
- function isComplex2(x) {
2288
- return !!(x && typeof x === "object" && Object.getPrototypeOf(x).isComplex === true);
2289
- }
2290
- function isFraction2(x) {
2291
- return !!(x && typeof x === "object" && Object.getPrototypeOf(x).isFraction === true);
2292
- }
2293
- function isUnit(x) {
2294
- return hasPrototypeFlag(x, "isUnit");
2295
- }
2296
- function isString(x) {
2297
- return typeof x === "string";
2298
- }
2299
- var isArray = Array.isArray;
2300
- function isMatrix(x) {
2301
- return hasPrototypeFlag(x, "isMatrix");
2302
- }
2303
- function isCollection(x) {
2304
- return Array.isArray(x) || isMatrix(x);
2305
- }
2306
- function isDenseMatrix(x) {
2307
- return hasOwnAndPrototypeFlag(x, "isDenseMatrix", "isMatrix");
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
- return isFinite(value) ? value === Math.round(value) : false;
2366
- }
2367
- function safeNumberType(numberStr, config2) {
2368
- if (config2.number === "bigint") {
2369
- try {
2370
- BigInt(numberStr);
2371
- } catch {
2372
- return config2.numberFallback;
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
- return config2.number;
2376
- }
2377
- var sign = Math.sign || function(x) {
2378
- if (x > 0) {
2379
- return 1;
2380
- } else if (x < 0) {
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
- var log2 = Math.log2 || function log22(x) {
2387
- return Math.log(x) / Math.LN2;
2388
- };
2389
- var log10 = Math.log10 || function log102(x) {
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
- const negate = x < 0;
2400
- let result;
2401
- if (negate) {
2402
- x = -x;
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
- if (isFinite(x)) {
2405
- result = Math.exp(Math.log(x) / 3);
2406
- result = (x / (result * result) + 2 * result) / 3;
2407
- } else {
2408
- result = x;
2305
+ /**
2306
+ * Alias for multiply — mathjs / Decimal.js compatibility.
2307
+ */
2308
+ mul(other) {
2309
+ return this.multiply(other);
2409
2310
  }
2410
- return negate ? -result : result;
2411
- };
2412
- var expm1 = Math.expm1 || function expm12(x) {
2413
- return x >= 2e-4 || x <= -2e-4 ? Math.exp(x) - 1 : x + x * x / 2 + x * x * x / 6;
2414
- };
2415
- function formatNumberToBase(n, base, size) {
2416
- const prefixes = { 2: "0b", 8: "0o", 16: "0x" };
2417
- const prefix = prefixes[base];
2418
- let suffix = "";
2419
- if (size) {
2420
- if (size < 1) {
2421
- throw new Error("size must be in greater than 0");
2422
- }
2423
- if (!isInteger(size)) {
2424
- throw new Error("size must be an integer");
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 (n < 0) {
2433
- n = n + 2 ** size;
2328
+ if (this._isInfinite) {
2329
+ const sign3 = this._sign * b._sign;
2330
+ return new _BigNumber(sign3, 0n, 0, false, true);
2434
2331
  }
2435
- suffix = `i${size}`;
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
- let sign2 = "";
2438
- if (n < 0) {
2439
- n = -n;
2440
- sign2 = "-";
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
- return `${sign2}${prefix}${n.toString(base)}${suffix}`;
2443
- }
2444
- function format(value, options) {
2445
- if (typeof options === "function") {
2446
- return options(value);
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
- if (value === Infinity) {
2449
- return "Infinity";
2450
- } else if (value === -Infinity) {
2451
- return "-Infinity";
2452
- } else if (isNaN(value)) {
2453
- return "NaN";
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
- function normalizeFormatOptions(options) {
2483
- let notation = "auto";
2484
- let precision;
2485
- let wordSize;
2486
- if (options !== void 0) {
2487
- if (isNumber(options)) {
2488
- precision = options;
2489
- } else if (isBigNumber2(options)) {
2490
- precision = options.toNumber();
2491
- } else if (isObject(options)) {
2492
- if (options.precision !== void 0) {
2493
- precision = _toNumberOrThrow(options.precision, () => {
2494
- throw new Error('Option "precision" must be a number or BigNumber');
2495
- });
2496
- }
2497
- if (options.wordSize !== void 0) {
2498
- wordSize = _toNumberOrThrow(options.wordSize, () => {
2499
- throw new Error('Option "wordSize" must be a number or BigNumber');
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
- } else {
2506
- throw new Error("Unsupported type of options, number, BigNumber, or object expected");
2386
+ base = base.multiply(base);
2387
+ e = Math.floor(e / 2);
2507
2388
  }
2389
+ return result.roundToPrecision(globalConfig.precision);
2508
2390
  }
2509
- return { notation, precision, wordSize };
2510
- }
2511
- function splitNumber(value) {
2512
- const match = String(value).toLowerCase().match(/^(-?)(\d+\.?\d*)(e([+-]?\d+))?$/);
2513
- if (!match) {
2514
- throw new SyntaxError("Invalid number " + value);
2515
- }
2516
- const sign2 = match[1];
2517
- const digits2 = match[2];
2518
- let exponent = parseFloat(match[4] || "0");
2519
- const dot = digits2.indexOf(".");
2520
- exponent += dot !== -1 ? dot - 1 : digits2.length - 1;
2521
- const coefficients = digits2.replace(".", "").replace(/^0*/, function(zeros2) {
2522
- exponent -= zeros2.length;
2523
- return "";
2524
- }).replace(/0*$/, "").split("").map(function(d) {
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
- let expDiff = Math.abs(e - newExp);
2553
- let decimalIdx = 1;
2554
- while (expDiff > 0) {
2555
- decimalIdx++;
2556
- expDiff--;
2410
+ // ============================================================
2411
+ // Comparison Methods
2412
+ // ============================================================
2413
+ equals(other) {
2414
+ return _BigNumber.compare(this, other) === 0;
2557
2415
  }
2558
- const decimals = c.slice(decimalIdx).join("");
2559
- const decimalVal = isNumber(precision) && decimals.length || decimals.match(/[1-9]/) ? "." + decimals : "";
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
- const splitValue = splitNumber(value);
2568
- const rounded = typeof precision === "number" ? roundDigits(splitValue, splitValue.exponent + 1 + precision) : splitValue;
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
- if (p < 0) {
2576
- c = zeros(-p + 1).concat(c);
2577
- p = 1;
2422
+ greaterThan(other) {
2423
+ return _BigNumber.compare(this, other) > 0;
2578
2424
  }
2579
- if (p < c.length) {
2580
- c.splice(p, 0, p === 0 ? "0." : ".");
2425
+ greaterThanOrEqual(other) {
2426
+ return _BigNumber.compare(this, other) >= 0;
2581
2427
  }
2582
- return rounded.sign + c.join("");
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
- const split = splitNumber(value);
2589
- const rounded = precision ? roundDigits(split, precision) : split;
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
- const first = c.shift();
2596
- return rounded.sign + first + (c.length > 0 ? "." + c.join("") : "") + "e" + (e >= 0 ? "+" : "") + e;
2597
- }
2598
- function toPrecision(value, precision, options) {
2599
- if (isNaN(value) || !isFinite(value)) {
2600
- return String(value);
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
- const lowerExp = _toNumberOrDefault(options?.lowerExp, -3);
2603
- const upperExp = _toNumberOrDefault(options?.upperExp, 5);
2604
- const split = splitNumber(value);
2605
- const rounded = precision ? roundDigits(split, precision) : split;
2606
- if (rounded.exponent < lowerExp || rounded.exponent >= upperExp) {
2607
- return toExponential(value, precision);
2608
- } else {
2609
- let c = rounded.coefficients;
2610
- const e = rounded.exponent;
2611
- if (precision && c.length < precision) {
2612
- c = c.concat(zeros(precision - c.length));
2613
- }
2614
- c = c.concat(
2615
- zeros(e - c.length + 1 + (precision && c.length < precision ? precision - c.length : 0))
2616
- );
2617
- c = zeros(-e).concat(c);
2618
- const dot = e > 0 ? e : 0;
2619
- if (dot < c.length - 1) {
2620
- c.splice(dot + 1, 0, ".");
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.sign + c.join("");
2462
+ return this.normalize(rounded === 0n ? 0 : this._sign, rounded, targetExp);
2623
2463
  }
2624
- }
2625
- function roundDigits(split, precision) {
2626
- const rounded = {
2627
- sign: split.sign,
2628
- coefficients: split.coefficients.slice(),
2629
- exponent: split.exponent
2630
- };
2631
- const c = rounded.coefficients;
2632
- if (precision !== void 0) {
2633
- while (precision <= 0) {
2634
- c.unshift(0);
2635
- rounded.exponent++;
2636
- precision++;
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
- if (c.length > precision) {
2639
- const removed = c.splice(precision, c.length - precision);
2640
- if (removed[0] >= 5) {
2641
- let i = precision - 1;
2642
- c[i]++;
2643
- while (c[i] === 10) {
2644
- c.pop();
2645
- if (i === 0) {
2646
- c.unshift(0);
2647
- rounded.exponent++;
2648
- i++;
2649
- }
2650
- i--;
2651
- c[i]++;
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
- return rounded;
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
- return arr;
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
- if (absTol < 0) {
2673
- throw new Error("Absolute tolerance must be at least 0");
2517
+ trunc() {
2518
+ return this.round(0, "down");
2674
2519
  }
2675
- if (isNaN(a) || isNaN(b)) {
2676
- return false;
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
- if (!isFinite(a) || !isFinite(b)) {
2679
- return a === b;
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
- if (a === b) {
2682
- return true;
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
- return Math.abs(a - b) <= Math.max(relTol * Math.max(Math.abs(a), Math.abs(b)), absTol);
2685
- }
2686
- var acosh = Math.acosh || function(x) {
2687
- return Math.log(Math.sqrt(x * x - 1) + x);
2688
- };
2689
- var asinh = Math.asinh || function(x) {
2690
- return Math.log(Math.sqrt(x * x + 1) + x);
2691
- };
2692
- var atanh = Math.atanh || function(x) {
2693
- return Math.log((1 + x) / (1 - x)) / 2;
2694
- };
2695
- var cosh = Math.cosh || function(x) {
2696
- return (Math.exp(x) + Math.exp(-x)) / 2;
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
- function _toNumberOrDefault(value, defaultValue) {
2724
- if (isNumber(value)) {
2725
- return value;
2726
- } else if (isBigNumber2(value)) {
2727
- return value.toNumber();
2728
- } else {
2729
- return defaultValue;
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
- // src/config.ts
2734
- var DEFAULT_CONFIG = {
2735
- // minimum relative difference between two compared values,
2736
- // used by all comparison functions
2737
- relTol: 1e-12,
2738
- // minimum absolute difference between two compared values,
2739
- // used by all comparison functions
2740
- absTol: 1e-15,
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
- if (typeof base === "bigint" && typeof exp === "bigint") return base ** exp;
2824
- return Math.pow(number(base), number(exp));
2825
- }
2826
- function abs(x) {
2827
- if (typeof x === "number") return Math.abs(x);
2828
- if (typeof x === "bigint") return x < 0n ? -x : x;
2829
- return x.abs();
2830
- }
2831
- function fix(x) {
2832
- if (typeof x === "number") return Math.trunc(x);
2833
- if (typeof x === "bigint") return x;
2834
- if (x instanceof Complex) return new Complex(Math.trunc(x.re), Math.trunc(x.im));
2835
- return x.sign() >= 0 ? x.floor() : x.ceil();
2836
- }
2837
- function round(x) {
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
- return x.re;
2864
- }
2865
-
2866
- // src/shared.ts
2867
- function hasOwnProperty(object, property) {
2868
- return !!object && Object.hasOwnProperty.call(object, property);
2869
- }
2870
- function endsWith(text, search) {
2871
- const start = text.length - search.length;
2872
- return text.substring(start, text.length) === search;
2873
- }
2874
- var warnOnce = /* @__PURE__ */ (() => {
2875
- const seen = {};
2876
- return function warnOnce2(...args) {
2877
- const message = args.join(", ");
2878
- if (!seen[message]) {
2879
- seen[message] = true;
2880
- console.warn("Warning:", ...args);
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
- function memoize(fn, { hasher, limit } = {}) {
2885
- const hash = hasher ?? ((args) => JSON.stringify(args));
2886
- const maxSize = limit == null ? Number.POSITIVE_INFINITY : limit;
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 cache = memoized.cache;
2892
- const key = hash(args);
2893
- if (cache.has(key)) {
2894
- const value2 = cache.get(key);
2895
- cache.delete(key);
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
- const value = fn.apply(fn, args);
2900
- cache.set(key, value);
2901
- if (cache.size > maxSize) {
2902
- cache.delete(cache.keys().next().value);
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 value;
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
- const cloneable = x;
2916
- if (typeof cloneable.clone === "function") {
2917
- return cloneable.clone();
2970
+ // ============================================================
2971
+ // Utility Methods
2972
+ // ============================================================
2973
+ isNaN() {
2974
+ return this._isNaN;
2918
2975
  }
2919
- if (Array.isArray(x)) {
2920
- return x.map((value) => clone(value));
2976
+ isFinite() {
2977
+ return !this._isNaN && !this._isInfinite;
2921
2978
  }
2922
- if (x instanceof Date) return new Date(x.valueOf());
2923
- if (isBigNumber2(x)) return x;
2924
- if (isObject(x)) {
2925
- return mapObject(x, clone);
2979
+ isInfinite() {
2980
+ return this._isInfinite;
2926
2981
  }
2927
- if (type === "function") {
2928
- return x;
2982
+ isZero() {
2983
+ return this._sign === 0 && !this._isNaN;
2929
2984
  }
2930
- throw new TypeError(`Cannot clone: unknown type of value (value: ${x})`);
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
- return clone2;
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
- return a;
2949
- }
2950
- function deepExtend(a, b) {
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
- for (const prop in b) {
2982
- if (hasOwnProperty(b, prop) && !(prop in Object.prototype) && !(prop in Function.prototype)) {
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
- return a;
3009
- }
3010
- function deepStrictEqual(a, b) {
3011
- let prop;
3012
- let i;
3013
- let len;
3014
- if (Array.isArray(a)) {
3015
- if (!Array.isArray(b)) {
3016
- return false;
3017
- }
3018
- if (a.length !== b.length) {
3019
- return false;
3020
- }
3021
- for (i = 0, len = a.length; i < len; i++) {
3022
- if (!deepStrictEqual(a[i], b[i])) {
3023
- return false;
3024
- }
3025
- }
3026
- return true;
3027
- } else if (typeof a === "function") {
3028
- return a === b;
3029
- } else if (a instanceof Object) {
3030
- if (Array.isArray(b) || !(b instanceof Object)) {
3031
- return false;
3032
- }
3033
- const aObj = a;
3034
- const bObj = b;
3035
- for (prop in aObj) {
3036
- if (!(prop in bObj) || !deepStrictEqual(aObj[prop], bObj[prop])) {
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
- for (prop in bObj) {
3041
- if (!(prop in aObj)) {
3042
- return false;
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 true;
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 deepFlatten(nestedObject) {
3051
- const flattenedObject = {};
3052
- _deepFlatten(nestedObject, flattenedObject);
3053
- return flattenedObject;
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 _deepFlatten(nestedObject, flattenedObject) {
3056
- for (const prop in nestedObject) {
3057
- if (hasOwnProperty(nestedObject, prop)) {
3058
- const value = nestedObject[prop];
3059
- if (typeof value === "object" && value !== null) {
3060
- _deepFlatten(value, flattenedObject);
3061
- } else {
3062
- flattenedObject[prop] = value;
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 canDefineProperty() {
3068
- try {
3069
- if (Object.defineProperty) {
3070
- Object.defineProperty({}, "x", {
3071
- get: function() {
3072
- return null;
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 lazy(object, prop, valueResolver) {
3082
- let _uninitialized = true;
3083
- let _value;
3084
- Object.defineProperty(object, prop, {
3085
- get: function() {
3086
- if (_uninitialized) {
3087
- _value = valueResolver();
3088
- _uninitialized = false;
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 traverse(object, path) {
3101
- if (path && typeof path === "string") {
3102
- return traverse(object, path.split("."));
3103
- }
3104
- let obj = object;
3105
- if (path) {
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 obj;
3140
+ if (typeof base === "bigint" && typeof exp === "bigint") return base ** exp;
3141
+ return Math.pow(number(base), number(exp));
3115
3142
  }
3116
- function isLegacyFactory(object) {
3117
- return !!object && typeof object.factory === "function";
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 get(object, path) {
3120
- if (typeof path === "string") {
3121
- if (isPath(path)) {
3122
- return get(object, path.split("."));
3123
- } else {
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 set(object, path, value) {
3135
- if (typeof path === "string") {
3136
- if (isPath(path)) {
3137
- return set(object, path.split("."), value);
3138
- } else {
3139
- object[path] = value;
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 pick(object, properties, transform) {
3158
- const copy = {};
3159
- for (let i = 0; i < properties.length; i++) {
3160
- const key = properties[i];
3161
- const value = get(object, key);
3162
- if (value !== void 0) {
3163
- set(copy, key, transform ? transform(value, key) : value);
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 pickShallow(object, properties) {
3169
- const copy = {};
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 isPath(str) {
3180
- return str.includes(".");
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
- isBigNumber2,
6267
+ isBigNumber,
6286
6268
  isBigInt,
6287
6269
  isComplex2,
6288
- isFraction2,
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,