2

I would like to create an integer value between 1 and infinity. I want to have a probability distribution where the smaller the number is, the higher the chance it is generated.

I generate a random value R between 0 and 2.

Take the series

enter image description here

I want to know the smallest m with which my sum is bigger than R.

I need a fast way to determine m. This is would be pretty straightforward if i had R in binary, since m would be equal to the number of 1's my number has in a row from the most significant bit, plus one.

There is an upper limit on the integer this method can generate: integer values have an upper limit and double precision can also only reach so high in the [0;2[ interval. This is irrelevant, however, since it depends on the accuracy of the data representation method.

What would be the fastest way to determine m?

PEC
  • 593
  • 1
  • 5
  • 16

2 Answers2

1

I think, straightforward solution will be OK as this series converges really fast:

if (r >= 2)
    throw new IllegalArgumentException();
double exp2M = 1 / (2 - r);
int x = (int)exp2M;
int ans = 0;
while (x > 0) {
    ++ans;
    x >>= 2;
}
return ans;
Dmitry Ginzburg
  • 7,391
  • 2
  • 37
  • 48
1

Set up the inequality

R <= 2 - 2**-m

Isolate the term with m

2**-m <= 2 - R
-m <= log2(2-R)
m >= -log2(2-R).

So it looks like you want ceiling(-log2(2-R)). This is basically an exponential distribution with discretization -- the algorithm for an exponential is -ln(1-U)/rate, where U is a Uniform(0,1) and 1/rate is the desired mean.

pjs
  • 18,696
  • 4
  • 27
  • 56