fix(numtower): inexact presence per value, POW sign from exact parity, i128::MIN numerators (improvise-59nw.1)
Answers ChatGPT Codex's P1 and Copilot's two findings on PR #337; each has a regression test that failed at edbb50c4.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
committed by
Edward Langley
parent
edbb50c426
commit
568f52165d
@@ -34,7 +34,10 @@ bytes, as the ADR measured, and `a_num_is_24_bytes` pins it.
|
||||
**The normal form.** An exact zero has no sign. A fraction is reduced and has a positive
|
||||
denominator. A value whose reduced denominator is `2^p·5^q`, with `k = max(p, q) <= 28`
|
||||
and a mantissa that fits 96 bits, is always the `Decimal`, never a `Fraction`. So
|
||||
`Fraction(n/1)` exists only when `n` does not fit 96 bits, as with `10^35/1`.
|
||||
`Fraction(n/1)` exists only when `n` does not fit 96 bits, as with `10^35/1`. Every `i128`
|
||||
is a valid numerator, `i128::MIN` included, because the arm is `Ratio<i128>`. That one
|
||||
value cannot be negated in `i128`, so `Operand::parts` keeps it out of the `i128` fast
|
||||
path and its arithmetic takes the bigint path (Copilot on PR #337).
|
||||
|
||||
## Arithmetic
|
||||
|
||||
@@ -116,6 +119,10 @@ rule, because the ADR decided it and because it needs no second division.
|
||||
negative power is a division and has its minimal scale.
|
||||
- **The edge values.** `0^0` is `1`. `0^-n` is `div/0`. `±1^n` is `±1` for any `n`,
|
||||
including one too large to compute.
|
||||
- **A demoted power takes its sign from the exact exponent.** `powf` gets the base's
|
||||
magnitude, and the sign is set from `base < 0 && n odd`. An exponent above 2^53 rounds
|
||||
to an even f64, so handing `powf` the signed base made `(-2)^(2^53 + 1)` read `+inf`
|
||||
(Copilot on PR #337).
|
||||
|
||||
### The ceiling
|
||||
|
||||
@@ -192,16 +199,24 @@ of the multiset of terms and not of their order.
|
||||
| the decimal partition | every decimal, and every fraction whose denominator is `2^p·5^q` with `k <= 28`, as an integer at scale 28 | 320 bits |
|
||||
| the groups | per other reduced denominator, the summed numerator | 256 bits each, in a `BTreeMap` |
|
||||
| `group_floats` | an `ExactSum` of each group's correctly rounded value | ADR 009's |
|
||||
| `inexact` | an `ExactSum` of the f64 terms, plus their net weight | ADR 009's |
|
||||
| `inexact` | an `ExactSum` of the f64 terms | ADR 009's |
|
||||
| `inexact_terms` | the net weight per f64 bit pattern, entries at zero dropped | a `BTreeMap` |
|
||||
|
||||
**The read.** It is exact when the net inexact weight is zero and at most K = 8 groups
|
||||
**The read.** It is exact when no inexact term is present and at most K = 8 groups
|
||||
remain. The groups and the decimal partition are then combined **over the lcm of their
|
||||
denominators, and reduced once**, and the stored bound applies to the result. Past K the
|
||||
read is the f64 accumulators: `group_floats`, the decimal partition converted once, and
|
||||
the inexact terms. That reading rounds each group, then the total. With inexact terms and
|
||||
at most K groups, the exact total is converted once and added to the inexact terms. A
|
||||
group whose numerator returns to zero is dropped, so "how many groups" is a function of
|
||||
state. The K cutoff overrides representability: nine denominators whose exact total fits
|
||||
state.
|
||||
|
||||
**"Is an inexact term present" is asked per value, never of the net weight.** The first
|
||||
version kept one net count. Inserting `1.0` and retracting `2.0` leaves the count at zero
|
||||
while the accumulator holds −1.0, so the read took the exact branch and dropped it
|
||||
(ChatGPT Codex, P1 on PR #337). Presence is now a map from f64 bit pattern to net weight,
|
||||
dropped at zero, the same rule the groups follow. It costs O(distinct inexact values),
|
||||
the same order as the groups. The K cutoff overrides representability: nine denominators whose exact total fits
|
||||
still read inexact (`more_than_k_denominators_read_inexact_even_when_the_total_fits`).
|
||||
That is question 13's second exception, and the ADR's flagged reading.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user