# Thread: random number from interval [0,1]

1. ## random number from interval [0,1]

Hello.

I am a student of C language.

How can I generate a pseudo-random real number from interval [0,1] ?

Can it be generalized to any interval? Like [0,a], where 'a' is a parameter?

I tried searching for it, I only found rand(), srand(), random(1), and randomize. None of it actually seems to work for me..

Later I actually succeded with something like

srand( (unsigned)time( NULL ) );
printf( " %6d\n", rand() );

but it only produces up to five digits integers and I cannot divide by 99999 to get it into [0,1].

Thank you.

2. rand() produces a pseudo-random number in the range [0, RAND_MAX]. Thus, you can divide the result of rand() by RAND_MAX and get a float/double value. Note, however, that rand() returns an int, and RAND_MAX is also an int, so simply dividing will result in a value of 0 most of the time, due to integer division, which throws away the decimal portion. Thus, cast one part of it:
Code:
```double rand_0_1(void)
{
return rand() / ((double) RAND_MAX);
}```

3. I agree with anduril462.
Even on the general formula, we have the same effect. ( I used his comment pretty much and I wrote this)
Code:
```#include <stdio.h>
#include <time.h>
#include <stdlib.h>

/* The division of integers usually gives a
* result smaller than max                 */
int randomRange(int min, int max)
{
return ( rand() % ( max - min ) ) + min;
}

int main(void)
{
int i=0;
srand(time(NULL));
while(i++!=10)
printf("%d\n", randomRange(0,2));
return 0;
}```
Source: Random numbers ∈[min, max]

EDIT: I admit I am not sure if we can ever get the max as result..

4. Originally Posted by std10093
EDIT: I admit I am not sure if we can ever get the max as result..
Yep, just use:
Code:
`rand() % (max - min + 1) + min;`

5. So no. It's like passing as argument max+1. But I get your point

6. I prefer to define the function so that a number in the range [0,1) is returened.. In other words, numbers as high as 0.9999... will be generated. With this definition, it is straightforward to define randbetween(x,y) in terms of this function.

Code:
```// return a random double in [0.0, 1.0)
double randfrac(void) {
double res = (rand() % RAND_MAX) / (double)RAND_MAX;
return res;
}

// return random double in [x,y)
double randbetween(double x, double y) {
return randfrac() * (y-x) + x;
}```
For seeding, you can use time(NULL) but it tends to give a poor seed if you run your program multiple times. I use the tv_usec value from gettimeofday

Code:
```// call srand(3) using the time value in microseconds
void doseed(void) {
struct timeval tp;
gettimeofday(&tp, NULL);
unsigned seed = (unsigned)tp.tv_usec;
srand(seed);
}```
Then just call doseed() once before calling any random number generating function

7. Originally Posted by c99tutorial
Code:
```// return a random double in [0.0, 1.0)
double randfrac(void) {
double res = (rand() % RAND_MAX) / (double)RAND_MAX;
return res;
}

// return random double in [x,y)
double randbetween(double x, double y) {
return randfrac() * (y-x) + x;
}```
The method that our fellow forum member Prelude recommended in her article on using rand is:
Code:
```double uniform_deviate(int seed)
{
return seed * (1.0 / (RAND_MAX + 1.0));
}

int r = M + uniform_deviate(rand()) * (N - M);```
though I do not see why uniform_deviate cannot be simplified to:
Code:
```double uniform_deviate(int seed)
{
return seed / (RAND_MAX + 1.0);
}```
plus having uniform_deviate take the pseudorandom number as an argument rather than calling rand() directly (in which case it should be renamed, heh) probably is not as flexible as it could be since RAND_MAX is used directly.

Originally Posted by c99tutorial
For seeding, you can use time(NULL) but it tends to give a poor seed if you run your program multiple times. I use the tv_usec value from gettimeofday
In that same article of hers, Prelude suggests hashing the bytes of a time_t, and I like it, especially with her argument that "the C and C++ standards guarantee that type punning is a portable operation for simple types".

8. Originally Posted by laserlight
though I do not see why uniform_deviate cannot be simplified to:
Code:
```double uniform_deviate(int seed)
{
return seed / (RAND_MAX + 1.0);
}```
Its an optimisation.
Some compilers, notably Visual Studio, wont make that optimisation when configured a certain way. I believe the /fp:strict option prevents the optimisation because it could produce a result that differs in some of the lower bits between doing only the division vs the multiplication (the division is then done at compile time). And of course in this code it shouldn't matter if the result differed by a tiny amount.

There is one issue with both though that I haven't thought of before, if RAND_MAX were a 64-bit value then RAND_MAX + 1.0 is not representable as a double. This would affect both bits of code. I'm not sure if any runtimes have RAND_MAX as a 64-bit data type though, or if that's even allowed.

9. Originally Posted by iMalc
There is one issue with both though that I haven't thought of before, if RAND_MAX were a 64-bit value then RAND_MAX + 1.0 is not representable as a double. This would affect both bits of code. I'm not sure if any runtimes have RAND_MAX as a 64-bit data type though, or if that's even allowed.
To be pedantic about the wording, "RAND_MAX + 1.0 might not be representable as a double". That would, of course, depend on what value the implementation gave to RAND_MAX. But that sort of uncertainty generally leads me to code defensively, as though it is definitely not representable as a double. Both the standard and the rationale seem to have little to say about it, though it appears to be implementation defined (within limits):
Originally Posted by C99 7.20 p3
The macros defined are...
RAND_MAX
which expands to an integer constant expression that is the maximum value returned by
the rand function;
Originally Posted by C999 7.20.2.1 p1
int rand(void);
Those two give a theoretical upper bound is whatever can fit in an int, since that is what rand() must return. On a 64-bit implementation, that could cause problems computing RAND_MAX + 1.0.
Originally Posted by C99 7.20.2.1 p5
The value of the RAND_MAX macro shall be at least 32767.
That gives a lower bound.

10. Originally Posted by iMalc
There is one issue with both though that I haven't thought of before, if RAND_MAX were a 64-bit value then RAND_MAX + 1.0 is not representable as a double. This would affect both bits of code.
Good point, but...

Originally Posted by anduril462
But that sort of uncertainty generally leads me to code defensively, as though it is definitely not representable as a double.
I think that if you are concerned about this, then perhaps a (static) assertion for this would work. As far as I can tell, it is not guaranteed that all values in the range of int are representable in the range of double or even long double, hence even a simple cast (without the addition) could be problematic on a given implementation.

If that is not feasible, I guess another approach is to use the rejection method of reducing the integer range such that you get a range that will be fine for conversion to double.

11. Thank you for replies.

Originally Posted by c99tutorial
Code:
```// call srand(3) using the time value in microseconds
void doseed(void) {
struct timeval tp;
gettimeofday(&tp, NULL);
unsigned seed = (unsigned)tp.tv_usec;
srand(seed);
}```
Just here in seeding.. This leads to announcing a error while compiling:

"In function doseed() storage size of tp isn't known"

How can I correct it?

12. The struct timeval structure represents an elapsed time. It is declared in sys/time.h and has the following members:

long int tv_sec
This represents the number of whole seconds of elapsed time.
long int tv_usec
This is the rest of the elapsed time (a fraction of a second), represented as the number of microseconds. It is always less than one million.
So, if you have not included sys/time.h then you won't know the size of it.