Java: creating random numbers with a logarithmic distribution

I am trying to create random numbers with a logarithmic distribution.

Where n = 1 occurs half the time, n = 2 occurs a quarter times, n = 3 - the eighth time, etc.

    int maxN = 5;
    int t = 1 << (maxN); // 2^maxN
    int n = maxN -
            ((int) (Math.log((Math.random() * t))
            / Math.log(2))); // maxN - log2(1..maxN)
    System.out.println("n=" + n);

In most cases, I get the result that I need, but since so often I get a value nthat is greater than maxN.

Why is this so? As I see it, the maximum value Math.random()is 1.0; therefore, the maximum value (Math.random() * t))is equal t,
therefore, the maximum value of log2 (t) is maxN, since t = 2 ^ maxN;

Where did my logic disappear?

thank

+3
source share
3

1,0 . , 1,0, ((int) (Math.log(Math.random() * t) / Math.log(2))) , , maxN - (the negative number) , maxN.

.

n = Math.floor(Math.log((Math.random() * t) + 1)/Math.log(2))

, :

0.0 <= Math.random() <= 1.0
0.0 <= Math.random() * t <= t
1.0 <= (Math.random() * t) + 1 <= t + 1.0
0.0 <= Math.log((Math.random() * t) + 1) <= Math.log(t + 1.0)
0.0 <= Math.log((Math.random() * t) + 1)/Math.log(2) <= Math.log(t + 1.0)/Math.log(2)

Since t = 2^maxN,
Math.log(t + 1.0)/Math.log(2) is slightly larger than maxN.

So do a Math.floor and you get the correct result:
0.0 <= Math.floor(Math.log((Math.random() * t) + 1)/Math.log(2)) <= maxN
+6

Math.random()*t 1, , Math.log(Math.random()*t) . , , Math.log(2), 0,69314718055994530941723212145818. , . . maxN - = maxN + - , n maxN. Math.random() * t int 1:

int n = maxN -
        ((int) (Math.log((int)((Math.random() * t)+1))
        / Math.log(2))); // maxN - log2(1..maxN)

1.

, 0. 0. , 1 maxN , Math.random() 1. , 1 , 2, , 3 , 0. 0, , 1 , 2 ..

+2

The problem is at the other end of the scale.

Think about what happens if you get a very small random number.

+1
source

Source: https://habr.com/ru/post/1765503/


All Articles