Problem
AnyDecimal draws a fraction that is supposed to be uniform in [0, 1), then maps it symmetrically around the midpoint of the requested range. The fraction is built from three Random.Next() calls (DecimalIntervalSpec.cs:145):
// A uniform-enough fraction in [0, 1): 93 random bits over the full decimal mantissa scale.
decimal fraction = new decimal(random.Next(), random.Next(), random.Next(), false, 28) / MaxFraction;
decimal mid = _min / 2 + _max / 2;
decimal half = _max / 2 - _min / 2;
decimal candidate = Clamped(mid + (fraction * 2 - 1) * half);
Random.Next() returns a non-negative int, so the top bit of each of the three 32-bit limbs of the 96-bit mantissa is always 0, and no limb can ever reach 2^31 - 1. But MaxFraction is the full 96-bit mantissa maximum (7.9228…, DecimalIntervalSpec.cs:14). The fraction therefore lives in [0, ~0.49999986], not [0, 1); (fraction * 2 - 1) lives in [-1, ~0); and every candidate lands in [min, mid).
Impact
The inclusive maximum documented on AnyDecimal.Between (AnyDecimal.cs:112) — and the entire upper half of every range — is unreachable. A test using Any.Decimal().Between(0m, 100m) to exercise "any valid percentage" silently never exercises 50–100. This inverts the library's core promise ("arbitrary yet valid, so hidden assumptions surface") into a hidden assumption of its own.
Reproduced against the built library: over 200,000 draws of Any.Decimal().Between(0m, 100m), the maximum observed was 49.99992….
Direction
Build the fraction from 96 genuinely uniform mantissa bits — any construction that fills all three limbs without fixing the top bit. For example:
byte[] limbs = new byte[12];
random.NextBytes(limbs);
decimal fraction = new decimal(
BitConverter.ToInt32(limbs, 0),
BitConverter.ToInt32(limbs, 4),
BitConverter.ToInt32(limbs, 8),
false, 28) / MaxFraction;
Any equivalent approach is acceptable provided the fraction covers [0, 1) uniformly and seeded reproducibility is preserved. Note the existing comment ("93 random bits over the full mantissa scale") already documents an intent the code does not meet.
Acceptance criteria
- A seeded reachability test proves
Any.Decimal().Between(lo, hi) observes values in both halves of the range, including near the inclusive maximum.
- The fix preserves seeded reproducibility (same seed ⇒ same sequence within a version).
- Point exclusions and allow-lists (
Except, OneOf, DifferentFrom) still behave.
- The stale
[0, 1) comment is corrected to describe the real construction.
Context
Surfaced by the 2026-07-20 architecture & design audit of the standalone Dummies library (doc/handwritten/for-maintainers/audit/2026-07-20-dummies-architecture-and-design-audit.md, §4.1(a); branch claude/dummies-architecture-audit-cru5aq). The defect survived the green test suite because tests assert membership, never reachability — see the companion reachability-tests issue.
Filed from the Claude Code session that produced the 2026-07-20 Dummies architecture & design audit: https://claude.ai/code/session_01GvrWFVoG74xiys3oyEft1G
Problem
AnyDecimaldraws a fraction that is supposed to be uniform in[0, 1), then maps it symmetrically around the midpoint of the requested range. The fraction is built from threeRandom.Next()calls (DecimalIntervalSpec.cs:145):Random.Next()returns a non-negativeint, so the top bit of each of the three 32-bit limbs of the 96-bit mantissa is always0, and no limb can ever reach2^31 - 1. ButMaxFractionis the full 96-bit mantissa maximum (7.9228…,DecimalIntervalSpec.cs:14). The fraction therefore lives in[0, ~0.49999986], not[0, 1);(fraction * 2 - 1)lives in[-1, ~0); and every candidate lands in[min, mid).Impact
The inclusive maximum documented on
AnyDecimal.Between(AnyDecimal.cs:112) — and the entire upper half of every range — is unreachable. A test usingAny.Decimal().Between(0m, 100m)to exercise "any valid percentage" silently never exercises 50–100. This inverts the library's core promise ("arbitrary yet valid, so hidden assumptions surface") into a hidden assumption of its own.Reproduced against the built library: over 200,000 draws of
Any.Decimal().Between(0m, 100m), the maximum observed was 49.99992….Direction
Build the fraction from 96 genuinely uniform mantissa bits — any construction that fills all three limbs without fixing the top bit. For example:
Any equivalent approach is acceptable provided the fraction covers
[0, 1)uniformly and seeded reproducibility is preserved. Note the existing comment ("93 random bits over the full mantissa scale") already documents an intent the code does not meet.Acceptance criteria
Any.Decimal().Between(lo, hi)observes values in both halves of the range, including near the inclusive maximum.Except,OneOf,DifferentFrom) still behave.[0, 1)comment is corrected to describe the real construction.Context
Surfaced by the 2026-07-20 architecture & design audit of the standalone
Dummieslibrary (doc/handwritten/for-maintainers/audit/2026-07-20-dummies-architecture-and-design-audit.md, §4.1(a); branchclaude/dummies-architecture-audit-cru5aq). The defect survived the green test suite because tests assert membership, never reachability — see the companion reachability-tests issue.Filed from the Claude Code session that produced the 2026-07-20 Dummies architecture & design audit: https://claude.ai/code/session_01GvrWFVoG74xiys3oyEft1G