--- jsr166/src/main/java/util/SplittableRandom.java 2013/07/10 15:40:19 1.1
+++ jsr166/src/main/java/util/SplittableRandom.java 2013/07/11 23:14:45 1.5
@@ -40,7 +40,7 @@ import java.util.stream.DoubleStream;
* A generator of uniform pseudorandom values applicable for use in
* (among other contexts) isolated parallel computations that may
* generate subtasks. Class SplittableRandom supports methods for
- * producing pseudorandom nunmbers of type {@code int}, {@code long},
+ * producing pseudorandom numbers of type {@code int}, {@code long},
* and {@code double} with similar usages as for class
* {@link java.util.Random} but differs in the following ways:
*
@@ -74,6 +74,7 @@ import java.util.stream.DoubleStream;
*
*
* @author Guy Steele
+ * @author Doug Lea
* @since 1.8
*/
public class SplittableRandom {
@@ -112,7 +113,7 @@ public class SplittableRandom {
* The value of gamma differs for each instance across a series of
* splits, and is generated using a slightly stripped-down variant
* of the same algorithm, but operating across calls to split(),
- * not calls to nextLong(): Each instance carries the state of
+ * not calls to nextSeed(): Each instance carries the state of
* this generator as nextSplit, and uses mix64(nextSplit) as its
* own gamma value. Computations of gammas themselves use a fixed
* constant as the second argument to the addGammaModGeorge
@@ -177,6 +178,12 @@ public class SplittableRandom {
private static final long DEFAULT_SEED_GAMMA = 0xBD24B73A95FB84D9L;
/**
+ * The least non-zero value returned by nextDouble(). This value
+ * is scaled by a random value of 53 bits to produce a result.
+ */
+ private static final double DOUBLE_UNIT = 1.0 / (1L << 53);
+
+ /**
* The next seed for default constructors.
*/
private static final AtomicLong defaultSeedGenerator =
@@ -310,12 +317,16 @@ public class SplittableRandom {
* evenly divisible by the range. The loop rejects candidates
* computed from otherwise over-represented values. The
* expected number of iterations under an ideal generator
- * varies from 1 to 2, depending on the bound.
+ * varies from 1 to 2, depending on the bound. The loop itself
+ * takes an unlovable form. Because the first candidate is
+ * already available, we need a break-in-the-middle
+ * construction, which is concisely but cryptically performed
+ * within the while-condition of a body-less for loop.
*
* 4. Otherwise, the range cannot be represented as a positive
- * long. Repeatedly generate unbounded longs until obtaining
- * a candidate meeting constraints (with an expected number of
- * iterations of less than two).
+ * long. The loop repeatedly generates unbounded longs until
+ * obtaining a candidate meeting constraints (with an expected
+ * number of iterations of less than two).
*/
long r = mix64(nextSeed());
@@ -375,8 +386,7 @@ public class SplittableRandom {
* @return a pseudorandom value
*/
final double internalNextDouble(double origin, double bound) {
- long bits = (1023L << 52) | (nextLong() >>> 12);
- double r = Double.longBitsToDouble(bits) - 1.0;
+ double r = (nextLong() >>> 11) * DOUBLE_UNIT;
if (origin < bound) {
r = r * (bound - origin) + origin;
if (r == bound) // correct for rounding
@@ -540,8 +550,7 @@ public class SplittableRandom {
* (inclusive) and {@code 1.0} (exclusive)
*/
public double nextDouble() {
- long bits = (1023L << 52) | (nextLong() >>> 12);
- return Double.longBitsToDouble(bits) - 1.0;
+ return (nextLong() >>> 11) * DOUBLE_UNIT;
}
/**
@@ -752,7 +761,8 @@ public class SplittableRandom {
/**
* Returns a stream with the given {@code streamSize} number of
- * pseudorandom {@code double} values.
+ * pseudorandom {@code double} values, each between {@code 0.0}
+ * (inclusive) and {@code 1.0} (exclusive).
*
* @param streamSize the number of values to generate
* @return a stream of {@code double} values
@@ -770,7 +780,8 @@ public class SplittableRandom {
/**
* Returns an effectively unlimited stream of pseudorandom {@code
- * double} values.
+ * double} values, each between {@code 0.0} (inclusive) and {@code
+ * 1.0} (exclusive).
*
* @implNote This method is implemented to be equivalent to {@code
* doubles(Long.MAX_VALUE)}.
@@ -866,8 +877,7 @@ public class SplittableRandom {
public int characteristics() {
return (Spliterator.SIZED | Spliterator.SUBSIZED |
- Spliterator.ORDERED | Spliterator.NONNULL |
- Spliterator.IMMUTABLE);
+ Spliterator.NONNULL | Spliterator.IMMUTABLE);
}
public boolean tryAdvance(IntConsumer consumer) {
@@ -921,8 +931,7 @@ public class SplittableRandom {
public int characteristics() {
return (Spliterator.SIZED | Spliterator.SUBSIZED |
- Spliterator.ORDERED | Spliterator.NONNULL |
- Spliterator.IMMUTABLE);
+ Spliterator.NONNULL | Spliterator.IMMUTABLE);
}
public boolean tryAdvance(LongConsumer consumer) {
@@ -977,8 +986,7 @@ public class SplittableRandom {
public int characteristics() {
return (Spliterator.SIZED | Spliterator.SUBSIZED |
- Spliterator.ORDERED | Spliterator.NONNULL |
- Spliterator.IMMUTABLE);
+ Spliterator.NONNULL | Spliterator.IMMUTABLE);
}
public boolean tryAdvance(DoubleConsumer consumer) {