Conversation
Add the cubic root (CubicRoot for FBig, Context::cbrt) and the general nth root (FBig::nth_root, Context::nth_root) to dashu-float, mirroring the existing sqrt and building on UBig::nth_root. The general nth_root follows sqrt's structure: shift the significand so the exponent is divisible by n and it carries at least n*precision digits, take the integer nth root, then round the last digit. Correct last-ulp rounding for arbitrary n uses an exact scaled comparison in the rounding closure: frac < 1/2 <=> 2^n * full < (2*root + 1)^n * BASE^low_digits which reduces exactly to sqrt's remainder test when n == 2. The expensive (2*root+1)^n term is evaluated only for the half-rounding modes. Notable details: - Short-circuit zero input, since UBig::ZERO.nth_root(n) returns ONE. - Support negative inputs for odd n (cbrt(-8) = -2); panic on even n of a negative, and on n == 0. - Use the stricter exactness test (rem == 0 && low == 0). - Add panic_root_zeroth to the error module (mirrors dashu-int). Tests cover exact and inexact cases for both bases, the n == 2 path cross-checked against sqrt (value and rounding flag), odd roots of negatives, panic cases, and a tight toward-zero bracketing check (r^n <= x < (r+ulp)^n evaluated at unlimited precision) across several inputs and degrees. Co-Authored-By: Claude <noreply@anthropic.com>
Add FBig::quantize(exp: isize) -> Rounded<Self>, the dashu analog of Python's Decimal.quantize(): it rounds self to the nearest multiple of BASE^exp using self's type-level rounding mode. This fills the long-standing `// TODO: implement quantize()` placeholder in convert.rs. The implementation reuses the existing split-and-round machinery (split_digits_ref + R::round_fract) shared with trunc/ceil/floor/round: - A finer-or-equal quantum (exp <= self.exponent) leaves the value unchanged and is Exact. - A coarser quantum rounds off low-order digits and is always Inexact, since a normalized significand is never divisible by BASE. Because dashu floats are normalized, trailing zeros cannot be stored to literally pin the exponent (unlike Python); instead the result's value is an exact multiple of BASE^exp and its precision is chosen so that result.ulp() == BASE^exp, i.e. precision = repr.exponent + repr.digits - exp. Thus quantize(1.234, -2) -> 1.23 at precision 3, while quantize(1.234, -10) is exact at precision 11. A result that rounds to zero gets unlimited precision, matching round(). Tests cover decimal/binary cases, exact and inexact branches with value and rounding-flag checks, result-precision assertions, mode sensitivity (HalfAway/Down/Up), negatives, zero, an infinity panic, and a sweep verifying the ulp == BASE^exp invariant across inputs and exponents. Co-Authored-By: Claude <noreply@anthropic.com>
For n with small prime factors (2, 3, 5, 7), decompose into a chain
of smaller root operations instead of computing x^{n-1} directly in
Newton's method. E.g. n=10000 → four sqrt + four 5th-root calls,
each computing x^{p-1} (x^4) instead of x^{9999}.
Also add a benchmark suite for exp, ln, powi, nth_root, and powf.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
CokieMiner
pushed a commit
to CokieMiner/dashu
that referenced
this pull request
Jun 25, 2026
…mpute#79) * Implement cbrt and nth_root for FBig with correct rounding Add the cubic root (CubicRoot for FBig, Context::cbrt) and the general nth root (FBig::nth_root, Context::nth_root) to dashu-float, mirroring the existing sqrt and building on UBig::nth_root. The general nth_root follows sqrt's structure: shift the significand so the exponent is divisible by n and it carries at least n*precision digits, take the integer nth root, then round the last digit. Correct last-ulp rounding for arbitrary n uses an exact scaled comparison in the rounding closure: frac < 1/2 <=> 2^n * full < (2*root + 1)^n * BASE^low_digits which reduces exactly to sqrt's remainder test when n == 2. The expensive (2*root+1)^n term is evaluated only for the half-rounding modes. Notable details: - Short-circuit zero input, since UBig::ZERO.nth_root(n) returns ONE. - Support negative inputs for odd n (cbrt(-8) = -2); panic on even n of a negative, and on n == 0. - Use the stricter exactness test (rem == 0 && low == 0). - Add panic_root_zeroth to the error module (mirrors dashu-int). Tests cover exact and inexact cases for both bases, the n == 2 path cross-checked against sqrt (value and rounding flag), odd roots of negatives, panic cases, and a tight toward-zero bracketing check (r^n <= x < (r+ulp)^n evaluated at unlimited precision) across several inputs and degrees. Co-Authored-By: Claude <noreply@anthropic.com> * Implement quantize(exp) for FBig Add FBig::quantize(exp: isize) -> Rounded<Self>, the dashu analog of Python's Decimal.quantize(): it rounds self to the nearest multiple of BASE^exp using self's type-level rounding mode. This fills the long-standing `// TODO: implement quantize()` placeholder in convert.rs. The implementation reuses the existing split-and-round machinery (split_digits_ref + R::round_fract) shared with trunc/ceil/floor/round: - A finer-or-equal quantum (exp <= self.exponent) leaves the value unchanged and is Exact. - A coarser quantum rounds off low-order digits and is always Inexact, since a normalized significand is never divisible by BASE. Because dashu floats are normalized, trailing zeros cannot be stored to literally pin the exponent (unlike Python); instead the result's value is an exact multiple of BASE^exp and its precision is chosen so that result.ulp() == BASE^exp, i.e. precision = repr.exponent + repr.digits - exp. Thus quantize(1.234, -2) -> 1.23 at precision 3, while quantize(1.234, -10) is exact at precision 11. A result that rounds to zero gets unlimited precision, matching round(). Tests cover decimal/binary cases, exact and inexact branches with value and rounding-flag checks, result-precision assertions, mode sensitivity (HalfAway/Down/Up), negatives, zero, an infinity panic, and a sweep verifying the ulp == BASE^exp invariant across inputs and exponents. Co-Authored-By: Claude <noreply@anthropic.com> * Accelerate UBig::nth_root for large composite n by factor reduction For n with small prime factors (2, 3, 5, 7), decompose into a chain of smaller root operations instead of computing x^{n-1} directly in Newton's method. E.g. n=10000 → four sqrt + four 5th-root calls, each computing x^{p-1} (x^4) instead of x^{9999}. Also add a benchmark suite for exp, ln, powi, nth_root, and powf. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Jacob Zhong <jacob@rimbot.com> Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.