Skip to content

Keep NextDoubleExclusive strictly below 1 at the top draw [patch] - #92

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/next-double-exclusive-upper-bound
Oct 6, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/next-double-exclusive-upper-bound

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #60

What was wrong

NextDoubleExclusive() scaled (NextUInt64() >> 11) + 0.5 by 2^-53. For the largest 53-bit draw, (2^53 - 1) + 0.5 is a tie between 2^53 - 1 and 2^53, and round-half-to-even picks 2^53. The method returned exactly 1.0, so Normal(0,1).Sample and LogNormal.Sample returned +Infinity.

Change

  • Draw 52 bits and scale by 2^-52 (RandomHelpers.OpenUnitScale). Every half-step sum is now exact, so results lie in [2^-53, 1 - 2^-53].
  • Updated the remarks to explain why it uses 52 bits rather than 53.

Tests

  • NextDoubleExclusive_Excludes_Both_Ends_At_The_Extreme_Draws uses a constant-word stub provider for ulong.MaxValue and 0. It asserts 0 < u < 1 and that Normal and LogNormal samples are finite.
  • With the fix reverted, the ulong.MaxValue case fails with NextDoubleExclusive returned 1. With the fix, it passes.
  • The full suite passes on net10.0: 928 tests, 0 failed.

Related: #61 covers a separate boundary bug in NextDouble(min, max) and is left to its own PR.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ABXREnMPNwAYQMdr4STcfE


Generated by Claude Code

The 53-bit draw plus half a step is not representable for the largest
draw: (2^53 - 1) + 0.5 is a tie that rounds to even, 2^53, so the method
returned exactly 1.0 and Normal/LogNormal Sample returned +Infinity.
Draw 52 bits instead, so every half-step sum is exact and the result
lies in [2^-53, 1 - 2^-53].

Fixes #60

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABXREnMPNwAYQMdr4STcfE
@sonarqubecloud

sonarqubecloud Bot commented Oct 6, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NextDoubleExclusive() can return exactly 1.0, so Normal/LogNormal Sample returns +Infinity

2 participants