* Modulo (remainder after truncating division). * Defined as: this - trunc(this / other) * other * * The sign of the result matches the sign of the dividend (this), * consistent with JavaScript's % operator and Decimal.js.
(other: BigDecimal | number)
| 882 | * consistent with JavaScript's % operator and Decimal.js. |
| 883 | */ |
| 884 | mod(other: BigDecimal | number): BigDecimal { |
| 885 | if (typeof other === 'number') other = new BigDecimal(other); |
| 886 | |
| 887 | const thisExp = this.exponent; |
| 888 | const otherExp = other.exponent; |
| 889 | |
| 890 | // Fast path: both finite |
| 891 | if (Number.isFinite(thisExp) && Number.isFinite(otherExp)) { |
| 892 | if (other.significand === 0n) return BigDecimal.NAN; // x mod 0 → NaN |
| 893 | if (this.significand === 0n) return fromRaw(0n, 0); // 0 mod x → 0 |
| 894 | |
| 895 | // Compute trunc(this / other) EXACTLY with bigints. Using the |
| 896 | // precision-bounded `div` here would round the quotient before |
| 897 | // truncating, producing a wrong remainder whenever |this / other| |
| 898 | // exceeds the working precision (e.g. `1e60 mod 3`). |
| 899 | // this / other = (s₁ · 10^(e₁−e₂)) / s₂ |
| 900 | const ediff = thisExp - otherExp; |
| 901 | const num = |
| 902 | ediff >= 0 ? this.significand * pow10(ediff) : this.significand; |
| 903 | const den = |
| 904 | ediff >= 0 ? other.significand : other.significand * pow10(-ediff); |
| 905 | const q = num / den; // bigint division truncates toward zero |
| 906 | return this.sub(fromRaw(q, 0).mul(other)); |
| 907 | } |
| 908 | |
| 909 | // Slow path: NaN or Infinity |
| 910 | if (thisExp !== thisExp || otherExp !== otherExp) return BigDecimal.NAN; |
| 911 | if (!Number.isFinite(thisExp)) return BigDecimal.NAN; // Inf mod x → NaN |
| 912 | // finite mod Inf → this |
| 913 | return new BigDecimal(this); |
| 914 | } |
| 915 | |
| 916 | /** |
| 917 | * Raise to a power. |
no test coverage detected