Reputation: 4937
I'm implementing my own random number generator, and the algorithm I'm using naturally gives me a nextLong()
method. However, using this core method, I need to implement the other standard methods, such as nextLong(long)
, nextInt()
, nextDouble()
, and so on, in terms of nextLong()
. For example:
public long nextLong(long n) {
long bits, val;
do {
bits = (nextLong() << 1) >>> 1;
val = bits % n;
} while (bits - val + n - 1 < 0L);
return val;
}
public int nextInt() {
return (int)nextLong();
}
How can I implement nextDouble
?
Upvotes: 0
Views: 153
Reputation: 159086
Don't know what the purpose of doing it yourself is, but you could just do it the same way the built-in Random
class does it for nextDouble()
, as described in the javadoc:
The method
nextDouble
is implemented by classRandom
as if by:public double nextDouble() { return (((long)next(26) << 27) + next(27)) / (double)(1L << 53); }
Since you don't have an int next(int bits)
method, but you do have a nextLong()
method, use the fact that ((long)next(26) << 27) + next(27)
is equivalent to next(53)
. It was done the long way because the next(int)
method returns an int
, i.e. max. 32 bits.
To get 53 bits from a long, you can use either the low or high 53 bits, your choice:
long low53 = nextLong() & ((1L << 53) - 1);
long high53 = nextLong() >>> (64 - 53);
So, your code would be:
private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53)
public double nextDouble() {
return (nextLong() >>> (64 - 53)) * DOUBLE_UNIT;
}
The DOUBLE_UNIT
stuff is how Random
actually does it internally, because multiplication is faster than division, e.g. see Floating point division vs floating point multiplication.
Upvotes: 3