Reorganize the abstract and interface classes.
--- a/src/java.base/share/classes/java/security/SecureRandom.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/security/SecureRandom.java Fri Jul 26 15:37:05 2019 -0300
@@ -27,7 +27,7 @@
import java.math.BigInteger;
import java.util.*;
-import java.util.random.RandomNumberGenerator;
+import java.util.random.RandomGenerator;
import java.util.regex.*;
import java.security.Provider.Service;
import sun.security.jca.*;
@@ -1030,7 +1030,7 @@
*/
@Override
public BigInteger period() {
- return RandomNumberGenerator.HUGE_PERIOD;
+ return RandomGenerator.HUGE_PERIOD;
}
// Declare serialVersionUID to be compatible with JDK1.1
--- a/src/java.base/share/classes/java/util/Random.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/Random.java Fri Jul 26 15:37:05 2019 -0300
@@ -29,13 +29,19 @@
import java.io.*;
import java.math.BigInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.DoubleConsumer;
+import java.util.function.Function;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
import java.util.Objects;
+import java.util.random.RandomGenerator;
+import java.util.random.RandomSupport;
+import java.util.random.RandomSupport.AbstractSpliteratorGenerator;
+import java.util.random.RandomSupport.RandomSpliterator;
import java.util.ServiceLoader;
import java.util.ServiceLoader.Provider;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.Function;
-import java.util.random.AbstractSharedRNG;
-import java.util.random.RandomNumberGenerator;
+import java.util.Spliterator;
import java.util.stream.Collectors;
/**
@@ -76,7 +82,7 @@
* @since 1.0
*/
public
-class Random extends AbstractSharedRNG implements java.io.Serializable {
+class Random extends AbstractSpliteratorGenerator implements java.io.Serializable {
/** use serialVersionUID from JDK 1.1 for interoperability */
static final long serialVersionUID = 3905348978240129619L;
@@ -507,24 +513,24 @@
*
* @since 14
*/
- public static RandomNumberGenerator byName(String name) throws IllegalArgumentException {
+ public static RandomGenerator byName(String name) throws IllegalArgumentException {
Objects.requireNonNull(name);
- Map<String, Provider<RandomNumberGenerator>> rngs = getRNGMap();
- Provider<RandomNumberGenerator> provider = rngs.get(name.toUpperCase());
+ Map<String, Provider<RandomGenerator>> rngs = getGeneratorMap();
+ Provider<RandomGenerator> provider = rngs.get(name.toUpperCase());
if (provider == null) {
throw new IllegalArgumentException(name + " is an unknown random number generator");
}
return provider.get();
}
- private static Map<String, Provider<RandomNumberGenerator>> rngMap;
+ private static Map<String, Provider<RandomGenerator>> rngMap;
- private static Map<String, Provider<RandomNumberGenerator>> getRNGMap() {
+ private static Map<String, Provider<RandomGenerator>> getGeneratorMap() {
if (rngMap == null) {
synchronized (Random.class) {
if (rngMap == null) {
rngMap = ServiceLoader
- .load(RandomNumberGenerator.class)
+ .load(RandomGenerator.class)
.stream()
.filter(p -> !p.type().isInterface())
.collect(Collectors.toMap(p -> p.type().getSimpleName().toUpperCase(),
@@ -601,4 +607,158 @@
private void resetSeed(long seedVal) {
unsafe.putReferenceVolatile(this, seedOffset, new AtomicLong(seedVal));
}
+
+ // Methods required by class AbstractSpliteratorGenerator
+ public Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) {
+ return new RandomIntsSpliterator(this, index, fence, origin, bound);
+ }
+ public Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound) {
+ return new RandomLongsSpliterator(this, index, fence, origin, bound);
+ }
+ public Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound) {
+ return new RandomDoublesSpliterator(this, index, fence, origin, bound);
+ }
+
+ /**
+ * Spliterators for producing streams. These are based on abstract spliterator classes provided
+ * by class AbstractSpliteratorGenerator. Each one needs to define only a constructor and two
+ * methods.
+ */
+ static class RandomIntsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfInt {
+ final AbstractSpliteratorGenerator generatingGenerator;
+ final int origin;
+ final int bound;
+
+ RandomIntsSpliterator(AbstractSpliteratorGenerator generatingGenerator, long index, long fence, int origin, int bound) {
+ super(index, fence);
+ this.generatingGenerator = generatingGenerator;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public Spliterator.OfInt trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ if (m <= i) return null;
+ index = m;
+ // The same generatingGenerator is used, with no splitting or copying.
+ return new RandomIntsSpliterator(generatingGenerator, i, m, origin, bound);
+ }
+
+ public boolean tryAdvance(IntConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(RandomSupport.boundedNextInt(generatingGenerator, origin, bound));
+ index = i + 1;
+ return true;
+ }
+ else return false;
+ }
+
+ public void forEachRemaining(IntConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ RandomGenerator r = generatingGenerator;
+ int o = origin, b = bound;
+ do {
+ consumer.accept(RandomSupport.boundedNextInt(r, o, b));
+ } while (++i < f);
+ }
+ }
+ }
+
+ /**
+ * Spliterator for long streams.
+ */
+ static class RandomLongsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfLong {
+ final AbstractSpliteratorGenerator generatingGenerator;
+ final long origin;
+ final long bound;
+
+ RandomLongsSpliterator(AbstractSpliteratorGenerator generatingGenerator, long index, long fence, long origin, long bound) {
+ super(index, fence);
+ this.generatingGenerator = generatingGenerator;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public Spliterator.OfLong trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ if (m <= i) return null;
+ index = m;
+ // The same generatingGenerator is used, with no splitting or copying.
+ return new RandomLongsSpliterator(generatingGenerator, i, m, origin, bound);
+ }
+
+ public boolean tryAdvance(LongConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(RandomSupport.boundedNextLong(generatingGenerator, origin, bound));
+ index = i + 1;
+ return true;
+ }
+ else return false;
+ }
+
+ public void forEachRemaining(LongConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ RandomGenerator r = generatingGenerator;
+ long o = origin, b = bound;
+ do {
+ consumer.accept(RandomSupport.boundedNextLong(r, o, b));
+ } while (++i < f);
+ }
+ }
+ }
+
+ /**
+ * Spliterator for double streams.
+ */
+ static class RandomDoublesSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfDouble {
+ final AbstractSpliteratorGenerator generatingGenerator;
+ final double origin;
+ final double bound;
+
+ RandomDoublesSpliterator(AbstractSpliteratorGenerator generatingGenerator, long index, long fence, double origin, double bound) {
+ super(index, fence);
+ this.generatingGenerator = generatingGenerator;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public Spliterator.OfDouble trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ if (m <= i) return null;
+ index = m;
+ // The same generatingGenerator is used, with no splitting or copying.
+ return new RandomDoublesSpliterator(generatingGenerator, i, m, origin, bound);
+ }
+
+ public boolean tryAdvance(DoubleConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(RandomSupport.boundedNextDouble(generatingGenerator, origin, bound));
+ index = i + 1;
+ return true;
+ }
+ else return false;
+ }
+
+ public void forEachRemaining(DoubleConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ RandomGenerator r = generatingGenerator;
+ double o = origin, b = bound;
+ do {
+ consumer.accept(RandomSupport.boundedNextDouble(r, o, b));
+ } while (++i < f);
+ }
+ }
+ }
}
--- a/src/java.base/share/classes/java/util/SplittableRandom.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/SplittableRandom.java Fri Jul 26 15:37:05 2019 -0300
@@ -26,9 +26,9 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
-import java.util.random.AbstractSplittableRNG;
-import java.util.random.RNGSupport;
-import java.util.random.SplittableRNG;
+import java.util.random.RandomGenerator.SplittableGenerator;
+import java.util.random.RandomSupport;
+import java.util.random.RandomSupport.AbstractSplittableGenerator;
/**
* A generator of uniform pseudorandom values applicable for use in
@@ -82,7 +82,7 @@
* @author Doug Lea
* @since 1.8
*/
-public final class SplittableRandom extends AbstractSplittableRNG {
+public final class SplittableRandom extends AbstractSplittableGenerator {
/*
* Implementation Overview.
@@ -216,7 +216,7 @@
/**
* The seed generator for default constructors.
*/
- private static final AtomicLong defaultGen = new AtomicLong(RNGSupport.initialSeed());
+ private static final AtomicLong defaultGen = new AtomicLong(RandomSupport.initialSeed());
/* ---------------- public methods ---------------- */
@@ -263,7 +263,7 @@
return new SplittableRandom(nextLong(), mixGamma(nextSeed()));
}
- public SplittableRandom split(SplittableRNG source) {
+ public SplittableRandom split(SplittableGenerator source) {
return new SplittableRandom(source.nextLong(), mixGamma(source.nextLong()));
}
--- a/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java Fri Jul 26 15:37:05 2019 -0300
@@ -33,7 +33,7 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*
* Additional modifications by Guy Steele in 2019 to refactor the code
- * and to implement the {@link RandomNumberGenerator} interface.
+ * and to implement the {@link RandomGenerator} interface.
*/
package java.util.concurrent;
@@ -44,7 +44,7 @@
import java.util.Spliterator;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
-import java.util.random.RNGSupport;
+import java.util.random.RandomSupport;
import jdk.internal.misc.Unsafe;
import jdk.internal.misc.VM;
@@ -123,7 +123,7 @@
* This implementation of ThreadLocalRandom overrides the
* definition of the nextGaussian() method in the class Random,
* and instead uses the ziggurat-based algorithm that is the
- * default for the RandomNumberGenerator interface.
+ * default for the RandomGenerator interface.
*/
private static int mix32(long z) {
@@ -152,7 +152,7 @@
static final void localInit() {
int p = probeGenerator.addAndGet(PROBE_INCREMENT);
int probe = (p == 0) ? 1 : p; // skip 0
- long seed = RNGSupport.mixMurmur64(seeder.getAndAdd(SEEDER_INCREMENT));
+ long seed = RandomSupport.mixMurmur64(seeder.getAndAdd(SEEDER_INCREMENT));
Thread t = Thread.currentThread();
U.putLong(t, SEED, seed);
U.putInt(t, PROBE, probe);
@@ -216,7 +216,7 @@
* @return a pseudorandom {@code long} value
*/
public long nextLong() {
- return RNGSupport.mixMurmur64(nextSeed());
+ return RandomSupport.mixMurmur64(nextSeed());
}
// Within-package utilities
@@ -375,8 +375,8 @@
* The next seed for default constructors.
*/
private static final AtomicLong seeder
- = new AtomicLong(RNGSupport.mixMurmur64(System.currentTimeMillis()) ^
- RNGSupport.mixMurmur64(System.nanoTime()));
+ = new AtomicLong(RandomSupport.mixMurmur64(System.currentTimeMillis()) ^
+ RandomSupport.mixMurmur64(System.nanoTime()));
// at end of <clinit> to survive static initialization circularity
static {
--- a/src/java.base/share/classes/java/util/random/AbstractArbitrarilyJumpableRNG.java Fri Jul 26 15:20:31 2019 -0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,534 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.random;
-
-import java.util.Spliterator;
-import java.util.function.Consumer;
-import java.util.function.DoubleConsumer;
-import java.util.function.IntConsumer;
-import java.util.function.LongConsumer;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-
-/**
- * This class provides much of the implementation of the
- * {@link ArbitrarilyJumpableRNG} interface, to minimize the effort
- * required to implement that interface.
- *
- * To implement a pseudorandom number generator, the programmer needs
- * only to extend this class and provide implementations for the
- * methods {@code nextInt()}, {@code nextLong()}, {@code copy()},
- * {@code jump(distance)}, {@code jumpPowerOfTwo(distance)},
- * {@code defaultJumpDistance()}, and {@code defaultLeapDistance()}.
- *
- * (If the pseudorandom number generator also has the ability to split,
- * then the programmer may wish to consider instead extending
- * {@link AbstractSplittableRNG}.)
- *
- * The programmer should generally provide at least three constructors:
- * one that takes no arguments, one that accepts a {@code long}
- * seed value, and one that accepts an array of seed {@code byte} values.
- * This class provides a public {@code initialSeed()} method that may
- * be useful in initializing some static state from which to derive
- * defaults seeds for use by the no-argument constructor.
- *
- * For the stream methods (such as {@code ints()} and {@code splits()}),
- * this class provides {@link Spliterator}-based implementations that
- * allow parallel execution when appropriate. In this respect
- * {@link ArbitrarilyJumpableRNG} differs from {@link JumpableRNG},
- * which provides very simple implementations that produce
- * sequential streams only.
- *
- * <p>An implementation of the {@link AbstractArbitrarilyJumpableRNG} class
- * must provide concrete definitions for the methods {@code nextInt()},
- * {@code nextLong}, {@code period()}, {@code copy()}, {@code jump(double)},
- * {@code defaultJumpDistance()}, and {@code defaultLeapDistance()}.
- * Default implementations are provided for all other methods.
- *
- * The documentation for each non-abstract method in this class
- * describes its implementation in detail. Each of these methods may
- * be overridden if the pseudorandom number generator being
- * implemented admits a more efficient implementation.
- *
- * @since 14
- */
-public abstract class AbstractArbitrarilyJumpableRNG
- extends AbstractSpliteratorRNG implements ArbitrarilyJumpableRNG {
-
- /*
- * Implementation Overview.
- *
- * This class provides most of the "user API" methods needed to satisfy
- * the interface ArbitrarilyJumpableRNG. Most of these methods
- * are in turn inherited from AbstractRNG and the non-public class
- * AbstractSpliteratorRNG; this file implements four versions of the
- * jumps method and defines the spliterators necessary to support them.
- *
- * File organization: First the non-public methods needed by the class
- * AbstractSpliteratorRNG, then the main public methods, followed by some
- * custom spliterator classes needed for stream methods.
- */
-
- // IllegalArgumentException messages
- static final String BadLogDistance = "logDistance must be non-negative";
-
- // Methods required by class AbstractSpliteratorRNG
- Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) {
- return new RandomIntsSpliterator(this, index, fence, origin, bound);
- }
- Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound) {
- return new RandomLongsSpliterator(this, index, fence, origin, bound);
- }
- Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound) {
- return new RandomDoublesSpliterator(this, index, fence, origin, bound);
- }
-
- // Similar methods used by this class
- Spliterator<RandomNumberGenerator> makeJumpsSpliterator(long index, long fence, double distance) {
- return new RandomJumpsSpliterator(this, index, fence, distance);
- }
- Spliterator<JumpableRNG> makeLeapsSpliterator(long index, long fence, double distance) {
- return new RandomLeapsSpliterator(this, index, fence, distance);
- }
- Spliterator<ArbitrarilyJumpableRNG> makeArbitraryJumpsSpliterator(long index, long fence, double distance) {
- return new RandomArbitraryJumpsSpliterator(this, index, fence, distance);
- }
-
- /* ---------------- public methods ---------------- */
-
- /**
- * Returns a new generator whose internal state is an exact copy
- * of this generator (therefore their future behavior should be
- * identical if subjected to the same series of operations).
- *
- * @return a new object that is a copy of this generator
- */
- public abstract AbstractArbitrarilyJumpableRNG copy();
-
- // Stream methods for jumping
-
- private static <T> Stream<T> stream(Spliterator<T> srng) {
- return StreamSupport.stream(srng, false);
- }
-
- /**
- * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
- * implements the {@link RandomNumberGenerator} interface, produced by jumping copies of this
- * generator by different integer multiples of the default jump distance.
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @implNote This method is implemented to be equivalent to {@code
- * jumps(Long.MAX_VALUE)}.
- */
- public Stream<RandomNumberGenerator> jumps() {
- return stream(makeJumpsSpliterator(0L, Long.MAX_VALUE, defaultJumpDistance()));
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * new pseudorandom number generators, each of which implements the
- * {@link RandomNumberGenerator} interface, produced by jumping copies of this generator
- * by different integer multiples of the default jump distance.
- *
- * @param streamSize the number of generators to generate
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero
- */
- public Stream<RandomNumberGenerator> jumps(long streamSize) {
- RNGSupport.checkStreamSize(streamSize);
- return stream(makeJumpsSpliterator(0L, streamSize, defaultJumpDistance()));
- }
-
- /**
- * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
- * implements the {@link RandomNumberGenerator} interface, produced by jumping copies of this
- * generator by different integer multiples of the specified jump distance.
- *
- * @param distance a distance to jump forward within the state cycle
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @implNote This method is implemented to be equivalent to {@code
- * jumps(Long.MAX_VALUE)}.
- */
- public Stream<ArbitrarilyJumpableRNG> jumps(double distance) {
- return stream(makeArbitraryJumpsSpliterator(0L, Long.MAX_VALUE, distance));
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
- * generators, each of which implements the {@link RandomNumberGenerator} interface, produced by
- * jumping copies of this generator by different integer multiples of the specified jump
- * distance.
- *
- * @param streamSize the number of generators to generate
- * @param distance a distance to jump forward within the state cycle
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero
- */
- public Stream<ArbitrarilyJumpableRNG> jumps(long streamSize, double distance) {
- RNGSupport.checkStreamSize(streamSize);
- return stream(makeArbitraryJumpsSpliterator(0L, streamSize, distance));
- }
-
- /**
- * Alter the state of this pseudorandom number generator so as to
- * jump forward a very large, fixed distance (typically 2<sup>128</sup>
- * or more) within its state cycle. The distance used is that
- * returned by method {@code defaultLeapDistance()}.
- */
- public void leap() {
- jump(defaultLeapDistance());
- }
-
- // Stream methods for leaping
-
- /**
- * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
- * implements the {@link RandomNumberGenerator} interface, produced by jumping copies of this
- * generator by different integer multiples of the default leap distance.
- *
- * @implNote This method is implemented to be equivalent to {@code leaps(Long.MAX_VALUE)}.
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- */
- public Stream<JumpableRNG> leaps() {
- return stream(makeLeapsSpliterator(0L, Long.MAX_VALUE, defaultLeapDistance()));
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
- * generators, each of which implements the {@link RandomNumberGenerator} interface, produced by
- * jumping copies of this generator by different integer multiples of the default leap
- * distance.
- *
- * @param streamSize the number of generators to generate
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero
- */
- public Stream<JumpableRNG> leaps(long streamSize) {
- return stream(makeLeapsSpliterator(0L, streamSize, defaultLeapDistance()));
- }
-
-
- /**
- * Spliterator for int streams. We multiplex the four int versions into one class by treating a
- * bound less than origin as unbounded, and also by treating "infinite" as equivalent to
- * {@code Long.MAX_VALUE}. For splits, we choose to override the method {@code trySplit()} to
- * try to optimize execution speed: instead of dividing a range in half, it breaks off the
- * largest possible chunk whose size is a power of two such that the remaining chunk is not
- * empty. In this way, the necessary jump distances will tend to be powers of two. The long
- * and double versions of this class are identical except for types.
- */
- static class RandomIntsSpliterator extends RNGSupport.RandomSpliterator implements Spliterator.OfInt {
- final ArbitrarilyJumpableRNG generatingRNG;
- final int origin;
- final int bound;
-
- RandomIntsSpliterator(ArbitrarilyJumpableRNG generatingRNG, long index, long fence, int origin, int bound) {
- super(index, fence);
- this.origin = origin; this.bound = bound;
- this.generatingRNG = generatingRNG;
- }
-
- public Spliterator.OfInt trySplit() {
- long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
- if (m <= i) return null;
- index = m;
- ArbitrarilyJumpableRNG r = generatingRNG;
- return new RandomIntsSpliterator(r.copyAndJump((double)delta), i, m, origin, bound);
- }
-
- public boolean tryAdvance(IntConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(RNGSupport.boundedNextInt(generatingRNG, origin, bound));
- index = i + 1;
- return true;
- }
- else return false;
- }
-
- public void forEachRemaining(IntConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- ArbitrarilyJumpableRNG r = generatingRNG;
- int o = origin, b = bound;
- do {
- consumer.accept(RNGSupport.boundedNextInt(r, o, b));
- } while (++i < f);
- }
- }
- }
-
- /**
- * Spliterator for long streams.
- */
- static class RandomLongsSpliterator extends RNGSupport.RandomSpliterator implements Spliterator.OfLong {
- final ArbitrarilyJumpableRNG generatingRNG;
- final long origin;
- final long bound;
-
- RandomLongsSpliterator(ArbitrarilyJumpableRNG generatingRNG, long index, long fence, long origin, long bound) {
- super(index, fence);
- this.generatingRNG = generatingRNG;
- this.origin = origin; this.bound = bound;
- }
-
- public Spliterator.OfLong trySplit() {
- long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
- if (m <= i) return null;
- index = m;
- ArbitrarilyJumpableRNG r = generatingRNG;
- return new RandomLongsSpliterator(r.copyAndJump((double)delta), i, m, origin, bound);
- }
-
- public boolean tryAdvance(LongConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(RNGSupport.boundedNextLong(generatingRNG, origin, bound));
- index = i + 1;
- return true;
- }
- else return false;
- }
-
- public void forEachRemaining(LongConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- ArbitrarilyJumpableRNG r = generatingRNG;
- long o = origin, b = bound;
- do {
- consumer.accept(RNGSupport.boundedNextLong(r, o, b));
- } while (++i < f);
- }
- }
- }
-
- /**
- * Spliterator for double streams.
- */
- static class RandomDoublesSpliterator extends RNGSupport.RandomSpliterator implements Spliterator.OfDouble {
- final ArbitrarilyJumpableRNG generatingRNG;
- final double origin;
- final double bound;
-
- RandomDoublesSpliterator(ArbitrarilyJumpableRNG generatingRNG, long index, long fence, double origin, double bound) {
- super(index, fence);
- this.generatingRNG = generatingRNG;
- this.origin = origin; this.bound = bound;
- }
-
- public Spliterator.OfDouble trySplit() {
-
- long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
- if (m <= i) return null;
- index = m;
- ArbitrarilyJumpableRNG r = generatingRNG;
- return new RandomDoublesSpliterator(r.copyAndJump((double)delta), i, m, origin, bound);
- }
-
- public boolean tryAdvance(DoubleConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(RNGSupport.boundedNextDouble(generatingRNG, origin, bound));
- index = i + 1;
- return true;
- }
- else return false;
- }
-
- public void forEachRemaining(DoubleConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- ArbitrarilyJumpableRNG r = generatingRNG;
- double o = origin, b = bound;
- do {
- consumer.accept(RNGSupport.boundedNextDouble(r, o, b));
- } while (++i < f);
- }
- }
- }
-
- // Spliterators for producing new generators by jumping or leaping. The
- // complete implementation of each of these spliterators is right here.
- // In the same manner as for the preceding spliterators, the method trySplit() is
- // coded to optimize execution speed: instead of dividing a range
- // in half, it breaks off the largest possible chunk whose
- // size is a power of two such that the remaining chunk is not
- // empty. In this way, the necessary jump distances will tend to be
- // powers of two.
-
- /**
- * Spliterator for stream of generators of type RandomNumberGenerator produced by jumps.
- */
- static class RandomJumpsSpliterator extends RNGSupport.RandomSpliterator implements Spliterator<RandomNumberGenerator> {
- ArbitrarilyJumpableRNG generatingRNG;
- final double distance;
-
- RandomJumpsSpliterator(ArbitrarilyJumpableRNG generatingRNG, long index, long fence, double distance) {
- super(index, fence);
- this.generatingRNG = generatingRNG; this.distance = distance;
- }
-
- public Spliterator<RandomNumberGenerator> trySplit() {
- long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
- if (m <= i) return null;
- index = m;
- ArbitrarilyJumpableRNG r = generatingRNG;
- // Because delta is a power of two, (distance * (double)delta) can always be computed exactly.
- return new RandomJumpsSpliterator(r.copyAndJump(distance * (double)delta), i, m, distance);
- }
-
- public boolean tryAdvance(Consumer<? super RandomNumberGenerator> consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(generatingRNG.copyAndJump(distance));
- index = i + 1;
- return true;
- }
- return false;
- }
-
- public void forEachRemaining(Consumer<? super RandomNumberGenerator> consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- ArbitrarilyJumpableRNG r = generatingRNG;
- do {
- consumer.accept(r.copyAndJump(distance));
- } while (++i < f);
- }
- }
- }
-
- /**
- * Spliterator for stream of generators of type RandomNumberGenerator produced by leaps.
- */
- static class RandomLeapsSpliterator extends RNGSupport.RandomSpliterator implements Spliterator<JumpableRNG> {
- ArbitrarilyJumpableRNG generatingRNG;
- final double distance;
-
- RandomLeapsSpliterator(ArbitrarilyJumpableRNG generatingRNG, long index, long fence, double distance) {
- super(index, fence);
- this.generatingRNG = generatingRNG; this.distance = distance;
- }
-
- public Spliterator<JumpableRNG> trySplit() {
- long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
- if (m <= i) return null;
- index = m;
- // Because delta is a power of two, (distance * (double)delta) can always be computed exactly.
- return new RandomLeapsSpliterator(generatingRNG.copyAndJump(distance * (double)delta), i, m, distance);
- }
-
- public boolean tryAdvance(Consumer<? super JumpableRNG> consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(generatingRNG.copyAndJump(distance));
- index = i + 1;
- return true;
- }
- return false;
- }
-
- public void forEachRemaining(Consumer<? super JumpableRNG> consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- ArbitrarilyJumpableRNG r = generatingRNG;
- do {
- consumer.accept(r.copyAndJump(distance));
- } while (++i < f);
- }
- }
- }
-
- /**
- * Spliterator for stream of generators of type RandomNumberGenerator produced by arbitrary jumps.
- */
- static class RandomArbitraryJumpsSpliterator extends RNGSupport.RandomSpliterator implements Spliterator<ArbitrarilyJumpableRNG> {
- ArbitrarilyJumpableRNG generatingRNG;
- final double distance;
-
- RandomArbitraryJumpsSpliterator(ArbitrarilyJumpableRNG generatingRNG, long index, long fence, double distance) {
- super(index, fence);
- this.generatingRNG = generatingRNG; this.distance = distance;
- }
-
- public Spliterator<ArbitrarilyJumpableRNG> trySplit() {
- long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
- if (m <= i) return null;
- index = m;
- // Because delta is a power of two, (distance * (double)delta) can always be computed exactly.
- return new RandomArbitraryJumpsSpliterator(generatingRNG.copyAndJump(distance * (double)delta), i, m, distance);
- }
-
- public boolean tryAdvance(Consumer<? super ArbitrarilyJumpableRNG> consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(generatingRNG.copyAndJump(distance));
- index = i + 1;
- return true;
- }
- return false;
- }
-
- public void forEachRemaining(Consumer<? super ArbitrarilyJumpableRNG> consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- ArbitrarilyJumpableRNG r = generatingRNG;
- do {
- consumer.accept(r.copyAndJump(distance));
- } while (++i < f);
- }
- }
- }
-
-}
--- a/src/java.base/share/classes/java/util/random/AbstractSharedRNG.java Fri Jul 26 15:20:31 2019 -0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.random;
-
-import java.util.Spliterator;
-import java.util.function.DoubleConsumer;
-import java.util.function.IntConsumer;
-import java.util.function.LongConsumer;
-
-/**
- * This class provides much of the implementation of the {@link RandomNumberGenerator}
- * interface, to minimize the effort required to implement that interface.
- *
- * To implement a pseudorandom number generator, the programmer needs
- * only to extend this class and provide implementations for the
- * {@code nextInt()} and {@code nextLong()} methods. In order for
- * the implementations of other methods in this class to operate
- * correctly, it must be safe for multiple threads to call these
- * methods on that same object. The principal purpose of this class
- * is to support the implementations of {@link java.util.Random}
- * and {@code java.util.concurrent.ThreadLocalRandom}, but it could
- * in principle be used to implement others as well.
- *
- * (If the pseudorandom number generator has the ability to split or
- * jump, then the programmer may wish to consider instead extending
- * another abstract class, such as {@link AbstractSplittableRNG},
- * {@link ArbitrarilyJumpableRNG}, or {@link AbstractArbitrarilyJumpableRNG}.)
- *
- * The programmer should generally provide at least three constructors:
- * one that takes no arguments, one that accepts a {@code long}
- * seed value, and one that accepts an array of seed {@code byte} values.
- * This class provides a public {@code initialSeed()} method that may
- * be useful in initializing some static state from which to derive
- * defaults seeds for use by the no-argument constructor.
- *
- * For the stream methods (such as {@code ints()} and {@code splits()}),
- * this class provides {@link Spliterator}-based implementations that
- * allow parallel execution when appropriate.
- *
- * The documentation for each non-abstract method in this class
- * describes its implementation in detail. Each of these methods may
- * be overridden if the pseudorandom number generator being
- * implemented admits a more efficient implementation.
- *
- * @since 14
- */
-public abstract class AbstractSharedRNG extends AbstractSpliteratorRNG {
- /*
- * Implementation Overview.
- *
- * This class provides most of the "user API" methods needed to
- * satisfy the interface RandomNumberGenerator. Most of these methods
- * are in turn inherited from AbstractRNG and the non-public class
- * AbstractSpliteratorRNG; this file implements methods and spliterators
- * necessary to support the latter.
- *
- * File organization: First some non-public methods, followed by
- * some custom spliterator classes needed for stream methods.
- */
-
- // Methods required by class AbstractSpliteratorRNG
- Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) {
- return new RandomIntsSpliterator(this, index, fence, origin, bound);
- }
- Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound) {
- return new RandomLongsSpliterator(this, index, fence, origin, bound);
- }
- Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound) {
- return new RandomDoublesSpliterator(this, index, fence, origin, bound);
- }
-
- /**
- * Spliterators for producing streams. These are based on abstract spliterator classes provided
- * by class AbstractSpliteratorRNG. Each one needs to define only a constructor and two
- * methods.
- */
- static class RandomIntsSpliterator extends RNGSupport.RandomSpliterator implements Spliterator.OfInt {
- final AbstractSharedRNG generatingRNG;
- final int origin;
- final int bound;
-
- RandomIntsSpliterator(AbstractSharedRNG generatingRNG, long index, long fence, int origin, int bound) {
- super(index, fence);
- this.generatingRNG = generatingRNG;
- this.origin = origin; this.bound = bound;
- }
-
- public Spliterator.OfInt trySplit() {
- long i = index, m = (i + fence) >>> 1;
- if (m <= i) return null;
- index = m;
- // The same generatingRNG is used, with no splitting or copying.
- return new RandomIntsSpliterator(generatingRNG, i, m, origin, bound);
- }
-
- public boolean tryAdvance(IntConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(RNGSupport.boundedNextInt(generatingRNG, origin, bound));
- index = i + 1;
- return true;
- }
- else return false;
- }
-
- public void forEachRemaining(IntConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- RandomNumberGenerator r = generatingRNG;
- int o = origin, b = bound;
- do {
- consumer.accept(RNGSupport.boundedNextInt(r, o, b));
- } while (++i < f);
- }
- }
- }
-
- /**
- * Spliterator for long streams.
- */
- static class RandomLongsSpliterator extends RNGSupport.RandomSpliterator implements Spliterator.OfLong {
- final AbstractSharedRNG generatingRNG;
- final long origin;
- final long bound;
-
- RandomLongsSpliterator(AbstractSharedRNG generatingRNG, long index, long fence, long origin, long bound) {
- super(index, fence);
- this.generatingRNG = generatingRNG;
- this.origin = origin; this.bound = bound;
- }
-
- public Spliterator.OfLong trySplit() {
- long i = index, m = (i + fence) >>> 1;
- if (m <= i) return null;
- index = m;
- // The same generatingRNG is used, with no splitting or copying.
- return new RandomLongsSpliterator(generatingRNG, i, m, origin, bound);
- }
-
- public boolean tryAdvance(LongConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(RNGSupport.boundedNextLong(generatingRNG, origin, bound));
- index = i + 1;
- return true;
- }
- else return false;
- }
-
- public void forEachRemaining(LongConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- RandomNumberGenerator r = generatingRNG;
- long o = origin, b = bound;
- do {
- consumer.accept(RNGSupport.boundedNextLong(r, o, b));
- } while (++i < f);
- }
- }
- }
-
- /**
- * Spliterator for double streams.
- */
- static class RandomDoublesSpliterator extends RNGSupport.RandomSpliterator implements Spliterator.OfDouble {
- final AbstractSharedRNG generatingRNG;
- final double origin;
- final double bound;
-
- RandomDoublesSpliterator(AbstractSharedRNG generatingRNG, long index, long fence, double origin, double bound) {
- super(index, fence);
- this.generatingRNG = generatingRNG;
- this.origin = origin; this.bound = bound;
- }
-
- public Spliterator.OfDouble trySplit() {
- long i = index, m = (i + fence) >>> 1;
- if (m <= i) return null;
- index = m;
- // The same generatingRNG is used, with no splitting or copying.
- return new RandomDoublesSpliterator(generatingRNG, i, m, origin, bound);
- }
-
- public boolean tryAdvance(DoubleConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(RNGSupport.boundedNextDouble(generatingRNG, origin, bound));
- index = i + 1;
- return true;
- }
- else return false;
- }
-
- public void forEachRemaining(DoubleConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- RandomNumberGenerator r = generatingRNG;
- double o = origin, b = bound;
- do {
- consumer.accept(RNGSupport.boundedNextDouble(r, o, b));
- } while (++i < f);
- }
- }
- }
-
-}
--- a/src/java.base/share/classes/java/util/random/AbstractSpliteratorRNG.java Fri Jul 26 15:20:31 2019 -0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,310 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oraclea and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.random;
-
-import java.util.Spliterator;
-import java.util.stream.Stream;
-import java.util.stream.DoubleStream;
-import java.util.stream.IntStream;
-import java.util.stream.LongStream;
-import java.util.stream.StreamSupport;
-
-/**
- * This class overrides the stream-producing methods (such as {@code ints()})
- * in class {@link AbstractRNG} to provide {@link Spliterator}-based
- * implmentations that support potentially parallel execution.
- *
- * To implement a pseudorandom number generator, the programmer needs
- * only to extend this class and provide implementations for the methods
- * {@code nextInt()}, {@code nextLong()}, {@code makeIntsSpliterator},
- * {@code makeLongsSpliterator}, and {@code makeDoublesSpliterator}.
- *
- * This class is not public; it provides shared code to the public
- * classes {@link AbstractSplittableRNG}, {@link AbstractSharedRNG},
- * and {@link AbstractArbitrarilyJumpableRNG}.
- *
- * @since 14
- */
-
-abstract class AbstractSpliteratorRNG implements RandomNumberGenerator {
- /*
- * Implementation Overview.
- *
- * This class provides most of the "user API" methods needed to
- * satisfy the interface RandomNumberGenerator. An implementation of this
- * interface need only extend this class and provide implementations
- * of six methods: nextInt, nextLong, and nextDouble (the versions
- * that take no arguments) and makeIntsSpliterator,
- * makeLongsSpliterator, and makeDoublesSpliterator.
- *
- * File organization: First the non-public abstract methods needed
- * to create spliterators, then the main public methods.
- */
-
- abstract Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound);
- abstract Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound);
- abstract Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound);
-
- /* ---------------- public methods ---------------- */
-
- // stream methods, coded in a way intended to better isolate for
- // maintenance purposes the small differences across forms.
-
- private static IntStream intStream(Spliterator.OfInt srng) {
- return StreamSupport.intStream(srng, false);
- }
-
- private static LongStream longStream(Spliterator.OfLong srng) {
- return StreamSupport.longStream(srng, false);
- }
-
- private static DoubleStream doubleStream(Spliterator.OfDouble srng) {
- return StreamSupport.doubleStream(srng, false);
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code int}
- * values from this generator and/or one split from it.
- *
- * @param streamSize the number of values to generate
- *
- * @return a stream of pseudorandom {@code int} values
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero
- */
- public IntStream ints(long streamSize) {
- RNGSupport.checkStreamSize(streamSize);
- return intStream(makeIntsSpliterator(0L, streamSize, Integer.MAX_VALUE, 0));
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandomly chosen
- * {@code int} values.
- *
- * @implNote The implementation of this method is effectively
- * equivalent to {@code ints(Long.MAX_VALUE)}.
- *
- * @return a stream of pseudorandomly chosen {@code int} values
- */
-
- public IntStream ints() {
- return intStream(makeIntsSpliterator(0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0));
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code int}
- * values from this generator and/or one split from it; each value conforms to the given origin
- * (inclusive) and bound (exclusive).
- *
- * @param streamSize the number of values to generate
- * @param randomNumberOrigin the origin (inclusive) of each random value
- * @param randomNumberBound the bound (exclusive) of each random value
- *
- * @return a stream of pseudorandom {@code int} values, each with the given origin (inclusive)
- * and bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero, or {@code
- * randomNumberOrigin} is greater than or equal to {@code
- * randomNumberBound}
- */
- public IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound) {
- RNGSupport.checkStreamSize(streamSize);
- RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
- return intStream(makeIntsSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandom {@code int} values from this
- * generator and/or one split from it; each value conforms to the given origin (inclusive) and
- * bound (exclusive).
- *
- * @param randomNumberOrigin the origin (inclusive) of each random value
- * @param randomNumberBound the bound (exclusive) of each random value
- *
- * @return a stream of pseudorandom {@code int} values, each with the given origin (inclusive)
- * and bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
- * {@code randomNumberBound}
- *
- * @implNote This method is implemented to be equivalent to {@code ints(Long.MAX_VALUE,
- * randomNumberOrigin, randomNumberBound)}.
- */
- public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
- RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
- return intStream(makeIntsSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound));
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code long}
- * values from this generator and/or one split from it.
- *
- * @param streamSize the number of values to generate
- *
- * @return a stream of pseudorandom {@code long} values
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero
- */
- public LongStream longs(long streamSize) {
- RNGSupport.checkStreamSize(streamSize);
- return longStream(makeLongsSpliterator(0L, streamSize, Long.MAX_VALUE, 0L));
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandom {@code long} values from this
- * generator and/or one split from it.
- *
- * @return a stream of pseudorandom {@code long} values
- *
- * @implNote This method is implemented to be equivalent to {@code
- * longs(Long.MAX_VALUE)}.
- */
- public LongStream longs() {
- return longStream(makeLongsSpliterator(0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L));
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code long}
- * values from this generator and/or one split from it; each value conforms to the given origin
- * (inclusive) and bound (exclusive).
- *
- * @param streamSize the number of values to generate
- * @param randomNumberOrigin the origin (inclusive) of each random value
- * @param randomNumberBound the bound (exclusive) of each random value
- *
- * @return a stream of pseudorandom {@code long} values, each with the given origin (inclusive)
- * and bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero, or {@code
- * randomNumberOrigin} is greater than or equal to {@code
- * randomNumberBound}
- */
- public LongStream longs(long streamSize, long randomNumberOrigin,
- long randomNumberBound) {
- RNGSupport.checkStreamSize(streamSize);
- RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
- return longStream(makeLongsSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandom {@code long} values from this
- * generator and/or one split from it; each value conforms to the given origin (inclusive) and
- * bound (exclusive).
- *
- * @param randomNumberOrigin the origin (inclusive) of each random value
- * @param randomNumberBound the bound (exclusive) of each random value
- *
- * @return a stream of pseudorandom {@code long} values, each with the given origin (inclusive)
- * and bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
- * {@code randomNumberBound}
- *
- * @implNote This method is implemented to be equivalent to {@code longs(Long.MAX_VALUE,
- * randomNumberOrigin, randomNumberBound)}.
- */
- public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
- RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
- return StreamSupport.longStream
- (makeLongsSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
- false);
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code double}
- * values from this generator and/or one split from it; each value is between zero (inclusive)
- * and one (exclusive).
- *
- * @param streamSize the number of values to generate
- *
- * @return a stream of {@code double} values
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero
- */
- public DoubleStream doubles(long streamSize) {
- RNGSupport.checkStreamSize(streamSize);
- return doubleStream(makeDoublesSpliterator(0L, streamSize, Double.MAX_VALUE, 0.0));
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandom {@code double} values from this
- * generator and/or one split from it; each value is between zero (inclusive) and one
- * (exclusive).
- *
- * @return a stream of pseudorandom {@code double} values
- *
- * @implNote This method is implemented to be equivalent to {@code
- * doubles(Long.MAX_VALUE)}.
- */
- public DoubleStream doubles() {
- return doubleStream(makeDoublesSpliterator(0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0));
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code double}
- * values from this generator and/or one split from it; each value conforms to the given origin
- * (inclusive) and bound (exclusive).
- *
- * @param streamSize the number of values to generate
- * @param randomNumberOrigin the origin (inclusive) of each random value
- * @param randomNumberBound the bound (exclusive) of each random value
- *
- * @return a stream of pseudorandom {@code double} values, each with the given origin
- * (inclusive) and bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero
- * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
- * {@code randomNumberBound}
- */
- public DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) {
- RNGSupport.checkStreamSize(streamSize);
- RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
- return doubleStream(makeDoublesSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandom {@code double} values from this
- * generator and/or one split from it; each value conforms to the given origin (inclusive) and
- * bound (exclusive).
- *
- * @param randomNumberOrigin the origin (inclusive) of each random value
- * @param randomNumberBound the bound (exclusive) of each random value
- *
- * @return a stream of pseudorandom {@code double} values, each with the given origin
- * (inclusive) and bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
- * {@code randomNumberBound}
- *
- * @implNote This method is implemented to be equivalent to {@code
- * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
- */
- public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
- RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
- return doubleStream(makeDoublesSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound));
- }
-
-}
--- a/src/java.base/share/classes/java/util/random/AbstractSplittableRNG.java Fri Jul 26 15:20:31 2019 -0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,364 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.random;
-
-import java.util.Spliterator;
-import java.util.function.Consumer;
-import java.util.function.DoubleConsumer;
-import java.util.function.IntConsumer;
-import java.util.function.LongConsumer;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-
-/**
- * This class provides much of the implementation of the {@link SplittableRNG} interface, to
- * minimize the effort required to implement this interface.
- * <p>
- * To implement a pseudorandom number generator, the programmer needs only to extend this class and
- * provide implementations for the methods {@code nextInt()}, {@code nextLong()}, {@code period()},
- * and {@code split(SplittableRNG)}.
- * <p>
- * (If the pseudorandom number generator also has the ability to jump, then the programmer may wish
- * to consider instead extending the class {@link ArbitrarilyJumpableRNG}. But if the pseudorandom
- * number generator furthermore has the ability to jump an arbitrary specified distance, then the
- * programmer may wish to consider instead extending the class {@link
- * AbstractArbitrarilyJumpableRNG}.)
- * <p>
- * The programmer should generally provide at least three constructors: one that takes no arguments,
- * one that accepts a {@code long} seed value, and one that accepts an array of seed {@code byte}
- * values. This class provides a public {@code initialSeed()} method that may be useful in
- * initializing some static state from which to derive defaults seeds for use by the no-argument
- * constructor.
- * <p>
- * For the stream methods (such as {@code ints()} and {@code splits()}), this class provides {@link
- * Spliterator} based implementations that allow parallel execution when appropriate.
- * <p>
- * The documentation for each non-abstract method in this class describes its implementation in
- * detail. Each of these methods may be overridden if the pseudorandom number generator being
- * implemented admits a more efficient implementation.
- *
- * @since 14
- */
-public abstract class AbstractSplittableRNG extends AbstractSpliteratorRNG implements SplittableRNG {
-
- /*
- * Implementation Overview.
- *
- * This class provides most of the "user API" methods needed to
- * satisfy the interface JumpableRNG. Most of these methods
- * are in turn inherited from AbstractRNG and the non-public class
- * AbstractSpliteratorRNG; this file implements two versions of the
- * splits method and defines the spliterators necessary to support
- * them.
- *
- * The abstract split() method from interface SplittableRNG is redeclared
- * here so as to narrow the return type to AbstractSplittableRNG.
- *
- * File organization: First the non-public methods needed by the class
- * AbstractSpliteratorRNG, then the main public methods, followed by some
- * custom spliterator classes.
- */
-
- Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) {
- return new RandomIntsSpliterator(this, index, fence, origin, bound);
- }
-
- Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound) {
- return new RandomLongsSpliterator(this, index, fence, origin, bound);
- }
-
- Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound) {
- return new RandomDoublesSpliterator(this, index, fence, origin, bound);
- }
-
- Spliterator<SplittableRNG> makeSplitsSpliterator(long index, long fence, SplittableRNG source) {
- return new RandomSplitsSpliterator(source, index, fence, this);
- }
-
- /* ---------------- public methods ---------------- */
-
- /**
- * Implements the @code{split()} method as {@code this.split(this) }.
- *
- * @return the new {@link AbstractSplittableRNG} instance
- */
- public SplittableRNG split() {
- return this.split(this);
- }
-
- // Stream methods for splittings
-
- /**
- * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
- * implements the {@link SplittableRNG} interface.
- * <p>
- * This pseudorandom number generator provides the entropy used to seed the new ones.
- *
- * @return a stream of {@link SplittableRNG} objects
- *
- * @implNote This method is implemented to be equivalent to {@code splits(Long.MAX_VALUE)}.
- */
- public Stream<SplittableRNG> splits() {
- return this.splits(Long.MAX_VALUE, this);
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
- * generators, each of which implements the {@link SplittableRNG} interface.
- * <p>
- * This pseudorandom number generator provides the entropy used to seed the new ones.
- *
- * @param streamSize the number of values to generate
- *
- * @return a stream of {@link SplittableRNG} objects
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero
- */
- public Stream<SplittableRNG> splits(long streamSize) {
- return this.splits(streamSize, this);
- }
-
- /**
- * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
- * implements the {@link SplittableRNG} interface.
- *
- * @param source a {@link SplittableRNG} instance to be used instead of this one as a source of
- * pseudorandom bits used to initialize the state of the new ones.
- *
- * @return a stream of {@link SplittableRNG} objects
- *
- * @implNote This method is implemented to be equivalent to {@code splits(Long.MAX_VALUE)}.
- */
- public Stream<SplittableRNG> splits(SplittableRNG source) {
- return this.splits(Long.MAX_VALUE, source);
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
- * generators, each of which implements the {@link SplittableRNG} interface.
- *
- * @param streamSize the number of values to generate
- * @param source a {@link SplittableRNG} instance to be used instead of this one as a source
- * of pseudorandom bits used to initialize the state of the new ones.
- *
- * @return a stream of {@link SplittableRNG} objects
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero
- */
- public Stream<SplittableRNG> splits(long streamSize, SplittableRNG source) {
- RNGSupport.checkStreamSize(streamSize);
- return StreamSupport.stream(makeSplitsSpliterator(0L, streamSize, source), false);
- }
-
- /**
- * Spliterator for int streams. We multiplex the four int versions into one class by treating a
- * bound less than origin as unbounded, and also by treating "infinite" as equivalent to
- * {@code Long.MAX_VALUE}. For splits, it uses the standard divide-by-two approach. The long and
- * double versions of this class are identical except for types.
- */
- static class RandomIntsSpliterator extends RNGSupport.RandomSpliterator implements Spliterator.OfInt {
- final SplittableRNG generatingRNG;
- final int origin;
- final int bound;
-
- RandomIntsSpliterator(SplittableRNG generatingRNG, long index, long fence, int origin, int bound) {
- super(index, fence);
- this.generatingRNG = generatingRNG;
- this.origin = origin; this.bound = bound;
- }
-
- public Spliterator.OfInt trySplit() {
- long i = index, m = (i + fence) >>> 1;
- if (m <= i) return null;
- index = m;
- return new RandomIntsSpliterator(generatingRNG.split(), i, m, origin, bound);
- }
-
- public boolean tryAdvance(IntConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(RNGSupport.boundedNextInt(generatingRNG, origin, bound));
- index = i + 1;
- return true;
- }
- else return false;
- }
-
- public void forEachRemaining(IntConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- RandomNumberGenerator r = generatingRNG;
- int o = origin, b = bound;
- do {
- consumer.accept(RNGSupport.boundedNextInt(r, o, b));
- } while (++i < f);
- }
- }
- }
-
- /**
- * Spliterator for long streams.
- */
- static class RandomLongsSpliterator extends RNGSupport.RandomSpliterator implements Spliterator.OfLong {
- final SplittableRNG generatingRNG;
- final long origin;
- final long bound;
-
- RandomLongsSpliterator(SplittableRNG generatingRNG, long index, long fence, long origin, long bound) {
- super(index, fence);
- this.generatingRNG = generatingRNG;
- this.origin = origin; this.bound = bound;
- }
-
- public Spliterator.OfLong trySplit() {
- long i = index, m = (i + fence) >>> 1;
- if (m <= i) return null;
- index = m;
- return new RandomLongsSpliterator(generatingRNG.split(), i, m, origin, bound);
- }
-
- public boolean tryAdvance(LongConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(RNGSupport.boundedNextLong(generatingRNG, origin, bound));
- index = i + 1;
- return true;
- }
- else return false;
- }
-
- public void forEachRemaining(LongConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- RandomNumberGenerator r = generatingRNG;
- long o = origin, b = bound;
- do {
- consumer.accept(RNGSupport.boundedNextLong(r, o, b));
- } while (++i < f);
- }
- }
- }
-
- /**
- * Spliterator for double streams.
- */
- static class RandomDoublesSpliterator extends RNGSupport.RandomSpliterator implements Spliterator.OfDouble {
- final SplittableRNG generatingRNG;
- final double origin;
- final double bound;
-
- RandomDoublesSpliterator(SplittableRNG generatingRNG, long index, long fence, double origin, double bound) {
- super(index, fence);
- this.generatingRNG = generatingRNG;
- this.origin = origin; this.bound = bound;
- }
-
- public Spliterator.OfDouble trySplit() {
- long i = index, m = (i + fence) >>> 1;
- if (m <= i) return null;
- index = m;
- return new RandomDoublesSpliterator(generatingRNG.split(), i, m, origin, bound);
- }
-
- public boolean tryAdvance(DoubleConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(RNGSupport.boundedNextDouble(generatingRNG, origin, bound));
- index = i + 1;
- return true;
- }
- else return false;
- }
-
- public void forEachRemaining(DoubleConsumer consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- RandomNumberGenerator r = generatingRNG;
- double o = origin, b = bound;
- do {
- consumer.accept(RNGSupport.boundedNextDouble(r, o, b));
- } while (++i < f);
- }
- }
- }
-
- /**
- * Spliterator for stream of generators of type SplittableRNG. We multiplex the two
- * versions into one class by treating "infinite" as equivalent to Long.MAX_VALUE.
- * For splits, it uses the standard divide-by-two approach.
- */
- static class RandomSplitsSpliterator extends RNGSupport.RandomSpliterator implements Spliterator<SplittableRNG> {
- final SplittableRNG generatingRNG;
- final SplittableRNG constructingRNG;
-
- RandomSplitsSpliterator(SplittableRNG generatingRNG, long index, long fence, SplittableRNG constructingRNG) {
- super(index, fence);
- this.generatingRNG = generatingRNG;
- this.constructingRNG = constructingRNG;
- }
-
- public Spliterator<SplittableRNG> trySplit() {
- long i = index, m = (i + fence) >>> 1;
- if (m <= i) return null;
- index = m;
- return new RandomSplitsSpliterator(generatingRNG.split(), i, m, constructingRNG);
- }
-
- public boolean tryAdvance(Consumer<? super SplittableRNG> consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- consumer.accept(constructingRNG.split(generatingRNG));
- index = i + 1;
- return true;
- }
- else return false;
- }
-
- public void forEachRemaining(Consumer<? super SplittableRNG> consumer) {
- if (consumer == null) throw new NullPointerException();
- long i = index, f = fence;
- if (i < f) {
- index = f;
- SplittableRNG c = constructingRNG;
- SplittableRNG r = generatingRNG;
- do {
- consumer.accept(c.split(r));
- } while (++i < f);
- }
- }
- }
-
-}
--- a/src/java.base/share/classes/java/util/random/ArbitrarilyJumpableRNG.java Fri Jul 26 15:20:31 2019 -0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.random;
-
-import java.util.stream.Stream;
-
-/**
- * This interface is designed to provide a common protocol for objects that generate sequences of
- * pseudorandom numbers (or Boolean values) and furthermore can easily <i>jump</i> to an arbitrarily
- * specified distant point in the state cycle.
- * <p>
- * Ideally, all {@link ArbitrarilyJumpableRNG} objects produced by iterative jumping from a single
- * original {@link ArbitrarilyJumpableRNG} object are statistically independent of one another and
- * individually uniform, provided that they do not traverse overlapping portions of the state cycle.
- * In practice, one must settle for some approximation to independence and uniformity. In
- * particular, a specific implementation may assume that each generator in a stream produced by the
- * {@code jumps} method is used to produce a number of values no larger than the jump distance
- * specified. Implementors are advised to use algorithms whose period is at least 2<sup>127</sup>.
- * <p>
- * For many applications, it suffices to jump forward by a power of two or some small multiple of a
- * power of two, but this power of two may not be representable as a {@code long} value. To avoid
- * the use of {@link java.math.BigInteger} values as jump distances, {@code double} values are used
- * instead.
- * <p>
- * Methods are provided to perform a single jump operation and also to produce a stream of
- * generators produced from the original by iterative copying and jumping of internal state. A
- * typical strategy for a multithreaded application is to create a single {@link
- * ArbitrarilyJumpableRNG} object, call its {@code jumps} method exactly once, and then parcel out
- * generators from the resulting stream, one to each thread. However, each generator produced also
- * has type {@link ArbitrarilyJumpableRNG}; with care, different jump distances can be used to
- * traverse the entire state cycle in various ways.
- * <p>
- * An implementation of the {@link ArbitrarilyJumpableRNG} interface must provide concrete
- * definitions for the methods {@code nextInt()}, {@code nextLong}, {@code period()}, {@code
- * copy()}, {@code jump(double)}, {@code defaultJumpDistance()}, and {@code defaultLeapDistance()}.
- * Default implementations are provided for all other methods. Perhaps the most convenient way to
- * implement this interface is to extend the abstract class {@link ArbitrarilyJumpableRNG}, which
- * provides spliterator-based implementations of the methods {@code ints}, {@code longs}, {@code
- * doubles}, {@code rngs}, {@code jumps}, and {@code leaps}.
- * <p>
- * Objects that implement {@link ArbitrarilyJumpableRNG} are typically not cryptographically secure.
- * Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure
- * pseudo-random number generator for use by security-sensitive applications.
- *
- * @since 14
- */
-public interface ArbitrarilyJumpableRNG extends LeapableRNG {
- /**
- * Returns a new generator whose internal state is an exact copy of this generator (therefore
- * their future behavior should be identical if subjected to the same series of operations).
- *
- * @return a new object that is a copy of this generator
- */
- ArbitrarilyJumpableRNG copy();
-
- /**
- * Alter the state of this pseudorandom number generator so as to jump forward a distance equal
- * to 2<sup>{@code logDistance}</sup> within its state cycle.
- *
- * @param logDistance the base-2 logarithm of the distance to jump forward within the state
- * cycle
- *
- * @throws IllegalArgumentException if {@code logDistance} is NaN or negative, or if
- * 2<sup>{@code logDistance}</sup> is greater than the period
- * of this generator
- */
- void jumpPowerOfTwo(int logDistance);
-
- /**
- * Alter the state of this pseudorandom number generator so as to jump forward a specified
- * distance within its state cycle.
- *
- * @param distance the distance to jump forward within the state cycle
- *
- * @throws IllegalArgumentException if {@code distance} is Nan, negative, or greater than the
- * period of this generator
- */
- void jump(double distance);
-
- /**
- * Alter the state of this pseudorandom number generator so as to jump forward a large, fixed
- * distance (typically 2<sup>64</sup> or more) within its state cycle. The distance used is
- * that returned by method {@code defaultJumpDistance()}.
- */
- default void jump() { jump(defaultJumpDistance()); }
-
- /**
- * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
- * implements the {@link ArbitrarilyJumpableRNG} interface, produced by jumping copies of this
- * generator by different integer multiples of the specified jump distance.
- *
- * @param distance a distance to jump forward within the state cycle
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @implNote This method is implemented to be equivalent to {@code jumps(Long.MAX_VALUE)}.
- */
- default Stream<ArbitrarilyJumpableRNG> jumps(double distance) {
- return Stream.generate(() -> copyAndJump(distance)).sequential();
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
- * generators, each of which implements the {@link ArbitrarilyJumpableRNG} interface, produced
- * by jumping copies of this generator by different integer multiples of the specified jump
- * distance.
- *
- * @param streamSize the number of generators to generate
- * @param distance a distance to jump forward within the state cycle
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero
- */
- default Stream<ArbitrarilyJumpableRNG> jumps(long streamSize, double distance) {
- return jumps(distance).limit(streamSize);
- }
-
- /**
- * Alter the state of this pseudorandom number generator so as to jump forward a very large,
- * fixed distance (typically 2<sup>128</sup> or more) within its state cycle. The distance used
- * is that returned by method {@code defaultJLeapDistance()}.
- */
- default void leap() { jump(defaultLeapDistance()); }
-
- /**
- * Copy this generator, jump this generator forward, then return the copy.
- *
- * @param distance a distance to jump forward within the state cycle
- *
- * @return a copy of this generator object before the jump occurred
- */
- default ArbitrarilyJumpableRNG copyAndJump(double distance) {
- ArbitrarilyJumpableRNG result = copy();
- jump(distance);
- return result;
- }
-
-}
--- a/src/java.base/share/classes/java/util/random/JumpableRNG.java Fri Jul 26 15:20:31 2019 -0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.random;
-
-import java.util.stream.Stream;
-
-/**
- * This interface is designed to provide a common protocol for objects that generate pseudorandom
- * sequences of numbers (or Boolean values) and furthermore can easily <i>jump</i> forward (by a
- * fixed amount) to a distant point in the state cycle.
- * <p>
- * Ideally, all {@link JumpableRNG} objects produced by iterative jumping from a single original
- * {@link JumpableRNG} object are statistically independent of one another and individually uniform.
- * In practice, one must settle for some approximation to independence and uniformity. In
- * particular, a specific implementation may assume that each generator in a stream produced by the
- * {@code jumps} method is used to produce a number of values no larger than either 2<sup>64</sup>
- * or the square root of its period. Implementors are advised to use algorithms whose period is at
- * least 2<sup>127</sup>.
- * <p>
- * Methods are provided to perform a single jump operation and also to produce a stream of
- * generators produced from the original by iterative copying and jumping of internal state. A
- * typical strategy for a multithreaded application is to create a single {@link JumpableRNG}
- * object, calls its {@code jumps} method exactly once, and then parcel out generators from the
- * resulting stream, one to each thread. It is generally not a good idea to call {@code jump} on a
- * generator that was itself produced by the {@code jumps} method, because the result may be a
- * generator identical to another generator already produce by that call to the {@code jumps}
- * method. For this reason, the return type of the {@code jumps} method is {@code
- * Stream<RandomNumberGenerator>} rather than {@code Stream<JumpableRNG>}, even though the actual
- * generator objects in that stream likely do also implement the {@link JumpableRNG} interface.
- * <p>
- * An implementation of the {@link JumpableRNG} interface must provide concrete definitions for the
- * methods {@code nextInt()}, {@code nextLong}, {@code period()}, {@code copy()}, {@code jump()},
- * and {@code defaultJumpDistance()}. Default implementations are provided for all other methods.
- * <p>
- * Objects that implement {@link JumpableRNG} are typically not cryptographically secure. Consider
- * instead using {@link java.security.SecureRandom} to get a cryptographically secure pseudo-random
- * number generator for use by security-sensitive applications.
- *
- * @since 14
- */
-public interface JumpableRNG extends StreamableRNG {
- /**
- * Returns a new generator whose internal state is an exact copy of this generator (therefore
- * their future behavior should be identical if subjected to the same series of operations).
- *
- * @return a new object that is a copy of this generator
- */
- JumpableRNG copy();
-
- /**
- * Alter the state of this pseudorandom number generator so as to jump forward a large, fixed
- * distance (typically 2<sup>64</sup> or more) within its state cycle.
- */
- void jump();
-
- /**
- * Returns the distance by which the {@code jump()} method will jump forward within the state
- * cycle of this generator object.
- *
- * @return the default jump distance (as a {@code double} value)
- */
- double defaultJumpDistance();
-
- /**
- * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
- * implements the {@link RandomNumberGenerator} interface.
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @implNote It is permitted to implement this method in a manner equivalent to
- * {@code jumps(Long.MAX_VALUE)}.
- * @implNote The default implementation produces a sequential stream that repeatedly
- * calls {@code copy()} and {@code jump()} on this generator, and the copies become the
- * generators produced by the stream.
- */
- default Stream<RandomNumberGenerator> jumps() {
- return Stream.generate(this::copyAndJump).sequential();
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
- * generators, each of which implements the {@link RandomNumberGenerator} interface.
- *
- * @param streamSize the number of generators to generate
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero
- * @implNote The default implementation produces a sequential stream that repeatedly
- * calls {@code copy()} and {@code jump()} on this generator, and the copies become the
- * generators produced by the stream.
- */
- default Stream<RandomNumberGenerator> jumps(long streamSize) {
- return jumps().limit(streamSize);
- }
-
- /**
- * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
- * implements the {@link RandomNumberGenerator} interface. Ideally the generators in the stream
- * will appear to be statistically independent.
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @implNote The default implementation calls {@code jumps()}.
- */
- default Stream<RandomNumberGenerator> rngs() {
- return this.jumps();
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
- * generators, each of which implements the {@link RandomNumberGenerator} interface. Ideally
- * the generators in the stream will appear to be statistically independent.
- *
- * @param streamSize the number of generators to generate
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero
- * @implNote The default implementation calls {@code jumps(streamSize)}.
- */
- default Stream<RandomNumberGenerator> rngs(long streamSize) {
- return this.jumps(streamSize);
- }
-
- /**
- * Copy this generator, jump this generator forward, then return the copy.
- *
- * @return a copy of this generator object before the jump occurred
- */
- default RandomNumberGenerator copyAndJump() {
- RandomNumberGenerator result = copy();
- jump();
- return result;
- }
-
-}
--- a/src/java.base/share/classes/java/util/random/L128X256MixRandom.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/random/L128X256MixRandom.java Fri Jul 26 15:37:05 2019 -0300
@@ -27,12 +27,15 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.random.RandomGenerator.SplittableGenerator;
+import java.util.random.RandomSupport.AbstractSplittableGenerator;
+
/**
* A generator of uniform pseudorandom values applicable for use in
* (among other contexts) isolated parallel computations that may
* generate subtasks. Class {@link L128X256MixRandom} implements
- * interfaces {@link RandomNumberGenerator} and {@link SplittableRNG},
+ * interfaces {@link RandomGenerator} and {@link SplittableGenerator},
* and therefore supports methods for producing pseudorandomly chosen
* numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
* as well as creating new split-off {@link L128X256MixRandom} objects,
@@ -143,7 +146,7 @@
*
* @since 14
*/
-public final class L128X256MixRandom extends AbstractSplittableRNG {
+public final class L128X256MixRandom extends AbstractSplittableGenerator {
/*
* Implementation Overview.
@@ -181,7 +184,7 @@
/**
* The seed generator for default constructors.
*/
- private static final AtomicLong defaultGen = new AtomicLong(RNGSupport.initialSeed());
+ private static final AtomicLong defaultGen = new AtomicLong(RandomSupport.initialSeed());
/*
* The period of this generator, which is (2**256 - 1) * 2**128.
@@ -250,10 +253,10 @@
// If x0, x1, x2, and x3 are all zero, we must choose nonzero values.
if ((x0 | x1 | x2 | x3) == 0) {
// At least three of the four values generated here will be nonzero.
- this.x0 = RNGSupport.mixStafford13(sh += RNGSupport.GOLDEN_RATIO_64);
- this.x1 = RNGSupport.mixStafford13(sh += RNGSupport.GOLDEN_RATIO_64);
- this.x2 = RNGSupport.mixStafford13(sh += RNGSupport.GOLDEN_RATIO_64);
- this.x3 = RNGSupport.mixStafford13(sh + RNGSupport.GOLDEN_RATIO_64);
+ this.x0 = RandomSupport.mixStafford13(sh += RandomSupport.GOLDEN_RATIO_64);
+ this.x1 = RandomSupport.mixStafford13(sh += RandomSupport.GOLDEN_RATIO_64);
+ this.x2 = RandomSupport.mixStafford13(sh += RandomSupport.GOLDEN_RATIO_64);
+ this.x3 = RandomSupport.mixStafford13(sh + RandomSupport.GOLDEN_RATIO_64);
}
}
@@ -275,14 +278,14 @@
// which will then be used to produce the first generated value.
// The other x values are filled in as if by a SplitMix PRNG with
// GOLDEN_RATIO_64 as the gamma value and Stafford13 as the mixer.
- this(RNGSupport.mixMurmur64(seed ^= RNGSupport.SILVER_RATIO_64),
- RNGSupport.mixMurmur64(seed += RNGSupport.GOLDEN_RATIO_64),
+ this(RandomSupport.mixMurmur64(seed ^= RandomSupport.SILVER_RATIO_64),
+ RandomSupport.mixMurmur64(seed += RandomSupport.GOLDEN_RATIO_64),
0,
1,
- RNGSupport.mixStafford13(seed),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed + RNGSupport.GOLDEN_RATIO_64));
+ RandomSupport.mixStafford13(seed),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed + RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -293,7 +296,7 @@
*/
public L128X256MixRandom() {
// Using GOLDEN_RATIO_64 here gives us a good Weyl sequence of values.
- this(defaultGen.getAndAdd(RNGSupport.GOLDEN_RATIO_64));
+ this(defaultGen.getAndAdd(RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -305,7 +308,7 @@
*/
public L128X256MixRandom(byte[] seed) {
// Convert the seed to 6 long values, of which the last 4 are not all zero.
- long[] data = RNGSupport.convertSeedBytesToLongs(seed, 6, 4);
+ long[] data = RandomSupport.convertSeedBytesToLongs(seed, 6, 4);
long ah = data[0], al = data[1], sh = data[2], sl = data[3], x0 = data[4], x1 = data[5], x2 = data[6], x3 = data[7];
// Force a to be odd.
this.ah = ah;
@@ -331,12 +334,12 @@
* and the same expected statistical properties apply to the
* entire set of generators constructed by such recursive splitting.
*
- * @param source a {@link SplittableRNG} instance to be used instead
+ * @param source a {@link SplittableGenerator} instance to be used instead
* of this one as a source of pseudorandom bits used to
* initialize the state of the new ones.
* @return a new instance of {@link L128X256MixRandom}
*/
- public L128X256MixRandom split(SplittableRNG source) {
+ public L128X256MixRandom split(SplittableGenerator source) {
// Literally pick a new instance "at random".
return new L128X256MixRandom(source.nextLong(), source.nextLong(),
source.nextLong(), source.nextLong(),
@@ -359,7 +362,7 @@
long q0 = x0, q1 = x1, q2 = x2, q3 = x3;
{ long t = q1 << 17; q2 ^= q0; q3 ^= q1; q1 ^= q2; q0 ^= q3; q2 ^= t; q3 = Long.rotateLeft(q3, 45); } // xoshiro256 1.0
x0 = q0; x1 = q1; x2 = q2; x3 = q3;
- return RNGSupport.mixLea64(z); // mixing function
+ return RandomSupport.mixLea64(z); // mixing function
}
public BigInteger period() {
--- a/src/java.base/share/classes/java/util/random/L32X64MixRandom.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/random/L32X64MixRandom.java Fri Jul 26 15:37:05 2019 -0300
@@ -27,12 +27,14 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.random.RandomGenerator.SplittableGenerator;
+import java.util.random.RandomSupport.AbstractSplittableGenerator;
/**
* A generator of uniform pseudorandom values applicable for use in
* (among other contexts) isolated parallel computations that may
* generate subtasks. Class {@link L32X64MixRandom} implements
- * interfaces {@link RandomNumberGenerator} and {@link SplittableRNG},
+ * interfaces {@link RandomGenerator} and {@link SplittableGenerator},
* and therefore supports methods for producing pseudorandomly chosen
* numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
* as well as creating new split-off {@link L32X64MixRandom} objects,
@@ -134,7 +136,7 @@
*
* @since 14
*/
-public final class L32X64MixRandom extends AbstractSplittableRNG {
+public final class L32X64MixRandom extends AbstractSplittableGenerator {
/*
* Implementation Overview.
@@ -168,7 +170,7 @@
/**
* The seed generator for default constructors.
*/
- private static final AtomicLong defaultGen = new AtomicLong(RNGSupport.initialSeed());
+ private static final AtomicLong defaultGen = new AtomicLong(RandomSupport.initialSeed());
/*
* The period of this generator, which is (2**64 - 1) * 2**32.
@@ -219,8 +221,8 @@
// If x0 and x1 are both zero, we must choose nonzero values.
if ((x0 | x1) == 0) {
// At least one of the two values generated here will be nonzero.
- this.x0 = RNGSupport.mixMurmur32(s += RNGSupport.GOLDEN_RATIO_32);
- this.x1 = RNGSupport.mixMurmur32(s + RNGSupport.GOLDEN_RATIO_32);
+ this.x0 = RandomSupport.mixMurmur32(s += RandomSupport.GOLDEN_RATIO_32);
+ this.x1 = RandomSupport.mixMurmur32(s + RandomSupport.GOLDEN_RATIO_32);
}
}
@@ -242,10 +244,10 @@
// which will then be used to produce the first generated value.
// Then x1 is filled in as if by a SplitMix PRNG with
// GOLDEN_RATIO_32 as the gamma value and Murmur32 as the mixer.
- this(RNGSupport.mixMurmur32((int)((seed ^= RNGSupport.SILVER_RATIO_64) >>> 32)),
+ this(RandomSupport.mixMurmur32((int)((seed ^= RandomSupport.SILVER_RATIO_64) >>> 32)),
1,
- RNGSupport.mixLea32((int)(seed)),
- RNGSupport.mixLea32((int)(seed) + RNGSupport.GOLDEN_RATIO_32));
+ RandomSupport.mixLea32((int)(seed)),
+ RandomSupport.mixLea32((int)(seed) + RandomSupport.GOLDEN_RATIO_32));
}
/**
@@ -256,7 +258,7 @@
*/
public L32X64MixRandom() {
// Using GOLDEN_RATIO_64 here gives us a good Weyl sequence of values.
- this(defaultGen.getAndAdd(RNGSupport.GOLDEN_RATIO_64));
+ this(defaultGen.getAndAdd(RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -268,7 +270,7 @@
*/
public L32X64MixRandom(byte[] seed) {
// Convert the seed to 4 int values, of which the last 2 are not all zero.
- int[] data = RNGSupport.convertSeedBytesToInts(seed, 4, 2);
+ int[] data = RandomSupport.convertSeedBytesToInts(seed, 4, 2);
int a = data[0], s = data[1], x0 = data[2], x1 = data[3];
// Force a to be odd.
this.a = a | 1;
@@ -288,12 +290,12 @@
* the same expected statistical properties apply to the entire set of generators constructed by
* such recursive splitting.
*
- * @param source a {@link SplittableRNG} instance to be used instead of this one as a source of
+ * @param source a {@link SplittableGenerator} instance to be used instead of this one as a source of
* pseudorandom bits used to initialize the state of the new ones.
*
* @return a new instance of {@link L32X64MixRandom}
*/
- public L32X64MixRandom split(SplittableRNG source) {
+ public L32X64MixRandom split(SplittableGenerator source) {
// Literally pick a new instance "at random".
return new L32X64MixRandom(source.nextInt(), source.nextInt(),
source.nextInt(), source.nextInt());
--- a/src/java.base/share/classes/java/util/random/L64X1024MixRandom.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/random/L64X1024MixRandom.java Fri Jul 26 15:37:05 2019 -0300
@@ -27,12 +27,14 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.random.RandomGenerator.SplittableGenerator;
+import java.util.random.RandomSupport.AbstractSplittableGenerator;
/**
* A generator of uniform pseudorandom values applicable for use in
* (among other contexts) isolated parallel computations that may
* generate subtasks. Class {@link L64X1024MixRandom} implements
- * interfaces {@link RandomNumberGenerator} and {@link SplittableRNG},
+ * interfaces {@link RandomGenerator} and {@link SplittableGenerator},
* and therefore supports methods for producing pseudorandomly chosen
* numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
* as well as creating new split-off {@link L64X1024MixRandom} objects,
@@ -134,7 +136,7 @@
*
* @since 14
*/
-public final class L64X1024MixRandom extends AbstractSplittableRNG {
+public final class L64X1024MixRandom extends AbstractSplittableGenerator {
/*
* Implementation Overview.
@@ -174,7 +176,7 @@
/**
* The seed generator for default constructors.
*/
- private static final AtomicLong defaultGen = new AtomicLong(RNGSupport.initialSeed());
+ private static final AtomicLong defaultGen = new AtomicLong(RandomSupport.initialSeed());
/*
* The period of this generator, which is (2**1024 - 1) * 2**64.
@@ -264,7 +266,7 @@
if ((x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | x13 | x14 | x15) == 0) {
// At least fifteen of the sixteen values generated here will be nonzero.
for (int j = 0; j < N; j++) {
- this.x[j] = RNGSupport.mixStafford13(s += RNGSupport.GOLDEN_RATIO_64);
+ this.x[j] = RandomSupport.mixStafford13(s += RandomSupport.GOLDEN_RATIO_64);
}
}
}
@@ -287,24 +289,24 @@
// which will then be used to produce the first generated value.
// The other x values are filled in as if by a SplitMix PRNG with
// GOLDEN_RATIO_64 as the gamma value and Stafford13 as the mixer.
- this(RNGSupport.mixMurmur64(seed ^= RNGSupport.SILVER_RATIO_64),
+ this(RandomSupport.mixMurmur64(seed ^= RandomSupport.SILVER_RATIO_64),
1,
- RNGSupport.mixStafford13(seed),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed + RNGSupport.GOLDEN_RATIO_64));
+ RandomSupport.mixStafford13(seed),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed + RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -315,7 +317,7 @@
*/
public L64X1024MixRandom() {
// Using GOLDEN_RATIO_64 here gives us a good Weyl sequence of values.
- this(defaultGen.getAndAdd(RNGSupport.GOLDEN_RATIO_64));
+ this(defaultGen.getAndAdd(RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -327,7 +329,7 @@
*/
public L64X1024MixRandom(byte[] seed) {
// Convert the seed to 18 long values, of which the last 16 are not all zero.
- long[] data = RNGSupport.convertSeedBytesToLongs(seed, 18, 16);
+ long[] data = RandomSupport.convertSeedBytesToLongs(seed, 18, 16);
long a = data[0], s = data[1];
// Force a to be odd.
this.a = a | 1;
@@ -351,12 +353,12 @@
* and the same expected statistical properties apply to the
* entire set of generators constructed by such recursive splitting.
*
- * @param source a {@link SplittableRNG} instance to be used instead
+ * @param source a {@link SplittableGenerator} instance to be used instead
* of this one as a source of pseudorandom bits used to
* initialize the state of the new ones.
* @return a new instance of {@link L64X1024MixRandom}
*/
- public L64X1024MixRandom split(SplittableRNG source) {
+ public L64X1024MixRandom split(SplittableGenerator source) {
// Literally pick a new instance "at random".
return new L64X1024MixRandom(source.nextLong(), source.nextLong(),
source.nextLong(), source.nextLong(),
@@ -388,7 +390,7 @@
x[q] = Long.rotateLeft(s0, 25) ^ s15 ^ (s15 << 27);
x[p] = Long.rotateLeft(s15, 36);
- return RNGSupport.mixLea64(z); // mixing function
+ return RandomSupport.mixLea64(z); // mixing function
}
public BigInteger period() {
--- a/src/java.base/share/classes/java/util/random/L64X1024Random.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/random/L64X1024Random.java Fri Jul 26 15:37:05 2019 -0300
@@ -27,12 +27,14 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.random.RandomGenerator.SplittableGenerator;
+import java.util.random.RandomSupport.AbstractSplittableGenerator;
/**
* A generator of uniform pseudorandom values applicable for use in
* (among other contexts) isolated parallel computations that may
* generate subtasks. Class {@link L64X1024Random} implements
- * interfaces {@link RandomNumberGenerator} and {@link SplittableRNG},
+ * interfaces {@link RandomGenerator} and {@link SplittableGenerator},
* and therefore supports methods for producing pseudorandomly chosen
* numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
* as well as creating new split-off {@link L64X1024Random} objects,
@@ -132,7 +134,7 @@
*
* @since 14
*/
-public final class L64X1024Random extends AbstractSplittableRNG {
+public final class L64X1024Random extends AbstractSplittableGenerator {
/*
* Implementation Overview.
@@ -172,7 +174,7 @@
/**
* The seed generator for default constructors.
*/
- private static final AtomicLong defaultGen = new AtomicLong(RNGSupport.initialSeed());
+ private static final AtomicLong defaultGen = new AtomicLong(RandomSupport.initialSeed());
/*
* The period of this generator, which is (2**1024 - 1) * 2**64.
@@ -261,7 +263,7 @@
// If x0, x1, ..., x15 are all zero (very unlikely), we must choose nonzero values.
if ((x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | x10 | x11 | x12 | x13 | x14 | x15) == 0) {
for (int j = 0; j < N; j++) {
- this.x[j] = RNGSupport.mixStafford13(s += RNGSupport.GOLDEN_RATIO_64);
+ this.x[j] = RandomSupport.mixStafford13(s += RandomSupport.GOLDEN_RATIO_64);
}
}
}
@@ -284,24 +286,24 @@
// which will then be used to produce the first generated value.
// The other x values are filled in as if by a SplitMix PRNG with
// GOLDEN_RATIO_64 as the gamma value and Stafford13 as the mixer.
- this(RNGSupport.mixMurmur64(seed ^= RNGSupport.SILVER_RATIO_64),
+ this(RandomSupport.mixMurmur64(seed ^= RandomSupport.SILVER_RATIO_64),
1,
- RNGSupport.mixStafford13(seed),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed + RNGSupport.GOLDEN_RATIO_64));
+ RandomSupport.mixStafford13(seed),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed + RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -312,7 +314,7 @@
*/
public L64X1024Random() {
// Using GOLDEN_RATIO_64 here gives us a good Weyl sequence of values.
- this(defaultGen.getAndAdd(RNGSupport.GOLDEN_RATIO_64));
+ this(defaultGen.getAndAdd(RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -324,7 +326,7 @@
*/
public L64X1024Random(byte[] seed) {
// Convert the seed to 18 long values, of which the last 16 are not all zero.
- long[] data = RNGSupport.convertSeedBytesToLongs(seed, 18, 16);
+ long[] data = RandomSupport.convertSeedBytesToLongs(seed, 18, 16);
long a = data[0], s = data[1];
// Force a to be odd.
this.a = a | 1;
@@ -348,12 +350,12 @@
* and the same expected statistical properties apply to the
* entire set of generators constructed by such recursive splitting.
*
- * @param source a {@link SplittableRNG} instance to be used instead
+ * @param source a {@link SplittableGenerator} instance to be used instead
* of this one as a source of pseudorandom bits used to
* initialize the state of the new ones.
* @return a new instance of {@link L64X1024Random}
*/
- public L64X1024Random split(SplittableRNG source) {
+ public L64X1024Random split(SplittableGenerator source) {
// Literally pick a new instance "at random".
return new L64X1024Random(source.nextLong(), source.nextLong(),
source.nextLong(), source.nextLong(),
--- a/src/java.base/share/classes/java/util/random/L64X128MixRandom.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/random/L64X128MixRandom.java Fri Jul 26 15:37:05 2019 -0300
@@ -27,12 +27,14 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.random.RandomGenerator.SplittableGenerator;
+import java.util.random.RandomSupport.AbstractSplittableGenerator;
/**
* A generator of uniform pseudorandom values applicable for use in
* (among other contexts) isolated parallel computations that may
* generate subtasks. Class {@link L64X128MixRandom} implements
- * interfaces {@link RandomNumberGenerator} and {@link SplittableRNG},
+ * interfaces {@link RandomGenerator} and {@link SplittableGenerator},
* and therefore supports methods for producing pseudorandomly chosen
* numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
* as well as creating new split-off {@link L64X128MixRandom} objects,
@@ -134,7 +136,7 @@
*
* @since 14
*/
-public final class L64X128MixRandom extends AbstractSplittableRNG {
+public final class L64X128MixRandom extends AbstractSplittableGenerator {
/*
* Implementation Overview.
@@ -168,7 +170,7 @@
/**
* The seed generator for default constructors.
*/
- private static final AtomicLong defaultGen = new AtomicLong(RNGSupport.initialSeed());
+ private static final AtomicLong defaultGen = new AtomicLong(RandomSupport.initialSeed());
/*
* The period of this generator, which is (2**128 - 1) * 2**64.
@@ -221,8 +223,8 @@
// If x0 and x1 are both zero, we must choose nonzero values.
if ((x0 | x1) == 0) {
// At least one of the two values generated here will be nonzero.
- this.x0 = RNGSupport.mixStafford13(s += RNGSupport.GOLDEN_RATIO_64);
- this.x1 = RNGSupport.mixStafford13(s + RNGSupport.GOLDEN_RATIO_64);
+ this.x0 = RandomSupport.mixStafford13(s += RandomSupport.GOLDEN_RATIO_64);
+ this.x1 = RandomSupport.mixStafford13(s + RandomSupport.GOLDEN_RATIO_64);
}
}
@@ -244,10 +246,10 @@
// which will then be used to produce the first generated value.
// Then x1 is filled in as if by a SplitMix PRNG with
// GOLDEN_RATIO_64 as the gamma value and Stafford13 as the mixer.
- this(RNGSupport.mixMurmur64(seed ^= RNGSupport.SILVER_RATIO_64),
+ this(RandomSupport.mixMurmur64(seed ^= RandomSupport.SILVER_RATIO_64),
1,
- RNGSupport.mixStafford13(seed),
- RNGSupport.mixStafford13(seed + RNGSupport.GOLDEN_RATIO_64));
+ RandomSupport.mixStafford13(seed),
+ RandomSupport.mixStafford13(seed + RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -258,7 +260,7 @@
*/
public L64X128MixRandom() {
// Using GOLDEN_RATIO_64 here gives us a good Weyl sequence of values.
- this(defaultGen.getAndAdd(RNGSupport.GOLDEN_RATIO_64));
+ this(defaultGen.getAndAdd(RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -270,7 +272,7 @@
*/
public L64X128MixRandom(byte[] seed) {
// Convert the seed to 4 long values, of which the last 2 are not all zero.
- long[] data = RNGSupport.convertSeedBytesToLongs(seed, 4, 2);
+ long[] data = RandomSupport.convertSeedBytesToLongs(seed, 4, 2);
long a = data[0], s = data[1], x0 = data[2], x1 = data[3];
// Force a to be odd.
this.a = a | 1;
@@ -292,13 +294,13 @@
* and the same expected statistical properties apply to the
* entire set of generators constructed by such recursive splitting.
*
- * @param source a {@link SplittableRNG} instance to be used instead
+ * @param source a {@link SplittableGenerator} instance to be used instead
* of this one as a source of pseudorandom bits used to
* initialize the state of the new ones.
*
* @return a new instance of {@link L64X128MixRandom}
*/
- public L64X128MixRandom split(SplittableRNG source) {
+ public L64X128MixRandom split(SplittableGenerator source) {
// Literally pick a new instance "at random".
return new L64X128MixRandom(source.nextLong(), source.nextLong(),
source.nextLong(), source.nextLong());
--- a/src/java.base/share/classes/java/util/random/L64X128Random.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/random/L64X128Random.java Fri Jul 26 15:37:05 2019 -0300
@@ -27,12 +27,14 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.random.RandomGenerator.SplittableGenerator;
+import java.util.random.RandomSupport.AbstractSplittableGenerator;
/**
* A generator of uniform pseudorandom values applicable for use in
* (among other contexts) isolated parallel computations that may
* generate subtasks. Class {@link L64X128Random} implements
- * interfaces {@link RandomNumberGenerator} and {@link SplittableRNG},
+ * interfaces {@link RandomGenerator} and {@link SplittableGenerator},
* and therefore supports methods for producing pseudorandomly chosen
* numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
* as well as creating new split-off {@link L64X128Random} objects,
@@ -132,7 +134,7 @@
*
* @since 14
*/
-public final class L64X128Random extends AbstractSplittableRNG {
+public final class L64X128Random extends AbstractSplittableGenerator {
/*
* Implementation Overview.
@@ -166,7 +168,7 @@
/**
* The seed generator for default constructors.
*/
- private static final AtomicLong defaultGen = new AtomicLong(RNGSupport.initialSeed());
+ private static final AtomicLong defaultGen = new AtomicLong(RandomSupport.initialSeed());
/*
* The period of this generator, which is (2**128 - 1) * 2**64.
@@ -217,8 +219,8 @@
// If x0 and x1 are both zero, we must choose nonzero values.
if ((x0 | x1) == 0) {
// At least one of the two values generated here will be nonzero.
- this.x0 = RNGSupport.mixStafford13(s += RNGSupport.GOLDEN_RATIO_64);
- this.x1 = RNGSupport.mixStafford13(s + RNGSupport.GOLDEN_RATIO_64);
+ this.x0 = RandomSupport.mixStafford13(s += RandomSupport.GOLDEN_RATIO_64);
+ this.x1 = RandomSupport.mixStafford13(s + RandomSupport.GOLDEN_RATIO_64);
}
}
@@ -240,10 +242,10 @@
// which will then be used to produce the first generated value.
// Then x1 is filled in as if by a SplitMix PRNG with
// GOLDEN_RATIO_64 as the gamma value and Stafford13 as the mixer.
- this(RNGSupport.mixMurmur64(seed ^= RNGSupport.SILVER_RATIO_64),
+ this(RandomSupport.mixMurmur64(seed ^= RandomSupport.SILVER_RATIO_64),
1,
- RNGSupport.mixStafford13(seed),
- RNGSupport.mixStafford13(seed + RNGSupport.GOLDEN_RATIO_64));
+ RandomSupport.mixStafford13(seed),
+ RandomSupport.mixStafford13(seed + RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -254,7 +256,7 @@
*/
public L64X128Random() {
// Using GOLDEN_RATIO_64 here gives us a good Weyl sequence of values.
- this(defaultGen.getAndAdd(RNGSupport.GOLDEN_RATIO_64));
+ this(defaultGen.getAndAdd(RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -266,7 +268,7 @@
*/
public L64X128Random(byte[] seed) {
// Convert the seed to 4 long values, of which the last 2 are not all zero.
- long[] data = RNGSupport.convertSeedBytesToLongs(seed, 4, 2);
+ long[] data = RandomSupport.convertSeedBytesToLongs(seed, 4, 2);
long a = data[0], s = data[1], x0 = data[2], x1 = data[3];
// Force a to be odd.
this.a = a | 1;
@@ -288,13 +290,13 @@
* and the same expected statistical properties apply to the
* entire set of generators constructed by such recursive splitting.
*
- * @param source a {@link SplittableRNG} instance to be used instead
+ * @param source a {@link SplittableGenerator} instance to be used instead
* of this one as a source of pseudorandom bits used to
* initialize the state of the new ones.
*
* @return a new instance of {@link L64X128Random}
*/
- public L64X128Random split(SplittableRNG source) {
+ public L64X128Random split(SplittableGenerator source) {
// Literally pick a new instance "at random".
return new L64X128Random(source.nextLong(), source.nextLong(),
source.nextLong(), source.nextLong());
--- a/src/java.base/share/classes/java/util/random/L64X256MixRandom.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/random/L64X256MixRandom.java Fri Jul 26 15:37:05 2019 -0300
@@ -27,12 +27,14 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.random.RandomGenerator.SplittableGenerator;
+import java.util.random.RandomSupport.AbstractSplittableGenerator;
/**
* A generator of uniform pseudorandom values applicable for use in
* (among other contexts) isolated parallel computations that may
* generate subtasks. Class {@link L64X256MixRandom} implements
- * interfaces {@link RandomNumberGenerator} and {@link SplittableRNG},
+ * interfaces {@link RandomGenerator} and {@link SplittableGenerator},
* and therefore supports methods for producing pseudorandomly chosen
* numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
* as well as creating new split-off {@link L64X256MixRandom} objects,
@@ -134,7 +136,7 @@
*
* @since 14
*/
-public final class L64X256MixRandom extends AbstractSplittableRNG {
+public final class L64X256MixRandom extends AbstractSplittableGenerator {
/*
* Implementation Overview.
@@ -169,7 +171,7 @@
/**
* The seed generator for default constructors.
*/
- private static final AtomicLong defaultGen = new AtomicLong(RNGSupport.initialSeed());
+ private static final AtomicLong defaultGen = new AtomicLong(RandomSupport.initialSeed());
/*
* The period of this generator, which is (2**256 - 1) * 2**64.
@@ -226,10 +228,10 @@
// If x0, x1, x2, and x3 are all zero, we must choose nonzero values.
if ((x0 | x1 | x2 | x3) == 0) {
// At least three of the four values generated here will be nonzero.
- this.x0 = RNGSupport.mixStafford13(s += RNGSupport.GOLDEN_RATIO_64);
- this.x1 = RNGSupport.mixStafford13(s += RNGSupport.GOLDEN_RATIO_64);
- this.x2 = RNGSupport.mixStafford13(s += RNGSupport.GOLDEN_RATIO_64);
- this.x3 = RNGSupport.mixStafford13(s + RNGSupport.GOLDEN_RATIO_64);
+ this.x0 = RandomSupport.mixStafford13(s += RandomSupport.GOLDEN_RATIO_64);
+ this.x1 = RandomSupport.mixStafford13(s += RandomSupport.GOLDEN_RATIO_64);
+ this.x2 = RandomSupport.mixStafford13(s += RandomSupport.GOLDEN_RATIO_64);
+ this.x3 = RandomSupport.mixStafford13(s + RandomSupport.GOLDEN_RATIO_64);
}
}
@@ -251,12 +253,12 @@
// which will then be used to produce the first generated value.
// The other x values are filled in as if by a SplitMix PRNG with
// GOLDEN_RATIO_64 as the gamma value and Stafford13 as the mixer.
- this(RNGSupport.mixMurmur64(seed ^= RNGSupport.SILVER_RATIO_64),
+ this(RandomSupport.mixMurmur64(seed ^= RandomSupport.SILVER_RATIO_64),
1,
- RNGSupport.mixStafford13(seed),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed + RNGSupport.GOLDEN_RATIO_64));
+ RandomSupport.mixStafford13(seed),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed + RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -267,7 +269,7 @@
*/
public L64X256MixRandom() {
// Using GOLDEN_RATIO_64 here gives us a good Weyl sequence of values.
- this(defaultGen.getAndAdd(RNGSupport.GOLDEN_RATIO_64));
+ this(defaultGen.getAndAdd(RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -279,7 +281,7 @@
*/
public L64X256MixRandom(byte[] seed) {
// Convert the seed to 6 long values, of which the last 4 are not all zero.
- long[] data = RNGSupport.convertSeedBytesToLongs(seed, 6, 4);
+ long[] data = RandomSupport.convertSeedBytesToLongs(seed, 6, 4);
long a = data[0], s = data[1], x0 = data[2], x1 = data[3], x2 = data[4], x3 = data[5];
// Force a to be odd.
this.a = a | 1;
@@ -303,13 +305,13 @@
* and the same expected statistical properties apply to the
* entire set of generators constructed by such recursive splitting.
*
- * @param source a {@link SplittableRNG} instance to be used instead
+ * @param source a {@link SplittableGenerator} instance to be used instead
* of this one as a source of pseudorandom bits used to
* initialize the state of the new ones.
*
* @return a new instance of {@link L64X256MixRandom}
*/
- public L64X256MixRandom split(SplittableRNG source) {
+ public L64X256MixRandom split(SplittableGenerator source) {
// Literally pick a new instance "at random".
return new L64X256MixRandom(source.nextLong(), source.nextLong(),
source.nextLong(), source.nextLong(),
@@ -327,7 +329,7 @@
long q0 = x0, q1 = x1, q2 = x2, q3 = x3;
{ long t = q1 << 17; q2 ^= q0; q3 ^= q1; q1 ^= q2; q0 ^= q3; q2 ^= t; q3 = Long.rotateLeft(q3, 45); } // xoshiro256 1.0
x0 = q0; x1 = q1; x2 = q2; x3 = q3;
- return RNGSupport.mixLea64(z); // mixing function
+ return RandomSupport.mixLea64(z); // mixing function
}
public BigInteger period() {
--- a/src/java.base/share/classes/java/util/random/L64X256Random.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/random/L64X256Random.java Fri Jul 26 15:37:05 2019 -0300
@@ -27,12 +27,14 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.random.RandomGenerator.SplittableGenerator;
+import java.util.random.RandomSupport.AbstractSplittableGenerator;
/**
* A generator of uniform pseudorandom values applicable for use in
* (among other contexts) isolated parallel computations that may
* generate subtasks. Class {@link L64X256Random} implements
- * interfaces {@link RandomNumberGenerator} and {@link SplittableRNG},
+ * interfaces {@link RandomGenerator} and {@link SplittableGenerator},
* and therefore supports methods for producing pseudorandomly chosen
* numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
* as well as creating new split-off {@link L64X256Random} objects,
@@ -132,7 +134,7 @@
*
* @since 14
*/
-public final class L64X256Random extends AbstractSplittableRNG {
+public final class L64X256Random extends AbstractSplittableGenerator {
/*
* Implementation Overview.
@@ -167,7 +169,7 @@
/**
* The seed generator for default constructors.
*/
- private static final AtomicLong defaultGen = new AtomicLong(RNGSupport.initialSeed());
+ private static final AtomicLong defaultGen = new AtomicLong(RandomSupport.initialSeed());
/*
* The period of this generator, which is (2**256 - 1) * 2**64.
@@ -224,10 +226,10 @@
// If x0, x1, x2, and x3 are all zero, we must choose nonzero values.
if ((x0 | x1 | x2 | x3) == 0) {
// At least three of the four values generated here will be nonzero.
- this.x0 = RNGSupport.mixStafford13(s += RNGSupport.GOLDEN_RATIO_64);
- this.x1 = RNGSupport.mixStafford13(s += RNGSupport.GOLDEN_RATIO_64);
- this.x2 = RNGSupport.mixStafford13(s += RNGSupport.GOLDEN_RATIO_64);
- this.x3 = RNGSupport.mixStafford13(s + RNGSupport.GOLDEN_RATIO_64);
+ this.x0 = RandomSupport.mixStafford13(s += RandomSupport.GOLDEN_RATIO_64);
+ this.x1 = RandomSupport.mixStafford13(s += RandomSupport.GOLDEN_RATIO_64);
+ this.x2 = RandomSupport.mixStafford13(s += RandomSupport.GOLDEN_RATIO_64);
+ this.x3 = RandomSupport.mixStafford13(s + RandomSupport.GOLDEN_RATIO_64);
}
}
@@ -249,12 +251,12 @@
// which will then be used to produce the first generated value.
// The other x values are filled in as if by a SplitMix PRNG with
// GOLDEN_RATIO_64 as the gamma value and Stafford13 as the mixer.
- this(RNGSupport.mixMurmur64(seed ^= RNGSupport.SILVER_RATIO_64),
+ this(RandomSupport.mixMurmur64(seed ^= RandomSupport.SILVER_RATIO_64),
1,
- RNGSupport.mixStafford13(seed),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed + RNGSupport.GOLDEN_RATIO_64));
+ RandomSupport.mixStafford13(seed),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed + RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -265,7 +267,7 @@
*/
public L64X256Random() {
// Using GOLDEN_RATIO_64 here gives us a good Weyl sequence of values.
- this(defaultGen.getAndAdd(RNGSupport.GOLDEN_RATIO_64));
+ this(defaultGen.getAndAdd(RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -277,7 +279,7 @@
*/
public L64X256Random(byte[] seed) {
// Convert the seed to 6 long values, of which the last 4 are not all zero.
- long[] data = RNGSupport.convertSeedBytesToLongs(seed, 6, 4);
+ long[] data = RandomSupport.convertSeedBytesToLongs(seed, 6, 4);
long a = data[0], s = data[1], x0 = data[2], x1 = data[3], x2 = data[4], x3 = data[5];
// Force a to be odd.
this.a = a | 1;
@@ -301,13 +303,13 @@
* and the same expected statistical properties apply to the
* entire set of generators constructed by such recursive splitting.
*
- * @param source a {@link SplittableRNG} instance to be used instead
+ * @param source a {@link SplittableGenerator} instance to be used instead
* of this one as a source of pseudorandom bits used to
* initialize the state of the new ones.
*
* @return a new instance of {@link L64X256Random}
*/
- public L64X256Random split(SplittableRNG source) {
+ public L64X256Random split(SplittableGenerator source) {
// Literally pick a new instance "at random".
return new L64X256Random(source.nextLong(), source.nextLong(),
source.nextLong(), source.nextLong(),
--- a/src/java.base/share/classes/java/util/random/LeapableRNG.java Fri Jul 26 15:20:31 2019 -0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.random;
-
-import java.util.stream.Stream;
-
-/**
- * This interface is designed to provide a common protocol for objects that generate sequences of
- * pseudorandom numbers (or Boolean values) and furthermore can easily not only jump but also
- * <i>leap</i> to a very distant point in the state cycle.
- * <p>
- * Typically one will construct a series of {@link LeapableRNG} objects by iterative leaping from a
- * single original {@link LeapableRNG} object, and then for each such object produce a subseries of
- * objects by iterative jumping. There is little conceptual difference between leaping and jumping,
- * but typically a leap will be a very long jump in the state cycle (perhaps distance
- * 2<sup>128</sup> or so).
- * <p>
- * Ideally, all {@link LeapableRNG} objects produced by iterative leaping and jumping from a single
- * original {@link LeapableRNG} object are statistically independent of one another and individually
- * uniform. In practice, one must settle for some approximation to independence and uniformity. In
- * particular, a specific implementation may assume that each generator in a stream produced by the
- * {@code leaps} method is used to produce (by jumping) a number of objects no larger than
- * 2<sup>64</sup>. Implementors are advised to use algorithms whose period is at least
- * 2<sup>191</sup>.
- * <p>
- * Methods are provided to perform a single leap operation and also to produce a stream of
- * generators produced from the original by iterative copying and leaping of internal state. The
- * generators produced must implement the {@link JumpableRNG} interface but need not also implement
- * the {@link LeapableRNG} interface. A typical strategy for a multithreaded application is to
- * create a single {@link LeapableRNG} object, calls its {@code leaps} method exactly once, and then
- * parcel out generators from the resulting stream, one to each thread. Then the {@code jumps}
- * method of each such generator be called to produce a substream of generator objects.
- * <p>
- * An implementation of the {@link LeapableRNG} interface must provide concrete definitions for the
- * methods {@code nextInt()}, {@code nextLong}, {@code period()}, {@code copy()}, {@code jump()},
- * {@code defaultJumpDistance()}, {@code leap()}, and {@code defaultLeapDistance()}. Default
- * implementations are provided for all other methods.
- * <p>
- * Objects that implement {@link LeapableRNG} are typically not cryptographically secure. Consider
- * instead using {@link java.security.SecureRandom} to get a cryptographically secure pseudo-random
- * number generator for use by security-sensitive applications.
- *
- * @since 14
- */
-public interface LeapableRNG extends JumpableRNG {
- /**
- * Returns a new generator whose internal state is an exact copy of this generator (therefore
- * their future behavior should be identical if subjected to the same series of operations).
- *
- * @return a new object that is a copy of this generator
- */
- LeapableRNG copy();
-
- /**
- * Alter the state of this pseudorandom number generator so as to leap forward a large, fixed
- * distance (typically 2<sup>96</sup> or more) within its state cycle.
- */
- void leap();
-
- /**
- * Returns the distance by which the {@code leap()} method will leap forward within the state
- * cycle of this generator object.
- *
- * @return the default leap distance (as a {@code double} value)
- */
- double defaultLeapDistance();
-
- /**
- * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
- * implements the {@link JumpableRNG} interface.
- *
- * @return a stream of objects that implement the {@link JumpableRNG} interface
- *
- * @implNote It is permitted to implement this method in a manner equivalent to {@code
- * leaps(Long.MAX_VALUE)}.
- * @implNote The default implementation produces a sequential stream that repeatedly
- * calls {@code copy()} and {@code leap()} on this generator, and the copies become the
- * generators produced by the stream.
- */
- default Stream<JumpableRNG> leaps() {
- return Stream.generate(this::copyAndLeap).sequential();
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
- * generators, each of which implements the {@link JumpableRNG} interface.
- *
- * @param streamSize the number of generators to generate
- *
- * @return a stream of objects that implement the {@link JumpableRNG} interface
- *
- * @throws IllegalArgumentException if {@code streamSize} is less than zero
- * @implNote The default implementation produces a sequential stream that repeatedly
- * calls {@code copy()} and {@code leap()} on this generator, and the copies become the
- * generators produced by the stream.
- */
- default Stream<JumpableRNG> leaps(long streamSize) {
- return leaps().limit(streamSize);
- }
-
- /**
- * Copy this generator, leap this generator forward, then return the copy.
- *
- * @return a copy of this generator object before the leap occurred
- */
- default JumpableRNG copyAndLeap() {
- JumpableRNG result = copy();
- leap();
- return result;
- }
-
-}
--- a/src/java.base/share/classes/java/util/random/MRG32k3a.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/random/MRG32k3a.java Fri Jul 26 15:37:05 2019 -0300
@@ -27,12 +27,14 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.random.RandomGenerator.LeapableGenerator;
+import java.util.random.RandomSupport.AbstractArbitrarilyJumpableGenerator;
/**
* A generator of uniform pseudorandom values applicable for use in
* (among other contexts) isolated parallel computations that may
* generate subtasks. Class {@link MRG32k3a} implements
- * interfaces {@link RandomNumberGenerator} and {@link AbstractArbitrarilyJumpableRNG},
+ * interfaces {@link RandomGenerator} and {@link AbstractArbitrarilyJumpableGenerator},
* and therefore supports methods for producing pseudorandomly chosen
* numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
* as well as creating new {@link Xoroshiro128PlusMRG32k3a} objects
@@ -53,7 +55,7 @@
*
* @since 14
*/
-public final class MRG32k3a extends AbstractArbitrarilyJumpableRNG {
+public final class MRG32k3a extends AbstractArbitrarilyJumpableGenerator {
/*
* Implementation Overview.
@@ -87,7 +89,7 @@
* The seed generator for default constructors.
*/
private static final AtomicLong DEFAULT_GEN =
- new AtomicLong(RNGSupport.initialSeed());
+ new AtomicLong(RandomSupport.initialSeed());
/*
32-bits Random number generator U(0,1): MRG32k3a
@@ -132,7 +134,7 @@
;
return (r + origin);
} else {
- return RNGSupport.boundedNextInt(this, origin, bound);
+ return RandomSupport.boundedNextInt(this, origin, bound);
}
} else {
return nextInt();
@@ -219,7 +221,7 @@
* may, and typically does, vary across program invocations.
*/
public MRG32k3a() {
- this(DEFAULT_GEN.getAndAdd(RNGSupport.GOLDEN_RATIO_64));
+ this(DEFAULT_GEN.getAndAdd(RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -231,7 +233,7 @@
*/
public MRG32k3a(byte[] seed) {
// Convert the seed to 6 int values.
- int[] data = RNGSupport.convertSeedBytesToInts(seed, 6, 0);
+ int[] data = RandomSupport.convertSeedBytesToInts(seed, 6, 0);
int s10 = data[0], s11 = data[1], s12 = data[2];
int s20 = data[3], s21 = data[4], s22 = data[5];
this.s10 = ((double)(((long)s10) & 0x00000000ffffffffL)) % M1;
--- a/src/java.base/share/classes/java/util/random/RNGSupport.java Fri Jul 26 15:20:31 2019 -0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1085 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.random;
-
-import java.util.Spliterator;
-import java.util.stream.DoubleStream;
-import java.util.stream.IntStream;
-import java.util.stream.LongStream;
-
-/**
- * Low-level utility methods helpful for implementing pseudorandom number generators.
- *
- * This class is mostly for library writers creating specific implementations of the
- * interface {@link RandomNumberGenerator}.
- *
- * @since 14
- */
-public class RNGSupport {
-
- /*
- * Implementation Overview.
- *
- * This class provides utility methods and constants frequently
- * useful in the implentation of pseudorandom number generators
- * that satisfy the interface {@link RandomNumberGenerator}.
- *
- * File organization: First some message strings, then the main
- * public methods, followed by a non-public base spliterator class.
- */
-
- // IllegalArgumentException messages
- static final String BAD_SIZE = "size must be non-negative";
- static final String BAD_DISTANCE = "jump distance must be finite, positive, and an exact integer";
- static final String BAD_BOUND = "bound must be positive";
- static final String BAD_FLOATING_BOUND = "bound must be finite and positive";
- static final String BAD_RANGE = "bound must be greater than origin";
-
- /* ---------------- public methods ---------------- */
-
- /**
- * Check a {@code long} proposed stream size for validity.
- *
- * @param streamSize the proposed stream size
- *
- * @throws IllegalArgumentException if {@code streamSize} is negative
- */
- public static void checkStreamSize(long streamSize) {
- if (streamSize < 0L)
- throw new IllegalArgumentException(BAD_SIZE);
- }
-
- /**
- * Check a {@code double} proposed jump distance for validity.
- *
- * @param distance the proposed jump distance
- *
- * @throws IllegalArgumentException if {@code size} not positive, finite, and an exact integer
- */
- public static void checkJumpDistance(double distance) {
- if (!(distance > 0.0 && distance < Float.POSITIVE_INFINITY
- && distance == Math.floor(distance))) {
- throw new IllegalArgumentException(BAD_DISTANCE);
- }
- }
-
- /**
- * Checks a {@code float} upper bound value for validity.
- *
- * @param bound the upper bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code bound} is not positive and finite
- */
- public static void checkBound(float bound) {
- if (!(bound > 0.0 && bound < Float.POSITIVE_INFINITY)) {
- throw new IllegalArgumentException(BAD_FLOATING_BOUND);
- }
- }
-
- /**
- * Checks a {@code double} upper bound value for validity.
- *
- * @param bound the upper bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code bound} is not positive and finite
- */
- public static void checkBound(double bound) {
- if (!(bound > 0.0 && bound < Double.POSITIVE_INFINITY)) {
- throw new IllegalArgumentException(BAD_FLOATING_BOUND);
- }
- }
-
- /**
- * Checks an {@code int} upper bound value for validity.
- *
- * @param bound the upper bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code bound} is not positive
- */
- public static void checkBound(int bound) {
- if (bound <= 0) {
- throw new IllegalArgumentException(BAD_BOUND);
- }
- }
-
- /**
- * Checks a {@code long} upper bound value for validity.
- *
- * @param bound the upper bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code bound} is not positive
- */
- public static void checkBound(long bound) {
- if (bound <= 0) {
- throw new IllegalArgumentException(BAD_BOUND);
- }
- }
-
- /**
- * Checks a {@code float} range for validity.
- *
- * @param origin the least value (inclusive) in the range
- * @param bound the upper bound (exclusive) of the range
- *
- * @throws IllegalArgumentException unless {@code origin} is finite, {@code bound} is finite,
- * and {@code bound - origin} is finite
- */
- public static void checkRange(float origin, float bound) {
- if (!(origin < bound && (bound - origin) < Float.POSITIVE_INFINITY)) {
- throw new IllegalArgumentException(BAD_RANGE);
- }
- }
-
- /**
- * Checks a {@code double} range for validity.
- *
- * @param origin the least value (inclusive) in the range
- * @param bound the upper bound (exclusive) of the range
- *
- * @throws IllegalArgumentException unless {@code origin} is finite, {@code bound} is finite,
- * and {@code bound - origin} is finite
- */
- public static void checkRange(double origin, double bound) {
- if (!(origin < bound && (bound - origin) < Double.POSITIVE_INFINITY)) {
- throw new IllegalArgumentException(BAD_RANGE);
- }
- }
-
- /**
- * Checks an {@code int} range for validity.
- *
- * @param origin the least value that can be returned
- * @param bound the upper bound (exclusive) for the returned value
- *
- * @throws IllegalArgumentException if {@code origin} is greater than or equal to {@code bound}
- */
- public static void checkRange(int origin, int bound) {
- if (origin >= bound) {
- throw new IllegalArgumentException(BAD_RANGE);
- }
- }
-
- /**
- * Checks a {@code long} range for validity.
- *
- * @param origin the least value that can be returned
- * @param bound the upper bound (exclusive) for the returned value
- *
- * @throws IllegalArgumentException if {@code origin} is greater than or equal to {@code bound}
- */
- public static void checkRange(long origin, long bound) {
- if (origin >= bound) {
- throw new IllegalArgumentException(BAD_RANGE);
- }
- }
-
- /**
- * Given an array of seed bytes of any length, construct an array
- * of {@code long} seed values of length {@code n}, such that the
- * last {@code z} values are not all zero.
- *
- * @param seed an array of {@code byte} values
- * @param n the length of the result array (should be nonnegative)
- * @param z the number of trailing result elements that are required
- * to be not all zero (should be nonnegative but not larger
- * than {@code n})
- *
- * @return an array of length {@code n} containing {@code long} seed values
- */
- public static long[] convertSeedBytesToLongs(byte[] seed, int n, int z) {
- final long[] result = new long[n];
- final int m = Math.min(seed.length, n << 3);
- // Distribute seed bytes into the words to be formed.
- for (int j = 0; j < m; j++) {
- result[j>>3] = (result[j>>3] << 8) | seed[j];
- }
- // If there aren't enough seed bytes for all the words we need,
- // use a SplitMix-style PRNG to fill in the rest.
- long v = result[0];
- for (int j = (m + 7) >> 3; j < n; j++) {
- result[j] = mixMurmur64(v += SILVER_RATIO_64);
- }
- // Finally, we need to make sure the last z words are not all zero.
- search: {
- for (int j = n - z; j < n; j++) {
- if (result[j] != 0) break search;
- }
- // If they are, fill in using a SplitMix-style PRNG.
- // Using "& ~1L" in the next line defends against the case z==1
- // by guaranteeing that the first generated value will be nonzero.
- long w = result[0] & ~1L;
- for (int j = n - z; j < n; j++) {
- result[j] = mixMurmur64(w += SILVER_RATIO_64);
- }
- }
- return result;
- }
-
- /**
- * Given an array of seed bytes of any length, construct an array
- * of {@code int} seed values of length {@code n}, such that the
- * last {@code z} values are not all zero.
- *
- * @param seed an array of {@code byte} values
- * @param n the length of the result array (should be nonnegative)
- * @param z the number of trailing result elements that are required
- * to be not all zero (should be nonnegative but not larger
- * than {@code n})
- *
- * @return an array of length {@code n} containing {@code int} seed values
- */
- public static int[] convertSeedBytesToInts(byte[] seed, int n, int z) {
- final int[] result = new int[n];
- final int m = Math.min(seed.length, n << 2);
- // Distribute seed bytes into the words to be formed.
- for (int j = 0; j < m; j++) {
- result[j>>2] = (result[j>>2] << 8) | seed[j];
- }
- // If there aren't enough seed bytes for all the words we need,
- // use a SplitMix-style PRNG to fill in the rest.
- int v = result[0];
- for (int j = (m + 3) >> 2; j < n; j++) {
- result[j] = mixMurmur32(v += SILVER_RATIO_32);
- }
- // Finally, we need to make sure the last z words are not all zero.
- search: {
- for (int j = n - z; j < n; j++) {
- if (result[j] != 0) break search;
- }
- // If they are, fill in using a SplitMix-style PRNG.
- // Using "& ~1" in the next line defends against the case z==1
- // by guaranteeing that the first generated value will be nonzero.
- int w = result[0] & ~1;
- for (int j = n - z; j < n; j++) {
- result[j] = mixMurmur32(w += SILVER_RATIO_32);
- }
- }
- return result;
- }
-
- /*
- * Bounded versions of nextX methods used by streams, as well as
- * the public nextX(origin, bound) methods. These exist mainly to
- * avoid the need for multiple versions of stream spliterators
- * across the different exported forms of streams.
- */
-
- /**
- * This is the form of {@code nextLong} used by a {@link LongStream}
- * {@link Spliterator} and by the public method
- * {@code nextLong(origin, bound)}. If {@code origin} is greater
- * than {@code bound}, then this method simply calls the unbounded
- * version of {@code nextLong()}, choosing pseudorandomly from
- * among all 2<sup>64</sup> possible {@code long} values}, and
- * otherwise uses one or more calls to {@code nextLong()} to
- * choose a value pseudorandomly from the possible values
- * between {@code origin} (inclusive) and {@code bound} (exclusive).
- *
- * @implNote This method first calls {@code nextLong()} to obtain
- * a {@code long} value that is assumed to be pseudorandomly
- * chosen uniformly and independently from the 2<sup>64</sup>
- * possible {@code long} values (that is, each of the 2<sup>64</sup>
- * possible long values is equally likely to be chosen).
- * Under some circumstances (when the specified range is not
- * a power of 2), {@code nextLong()} may be called additional times
- * to ensure that that the values in the specified range are
- * equally likely to be chosen (provided the assumption holds).
- * <p>
- * The implementation considers four cases:
- * <ol>
- *
- * <li> If the {@code} bound} is less than or equal to the {@code origin}
- * (indicated an unbounded form), the 64-bit {@code long} value
- * obtained from {@code nextLong()} is returned directly.
- *
- * <li> Otherwise, if the length <i>n</i> of the specified range is an
- * exact power of two 2<sup><i>m</i></sup> for some integer
- * <i>m</i>, then return the sum of {@code origin} and the
- * <i>m</i> lowest-order bits of the value from {@code nextLong()}.
- *
- * <li> Otherwise, if the length <i>n</i> of the specified range
- * is less than 2<sup>63</sup>, then the basic idea is to use the
- * remainder modulo <i>n</i> of the value from {@code nextLong()},
- * but with this approach some values will be over-represented.
- * Therefore a loop is used to avoid potential bias by rejecting
- * candidates that are too large. Assuming that the results from
- * {@code nextLong()} are truly chosen uniformly and independently,
- * the expected number of iterations will be somewhere between
- * 1 and 2, depending on the precise value of <i>n</i>.
- *
- * <li> Otherwise, the length <i>n</i> of the specified range
- * cannot be represented as a positive {@code long} value.
- * A loop repeatedly calls {@code nextlong()} until obtaining
- * a suitable candidate, Again, the expected number of iterations
- * is less than 2.
- *
- * </ol>
- *
- * @param rng a random number generator to be used as a
- * source of pseudorandom {@code long} values
- * @param origin the least value that can be produced,
- * unless greater than or equal to {@code bound}
- * @param bound the upper bound (exclusive), unless {@code origin}
- * is greater than or equal to {@code bound}
- *
- * @return a pseudorandomly chosen {@code long} value,
- * which will be between {@code origin} (inclusive) and
- * {@code bound} exclusive unless {@code origin}
- * is greater than or equal to {@code bound}
- */
- public static long boundedNextLong(RandomNumberGenerator rng, long origin, long bound) {
- long r = rng.nextLong();
- if (origin < bound) {
- // It's not case (1).
- final long n = bound - origin;
- final long m = n - 1;
- if ((n & m) == 0L) {
- // It is case (2): length of range is a power of 2.
- r = (r & m) + origin;
- } else if (n > 0L) {
- // It is case (3): need to reject over-represented candidates.
- /* This loop takes an unlovable form (but it works):
- 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. */
- for (long u = r >>> 1; // ensure nonnegative
- u + m - (r = u % n) < 0L; // rejection check
- u = rng.nextLong() >>> 1) // retry
- ;
- r += origin;
- }
- else {
- // It is case (4): length of range not representable as long.
- while (r < origin || r >= bound)
- r = rng.nextLong();
- }
- }
- return r;
- }
-
- /**
- * This is the form of {@code nextLong} used by the public method
- * {@code nextLong(bound)}. This is essentially a version of
- * {@code boundedNextLong(origin, bound)} that has been
- * specialized for the case where the {@code origin} is zero
- * and the {@code bound} is greater than zero. The value
- * returned is chosen pseudorandomly from nonnegative integer
- * values less than {@code bound}.
- *
- * @implNote This method first calls {@code nextLong()} to obtain
- * a {@code long} value that is assumed to be pseudorandomly
- * chosen uniformly and independently from the 2<sup>64</sup>
- * possible {@code long} values (that is, each of the 2<sup>64</sup>
- * possible long values is equally likely to be chosen).
- * Under some circumstances (when the specified range is not
- * a power of 2), {@code nextLong()} may be called additional times
- * to ensure that that the values in the specified range are
- * equally likely to be chosen (provided the assumption holds).
- * <p>
- * The implementation considers two cases:
- * <ol>
- *
- * <li> If {@code bound} is an exact power of two 2<sup><i>m</i></sup>
- * for some integer <i>m</i>, then return the sum of {@code origin}
- * and the <i>m</i> lowest-order bits of the value from
- * {@code nextLong()}.
- *
- * <li> Otherwise, the basic idea is to use the remainder modulo
- * <i>bound</i> of the value from {@code nextLong()},
- * but with this approach some values will be over-represented.
- * Therefore a loop is used to avoid potential bias by rejecting
- * candidates that vare too large. Assuming that the results from
- * {@code nextLong()} are truly chosen uniformly and independently,
- * the expected number of iterations will be somewhere between
- * 1 and 2, depending on the precise value of <i>bound</i>.
- *
- * </ol>
- *
- * @param rng a random number generator to be used as a
- * source of pseudorandom {@code long} values
- * @param bound the upper bound (exclusive); must be greater than zero
- *
- * @return a pseudorandomly chosen {@code long} value
- */
- public static long boundedNextLong(RandomNumberGenerator rng, long bound) {
- // Specialize boundedNextLong for origin == 0, bound > 0
- final long m = bound - 1;
- long r = rng.nextLong();
- if ((bound & m) == 0L) {
- // The bound is a power of 2.
- r &= m;
- } else {
- // Must reject over-represented candidates
- /* This loop takes an unlovable form (but it works):
- 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. */
- for (long u = r >>> 1;
- u + m - (r = u % bound) < 0L;
- u = rng.nextLong() >>> 1)
- ;
- }
- return r;
- }
-
- /**
- * This is the form of {@code nextInt} used by an {@link IntStream}
- * {@link Spliterator} and by the public method
- * {@code nextInt(origin, bound)}. If {@code origin} is greater
- * than {@code bound}, then this method simply calls the unbounded
- * version of {@code nextInt()}, choosing pseudorandomly from
- * among all 2<sup>64</sup> possible {@code int} values}, and
- * otherwise uses one or more calls to {@code nextInt()} to
- * choose a value pseudorandomly from the possible values
- * between {@code origin} (inclusive) and {@code bound} (exclusive).
- *
- * @param rng a random number generator to be used as a
- * source of pseudorandom {@code int} values
- * @param origin the least value that can be produced,
- * unless greater than or equal to {@code bound}
- * @param bound the upper bound (exclusive), unless {@code origin}
- * is greater than or equal to {@code bound}
- *
- * @return a pseudorandomly chosen {@code int} value,
- * which will be between {@code origin} (inclusive) and
- * {@code bound} exclusive unless {@code origin}
- * is greater than or equal to {@code bound}
- *
- * @implNote The implementation of this method is identical to
- * the implementation of {@code nextLong(origin, bound)}
- * except that {@code int} values and the {@code nextInt()}
- * method are used rather than {@code long} values and the
- * {@code nextLong()} method.
- */
- public static int boundedNextInt(RandomNumberGenerator rng, int origin, int bound) {
- int r = rng.nextInt();
- if (origin < bound) {
- // It's not case (1).
- final int n = bound - origin;
- final int m = n - 1;
- if ((n & m) == 0) {
- // It is case (2): length of range is a power of 2.
- r = (r & m) + origin;
- } else if (n > 0) {
- // It is case (3): need to reject over-represented candidates.
- for (int u = r >>> 1;
- u + m - (r = u % n) < 0;
- u = rng.nextInt() >>> 1)
- ;
- r += origin;
- }
- else {
- // It is case (4): length of range not representable as long.
- while (r < origin || r >= bound) {
- r = rng.nextInt();
- }
- }
- }
- return r;
- }
-
- /**
- * This is the form of {@code nextInt} used by the public method
- * {@code nextInt(bound)}. This is essentially a version of
- * {@code boundedNextInt(origin, bound)} that has been
- * specialized for the case where the {@code origin} is zero
- * and the {@code bound} is greater than zero. The value
- * returned is chosen pseudorandomly from nonnegative integer
- * values less than {@code bound}.
- *
- * @param rng a random number generator to be used as a
- * source of pseudorandom {@code long} values
- * @param bound the upper bound (exclusive); must be greater than zero
- *
- * @return a pseudorandomly chosen {@code long} value
- *
- * @implNote The implementation of this method is identical to
- * the implementation of {@code nextLong(bound)}
- * except that {@code int} values and the {@code nextInt()}
- * method are used rather than {@code long} values and the
- * {@code nextLong()} method.
- */
- public static int boundedNextInt(RandomNumberGenerator rng, int bound) {
- // Specialize boundedNextInt for origin == 0, bound > 0
- final int m = bound - 1;
- int r = rng.nextInt();
- if ((bound & m) == 0) {
- // The bound is a power of 2.
- r &= m;
- } else {
- // Must reject over-represented candidates
- for (int u = r >>> 1;
- u + m - (r = u % bound) < 0;
- u = rng.nextInt() >>> 1)
- ;
- }
- return r;
- }
-
- /**
- * This is the form of {@code nextDouble} used by a {@link DoubleStream}
- * {@link Spliterator} and by the public method
- * {@code nextDouble(origin, bound)}. If {@code origin} is greater
- * than {@code bound}, then this method simply calls the unbounded
- * version of {@code nextDouble()}, and otherwise scales and translates
- * the result of a call to {@code nextDouble()} so that it lies
- * between {@code origin} (inclusive) and {@code bound} (exclusive).
- *
- * @implNote The implementation considers two cases:
- * <ol>
- *
- * <li> If the {@code bound} is less than or equal to the {@code origin}
- * (indicated an unbounded form), the 64-bit {@code double} value
- * obtained from {@code nextDouble()} is returned directly.
- *
- * <li> Otherwise, the result of a call to {@code nextDouble} is
- * multiplied by {@code (bound - origin)}, then {@code origin}
- * is added, and then if this this result is not less than
- * {@code bound} (which can sometimes occur because of rounding),
- * it is replaced with the largest {@code double} value that
- * is less than {@code bound}.
- *
- * </ol>
- *
- * @param rng a random number generator to be used as a
- * source of pseudorandom {@code double} values
- * @param origin the least value that can be produced,
- * unless greater than or equal to {@code bound}; must be finite
- * @param bound the upper bound (exclusive), unless {@code origin}
- * is greater than or equal to {@code bound}; must be finite
- * @return a pseudorandomly chosen {@code double} value,
- * which will be between {@code origin} (inclusive) and
- * {@code bound} exclusive unless {@code origin}
- * is greater than or equal to {@code bound},
- * in which case it will be between 0.0 (inclusive)
- * and 1.0 (exclusive)
- */
- public static double boundedNextDouble(RandomNumberGenerator rng, double origin, double bound) {
- double r = rng.nextDouble();
- if (origin < bound) {
- r = r * (bound - origin) + origin;
- if (r >= bound) // may need to correct a rounding problem
- r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
- }
- return r;
- }
-
- /**
- * This is the form of {@code nextDouble} used by the public method
- * {@code nextDouble(bound)}. This is essentially a version of
- * {@code boundedNextDouble(origin, bound)} that has been
- * specialized for the case where the {@code origin} is zero
- * and the {@code bound} is greater than zero.
- *
- * @implNote The result of a call to {@code nextDouble} is
- * multiplied by {@code bound}, and then if this result is
- * not less than {@code bound} (which can sometimes occur
- * because of rounding), it is replaced with the largest
- * {@code double} value that is less than {@code bound}.
- *
- * @param rng a random number generator to be used as a
- * source of pseudorandom {@code double} values
- * @param bound the upper bound (exclusive); must be finite and
- * greater than zero
- * @return a pseudorandomly chosen {@code double} value
- * between zero (inclusive) and {@code bound} (exclusive)
- */
- public static double boundedNextDouble(RandomNumberGenerator rng, double bound) {
- // Specialize boundedNextDouble for origin == 0, bound > 0
- double r = rng.nextDouble();
- r = r * bound;
- if (r >= bound) // may need to correct a rounding problem
- r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
- return r;
- }
-
- /**
- * This is the form of {@code nextFloat} used by a {@code Stream<Float>}
- * {@link Spliterator} (if there were any) and by the public method
- * {@code nextFloat(origin, bound)}. If {@code origin} is greater
- * than {@code bound}, then this method simply calls the unbounded
- * version of {@code nextFloat()}, and otherwise scales and translates
- * the result of a call to {@code nextFloat()} so that it lies
- * between {@code origin} (inclusive) and {@code bound} (exclusive).
- *
- * @implNote The implementation of this method is identical to
- * the implementation of {@code nextDouble(origin, bound)}
- * except that {@code float} values and the {@code nextFloat()}
- * method are used rather than {@code double} values and the
- * {@code nextDouble()} method.
- *
- * @param rng a random number generator to be used as a
- * source of pseudorandom {@code float} values
- * @param origin the least value that can be produced,
- * unless greater than or equal to {@code bound}; must be finite
- * @param bound the upper bound (exclusive), unless {@code origin}
- * is greater than or equal to {@code bound}; must be finite
- * @return a pseudorandomly chosen {@code float} value,
- * which will be between {@code origin} (inclusive) and
- * {@code bound} exclusive unless {@code origin}
- * is greater than or equal to {@code bound},
- * in which case it will be between 0.0 (inclusive)
- * and 1.0 (exclusive)
- */
- public static float boundedNextFloat(RandomNumberGenerator rng, float origin, float bound) {
- float r = rng.nextFloat();
- if (origin < bound) {
- r = r * (bound - origin) + origin;
- if (r >= bound) // may need to correct a rounding problem
- r = Float.intBitsToFloat(Float.floatToIntBits(bound) - 1);
- }
- return r;
- }
-
- /**
- * This is the form of {@code nextFloat} used by the public method
- * {@code nextFloat(bound)}. This is essentially a version of
- * {@code boundedNextFloat(origin, bound)} that has been
- * specialized for the case where the {@code origin} is zero
- * and the {@code bound} is greater than zero.
- *
- * @implNote The implementation of this method is identical to
- * the implementation of {@code nextDouble(bound)}
- * except that {@code float} values and the {@code nextFloat()}
- * method are used rather than {@code double} values and the
- * {@code nextDouble()} method.
- *
- * @param rng a random number generator to be used as a
- * source of pseudorandom {@code float} values
- * @param bound the upper bound (exclusive); must be finite and
- * greater than zero
- * @return a pseudorandomly chosen {@code float} value
- * between zero (inclusive) and {@code bound} (exclusive)
- */
- public static float boundedNextFloat(RandomNumberGenerator rng, float bound) {
- // Specialize boundedNextFloat for origin == 0, bound > 0
- float r = rng.nextFloat();
- r = r * bound;
- if (r >= bound) // may need to correct a rounding problem
- r = Float.intBitsToFloat(Float.floatToIntBits(bound) - 1);
- return r;
- }
-
- // The following decides which of two strategies initialSeed() will use.
- private static boolean secureRandomSeedRequested() {
- String pp = java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction(
- "java.util.secureRandomSeed"));
- return (pp != null && pp.equalsIgnoreCase("true"));
- }
-
- private static final boolean useSecureRandomSeed = secureRandomSeedRequested();
-
- /**
- * Returns a {@code long} value (chosen from some
- * machine-dependent entropy source) that may be useful for
- * initializing a source of seed values for instances of {@link RandomNumberGenerator}
- * created by zero-argument constructors. (This method should
- * <i>not</i> be called repeatedly, once per constructed
- * object; at most it should be called once per class.)
- *
- * @return a {@code long} value, randomly chosen using
- * appropriate environmental entropy
- */
- public static long initialSeed() {
- if (useSecureRandomSeed) {
- byte[] seedBytes = java.security.SecureRandom.getSeed(8);
- long s = (long)(seedBytes[0]) & 0xffL;
- for (int i = 1; i < 8; ++i)
- s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
- return s;
- }
- return (mixStafford13(System.currentTimeMillis()) ^
- mixStafford13(System.nanoTime()));
- }
-
- /**
- * The first 32 bits of the golden ratio (1+sqrt(5))/2, forced to be odd.
- * Useful for producing good Weyl sequences or as an arbitrary nonzero odd value.
- */
- public static final int GOLDEN_RATIO_32 = 0x9e3779b9;
-
- /**
- * The first 64 bits of the golden ratio (1+sqrt(5))/2, forced to be odd.
- * Useful for producing good Weyl sequences or as an arbitrary nonzero odd value.
- */
- public static final long GOLDEN_RATIO_64 = 0x9e3779b97f4a7c15L;
-
- /**
- * The first 32 bits of the silver ratio 1+sqrt(2), forced to be odd.
- * Useful for producing good Weyl sequences or as an arbitrary nonzero odd value.
- */
- public static final int SILVER_RATIO_32 = 0x6A09E667;
-
- /**
- * The first 64 bits of the silver ratio 1+sqrt(2), forced to be odd.
- * Useful for producing good Weyl sequences or as an arbitrary nonzero odd value.
- */
- public static final long SILVER_RATIO_64 = 0x6A09E667F3BCC909L;
-
- /**
- * Computes the 64-bit mixing function for MurmurHash3.
- * This is a 64-bit hashing function with excellent avalanche statistics.
- * https://github.com/aappleby/smhasher/wiki/MurmurHash3
- *
- * Note that if the argument {@code z} is 0, the result is 0.
- *
- * @param z any long value
- *
- * @return the result of hashing z
- */
- public static long mixMurmur64(long z) {
- z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
- z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
- return z ^ (z >>> 33);
- }
-
- /**
- * Computes Stafford variant 13 of the 64-bit mixing function for MurmurHash3.
- * This is a 64-bit hashing function with excellent avalanche statistics.
- * http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html
- *
- * Note that if the argument {@code z} is 0, the result is 0.
- *
- * @param z any long value
- *
- * @return the result of hashing z
- */
- public static long mixStafford13(long z) {
- z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L;
- z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
- return z ^ (z >>> 31);
- }
-
- /**
- * Computes Doug Lea's 64-bit mixing function.
- * This is a 64-bit hashing function with excellent avalanche statistics.
- * It has the advantages of using the same multiplicative constant twice
- * and of using only 32-bit shifts.
- *
- * Note that if the argument {@code z} is 0, the result is 0.
- *
- * @param z any long value
- *
- * @return the result of hashing z
- */
- public static long mixLea64(long z) {
- z = (z ^ (z >>> 32)) * 0xdaba0b6eb09322e3L;
- z = (z ^ (z >>> 32)) * 0xdaba0b6eb09322e3L;
- return z ^ (z >>> 32);
- }
-
- /**
- * Computes the 32-bit mixing function for MurmurHash3.
- * This is a 32-bit hashing function with excellent avalanche statistics.
- * https://github.com/aappleby/smhasher/wiki/MurmurHash3
- *
- * Note that if the argument {@code z} is 0, the result is 0.
- *
- * @param z any long value
- *
- * @return the result of hashing z
- */
- public static int mixMurmur32(int z) {
- z = (z ^ (z >>> 16)) * 0x85ebca6b;
- z = (z ^ (z >>> 13)) * 0xc2b2ae35;
- return z ^ (z >>> 16);
- }
-
- /**
- * Computes Doug Lea's 32-bit mixing function.
- * This is a 32-bit hashing function with excellent avalanche statistics.
- * It has the advantages of using the same multiplicative constant twice
- * and of using only 16-bit shifts.
- *
- * Note that if the argument {@code z} is 0, the result is 0.
- *
- * @param z any long value
- *
- * @return the result of hashing z
- */
- public static int mixLea32(int z) {
- z = (z ^ (z >>> 16)) * 0xd36d884b;
- z = (z ^ (z >>> 16)) * 0xd36d884b;
- return z ^ (z >>> 16);
- }
-
- // Non-public (package only) support for spliterators needed by AbstractSplittableRNG
- // and AbstractArbitrarilyJumpableRNG and AbstractSharedRNG
-
- /**
- * Base class for making Spliterator classes for streams of randomly chosen values.
- */
- static abstract class RandomSpliterator {
- long index;
- final long fence;
-
- RandomSpliterator(long index, long fence) {
- this.index = index; this.fence = fence;
- }
-
- public long estimateSize() {
- return fence - index;
- }
-
- public int characteristics() {
- return (Spliterator.SIZED | Spliterator.SUBSIZED |
- Spliterator.NONNULL | Spliterator.IMMUTABLE);
- }
- }
-
-
- /*
- * Implementation support for nextExponential() and nextGaussian() methods of RandomNumberGenerator.
- *
- * Each is implemented using McFarland's fast modified ziggurat algorithm (largely
- * table-driven, with rare cases handled by computation and rejection sampling).
- * Walker's alias method for sampling a discrete distribution also plays a role.
- *
- * The tables themselves, as well as a number of associated parameters, are defined
- * in class java.util.DoubleZigguratTables, which is automatically generated by the
- * program create_ziggurat_tables.c (which takes only a few seconds to run).
- *
- * For more information about the algorithms, see these articles:
- *
- * Christopher D. McFarland. 2016 (published online 24 Jun 2015). A modified ziggurat
- * algorithm for generating exponentially and normally distributed pseudorandom numbers.
- * Journal of Statistical Computation and Simulation 86 (7), pages 1281-1294.
- * https://www.tandfonline.com/doi/abs/10.1080/00949655.2015.1060234
- * Also at https://arxiv.org/abs/1403.6870 (26 March 2014).
- *
- * Alastair J. Walker. 1977. An efficient method for generating discrete random
- * variables with general distributions. ACM Trans. Math. Software 3, 3
- * (September 1977), 253-256. DOI: https://doi.org/10.1145/355744.355749
- *
- * Certain details of these algorithms depend critically on the quality of the
- * low-order bits delivered by NextLong(). These algorithms should not be used
- * with RNG algorithms (such as a simple Linear Congruential Generator) whose
- * low-order output bits do not have good statistical quality.
- */
-
- // Implementation support for nextExponential()
-
- static double computeNextExponential(RandomNumberGenerator rng) {
- long U1 = rng.nextLong();
- // Experimentation on a variety of machines indicates that it is overall much faster
- // to do the following & and < operations on longs rather than first cast U1 to int
- // (but then we need to cast to int before doing the array indexing operation).
- long i = U1 & DoubleZigguratTables.exponentialLayerMask;
- if (i < DoubleZigguratTables.exponentialNumberOfLayers) {
- // This is the fast path (occurring more than 98% of the time). Make an early exit.
- return DoubleZigguratTables.exponentialX[(int)i] * (U1 >>> 1);
- }
- // We didn't use the upper part of U1 after all. We'll be able to use it later.
-
- for (double extra = 0.0; ; ) {
- // Use Walker's alias method to sample an (unsigned) integer j from a discrete
- // probability distribution that includes the tail and all the ziggurat overhangs;
- // j will be less than DoubleZigguratTables.exponentialNumberOfLayers + 1.
- long UA = rng.nextLong();
- int j = (int)UA & DoubleZigguratTables.exponentialAliasMask;
- if (UA >= DoubleZigguratTables.exponentialAliasThreshold[j]) {
- j = DoubleZigguratTables.exponentialAliasMap[j] & DoubleZigguratTables.exponentialSignCorrectionMask;
- }
- if (j > 0) { // Sample overhang j
- // For the exponential distribution, every overhang is convex.
- final double[] X = DoubleZigguratTables.exponentialX;
- final double[] Y = DoubleZigguratTables.exponentialY;
- for (;; U1 = (rng.nextLong() >>> 1)) {
- long U2 = (rng.nextLong() >>> 1);
- // Compute the actual x-coordinate of the randomly chosen point.
- double x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
- // Does the point lie below the curve?
- long Udiff = U2 - U1;
- if (Udiff < 0) {
- // We picked a point in the upper-right triangle. None of those can be accepted.
- // So remap the point into the lower-left triangle and try that.
- // In effect, we swap U1 and U2, and invert the sign of Udiff.
- Udiff = -Udiff;
- U2 = U1;
- U1 -= Udiff;
- }
- if (Udiff >= DoubleZigguratTables.exponentialConvexMargin) {
- return x + extra; // The chosen point is way below the curve; accept it.
- }
- // Compute the actual y-coordinate of the randomly chosen point.
- double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
- // Now see how that y-coordinate compares to the curve
- if (y <= Math.exp(-x)) {
- return x + extra; // The chosen point is below the curve; accept it.
- }
- // Otherwise, we reject this sample and have to try again.
- }
- }
- // We are now committed to sampling from the tail. We could do a recursive call
- // and then add X[0] but we save some time and stack space by using an iterative loop.
- extra += DoubleZigguratTables.exponentialX0;
- // This is like the first five lines of this method, but if it returns, it first adds "extra".
- U1 = rng.nextLong();
- i = U1 & DoubleZigguratTables.exponentialLayerMask;
- if (i < DoubleZigguratTables.exponentialNumberOfLayers) {
- return DoubleZigguratTables.exponentialX[(int)i] * (U1 >>> 1) + extra;
- }
- }
- }
-
- // Implementation support for nextGaussian()
-
- static double computeNextGaussian(RandomNumberGenerator rng) {
- long U1 = rng.nextLong();
- // Experimentation on a variety of machines indicates that it is overall much faster
- // to do the following & and < operations on longs rather than first cast U1 to int
- // (but then we need to cast to int before doing the array indexing operation).
- long i = U1 & DoubleZigguratTables.normalLayerMask;
-
- if (i < DoubleZigguratTables.normalNumberOfLayers) {
- // This is the fast path (occurring more than 98% of the time). Make an early exit.
- return DoubleZigguratTables.normalX[(int)i] * U1; // Note that the sign bit of U1 is used here.
- }
- // We didn't use the upper part of U1 after all.
- // Pull U1 apart into a sign bit and a 63-bit value for later use.
- double signBit = (U1 >= 0) ? 1.0 : -1.0;
- U1 = (U1 << 1) >>> 1;
-
- // Use Walker's alias method to sample an (unsigned) integer j from a discrete
- // probability distribution that includes the tail and all the ziggurat overhangs;
- // j will be less than DoubleZigguratTables.normalNumberOfLayers + 1.
- long UA = rng.nextLong();
- int j = (int)UA & DoubleZigguratTables.normalAliasMask;
- if (UA >= DoubleZigguratTables.normalAliasThreshold[j]) {
- j = DoubleZigguratTables.normalAliasMap[j] & DoubleZigguratTables.normalSignCorrectionMask;
- }
-
- double x;
- // Now the goal is to choose the result, which will be multiplied by signBit just before return.
-
- // There are four kinds of overhangs:
- //
- // j == 0 : Sample from tail
- // 0 < j < normalInflectionIndex : Overhang is convex; can reject upper-right triangle
- // j == normalInflectionIndex : Overhang includes the inflection point
- // j > normalInflectionIndex : Overhang is concave; can accept point in lower-left triangle
- //
- // Choose one of four loops to compute x, each specialized for a specific kind of overhang.
- // Conditional statements are arranged such that the more likely outcomes are first.
-
- // In the three cases other than the tail case:
- // U1 represents a fraction (scaled by 2**63) of the width of rectangle measured from the left.
- // U2 represents a fraction (scaled by 2**63) of the height of rectangle measured from the top.
- // Together they indicate a randomly chosen point within the rectangle.
-
- final double[] X = DoubleZigguratTables.normalX;
- final double[] Y = DoubleZigguratTables.normalY;
- if (j > DoubleZigguratTables.normalInflectionIndex) { // Concave overhang
- for (;; U1 = (rng.nextLong() >>> 1)) {
- long U2 = (rng.nextLong() >>> 1);
- // Compute the actual x-coordinate of the randomly chosen point.
- x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
- // Does the point lie below the curve?
- long Udiff = U2 - U1;
- if (Udiff >= 0) {
- break; // The chosen point is in the lower-left triangle; accept it.
- }
- if (Udiff <= -DoubleZigguratTables.normalConcaveMargin) {
- continue; // The chosen point is way above the curve; reject it.
- }
- // Compute the actual y-coordinate of the randomly chosen point.
- double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
- // Now see how that y-coordinate compares to the curve
- if (y <= Math.exp(-0.5*x*x)) {
- break; // The chosen point is below the curve; accept it.
- }
- // Otherwise, we reject this sample and have to try again.
- }
- } else if (j == 0) { // Tail
- // Tail-sampling method of Marsaglia and Tsang. See any one of:
- // Marsaglia and Tsang. 1984. A fast, easily implemented method for sampling from decreasing
- // or symmetric unimodal density functions. SIAM J. Sci. Stat. Comput. 5, 349-359.
- // Marsaglia and Tsang. 1998. The Monty Python method for generating random variables.
- // ACM Trans. Math. Softw. 24, 3 (September 1998), 341-350. See page 342, step (4).
- // http://doi.org/10.1145/292395.292453
- // Thomas, Luk, Leong, and Villasenor. 2007. Gaussian random number generators.
- // ACM Comput. Surv. 39, 4, Article 11 (November 2007). See Algorithm 16.
- // http://doi.org/10.1145/1287620.1287622
- // Compute two separate random exponential samples and then compare them in certain way.
- do {
- x = (1.0 / DoubleZigguratTables.normalX0) * computeNextExponential(rng);
- } while (computeNextExponential(rng) < 0.5*x*x);
- x += DoubleZigguratTables.normalX0;
- } else if (j < DoubleZigguratTables.normalInflectionIndex) { // Convex overhang
- for (;; U1 = (rng.nextLong() >>> 1)) {
- long U2 = (rng.nextLong() >>> 1);
- // Compute the actual x-coordinate of the randomly chosen point.
- x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
- // Does the point lie below the curve?
- long Udiff = U2 - U1;
- if (Udiff < 0) {
- // We picked a point in the upper-right triangle. None of those can be accepted.
- // So remap the point into the lower-left triangle and try that.
- // In effect, we swap U1 and U2, and invert the sign of Udiff.
- Udiff = -Udiff;
- U2 = U1;
- U1 -= Udiff;
- }
- if (Udiff >= DoubleZigguratTables.normalConvexMargin) {
- break; // The chosen point is way below the curve; accept it.
- }
- // Compute the actual y-coordinate of the randomly chosen point.
- double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
- // Now see how that y-coordinate compares to the curve
- if (y <= Math.exp(-0.5*x*x)) break; // The chosen point is below the curve; accept it.
- // Otherwise, we reject this sample and have to try again.
- }
- } else {
- // The overhang includes the inflection point, so the curve is both convex and concave
- for (;; U1 = (rng.nextLong() >>> 1)) {
- long U2 = (rng.nextLong() >>> 1);
- // Compute the actual x-coordinate of the randomly chosen point.
- x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
- // Does the point lie below the curve?
- long Udiff = U2 - U1;
- if (Udiff >= DoubleZigguratTables.normalConvexMargin) {
- break; // The chosen point is way below the curve; accept it.
- }
- if (Udiff <= -DoubleZigguratTables.normalConcaveMargin) {
- continue; // The chosen point is way above the curve; reject it.
- }
- // Compute the actual y-coordinate of the randomly chosen point.
- double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
- // Now see how that y-coordinate compares to the curve
- if (y <= Math.exp(-0.5*x*x)) {
- break; // The chosen point is below the curve; accept it.
- }
- // Otherwise, we reject this sample and have to try again.
- }
- }
- return signBit*x;
- }
-
-}
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/util/random/RandomGenerator.java Fri Jul 26 15:37:05 2019 -0300
@@ -0,0 +1,1250 @@
+/*
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.util.random;
+
+import java.math.BigInteger;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+/**
+ * The {@link RandomGenerator} interface is designed to provide a common protocol for objects
+ * that generate random or (more typically) pseudorandom sequences of numbers (or Boolean values).
+ * Such a sequence may be obtained by either repeatedly invoking a method that returns a single
+ * (pseudo)randomly chosen value, or by invoking a method that returns a stream of (pseudo)randomly
+ * chosen values.
+ * <p>
+ * Ideally, given an implicitly or explicitly specified range of values, each value would be chosen
+ * independently and uniformly from that range. In practice, one may have to settle for some
+ * approximation to independence and uniformity.
+ * <p>
+ * In the case of {@code int}, {@code long}, and {@link Boolean} values, if there is no explicit
+ * specification of range, then the range includes all possible values of the type. In the case of
+ * {@code float} and {@code double} values, a value is always chosen from the set of
+ * 2<sup><i>w</i></sup> values between 0.0 (inclusive) and 1.0 (exclusive), where <i>w</i> is 23 for
+ * {@code float} values and 52 for {@code double} values, such that adjacent values differ by
+ * 2<sup>−<i>w</i></sup>; if an explicit range is specified, then the chosen number is
+ * computationally scaled and translated so as to appear to have been chosen from that range.
+ * <p>
+ * Each method that returns a stream produces a stream of values each of which is chosen in the same
+ * manner as for a method that returns a single (pseudo)randomly chosen value. For example, if
+ * {@code r} implements {@link RandomGenerator}, then the method call {@code r.ints(100)}
+ * returns a stream of 100 {@code int} values. These are not necessarily the exact same values that
+ * would have been returned if instead {@code r.nextInt()} had been called 100 times; all that is
+ * guaranteed is that each value in the stream is chosen in a similar (pseudo)random manner from the
+ * same range.
+ * <p>
+ * Every object that implements the {@link RandomGenerator} interface is assumed to contain a
+ * finite amount of state. Using such an object to generate a pseudorandomly chosen value alters
+ * its state. The number of distinct possible states of such an object is called its
+ * <i>period</i>. (Some implementations of the {@link RandomGenerator} interface
+ * may be truly random rather than pseudorandom, for example relying on the statistical behavior of
+ * a physical object to derive chosen values. Such implementations do not have a fixed period.)
+ * <p>
+ * As a rule, objects that implement the {@link RandomGenerator} interface need not be
+ * thread-safe. It is recommended that multithreaded applications use either {@link
+ * ThreadLocalRandom} or (preferably) pseudorandom number generators that implement the {@link
+ * SplittableGenerator} or {@link JumpableGenerator} interface.
+ * <p>
+ * To implement this interface, a class only needs to provide concrete definitions for the methods
+ * {@code nextLong()} and {@code period()}. Default implementations are provided for all other
+ * methods (but it may be desirable to override some of them, especially {@code nextInt()} if the
+ * underlying algorithm is {@code int}-based). Moerover, it may be preferable instead to implement
+ * another interface such as {@link JumpableGenerator} or {@link LeapableGenerator}, or to extend an abstract
+ * class such as {@link AbstractSplittableGenerator} or {@link AbstractArbitrarilyJumpableGenerator}.
+ * <p>
+ * Objects that implement {@link RandomGenerator} are typically not cryptographically secure.
+ * Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure
+ * pseudorandom number generator for use by security-sensitive applications. Note, however, that
+ * {@code java.security.SecureRandom} does implement the {@link RandomGenerator} interface, so
+ * that instances of {@code java.security.SecureRandom} may be used interchangeably with other types
+ * of pseudorandom generators in applications that do not require a secure generator.
+ *
+ * @since 14
+ */
+public interface RandomGenerator {
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandomly chosen
+ * {@code double} values.
+ *
+ * @return a stream of pseudorandomly chosen {@code double} values
+ *
+ * @implNote It is permitted to implement this method in a manner
+ * equivalent to {@code doubles(Long.MAX_VALUE)}.
+ *
+ * @implNote The default implementation produces a sequential stream
+ * that repeatedly calls {@code nextDouble()}.
+ */
+ default DoubleStream doubles() {
+ return DoubleStream.generate(this::nextDouble).sequential();
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandomly chosen
+ * {@code double} values, where each value is between the specified
+ * origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param randomNumberOrigin the least value that can be produced
+ * @param randomNumberBound the upper bound (exclusive) for each value produced
+ *
+ * @return a stream of pseudorandomly chosen {@code double} values, each between
+ * the specified origin (inclusive) and the specified bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ *
+ * @implNote It is permitted to implement this method in a manner
+ * equivalent to
+ * {@code doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+ * @implNote The default implementation produces a sequential stream that repeatedly
+ * calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}.
+ */
+ default DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
+ RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
+ return DoubleStream.generate(() -> nextDouble(randomNumberOrigin, randomNumberBound)).sequential();
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandomly chosen {@code double} values.
+ *
+ * @param streamSize the number of values to generate
+ *
+ * @return a stream of pseudorandomly chosen {@code double} values
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ *
+ * @implNote The default implementation produces a sequential stream
+ * that repeatedly calls {@code nextDouble()}.
+ */
+ default DoubleStream doubles(long streamSize) {
+ RandomSupport.checkStreamSize(streamSize);
+ return doubles().limit(streamSize);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandomly chosen {@code double} values, where each value is between
+ * the specified origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the least value that can be produced
+ * @param randomNumberBound the upper bound (exclusive) for each value produced
+ *
+ * @return a stream of pseudorandomly chosen {@code double} values, each between
+ * the specified origin (inclusive) and the specified bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero, or {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ *
+ * @implNote The default implementation produces a sequential stream
+ * that repeatedly calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}.
+ */
+ default DoubleStream doubles(long streamSize, double randomNumberOrigin,
+ double randomNumberBound) {
+ RandomSupport.checkStreamSize(streamSize);
+ RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
+ return doubles(randomNumberOrigin, randomNumberBound).limit(streamSize);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandomly chosen
+ * {@code int} values.
+ *
+ * @return a stream of pseudorandomly chosen {@code int} values
+ *
+ * @implNote It is permitted to implement this method in a manner
+ * equivalent to {@code ints(Long.MAX_VALUE)}.
+ * @implNote The default implementation produces a sequential stream
+ * that repeatedly calls {@code nextInt()}.
+ */
+ default IntStream ints() {
+ return IntStream.generate(this::nextInt).sequential();
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandomly chosen
+ * {@code int} values, where each value is between the specified
+ * origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param randomNumberOrigin the least value that can be produced
+ * @param randomNumberBound the upper bound (exclusive) for each value produced
+ *
+ * @return a stream of pseudorandomly chosen {@code int} values, each between
+ * the specified origin (inclusive) and the specified bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ *
+ * @implNote It is permitted to implement this method in a manner equivalent to
+ * {@code ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+ * @implNote The default implementation produces a sequential stream that repeatedly
+ * calls {@code nextInt(randomNumberOrigin, randomNumberBound)}.
+ */
+ default IntStream ints(int randomNumberOrigin, int randomNumberBound) {
+ RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
+ return IntStream.generate(() -> nextInt(randomNumberOrigin, randomNumberBound)).sequential();
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandomly chosen {@code int} values.
+ *
+ * @param streamSize the number of values to generate
+ *
+ * @return a stream of pseudorandomly chosen {@code int} values
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ *
+ * @implNote The default implementation produces a sequential stream
+ * that repeatedly calls {@code nextInt()}.
+ */
+ default IntStream ints(long streamSize) {
+ RandomSupport.checkStreamSize(streamSize);
+ return ints().limit(streamSize);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandomly chosen {@code int} values, where each value is between
+ * the specified origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the least value that can be produced
+ * @param randomNumberBound the upper bound (exclusive) for each value produced
+ *
+ * @return a stream of pseudorandomly chosen {@code int} values, each between
+ * the specified origin (inclusive) and the specified bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero, or {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ *
+ * @implNote The default implementation produces a sequential stream that repeatedly
+ * calls {@code nextInt(randomNumberOrigin, randomNumberBound)}.
+ */
+ default IntStream ints(long streamSize, int randomNumberOrigin,
+ int randomNumberBound) {
+ RandomSupport.checkStreamSize(streamSize);
+ RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
+ return ints(randomNumberOrigin, randomNumberBound).limit(streamSize);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandomly chosen
+ * {@code long} values.
+ *
+ * @return a stream of pseudorandomly chosen {@code long} values
+ *
+ * @implNote It is permitted to implement this method in a manner
+ * equivalent to {@code longs(Long.MAX_VALUE)}.
+ * @implNote The default implementation produces a sequential stream
+ * that repeatedly calls {@code nextLong()}.
+ */
+ default LongStream longs() {
+ return LongStream.generate(this::nextLong).sequential();
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandomly chosen
+ * {@code long} values, where each value is between the specified
+ * origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param randomNumberOrigin the least value that can be produced
+ * @param randomNumberBound the upper bound (exclusive) for each value produced
+ *
+ * @return a stream of pseudorandomly chosen {@code long} values, each between
+ * the specified origin (inclusive) and the specified bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ *
+ * @implNote It is permitted to implement this method in a manner
+ * equivalent to {@code longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+ * @implNote The default implementation produces a sequential stream that repeatedly
+ * calls {@code nextLong(randomNumberOrigin, randomNumberBound)}.
+ */
+ default LongStream longs(long randomNumberOrigin, long randomNumberBound) {
+ RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
+ return LongStream.generate(() -> nextLong(randomNumberOrigin, randomNumberBound)).sequential();
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandomly chosen {@code long} values.
+ *
+ * @param streamSize the number of values to generate
+ *
+ * @return a stream of pseudorandomly chosen {@code long} values
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ *
+ * @implNote The default implementation produces a sequential stream
+ * that repeatedly calls {@code nextLong()}.
+ */
+ default LongStream longs(long streamSize) {
+ RandomSupport.checkStreamSize(streamSize);
+ return longs().limit(streamSize);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandomly chosen {@code long} values, where each value is between
+ * the specified origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the least value that can be produced
+ * @param randomNumberBound the upper bound (exclusive) for each value produced
+ *
+ * @return a stream of pseudorandomly chosen {@code long} values, each between
+ * the specified origin (inclusive) and the specified bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero, or {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ *
+ * @implNote The default implementation produces a sequential stream that repeatedly
+ * calls {@code nextLong(randomNumberOrigin, randomNumberBound)}.
+ */
+ default LongStream longs(long streamSize, long randomNumberOrigin,
+ long randomNumberBound) {
+ RandomSupport.checkStreamSize(streamSize);
+ RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
+ return longs(randomNumberOrigin, randomNumberBound).limit(streamSize);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code boolean} value.
+ * <p>
+ * The default implementation tests the high-order bit (sign bit) of a value produced by {@code
+ * nextInt()}, on the grounds that some algorithms for pseudorandom number generation produce
+ * values whose high-order bits have better statistical quality than the low-order bits.
+ *
+ * @return a pseudorandomly chosen {@code boolean} value
+ */
+ default boolean nextBoolean() {
+ return nextInt() < 0;
+ }
+
+ /**
+ * Returns a pseudorandom {@code float} value between zero (inclusive) and one (exclusive).
+ * <p>
+ * The default implementation uses the 24 high-order bits from a call to {@code nextInt()}.
+ *
+ * @return a pseudorandom {@code float} value between zero (inclusive) and one (exclusive)
+ */
+ default float nextFloat() {
+ return (nextInt() >>> 8) * 0x1.0p-24f;
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code float} value between zero
+ * (inclusive) and the specified bound (exclusive).
+ *
+ * @param bound the upper bound (exclusive) for the returned value.
+ * Must be positive and finite
+ *
+ * @return a pseudorandomly chosen {@code float} value between
+ * zero (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code bound} is not
+ * positive and finite
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkBound(bound)} and then
+ * {@code RandomSupport.boundedNextFloat(this, bound)}.
+ */
+ default float nextFloat(float bound) {
+ RandomSupport.checkBound(bound);
+ return RandomSupport.boundedNextFloat(this, bound);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code float} value between the
+ * specified origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param origin the least value that can be returned
+ * @param bound the upper bound (exclusive)
+ *
+ * @return a pseudorandomly chosen {@code float} value between the
+ * origin (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException unless {@code origin} is finite,
+ * {@code bound} is finite, and {@code origin} is less than
+ * {@code bound}
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkRange(origin, bound)} and then
+ * {@code RandomSupport.boundedNextFloat(this, origin, bound)}.
+ */
+ default float nextFloat(float origin, float bound) {
+ RandomSupport.checkRange(origin, bound);
+ return RandomSupport.boundedNextFloat(this, origin, bound);
+ }
+
+ /**
+ * Returns a pseudorandom {@code double} value between zero (inclusive) and one (exclusive).
+ * <p>
+ * The default implementation uses the 53 high-order bits from a call to {@code nextLong()}.
+ *
+ * @return a pseudorandom {@code double} value between zero (inclusive) and one (exclusive)
+ */
+ default double nextDouble() {
+ return (nextLong() >>> 11) * 0x1.0p-53;
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code double} value between zero
+ * (inclusive) and the specified bound (exclusive).
+ *
+ * @param bound the upper bound (exclusive) for the returned value.
+ * Must be positive and finite
+ *
+ * @return a pseudorandomly chosen {@code double} value between
+ * zero (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code bound} is not
+ * positive and finite
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkBound(bound)} and then
+ * {@code RandomSupport.boundedNextDouble(this, bound)}.
+ */
+ default double nextDouble(double bound) {
+ RandomSupport.checkBound(bound);
+ return RandomSupport.boundedNextDouble(this, bound);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code double} value between the
+ * specified origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param origin the least value that can be returned
+ * @param bound the upper bound (exclusive) for the returned value
+ *
+ * @return a pseudorandomly chosen {@code double} value between the
+ * origin (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException unless {@code origin} is finite,
+ * {@code bound} is finite, and {@code origin} is less than
+ * {@code bound}
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkRange(origin, bound)} and then
+ * {@code RandomSupport.boundedNextDouble(this, origin, bound)}.
+ */
+ default double nextDouble(double origin, double bound) {
+ RandomSupport.checkRange(origin, bound);
+ return RandomSupport.boundedNextDouble(this, origin, bound);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code int} value.
+ * <p>
+ * The default implementation uses the 32 high-order bits from a call to {@code nextLong()}.
+ *
+ * @return a pseudorandomly chosen {@code int} value
+ */
+ default public int nextInt() {
+ return (int)(nextLong() >>> 32);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code int} value between
+ * zero (inclusive) and the specified bound (exclusive).
+ *
+ * @param bound the upper bound (exclusive) for the returned value. Must be positive.
+ *
+ * @return a pseudorandomly chosen {@code int} value between
+ * zero (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code bound} is not positive
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkBound(bound)} and then
+ * {@code RandomSupport.boundedNextInt(this, bound)}.
+ */
+ default int nextInt(int bound) {
+ RandomSupport.checkBound(bound);
+ return RandomSupport.boundedNextInt(this, bound);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code int} value between the
+ * specified origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param origin the least value that can be returned
+ * @param bound the upper bound (exclusive) for the returned value
+ *
+ * @return a pseudorandomly chosen {@code int} value between the
+ * origin (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code origin} is greater than
+ * or equal to {@code bound}
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkRange(origin, bound)} and then
+ * {@code RandomSupport.boundedNextInt(this, origin, bound)}.
+ */
+ default int nextInt(int origin, int bound) {
+ RandomSupport.checkRange(origin, bound);
+ return RandomSupport.boundedNextInt(this, origin, bound);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code long} value.
+ *
+ * @return a pseudorandomly chosen {@code long} value
+ */
+ long nextLong();
+
+ /**
+ * Returns a pseudorandomly chosen {@code long} value between
+ * zero (inclusive) and the specified bound (exclusive).
+ *
+ * @param bound the upper bound (exclusive) for the returned value. Must be positive.
+ *
+ * @return a pseudorandomly chosen {@code long} value between
+ * zero (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code bound} is not positive
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkBound(bound)} and then
+ * {@code RandomSupport.boundedNextLong(this, bound)}.
+ */
+ default long nextLong(long bound) {
+ RandomSupport.checkBound(bound);
+ return RandomSupport.boundedNextLong(this, bound);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code long} value between the
+ * specified origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param origin the least value that can be returned
+ * @param bound the upper bound (exclusive) for the returned value
+ *
+ * @return a pseudorandomly chosen {@code long} value between the
+ * origin (inclusive) and the bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code origin} is greater than
+ * or equal to {@code bound}
+ *
+ * @implNote The default implementation simply calls
+ * {@code RandomSupport.checkRange(origin, bound)} and then
+ * {@code RandomSupport.boundedNextInt(this, origin, bound)}.
+ *
+ */
+ default long nextLong(long origin, long bound) {
+ RandomSupport.checkRange(origin, bound);
+ return RandomSupport.boundedNextLong(this, origin, bound);
+ }
+
+ /**
+ * Returns a {@code double} value pseudorandomly chosen from
+ * a Gaussian (normal) distribution whose mean is 0 and whose
+ * standard deviation is 1.
+ *
+ * @return a {@code double} value pseudorandomly chosen from a
+ * Gaussian distribution
+ */
+ default double nextGaussian() {
+ return RandomSupport.computeNextGaussian(this);
+ }
+
+ /**
+ * Returns a {@code double} value pseudorandomly chosen from
+ * a Gaussian (normal) distribution with a mean and
+ * standard deviation specified by the arguments.
+ *
+ * @param mean the mean of the Gaussian distribution to be drawn from
+ * @param stddev the standard deviation (square root of the variance)
+ * of the Gaussian distribution to be drawn from
+ *
+ * @return a {@code double} value pseudorandomly chosen from the
+ * specified Gaussian distribution
+ *
+ * @throws IllegalArgumentException if {@code stddev} is negative
+ */
+ default double nextGaussian(double mean, double stddev) {
+ if (stddev < 0.0) throw new IllegalArgumentException("standard deviation must be non-negative");
+ return mean + stddev * RandomSupport.computeNextGaussian(this);
+ }
+
+ /**
+ * Returns a nonnegative {@code double} value pseudorandomly chosen
+ * from an exponential distribution whose mean is 1.
+ *
+ * @return a nonnegative {@code double} value pseudorandomly chosen from an
+ * exponential distribution
+ */
+ default double nextExponential() {
+ return RandomSupport.computeNextExponential(this);
+ }
+
+ /**
+ * Returns the period of this {@link RandomGenerator} object.
+ *
+ * @return a {@link BigInteger} whose value is the number of distinct possible states of this
+ * {@link RandomGenerator} object, or 0 if unknown, or negative if extremely
+ * large.
+ */
+ BigInteger period();
+
+ /**
+ * The value (0) returned by the {@code period()} method if the period is unknown.
+ */
+ static final BigInteger UNKNOWN_PERIOD = BigInteger.ZERO;
+
+ /**
+ * The (negative) value returned by the {@code period()} method if this generator
+ * has no period because it is truly random rather than just pseudorandom.
+ */
+ static final BigInteger TRULY_RANDOM = BigInteger.valueOf(-1);
+
+ /**
+ * The (negative) value that may be returned by the {@code period()} method
+ * if this generator has a huge period (larger than 2**(2**16)).
+ */
+ static final BigInteger HUGE_PERIOD = BigInteger.valueOf(-2);
+
+ /**
+ * The {@link StreamableGenerator} interface augments the {@link RandomGenerator} interface
+ * to provide methods that return streams of {@link RandomGenerator} objects.
+ * Ideally, such a stream of objects would have the property that the
+ * behavior of each object is statistically independent of all the others.
+ * In practice, one may have to settle for some approximation to this property.
+ *
+ * A generator that implements interface {@link SplittableGenerator}
+ * may choose to use its {@code splits} method to implement the {@code rngs}
+ * method required by this interface.
+ *
+ * A generator that implements interface {@link JumpableGenerator}
+ * may choose to use its {@code jumps} method to implement the {@code rngs}
+ * method required by this interface.
+ *
+ * A generator that implements interface {@link LeapableGenerator}
+ * may choose to use its {@code leaps} method to implement the {@code rngs}
+ * method required by this interface.
+ * <p>
+ * An implementation of the {@link StreamableGenerator} interface must provide
+ * concrete definitions for the methods {@code nextInt()}, {@code nextLong},
+ * {@code period()}, and {@code rngs()}.
+ * Default implementations are provided for all other methods.
+ * <p>
+ * Objects that implement {@link StreamableGenerator} are typically
+ * not cryptographically secure. Consider instead using
+ * {@link java.security.SecureRandom} to get a cryptographically
+ * secure pseudo-random number generator for use by
+ * security-sensitive applications.
+ *
+ * @since 14
+ */
+ public interface StreamableGenerator extends RandomGenerator {
+ /**
+ * Returns an effectively unlimited stream of objects, each of
+ * which implements the {@link RandomGenerator} interface. Ideally the
+ * generators in the stream will appear to be statistically
+ * independent. The new generators should be of the same kind
+ * as this generator.
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @implNote It is permitted to implement this method in a manner
+ * equivalent to {@code rngs(Long.MAX_VALUE)}.
+ */
+ Stream<RandomGenerator> rngs();
+
+ /**
+ * Returns an effectively unlimited stream of objects, each of
+ * which implements the {@link RandomGenerator} interface. Ideally the
+ * generators in the stream will appear to be statistically
+ * independent. The new generators should be of the same kind
+ * as this generator.
+ *
+ * @param streamSize the number of generators to generate
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ *
+ * @implNote The default implementation calls {@code rngs()} and
+ * then limits its length to {@code streamSize}.
+ */
+ default Stream<RandomGenerator> rngs(long streamSize) {
+ RandomSupport.checkStreamSize(streamSize);
+ return rngs().limit(streamSize);
+ }
+ }
+
+ /**
+ * This interface is designed to provide a common protocol for objects
+ * that generate sequences of pseudorandom numbers (or Boolean values)
+ * and furthermore can be <i>split</i> into two objects (the original
+ * one and a new one) each of which obey that same protocol (and therefore
+ * can be recursively split indefinitely).
+ * <p>
+ * Ideally, all {@link SplittableGenerator} objects produced by recursive
+ * splitting from a single original {@link SplittableGenerator} object are
+ * statistically independent of one another and individually uniform.
+ * Therefore we would expect the set of values collectively generated
+ * by a set of such objects to have the same statistical properties as
+ * if the same quantity of values were generated by a single thread
+ * using a single {@link SplittableGenerator} object. In practice, one must
+ * settle for some approximation to independence and uniformity.
+ * <p>
+ * Methods are provided to perform a single splitting operation and
+ * also to produce a stream of generators split off from the original
+ * (by either iterative or recursive splitting, or a combination).
+ * <p>
+ * An implementation of the {@link SplittableGenerator} interface must provide
+ * concrete definitions for the methods {@code nextInt()}, {@code nextLong},
+ * {@code period()}, {@code split()}, {@code split(SplittableGenerator)},
+ * {@code splits()}, {@code splits(long)}, {@code splits(SplittableGenerator)},
+ * and {@code splits(long, SplittableGenerator)}. Perhaps the most convenient
+ * way to implement this interface is to extend the abstract class
+ * {@link AbstractSplittableGenerator}.
+ * <p>
+ * Objects that implement {@link SplittableGenerator} are
+ * typically not cryptographically secure. Consider instead using
+ * {@link java.security.SecureRandom} to get a cryptographically
+ * secure pseudo-random number generator for use by
+ * security-sensitive applications.
+ *
+ * @since 14
+ */
+ public interface SplittableGenerator extends StreamableGenerator {
+
+ /**
+ * Returns a new pseudorandom number generator, split off from
+ * this one, that implements the {@link RandomGenerator} and {@link SplittableGenerator}
+ * interfaces.
+ *
+ * This pseudorandom number generator may be used as a source of
+ * pseudorandom bits used to initialize the state the new one.
+ *
+ * @return a new object that implements the {@link RandomGenerator} and
+ * {@link SplittableGenerator} interfaces
+ */
+ SplittableGenerator split();
+
+ /**
+ * Returns a new pseudorandom number generator, split off from
+ * this one, that implements the {@link RandomGenerator} and {@link SplittableGenerator}
+ * interfaces.
+ *
+ * @param source a {@link SplittableGenerator} instance to be used instead
+ * of this one as a source of pseudorandom bits used to
+ * initialize the state of the new ones.
+ *
+ * @return an object that implements the {@link RandomGenerator} and
+ * {@link SplittableGenerator} interfaces
+ */
+ SplittableGenerator split(SplittableGenerator source);
+
+ /**
+ * Returns an effectively unlimited stream of new pseudorandom
+ * number generators, each of which implements the {@link SplittableGenerator}
+ * interface.
+ *
+ * This pseudorandom number generator may be used as a source of
+ * pseudorandom bits used to initialize the state the new ones.
+ *
+ * @implNote It is permitted to implement this method in a manner
+ * equivalent to {@code splits(Long.MAX_VALUE)}.
+ *
+ * @return a stream of {@link SplittableGenerator} objects
+ */
+ default Stream<SplittableGenerator> splits() {
+ return this.splits(this);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * new pseudorandom number generators, each of which implements the
+ * {@link SplittableGenerator} interface.
+ *
+ * This pseudorandom number generator may be used as a source of
+ * pseudorandom bits used to initialize the state the new ones.
+ *
+ * @param streamSize the number of values to generate
+ *
+ * @return a stream of {@link SplittableGenerator} objects
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ */
+ Stream<SplittableGenerator> splits(long streamSize);
+
+ /**
+ * Returns an effectively unlimited stream of new pseudorandom
+ * number generators, each of which implements the {@link SplittableGenerator}
+ * interface.
+ *
+ * @param source a {@link SplittableGenerator} instance to be used instead
+ * of this one as a source of pseudorandom bits used to
+ * initialize the state of the new ones.
+ *
+ * @return a stream of {@link SplittableGenerator} objects
+ *
+ * @implNote It is permitted to implement this method in a manner
+ * equivalent to {@code splits(Long.MAX_VALUE, source)}.
+ */
+ Stream<SplittableGenerator> splits(SplittableGenerator source);
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * new pseudorandom number generators, each of which implements the
+ * {@link SplittableGenerator} interface.
+ *
+ * @param streamSize the number of values to generate
+ * @param source a {@link SplittableGenerator} instance to be used instead
+ * of this one as a source of pseudorandom bits used to
+ * initialize the state of the new ones.
+ *
+ * @return a stream of {@link SplittableGenerator} objects
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ */
+ Stream<SplittableGenerator> splits(long streamSize, SplittableGenerator source);
+
+ /**
+ * Returns an effectively unlimited stream of new pseudorandom
+ * number generators, each of which implements the {@link RandomGenerator}
+ * interface. Ideally the generators in the stream will appear
+ * to be statistically independent.
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @implNote The default implementation calls {@code splits()}.
+ */
+ default Stream<RandomGenerator> rngs() {
+ return this.splits().map(x -> (RandomGenerator)x);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * new pseudorandom number generators, each of which implements the
+ * {@link RandomGenerator} interface. Ideally the generators in the stream will
+ * appear to be statistically independent.
+ *
+ * @param streamSize the number of generators to generate
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ *
+ * @implNote The default implementation calls {@code splits(streamSize)}.
+ */
+ default Stream<RandomGenerator> rngs(long streamSize) {
+ return this.splits(streamSize).map(x -> (RandomGenerator)x);
+ }
+ }
+
+ /**
+ * This interface is designed to provide a common protocol for objects that generate pseudorandom
+ * sequences of numbers (or Boolean values) and furthermore can easily <i>jump</i> forward (by a
+ * fixed amount) to a distant point in the state cycle.
+ * <p>
+ * Ideally, all {@link JumpableGenerator} objects produced by iterative jumping from a single original
+ * {@link JumpableGenerator} object are statistically independent of one another and individually uniform.
+ * In practice, one must settle for some approximation to independence and uniformity. In
+ * particular, a specific implementation may assume that each generator in a stream produced by the
+ * {@code jumps} method is used to produce a number of values no larger than either 2<sup>64</sup>
+ * or the square root of its period. Implementors are advised to use algorithms whose period is at
+ * least 2<sup>127</sup>.
+ * <p>
+ * Methods are provided to perform a single jump operation and also to produce a stream of
+ * generators produced from the original by iterative copying and jumping of internal state. A
+ * typical strategy for a multithreaded application is to create a single {@link JumpableGenerator}
+ * object, calls its {@code jumps} method exactly once, and then parcel out generators from the
+ * resulting stream, one to each thread. It is generally not a good idea to call {@code jump} on a
+ * generator that was itself produced by the {@code jumps} method, because the result may be a
+ * generator identical to another generator already produce by that call to the {@code jumps}
+ * method. For this reason, the return type of the {@code jumps} method is {@code
+ * Stream<RandomGenerator>} rather than {@code Stream<JumpableGenerator>}, even though the actual
+ * generator objects in that stream likely do also implement the {@link JumpableGenerator} interface.
+ * <p>
+ * An implementation of the {@link JumpableGenerator} interface must provide concrete definitions for the
+ * methods {@code nextInt()}, {@code nextLong}, {@code period()}, {@code copy()}, {@code jump()},
+ * and {@code defaultJumpDistance()}. Default implementations are provided for all other methods.
+ * <p>
+ * Objects that implement {@link JumpableGenerator} are typically not cryptographically secure. Consider
+ * instead using {@link java.security.SecureRandom} to get a cryptographically secure pseudo-random
+ * number generator for use by security-sensitive applications.
+ *
+ * @since 14
+ */
+ public interface JumpableGenerator extends StreamableGenerator {
+ /**
+ * Returns a new generator whose internal state is an exact copy of this generator (therefore
+ * their future behavior should be identical if subjected to the same series of operations).
+ *
+ * @return a new object that is a copy of this generator
+ */
+ JumpableGenerator copy();
+
+ /**
+ * Alter the state of this pseudorandom number generator so as to jump forward a large, fixed
+ * distance (typically 2<sup>64</sup> or more) within its state cycle.
+ */
+ void jump();
+
+ /**
+ * Returns the distance by which the {@code jump()} method will jump forward within the state
+ * cycle of this generator object.
+ *
+ * @return the default jump distance (as a {@code double} value)
+ */
+ double defaultJumpDistance();
+
+ /**
+ * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
+ * implements the {@link RandomGenerator} interface.
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @implNote It is permitted to implement this method in a manner equivalent to
+ * {@code jumps(Long.MAX_VALUE)}.
+ * @implNote The default implementation produces a sequential stream that repeatedly
+ * calls {@code copy()} and {@code jump()} on this generator, and the copies become the
+ * generators produced by the stream.
+ */
+ default Stream<RandomGenerator> jumps() {
+ return Stream.generate(this::copyAndJump).sequential();
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
+ * generators, each of which implements the {@link RandomGenerator} interface.
+ *
+ * @param streamSize the number of generators to generate
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero
+ * @implNote The default implementation produces a sequential stream that repeatedly
+ * calls {@code copy()} and {@code jump()} on this generator, and the copies become the
+ * generators produced by the stream.
+ */
+ default Stream<RandomGenerator> jumps(long streamSize) {
+ return jumps().limit(streamSize);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
+ * implements the {@link RandomGenerator} interface. Ideally the generators in the stream
+ * will appear to be statistically independent.
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @implNote The default implementation calls {@code jumps()}.
+ */
+ default Stream<RandomGenerator> rngs() {
+ return this.jumps();
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
+ * generators, each of which implements the {@link RandomGenerator} interface. Ideally
+ * the generators in the stream will appear to be statistically independent.
+ *
+ * @param streamSize the number of generators to generate
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero
+ * @implNote The default implementation calls {@code jumps(streamSize)}.
+ */
+ default Stream<RandomGenerator> rngs(long streamSize) {
+ return this.jumps(streamSize);
+ }
+
+ /**
+ * Copy this generator, jump this generator forward, then return the copy.
+ *
+ * @return a copy of this generator object before the jump occurred
+ */
+ default RandomGenerator copyAndJump() {
+ RandomGenerator result = copy();
+ jump();
+ return result;
+ }
+
+ }
+
+ /**
+ * This interface is designed to provide a common protocol for objects that generate sequences of
+ * pseudorandom numbers (or Boolean values) and furthermore can easily not only jump but also
+ * <i>leap</i> to a very distant point in the state cycle.
+ * <p>
+ * Typically one will construct a series of {@link LeapableGenerator} objects by iterative leaping from a
+ * single original {@link LeapableGenerator} object, and then for each such object produce a subseries of
+ * objects by iterative jumping. There is little conceptual difference between leaping and jumping,
+ * but typically a leap will be a very long jump in the state cycle (perhaps distance
+ * 2<sup>128</sup> or so).
+ * <p>
+ * Ideally, all {@link LeapableGenerator} objects produced by iterative leaping and jumping from a single
+ * original {@link LeapableGenerator} object are statistically independent of one another and individually
+ * uniform. In practice, one must settle for some approximation to independence and uniformity. In
+ * particular, a specific implementation may assume that each generator in a stream produced by the
+ * {@code leaps} method is used to produce (by jumping) a number of objects no larger than
+ * 2<sup>64</sup>. Implementors are advised to use algorithms whose period is at least
+ * 2<sup>191</sup>.
+ * <p>
+ * Methods are provided to perform a single leap operation and also to produce a stream of
+ * generators produced from the original by iterative copying and leaping of internal state. The
+ * generators produced must implement the {@link JumpableGenerator} interface but need not also implement
+ * the {@link LeapableGenerator} interface. A typical strategy for a multithreaded application is to
+ * create a single {@link LeapableGenerator} object, calls its {@code leaps} method exactly once, and then
+ * parcel out generators from the resulting stream, one to each thread. Then the {@code jumps}
+ * method of each such generator be called to produce a substream of generator objects.
+ * <p>
+ * An implementation of the {@link LeapableGenerator} interface must provide concrete definitions for the
+ * methods {@code nextInt()}, {@code nextLong}, {@code period()}, {@code copy()}, {@code jump()},
+ * {@code defaultJumpDistance()}, {@code leap()}, and {@code defaultLeapDistance()}. Default
+ * implementations are provided for all other methods.
+ * <p>
+ * Objects that implement {@link LeapableGenerator} are typically not cryptographically secure. Consider
+ * instead using {@link java.security.SecureRandom} to get a cryptographically secure pseudo-random
+ * number generator for use by security-sensitive applications.
+ *
+ * @since 14
+ */
+ public interface LeapableGenerator extends JumpableGenerator {
+ /**
+ * Returns a new generator whose internal state is an exact copy of this generator (therefore
+ * their future behavior should be identical if subjected to the same series of operations).
+ *
+ * @return a new object that is a copy of this generator
+ */
+ LeapableGenerator copy();
+
+ /**
+ * Alter the state of this pseudorandom number generator so as to leap forward a large, fixed
+ * distance (typically 2<sup>96</sup> or more) within its state cycle.
+ */
+ void leap();
+
+ /**
+ * Returns the distance by which the {@code leap()} method will leap forward within the state
+ * cycle of this generator object.
+ *
+ * @return the default leap distance (as a {@code double} value)
+ */
+ double defaultLeapDistance();
+
+ /**
+ * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
+ * implements the {@link JumpableGenerator} interface.
+ *
+ * @return a stream of objects that implement the {@link JumpableGenerator} interface
+ *
+ * @implNote It is permitted to implement this method in a manner equivalent to {@code
+ * leaps(Long.MAX_VALUE)}.
+ * @implNote The default implementation produces a sequential stream that repeatedly
+ * calls {@code copy()} and {@code leap()} on this generator, and the copies become the
+ * generators produced by the stream.
+ */
+ default Stream<JumpableGenerator> leaps() {
+ return Stream.generate(this::copyAndLeap).sequential();
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
+ * generators, each of which implements the {@link JumpableGenerator} interface.
+ *
+ * @param streamSize the number of generators to generate
+ *
+ * @return a stream of objects that implement the {@link JumpableGenerator} interface
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero
+ * @implNote The default implementation produces a sequential stream that repeatedly
+ * calls {@code copy()} and {@code leap()} on this generator, and the copies become the
+ * generators produced by the stream.
+ */
+ default Stream<JumpableGenerator> leaps(long streamSize) {
+ return leaps().limit(streamSize);
+ }
+
+ /**
+ * Copy this generator, leap this generator forward, then return the copy.
+ *
+ * @return a copy of this generator object before the leap occurred
+ */
+ default JumpableGenerator copyAndLeap() {
+ JumpableGenerator result = copy();
+ leap();
+ return result;
+ }
+
+ }
+
+ /**
+ * This interface is designed to provide a common protocol for objects that generate sequences of
+ * pseudorandom numbers (or Boolean values) and furthermore can easily <i>jump</i> to an arbitrarily
+ * specified distant point in the state cycle.
+ * <p>
+ * Ideally, all {@link ArbitrarilyJumpableGenerator} objects produced by iterative jumping from a single
+ * original {@link ArbitrarilyJumpableGenerator} object are statistically independent of one another and
+ * individually uniform, provided that they do not traverse overlapping portions of the state cycle.
+ * In practice, one must settle for some approximation to independence and uniformity. In
+ * particular, a specific implementation may assume that each generator in a stream produced by the
+ * {@code jumps} method is used to produce a number of values no larger than the jump distance
+ * specified. Implementors are advised to use algorithms whose period is at least 2<sup>127</sup>.
+ * <p>
+ * For many applications, it suffices to jump forward by a power of two or some small multiple of a
+ * power of two, but this power of two may not be representable as a {@code long} value. To avoid
+ * the use of {@link java.math.BigInteger} values as jump distances, {@code double} values are used
+ * instead.
+ * <p>
+ * Methods are provided to perform a single jump operation and also to produce a stream of
+ * generators produced from the original by iterative copying and jumping of internal state. A
+ * typical strategy for a multithreaded application is to create a single {@link
+ * ArbitrarilyJumpableGenerator} object, call its {@code jumps} method exactly once, and then parcel out
+ * generators from the resulting stream, one to each thread. However, each generator produced also
+ * has type {@link ArbitrarilyJumpableGenerator}; with care, different jump distances can be used to
+ * traverse the entire state cycle in various ways.
+ * <p>
+ * An implementation of the {@link ArbitrarilyJumpableGenerator} interface must provide concrete
+ * definitions for the methods {@code nextInt()}, {@code nextLong}, {@code period()}, {@code
+ * copy()}, {@code jump(double)}, {@code defaultJumpDistance()}, and {@code defaultLeapDistance()}.
+ * Default implementations are provided for all other methods. Perhaps the most convenient way to
+ * implement this interface is to extend the abstract class {@link ArbitrarilyJumpableGenerator}, which
+ * provides spliterator-based implementations of the methods {@code ints}, {@code longs}, {@code
+ * doubles}, {@code rngs}, {@code jumps}, and {@code leaps}.
+ * <p>
+ * Objects that implement {@link ArbitrarilyJumpableGenerator} are typically not cryptographically secure.
+ * Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure
+ * pseudo-random number generator for use by security-sensitive applications.
+ *
+ * @since 14
+ */
+ public interface ArbitrarilyJumpableGenerator extends LeapableGenerator {
+ /**
+ * Returns a new generator whose internal state is an exact copy of this generator (therefore
+ * their future behavior should be identical if subjected to the same series of operations).
+ *
+ * @return a new object that is a copy of this generator
+ */
+ ArbitrarilyJumpableGenerator copy();
+
+ /**
+ * Alter the state of this pseudorandom number generator so as to jump forward a distance equal
+ * to 2<sup>{@code logDistance}</sup> within its state cycle.
+ *
+ * @param logDistance the base-2 logarithm of the distance to jump forward within the state
+ * cycle
+ *
+ * @throws IllegalArgumentException if {@code logDistance} is NaN or negative, or if
+ * 2<sup>{@code logDistance}</sup> is greater than the period
+ * of this generator
+ */
+ void jumpPowerOfTwo(int logDistance);
+
+ /**
+ * Alter the state of this pseudorandom number generator so as to jump forward a specified
+ * distance within its state cycle.
+ *
+ * @param distance the distance to jump forward within the state cycle
+ *
+ * @throws IllegalArgumentException if {@code distance} is Nan, negative, or greater than the
+ * period of this generator
+ */
+ void jump(double distance);
+
+ /**
+ * Alter the state of this pseudorandom number generator so as to jump forward a large, fixed
+ * distance (typically 2<sup>64</sup> or more) within its state cycle. The distance used is
+ * that returned by method {@code defaultJumpDistance()}.
+ */
+ default void jump() { jump(defaultJumpDistance()); }
+
+ /**
+ * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
+ * implements the {@link ArbitrarilyJumpableGenerator} interface, produced by jumping copies of this
+ * generator by different integer multiples of the specified jump distance.
+ *
+ * @param distance a distance to jump forward within the state cycle
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @implNote This method is implemented to be equivalent to {@code jumps(Long.MAX_VALUE)}.
+ */
+ default Stream<ArbitrarilyJumpableGenerator> jumps(double distance) {
+ return Stream.generate(() -> copyAndJump(distance)).sequential();
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
+ * generators, each of which implements the {@link ArbitrarilyJumpableGenerator} interface, produced
+ * by jumping copies of this generator by different integer multiples of the specified jump
+ * distance.
+ *
+ * @param streamSize the number of generators to generate
+ * @param distance a distance to jump forward within the state cycle
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero
+ */
+ default Stream<ArbitrarilyJumpableGenerator> jumps(long streamSize, double distance) {
+ return jumps(distance).limit(streamSize);
+ }
+
+ /**
+ * Alter the state of this pseudorandom number generator so as to jump forward a very large,
+ * fixed distance (typically 2<sup>128</sup> or more) within its state cycle. The distance used
+ * is that returned by method {@code defaultJLeapDistance()}.
+ */
+ default void leap() { jump(defaultLeapDistance()); }
+
+ /**
+ * Copy this generator, jump this generator forward, then return the copy.
+ *
+ * @param distance a distance to jump forward within the state cycle
+ *
+ * @return a copy of this generator object before the jump occurred
+ */
+ default ArbitrarilyJumpableGenerator copyAndJump(double distance) {
+ ArbitrarilyJumpableGenerator result = copy();
+ jump(distance);
+ return result;
+ }
+
+ }
+}
--- a/src/java.base/share/classes/java/util/random/RandomNumberGenerator.java Fri Jul 26 15:20:31 2019 -0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,639 +0,0 @@
-/*
- * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.random;
-
-import java.math.BigInteger;
-import java.util.stream.DoubleStream;
-import java.util.stream.IntStream;
-import java.util.stream.LongStream;
-
-/**
- * The {@link RandomNumberGenerator} interface is designed to provide a common protocol for objects
- * that generate random or (more typically) pseudorandom sequences of numbers (or Boolean values).
- * Such a sequence may be obtained by either repeatedly invoking a method that returns a single
- * (pseudo)randomly chosen value, or by invoking a method that returns a stream of (pseudo)randomly
- * chosen values.
- * <p>
- * Ideally, given an implicitly or explicitly specified range of values, each value would be chosen
- * independently and uniformly from that range. In practice, one may have to settle for some
- * approximation to independence and uniformity.
- * <p>
- * In the case of {@code int}, {@code long}, and {@link Boolean} values, if there is no explicit
- * specification of range, then the range includes all possible values of the type. In the case of
- * {@code float} and {@code double} values, a value is always chosen from the set of
- * 2<sup><i>w</i></sup> values between 0.0 (inclusive) and 1.0 (exclusive), where <i>w</i> is 23 for
- * {@code float} values and 52 for {@code double} values, such that adjacent values differ by
- * 2<sup>−<i>w</i></sup>; if an explicit range is specified, then the chosen number is
- * computationally scaled and translated so as to appear to have been chosen from that range.
- * <p>
- * Each method that returns a stream produces a stream of values each of which is chosen in the same
- * manner as for a method that returns a single (pseudo)randomly chosen value. For example, if
- * {@code r} implements {@link RandomNumberGenerator}, then the method call {@code r.ints(100)}
- * returns a stream of 100 {@code int} values. These are not necessarily the exact same values that
- * would have been returned if instead {@code r.nextInt()} had been called 100 times; all that is
- * guaranteed is that each value in the stream is chosen in a similar (pseudo)random manner from the
- * same range.
- * <p>
- * Every object that implements the {@link RandomNumberGenerator} interface is assumed to contain a
- * finite amount of state. Using such an object to generate a pseudorandomly chosen value alters
- * its state. The number of distinct possible states of such an object is called its
- * <i>period</i>. (Some implementations of the {@link RandomNumberGenerator} interface
- * may be truly random rather than pseudorandom, for example relying on the statistical behavior of
- * a physical object to derive chosen values. Such implementations do not have a fixed period.)
- * <p>
- * As a rule, objects that implement the {@link RandomNumberGenerator} interface need not be
- * thread-safe. It is recommended that multithreaded applications use either {@link
- * ThreadLocalRandom} or (preferably) pseudorandom number generators that implement the {@link
- * SplittableRNG} or {@link JumpableRNG} interface.
- * <p>
- * To implement this interface, a class only needs to provide concrete definitions for the methods
- * {@code nextLong()} and {@code period()}. Default implementations are provided for all other
- * methods (but it may be desirable to override some of them, especially {@code nextInt()} if the
- * underlying algorithm is {@code int}-based). Moerover, it may be preferable instead to implement
- * another interface such as {@link JumpableRNG} or {@link LeapableRNG}, or to extend an abstract
- * class such as {@link AbstractSplittableRNG} or {@link AbstractArbitrarilyJumpableRNG}.
- * <p>
- * Objects that implement {@link RandomNumberGenerator} are typically not cryptographically secure.
- * Consider instead using {@link java.security.SecureRandom} to get a cryptographically secure
- * pseudorandom number generator for use by security-sensitive applications. Note, however, that
- * {@code java.security.SecureRandom} does implement the {@link RandomNumberGenerator} interface, so
- * that instances of {@code java.security.SecureRandom} may be used interchangeably with other types
- * of pseudorandom generators in applications that do not require a secure generator.
- *
- * @since 14
- */
-public interface RandomNumberGenerator {
-
- /**
- * Returns an effectively unlimited stream of pseudorandomly chosen
- * {@code double} values.
- *
- * @return a stream of pseudorandomly chosen {@code double} values
- *
- * @implNote It is permitted to implement this method in a manner
- * equivalent to {@code doubles(Long.MAX_VALUE)}.
- *
- * @implNote The default implementation produces a sequential stream
- * that repeatedly calls {@code nextDouble()}.
- */
- default DoubleStream doubles() {
- return DoubleStream.generate(this::nextDouble).sequential();
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandomly chosen
- * {@code double} values, where each value is between the specified
- * origin (inclusive) and the specified bound (exclusive).
- *
- * @param randomNumberOrigin the least value that can be produced
- * @param randomNumberBound the upper bound (exclusive) for each value produced
- *
- * @return a stream of pseudorandomly chosen {@code double} values, each between
- * the specified origin (inclusive) and the specified bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code randomNumberOrigin}
- * is greater than or equal to {@code randomNumberBound}
- *
- * @implNote It is permitted to implement this method in a manner
- * equivalent to
- * {@code doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
- * @implNote The default implementation produces a sequential stream that repeatedly
- * calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}.
- */
- default DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
- RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
- return DoubleStream.generate(() -> nextDouble(randomNumberOrigin, randomNumberBound)).sequential();
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * pseudorandomly chosen {@code double} values.
- *
- * @param streamSize the number of values to generate
- *
- * @return a stream of pseudorandomly chosen {@code double} values
- *
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero
- *
- * @implNote The default implementation produces a sequential stream
- * that repeatedly calls {@code nextDouble()}.
- */
- default DoubleStream doubles(long streamSize) {
- RNGSupport.checkStreamSize(streamSize);
- return doubles().limit(streamSize);
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * pseudorandomly chosen {@code double} values, where each value is between
- * the specified origin (inclusive) and the specified bound (exclusive).
- *
- * @param streamSize the number of values to generate
- * @param randomNumberOrigin the least value that can be produced
- * @param randomNumberBound the upper bound (exclusive) for each value produced
- *
- * @return a stream of pseudorandomly chosen {@code double} values, each between
- * the specified origin (inclusive) and the specified bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero, or {@code randomNumberOrigin}
- * is greater than or equal to {@code randomNumberBound}
- *
- * @implNote The default implementation produces a sequential stream
- * that repeatedly calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}.
- */
- default DoubleStream doubles(long streamSize, double randomNumberOrigin,
- double randomNumberBound) {
- RNGSupport.checkStreamSize(streamSize);
- RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
- return doubles(randomNumberOrigin, randomNumberBound).limit(streamSize);
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandomly chosen
- * {@code int} values.
- *
- * @return a stream of pseudorandomly chosen {@code int} values
- *
- * @implNote It is permitted to implement this method in a manner
- * equivalent to {@code ints(Long.MAX_VALUE)}.
- * @implNote The default implementation produces a sequential stream
- * that repeatedly calls {@code nextInt()}.
- */
- default IntStream ints() {
- return IntStream.generate(this::nextInt).sequential();
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandomly chosen
- * {@code int} values, where each value is between the specified
- * origin (inclusive) and the specified bound (exclusive).
- *
- * @param randomNumberOrigin the least value that can be produced
- * @param randomNumberBound the upper bound (exclusive) for each value produced
- *
- * @return a stream of pseudorandomly chosen {@code int} values, each between
- * the specified origin (inclusive) and the specified bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code randomNumberOrigin}
- * is greater than or equal to {@code randomNumberBound}
- *
- * @implNote It is permitted to implement this method in a manner equivalent to
- * {@code ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
- * @implNote The default implementation produces a sequential stream that repeatedly
- * calls {@code nextInt(randomNumberOrigin, randomNumberBound)}.
- */
- default IntStream ints(int randomNumberOrigin, int randomNumberBound) {
- RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
- return IntStream.generate(() -> nextInt(randomNumberOrigin, randomNumberBound)).sequential();
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * pseudorandomly chosen {@code int} values.
- *
- * @param streamSize the number of values to generate
- *
- * @return a stream of pseudorandomly chosen {@code int} values
- *
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero
- *
- * @implNote The default implementation produces a sequential stream
- * that repeatedly calls {@code nextInt()}.
- */
- default IntStream ints(long streamSize) {
- RNGSupport.checkStreamSize(streamSize);
- return ints().limit(streamSize);
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * pseudorandomly chosen {@code int} values, where each value is between
- * the specified origin (inclusive) and the specified bound (exclusive).
- *
- * @param streamSize the number of values to generate
- * @param randomNumberOrigin the least value that can be produced
- * @param randomNumberBound the upper bound (exclusive) for each value produced
- *
- * @return a stream of pseudorandomly chosen {@code int} values, each between
- * the specified origin (inclusive) and the specified bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero, or {@code randomNumberOrigin}
- * is greater than or equal to {@code randomNumberBound}
- *
- * @implNote The default implementation produces a sequential stream that repeatedly
- * calls {@code nextInt(randomNumberOrigin, randomNumberBound)}.
- */
- default IntStream ints(long streamSize, int randomNumberOrigin,
- int randomNumberBound) {
- RNGSupport.checkStreamSize(streamSize);
- RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
- return ints(randomNumberOrigin, randomNumberBound).limit(streamSize);
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandomly chosen
- * {@code long} values.
- *
- * @return a stream of pseudorandomly chosen {@code long} values
- *
- * @implNote It is permitted to implement this method in a manner
- * equivalent to {@code longs(Long.MAX_VALUE)}.
- * @implNote The default implementation produces a sequential stream
- * that repeatedly calls {@code nextLong()}.
- */
- default LongStream longs() {
- return LongStream.generate(this::nextLong).sequential();
- }
-
- /**
- * Returns an effectively unlimited stream of pseudorandomly chosen
- * {@code long} values, where each value is between the specified
- * origin (inclusive) and the specified bound (exclusive).
- *
- * @param randomNumberOrigin the least value that can be produced
- * @param randomNumberBound the upper bound (exclusive) for each value produced
- *
- * @return a stream of pseudorandomly chosen {@code long} values, each between
- * the specified origin (inclusive) and the specified bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code randomNumberOrigin}
- * is greater than or equal to {@code randomNumberBound}
- *
- * @implNote It is permitted to implement this method in a manner
- * equivalent to {@code longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
- * @implNote The default implementation produces a sequential stream that repeatedly
- * calls {@code nextLong(randomNumberOrigin, randomNumberBound)}.
- */
- default LongStream longs(long randomNumberOrigin, long randomNumberBound) {
- RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
- return LongStream.generate(() -> nextLong(randomNumberOrigin, randomNumberBound)).sequential();
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * pseudorandomly chosen {@code long} values.
- *
- * @param streamSize the number of values to generate
- *
- * @return a stream of pseudorandomly chosen {@code long} values
- *
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero
- *
- * @implNote The default implementation produces a sequential stream
- * that repeatedly calls {@code nextLong()}.
- */
- default LongStream longs(long streamSize) {
- RNGSupport.checkStreamSize(streamSize);
- return longs().limit(streamSize);
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * pseudorandomly chosen {@code long} values, where each value is between
- * the specified origin (inclusive) and the specified bound (exclusive).
- *
- * @param streamSize the number of values to generate
- * @param randomNumberOrigin the least value that can be produced
- * @param randomNumberBound the upper bound (exclusive) for each value produced
- *
- * @return a stream of pseudorandomly chosen {@code long} values, each between
- * the specified origin (inclusive) and the specified bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero, or {@code randomNumberOrigin}
- * is greater than or equal to {@code randomNumberBound}
- *
- * @implNote The default implementation produces a sequential stream that repeatedly
- * calls {@code nextLong(randomNumberOrigin, randomNumberBound)}.
- */
- default LongStream longs(long streamSize, long randomNumberOrigin,
- long randomNumberBound) {
- RNGSupport.checkStreamSize(streamSize);
- RNGSupport.checkRange(randomNumberOrigin, randomNumberBound);
- return longs(randomNumberOrigin, randomNumberBound).limit(streamSize);
- }
-
- /**
- * Returns a pseudorandomly chosen {@code boolean} value.
- * <p>
- * The default implementation tests the high-order bit (sign bit) of a value produced by {@code
- * nextInt()}, on the grounds that some algorithms for pseudorandom number generation produce
- * values whose high-order bits have better statistical quality than the low-order bits.
- *
- * @return a pseudorandomly chosen {@code boolean} value
- */
- default boolean nextBoolean() {
- return nextInt() < 0;
- }
-
- /**
- * Returns a pseudorandom {@code float} value between zero (inclusive) and one (exclusive).
- * <p>
- * The default implementation uses the 24 high-order bits from a call to {@code nextInt()}.
- *
- * @return a pseudorandom {@code float} value between zero (inclusive) and one (exclusive)
- */
- default float nextFloat() {
- return (nextInt() >>> 8) * 0x1.0p-24f;
- }
-
- /**
- * Returns a pseudorandomly chosen {@code float} value between zero
- * (inclusive) and the specified bound (exclusive).
- *
- * @param bound the upper bound (exclusive) for the returned value.
- * Must be positive and finite
- *
- * @return a pseudorandomly chosen {@code float} value between
- * zero (inclusive) and the bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code bound} is not
- * positive and finite
- *
- * @implNote The default implementation simply calls
- * {@code RNGSupport.checkBound(bound)} and then
- * {@code RNGSupport.boundedNextFloat(this, bound)}.
- */
- default float nextFloat(float bound) {
- RNGSupport.checkBound(bound);
- return RNGSupport.boundedNextFloat(this, bound);
- }
-
- /**
- * Returns a pseudorandomly chosen {@code float} value between the
- * specified origin (inclusive) and the specified bound (exclusive).
- *
- * @param origin the least value that can be returned
- * @param bound the upper bound (exclusive)
- *
- * @return a pseudorandomly chosen {@code float} value between the
- * origin (inclusive) and the bound (exclusive)
- *
- * @throws IllegalArgumentException unless {@code origin} is finite,
- * {@code bound} is finite, and {@code origin} is less than
- * {@code bound}
- *
- * @implNote The default implementation simply calls
- * {@code RNGSupport.checkRange(origin, bound)} and then
- * {@code RNGSupport.boundedNextFloat(this, origin, bound)}.
- */
- default float nextFloat(float origin, float bound) {
- RNGSupport.checkRange(origin, bound);
- return RNGSupport.boundedNextFloat(this, origin, bound);
- }
-
- /**
- * Returns a pseudorandom {@code double} value between zero (inclusive) and one (exclusive).
- * <p>
- * The default implementation uses the 53 high-order bits from a call to {@code nextLong()}.
- *
- * @return a pseudorandom {@code double} value between zero (inclusive) and one (exclusive)
- */
- default double nextDouble() {
- return (nextLong() >>> 11) * 0x1.0p-53;
- }
-
- /**
- * Returns a pseudorandomly chosen {@code double} value between zero
- * (inclusive) and the specified bound (exclusive).
- *
- * @param bound the upper bound (exclusive) for the returned value.
- * Must be positive and finite
- *
- * @return a pseudorandomly chosen {@code double} value between
- * zero (inclusive) and the bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code bound} is not
- * positive and finite
- *
- * @implNote The default implementation simply calls
- * {@code RNGSupport.checkBound(bound)} and then
- * {@code RNGSupport.boundedNextDouble(this, bound)}.
- */
- default double nextDouble(double bound) {
- RNGSupport.checkBound(bound);
- return RNGSupport.boundedNextDouble(this, bound);
- }
-
- /**
- * Returns a pseudorandomly chosen {@code double} value between the
- * specified origin (inclusive) and the specified bound (exclusive).
- *
- * @param origin the least value that can be returned
- * @param bound the upper bound (exclusive) for the returned value
- *
- * @return a pseudorandomly chosen {@code double} value between the
- * origin (inclusive) and the bound (exclusive)
- *
- * @throws IllegalArgumentException unless {@code origin} is finite,
- * {@code bound} is finite, and {@code origin} is less than
- * {@code bound}
- *
- * @implNote The default implementation simply calls
- * {@code RNGSupport.checkRange(origin, bound)} and then
- * {@code RNGSupport.boundedNextDouble(this, origin, bound)}.
- */
- default double nextDouble(double origin, double bound) {
- RNGSupport.checkRange(origin, bound);
- return RNGSupport.boundedNextDouble(this, origin, bound);
- }
-
- /**
- * Returns a pseudorandomly chosen {@code int} value.
- * <p>
- * The default implementation uses the 32 high-order bits from a call to {@code nextLong()}.
- *
- * @return a pseudorandomly chosen {@code int} value
- */
- default public int nextInt() {
- return (int)(nextLong() >>> 32);
- }
-
- /**
- * Returns a pseudorandomly chosen {@code int} value between
- * zero (inclusive) and the specified bound (exclusive).
- *
- * @param bound the upper bound (exclusive) for the returned value. Must be positive.
- *
- * @return a pseudorandomly chosen {@code int} value between
- * zero (inclusive) and the bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code bound} is not positive
- *
- * @implNote The default implementation simply calls
- * {@code RNGSupport.checkBound(bound)} and then
- * {@code RNGSupport.boundedNextInt(this, bound)}.
- */
- default int nextInt(int bound) {
- RNGSupport.checkBound(bound);
- return RNGSupport.boundedNextInt(this, bound);
- }
-
- /**
- * Returns a pseudorandomly chosen {@code int} value between the
- * specified origin (inclusive) and the specified bound (exclusive).
- *
- * @param origin the least value that can be returned
- * @param bound the upper bound (exclusive) for the returned value
- *
- * @return a pseudorandomly chosen {@code int} value between the
- * origin (inclusive) and the bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code origin} is greater than
- * or equal to {@code bound}
- *
- * @implNote The default implementation simply calls
- * {@code RNGSupport.checkRange(origin, bound)} and then
- * {@code RNGSupport.boundedNextInt(this, origin, bound)}.
- */
- default int nextInt(int origin, int bound) {
- RNGSupport.checkRange(origin, bound);
- return RNGSupport.boundedNextInt(this, origin, bound);
- }
-
- /**
- * Returns a pseudorandomly chosen {@code long} value.
- *
- * @return a pseudorandomly chosen {@code long} value
- */
- long nextLong();
-
- /**
- * Returns a pseudorandomly chosen {@code long} value between
- * zero (inclusive) and the specified bound (exclusive).
- *
- * @param bound the upper bound (exclusive) for the returned value. Must be positive.
- *
- * @return a pseudorandomly chosen {@code long} value between
- * zero (inclusive) and the bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code bound} is not positive
- *
- * @implNote The default implementation simply calls
- * {@code RNGSupport.checkBound(bound)} and then
- * {@code RNGSupport.boundedNextLong(this, bound)}.
- */
- default long nextLong(long bound) {
- RNGSupport.checkBound(bound);
- return RNGSupport.boundedNextLong(this, bound);
- }
-
- /**
- * Returns a pseudorandomly chosen {@code long} value between the
- * specified origin (inclusive) and the specified bound (exclusive).
- *
- * @param origin the least value that can be returned
- * @param bound the upper bound (exclusive) for the returned value
- *
- * @return a pseudorandomly chosen {@code long} value between the
- * origin (inclusive) and the bound (exclusive)
- *
- * @throws IllegalArgumentException if {@code origin} is greater than
- * or equal to {@code bound}
- *
- * @implNote The default implementation simply calls
- * {@code RNGSupport.checkRange(origin, bound)} and then
- * {@code RNGSupport.boundedNextInt(this, origin, bound)}.
- *
- */
- default long nextLong(long origin, long bound) {
- RNGSupport.checkRange(origin, bound);
- return RNGSupport.boundedNextLong(this, origin, bound);
- }
-
- /**
- * Returns a {@code double} value pseudorandomly chosen from
- * a Gaussian (normal) distribution whose mean is 0 and whose
- * standard deviation is 1.
- *
- * @return a {@code double} value pseudorandomly chosen from a
- * Gaussian distribution
- */
- default double nextGaussian() {
- return RNGSupport.computeNextGaussian(this);
- }
-
- /**
- * Returns a {@code double} value pseudorandomly chosen from
- * a Gaussian (normal) distribution with a mean and
- * standard deviation specified by the arguments.
- *
- * @param mean the mean of the Gaussian distribution to be drawn from
- * @param stddev the standard deviation (square root of the variance)
- * of the Gaussian distribution to be drawn from
- *
- * @return a {@code double} value pseudorandomly chosen from the
- * specified Gaussian distribution
- *
- * @throws IllegalArgumentException if {@code stddev} is negative
- */
- default double nextGaussian(double mean, double stddev) {
- if (stddev < 0.0) throw new IllegalArgumentException("standard deviation must be non-negative");
- return mean + stddev * RNGSupport.computeNextGaussian(this);
- }
-
- /**
- * Returns a nonnegative {@code double} value pseudorandomly chosen
- * from an exponential distribution whose mean is 1.
- *
- * @return a nonnegative {@code double} value pseudorandomly chosen from an
- * exponential distribution
- */
- default double nextExponential() {
- return RNGSupport.computeNextExponential(this);
- }
-
- /**
- * Returns the period of this {@link RandomNumberGenerator} object.
- *
- * @return a {@link BigInteger} whose value is the number of distinct possible states of this
- * {@link RandomNumberGenerator} object, or 0 if unknown, or negative if extremely
- * large.
- */
- BigInteger period();
-
- /**
- * The value (0) returned by the {@code period()} method if the period is unknown.
- */
- static final BigInteger UNKNOWN_PERIOD = BigInteger.ZERO;
-
- /**
- * The (negative) value returned by the {@code period()} method if this generator
- * has no period because it is truly random rather than just pseudorandom.
- */
- static final BigInteger TRULY_RANDOM = BigInteger.valueOf(-1);
-
- /**
- * The (negative) value that may be returned by the {@code period()} method
- * if this generator has a huge period (larger than 2**(2**16)).
- */
- static final BigInteger HUGE_PERIOD = BigInteger.valueOf(-2);
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/util/random/RandomSupport.java Fri Jul 26 15:37:05 2019 -0300
@@ -0,0 +1,2247 @@
+/*
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.util.random;
+
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+import java.util.random.RandomGenerator.SplittableGenerator;
+import java.util.Spliterator;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+/**
+ * Low-level utility methods helpful for implementing pseudorandom number generators.
+ *
+ * This class is mostly for library writers creating specific implementations of the
+ * interface {@link RandomGenerator}.
+ *
+ * @since 14
+ */
+public class RandomSupport {
+
+ /*
+ * Implementation Overview.
+ *
+ * This class provides utility methods and constants frequently
+ * useful in the implentation of pseudorandom number generators
+ * that satisfy the interface {@link RandomGenerator}.
+ *
+ * File organization: First some message strings, then the main
+ * public methods, followed by a non-public base spliterator class.
+ */
+
+ // IllegalArgumentException messages
+ static final String BAD_SIZE = "size must be non-negative";
+ static final String BAD_DISTANCE = "jump distance must be finite, positive, and an exact integer";
+ static final String BAD_BOUND = "bound must be positive";
+ static final String BAD_FLOATING_BOUND = "bound must be finite and positive";
+ static final String BAD_RANGE = "bound must be greater than origin";
+
+ /* ---------------- public methods ---------------- */
+
+ /**
+ * Check a {@code long} proposed stream size for validity.
+ *
+ * @param streamSize the proposed stream size
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is negative
+ */
+ public static void checkStreamSize(long streamSize) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BAD_SIZE);
+ }
+
+ /**
+ * Check a {@code double} proposed jump distance for validity.
+ *
+ * @param distance the proposed jump distance
+ *
+ * @throws IllegalArgumentException if {@code size} not positive, finite, and an exact integer
+ */
+ public static void checkJumpDistance(double distance) {
+ if (!(distance > 0.0 && distance < Float.POSITIVE_INFINITY
+ && distance == Math.floor(distance))) {
+ throw new IllegalArgumentException(BAD_DISTANCE);
+ }
+ }
+
+ /**
+ * Checks a {@code float} upper bound value for validity.
+ *
+ * @param bound the upper bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code bound} is not positive and finite
+ */
+ public static void checkBound(float bound) {
+ if (!(bound > 0.0 && bound < Float.POSITIVE_INFINITY)) {
+ throw new IllegalArgumentException(BAD_FLOATING_BOUND);
+ }
+ }
+
+ /**
+ * Checks a {@code double} upper bound value for validity.
+ *
+ * @param bound the upper bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code bound} is not positive and finite
+ */
+ public static void checkBound(double bound) {
+ if (!(bound > 0.0 && bound < Double.POSITIVE_INFINITY)) {
+ throw new IllegalArgumentException(BAD_FLOATING_BOUND);
+ }
+ }
+
+ /**
+ * Checks an {@code int} upper bound value for validity.
+ *
+ * @param bound the upper bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code bound} is not positive
+ */
+ public static void checkBound(int bound) {
+ if (bound <= 0) {
+ throw new IllegalArgumentException(BAD_BOUND);
+ }
+ }
+
+ /**
+ * Checks a {@code long} upper bound value for validity.
+ *
+ * @param bound the upper bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code bound} is not positive
+ */
+ public static void checkBound(long bound) {
+ if (bound <= 0) {
+ throw new IllegalArgumentException(BAD_BOUND);
+ }
+ }
+
+ /**
+ * Checks a {@code float} range for validity.
+ *
+ * @param origin the least value (inclusive) in the range
+ * @param bound the upper bound (exclusive) of the range
+ *
+ * @throws IllegalArgumentException unless {@code origin} is finite, {@code bound} is finite,
+ * and {@code bound - origin} is finite
+ */
+ public static void checkRange(float origin, float bound) {
+ if (!(origin < bound && (bound - origin) < Float.POSITIVE_INFINITY)) {
+ throw new IllegalArgumentException(BAD_RANGE);
+ }
+ }
+
+ /**
+ * Checks a {@code double} range for validity.
+ *
+ * @param origin the least value (inclusive) in the range
+ * @param bound the upper bound (exclusive) of the range
+ *
+ * @throws IllegalArgumentException unless {@code origin} is finite, {@code bound} is finite,
+ * and {@code bound - origin} is finite
+ */
+ public static void checkRange(double origin, double bound) {
+ if (!(origin < bound && (bound - origin) < Double.POSITIVE_INFINITY)) {
+ throw new IllegalArgumentException(BAD_RANGE);
+ }
+ }
+
+ /**
+ * Checks an {@code int} range for validity.
+ *
+ * @param origin the least value that can be returned
+ * @param bound the upper bound (exclusive) for the returned value
+ *
+ * @throws IllegalArgumentException if {@code origin} is greater than or equal to {@code bound}
+ */
+ public static void checkRange(int origin, int bound) {
+ if (origin >= bound) {
+ throw new IllegalArgumentException(BAD_RANGE);
+ }
+ }
+
+ /**
+ * Checks a {@code long} range for validity.
+ *
+ * @param origin the least value that can be returned
+ * @param bound the upper bound (exclusive) for the returned value
+ *
+ * @throws IllegalArgumentException if {@code origin} is greater than or equal to {@code bound}
+ */
+ public static void checkRange(long origin, long bound) {
+ if (origin >= bound) {
+ throw new IllegalArgumentException(BAD_RANGE);
+ }
+ }
+
+ /**
+ * Given an array of seed bytes of any length, construct an array
+ * of {@code long} seed values of length {@code n}, such that the
+ * last {@code z} values are not all zero.
+ *
+ * @param seed an array of {@code byte} values
+ * @param n the length of the result array (should be nonnegative)
+ * @param z the number of trailing result elements that are required
+ * to be not all zero (should be nonnegative but not larger
+ * than {@code n})
+ *
+ * @return an array of length {@code n} containing {@code long} seed values
+ */
+ public static long[] convertSeedBytesToLongs(byte[] seed, int n, int z) {
+ final long[] result = new long[n];
+ final int m = Math.min(seed.length, n << 3);
+ // Distribute seed bytes into the words to be formed.
+ for (int j = 0; j < m; j++) {
+ result[j>>3] = (result[j>>3] << 8) | seed[j];
+ }
+ // If there aren't enough seed bytes for all the words we need,
+ // use a SplitMix-style PRNG to fill in the rest.
+ long v = result[0];
+ for (int j = (m + 7) >> 3; j < n; j++) {
+ result[j] = mixMurmur64(v += SILVER_RATIO_64);
+ }
+ // Finally, we need to make sure the last z words are not all zero.
+ search: {
+ for (int j = n - z; j < n; j++) {
+ if (result[j] != 0) break search;
+ }
+ // If they are, fill in using a SplitMix-style PRNG.
+ // Using "& ~1L" in the next line defends against the case z==1
+ // by guaranteeing that the first generated value will be nonzero.
+ long w = result[0] & ~1L;
+ for (int j = n - z; j < n; j++) {
+ result[j] = mixMurmur64(w += SILVER_RATIO_64);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Given an array of seed bytes of any length, construct an array
+ * of {@code int} seed values of length {@code n}, such that the
+ * last {@code z} values are not all zero.
+ *
+ * @param seed an array of {@code byte} values
+ * @param n the length of the result array (should be nonnegative)
+ * @param z the number of trailing result elements that are required
+ * to be not all zero (should be nonnegative but not larger
+ * than {@code n})
+ *
+ * @return an array of length {@code n} containing {@code int} seed values
+ */
+ public static int[] convertSeedBytesToInts(byte[] seed, int n, int z) {
+ final int[] result = new int[n];
+ final int m = Math.min(seed.length, n << 2);
+ // Distribute seed bytes into the words to be formed.
+ for (int j = 0; j < m; j++) {
+ result[j>>2] = (result[j>>2] << 8) | seed[j];
+ }
+ // If there aren't enough seed bytes for all the words we need,
+ // use a SplitMix-style PRNG to fill in the rest.
+ int v = result[0];
+ for (int j = (m + 3) >> 2; j < n; j++) {
+ result[j] = mixMurmur32(v += SILVER_RATIO_32);
+ }
+ // Finally, we need to make sure the last z words are not all zero.
+ search: {
+ for (int j = n - z; j < n; j++) {
+ if (result[j] != 0) break search;
+ }
+ // If they are, fill in using a SplitMix-style PRNG.
+ // Using "& ~1" in the next line defends against the case z==1
+ // by guaranteeing that the first generated value will be nonzero.
+ int w = result[0] & ~1;
+ for (int j = n - z; j < n; j++) {
+ result[j] = mixMurmur32(w += SILVER_RATIO_32);
+ }
+ }
+ return result;
+ }
+
+ /*
+ * Bounded versions of nextX methods used by streams, as well as
+ * the public nextX(origin, bound) methods. These exist mainly to
+ * avoid the need for multiple versions of stream spliterators
+ * across the different exported forms of streams.
+ */
+
+ /**
+ * This is the form of {@code nextLong} used by a {@link LongStream}
+ * {@link Spliterator} and by the public method
+ * {@code nextLong(origin, bound)}. If {@code origin} is greater
+ * than {@code bound}, then this method simply calls the unbounded
+ * version of {@code nextLong()}, choosing pseudorandomly from
+ * among all 2<sup>64</sup> possible {@code long} values}, and
+ * otherwise uses one or more calls to {@code nextLong()} to
+ * choose a value pseudorandomly from the possible values
+ * between {@code origin} (inclusive) and {@code bound} (exclusive).
+ *
+ * @implNote This method first calls {@code nextLong()} to obtain
+ * a {@code long} value that is assumed to be pseudorandomly
+ * chosen uniformly and independently from the 2<sup>64</sup>
+ * possible {@code long} values (that is, each of the 2<sup>64</sup>
+ * possible long values is equally likely to be chosen).
+ * Under some circumstances (when the specified range is not
+ * a power of 2), {@code nextLong()} may be called additional times
+ * to ensure that that the values in the specified range are
+ * equally likely to be chosen (provided the assumption holds).
+ * <p>
+ * The implementation considers four cases:
+ * <ol>
+ *
+ * <li> If the {@code} bound} is less than or equal to the {@code origin}
+ * (indicated an unbounded form), the 64-bit {@code long} value
+ * obtained from {@code nextLong()} is returned directly.
+ *
+ * <li> Otherwise, if the length <i>n</i> of the specified range is an
+ * exact power of two 2<sup><i>m</i></sup> for some integer
+ * <i>m</i>, then return the sum of {@code origin} and the
+ * <i>m</i> lowest-order bits of the value from {@code nextLong()}.
+ *
+ * <li> Otherwise, if the length <i>n</i> of the specified range
+ * is less than 2<sup>63</sup>, then the basic idea is to use the
+ * remainder modulo <i>n</i> of the value from {@code nextLong()},
+ * but with this approach some values will be over-represented.
+ * Therefore a loop is used to avoid potential bias by rejecting
+ * candidates that are too large. Assuming that the results from
+ * {@code nextLong()} are truly chosen uniformly and independently,
+ * the expected number of iterations will be somewhere between
+ * 1 and 2, depending on the precise value of <i>n</i>.
+ *
+ * <li> Otherwise, the length <i>n</i> of the specified range
+ * cannot be represented as a positive {@code long} value.
+ * A loop repeatedly calls {@code nextlong()} until obtaining
+ * a suitable candidate, Again, the expected number of iterations
+ * is less than 2.
+ *
+ * </ol>
+ *
+ * @param rng a random number generator to be used as a
+ * source of pseudorandom {@code long} values
+ * @param origin the least value that can be produced,
+ * unless greater than or equal to {@code bound}
+ * @param bound the upper bound (exclusive), unless {@code origin}
+ * is greater than or equal to {@code bound}
+ *
+ * @return a pseudorandomly chosen {@code long} value,
+ * which will be between {@code origin} (inclusive) and
+ * {@code bound} exclusive unless {@code origin}
+ * is greater than or equal to {@code bound}
+ */
+ public static long boundedNextLong(RandomGenerator rng, long origin, long bound) {
+ long r = rng.nextLong();
+ if (origin < bound) {
+ // It's not case (1).
+ final long n = bound - origin;
+ final long m = n - 1;
+ if ((n & m) == 0L) {
+ // It is case (2): length of range is a power of 2.
+ r = (r & m) + origin;
+ } else if (n > 0L) {
+ // It is case (3): need to reject over-represented candidates.
+ /* This loop takes an unlovable form (but it works):
+ 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. */
+ for (long u = r >>> 1; // ensure nonnegative
+ u + m - (r = u % n) < 0L; // rejection check
+ u = rng.nextLong() >>> 1) // retry
+ ;
+ r += origin;
+ }
+ else {
+ // It is case (4): length of range not representable as long.
+ while (r < origin || r >= bound)
+ r = rng.nextLong();
+ }
+ }
+ return r;
+ }
+
+ /**
+ * This is the form of {@code nextLong} used by the public method
+ * {@code nextLong(bound)}. This is essentially a version of
+ * {@code boundedNextLong(origin, bound)} that has been
+ * specialized for the case where the {@code origin} is zero
+ * and the {@code bound} is greater than zero. The value
+ * returned is chosen pseudorandomly from nonnegative integer
+ * values less than {@code bound}.
+ *
+ * @implNote This method first calls {@code nextLong()} to obtain
+ * a {@code long} value that is assumed to be pseudorandomly
+ * chosen uniformly and independently from the 2<sup>64</sup>
+ * possible {@code long} values (that is, each of the 2<sup>64</sup>
+ * possible long values is equally likely to be chosen).
+ * Under some circumstances (when the specified range is not
+ * a power of 2), {@code nextLong()} may be called additional times
+ * to ensure that that the values in the specified range are
+ * equally likely to be chosen (provided the assumption holds).
+ * <p>
+ * The implementation considers two cases:
+ * <ol>
+ *
+ * <li> If {@code bound} is an exact power of two 2<sup><i>m</i></sup>
+ * for some integer <i>m</i>, then return the sum of {@code origin}
+ * and the <i>m</i> lowest-order bits of the value from
+ * {@code nextLong()}.
+ *
+ * <li> Otherwise, the basic idea is to use the remainder modulo
+ * <i>bound</i> of the value from {@code nextLong()},
+ * but with this approach some values will be over-represented.
+ * Therefore a loop is used to avoid potential bias by rejecting
+ * candidates that vare too large. Assuming that the results from
+ * {@code nextLong()} are truly chosen uniformly and independently,
+ * the expected number of iterations will be somewhere between
+ * 1 and 2, depending on the precise value of <i>bound</i>.
+ *
+ * </ol>
+ *
+ * @param rng a random number generator to be used as a
+ * source of pseudorandom {@code long} values
+ * @param bound the upper bound (exclusive); must be greater than zero
+ *
+ * @return a pseudorandomly chosen {@code long} value
+ */
+ public static long boundedNextLong(RandomGenerator rng, long bound) {
+ // Specialize boundedNextLong for origin == 0, bound > 0
+ final long m = bound - 1;
+ long r = rng.nextLong();
+ if ((bound & m) == 0L) {
+ // The bound is a power of 2.
+ r &= m;
+ } else {
+ // Must reject over-represented candidates
+ /* This loop takes an unlovable form (but it works):
+ 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. */
+ for (long u = r >>> 1;
+ u + m - (r = u % bound) < 0L;
+ u = rng.nextLong() >>> 1)
+ ;
+ }
+ return r;
+ }
+
+ /**
+ * This is the form of {@code nextInt} used by an {@link IntStream}
+ * {@link Spliterator} and by the public method
+ * {@code nextInt(origin, bound)}. If {@code origin} is greater
+ * than {@code bound}, then this method simply calls the unbounded
+ * version of {@code nextInt()}, choosing pseudorandomly from
+ * among all 2<sup>64</sup> possible {@code int} values}, and
+ * otherwise uses one or more calls to {@code nextInt()} to
+ * choose a value pseudorandomly from the possible values
+ * between {@code origin} (inclusive) and {@code bound} (exclusive).
+ *
+ * @param rng a random number generator to be used as a
+ * source of pseudorandom {@code int} values
+ * @param origin the least value that can be produced,
+ * unless greater than or equal to {@code bound}
+ * @param bound the upper bound (exclusive), unless {@code origin}
+ * is greater than or equal to {@code bound}
+ *
+ * @return a pseudorandomly chosen {@code int} value,
+ * which will be between {@code origin} (inclusive) and
+ * {@code bound} exclusive unless {@code origin}
+ * is greater than or equal to {@code bound}
+ *
+ * @implNote The implementation of this method is identical to
+ * the implementation of {@code nextLong(origin, bound)}
+ * except that {@code int} values and the {@code nextInt()}
+ * method are used rather than {@code long} values and the
+ * {@code nextLong()} method.
+ */
+ public static int boundedNextInt(RandomGenerator rng, int origin, int bound) {
+ int r = rng.nextInt();
+ if (origin < bound) {
+ // It's not case (1).
+ final int n = bound - origin;
+ final int m = n - 1;
+ if ((n & m) == 0) {
+ // It is case (2): length of range is a power of 2.
+ r = (r & m) + origin;
+ } else if (n > 0) {
+ // It is case (3): need to reject over-represented candidates.
+ for (int u = r >>> 1;
+ u + m - (r = u % n) < 0;
+ u = rng.nextInt() >>> 1)
+ ;
+ r += origin;
+ }
+ else {
+ // It is case (4): length of range not representable as long.
+ while (r < origin || r >= bound) {
+ r = rng.nextInt();
+ }
+ }
+ }
+ return r;
+ }
+
+ /**
+ * This is the form of {@code nextInt} used by the public method
+ * {@code nextInt(bound)}. This is essentially a version of
+ * {@code boundedNextInt(origin, bound)} that has been
+ * specialized for the case where the {@code origin} is zero
+ * and the {@code bound} is greater than zero. The value
+ * returned is chosen pseudorandomly from nonnegative integer
+ * values less than {@code bound}.
+ *
+ * @param rng a random number generator to be used as a
+ * source of pseudorandom {@code long} values
+ * @param bound the upper bound (exclusive); must be greater than zero
+ *
+ * @return a pseudorandomly chosen {@code long} value
+ *
+ * @implNote The implementation of this method is identical to
+ * the implementation of {@code nextLong(bound)}
+ * except that {@code int} values and the {@code nextInt()}
+ * method are used rather than {@code long} values and the
+ * {@code nextLong()} method.
+ */
+ public static int boundedNextInt(RandomGenerator rng, int bound) {
+ // Specialize boundedNextInt for origin == 0, bound > 0
+ final int m = bound - 1;
+ int r = rng.nextInt();
+ if ((bound & m) == 0) {
+ // The bound is a power of 2.
+ r &= m;
+ } else {
+ // Must reject over-represented candidates
+ for (int u = r >>> 1;
+ u + m - (r = u % bound) < 0;
+ u = rng.nextInt() >>> 1)
+ ;
+ }
+ return r;
+ }
+
+ /**
+ * This is the form of {@code nextDouble} used by a {@link DoubleStream}
+ * {@link Spliterator} and by the public method
+ * {@code nextDouble(origin, bound)}. If {@code origin} is greater
+ * than {@code bound}, then this method simply calls the unbounded
+ * version of {@code nextDouble()}, and otherwise scales and translates
+ * the result of a call to {@code nextDouble()} so that it lies
+ * between {@code origin} (inclusive) and {@code bound} (exclusive).
+ *
+ * @implNote The implementation considers two cases:
+ * <ol>
+ *
+ * <li> If the {@code bound} is less than or equal to the {@code origin}
+ * (indicated an unbounded form), the 64-bit {@code double} value
+ * obtained from {@code nextDouble()} is returned directly.
+ *
+ * <li> Otherwise, the result of a call to {@code nextDouble} is
+ * multiplied by {@code (bound - origin)}, then {@code origin}
+ * is added, and then if this this result is not less than
+ * {@code bound} (which can sometimes occur because of rounding),
+ * it is replaced with the largest {@code double} value that
+ * is less than {@code bound}.
+ *
+ * </ol>
+ *
+ * @param rng a random number generator to be used as a
+ * source of pseudorandom {@code double} values
+ * @param origin the least value that can be produced,
+ * unless greater than or equal to {@code bound}; must be finite
+ * @param bound the upper bound (exclusive), unless {@code origin}
+ * is greater than or equal to {@code bound}; must be finite
+ * @return a pseudorandomly chosen {@code double} value,
+ * which will be between {@code origin} (inclusive) and
+ * {@code bound} exclusive unless {@code origin}
+ * is greater than or equal to {@code bound},
+ * in which case it will be between 0.0 (inclusive)
+ * and 1.0 (exclusive)
+ */
+ public static double boundedNextDouble(RandomGenerator rng, double origin, double bound) {
+ double r = rng.nextDouble();
+ if (origin < bound) {
+ r = r * (bound - origin) + origin;
+ if (r >= bound) // may need to correct a rounding problem
+ r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
+ }
+ return r;
+ }
+
+ /**
+ * This is the form of {@code nextDouble} used by the public method
+ * {@code nextDouble(bound)}. This is essentially a version of
+ * {@code boundedNextDouble(origin, bound)} that has been
+ * specialized for the case where the {@code origin} is zero
+ * and the {@code bound} is greater than zero.
+ *
+ * @implNote The result of a call to {@code nextDouble} is
+ * multiplied by {@code bound}, and then if this result is
+ * not less than {@code bound} (which can sometimes occur
+ * because of rounding), it is replaced with the largest
+ * {@code double} value that is less than {@code bound}.
+ *
+ * @param rng a random number generator to be used as a
+ * source of pseudorandom {@code double} values
+ * @param bound the upper bound (exclusive); must be finite and
+ * greater than zero
+ * @return a pseudorandomly chosen {@code double} value
+ * between zero (inclusive) and {@code bound} (exclusive)
+ */
+ public static double boundedNextDouble(RandomGenerator rng, double bound) {
+ // Specialize boundedNextDouble for origin == 0, bound > 0
+ double r = rng.nextDouble();
+ r = r * bound;
+ if (r >= bound) // may need to correct a rounding problem
+ r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
+ return r;
+ }
+
+ /**
+ * This is the form of {@code nextFloat} used by a {@code Stream<Float>}
+ * {@link Spliterator} (if there were any) and by the public method
+ * {@code nextFloat(origin, bound)}. If {@code origin} is greater
+ * than {@code bound}, then this method simply calls the unbounded
+ * version of {@code nextFloat()}, and otherwise scales and translates
+ * the result of a call to {@code nextFloat()} so that it lies
+ * between {@code origin} (inclusive) and {@code bound} (exclusive).
+ *
+ * @implNote The implementation of this method is identical to
+ * the implementation of {@code nextDouble(origin, bound)}
+ * except that {@code float} values and the {@code nextFloat()}
+ * method are used rather than {@code double} values and the
+ * {@code nextDouble()} method.
+ *
+ * @param rng a random number generator to be used as a
+ * source of pseudorandom {@code float} values
+ * @param origin the least value that can be produced,
+ * unless greater than or equal to {@code bound}; must be finite
+ * @param bound the upper bound (exclusive), unless {@code origin}
+ * is greater than or equal to {@code bound}; must be finite
+ * @return a pseudorandomly chosen {@code float} value,
+ * which will be between {@code origin} (inclusive) and
+ * {@code bound} exclusive unless {@code origin}
+ * is greater than or equal to {@code bound},
+ * in which case it will be between 0.0 (inclusive)
+ * and 1.0 (exclusive)
+ */
+ public static float boundedNextFloat(RandomGenerator rng, float origin, float bound) {
+ float r = rng.nextFloat();
+ if (origin < bound) {
+ r = r * (bound - origin) + origin;
+ if (r >= bound) // may need to correct a rounding problem
+ r = Float.intBitsToFloat(Float.floatToIntBits(bound) - 1);
+ }
+ return r;
+ }
+
+ /**
+ * This is the form of {@code nextFloat} used by the public method
+ * {@code nextFloat(bound)}. This is essentially a version of
+ * {@code boundedNextFloat(origin, bound)} that has been
+ * specialized for the case where the {@code origin} is zero
+ * and the {@code bound} is greater than zero.
+ *
+ * @implNote The implementation of this method is identical to
+ * the implementation of {@code nextDouble(bound)}
+ * except that {@code float} values and the {@code nextFloat()}
+ * method are used rather than {@code double} values and the
+ * {@code nextDouble()} method.
+ *
+ * @param rng a random number generator to be used as a
+ * source of pseudorandom {@code float} values
+ * @param bound the upper bound (exclusive); must be finite and
+ * greater than zero
+ * @return a pseudorandomly chosen {@code float} value
+ * between zero (inclusive) and {@code bound} (exclusive)
+ */
+ public static float boundedNextFloat(RandomGenerator rng, float bound) {
+ // Specialize boundedNextFloat for origin == 0, bound > 0
+ float r = rng.nextFloat();
+ r = r * bound;
+ if (r >= bound) // may need to correct a rounding problem
+ r = Float.intBitsToFloat(Float.floatToIntBits(bound) - 1);
+ return r;
+ }
+
+ // The following decides which of two strategies initialSeed() will use.
+ private static boolean secureRandomSeedRequested() {
+ String pp = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction(
+ "java.util.secureRandomSeed"));
+ return (pp != null && pp.equalsIgnoreCase("true"));
+ }
+
+ private static final boolean useSecureRandomSeed = secureRandomSeedRequested();
+
+ /**
+ * Returns a {@code long} value (chosen from some
+ * machine-dependent entropy source) that may be useful for
+ * initializing a source of seed values for instances of {@link RandomGenerator}
+ * created by zero-argument constructors. (This method should
+ * <i>not</i> be called repeatedly, once per constructed
+ * object; at most it should be called once per class.)
+ *
+ * @return a {@code long} value, randomly chosen using
+ * appropriate environmental entropy
+ */
+ public static long initialSeed() {
+ if (useSecureRandomSeed) {
+ byte[] seedBytes = java.security.SecureRandom.getSeed(8);
+ long s = (long)(seedBytes[0]) & 0xffL;
+ for (int i = 1; i < 8; ++i)
+ s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
+ return s;
+ }
+ return (mixStafford13(System.currentTimeMillis()) ^
+ mixStafford13(System.nanoTime()));
+ }
+
+ /**
+ * The first 32 bits of the golden ratio (1+sqrt(5))/2, forced to be odd.
+ * Useful for producing good Weyl sequences or as an arbitrary nonzero odd value.
+ */
+ public static final int GOLDEN_RATIO_32 = 0x9e3779b9;
+
+ /**
+ * The first 64 bits of the golden ratio (1+sqrt(5))/2, forced to be odd.
+ * Useful for producing good Weyl sequences or as an arbitrary nonzero odd value.
+ */
+ public static final long GOLDEN_RATIO_64 = 0x9e3779b97f4a7c15L;
+
+ /**
+ * The first 32 bits of the silver ratio 1+sqrt(2), forced to be odd.
+ * Useful for producing good Weyl sequences or as an arbitrary nonzero odd value.
+ */
+ public static final int SILVER_RATIO_32 = 0x6A09E667;
+
+ /**
+ * The first 64 bits of the silver ratio 1+sqrt(2), forced to be odd.
+ * Useful for producing good Weyl sequences or as an arbitrary nonzero odd value.
+ */
+ public static final long SILVER_RATIO_64 = 0x6A09E667F3BCC909L;
+
+ /**
+ * Computes the 64-bit mixing function for MurmurHash3.
+ * This is a 64-bit hashing function with excellent avalanche statistics.
+ * https://github.com/aappleby/smhasher/wiki/MurmurHash3
+ *
+ * Note that if the argument {@code z} is 0, the result is 0.
+ *
+ * @param z any long value
+ *
+ * @return the result of hashing z
+ */
+ public static long mixMurmur64(long z) {
+ z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
+ z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
+ return z ^ (z >>> 33);
+ }
+
+ /**
+ * Computes Stafford variant 13 of the 64-bit mixing function for MurmurHash3.
+ * This is a 64-bit hashing function with excellent avalanche statistics.
+ * http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html
+ *
+ * Note that if the argument {@code z} is 0, the result is 0.
+ *
+ * @param z any long value
+ *
+ * @return the result of hashing z
+ */
+ public static long mixStafford13(long z) {
+ z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L;
+ z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
+ return z ^ (z >>> 31);
+ }
+
+ /**
+ * Computes Doug Lea's 64-bit mixing function.
+ * This is a 64-bit hashing function with excellent avalanche statistics.
+ * It has the advantages of using the same multiplicative constant twice
+ * and of using only 32-bit shifts.
+ *
+ * Note that if the argument {@code z} is 0, the result is 0.
+ *
+ * @param z any long value
+ *
+ * @return the result of hashing z
+ */
+ public static long mixLea64(long z) {
+ z = (z ^ (z >>> 32)) * 0xdaba0b6eb09322e3L;
+ z = (z ^ (z >>> 32)) * 0xdaba0b6eb09322e3L;
+ return z ^ (z >>> 32);
+ }
+
+ /**
+ * Computes the 32-bit mixing function for MurmurHash3.
+ * This is a 32-bit hashing function with excellent avalanche statistics.
+ * https://github.com/aappleby/smhasher/wiki/MurmurHash3
+ *
+ * Note that if the argument {@code z} is 0, the result is 0.
+ *
+ * @param z any long value
+ *
+ * @return the result of hashing z
+ */
+ public static int mixMurmur32(int z) {
+ z = (z ^ (z >>> 16)) * 0x85ebca6b;
+ z = (z ^ (z >>> 13)) * 0xc2b2ae35;
+ return z ^ (z >>> 16);
+ }
+
+ /**
+ * Computes Doug Lea's 32-bit mixing function.
+ * This is a 32-bit hashing function with excellent avalanche statistics.
+ * It has the advantages of using the same multiplicative constant twice
+ * and of using only 16-bit shifts.
+ *
+ * Note that if the argument {@code z} is 0, the result is 0.
+ *
+ * @param z any long value
+ *
+ * @return the result of hashing z
+ */
+ public static int mixLea32(int z) {
+ z = (z ^ (z >>> 16)) * 0xd36d884b;
+ z = (z ^ (z >>> 16)) * 0xd36d884b;
+ return z ^ (z >>> 16);
+ }
+
+ // Non-public (package only) support for spliterators needed by AbstractSplittableGenerator
+ // and AbstractArbitrarilyJumpableGenerator and AbstractSharedGenerator
+
+ /**
+ * Base class for making Spliterator classes for streams of randomly chosen values.
+ */
+ public abstract static class RandomSpliterator {
+
+ /** low range value */
+ public long index;
+
+ /** high range value */
+ public final long fence;
+
+ /**
+ * Constructor
+ *
+ * @param index low range value
+ * @param fence high range value
+ */
+ public RandomSpliterator(long index, long fence) {
+ this.index = index; this.fence = fence;
+ }
+
+ /**
+ * Returns estimated size.
+ *
+ * @return estimated size
+ */
+ public long estimateSize() {
+ return fence - index;
+ }
+
+ /**
+ * Returns characteristics.
+ *
+ * @return characteristics
+ */
+ public int characteristics() {
+ return (Spliterator.SIZED | Spliterator.SUBSIZED |
+ Spliterator.NONNULL | Spliterator.IMMUTABLE);
+ }
+ }
+
+
+ /*
+ * Implementation support for nextExponential() and nextGaussian() methods of RandomGenerator.
+ *
+ * Each is implemented using McFarland's fast modified ziggurat algorithm (largely
+ * table-driven, with rare cases handled by computation and rejection sampling).
+ * Walker's alias method for sampling a discrete distribution also plays a role.
+ *
+ * The tables themselves, as well as a number of associated parameters, are defined
+ * in class java.util.DoubleZigguratTables, which is automatically generated by the
+ * program create_ziggurat_tables.c (which takes only a few seconds to run).
+ *
+ * For more information about the algorithms, see these articles:
+ *
+ * Christopher D. McFarland. 2016 (published online 24 Jun 2015). A modified ziggurat
+ * algorithm for generating exponentially and normally distributed pseudorandom numbers.
+ * Journal of Statistical Computation and Simulation 86 (7), pages 1281-1294.
+ * https://www.tandfonline.com/doi/abs/10.1080/00949655.2015.1060234
+ * Also at https://arxiv.org/abs/1403.6870 (26 March 2014).
+ *
+ * Alastair J. Walker. 1977. An efficient method for generating discrete random
+ * variables with general distributions. ACM Trans. Math. Software 3, 3
+ * (September 1977), 253-256. DOI: https://doi.org/10.1145/355744.355749
+ *
+ * Certain details of these algorithms depend critically on the quality of the
+ * low-order bits delivered by NextLong(). These algorithms should not be used
+ * with RNG algorithms (such as a simple Linear Congruential Generator) whose
+ * low-order output bits do not have good statistical quality.
+ */
+
+ // Implementation support for nextExponential()
+
+ static double computeNextExponential(RandomGenerator rng) {
+ long U1 = rng.nextLong();
+ // Experimentation on a variety of machines indicates that it is overall much faster
+ // to do the following & and < operations on longs rather than first cast U1 to int
+ // (but then we need to cast to int before doing the array indexing operation).
+ long i = U1 & DoubleZigguratTables.exponentialLayerMask;
+ if (i < DoubleZigguratTables.exponentialNumberOfLayers) {
+ // This is the fast path (occurring more than 98% of the time). Make an early exit.
+ return DoubleZigguratTables.exponentialX[(int)i] * (U1 >>> 1);
+ }
+ // We didn't use the upper part of U1 after all. We'll be able to use it later.
+
+ for (double extra = 0.0; ; ) {
+ // Use Walker's alias method to sample an (unsigned) integer j from a discrete
+ // probability distribution that includes the tail and all the ziggurat overhangs;
+ // j will be less than DoubleZigguratTables.exponentialNumberOfLayers + 1.
+ long UA = rng.nextLong();
+ int j = (int)UA & DoubleZigguratTables.exponentialAliasMask;
+ if (UA >= DoubleZigguratTables.exponentialAliasThreshold[j]) {
+ j = DoubleZigguratTables.exponentialAliasMap[j] & DoubleZigguratTables.exponentialSignCorrectionMask;
+ }
+ if (j > 0) { // Sample overhang j
+ // For the exponential distribution, every overhang is convex.
+ final double[] X = DoubleZigguratTables.exponentialX;
+ final double[] Y = DoubleZigguratTables.exponentialY;
+ for (;; U1 = (rng.nextLong() >>> 1)) {
+ long U2 = (rng.nextLong() >>> 1);
+ // Compute the actual x-coordinate of the randomly chosen point.
+ double x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
+ // Does the point lie below the curve?
+ long Udiff = U2 - U1;
+ if (Udiff < 0) {
+ // We picked a point in the upper-right triangle. None of those can be accepted.
+ // So remap the point into the lower-left triangle and try that.
+ // In effect, we swap U1 and U2, and invert the sign of Udiff.
+ Udiff = -Udiff;
+ U2 = U1;
+ U1 -= Udiff;
+ }
+ if (Udiff >= DoubleZigguratTables.exponentialConvexMargin) {
+ return x + extra; // The chosen point is way below the curve; accept it.
+ }
+ // Compute the actual y-coordinate of the randomly chosen point.
+ double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
+ // Now see how that y-coordinate compares to the curve
+ if (y <= Math.exp(-x)) {
+ return x + extra; // The chosen point is below the curve; accept it.
+ }
+ // Otherwise, we reject this sample and have to try again.
+ }
+ }
+ // We are now committed to sampling from the tail. We could do a recursive call
+ // and then add X[0] but we save some time and stack space by using an iterative loop.
+ extra += DoubleZigguratTables.exponentialX0;
+ // This is like the first five lines of this method, but if it returns, it first adds "extra".
+ U1 = rng.nextLong();
+ i = U1 & DoubleZigguratTables.exponentialLayerMask;
+ if (i < DoubleZigguratTables.exponentialNumberOfLayers) {
+ return DoubleZigguratTables.exponentialX[(int)i] * (U1 >>> 1) + extra;
+ }
+ }
+ }
+
+ // Implementation support for nextGaussian()
+
+ static double computeNextGaussian(RandomGenerator rng) {
+ long U1 = rng.nextLong();
+ // Experimentation on a variety of machines indicates that it is overall much faster
+ // to do the following & and < operations on longs rather than first cast U1 to int
+ // (but then we need to cast to int before doing the array indexing operation).
+ long i = U1 & DoubleZigguratTables.normalLayerMask;
+
+ if (i < DoubleZigguratTables.normalNumberOfLayers) {
+ // This is the fast path (occurring more than 98% of the time). Make an early exit.
+ return DoubleZigguratTables.normalX[(int)i] * U1; // Note that the sign bit of U1 is used here.
+ }
+ // We didn't use the upper part of U1 after all.
+ // Pull U1 apart into a sign bit and a 63-bit value for later use.
+ double signBit = (U1 >= 0) ? 1.0 : -1.0;
+ U1 = (U1 << 1) >>> 1;
+
+ // Use Walker's alias method to sample an (unsigned) integer j from a discrete
+ // probability distribution that includes the tail and all the ziggurat overhangs;
+ // j will be less than DoubleZigguratTables.normalNumberOfLayers + 1.
+ long UA = rng.nextLong();
+ int j = (int)UA & DoubleZigguratTables.normalAliasMask;
+ if (UA >= DoubleZigguratTables.normalAliasThreshold[j]) {
+ j = DoubleZigguratTables.normalAliasMap[j] & DoubleZigguratTables.normalSignCorrectionMask;
+ }
+
+ double x;
+ // Now the goal is to choose the result, which will be multiplied by signBit just before return.
+
+ // There are four kinds of overhangs:
+ //
+ // j == 0 : Sample from tail
+ // 0 < j < normalInflectionIndex : Overhang is convex; can reject upper-right triangle
+ // j == normalInflectionIndex : Overhang includes the inflection point
+ // j > normalInflectionIndex : Overhang is concave; can accept point in lower-left triangle
+ //
+ // Choose one of four loops to compute x, each specialized for a specific kind of overhang.
+ // Conditional statements are arranged such that the more likely outcomes are first.
+
+ // In the three cases other than the tail case:
+ // U1 represents a fraction (scaled by 2**63) of the width of rectangle measured from the left.
+ // U2 represents a fraction (scaled by 2**63) of the height of rectangle measured from the top.
+ // Together they indicate a randomly chosen point within the rectangle.
+
+ final double[] X = DoubleZigguratTables.normalX;
+ final double[] Y = DoubleZigguratTables.normalY;
+ if (j > DoubleZigguratTables.normalInflectionIndex) { // Concave overhang
+ for (;; U1 = (rng.nextLong() >>> 1)) {
+ long U2 = (rng.nextLong() >>> 1);
+ // Compute the actual x-coordinate of the randomly chosen point.
+ x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
+ // Does the point lie below the curve?
+ long Udiff = U2 - U1;
+ if (Udiff >= 0) {
+ break; // The chosen point is in the lower-left triangle; accept it.
+ }
+ if (Udiff <= -DoubleZigguratTables.normalConcaveMargin) {
+ continue; // The chosen point is way above the curve; reject it.
+ }
+ // Compute the actual y-coordinate of the randomly chosen point.
+ double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
+ // Now see how that y-coordinate compares to the curve
+ if (y <= Math.exp(-0.5*x*x)) {
+ break; // The chosen point is below the curve; accept it.
+ }
+ // Otherwise, we reject this sample and have to try again.
+ }
+ } else if (j == 0) { // Tail
+ // Tail-sampling method of Marsaglia and Tsang. See any one of:
+ // Marsaglia and Tsang. 1984. A fast, easily implemented method for sampling from decreasing
+ // or symmetric unimodal density functions. SIAM J. Sci. Stat. Comput. 5, 349-359.
+ // Marsaglia and Tsang. 1998. The Monty Python method for generating random variables.
+ // ACM Trans. Math. Softw. 24, 3 (September 1998), 341-350. See page 342, step (4).
+ // http://doi.org/10.1145/292395.292453
+ // Thomas, Luk, Leong, and Villasenor. 2007. Gaussian random number generators.
+ // ACM Comput. Surv. 39, 4, Article 11 (November 2007). See Algorithm 16.
+ // http://doi.org/10.1145/1287620.1287622
+ // Compute two separate random exponential samples and then compare them in certain way.
+ do {
+ x = (1.0 / DoubleZigguratTables.normalX0) * computeNextExponential(rng);
+ } while (computeNextExponential(rng) < 0.5*x*x);
+ x += DoubleZigguratTables.normalX0;
+ } else if (j < DoubleZigguratTables.normalInflectionIndex) { // Convex overhang
+ for (;; U1 = (rng.nextLong() >>> 1)) {
+ long U2 = (rng.nextLong() >>> 1);
+ // Compute the actual x-coordinate of the randomly chosen point.
+ x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
+ // Does the point lie below the curve?
+ long Udiff = U2 - U1;
+ if (Udiff < 0) {
+ // We picked a point in the upper-right triangle. None of those can be accepted.
+ // So remap the point into the lower-left triangle and try that.
+ // In effect, we swap U1 and U2, and invert the sign of Udiff.
+ Udiff = -Udiff;
+ U2 = U1;
+ U1 -= Udiff;
+ }
+ if (Udiff >= DoubleZigguratTables.normalConvexMargin) {
+ break; // The chosen point is way below the curve; accept it.
+ }
+ // Compute the actual y-coordinate of the randomly chosen point.
+ double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
+ // Now see how that y-coordinate compares to the curve
+ if (y <= Math.exp(-0.5*x*x)) break; // The chosen point is below the curve; accept it.
+ // Otherwise, we reject this sample and have to try again.
+ }
+ } else {
+ // The overhang includes the inflection point, so the curve is both convex and concave
+ for (;; U1 = (rng.nextLong() >>> 1)) {
+ long U2 = (rng.nextLong() >>> 1);
+ // Compute the actual x-coordinate of the randomly chosen point.
+ x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
+ // Does the point lie below the curve?
+ long Udiff = U2 - U1;
+ if (Udiff >= DoubleZigguratTables.normalConvexMargin) {
+ break; // The chosen point is way below the curve; accept it.
+ }
+ if (Udiff <= -DoubleZigguratTables.normalConcaveMargin) {
+ continue; // The chosen point is way above the curve; reject it.
+ }
+ // Compute the actual y-coordinate of the randomly chosen point.
+ double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
+ // Now see how that y-coordinate compares to the curve
+ if (y <= Math.exp(-0.5*x*x)) {
+ break; // The chosen point is below the curve; accept it.
+ }
+ // Otherwise, we reject this sample and have to try again.
+ }
+ }
+ return signBit*x;
+ }
+
+ /**
+ * This class overrides the stream-producing methods (such as {@code ints()})
+ * in class {@link AbstractGenerator} to provide {@link Spliterator}-based
+ * implmentations that support potentially parallel execution.
+ *
+ * To implement a pseudorandom number generator, the programmer needs
+ * only to extend this class and provide implementations for the methods
+ * {@code nextInt()}, {@code nextLong()}, {@code makeIntsSpliterator},
+ * {@code makeLongsSpliterator}, and {@code makeDoublesSpliterator}.
+ *
+ * This class is not public; it provides shared code to the public
+ * classes {@link AbstractSplittableGenerator}, {@link AbstractSharedGenerator},
+ * and {@link AbstractArbitrarilyJumpableGenerator}.
+ *
+ * @since 14
+ */
+ public abstract static class AbstractSpliteratorGenerator implements RandomGenerator {
+ /*
+ * Implementation Overview.
+ *
+ * This class provides most of the "user API" methods needed to
+ * satisfy the interface RandomGenerator. An implementation of this
+ * interface need only extend this class and provide implementations
+ * of six methods: nextInt, nextLong, and nextDouble (the versions
+ * that take no arguments) and makeIntsSpliterator,
+ * makeLongsSpliterator, and makeDoublesSpliterator.
+ *
+ * File organization: First the non-public abstract methods needed
+ * to create spliterators, then the main public methods.
+ */
+
+ /**
+ * Needs comment (was made public to be overridden out of package.)
+ *
+ * @param index low
+ * @param fence high
+ * @param origin low
+ * @param bound high
+ * @return result
+ */
+ public abstract Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound);
+
+ /**
+ * Needs comment (was made public to be overridden out of package.)
+ *
+ * @param index low
+ * @param fence high
+ * @param origin low
+ * @param bound high
+ * @return result
+ */
+ public abstract Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound);
+
+ /**
+ * Needs comment (was made public to be overridden out of package.)
+ *
+ * @param index low
+ * @param fence high
+ * @param origin low
+ * @param bound high
+ * @return result
+ */
+ public abstract Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound);
+
+ /* ---------------- public methods ---------------- */
+
+ // stream methods, coded in a way intended to better isolate for
+ // maintenance purposes the small differences across forms.
+
+ private static IntStream intStream(Spliterator.OfInt srng) {
+ return StreamSupport.intStream(srng, false);
+ }
+
+ private static LongStream longStream(Spliterator.OfLong srng) {
+ return StreamSupport.longStream(srng, false);
+ }
+
+ private static DoubleStream doubleStream(Spliterator.OfDouble srng) {
+ return StreamSupport.doubleStream(srng, false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code int}
+ * values from this generator and/or one split from it.
+ *
+ * @param streamSize the number of values to generate
+ *
+ * @return a stream of pseudorandom {@code int} values
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero
+ */
+ public IntStream ints(long streamSize) {
+ RandomSupport.checkStreamSize(streamSize);
+ return intStream(makeIntsSpliterator(0L, streamSize, Integer.MAX_VALUE, 0));
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandomly chosen
+ * {@code int} values.
+ *
+ * @implNote The implementation of this method is effectively
+ * equivalent to {@code ints(Long.MAX_VALUE)}.
+ *
+ * @return a stream of pseudorandomly chosen {@code int} values
+ */
+
+ public IntStream ints() {
+ return intStream(makeIntsSpliterator(0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0));
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code int}
+ * values from this generator and/or one split from it; each value conforms to the given origin
+ * (inclusive) and bound (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ *
+ * @return a stream of pseudorandom {@code int} values, each with the given origin (inclusive)
+ * and bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero, or {@code
+ * randomNumberOrigin} is greater than or equal to {@code
+ * randomNumberBound}
+ */
+ public IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound) {
+ RandomSupport.checkStreamSize(streamSize);
+ RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
+ return intStream(makeIntsSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code int} values from this
+ * generator and/or one split from it; each value conforms to the given origin (inclusive) and
+ * bound (exclusive).
+ *
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ *
+ * @return a stream of pseudorandom {@code int} values, each with the given origin (inclusive)
+ * and bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
+ * {@code randomNumberBound}
+ *
+ * @implNote This method is implemented to be equivalent to {@code ints(Long.MAX_VALUE,
+ * randomNumberOrigin, randomNumberBound)}.
+ */
+ public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
+ RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
+ return intStream(makeIntsSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound));
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code long}
+ * values from this generator and/or one split from it.
+ *
+ * @param streamSize the number of values to generate
+ *
+ * @return a stream of pseudorandom {@code long} values
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero
+ */
+ public LongStream longs(long streamSize) {
+ RandomSupport.checkStreamSize(streamSize);
+ return longStream(makeLongsSpliterator(0L, streamSize, Long.MAX_VALUE, 0L));
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code long} values from this
+ * generator and/or one split from it.
+ *
+ * @return a stream of pseudorandom {@code long} values
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * longs(Long.MAX_VALUE)}.
+ */
+ public LongStream longs() {
+ return longStream(makeLongsSpliterator(0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L));
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code long}
+ * values from this generator and/or one split from it; each value conforms to the given origin
+ * (inclusive) and bound (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ *
+ * @return a stream of pseudorandom {@code long} values, each with the given origin (inclusive)
+ * and bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero, or {@code
+ * randomNumberOrigin} is greater than or equal to {@code
+ * randomNumberBound}
+ */
+ public LongStream longs(long streamSize, long randomNumberOrigin,
+ long randomNumberBound) {
+ RandomSupport.checkStreamSize(streamSize);
+ RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
+ return longStream(makeLongsSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code long} values from this
+ * generator and/or one split from it; each value conforms to the given origin (inclusive) and
+ * bound (exclusive).
+ *
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ *
+ * @return a stream of pseudorandom {@code long} values, each with the given origin (inclusive)
+ * and bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
+ * {@code randomNumberBound}
+ *
+ * @implNote This method is implemented to be equivalent to {@code longs(Long.MAX_VALUE,
+ * randomNumberOrigin, randomNumberBound)}.
+ */
+ public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
+ RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
+ return StreamSupport.longStream
+ (makeLongsSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code double}
+ * values from this generator and/or one split from it; each value is between zero (inclusive)
+ * and one (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ *
+ * @return a stream of {@code double} values
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero
+ */
+ public DoubleStream doubles(long streamSize) {
+ RandomSupport.checkStreamSize(streamSize);
+ return doubleStream(makeDoublesSpliterator(0L, streamSize, Double.MAX_VALUE, 0.0));
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code double} values from this
+ * generator and/or one split from it; each value is between zero (inclusive) and one
+ * (exclusive).
+ *
+ * @return a stream of pseudorandom {@code double} values
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * doubles(Long.MAX_VALUE)}.
+ */
+ public DoubleStream doubles() {
+ return doubleStream(makeDoublesSpliterator(0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0));
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code double}
+ * values from this generator and/or one split from it; each value conforms to the given origin
+ * (inclusive) and bound (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ *
+ * @return a stream of pseudorandom {@code double} values, each with the given origin
+ * (inclusive) and bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero
+ * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
+ * {@code randomNumberBound}
+ */
+ public DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) {
+ RandomSupport.checkStreamSize(streamSize);
+ RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
+ return doubleStream(makeDoublesSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code double} values from this
+ * generator and/or one split from it; each value conforms to the given origin (inclusive) and
+ * bound (exclusive).
+ *
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ *
+ * @return a stream of pseudorandom {@code double} values, each with the given origin
+ * (inclusive) and bound (exclusive)
+ *
+ * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
+ * {@code randomNumberBound}
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+ */
+ public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
+ RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
+ return doubleStream(makeDoublesSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound));
+ }
+
+ }
+
+ /**
+ * This class provides much of the implementation of the
+ * {@link ArbitrarilyJumpableGenerator} interface, to minimize the effort
+ * required to implement that interface.
+ *
+ * To implement a pseudorandom number generator, the programmer needs
+ * only to extend this class and provide implementations for the
+ * methods {@link #nextInt()}, {@link #nextLong()}, {@link #copy()},
+ * {@link #jump(double)}, {@link #jumpPowerOfTwo(int)},
+ * {@link #defaultJumpDistance()}, and {@link #defaultLeapDistance()}.
+ *
+ * (If the pseudorandom number generator also has the ability to split,
+ * then the programmer may wish to consider instead extending
+ * {@link AbstractSplittableGenerator}.)
+ *
+ * The programmer should generally provide at least three constructors:
+ * one that takes no arguments, one that accepts a {@code long}
+ * seed value, and one that accepts an array of seed {@code byte} values.
+ * This class provides a public {@code initialSeed()} method that may
+ * be useful in initializing some static state from which to derive
+ * defaults seeds for use by the no-argument constructor.
+ *
+ * For the stream methods (such as {@code ints()} and {@code splits()}),
+ * this class provides {@link Spliterator}-based implementations that
+ * allow parallel execution when appropriate. In this respect
+ * {@link ArbitrarilyJumpableGenerator} differs from {@link JumpableGenerator},
+ * which provides very simple implementations that produce
+ * sequential streams only.
+ *
+ * <p>An implementation of the {@link AbstractArbitrarilyJumpableGenerator} class
+ * must provide concrete definitions for the methods {@code nextInt()},
+ * {@code nextLong}, {@code period()}, {@code copy()}, {@code jump(double)},
+ * {@code defaultJumpDistance()}, and {@code defaultLeapDistance()}.
+ * Default implementations are provided for all other methods.
+ *
+ * The documentation for each non-abstract method in this class
+ * describes its implementation in detail. Each of these methods may
+ * be overridden if the pseudorandom number generator being
+ * implemented admits a more efficient implementation.
+ *
+ * @since 14
+ */
+ public abstract static class AbstractArbitrarilyJumpableGenerator
+ extends AbstractSpliteratorGenerator implements RandomGenerator.ArbitrarilyJumpableGenerator {
+
+ /*
+ * Implementation Overview.
+ *
+ * This class provides most of the "user API" methods needed to satisfy
+ * the interface ArbitrarilyJumpableGenerator. Most of these methods
+ * are in turn inherited from AbstractGenerator and the non-public class
+ * AbstractSpliteratorGenerator; this file implements four versions of the
+ * jumps method and defines the spliterators necessary to support them.
+ *
+ * File organization: First the non-public methods needed by the class
+ * AbstractSpliteratorGenerator, then the main public methods, followed by some
+ * custom spliterator classes needed for stream methods.
+ */
+
+ // IllegalArgumentException messages
+ static final String BadLogDistance = "logDistance must be non-negative";
+
+ // Methods required by class AbstractSpliteratorGenerator
+ public Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) {
+ return new RandomIntsSpliterator(this, index, fence, origin, bound);
+ }
+ public Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound) {
+ return new RandomLongsSpliterator(this, index, fence, origin, bound);
+ }
+ public Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound) {
+ return new RandomDoublesSpliterator(this, index, fence, origin, bound);
+ }
+
+ // Similar methods used by this class
+ Spliterator<RandomGenerator> makeJumpsSpliterator(long index, long fence, double distance) {
+ return new RandomJumpsSpliterator(this, index, fence, distance);
+ }
+ Spliterator<JumpableGenerator> makeLeapsSpliterator(long index, long fence, double distance) {
+ return new RandomLeapsSpliterator(this, index, fence, distance);
+ }
+ Spliterator<ArbitrarilyJumpableGenerator> makeArbitraryJumpsSpliterator(long index, long fence, double distance) {
+ return new RandomArbitraryJumpsSpliterator(this, index, fence, distance);
+ }
+
+ /* ---------------- public methods ---------------- */
+
+ /**
+ * Returns a new generator whose internal state is an exact copy
+ * of this generator (therefore their future behavior should be
+ * identical if subjected to the same series of operations).
+ *
+ * @return a new object that is a copy of this generator
+ */
+ public abstract AbstractArbitrarilyJumpableGenerator copy();
+
+ // Stream methods for jumping
+
+ private static <T> Stream<T> stream(Spliterator<T> srng) {
+ return StreamSupport.stream(srng, false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
+ * implements the {@link RandomGenerator} interface, produced by jumping copies of this
+ * generator by different integer multiples of the default jump distance.
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * jumps(Long.MAX_VALUE)}.
+ */
+ public Stream<RandomGenerator> jumps() {
+ return stream(makeJumpsSpliterator(0L, Long.MAX_VALUE, defaultJumpDistance()));
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * new pseudorandom number generators, each of which implements the
+ * {@link RandomGenerator} interface, produced by jumping copies of this generator
+ * by different integer multiples of the default jump distance.
+ *
+ * @param streamSize the number of generators to generate
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero
+ */
+ public Stream<RandomGenerator> jumps(long streamSize) {
+ RandomSupport.checkStreamSize(streamSize);
+ return stream(makeJumpsSpliterator(0L, streamSize, defaultJumpDistance()));
+ }
+
+ /**
+ * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
+ * implements the {@link RandomGenerator} interface, produced by jumping copies of this
+ * generator by different integer multiples of the specified jump distance.
+ *
+ * @param distance a distance to jump forward within the state cycle
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * jumps(Long.MAX_VALUE)}.
+ */
+ public Stream<ArbitrarilyJumpableGenerator> jumps(double distance) {
+ return stream(makeArbitraryJumpsSpliterator(0L, Long.MAX_VALUE, distance));
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
+ * generators, each of which implements the {@link RandomGenerator} interface, produced by
+ * jumping copies of this generator by different integer multiples of the specified jump
+ * distance.
+ *
+ * @param streamSize the number of generators to generate
+ * @param distance a distance to jump forward within the state cycle
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero
+ */
+ public Stream<ArbitrarilyJumpableGenerator> jumps(long streamSize, double distance) {
+ RandomSupport.checkStreamSize(streamSize);
+ return stream(makeArbitraryJumpsSpliterator(0L, streamSize, distance));
+ }
+
+ /**
+ * Alter the state of this pseudorandom number generator so as to
+ * jump forward a very large, fixed distance (typically 2<sup>128</sup>
+ * or more) within its state cycle. The distance used is that
+ * returned by method {@code defaultLeapDistance()}.
+ */
+ public void leap() {
+ jump(defaultLeapDistance());
+ }
+
+ // Stream methods for leaping
+
+ /**
+ * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
+ * implements the {@link RandomGenerator} interface, produced by jumping copies of this
+ * generator by different integer multiples of the default leap distance.
+ *
+ * @implNote This method is implemented to be equivalent to {@code leaps(Long.MAX_VALUE)}.
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ */
+ public Stream<JumpableGenerator> leaps() {
+ return stream(makeLeapsSpliterator(0L, Long.MAX_VALUE, defaultLeapDistance()));
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
+ * generators, each of which implements the {@link RandomGenerator} interface, produced by
+ * jumping copies of this generator by different integer multiples of the default leap
+ * distance.
+ *
+ * @param streamSize the number of generators to generate
+ *
+ * @return a stream of objects that implement the {@link RandomGenerator} interface
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero
+ */
+ public Stream<JumpableGenerator> leaps(long streamSize) {
+ return stream(makeLeapsSpliterator(0L, streamSize, defaultLeapDistance()));
+ }
+
+
+ /**
+ * Spliterator for int streams. We multiplex the four int versions into one class by treating a
+ * bound less than origin as unbounded, and also by treating "infinite" as equivalent to
+ * {@code Long.MAX_VALUE}. For splits, we choose to override the method {@code trySplit()} to
+ * try to optimize execution speed: instead of dividing a range in half, it breaks off the
+ * largest possible chunk whose size is a power of two such that the remaining chunk is not
+ * empty. In this way, the necessary jump distances will tend to be powers of two. The long
+ * and double versions of this class are identical except for types.
+ */
+ static class RandomIntsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfInt {
+ final ArbitrarilyJumpableGenerator generatingGenerator;
+ final int origin;
+ final int bound;
+
+ RandomIntsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, int origin, int bound) {
+ super(index, fence);
+ this.origin = origin; this.bound = bound;
+ this.generatingGenerator = generatingGenerator;
+ }
+
+ public Spliterator.OfInt trySplit() {
+ long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
+ if (m <= i) return null;
+ index = m;
+ ArbitrarilyJumpableGenerator r = generatingGenerator;
+ return new RandomIntsSpliterator(r.copyAndJump((double)delta), i, m, origin, bound);
+ }
+
+ public boolean tryAdvance(IntConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(RandomSupport.boundedNextInt(generatingGenerator, origin, bound));
+ index = i + 1;
+ return true;
+ }
+ else return false;
+ }
+
+ public void forEachRemaining(IntConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ ArbitrarilyJumpableGenerator r = generatingGenerator;
+ int o = origin, b = bound;
+ do {
+ consumer.accept(RandomSupport.boundedNextInt(r, o, b));
+ } while (++i < f);
+ }
+ }
+ }
+
+ /**
+ * Spliterator for long streams.
+ */
+ static class RandomLongsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfLong {
+ final ArbitrarilyJumpableGenerator generatingGenerator;
+ final long origin;
+ final long bound;
+
+ RandomLongsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, long origin, long bound) {
+ super(index, fence);
+ this.generatingGenerator = generatingGenerator;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public Spliterator.OfLong trySplit() {
+ long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
+ if (m <= i) return null;
+ index = m;
+ ArbitrarilyJumpableGenerator r = generatingGenerator;
+ return new RandomLongsSpliterator(r.copyAndJump((double)delta), i, m, origin, bound);
+ }
+
+ public boolean tryAdvance(LongConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(RandomSupport.boundedNextLong(generatingGenerator, origin, bound));
+ index = i + 1;
+ return true;
+ }
+ else return false;
+ }
+
+ public void forEachRemaining(LongConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ ArbitrarilyJumpableGenerator r = generatingGenerator;
+ long o = origin, b = bound;
+ do {
+ consumer.accept(RandomSupport.boundedNextLong(r, o, b));
+ } while (++i < f);
+ }
+ }
+ }
+
+ /**
+ * Spliterator for double streams.
+ */
+ static class RandomDoublesSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfDouble {
+ final ArbitrarilyJumpableGenerator generatingGenerator;
+ final double origin;
+ final double bound;
+
+ RandomDoublesSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, double origin, double bound) {
+ super(index, fence);
+ this.generatingGenerator = generatingGenerator;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public Spliterator.OfDouble trySplit() {
+
+ long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
+ if (m <= i) return null;
+ index = m;
+ ArbitrarilyJumpableGenerator r = generatingGenerator;
+ return new RandomDoublesSpliterator(r.copyAndJump((double)delta), i, m, origin, bound);
+ }
+
+ public boolean tryAdvance(DoubleConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(RandomSupport.boundedNextDouble(generatingGenerator, origin, bound));
+ index = i + 1;
+ return true;
+ }
+ else return false;
+ }
+
+ public void forEachRemaining(DoubleConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ ArbitrarilyJumpableGenerator r = generatingGenerator;
+ double o = origin, b = bound;
+ do {
+ consumer.accept(RandomSupport.boundedNextDouble(r, o, b));
+ } while (++i < f);
+ }
+ }
+ }
+
+ // Spliterators for producing new generators by jumping or leaping. The
+ // complete implementation of each of these spliterators is right here.
+ // In the same manner as for the preceding spliterators, the method trySplit() is
+ // coded to optimize execution speed: instead of dividing a range
+ // in half, it breaks off the largest possible chunk whose
+ // size is a power of two such that the remaining chunk is not
+ // empty. In this way, the necessary jump distances will tend to be
+ // powers of two.
+
+ /**
+ * Spliterator for stream of generators of type RandomGenerator produced by jumps.
+ */
+ static class RandomJumpsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator<RandomGenerator> {
+ ArbitrarilyJumpableGenerator generatingGenerator;
+ final double distance;
+
+ RandomJumpsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, double distance) {
+ super(index, fence);
+ this.generatingGenerator = generatingGenerator; this.distance = distance;
+ }
+
+ public Spliterator<RandomGenerator> trySplit() {
+ long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
+ if (m <= i) return null;
+ index = m;
+ ArbitrarilyJumpableGenerator r = generatingGenerator;
+ // Because delta is a power of two, (distance * (double)delta) can always be computed exactly.
+ return new RandomJumpsSpliterator(r.copyAndJump(distance * (double)delta), i, m, distance);
+ }
+
+ public boolean tryAdvance(Consumer<? super RandomGenerator> consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(generatingGenerator.copyAndJump(distance));
+ index = i + 1;
+ return true;
+ }
+ return false;
+ }
+
+ public void forEachRemaining(Consumer<? super RandomGenerator> consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ ArbitrarilyJumpableGenerator r = generatingGenerator;
+ do {
+ consumer.accept(r.copyAndJump(distance));
+ } while (++i < f);
+ }
+ }
+ }
+
+ /**
+ * Spliterator for stream of generators of type RandomGenerator produced by leaps.
+ */
+ static class RandomLeapsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator<JumpableGenerator> {
+ ArbitrarilyJumpableGenerator generatingGenerator;
+ final double distance;
+
+ RandomLeapsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, double distance) {
+ super(index, fence);
+ this.generatingGenerator = generatingGenerator; this.distance = distance;
+ }
+
+ public Spliterator<JumpableGenerator> trySplit() {
+ long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
+ if (m <= i) return null;
+ index = m;
+ // Because delta is a power of two, (distance * (double)delta) can always be computed exactly.
+ return new RandomLeapsSpliterator(generatingGenerator.copyAndJump(distance * (double)delta), i, m, distance);
+ }
+
+ public boolean tryAdvance(Consumer<? super JumpableGenerator> consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(generatingGenerator.copyAndJump(distance));
+ index = i + 1;
+ return true;
+ }
+ return false;
+ }
+
+ public void forEachRemaining(Consumer<? super JumpableGenerator> consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ ArbitrarilyJumpableGenerator r = generatingGenerator;
+ do {
+ consumer.accept(r.copyAndJump(distance));
+ } while (++i < f);
+ }
+ }
+ }
+
+ /**
+ * Spliterator for stream of generators of type RandomGenerator produced by arbitrary jumps.
+ */
+ static class RandomArbitraryJumpsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator<ArbitrarilyJumpableGenerator> {
+ ArbitrarilyJumpableGenerator generatingGenerator;
+ final double distance;
+
+ RandomArbitraryJumpsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, double distance) {
+ super(index, fence);
+ this.generatingGenerator = generatingGenerator; this.distance = distance;
+ }
+
+ public Spliterator<ArbitrarilyJumpableGenerator> trySplit() {
+ long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
+ if (m <= i) return null;
+ index = m;
+ // Because delta is a power of two, (distance * (double)delta) can always be computed exactly.
+ return new RandomArbitraryJumpsSpliterator(generatingGenerator.copyAndJump(distance * (double)delta), i, m, distance);
+ }
+
+ public boolean tryAdvance(Consumer<? super ArbitrarilyJumpableGenerator> consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(generatingGenerator.copyAndJump(distance));
+ index = i + 1;
+ return true;
+ }
+ return false;
+ }
+
+ public void forEachRemaining(Consumer<? super ArbitrarilyJumpableGenerator> consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ ArbitrarilyJumpableGenerator r = generatingGenerator;
+ do {
+ consumer.accept(r.copyAndJump(distance));
+ } while (++i < f);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * This class provides much of the implementation of the {@link SplittableGenerator} interface, to
+ * minimize the effort required to implement this interface.
+ * <p>
+ * To implement a pseudorandom number generator, the programmer needs only to extend this class and
+ * provide implementations for the methods {@code nextInt()}, {@code nextLong()}, {@code period()},
+ * and {@code split(SplittableGenerator)}.
+ * <p>
+ * (If the pseudorandom number generator also has the ability to jump, then the programmer may wish
+ * to consider instead extending the class {@link ArbitrarilyJumpableGenerator}. But if the pseudorandom
+ * number generator furthermore has the ability to jump an arbitrary specified distance, then the
+ * programmer may wish to consider instead extending the class {@link
+ * AbstractArbitrarilyJumpableGenerator}.)
+ * <p>
+ * The programmer should generally provide at least three constructors: one that takes no arguments,
+ * one that accepts a {@code long} seed value, and one that accepts an array of seed {@code byte}
+ * values. This class provides a public {@code initialSeed()} method that may be useful in
+ * initializing some static state from which to derive defaults seeds for use by the no-argument
+ * constructor.
+ * <p>
+ * For the stream methods (such as {@code ints()} and {@code splits()}), this class provides {@link
+ * Spliterator} based implementations that allow parallel execution when appropriate.
+ * <p>
+ * The documentation for each non-abstract method in this class describes its implementation in
+ * detail. Each of these methods may be overridden if the pseudorandom number generator being
+ * implemented admits a more efficient implementation.
+ *
+ * @since 14
+ */
+ public abstract static class AbstractSplittableGenerator extends AbstractSpliteratorGenerator implements SplittableGenerator {
+
+ /*
+ * Implementation Overview.
+ *
+ * This class provides most of the "user API" methods needed to
+ * satisfy the interface JumpableGenerator. Most of these methods
+ * are in turn inherited from AbstractGenerator and the non-public class
+ * AbstractSpliteratorGenerator; this file implements two versions of the
+ * splits method and defines the spliterators necessary to support
+ * them.
+ *
+ * The abstract split() method from interface SplittableGenerator is redeclared
+ * here so as to narrow the return type to AbstractSplittableGenerator.
+ *
+ * File organization: First the non-public methods needed by the class
+ * AbstractSpliteratorGenerator, then the main public methods, followed by some
+ * custom spliterator classes.
+ */
+
+ public Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) {
+ return new RandomIntsSpliterator(this, index, fence, origin, bound);
+ }
+
+ public Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound) {
+ return new RandomLongsSpliterator(this, index, fence, origin, bound);
+ }
+
+ public Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound) {
+ return new RandomDoublesSpliterator(this, index, fence, origin, bound);
+ }
+
+ Spliterator<SplittableGenerator> makeSplitsSpliterator(long index, long fence, SplittableGenerator source) {
+ return new RandomSplitsSpliterator(source, index, fence, this);
+ }
+
+ /* ---------------- public methods ---------------- */
+
+ /**
+ * Implements the @code{split()} method as {@code this.split(this) }.
+ *
+ * @return the new {@link AbstractSplittableGenerator} instance
+ */
+ public SplittableGenerator split() {
+ return this.split(this);
+ }
+
+ // Stream methods for splittings
+
+ /**
+ * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
+ * implements the {@link SplittableGenerator} interface.
+ * <p>
+ * This pseudorandom number generator provides the entropy used to seed the new ones.
+ *
+ * @return a stream of {@link SplittableGenerator} objects
+ *
+ * @implNote This method is implemented to be equivalent to {@code splits(Long.MAX_VALUE)}.
+ */
+ public Stream<SplittableGenerator> splits() {
+ return this.splits(Long.MAX_VALUE, this);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
+ * generators, each of which implements the {@link SplittableGenerator} interface.
+ * <p>
+ * This pseudorandom number generator provides the entropy used to seed the new ones.
+ *
+ * @param streamSize the number of values to generate
+ *
+ * @return a stream of {@link SplittableGenerator} objects
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero
+ */
+ public Stream<SplittableGenerator> splits(long streamSize) {
+ return this.splits(streamSize, this);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
+ * implements the {@link SplittableGenerator} interface.
+ *
+ * @param source a {@link SplittableGenerator} instance to be used instead of this one as a source of
+ * pseudorandom bits used to initialize the state of the new ones.
+ *
+ * @return a stream of {@link SplittableGenerator} objects
+ *
+ * @implNote This method is implemented to be equivalent to {@code splits(Long.MAX_VALUE)}.
+ */
+ public Stream<SplittableGenerator> splits(SplittableGenerator source) {
+ return this.splits(Long.MAX_VALUE, source);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
+ * generators, each of which implements the {@link SplittableGenerator} interface.
+ *
+ * @param streamSize the number of values to generate
+ * @param source a {@link SplittableGenerator} instance to be used instead of this one as a source
+ * of pseudorandom bits used to initialize the state of the new ones.
+ *
+ * @return a stream of {@link SplittableGenerator} objects
+ *
+ * @throws IllegalArgumentException if {@code streamSize} is less than zero
+ */
+ public Stream<SplittableGenerator> splits(long streamSize, SplittableGenerator source) {
+ RandomSupport.checkStreamSize(streamSize);
+ return StreamSupport.stream(makeSplitsSpliterator(0L, streamSize, source), false);
+ }
+
+ /**
+ * Spliterator for int streams. We multiplex the four int versions into one class by treating a
+ * bound less than origin as unbounded, and also by treating "infinite" as equivalent to
+ * {@code Long.MAX_VALUE}. For splits, it uses the standard divide-by-two approach. The long and
+ * double versions of this class are identical except for types.
+ */
+ static class RandomIntsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfInt {
+ final SplittableGenerator generatingGenerator;
+ final int origin;
+ final int bound;
+
+ RandomIntsSpliterator(SplittableGenerator generatingGenerator, long index, long fence, int origin, int bound) {
+ super(index, fence);
+ this.generatingGenerator = generatingGenerator;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public Spliterator.OfInt trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ if (m <= i) return null;
+ index = m;
+ return new RandomIntsSpliterator(generatingGenerator.split(), i, m, origin, bound);
+ }
+
+ public boolean tryAdvance(IntConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(RandomSupport.boundedNextInt(generatingGenerator, origin, bound));
+ index = i + 1;
+ return true;
+ }
+ else return false;
+ }
+
+ public void forEachRemaining(IntConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ RandomGenerator r = generatingGenerator;
+ int o = origin, b = bound;
+ do {
+ consumer.accept(RandomSupport.boundedNextInt(r, o, b));
+ } while (++i < f);
+ }
+ }
+ }
+
+ /**
+ * Spliterator for long streams.
+ */
+ static class RandomLongsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfLong {
+ final SplittableGenerator generatingGenerator;
+ final long origin;
+ final long bound;
+
+ RandomLongsSpliterator(SplittableGenerator generatingGenerator, long index, long fence, long origin, long bound) {
+ super(index, fence);
+ this.generatingGenerator = generatingGenerator;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public Spliterator.OfLong trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ if (m <= i) return null;
+ index = m;
+ return new RandomLongsSpliterator(generatingGenerator.split(), i, m, origin, bound);
+ }
+
+ public boolean tryAdvance(LongConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(RandomSupport.boundedNextLong(generatingGenerator, origin, bound));
+ index = i + 1;
+ return true;
+ }
+ else return false;
+ }
+
+ public void forEachRemaining(LongConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ RandomGenerator r = generatingGenerator;
+ long o = origin, b = bound;
+ do {
+ consumer.accept(RandomSupport.boundedNextLong(r, o, b));
+ } while (++i < f);
+ }
+ }
+ }
+
+ /**
+ * Spliterator for double streams.
+ */
+ static class RandomDoublesSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfDouble {
+ final SplittableGenerator generatingGenerator;
+ final double origin;
+ final double bound;
+
+ RandomDoublesSpliterator(SplittableGenerator generatingGenerator, long index, long fence, double origin, double bound) {
+ super(index, fence);
+ this.generatingGenerator = generatingGenerator;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public Spliterator.OfDouble trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ if (m <= i) return null;
+ index = m;
+ return new RandomDoublesSpliterator(generatingGenerator.split(), i, m, origin, bound);
+ }
+
+ public boolean tryAdvance(DoubleConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(RandomSupport.boundedNextDouble(generatingGenerator, origin, bound));
+ index = i + 1;
+ return true;
+ }
+ else return false;
+ }
+
+ public void forEachRemaining(DoubleConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ RandomGenerator r = generatingGenerator;
+ double o = origin, b = bound;
+ do {
+ consumer.accept(RandomSupport.boundedNextDouble(r, o, b));
+ } while (++i < f);
+ }
+ }
+ }
+
+ /**
+ * Spliterator for stream of generators of type SplittableGenerator. We multiplex the two
+ * versions into one class by treating "infinite" as equivalent to Long.MAX_VALUE.
+ * For splits, it uses the standard divide-by-two approach.
+ */
+ static class RandomSplitsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator<SplittableGenerator> {
+ final SplittableGenerator generatingGenerator;
+ final SplittableGenerator constructingGenerator;
+
+ RandomSplitsSpliterator(SplittableGenerator generatingGenerator, long index, long fence, SplittableGenerator constructingGenerator) {
+ super(index, fence);
+ this.generatingGenerator = generatingGenerator;
+ this.constructingGenerator = constructingGenerator;
+ }
+
+ public Spliterator<SplittableGenerator> trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ if (m <= i) return null;
+ index = m;
+ return new RandomSplitsSpliterator(generatingGenerator.split(), i, m, constructingGenerator);
+ }
+
+ public boolean tryAdvance(Consumer<? super SplittableGenerator> consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(constructingGenerator.split(generatingGenerator));
+ index = i + 1;
+ return true;
+ }
+ else return false;
+ }
+
+ public void forEachRemaining(Consumer<? super SplittableGenerator> consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ SplittableGenerator c = constructingGenerator;
+ SplittableGenerator r = generatingGenerator;
+ do {
+ consumer.accept(c.split(r));
+ } while (++i < f);
+ }
+ }
+ }
+
+ }
+
+}
+
--- a/src/java.base/share/classes/java/util/random/SplittableRNG.java Fri Jul 26 15:20:31 2019 -0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.random;
-
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-import java.util.stream.IntStream;
-import java.util.stream.LongStream;
-import java.util.stream.DoubleStream;
-
-/**
- * This interface is designed to provide a common protocol for objects
- * that generate sequences of pseudorandom numbers (or Boolean values)
- * and furthermore can be <i>split</i> into two objects (the original
- * one and a new one) each of which obey that same protocol (and therefore
- * can be recursively split indefinitely).
- * <p>
- * Ideally, all {@link SplittableRNG} objects produced by recursive
- * splitting from a single original {@link SplittableRNG} object are
- * statistically independent of one another and individually uniform.
- * Therefore we would expect the set of values collectively generated
- * by a set of such objects to have the same statistical properties as
- * if the same quantity of values were generated by a single thread
- * using a single {@link SplittableRNG} object. In practice, one must
- * settle for some approximation to independence and uniformity.
- * <p>
- * Methods are provided to perform a single splitting operation and
- * also to produce a stream of generators split off from the original
- * (by either iterative or recursive splitting, or a combination).
- * <p>
- * An implementation of the {@link SplittableRNG} interface must provide
- * concrete definitions for the methods {@code nextInt()}, {@code nextLong},
- * {@code period()}, {@code split()}, {@code split(SplittableRNG)},
- * {@code splits()}, {@code splits(long)}, {@code splits(SplittableRNG)},
- * and {@code splits(long, SplittableRNG)}. Perhaps the most convenient
- * way to implement this interface is to extend the abstract class
- * {@link AbstractSplittableRNG}.
- * <p>
- * Objects that implement {@link SplittableRNG} are
- * typically not cryptographically secure. Consider instead using
- * {@link java.security.SecureRandom} to get a cryptographically
- * secure pseudo-random number generator for use by
- * security-sensitive applications.
- *
- * @since 14
- */
-public interface SplittableRNG extends StreamableRNG {
-
- /**
- * Returns a new pseudorandom number generator, split off from
- * this one, that implements the {@link RandomNumberGenerator} and {@link SplittableRNG}
- * interfaces.
- *
- * This pseudorandom number generator may be used as a source of
- * pseudorandom bits used to initialize the state the new one.
- *
- * @return a new object that implements the {@link RandomNumberGenerator} and
- * {@link SplittableRNG} interfaces
- */
- SplittableRNG split();
-
- /**
- * Returns a new pseudorandom number generator, split off from
- * this one, that implements the {@link RandomNumberGenerator} and {@link SplittableRNG}
- * interfaces.
- *
- * @param source a {@link SplittableRNG} instance to be used instead
- * of this one as a source of pseudorandom bits used to
- * initialize the state of the new ones.
- *
- * @return an object that implements the {@link RandomNumberGenerator} and
- * {@link SplittableRNG} interfaces
- */
- SplittableRNG split(SplittableRNG source);
-
- /**
- * Returns an effectively unlimited stream of new pseudorandom
- * number generators, each of which implements the {@link SplittableRNG}
- * interface.
- *
- * This pseudorandom number generator may be used as a source of
- * pseudorandom bits used to initialize the state the new ones.
- *
- * @implNote It is permitted to implement this method in a manner
- * equivalent to {@code splits(Long.MAX_VALUE)}.
- *
- * @return a stream of {@link SplittableRNG} objects
- */
- default Stream<SplittableRNG> splits() {
- return this.splits(this);
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * new pseudorandom number generators, each of which implements the
- * {@link SplittableRNG} interface.
- *
- * This pseudorandom number generator may be used as a source of
- * pseudorandom bits used to initialize the state the new ones.
- *
- * @param streamSize the number of values to generate
- *
- * @return a stream of {@link SplittableRNG} objects
- *
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero
- */
- Stream<SplittableRNG> splits(long streamSize);
-
- /**
- * Returns an effectively unlimited stream of new pseudorandom
- * number generators, each of which implements the {@link SplittableRNG}
- * interface.
- *
- * @param source a {@link SplittableRNG} instance to be used instead
- * of this one as a source of pseudorandom bits used to
- * initialize the state of the new ones.
- *
- * @return a stream of {@link SplittableRNG} objects
- *
- * @implNote It is permitted to implement this method in a manner
- * equivalent to {@code splits(Long.MAX_VALUE, source)}.
- */
- Stream<SplittableRNG> splits(SplittableRNG source);
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * new pseudorandom number generators, each of which implements the
- * {@link SplittableRNG} interface.
- *
- * @param streamSize the number of values to generate
- * @param source a {@link SplittableRNG} instance to be used instead
- * of this one as a source of pseudorandom bits used to
- * initialize the state of the new ones.
- *
- * @return a stream of {@link SplittableRNG} objects
- *
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero
- */
- Stream<SplittableRNG> splits(long streamSize, SplittableRNG source);
-
- /**
- * Returns an effectively unlimited stream of new pseudorandom
- * number generators, each of which implements the {@link RandomNumberGenerator}
- * interface. Ideally the generators in the stream will appear
- * to be statistically independent.
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @implNote The default implementation calls {@code splits()}.
- */
- default Stream<RandomNumberGenerator> rngs() {
- return this.splits().map(x -> (RandomNumberGenerator)x);
- }
-
- /**
- * Returns a stream producing the given {@code streamSize} number of
- * new pseudorandom number generators, each of which implements the
- * {@link RandomNumberGenerator} interface. Ideally the generators in the stream will
- * appear to be statistically independent.
- *
- * @param streamSize the number of generators to generate
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero
- *
- * @implNote The default implementation calls {@code splits(streamSize)}.
- */
- default Stream<RandomNumberGenerator> rngs(long streamSize) {
- return this.splits(streamSize).map(x -> (RandomNumberGenerator)x);
- }
-}
--- a/src/java.base/share/classes/java/util/random/StreamableRNG.java Fri Jul 26 15:20:31 2019 -0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.random;
-
-import java.util.stream.Stream;
-
-
-/**
- * The {@link StreamableRNG} interface augments the {@link RandomNumberGenerator} interface
- * to provide methods that return streams of {@link RandomNumberGenerator} objects.
- * Ideally, such a stream of objects would have the property that the
- * behavior of each object is statistically independent of all the others.
- * In practice, one may have to settle for some approximation to this property.
- *
- * A generator that implements interface {@link SplittableRNG}
- * may choose to use its {@code splits} method to implement the {@code rngs}
- * method required by this interface.
- *
- * A generator that implements interface {@link JumpableRNG}
- * may choose to use its {@code jumps} method to implement the {@code rngs}
- * method required by this interface.
- *
- * A generator that implements interface {@link LeapableRNG}
- * may choose to use its {@code leaps} method to implement the {@code rngs}
- * method required by this interface.
- * <p>
- * An implementation of the {@link StreamableRNG} interface must provide
- * concrete definitions for the methods {@code nextInt()}, {@code nextLong},
- * {@code period()}, and {@code rngs()}.
- * Default implementations are provided for all other methods.
- * <p>
- * Objects that implement {@link StreamableRNG} are typically
- * not cryptographically secure. Consider instead using
- * {@link java.security.SecureRandom} to get a cryptographically
- * secure pseudo-random number generator for use by
- * security-sensitive applications.
- *
- * @since 14
- */
-
-public interface StreamableRNG extends RandomNumberGenerator {
- /**
- * Returns an effectively unlimited stream of objects, each of
- * which implements the {@link RandomNumberGenerator} interface. Ideally the
- * generators in the stream will appear to be statistically
- * independent. The new generators should be of the same kind
- * as this generator.
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @implNote It is permitted to implement this method in a manner
- * equivalent to {@code rngs(Long.MAX_VALUE)}.
- */
- Stream<RandomNumberGenerator> rngs();
-
- /**
- * Returns an effectively unlimited stream of objects, each of
- * which implements the {@link RandomNumberGenerator} interface. Ideally the
- * generators in the stream will appear to be statistically
- * independent. The new generators should be of the same kind
- * as this generator.
- *
- * @param streamSize the number of generators to generate
- *
- * @return a stream of objects that implement the {@link RandomNumberGenerator} interface
- *
- * @throws IllegalArgumentException if {@code streamSize} is
- * less than zero
- *
- * @implNote The default implementation calls {@code rngs()} and
- * then limits its length to {@code streamSize}.
- */
- default Stream<RandomNumberGenerator> rngs(long streamSize) {
- RNGSupport.checkStreamSize(streamSize);
- return rngs().limit(streamSize);
- }
-}
--- a/src/java.base/share/classes/java/util/random/Xoroshiro128Plus.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/random/Xoroshiro128Plus.java Fri Jul 26 15:37:05 2019 -0300
@@ -27,12 +27,13 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.random.RandomGenerator.LeapableGenerator;
/**
* A generator of uniform pseudorandom values applicable for use in
* (among other contexts) isolated parallel computations that may
* generate subtasks. Class {@link Xoroshiro128Plus} implements
- * interfaces {@link RandomNumberGenerator} and {@link LeapableRNG},
+ * interfaces {@link RandomGenerator} and {@link LeapableGenerator},
* and therefore supports methods for producing pseudorandomly chosen
* numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
* as well as creating new {@link Xoroshiro128Plus} objects
@@ -76,7 +77,7 @@
*
* @since 14
*/
-public final class Xoroshiro128Plus implements LeapableRNG {
+public final class Xoroshiro128Plus implements LeapableGenerator {
/*
* Implementation Overview.
@@ -109,7 +110,7 @@
*
* File organization: First the non-public methods that constitute the
* main algorithm, then the public methods. Note that many methods are
- * defined by classes {@link AbstractJumpableRNG} and {@link AbstractRNG}.
+ * defined by classes {@link AbstractJumpableGenerator} and {@link AbstractGenerator}.
*/
/* ---------------- static fields ---------------- */
@@ -117,7 +118,7 @@
/**
* The seed generator for default constructors.
*/
- private static final AtomicLong defaultGen = new AtomicLong(RNGSupport.initialSeed());
+ private static final AtomicLong defaultGen = new AtomicLong(RandomSupport.initialSeed());
/*
* The period of this generator, which is 2**128 - 1.
@@ -149,8 +150,8 @@
// If x0 and x1 are both zero, we must choose nonzero values.
if ((x0 | x1) == 0) {
// At least one of the two values generated here will be nonzero.
- this.x0 = RNGSupport.mixStafford13(x0 += RNGSupport.GOLDEN_RATIO_64);
- this.x1 = (x0 += RNGSupport.GOLDEN_RATIO_64);
+ this.x0 = RandomSupport.mixStafford13(x0 += RandomSupport.GOLDEN_RATIO_64);
+ this.x1 = (x0 += RandomSupport.GOLDEN_RATIO_64);
}
}
@@ -169,8 +170,8 @@
//
// The x values are then filled in as if by a SplitMix PRNG with
// GOLDEN_RATIO_64 as the gamma value and Stafford13 as the mixer.
- this(RNGSupport.mixStafford13(seed ^= RNGSupport.SILVER_RATIO_64),
- RNGSupport.mixStafford13(seed + RNGSupport.GOLDEN_RATIO_64));
+ this(RandomSupport.mixStafford13(seed ^= RandomSupport.SILVER_RATIO_64),
+ RandomSupport.mixStafford13(seed + RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -181,7 +182,7 @@
*/
public Xoroshiro128Plus() {
// Using GOLDEN_RATIO_64 here gives us a good Weyl sequence of values.
- this(defaultGen.getAndAdd(RNGSupport.GOLDEN_RATIO_64));
+ this(defaultGen.getAndAdd(RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -193,7 +194,7 @@
*/
public Xoroshiro128Plus(byte[] seed) {
// Convert the seed to 2 long values, which are not both zero.
- long[] data = RNGSupport.convertSeedBytesToLongs(seed, 2, 2);
+ long[] data = RandomSupport.convertSeedBytesToLongs(seed, 2, 2);
long x0 = data[0], x1 = data[1];
this.x0 = x0;
this.x1 = x1;
--- a/src/java.base/share/classes/java/util/random/Xoroshiro128StarStar.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/random/Xoroshiro128StarStar.java Fri Jul 26 15:37:05 2019 -0300
@@ -27,12 +27,13 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.random.RandomGenerator.LeapableGenerator;
/**
* A generator of uniform pseudorandom values applicable for use in
* (among other contexts) isolated parallel computations that may
* generate subtasks. Class {@link Xoroshiro128StarStar} implements
- * interfaces {@link RandomNumberGenerator} and {@link LeapableRNG},
+ * interfaces {@link RandomGenerator} and {@link LeapableGenerator},
* and therefore supports methods for producing pseudorandomly chosen
* numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
* as well as creating new {@link Xoroshiro128StarStar} objects
@@ -81,7 +82,7 @@
*
* @since 14
*/
-public final class Xoroshiro128StarStar implements LeapableRNG {
+public final class Xoroshiro128StarStar implements LeapableGenerator {
/*
* Implementation Overview.
@@ -114,7 +115,7 @@
*
* File organization: First the non-public methods that constitute the
* main algorithm, then the public methods. Note that many methods are
- * defined by classes {@link AbstractJumpableRNG} and {@link AbstractRNG}.
+ * defined by classes {@link AbstractJumpableGenerator} and {@link AbstractGenerator}.
*/
/* ---------------- static fields ---------------- */
@@ -122,7 +123,7 @@
/**
* The seed generator for default constructors.
*/
- private static final AtomicLong DEFAULT_GEN = new AtomicLong(RNGSupport.initialSeed());
+ private static final AtomicLong DEFAULT_GEN = new AtomicLong(RandomSupport.initialSeed());
/*
* The period of this generator, which is 2**128 - 1.
@@ -154,8 +155,8 @@
// If x0 and x1 are both zero, we must choose nonzero values.
if ((x0 | x1) == 0) {
// At least one of the two values generated here will be nonzero.
- this.x0 = RNGSupport.mixStafford13(x0 += RNGSupport.GOLDEN_RATIO_64);
- this.x1 = (x0 += RNGSupport.GOLDEN_RATIO_64);
+ this.x0 = RandomSupport.mixStafford13(x0 += RandomSupport.GOLDEN_RATIO_64);
+ this.x1 = (x0 += RandomSupport.GOLDEN_RATIO_64);
}
}
@@ -174,8 +175,8 @@
//
// The x values are then filled in as if by a SplitMix PRNG with
// GOLDEN_RATIO_64 as the gamma value and Stafford13 as the mixer.
- this(RNGSupport.mixStafford13(seed ^= RNGSupport.SILVER_RATIO_64),
- RNGSupport.mixStafford13(seed + RNGSupport.GOLDEN_RATIO_64));
+ this(RandomSupport.mixStafford13(seed ^= RandomSupport.SILVER_RATIO_64),
+ RandomSupport.mixStafford13(seed + RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -186,7 +187,7 @@
*/
public Xoroshiro128StarStar() {
// Using GOLDEN_RATIO_64 here gives us a good Weyl sequence of values.
- this(DEFAULT_GEN.getAndAdd(RNGSupport.GOLDEN_RATIO_64));
+ this(DEFAULT_GEN.getAndAdd(RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -198,7 +199,7 @@
*/
public Xoroshiro128StarStar(byte[] seed) {
// Convert the seed to 2 long values, which are not both zero.
- long[] data = RNGSupport.convertSeedBytesToLongs(seed, 2, 2);
+ long[] data = RandomSupport.convertSeedBytesToLongs(seed, 2, 2);
long x0 = data[0], x1 = data[1];
this.x0 = x0;
this.x1 = x1;
--- a/src/java.base/share/classes/java/util/random/Xoshiro256StarStar.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/java/util/random/Xoshiro256StarStar.java Fri Jul 26 15:37:05 2019 -0300
@@ -27,12 +27,13 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.random.RandomGenerator.LeapableGenerator;
/**
* A generator of uniform pseudorandom values applicable for use in
* (among other contexts) isolated parallel computations that may
* generate subtasks. Class {@link Xoshiro256StarStar} implements
- * interfaces {@link RandomNumberGenerator} and {@link LeapableRNG},
+ * interfaces {@link RandomGenerator} and {@link LeapableGenerator},
* and therefore supports methods for producing pseudorandomly chosen
* numbers of type {@code int}, {@code long}, {@code float}, and {@code double}
* as well as creating new {@link Xoshiro256StarStar} objects
@@ -89,7 +90,7 @@
*
* @since 14
*/
-public final class Xoshiro256StarStar implements LeapableRNG {
+public final class Xoshiro256StarStar implements LeapableGenerator {
/*
* Implementation Overview.
@@ -128,7 +129,7 @@
/**
* The seed generator for default constructors.
*/
- private static final AtomicLong DEFAULT_GEN = new AtomicLong(RNGSupport.initialSeed());
+ private static final AtomicLong DEFAULT_GEN = new AtomicLong(RandomSupport.initialSeed());
/*
* The period of this generator, which is 2**256 - 1.
@@ -164,10 +165,10 @@
// If x0, x1, x2, and x3 are all zero, we must choose nonzero values.
if ((x0 | x1 | x2 | x3) == 0) {
// At least three of the four values generated here will be nonzero.
- this.x0 = RNGSupport.mixStafford13(x0 += RNGSupport.GOLDEN_RATIO_64);
- this.x1 = (x0 += RNGSupport.GOLDEN_RATIO_64);
- this.x2 = (x0 += RNGSupport.GOLDEN_RATIO_64);
- this.x3 = (x0 += RNGSupport.GOLDEN_RATIO_64);
+ this.x0 = RandomSupport.mixStafford13(x0 += RandomSupport.GOLDEN_RATIO_64);
+ this.x1 = (x0 += RandomSupport.GOLDEN_RATIO_64);
+ this.x2 = (x0 += RandomSupport.GOLDEN_RATIO_64);
+ this.x3 = (x0 += RandomSupport.GOLDEN_RATIO_64);
}
}
@@ -186,10 +187,10 @@
//
// The x values are then filled in as if by a SplitMix PRNG with
// GOLDEN_RATIO_64 as the gamma value and Stafford13 as the mixer.
- this(RNGSupport.mixStafford13(seed ^= RNGSupport.SILVER_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed += RNGSupport.GOLDEN_RATIO_64),
- RNGSupport.mixStafford13(seed + RNGSupport.GOLDEN_RATIO_64));
+ this(RandomSupport.mixStafford13(seed ^= RandomSupport.SILVER_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed += RandomSupport.GOLDEN_RATIO_64),
+ RandomSupport.mixStafford13(seed + RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -200,7 +201,7 @@
*/
public Xoshiro256StarStar() {
// Using GOLDEN_RATIO_64 here gives us a good Weyl sequence of values.
- this(DEFAULT_GEN.getAndAdd(RNGSupport.GOLDEN_RATIO_64));
+ this(DEFAULT_GEN.getAndAdd(RandomSupport.GOLDEN_RATIO_64));
}
/**
@@ -212,7 +213,7 @@
*/
public Xoshiro256StarStar(byte[] seed) {
// Convert the seed to 4 long values, which are not all zero.
- long[] data = RNGSupport.convertSeedBytesToLongs(seed, 4, 4);
+ long[] data = RandomSupport.convertSeedBytesToLongs(seed, 4, 4);
long x0 = data[0], x1 = data[1], x2 = data[2], x3 = data[3];
this.x0 = x0;
this.x1 = x1;
--- a/src/java.base/share/classes/module-info.java Fri Jul 26 15:20:31 2019 -0300
+++ b/src/java.base/share/classes/module-info.java Fri Jul 26 15:37:05 2019 -0300
@@ -350,7 +350,7 @@
uses java.time.chrono.AbstractChronology;
uses java.time.chrono.Chronology;
uses java.time.zone.ZoneRulesProvider;
- uses java.util.random.RandomNumberGenerator;
+ uses java.util.random.RandomGenerator;
uses java.util.spi.CalendarDataProvider;
uses java.util.spi.CalendarNameProvider;
uses java.util.spi.CurrencyNameProvider;
@@ -375,7 +375,7 @@
provides java.nio.file.spi.FileSystemProvider with
jdk.internal.jrtfs.JrtFileSystemProvider;
- provides java.util.random.RandomNumberGenerator with
+ provides java.util.random.RandomGenerator with
java.util.random.L128X256MixRandom,
java.util.random.L32X64MixRandom,
java.util.random.L64X1024MixRandom,