newrandom/Rng.java
branchbriangoetz-test-branch
changeset 57369 6d87e9f7a1ec
equal deleted inserted replaced
57366:c646b256fbcc 57369:6d87e9f7a1ec
       
     1 /*
       
     2  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
       
     3  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
       
     4  *
       
     5  *
       
     6  *
       
     7  *
       
     8  *
       
     9  *
       
    10  *
       
    11  *
       
    12  *
       
    13  *
       
    14  *
       
    15  *
       
    16  *
       
    17  *
       
    18  *
       
    19  *
       
    20  *
       
    21  *
       
    22  *
       
    23  *
       
    24  */
       
    25 // package java.util;
       
    26 
       
    27 import java.math.BigInteger;
       
    28 import java.util.stream.DoubleStream;
       
    29 import java.util.stream.IntStream;
       
    30 import java.util.stream.LongStream;
       
    31 
       
    32 /**
       
    33  * The {@code Rng} interface is designed to provide a common protocol
       
    34  * for objects that generate random or (more typically) pseudorandom
       
    35  * sequences of numbers (or Boolean values).  Such a sequence may be
       
    36  * obtained by either repeatedly invoking a method that returns a
       
    37  * single (pseudo)randomly chosen value, or by invoking a method that
       
    38  * returns a stream of (pseudo)randomly chosen values.
       
    39  *
       
    40  * <p>Ideally, given an implicitly or explicitly specified range of values,
       
    41  * each value would be chosen independently and uniformly from that range.
       
    42  * In practice, one may have to settle for some approximation to independence
       
    43  * and uniformity.
       
    44  *
       
    45  * <p>In the case of {@code int}, {@code long}, and {@code Boolean}
       
    46  * values, if there is no explicit specification of range, then the
       
    47  * range includes all possible values of the type.  In the case of
       
    48  * {@code float} and {@code double} values, a value is always chosen
       
    49  * from the set of 2<sup><it>w</it></sup> values between 0.0 (inclusive)
       
    50  * and 1.0 (exclusive), where <it>w</it> is 23 for {@code float}
       
    51  * values and 52 for {@code double} values, such that adjacent values
       
    52  * differ by 2<sup>&minus;<it>w</it></sup>; if an explicit range is
       
    53  * specified, then the chosen number is computationally scaled and
       
    54  * translated so as to appear to have been chosen from that range.
       
    55  *
       
    56  * <p>Each method that returns a stream produces a stream of values each of
       
    57  * which is chosen in the same manner as for a method that
       
    58  * returns a single (pseudo)randomly chosen value.  For example, if {@code r}
       
    59  * implements {@code Rng}, then the method call {@code r.ints(100)} returns
       
    60  * a stream of 100 {@code int} values.  These are not necessarily the exact
       
    61  * same values that would have been returned if instead {@code r.nextInt()}
       
    62  * had been called 100 times; all that is guaranteed is that each value in
       
    63  * the stream is chosen in a similar (pseudo)random manner from the same range.
       
    64  *
       
    65  * <p>Every object that implements the {@code Rng} interface is assumed
       
    66  * to contain a finite amount of state.  Using such an object to
       
    67  * generate a pseudorandomly chosen value alters its state.  The
       
    68  * number of distinct possible states of such an object is called its
       
    69  * <it>period</it>.  (Some implementations of the {@code Rng} interface
       
    70  * may be truly random rather than pseudorandom, for example relying
       
    71  * on the statistical behavior of a physical object to derive chosen
       
    72  * values.  Such implementations do not have a fixed period.)
       
    73  *
       
    74  * <p>As a rule, objects that implement the {@code Rng} interface need not
       
    75  * be thread-safe.  It is recommended that multithreaded applications
       
    76  * use either {@code ThreadLocalRandom} or (preferably) pseudorandom
       
    77  * number generators that implement the {@code SplittableRng} or
       
    78  * {@code JumpableRng} interface.
       
    79 
       
    80  * To implement this interface, a class only needs to provide concrete
       
    81  * definitions for the methods {@code nextLong()} and {@code period()}.
       
    82  * Default implementations are provided for all other methods
       
    83  * (but it may be desirable to override some of them, especially
       
    84  * {@code nextInt()} if the underlying algorithm is {@code int}-based).
       
    85  * Moerover, it may be preferable instead to implement another interface
       
    86  * such as {@link java.util.JumpableRng} or {@link java.util.LeapableRng},
       
    87  * or to extend an abstract class such as {@link java.util.AbstractSplittableRng}
       
    88  * or {@link java.util.AbstractArbitrarilyJumpableRng}.
       
    89  *
       
    90  * <p>Objects that implement {@code java.util.Rng} are typically
       
    91  * not cryptographically secure.  Consider instead using
       
    92  * {@link java.security.SecureRandom} to get a cryptographically
       
    93  * secure pseudorandom number generator for use by
       
    94  * security-sensitive applications.  Note, however, that
       
    95  * {@code java.security.SecureRandom} does implement the {@code Rng}
       
    96  * interface, so that instances of {@code java.security.SecureRandom}
       
    97  * may be used interchangeably with other types of pseudorandom
       
    98  * generators in applications that do not require a secure generator.
       
    99  *
       
   100  * @author  Guy Steele
       
   101  * @since   1.9
       
   102  */
       
   103 
       
   104 interface Rng {
       
   105 
       
   106     /**
       
   107      * Returns an effectively unlimited stream of pseudorandomly chosen
       
   108      * {@code double} values.
       
   109      *
       
   110      * @implNote It is permitted to implement this method in a manner
       
   111      * equivalent to {@code doubles(Long.MAX_VALUE)}.
       
   112      *
       
   113      * @implNote The default implementation produces a sequential stream
       
   114      * that repeatedly calls {@code nextDouble()}.
       
   115      *
       
   116      * @return a stream of pseudorandomly chosen {@code double} values
       
   117      */
       
   118 
       
   119     default DoubleStream doubles() {
       
   120         return DoubleStream.generate(this::nextDouble).sequential();
       
   121     }
       
   122 
       
   123     /**
       
   124      * Returns an effectively unlimited stream of pseudorandomly chosen
       
   125      * {@code double} values, where each value is between the specified
       
   126      * origin (inclusive) and the specified bound (exclusive).
       
   127      *
       
   128      * @implNote It is permitted to implement this method in a manner
       
   129      *           equivalent to 
       
   130      * {@code doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
       
   131      *
       
   132      * @implNote The default implementation produces a sequential stream
       
   133      * that repeatedly calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}.
       
   134      *
       
   135      * @param randomNumberOrigin the least value that can be produced
       
   136      * @param randomNumberBound the upper bound (exclusive) for each value produced
       
   137      * @return a stream of pseudorandomly chosen {@code double} values, each between
       
   138      *         the specified origin (inclusive) and the specified bound (exclusive)
       
   139      * @throws IllegalArgumentException if {@code randomNumberOrigin}
       
   140      *         is greater than or equal to {@code randomNumberBound}
       
   141      */
       
   142     default DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
       
   143 	RngSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   144         return DoubleStream.generate(() -> nextDouble(randomNumberOrigin, randomNumberBound)).sequential();
       
   145     }
       
   146 
       
   147     /**
       
   148      * Returns a stream producing the given {@code streamSize} number of
       
   149      * pseudorandomly chosen {@code double} values.
       
   150      *
       
   151      * @implNote The default implementation produces a sequential stream
       
   152      * that repeatedly calls {@code nextDouble()}.
       
   153      *
       
   154      * @param streamSize the number of values to generate
       
   155      * @return a stream of pseudorandomly chosen {@code double} values
       
   156      * @throws IllegalArgumentException if {@code streamSize} is
       
   157      *         less than zero
       
   158      */
       
   159     default DoubleStream doubles(long streamSize) {
       
   160 	RngSupport.checkStreamSize(streamSize);
       
   161 	return doubles().limit(streamSize);
       
   162     }
       
   163 
       
   164     /**
       
   165      * Returns a stream producing the given {@code streamSize} number of
       
   166      * pseudorandomly chosen {@code double} values, where each value is between
       
   167      * the specified origin (inclusive) and the specified bound (exclusive).
       
   168      *
       
   169      * @implNote The default implementation produces a sequential stream
       
   170      * that repeatedly calls {@code nextDouble(randomNumberOrigin, randomNumberBound)}.
       
   171      *
       
   172      * @param streamSize the number of values to generate
       
   173      * @param randomNumberOrigin the least value that can be produced
       
   174      * @param randomNumberBound the upper bound (exclusive) for each value produced
       
   175      * @return a stream of pseudorandomly chosen {@code double} values, each between
       
   176      *         the specified origin (inclusive) and the specified bound (exclusive)
       
   177      * @throws IllegalArgumentException if {@code streamSize} is
       
   178      *         less than zero, or {@code randomNumberOrigin}
       
   179      *         is greater than or equal to {@code randomNumberBound}
       
   180      */
       
   181     default DoubleStream doubles(long streamSize, double randomNumberOrigin,
       
   182 			  double randomNumberBound) {
       
   183 	RngSupport.checkStreamSize(streamSize);
       
   184 	RngSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   185 	return doubles(randomNumberOrigin, randomNumberBound).limit(streamSize);
       
   186     }
       
   187    
       
   188     /**
       
   189      * Returns an effectively unlimited stream of pseudorandomly chosen
       
   190      * {@code int} values.
       
   191      *
       
   192      * @implNote It is permitted to implement this method in a manner
       
   193      * equivalent to {@code ints(Long.MAX_VALUE)}.
       
   194      *
       
   195      * @implNote The default implementation produces a sequential stream
       
   196      * that repeatedly calls {@code nextInt()}.
       
   197      *
       
   198      * @return a stream of pseudorandomly chosen {@code int} values
       
   199      */
       
   200 
       
   201     default IntStream ints() {
       
   202         return IntStream.generate(this::nextInt).sequential();
       
   203     }
       
   204 
       
   205     /**
       
   206      * Returns an effectively unlimited stream of pseudorandomly chosen
       
   207      * {@code int} values, where each value is between the specified
       
   208      * origin (inclusive) and the specified bound (exclusive).
       
   209      *
       
   210      * @implNote It is permitted to implement this method in a manner
       
   211      *           equivalent to 
       
   212      * {@code ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
       
   213      *
       
   214      * @implNote The default implementation produces a sequential stream
       
   215      * that repeatedly calls {@code nextInt(randomNumberOrigin, randomNumberBound)}.
       
   216      *
       
   217      * @param randomNumberOrigin the least value that can be produced
       
   218      * @param randomNumberBound the upper bound (exclusive) for each value produced
       
   219      * @return a stream of pseudorandomly chosen {@code int} values, each between
       
   220      *         the specified origin (inclusive) and the specified bound (exclusive)
       
   221      * @throws IllegalArgumentException if {@code randomNumberOrigin}
       
   222      *         is greater than or equal to {@code randomNumberBound}
       
   223      */
       
   224     default IntStream ints(int randomNumberOrigin, int randomNumberBound) {
       
   225 	RngSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   226         return IntStream.generate(() -> nextInt(randomNumberOrigin, randomNumberBound)).sequential();
       
   227     }
       
   228 
       
   229     /**
       
   230      * Returns a stream producing the given {@code streamSize} number of
       
   231      * pseudorandomly chosen {@code int} values.
       
   232      *
       
   233      * @implNote The default implementation produces a sequential stream
       
   234      * that repeatedly calls {@code nextInt()}.
       
   235      *
       
   236      * @param streamSize the number of values to generate
       
   237      * @return a stream of pseudorandomly chosen {@code int} values
       
   238      * @throws IllegalArgumentException if {@code streamSize} is
       
   239      *         less than zero
       
   240      */
       
   241     default IntStream ints(long streamSize) {
       
   242 	RngSupport.checkStreamSize(streamSize);
       
   243 	return ints().limit(streamSize);
       
   244     }
       
   245 
       
   246     /**
       
   247      * Returns a stream producing the given {@code streamSize} number of
       
   248      * pseudorandomly chosen {@code int} values, where each value is between
       
   249      * the specified origin (inclusive) and the specified bound (exclusive).
       
   250      *
       
   251      * @implNote The default implementation produces a sequential stream
       
   252      * that repeatedly calls {@code nextInt(randomNumberOrigin, randomNumberBound)}.
       
   253      *
       
   254      * @param streamSize the number of values to generate
       
   255      * @param randomNumberOrigin the least value that can be produced
       
   256      * @param randomNumberBound the upper bound (exclusive) for each value produced
       
   257      * @return a stream of pseudorandomly chosen {@code int} values, each between
       
   258      *         the specified origin (inclusive) and the specified bound (exclusive)
       
   259      * @throws IllegalArgumentException if {@code streamSize} is
       
   260      *         less than zero, or {@code randomNumberOrigin}
       
   261      *         is greater than or equal to {@code randomNumberBound}
       
   262      */
       
   263     default IntStream ints(long streamSize, int randomNumberOrigin,
       
   264 			  int randomNumberBound) {
       
   265 	RngSupport.checkStreamSize(streamSize);
       
   266 	RngSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   267 	return ints(randomNumberOrigin, randomNumberBound).limit(streamSize);
       
   268     }
       
   269 
       
   270     /**
       
   271      * Returns an effectively unlimited stream of pseudorandomly chosen
       
   272      * {@code long} values.
       
   273      *
       
   274      * @implNote It is permitted to implement this method in a manner
       
   275      * equivalent to {@code longs(Long.MAX_VALUE)}.
       
   276      *
       
   277      * @implNote The default implementation produces a sequential stream
       
   278      * that repeatedly calls {@code nextLong()}.
       
   279      *
       
   280      * @return a stream of pseudorandomly chosen {@code long} values
       
   281      */
       
   282 
       
   283     default LongStream longs() {
       
   284         return LongStream.generate(this::nextLong).sequential();
       
   285     }
       
   286 
       
   287     /**
       
   288      * Returns an effectively unlimited stream of pseudorandomly chosen
       
   289      * {@code long} values, where each value is between the specified
       
   290      * origin (inclusive) and the specified bound (exclusive).
       
   291      *
       
   292      * @implNote It is permitted to implement this method in a manner
       
   293      *           equivalent to 
       
   294      * {@code longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
       
   295      *
       
   296      * @implNote The default implementation produces a sequential stream
       
   297      * that repeatedly calls {@code nextLong(randomNumberOrigin, randomNumberBound)}.
       
   298      *
       
   299      * @param randomNumberOrigin the least value that can be produced
       
   300      * @param randomNumberBound the upper bound (exclusive) for each value produced
       
   301      * @return a stream of pseudorandomly chosen {@code long} values, each between
       
   302      *         the specified origin (inclusive) and the specified bound (exclusive)
       
   303      * @throws IllegalArgumentException if {@code randomNumberOrigin}
       
   304      *         is greater than or equal to {@code randomNumberBound}
       
   305      */
       
   306     default LongStream longs(long randomNumberOrigin, long randomNumberBound) {
       
   307 	RngSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   308         return LongStream.generate(() -> nextLong(randomNumberOrigin, randomNumberBound)).sequential();
       
   309     }
       
   310 
       
   311     /**
       
   312      * Returns a stream producing the given {@code streamSize} number of
       
   313      * pseudorandomly chosen {@code long} values.
       
   314      *
       
   315      * @implNote The default implementation produces a sequential stream
       
   316      * that repeatedly calls {@code nextLong()}.
       
   317      *
       
   318      * @param streamSize the number of values to generate
       
   319      * @return a stream of pseudorandomly chosen {@code long} values
       
   320      * @throws IllegalArgumentException if {@code streamSize} is
       
   321      *         less than zero
       
   322      */
       
   323     default LongStream longs(long streamSize) {
       
   324 	RngSupport.checkStreamSize(streamSize);
       
   325 	return longs().limit(streamSize);
       
   326     }
       
   327 
       
   328     /**
       
   329      * Returns a stream producing the given {@code streamSize} number of
       
   330      * pseudorandomly chosen {@code long} values, where each value is between
       
   331      * the specified origin (inclusive) and the specified bound (exclusive).
       
   332      *
       
   333      * @implNote The default implementation produces a sequential stream
       
   334      * that repeatedly calls {@code nextLong(randomNumberOrigin, randomNumberBound)}.
       
   335      *
       
   336      * @param streamSize the number of values to generate
       
   337      * @param randomNumberOrigin the least value that can be produced
       
   338      * @param randomNumberBound the upper bound (exclusive) for each value produced
       
   339      * @return a stream of pseudorandomly chosen {@code long} values, each between
       
   340      *         the specified origin (inclusive) and the specified bound (exclusive)
       
   341      * @throws IllegalArgumentException if {@code streamSize} is
       
   342      *         less than zero, or {@code randomNumberOrigin}
       
   343      *         is greater than or equal to {@code randomNumberBound}
       
   344      */
       
   345     default LongStream longs(long streamSize, long randomNumberOrigin,
       
   346 			  long randomNumberBound) {
       
   347 	RngSupport.checkStreamSize(streamSize);
       
   348 	RngSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
   349 	return longs(randomNumberOrigin, randomNumberBound).limit(streamSize);
       
   350     }
       
   351 
       
   352     /**
       
   353      * Returns a pseudorandomly chosen {@code boolean} value.
       
   354      *
       
   355      * <p>The default implementation tests the high-order bit (sign bit)
       
   356      * of a value produced by {@code nextInt()}, on the grounds
       
   357      * that some algorithms for pseudorandom number generation
       
   358      * produce values whose high-order bits have better
       
   359      * statistical quality than the low-order bits.
       
   360      *
       
   361      * @return a pseudorandomly chosen {@code boolean} value
       
   362      */
       
   363     default boolean nextBoolean() {
       
   364         return nextInt() < 0;
       
   365     }
       
   366 
       
   367     /**
       
   368      * Returns a pseudorandom {@code float} value between zero
       
   369      * (inclusive) and one (exclusive).
       
   370      *
       
   371      * The default implementation uses the 24 high-order bits
       
   372      * from a call to {@code nextInt()}.
       
   373      *
       
   374      * @return a pseudorandom {@code float} value between zero
       
   375      *         (inclusive) and one (exclusive)
       
   376      */
       
   377     default float nextFloat() {
       
   378         return (nextInt() >>> 8) * 0x1.0p-24f;
       
   379     }
       
   380 
       
   381     /**
       
   382      * Returns a pseudorandomly chosen {@code float} value between zero
       
   383      * (inclusive) and the specified bound (exclusive).
       
   384      *
       
   385      * @implNote The default implementation simply calls
       
   386      *     {@code RngSupport.checkBound(bound)} and then
       
   387      *     {@code RngSupport.boundedNextFloat(this, bound)}.
       
   388      *
       
   389      * @param bound the upper bound (exclusive) for the returned value.
       
   390      *        Must be positive and finite
       
   391      * @return a pseudorandomly chosen {@code float} value between
       
   392      *         zero (inclusive) and the bound (exclusive)
       
   393      * @throws IllegalArgumentException if {@code bound} is not
       
   394      *         positive and finite
       
   395      */
       
   396     default float nextFloat(float bound) {
       
   397 	RngSupport.checkBound(bound);
       
   398 	return RngSupport.boundedNextFloat(this, bound);
       
   399     }
       
   400 
       
   401     /**
       
   402      * Returns a pseudorandomly chosen {@code float} value between the
       
   403      * specified origin (inclusive) and the specified bound (exclusive).
       
   404      *
       
   405      * @implNote The default implementation simply calls
       
   406      *     {@code RngSupport.checkRange(origin, bound)} and then
       
   407      *     {@code RngSupport.boundedNextFloat(this, origin, bound)}.
       
   408      *
       
   409      * @param origin the least value that can be returned
       
   410      * @param bound the upper bound (exclusive)
       
   411      * @return a pseudorandomly chosen {@code float} value between the
       
   412      *         origin (inclusive) and the bound (exclusive)
       
   413      * @throws IllegalArgumentException unless {@code origin} is finite,
       
   414      *         {@code bound} is finite, and {@code origin} is less than
       
   415      *         {@code bound}
       
   416      */
       
   417     default float nextFloat(float origin, float bound) {
       
   418 	RngSupport.checkRange(origin, bound);
       
   419         return RngSupport.boundedNextFloat(this, origin, bound);
       
   420     }
       
   421 
       
   422     /**
       
   423      * Returns a pseudorandom {@code double} value between zero
       
   424      * (inclusive) and one (exclusive).
       
   425      *
       
   426      * The default implementation uses the 53 high-order bits
       
   427      * from a call to {@code nextLong()}.
       
   428      *
       
   429      * @return a pseudorandom {@code double} value between zero
       
   430      *         (inclusive) and one (exclusive)
       
   431      */
       
   432     default double nextDouble() {
       
   433         return (nextLong() >>> 11) * 0x1.0p-53;
       
   434     }
       
   435 
       
   436     /**
       
   437      * Returns a pseudorandomly chosen {@code double} value between zero
       
   438      * (inclusive) and the specified bound (exclusive).
       
   439      *
       
   440      * @implNote The default implementation simply calls
       
   441      *     {@code RngSupport.checkBound(bound)} and then
       
   442      *     {@code RngSupport.boundedNextDouble(this, bound)}.
       
   443      *
       
   444      * @param bound the upper bound (exclusive) for the returned value.
       
   445      *        Must be positive and finite
       
   446      * @return a pseudorandomly chosen {@code double} value between
       
   447      *         zero (inclusive) and the bound (exclusive)
       
   448      * @throws IllegalArgumentException if {@code bound} is not
       
   449      *         positive and finite
       
   450      */
       
   451     default double nextDouble(double bound) {
       
   452 	RngSupport.checkBound(bound);
       
   453 	return RngSupport.boundedNextDouble(this, bound);
       
   454     }
       
   455 
       
   456     /**
       
   457      * Returns a pseudorandomly chosen {@code double} value between the
       
   458      * specified origin (inclusive) and the specified bound (exclusive).
       
   459      *
       
   460      * @implNote The default implementation simply calls
       
   461      *     {@code RngSupport.checkRange(origin, bound)} and then
       
   462      *     {@code RngSupport.boundedNextDouble(this, origin, bound)}.
       
   463      *
       
   464      * @param origin the least value that can be returned
       
   465      * @param bound the upper bound (exclusive) for the returned value
       
   466      * @return a pseudorandomly chosen {@code double} value between the
       
   467      *         origin (inclusive) and the bound (exclusive)
       
   468      * @throws IllegalArgumentException unless {@code origin} is finite,
       
   469      *         {@code bound} is finite, and {@code origin} is less than
       
   470      *         {@code bound}
       
   471      */
       
   472     default double nextDouble(double origin, double bound) {
       
   473 	RngSupport.checkRange(origin, bound);
       
   474         return RngSupport.boundedNextDouble(this, origin, bound);
       
   475     }
       
   476 
       
   477     /**
       
   478      * Returns a pseudorandomly chosen {@code int} value.
       
   479      *
       
   480      * The default implementation uses the 32 high-order bits
       
   481      * from a call to {@code nextLong()}.
       
   482      *
       
   483      * @return a pseudorandomly chosen {@code int} value
       
   484      */
       
   485     default public int nextInt() {
       
   486 	return (int)(nextLong() >>> 32);
       
   487     }
       
   488 
       
   489     /**
       
   490      * Returns a pseudorandomly chosen {@code int} value between
       
   491      * zero (inclusive) and the specified bound (exclusive).
       
   492      *
       
   493      * @implNote The default implementation simply calls
       
   494      *     {@code RngSupport.checkBound(bound)} and then
       
   495      *     {@code RngSupport.boundedNextInt(this, bound)}.
       
   496      *
       
   497      * @param bound the upper bound (exclusive) for the returned value.  Must be positive.
       
   498      * @return a pseudorandomly chosen {@code int} value between
       
   499      *         zero (inclusive) and the bound (exclusive)
       
   500      * @throws IllegalArgumentException if {@code bound} is not positive
       
   501      */
       
   502     default int nextInt(int bound) {
       
   503 	RngSupport.checkBound(bound);
       
   504 	return RngSupport.boundedNextInt(this, bound);
       
   505     }
       
   506 
       
   507     /**
       
   508      * Returns a pseudorandomly chosen {@code int} value between the
       
   509      * specified origin (inclusive) and the specified bound (exclusive).
       
   510      *
       
   511      * @implNote The default implementation simply calls
       
   512      *     {@code RngSupport.checkRange(origin, bound)} and then
       
   513      *     {@code RngSupport.boundedNextInt(this, origin, bound)}.
       
   514      *
       
   515      * @param origin the least value that can be returned
       
   516      * @param bound the upper bound (exclusive) for the returned value
       
   517      * @return a pseudorandomly chosen {@code int} value between the
       
   518      *         origin (inclusive) and the bound (exclusive)
       
   519      * @throws IllegalArgumentException if {@code origin} is greater than
       
   520      *         or equal to {@code bound}
       
   521      */
       
   522     default int nextInt(int origin, int bound) {
       
   523 	RngSupport.checkRange(origin, bound);
       
   524         return RngSupport.boundedNextInt(this, origin, bound);
       
   525     }
       
   526 
       
   527     /**
       
   528      * Returns a pseudorandomly chosen {@code long} value.
       
   529      *
       
   530      * @return a pseudorandomly chosen {@code long} value
       
   531      */
       
   532     long nextLong();
       
   533 
       
   534     /**
       
   535      * Returns a pseudorandomly chosen {@code long} value between
       
   536      * zero (inclusive) and the specified bound (exclusive).
       
   537      *
       
   538      * @implNote The default implementation simply calls
       
   539      *     {@code RngSupport.checkBound(bound)} and then
       
   540      *     {@code RngSupport.boundedNextLong(this, bound)}.
       
   541      *
       
   542      * @param bound the upper bound (exclusive) for the returned value.  Must be positive.
       
   543      * @return a pseudorandomly chosen {@code long} value between
       
   544      *         zero (inclusive) and the bound (exclusive)
       
   545      * @throws IllegalArgumentException if {@code bound} is not positive
       
   546      */
       
   547     default long nextLong(long bound) {
       
   548 	RngSupport.checkBound(bound);
       
   549 	return RngSupport.boundedNextLong(this, bound);
       
   550     }
       
   551 
       
   552     /**
       
   553      * Returns a pseudorandomly chosen {@code long} value between the
       
   554      * specified origin (inclusive) and the specified bound (exclusive).
       
   555      *
       
   556      * @implNote The default implementation simply calls
       
   557      *     {@code RngSupport.checkRange(origin, bound)} and then
       
   558      *     {@code RngSupport.boundedNextInt(this, origin, bound)}.
       
   559      *
       
   560      * @param origin the least value that can be returned
       
   561      * @param bound the upper bound (exclusive) for the returned value
       
   562      * @return a pseudorandomly chosen {@code long} value between the
       
   563      *         origin (inclusive) and the bound (exclusive)
       
   564      * @throws IllegalArgumentException if {@code origin} is greater than
       
   565      *         or equal to {@code bound}
       
   566      */
       
   567     default long nextLong(long origin, long bound) {
       
   568 	RngSupport.checkRange(origin, bound);
       
   569         return RngSupport.boundedNextLong(this, origin, bound);
       
   570     }
       
   571     
       
   572     /**
       
   573      * Returns a {@code double} value pseudorandomly chosen from
       
   574      * a Gaussian (normal) distribution whose mean is 0 and whose
       
   575      * standard deviation is 1.
       
   576      *
       
   577      * @return a {@code double} value pseudorandomly chosen from a
       
   578      *         Gaussian distribution
       
   579      */
       
   580     default double nextGaussian() {
       
   581 	return RngSupport.computeNextGaussian(this);
       
   582     }
       
   583 
       
   584     /**
       
   585      * Returns a {@code double} value pseudorandomly chosen from
       
   586      * a Gaussian (normal) distribution with a mean and
       
   587      * standard deviation specified by the arguments.
       
   588      *
       
   589      * @param mean the mean of the Gaussian distribution to be drawn from
       
   590      * @param stddev the standard deviation of the Gaussian distribution to be drawn from
       
   591      * @return a {@code double} value pseudorandomly chosen from the
       
   592      *         specified Gaussian distribution
       
   593      */
       
   594     default double nextGaussian(double mean, double stddev) {
       
   595 	return mean + RngSupport.computeNextGaussian(this) * stddev * stddev;
       
   596     }
       
   597 
       
   598     /**
       
   599      * Returns a nonnegative {@code double} value pseudorandomly chosen
       
   600      * from an exponential distribution whose mean is 1.
       
   601      *
       
   602      * @return a nonnegative {@code double} value pseudorandomly chosen from an
       
   603      *         exponential distribution
       
   604      */
       
   605     default double nextExponential() {
       
   606 	return RngSupport.computeNextExponential(this);
       
   607     }
       
   608 
       
   609     
       
   610     /**
       
   611      * Returns the period of this {@code Rng} object.
       
   612      *
       
   613      * @return a {@code BigInteger} whose value is the number of
       
   614      *         distinct possible states of this {@code Rng} object,
       
   615      *         or 0 if unknown, or negative if extremely large.
       
   616      */
       
   617     BigInteger period();
       
   618 
       
   619     /**
       
   620      * The value (0) returned by the {@code period()} method if the period is unknown.
       
   621      */
       
   622     static final BigInteger UNKNOWN_PERIOD = BigInteger.ZERO;
       
   623 
       
   624     /**
       
   625      * The (negative) value returned by the {@code period()} method if this generator
       
   626      * has no period because it is truly random rather than just pseudorandom.
       
   627      */
       
   628     static final BigInteger TRULY_RANDOM = BigInteger.valueOf(-1);
       
   629 
       
   630     /**
       
   631      * The (negative) value that may be returned by the {@code period()} method
       
   632      * if this generator has a huge period (larger than 2**(2**16)).
       
   633      */
       
   634     static final BigInteger HUGE_PERIOD = BigInteger.valueOf(-2);
       
   635 }