Addendum:
Taking a look at the java.util.Random
source code included with the distribution of Oracle JDK 7 ("Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms") shows this simple code:
class Random {
public float nextFloat() {
return next(24) / ((float)(1 << 24));
}
protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this.seed;
do {
oldseed = seed.get();
nextseed = (oldseed * multiplier + addend) & mask;
} while (!seed.compareAndSet(oldseed, nextseed));
return (int)(nextseed >>> (48 - bits));
}
}
Thus, for nextFloat()
:
- Take a "random integer value" between 0 and 2^24-1 (or rather, a random 24-bit bitpattern interpreted as an integer value),
- Convert it to float (in Java, "float" is mandated to be an IEEE 724 32-bit floating point, which can represent up to 2^24 with no loss of precision, and this will thus be a value between 0 and 1.6777215E7)
- Then divide it by the float representation of 2^24, again just representable with no loss of precision as 1.6777216E7. 2^24+1 = 16777217 would drop down to 1.6777216E7 when forced to be float. In the code, this should really be a constant. Hey Sun, cycles don't grow on trees!!
- Division results in a float in [0.0 .. 0.99999994] (the correct division result would be around 0.999999940395355224609375), with, I think, all the possible IEEE 724 floating point values in between 'equally possible'.
See also IEEE floating point and Floating-Point Arithmetic on the JVM.
The Javadoc comments for `next() is:
/**
* Generates the next pseudorandom number. Subclasses should
* override this, as this is used by all other methods.
*
* <p>The general contract of {@code next} is that it returns an
* {@code int} value and if the argument {@code bits} is between
* {@code 1} and {@code 32} (inclusive), then that many low-order
* bits of the returned value will be (approximately) independently
* chosen bit values, each of which is (approximately) equally
* likely to be {@code 0} or {@code 1}. The method {@code next} is
* implemented by class {@code Random} by atomically updating the seed to
* <pre>{@code (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)}</pre>
* and returning
* <pre>{@code (int)(seed >>> (48 - bits))}.</pre>
*
* This is a linear congruential pseudorandom number generator, as
* defined by D. H. Lehmer and described by Donald E. Knuth in
* <i>The Art of Computer Programming,</i> Volume 3:
* <i>Seminumerical Algorithms</i>, section 3.2.1.
*
* @param bits random bits
* @return the next pseudorandom value from this random number
* generator's sequence
* @since 1.1
*/
The Javadoc comments for nextFloat()
is:
/**
* Returns the next pseudorandom, uniformly distributed {@code float}
* value between {@code 0.0} and {@code 1.0} from this random
* number generator's sequence.
*
* <p>The general contract of {@code nextFloat} is that one
* {@code float} value, chosen (approximately) uniformly from the
* range {@code 0.0f} (inclusive) to {@code 1.0f} (exclusive), is
* pseudorandomly generated and returned. All 2<font
* size="-1"><sup>24</sup></font> possible {@code float} values
* of the form <i>m x </i>2<font
* size="-1"><sup>-24</sup></font>, where <i>m</i> is a positive
* integer less than 2<font size="-1"><sup>24</sup> </font>, are
* produced with (approximately) equal probability.
*
* <p>The method {@code nextFloat} is implemented by class {@code Random}
* as if by:
* <pre> {@code
* public float nextFloat() {
* return next(24) / ((float)(1 << 24));
* }}</pre>
*
* <p>The hedge "approximately" is used in the foregoing description only
* because the next method is only approximately an unbiased source of
* independently chosen bits. If it were a perfect source of randomly
* chosen bits, then the algorithm shown would choose {@code float}
* values from the stated range with perfect uniformity.<p>
* [In early versions of Java, the result was incorrectly calculated as:
* <pre> {@code
* return next(30) / ((float)(1 << 30));}</pre>
* This might seem to be equivalent, if not better, but in fact it
* introduced a slight nonuniformity because of the bias in the rounding
* of floating-point numbers: it was slightly more likely that the
* low-order bit of the significand would be 0 than that it would be 1.]
*
* @return the next pseudorandom, uniformly distributed {@code float}
* value between {@code 0.0} and {@code 1.0} from this
* random number generator's sequence
*/