Skip to content

Consider adding next_f32/next_f64 methods to rand::Rng #425

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

Closed
huonw opened this issue Oct 30, 2014 · 0 comments · Fixed by rust-lang/rust#18534
Closed

Consider adding next_f32/next_f64 methods to rand::Rng #425

huonw opened this issue Oct 30, 2014 · 0 comments · Fixed by rust-lang/rust#18534

Comments

@huonw
Copy link
Member

huonw commented Oct 30, 2014

There are random number generators that generate floating point numbers directly (e.g. dSFMT). Currently, implementing the rand::Rng trait requires next_u32 and possibly next_u64 (which must be implemented to be uniformly distributed) so these random number generators require some very inefficient contortions to fit into this interface, and don't get any speed benefit when generating f32s or f64s since everything goes via next_u32 and next_u64.

I propose changing rand to:

impl Rand for f32 {
    fn rand<R: Rng>(rng: &mut R) -> f32 {
        rng.next_f32()
    }
}

trait Rng {
    // ...

    /// Override if your RNG can generate [0, 1) numbers more efficiently.
    fn next_f32(&mut self) -> f32 {
        (rng.next_u32() >> 8) as f32 / (1 << 24) as f32
    }
}

and similarly for f64. This means a RNG that creates floating point numbers directly can override next_f32 and next_f64 so that generic users reap the benefits.

Random numbers are often used for numeric simulations, and so this seems like a sensible addition, and I cannot think of any other core types that deserve an explicit specialisation in this form so this shouldn't be a slippery slope.

huonw added a commit to rust-random/rand that referenced this issue Feb 3, 2015
Some random number generates output floating point numbers directly, so
by providing these methods all the functionality in librand is available
with high-performance for these things.

An example of such an is dSFMT (Double precision SIMD-oriented Fast
Mersenne Twister).

The choice to use the open interval [0, 1) has backing elsewhere,
e.g. GSL (GNU Scientific Library) uses this range, and dSFMT supports
generating this natively (I believe the most natural range for that
library is [1, 2), but that is not totally sensible from a user
perspective, and would trip people up).

Fixes rust-lang/rfcs#425.
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 a pull request may close this issue.

1 participant