-
Notifications
You must be signed in to change notification settings - Fork 431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Output of gen_range
is platform dependent for usize
#1399
Comments
We could add Should we, in this case, make We could go further and remove support for |
For this use case, we could also change |
What about 16 bit targets? Would they generate |
Yes, we only have |
Similar, recent issues: #1373 #1415. Also, discussions by rand developers: comment in #1196, #809, #805. We should consider this again. To be precise, there are two issues:
SolutionsDocument the portability hazardIn the book: Portability of usize We could document this hazard in more places, especially on Test the rangeWe use this internal method for fn gen_index<R: Rng + ?Sized>(rng: &mut R, ubound: usize) -> usize {
if ubound <= (core::u32::MAX as usize) {
rng.gen_range(0..ubound as u32) as usize
} else {
rng.gen_range(0..ubound)
}
} This is an extra conditional-jump on 64-bit platforms, but one which almost always resolves to the first branch in practice, and thus likely has a little cost in most cases. We could use this approach also for the impl of Above + remove non-portable
|
Locations where non-portable generation of
As a lesser form of non-portability, the following support
From the above, Non-portable wrapperWe could add a wrapper type, We can then remove support for generating unwrapped |
FYI I'm strongly considering removing all support for random
We could even release this, then add sampling back later if there is a significant demand — though I'd prefer not to, since this is non-portable behaviour, and any case where random |
Couldn't we make it portable (by using |
We could do. There's already |
Small update: #1471 and |
Changed in #1487. |
The output of
Rng::gen_range
is different depending on whetherusize
is 32 bits or 64 bits on the current platform, even if the requested range is small (0..12
in my case). For example:On a 64-bits system, the output is:
4 8 6 0 5 1 5 8 9 10 11 7 6 11 1 8
On a 32-bits system, the output is:
4 1 8 0 6 1 0 8 5 11 1 9 5 5 8 6
This does not affect
SliceRandom::choose
, thanks to some special handling ingen_index
:rand/src/seq/mod.rs
Lines 699 to 710 in 7ff0fc9
This means that, contrary to my expectations,
my_slice.choose(&mut rng)
andmy_slice[rng.gen_range(0..my_slice.len())]
are not equivalent (even ignoring the case of an empty slice).I'm not sure if this qualifies as a bug, but it definitely surprised me, and took me some time to debug. I'm also not sure if it can be fixed, and if fixing it would constitute a breaking change.
In any case it could be documented, here in the book and here on
Rng::gen_range
.The text was updated successfully, but these errors were encountered: