Skip to content

Unbiased ints (breaking, 3.0.0) - #2

Merged
tacyarg merged 2 commits into
masterfrom
fix/unbiased-ints
Sep 28, 2026
Merged

tacyarg merged 2 commits into
masterfrom
fix/unbiased-ints

Conversation

@tacyarg

@tacyarg tacyarg commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

ints() used floor(min + float * max). When max doesn't divide 2^32, some results come up one draw more often than others. When max is above 2^32 it could only return multiples of 2^(bits over 32). This switches to Lemire's multiply-shift with rejection: it gives exactly the same value as the old mapping for every accepted u32 (0 differences in 5.2M sampled draws at max 1e6/1e9/3e9) and redraws the rest. It's breaking because a draw that hits a rejected value now returns a different number. That happens to (2^32 mod max)/2^32 of integers: ~1e-9 at max=6, 0.0225% at max=1e6, 6.9% at max=1e9, 30% at max=3e9. max > 2^32 now throws. floats, ByteGenerator, bytesToFloat and floatToInt are unchanged. Tests: 180 pass, including new rejection vectors. Release after merge: npm version major.

@tacyarg
tacyarg merged commit c221bd3 into master Sep 28, 2026
5 checks passed
@tacyarg
tacyarg deleted the fix/unbiased-ints branch September 28, 2026 23:51
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.

1 participant