-
-
Notifications
You must be signed in to change notification settings - Fork 459
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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: