Search code examples
c++crandomgsl

Uniform random number generator in closed interval


I need a unbiased uniform random number generator (of double) for c or c++ on a closed interval, say [0,1].

Many random number generators, such as the GSL gsl_rng_uniform(r),works only in open intervals, as [0,1), but this does not fit into my case.

Al.


Solution

  • There is something wrong with the concept of a closed interval unless you have integer values - since the probability of hitting the "end" of the interval is infinitesimally small. If you have an integer random number generator with a maximum value RAND_MAX, then you get a closed interval by computing

    rand() / double(RAND_MAX)
    

    since it will go exactly from 0 to 1 (inclusive)

    If this does not give you sufficient resolution, you could consider "concatenating" multiple random numbers. Given that a double actually has a mantissa of 53 bits (plus one bit that is "always 1"), you could do this (this code assumes that RAND_MAX = 0xFFFFFFFF for readability; you can improve on it...):

    #include <stdio.h>
    #include <stdlib.h>
    
    double goodRand() {
      unsigned long long r;
      unsigned long long int r1, r2;
      r1 = rand();
      r2 = rand();
      r = (r1 << 22) + (r2 & 0x003FFFFF);
      return (double) r/ (double)(0x001FFFFFFFFFFFFF);
    }
    
    int main(void) {
      int i;
      double rMax = 0;
      for (i =0; i < 10000; i++) {
        double temp;
        temp = goodRand();
        rMax = (temp>rMax)?temp:rMax;
      }
      printf("max value is %lf\n", rMax);
    }
    

    Now you have very finely sampled random numbers with a maximum value of 1.0 (inclusive). You can make the code a bit more compact but this is the general idea...