gen.int: span overflow on full-width ranges #16
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Bug
gen.intcomputeshi - lo + 1for the span of the drawn interval, so a range covering the full Nix integer width overflows and the draw aborts:gen.anythingWithsidesteps it with+-(2^62 - 1)(seed153fd0), but any user range wider than 2^63 - 1 hits the same overflow, silently or with an abort thattryEvalcannot catch.Suggested fix
hi - lodoes not fit (e.g. sign draw + magnitude draw), or clamp the span and document the limit.towardsshrink candidates, which computex - origin.int (range.constant (-9223372036854775807) 9223372036854775807)neither aborts nor leaves the bounds.Found while implementing #12.
The span overflow itself is untouched —
gen.intstill computeshi - lo + 1.But a precondition for any fix is now in place, and part of the dogfood test is
covered.
rng.belowused to read a single 24-bit word and take it modulo the bound, sono draw could land more than 2^24 above a range's low end (844a40c). Fixing the
span computation alone would therefore not have helped: even with a correct span
for a full-width range, every draw would still have clustered at the bottom.
belownow assembles the draw from several words and lands in[0, 2^63)exactly, the top word cut to 15 bits so the largest sum is 2^63 - 1 — which is
the largest bound
gen.intcan express before the span overflows. So the drawside is ready for whatever the span side ends up doing.
The suggested dogfood test is
int (range.constant (-9223372036854775807) 9223372036854775807), whose span is 2^64 - 1 and still overflows. The widestspan that does not overflow is now exercised:
tests/self.nixhas "int over arange wider than one rng word reaches both of its halves", which draws from
range.constant (-(2^62 - 1)) (2^62 - 1)— span exactly 2^63 - 1 — and assertsboth halves are reached (672fb60). It pins the arithmetic just under the NixInt
maximum, so the remaining work here is the overflow above that point.
Still open as filed: the span computation, and the same check for
towards,which computes
x - origin.