lundi 8 mars 2021

Understanding Java Random next Integer with bound algorithm

I'm looking at the way the Java Random library generates an integer given an upper bound, but I don't quite understand the algorithm. In the docs it says:

The algorithm is slightly tricky. It rejects values that would result in an uneven distribution (due to the fact that 2^31 is not divisible by n). The probability of a value being rejected depends on n. The worst case is n=2^30+1, for which the probability of a reject is 1/2, and the expected number of iterations before the loop terminates is 2.

But I really don't see how this implementation takes this into account, specifically the while condition in the code. To me it seems that this would (almost) always succeed with 50% success rate. Especially when looking at very low values for bound (which I think is used a lot when imposing a bound). It seems to me like the condition in the while is just checking the sign of bits, so why bother with the line they use?

public int nextInt(int bound) {
   if (bound <= 0)
        throw new IllegalArgumentException("bound must be positive");

      if ((bound & -bound) == bound)  // i.e., bound is a power of 2
        return (int)((bound * (long)next(31)) >> 31);

      int bits, val;
      do {
          bits = next(31);
          val = bits % bound;
      } while (bits - val + (bound-1) < 0);
      return val;
 }



Aucun commentaire:

Enregistrer un commentaire