--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/newrandom/Rng.java Thu May 23 16:45:56 2019 -0400
@@ -0,0 +1,635 @@
+/*
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+// package java.util;
+
+import java.math.BigInteger;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+
+/**
+ * The {@code Rng} 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 {@code 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><it>w</it></sup> values between 0.0 (inclusive)
+ * and 1.0 (exclusive), where <it>w</it> is 23 for {@code float}
+ * values and 52 for {@code double} values, such that adjacent values
+ * differ by 2<sup>−<it>w</it></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 {@code Rng}, 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 {@code Rng} 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
+ * <it>period</it>. (Some implementations of the {@code Rng} 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 {@code Rng} interface need not
+ * be thread-safe. It is recommended that multithreaded applications
+ * use either {@code ThreadLocalRandom} or (preferably) pseudorandom
+ * number generators that implement the {@code SplittableRng} or
+ * {@code JumpableRng} interface.
+
+ * 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 java.util.JumpableRng} or {@link java.util.LeapableRng},
+ * or to extend an abstract class such as {@link java.util.AbstractSplittableRng}
+ * or {@link java.util.AbstractArbitrarilyJumpableRng}.
+ *
+ * <p>Objects that implement {@code java.util.Rng} 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 {@code Rng}
+ * 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.
+ *
+ * @author Guy Steele
+ * @since 1.9
+ */
+
+interface Rng {
+
+ /**
+ * Returns an effectively unlimited 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()}.
+ *
+ * @return a stream of pseudorandomly chosen {@code double} values
+ */
+
+ 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).
+ *
+ * @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)}.
+ *
+ * @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}
+ */
+ 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.
+ *
+ * @implNote The default implementation produces a sequential stream
+ * that repeatedly calls {@code nextDouble()}.
+ *
+ * @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
+ */
+ 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).
+ *
+ * @implNote The default implementation produces a sequential stream
+ * that repeatedly calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}.
+ *
+ * @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}
+ */
+ 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.
+ *
+ * @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()}.
+ *
+ * @return a stream of pseudorandomly chosen {@code int} values
+ */
+
+ 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).
+ *
+ * @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)}.
+ *
+ * @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}
+ */
+ 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.
+ *
+ * @implNote The default implementation produces a sequential stream
+ * that repeatedly calls {@code nextInt()}.
+ *
+ * @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
+ */
+ 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).
+ *
+ * @implNote The default implementation produces a sequential stream
+ * that repeatedly calls {@code nextInt(randomNumberOrigin, randomNumberBound)}.
+ *
+ * @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}
+ */
+ 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.
+ *
+ * @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()}.
+ *
+ * @return a stream of pseudorandomly chosen {@code long} values
+ */
+
+ 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).
+ *
+ * @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)}.
+ *
+ * @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}
+ */
+ 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.
+ *
+ * @implNote The default implementation produces a sequential stream
+ * that repeatedly calls {@code nextLong()}.
+ *
+ * @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
+ */
+ 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).
+ *
+ * @implNote The default implementation produces a sequential stream
+ * that repeatedly calls {@code nextLong(randomNumberOrigin, randomNumberBound)}.
+ *
+ * @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}
+ */
+ 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).
+ *
+ * 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).
+ *
+ * @implNote The default implementation simply calls
+ * {@code RngSupport.checkBound(bound)} and then
+ * {@code RngSupport.boundedNextFloat(this, bound)}.
+ *
+ * @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
+ */
+ 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).
+ *
+ * @implNote The default implementation simply calls
+ * {@code RngSupport.checkRange(origin, bound)} and then
+ * {@code RngSupport.boundedNextFloat(this, origin, bound)}.
+ *
+ * @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}
+ */
+ 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).
+ *
+ * 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).
+ *
+ * @implNote The default implementation simply calls
+ * {@code RngSupport.checkBound(bound)} and then
+ * {@code RngSupport.boundedNextDouble(this, bound)}.
+ *
+ * @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
+ */
+ 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).
+ *
+ * @implNote The default implementation simply calls
+ * {@code RngSupport.checkRange(origin, bound)} and then
+ * {@code RngSupport.boundedNextDouble(this, origin, bound)}.
+ *
+ * @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}
+ */
+ default double nextDouble(double origin, double bound) {
+ RngSupport.checkRange(origin, bound);
+ return RngSupport.boundedNextDouble(this, origin, bound);
+ }
+
+ /**
+ * Returns a pseudorandomly chosen {@code int} value.
+ *
+ * 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).
+ *
+ * @implNote The default implementation simply calls
+ * {@code RngSupport.checkBound(bound)} and then
+ * {@code RngSupport.boundedNextInt(this, bound)}.
+ *
+ * @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
+ */
+ 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).
+ *
+ * @implNote The default implementation simply calls
+ * {@code RngSupport.checkRange(origin, bound)} and then
+ * {@code RngSupport.boundedNextInt(this, origin, bound)}.
+ *
+ * @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}
+ */
+ 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).
+ *
+ * @implNote The default implementation simply calls
+ * {@code RngSupport.checkBound(bound)} and then
+ * {@code RngSupport.boundedNextLong(this, bound)}.
+ *
+ * @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
+ */
+ 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).
+ *
+ * @implNote The default implementation simply calls
+ * {@code RngSupport.checkRange(origin, bound)} and then
+ * {@code RngSupport.boundedNextInt(this, origin, bound)}.
+ *
+ * @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}
+ */
+ 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 of the Gaussian distribution to be drawn from
+ * @return a {@code double} value pseudorandomly chosen from the
+ * specified Gaussian distribution
+ */
+ default double nextGaussian(double mean, double stddev) {
+ return mean + RngSupport.computeNextGaussian(this) * stddev * stddev;
+ }
+
+ /**
+ * 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 {@code Rng} object.
+ *
+ * @return a {@code BigInteger} whose value is the number of
+ * distinct possible states of this {@code Rng} 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);
+}