Conversation
Migrate the remaining real transcendentals to guaranteed-correct rounding via the Ziv retry loop (`Context::ziv`/`ziv_pair`): - Trig (sin, cos, sin_cos, tan, asin, acos, atan, atan2): extract near-correct `_compute` series cores and wrap them in Ziv. The argument reduction folds a `|k|·ulp(π/2)` reduction-error term into the radius so the containment test stays sound for huge `|x|`. - Hyperbolic (sinh, cosh, sinh_cosh, tanh, asinh, acosh, atanh): composition-based, treating the Ziv-correct `exp_m1`/`ln_1p` as black boxes; the unreachable exp-overflow case is hoisted via a shared `exp_overflows` probe (closures can't return `Err`). - `hypot`: composition-based (sqrt attenuates), small-constant radius. `sin_cos`/`sinh_cosh` certify both halves via the new `ziv_pair` driver. `powf` is left near-correct — its `exp(y·ln x)` amplification makes the data-dependent radius converge poorly for large results, so a dedicated treatment is deferred. Bound propagation: the migrated `Context`/`FBig`/`CachedFBig` methods move to `R: ErrorBounds`; dashu-cmplx's complex `sqrt`/`norm`/`abs`/ `arg` follow (they route through `hypot`/`atan2`). Tests: 20 exact-oracle soundness tests (`f(x)@p == f(x)@2p re-rounded`) covering every migrated function; existing trig/hyper/exp suites pass. Docs: float CHANGELOG, V1-ROADMAP, and bilingual compliance/faq updated. Co-Authored-By: Claude <noreply@anthropic.com>
…to powi
powf with a non-integer exponent is now correctly rounded via the Ziv loop.
The fix for the previously-deferred amplification problem: the error radius is
result.ulp()*(|y*ln x|+1)*(B+8) taken at the *working* precision, so it shrinks
as B^{-guard} and the containment test converges. A radius computed at unlimited
precision is constant across retries and never settles for a value near a
rounding boundary, which is why the earlier attempt infinite-retried.
An integer-valued exponent now delegates to powi (binary exponentiation), gated
on Repr::is_int. This also admits a negative base (sign fixed by the exponent's
parity) -- the old OutOfDomain TODO. That path is near-correct (<=1 ulp),
matching powi. The exp overflow case is hoisted out of the Ziv closure.
Also: Repr::is_int is now const (pure exponent/sentinel check).
Co-Authored-By: Claude <noreply@anthropic.com>
acos(1) = pi/2 - asin(1) cancels to exactly 0, but the composition carries a positive radius. Under a directed rounding mode (Down/Zero/Up) the preimage of 0 is one-sided ([0, ulp)), so the Ziv containment test can never certify it -- any positive radius dips the interval below 0 -- and it infinite-retried. This was the signed_zero.rs full-file hang: test_asin_acos_unit_under_down hung on acos(1) under Down. Short-circuit x = 1 to the exact 0 before the Ziv loop, matching asin's existing |x| = 1 special case. (asin(+-1) = +-pi/2 and acos(-1) = pi are nonzero, so they were already fine.) Co-Authored-By: Claude <noreply@anthropic.com>
A scan of every transcendental at its exact-representable special inputs under Down/Up/Zero turned up two more instances of the acos(1) hang (a transcendental whose true value is exactly representable carries a positive radius that can't be certified against the value's one-sided preimage, so Ziv infinite-retries): - asin(0) = 0: asin lacked the x=0 short-circuit that asinh/atanh/sin/cos/... all have, so it computed atan(0)=0 with a positive radius and infinite-retried. Now short-circuits to +-0 (asin is odd), matching the rest of the family. - acos(-1) = pi: short-circuited for symmetry with acos(1). The scan confirmed no other transcendentals hang (sqrt of perfect squares, exp(0), cos(0), cosh(0), powf(x,0), nth_root of exact roots, etc. are all already special-cased or detect exact results). Remaining: hypot of an exact Pythagorean triple (e.g. hypot(3,4)=5) -- same containment class but no clean single special case, plus a dashu-int NTT crash hit during the retry; tracked separately. Co-Authored-By: Claude <noreply@anthropic.com>
add_signed_sqr_conv and add_signed_mul_conv assumed a non-zero input (debug_assert!(la_bits > 0)); an all-zero slice panicked in debug and indexed out of bounds in release. sqrt_rem of a perfect square with many trailing zero words squares the estimate's all-zero low half to verify the remainder, so this was reachable -- and was the crash behind dashu-float's hypot(3,4) under directed rounding (the Ziv retry drove sqrt to a precision where the scaled significand hit the NTT path). An all-zero operand now returns early: the product is zero, so c += sign*a*b (or a^2) is a no-op. This matches the existing zero-guard in the chunked-multiply closure. Regression test: sqrt_rem of (1<<560000)^2. Co-Authored-By: Claude <noreply@anthropic.com>
The float changelog's hypot note said the underlying dashu-int NTT crash was "tracked separately"; that crash is now fixed (a482d7e), so update the note to reflect that hypot(exact) still infinite-retries on the containment issue, but no longer crashes. Co-Authored-By: Claude <noreply@anthropic.com>
Replace the ratio form (large * sqrt(1 + (small/large)^2)) with the scaled direct form sqrt(large^2 + small^2), tracking each step's Exact/Inexact flag (MPFR's `exact` flag in hypot.c). When the whole chain is exact -- which holds for every Pythagorean-triple input -- the closure reports radius 0, which ziv accepts without the containment test. This is the only way to terminate an exactly-representable result under directed rounding, where the value sits on a one-sided preimage boundary. The ratio form broke this for triples like hypot(5,12)=13: 5/12 is a non-terminating binary fraction, so div returned Inexact even though the final result 13 is exact. The direct form has no division, so sqr/add/sqrt are all exact for integer inputs -- mirroring how MPFR avoids a division precisely so its exact flag works for every triple. Both operands are scaled down by k base-B digits before squaring (k chosen so large^2 can't overflow the exponent) and the root scaled back, exactly MPFR's sh. Regression tests: hypot of (3,4)/(5,12)/(8,15) under Down/Up/Zero all return the exact integer. 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.