The code for nextInt(int) checks the range number n is a power of two and if so it computes a fast solution:

    return (int) ((n * (long) (nextInt() >>> 1)) >> 31);

This scales a 31 bit positive number by a power of 2 (i.e. n) then discards bits. So this is effectively just a left shift followed by a right shift to discard significant bits from the number. The same result can be achieved using a mask to discard the significant bits:

    return nextInt() & (n-1)

This works if n is a power of 2 as (n-1) will be all the bits set below it. Note: This method is employed by ThreadLocalRandom.

It also makes the method applicable to nextLong(long) since you no longer require the long multiplication arithmetic.

I suggest updating the methods to use masking. Note that the output from the following method will be the same:

    public int nextInt(int n) {
        checkStrictlyPositive(n);

        final int nm1 = n - 1;
        if ((n & nm1) == 0) {
            // Range is a power of 2
            return (nextInt() >>> 1) & nm1;
        }
        int bits;
        int val;
        do {
            bits = nextInt() >>> 1;
            val = bits % n;
        } while (bits - val + nm1 < 0);

        return val;
    }

It can be sped up by removing the unsigned shift for the power of 2 case, but that would make the output change as the least significant bit is now part of the result.

Alex







---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to