* Divide this value by another. * Uses `BigDecimal.precision` to determine significant digits for inexact results. * * Special cases: * - NaN / x → NaN, x / NaN → NaN * - nonzero / 0 → +/-Infinity (matching Decimal.js behavior) * - 0 / 0 → NaN * - Inf / finite → Inf (correct
(other: BigDecimal | number)
| 699 | * - Inf / Inf → NaN |
| 700 | */ |
| 701 | div(other: BigDecimal | number): BigDecimal { |
| 702 | if (typeof other === 'number') other = new BigDecimal(other); |
| 703 | |
| 704 | const thisExp = this.exponent; |
| 705 | const otherExp = other.exponent; |
| 706 | const thisSig = this.significand; |
| 707 | const otherSig = other.significand; |
| 708 | |
| 709 | // Fast path: both finite |
| 710 | if (Number.isFinite(thisExp) && Number.isFinite(otherExp)) { |
| 711 | // Division by zero |
| 712 | if (otherSig === 0n) { |
| 713 | if (thisSig === 0n) return BigDecimal.NAN; // 0/0 → NaN |
| 714 | return thisSig > 0n |
| 715 | ? BigDecimal.POSITIVE_INFINITY |
| 716 | : BigDecimal.NEGATIVE_INFINITY; |
| 717 | } |
| 718 | // 0 / nonzero → 0 |
| 719 | if (thisSig === 0n) return fromRaw(0n, 0); |
| 720 | |
| 721 | // General case |
| 722 | const prec = BigDecimal.precision; |
| 723 | const guard = 10; |
| 724 | const dividendDigits = this._digitCount(); |
| 725 | const divisorDigits = other._digitCount(); |
| 726 | const totalScale = |
| 727 | prec + guard + Math.max(0, divisorDigits - dividendDigits); |
| 728 | const scale = pow10(totalScale); |
| 729 | const quotient = (thisSig * scale) / otherSig; |
| 730 | const resultExp = thisExp - otherExp - totalScale; |
| 731 | // The quotient carries `prec + guard` digits (guard = 10), so rounding it |
| 732 | // to `prec` always happens — it can never hit the `digits <= n → return |
| 733 | // this` short-circuit. Two economies over `…toPrecision(prec)`: |
| 734 | // |
| 735 | // 1. Skip normalizing the (large) quotient: stripping z trailing zeros |
| 736 | // scales the significand, the rounding divisor, and the round-half-even |
| 737 | // tie point all by 10^z, so the rounded significand/exponent is |
| 738 | // byte-identical either way, and the rounding re-normalizes its own |
| 739 | // (smaller) result. Saves one full-width normalize per division. |
| 740 | // 2. Derive the quotient's digit count instead of recomputing it with a |
| 741 | // `bigintDigits` bit-length scan. The numerator `thisSig·10^totalScale` |
| 742 | // has exactly `dividendDigits + totalScale` digits; dividing by an |
| 743 | // `otherSig` of `divisorDigits` digits yields a quotient of exactly |
| 744 | // `lo` or `lo + 1` digits (integer division of an a-digit by a b-digit |
| 745 | // value gives a−b or a−b+1 digits). Resolve the ±1 with one cached-pow10 |
| 746 | // boundary compare. `lo ≥ prec + guard > prec`, so it always rounds. |
| 747 | const absQuot = quotient < 0n ? -quotient : quotient; |
| 748 | const lo = dividendDigits + totalScale - divisorDigits; |
| 749 | const quotientDigits = absQuot >= pow10(lo) ? lo + 1 : lo; |
| 750 | return rawUnnormalized(quotient, resultExp).roundToPrecKnownDigits( |
| 751 | prec, |
| 752 | quotientDigits |
| 753 | ); |
| 754 | } |
| 755 | |
| 756 | // Slow path: NaN or Infinity |
| 757 | if (thisExp !== thisExp || otherExp !== otherExp) return BigDecimal.NAN; |
| 758 |
no test coverage detected