I have to generate random double number in between 0 and 1. How can i do this using C? I\'ve tried to generate an integer number between 0 and one million and then divide th
generate random double number in between 0 and 1
Some things to consider:
Include 1.0??
I'd expect a goal of "in range [0, 1)" rather than "in range [0, 1]". That inclusion of 1.0 creates complexities as it unbalances the distribution. Let us assume [0, 1).
rand()
Quality
rand()
is of unspecified quality and and its range [0...RAND_MAX] might not end 1 less than a power of two. Let us assume rand()
is good enough for now and RAND_MAX
is a Mersenne Number (which is very common) to facilitate joining multiple rand()
calls with a simple ^
.
Small numbers
About half of all positive double
are less than 1.0. Should all of them have a chance?
Typicality DBL_MANT_DIG
is 53 and so:
There are 252 double
values in the [0.5...1.0) range.
There are 252 double
values in the [0.25...0.5) range.
There are 252 double
values in the [0.125...0.25) range.
...
Do we want a 50% chance of a value from the first group, 25% from the next, 12.5% from the next .... ?
Or satisfied with:
Form 253 double
values in the [0.0...1.0) range evenly distributed?
Let us go for the second goal for now - easier to code.
Generate an whole number double
in the range [0...253) and then divide by 253.
RAND_MAX >= 0x7FFF
by definition, so we get at least 15 bits of random bits.
Below is some illustrative code that, not so efficiently, forms a double
[0.0 ... 1.0).
// Illustrative code
double rand_double_01(void) {
unsigned long long r = 0;
#define RANDOM_BITS 15
for (int i = 0; i < DBL_MANT_DIG; i += RANDOM_BITS) {
r <<= RANDOM_BITS;
r ^= rand();
}
r %= 1uLL << DBL_MANT_DIG; // Mask off lower 53 bits
double dr = r; // expected conversion is exact
// scale [0 ... 1.0)
dr /= 1uLL << DBL_MANT_DIG; // expected conversion/quotient exact
return double dr;
}
Note: Above code can fail when DBL_MANT_DIG >= 64
(not common) or FLT_RADIX != 2
(very uncommon).