how to represent these kind of probabilities in C++?

Assuming the purpose of the 1,000,000 element array is to randomly pick one of the seven elements in a non-linear distribution with (at least) six decimal digits of accuracy, there’s easier ways to do that.

You showed you could normalize the probabilities to sum to 1 (good!), so step one would be to normalize them to integers summing to 1,073,741,824 (2^30):

0.00112       ->   1903498.331       ->   1903498
0.12311       -> 209231856.7         -> 209231857
0.3933393     -> 668500626.0         -> 668500626
0.111010      -> 188667276.5         -> 188667276  (I rounded this down)
0.0002        ->    339910.4162      ->    339910
0.003         ->   5098656.244       ->   5098656
0.00000000004 ->         0.067982083 ->         1  (I rounded this up)

and put their sums into an array:

static const int dist[7] = {1903498, 
                            211135355, 
                            879635981, 
                            1068303257, 
                            1068643167, 
                            1073741823, 
                            1073741824}; //last should be 1073741824

and then to pick a random one with your distribution:

element getrandom(element data[7]) {
    int r = ((rand() * RAND_MAX) ^ rand()) & 0x3FFFFFFF; //(2^30)-1
    for(int i=0; i<6; ++i) {
        if (r < dist[i]) return data[i];
    }
    return data[6];
}

This will be MUCH faster to initialize, MUCH smaller, and probably faster.
Note that even with six digits of accuracy, that last one wouldn’t appear ever. I fudged it’s odds up to the minimum to show.

Leave a Comment