Reputation: 2459
On Wikipedia, I found the following random number generator:
#include <stdint.h>
/* The state must be seeded so that it is not everywhere zero. */
uint64_t s[ 2 ];
uint64_t next(void) {
uint64_t s1 = s[ 0 ];
const uint64_t s0 = s[ 1 ];
s[ 0 ] = s0;
s1 ^= s1 << 23;
return ( s[ 1 ] = ( s1 ^ s0 ^ ( s1 >> 17 ) ^ ( s0 >> 26 ) ) ) + s0;
}
Now, when implemented, (using a random seed for s[0] and s1), this works nicely, but outputs numbers like:
2318509732609079156, 5455176535758408500, 14446583927462861784, 3420274542024626201, etc.
My question now is: How can I transform these numbers to a uniform real distribution [0,1[, i.e. with 0 included and 1 excluded?
Upvotes: 1
Views: 1114
Reputation: 5844
Assuming that you want a double
result, simply cast the result of your random generator to double
and divide by the maximum value (i.e. 2^64):
double result = next() / (double) std::numeric_limits<uint64_t>::max();
Note that some precision might be lost when converting to 64bit real values, so the values might not be exactly uniformly distributed. If this matters for your application, you shouldn't use this code...
edit: Sorry, this could also result in the value 1
. A simple workaround would be to repeat this until the value is not 1
, or making sure that next()
never returns std::numeric_limits<uint64_t>::max()
.
edit: Even simpler, as inspired by 40two's answer: Call std::uniform_real_distribution with your random generator:
std::uniform_real_distribution<double> distribution(0.0,1.0);
double random_number_in_01 = distribution(next);
Upvotes: 1
Reputation: 42899
In C++11 there's a way to produce uniformly distributed numbers over an interval with std::uniform_real_distribution
:
// uniform_real_distribution
#include <iostream>
#include <random>
int main()
{
std::default_random_engine generator;
std::uniform_real_distribution<double> distribution(0.0,1.0);
double random_number_in_01 = distribution(generator);
return 0;
}
Upvotes: 3