src/java.base/share/classes/java/util/SplittableRandom.java
branchJDK-8193209-branch
changeset 59086 214afc7a1e02
parent 52957 c7c285b0b640
equal deleted inserted replaced
59085:c660730af328 59086:214afc7a1e02
     1 /*
     1 /*
     2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    20  *
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
       
    26 package java.util;
    25 package java.util;
    27 
    26 
       
    27 import java.math.BigInteger;
    28 import java.util.concurrent.atomic.AtomicLong;
    28 import java.util.concurrent.atomic.AtomicLong;
    29 import java.util.function.DoubleConsumer;
    29 import java.util.random.RandomGenerator.SplittableGenerator;
    30 import java.util.function.IntConsumer;
    30 import java.util.random.RandomSupport;
    31 import java.util.function.LongConsumer;
    31 import java.util.random.RandomSupport.AbstractSplittableGenerator;
    32 import java.util.stream.DoubleStream;
       
    33 import java.util.stream.IntStream;
       
    34 import java.util.stream.LongStream;
       
    35 import java.util.stream.StreamSupport;
       
    36 
    32 
    37 /**
    33 /**
    38  * A generator of uniform pseudorandom values applicable for use in
    34  * A generator of uniform pseudorandom values applicable for use in
    39  * (among other contexts) isolated parallel computations that may
    35  * (among other contexts) isolated parallel computations that may
    40  * generate subtasks. Class {@code SplittableRandom} supports methods for
    36  * generate subtasks. Class {@code SplittableRandom} supports methods for
    50  * href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> version
    46  * href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> version
    51  * 3.31.1</a>.) These tests validate only the methods for certain
    47  * 3.31.1</a>.) These tests validate only the methods for certain
    52  * types and ranges, but similar properties are expected to hold, at
    48  * types and ranges, but similar properties are expected to hold, at
    53  * least approximately, for others as well. The <em>period</em>
    49  * least approximately, for others as well. The <em>period</em>
    54  * (length of any series of generated values before it repeats) is at
    50  * (length of any series of generated values before it repeats) is at
    55  * least 2<sup>64</sup>.
    51  * least 2<sup>64</sup>. </li>
    56  *
    52  *
    57  * <li>Method {@link #split} constructs and returns a new
    53  * <li> Method {@link #split} constructs and returns a new
    58  * SplittableRandom instance that shares no mutable state with the
    54  * SplittableRandom instance that shares no mutable state with the
    59  * current instance. However, with very high probability, the
    55  * current instance. However, with very high probability, the
    60  * values collectively generated by the two objects have the same
    56  * values collectively generated by the two objects have the same
    61  * statistical properties as if the same quantity of values were
    57  * statistical properties as if the same quantity of values were
    62  * generated by a single thread using a single {@code
    58  * generated by a single thread using a single {@code
    63  * SplittableRandom} object.
    59  * SplittableRandom} object.  </li>
    64  *
    60  *
    65  * <li>Instances of SplittableRandom are <em>not</em> thread-safe.
    61  * <li>Instances of SplittableRandom are <em>not</em> thread-safe.
    66  * They are designed to be split, not shared, across threads. For
    62  * They are designed to be split, not shared, across threads. For
    67  * example, a {@link java.util.concurrent.ForkJoinTask
    63  * example, a {@link java.util.concurrent.ForkJoinTask
    68  * fork/join-style} computation using random numbers might include a
    64  * fork/join-style} computation using random numbers might include a
    69  * construction of the form {@code new
    65  * construction of the form {@code new
    70  * Subtask(aSplittableRandom.split()).fork()}.
    66  * Subtask(aSplittableRandom.split()).fork()}.
    71  *
    67  *
    72  * <li>This class provides additional methods for generating random
    68  * <li>This class provides additional methods for generating random
    73  * streams, that employ the above techniques when used in {@code
    69  * streams, that employ the above techniques when used in {@code
    74  * stream.parallel()} mode.
    70  * stream.parallel()} mode.</li>
    75  *
    71  *
    76  * </ul>
    72  * </ul>
    77  *
    73  *
    78  * <p>Instances of {@code SplittableRandom} are not cryptographically
    74  * <p>Instances of {@code SplittableRandom} are not cryptographically
    79  * secure.  Consider instead using {@link java.security.SecureRandom}
    75  * secure.  Consider instead using {@link java.security.SecureRandom}
    80  * in security-sensitive applications. Additionally,
    76  * in security-sensitive applications. Additionally,
    81  * default-constructed instances do not use a cryptographically random
    77  * default-constructed instances do not use a cryptographically random
    82  * seed unless the {@linkplain System#getProperty system property}
    78  * seed unless the {@linkplain System#getProperty system property}
    83  * {@systemProperty java.util.secureRandomSeed} is set to {@code true}.
    79  * {@code java.util.secureRandomSeed} is set to {@code true}.
    84  *
    80  *
    85  * @author  Guy Steele
    81  * @author  Guy Steele
    86  * @author  Doug Lea
    82  * @author  Doug Lea
    87  * @since   1.8
    83  * @since   1.8
    88  */
    84  */
    89 public final class SplittableRandom {
    85 public final class SplittableRandom extends AbstractSplittableGenerator {
    90 
    86 
    91     /*
    87     /*
    92      * Implementation Overview.
    88      * Implementation Overview.
    93      *
    89      *
    94      * This algorithm was inspired by the "DotMix" algorithm by
    90      * This algorithm was inspired by the "DotMix" algorithm by
   159      * value for (unsplit) SplittableRandoms.
   155      * value for (unsplit) SplittableRandoms.
   160      */
   156      */
   161     private static final long GOLDEN_GAMMA = 0x9e3779b97f4a7c15L;
   157     private static final long GOLDEN_GAMMA = 0x9e3779b97f4a7c15L;
   162 
   158 
   163     /**
   159     /**
   164      * The least non-zero value returned by nextDouble(). This value
       
   165      * is scaled by a random value of 53 bits to produce a result.
       
   166      */
       
   167     private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53);
       
   168 
       
   169     /**
       
   170      * The seed. Updated only via method nextSeed.
   160      * The seed. Updated only via method nextSeed.
   171      */
   161      */
   172     private long seed;
   162     private long seed;
   173 
   163 
   174     /**
   164     /**
   184         this.gamma = gamma;
   174         this.gamma = gamma;
   185     }
   175     }
   186 
   176 
   187     /**
   177     /**
   188      * Computes Stafford variant 13 of 64bit mix function.
   178      * Computes Stafford variant 13 of 64bit mix function.
       
   179      * http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html
   189      */
   180      */
   190     private static long mix64(long z) {
   181     private static long mix64(long z) {
   191         z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L;
   182         z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L;
   192         z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
   183         z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
   193         return z ^ (z >>> 31);
   184         return z ^ (z >>> 31);
   194     }
   185     }
   195 
   186 
   196     /**
   187     /**
   197      * Returns the 32 high bits of Stafford variant 4 mix64 function as int.
   188      * Returns the 32 high bits of Stafford variant 4 mix64 function as int.
       
   189      * http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html
   198      */
   190      */
   199     private static int mix32(long z) {
   191     private static int mix32(long z) {
   200         z = (z ^ (z >>> 33)) * 0x62a9d9ed799705f5L;
   192         z = (z ^ (z >>> 33)) * 0x62a9d9ed799705f5L;
   201         return (int)(((z ^ (z >>> 28)) * 0xcb24d0a5c88c35b3L) >>> 32);
   193         return (int)(((z ^ (z >>> 28)) * 0xcb24d0a5c88c35b3L) >>> 32);
   202     }
   194     }
   203 
   195 
   204     /**
   196     /**
   205      * Returns the gamma value to use for a new split instance.
   197      * Returns the gamma value to use for a new split instance.
       
   198      * Uses the 64bit mix function from MurmurHash3.
       
   199      * https://github.com/aappleby/smhasher/wiki/MurmurHash3
   206      */
   200      */
   207     private static long mixGamma(long z) {
   201     private static long mixGamma(long z) {
   208         z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL; // MurmurHash3 mix constants
   202         z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL; // MurmurHash3 mix constants
   209         z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
   203         z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
   210         z = (z ^ (z >>> 33)) | 1L;                  // force to be odd
   204         z = (z ^ (z >>> 33)) | 1L;                  // force to be odd
   217      */
   211      */
   218     private long nextSeed() {
   212     private long nextSeed() {
   219         return seed += gamma;
   213         return seed += gamma;
   220     }
   214     }
   221 
   215 
   222     // IllegalArgumentException messages
       
   223     static final String BAD_BOUND = "bound must be positive";
       
   224     static final String BAD_RANGE = "bound must be greater than origin";
       
   225     static final String BAD_SIZE  = "size must be non-negative";
       
   226 
       
   227     /**
   216     /**
   228      * The seed generator for default constructors.
   217      * The seed generator for default constructors.
   229      */
   218      */
   230     private static final AtomicLong defaultGen
   219     private static final AtomicLong defaultGen = new AtomicLong(RandomSupport.initialSeed());
   231         = new AtomicLong(mix64(System.currentTimeMillis()) ^
       
   232                          mix64(System.nanoTime()));
       
   233 
       
   234     // at end of <clinit> to survive static initialization circularity
       
   235     static {
       
   236         if (java.security.AccessController.doPrivileged(
       
   237             new java.security.PrivilegedAction<Boolean>() {
       
   238                 public Boolean run() {
       
   239                     return Boolean.getBoolean("java.util.secureRandomSeed");
       
   240                 }})) {
       
   241             byte[] seedBytes = java.security.SecureRandom.getSeed(8);
       
   242             long s = (long)seedBytes[0] & 0xffL;
       
   243             for (int i = 1; i < 8; ++i)
       
   244                 s = (s << 8) | ((long)seedBytes[i] & 0xffL);
       
   245             defaultGen.set(s);
       
   246         }
       
   247     }
       
   248 
       
   249     /*
       
   250      * Internal versions of nextX methods used by streams, as well as
       
   251      * the public nextX(origin, bound) methods.  These exist mainly to
       
   252      * avoid the need for multiple versions of stream spliterators
       
   253      * across the different exported forms of streams.
       
   254      */
       
   255 
       
   256     /**
       
   257      * The form of nextLong used by LongStream Spliterators.  If
       
   258      * origin is greater than bound, acts as unbounded form of
       
   259      * nextLong, else as bounded form.
       
   260      *
       
   261      * @param origin the least value, unless greater than bound
       
   262      * @param bound the upper bound (exclusive), must not equal origin
       
   263      * @return a pseudorandom value
       
   264      */
       
   265     final long internalNextLong(long origin, long bound) {
       
   266         /*
       
   267          * Four Cases:
       
   268          *
       
   269          * 1. If the arguments indicate unbounded form, act as
       
   270          * nextLong().
       
   271          *
       
   272          * 2. If the range is an exact power of two, apply the
       
   273          * associated bit mask.
       
   274          *
       
   275          * 3. If the range is positive, loop to avoid potential bias
       
   276          * when the implicit nextLong() bound (2<sup>64</sup>) is not
       
   277          * evenly divisible by the range. The loop rejects candidates
       
   278          * computed from otherwise over-represented values.  The
       
   279          * expected number of iterations under an ideal generator
       
   280          * varies from 1 to 2, depending on the bound. The loop itself
       
   281          * takes an unlovable form. Because the first candidate is
       
   282          * already available, we need a break-in-the-middle
       
   283          * construction, which is concisely but cryptically performed
       
   284          * within the while-condition of a body-less for loop.
       
   285          *
       
   286          * 4. Otherwise, the range cannot be represented as a positive
       
   287          * long.  The loop repeatedly generates unbounded longs until
       
   288          * obtaining a candidate meeting constraints (with an expected
       
   289          * number of iterations of less than two).
       
   290          */
       
   291 
       
   292         long r = mix64(nextSeed());
       
   293         if (origin < bound) {
       
   294             long n = bound - origin, m = n - 1;
       
   295             if ((n & m) == 0L)  // power of two
       
   296                 r = (r & m) + origin;
       
   297             else if (n > 0L) {  // reject over-represented candidates
       
   298                 for (long u = r >>> 1;            // ensure nonnegative
       
   299                      u + m - (r = u % n) < 0L;    // rejection check
       
   300                      u = mix64(nextSeed()) >>> 1) // retry
       
   301                     ;
       
   302                 r += origin;
       
   303             }
       
   304             else {              // range not representable as long
       
   305                 while (r < origin || r >= bound)
       
   306                     r = mix64(nextSeed());
       
   307             }
       
   308         }
       
   309         return r;
       
   310     }
       
   311 
       
   312     /**
       
   313      * The form of nextInt used by IntStream Spliterators.
       
   314      * Exactly the same as long version, except for types.
       
   315      *
       
   316      * @param origin the least value, unless greater than bound
       
   317      * @param bound the upper bound (exclusive), must not equal origin
       
   318      * @return a pseudorandom value
       
   319      */
       
   320     final int internalNextInt(int origin, int bound) {
       
   321         int r = mix32(nextSeed());
       
   322         if (origin < bound) {
       
   323             int n = bound - origin, m = n - 1;
       
   324             if ((n & m) == 0)
       
   325                 r = (r & m) + origin;
       
   326             else if (n > 0) {
       
   327                 for (int u = r >>> 1;
       
   328                      u + m - (r = u % n) < 0;
       
   329                      u = mix32(nextSeed()) >>> 1)
       
   330                     ;
       
   331                 r += origin;
       
   332             }
       
   333             else {
       
   334                 while (r < origin || r >= bound)
       
   335                     r = mix32(nextSeed());
       
   336             }
       
   337         }
       
   338         return r;
       
   339     }
       
   340 
       
   341     /**
       
   342      * The form of nextDouble used by DoubleStream Spliterators.
       
   343      *
       
   344      * @param origin the least value, unless greater than bound
       
   345      * @param bound the upper bound (exclusive), must not equal origin
       
   346      * @return a pseudorandom value
       
   347      */
       
   348     final double internalNextDouble(double origin, double bound) {
       
   349         double r = (nextLong() >>> 11) * DOUBLE_UNIT;
       
   350         if (origin < bound) {
       
   351             r = r * (bound - origin) + origin;
       
   352             if (r >= bound) // correct for rounding
       
   353                 r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
       
   354         }
       
   355         return r;
       
   356     }
       
   357 
   220 
   358     /* ---------------- public methods ---------------- */
   221     /* ---------------- public methods ---------------- */
   359 
   222 
   360     /**
   223     /**
   361      * Creates a new SplittableRandom instance using the specified
   224      * Creates a new SplittableRandom instance using the specified
   373      * generate sequences of values that are statistically independent
   236      * generate sequences of values that are statistically independent
   374      * of those of any other instances in the current program; and
   237      * of those of any other instances in the current program; and
   375      * may, and typically does, vary across program invocations.
   238      * may, and typically does, vary across program invocations.
   376      */
   239      */
   377     public SplittableRandom() { // emulate defaultGen.split()
   240     public SplittableRandom() { // emulate defaultGen.split()
   378         long s = defaultGen.getAndAdd(GOLDEN_GAMMA << 1);
   241         long s = defaultGen.getAndAdd(2 * GOLDEN_GAMMA);
   379         this.seed = mix64(s);
   242         this.seed = mix64(s);
   380         this.gamma = mixGamma(s + GOLDEN_GAMMA);
   243         this.gamma = mixGamma(s + GOLDEN_GAMMA);
   381     }
   244     }
       
   245 
       
   246     //    public SplittableRandom copy() { return new SplittableRandom(seed, gamma); }
   382 
   247 
   383     /**
   248     /**
   384      * Constructs and returns a new SplittableRandom instance that
   249      * Constructs and returns a new SplittableRandom instance that
   385      * shares no mutable state with this instance. However, with very
   250      * shares no mutable state with this instance. However, with very
   386      * high probability, the set of values collectively generated by
   251      * high probability, the set of values collectively generated by
   396      */
   261      */
   397     public SplittableRandom split() {
   262     public SplittableRandom split() {
   398         return new SplittableRandom(nextLong(), mixGamma(nextSeed()));
   263         return new SplittableRandom(nextLong(), mixGamma(nextSeed()));
   399     }
   264     }
   400 
   265 
   401     /**
   266     public SplittableRandom split(SplittableGenerator source) {
   402      * Fills a user-supplied byte array with generated pseudorandom bytes.
   267         return new SplittableRandom(source.nextLong(), mixGamma(source.nextLong()));
   403      *
       
   404      * @param  bytes the byte array to fill with pseudorandom bytes
       
   405      * @throws NullPointerException if bytes is null
       
   406      * @since  10
       
   407      */
       
   408     public void nextBytes(byte[] bytes) {
       
   409         int i = 0;
       
   410         int len = bytes.length;
       
   411         for (int words = len >> 3; words--> 0; ) {
       
   412             long rnd = nextLong();
       
   413             for (int n = 8; n--> 0; rnd >>>= Byte.SIZE)
       
   414                 bytes[i++] = (byte)rnd;
       
   415         }
       
   416         if (i < len)
       
   417             for (long rnd = nextLong(); i < len; rnd >>>= Byte.SIZE)
       
   418                 bytes[i++] = (byte)rnd;
       
   419     }
   268     }
   420 
   269 
   421     /**
   270     /**
   422      * Returns a pseudorandom {@code int} value.
   271      * Returns a pseudorandom {@code int} value.
   423      *
   272      *
   426     public int nextInt() {
   275     public int nextInt() {
   427         return mix32(nextSeed());
   276         return mix32(nextSeed());
   428     }
   277     }
   429 
   278 
   430     /**
   279     /**
   431      * Returns a pseudorandom {@code int} value between zero (inclusive)
       
   432      * and the specified bound (exclusive).
       
   433      *
       
   434      * @param bound the upper bound (exclusive).  Must be positive.
       
   435      * @return a pseudorandom {@code int} value between zero
       
   436      *         (inclusive) and the bound (exclusive)
       
   437      * @throws IllegalArgumentException if {@code bound} is not positive
       
   438      */
       
   439     public int nextInt(int bound) {
       
   440         if (bound <= 0)
       
   441             throw new IllegalArgumentException(BAD_BOUND);
       
   442         // Specialize internalNextInt for origin 0
       
   443         int r = mix32(nextSeed());
       
   444         int m = bound - 1;
       
   445         if ((bound & m) == 0) // power of two
       
   446             r &= m;
       
   447         else { // reject over-represented candidates
       
   448             for (int u = r >>> 1;
       
   449                  u + m - (r = u % bound) < 0;
       
   450                  u = mix32(nextSeed()) >>> 1)
       
   451                 ;
       
   452         }
       
   453         return r;
       
   454     }
       
   455 
       
   456     /**
       
   457      * Returns a pseudorandom {@code int} value between the specified
       
   458      * origin (inclusive) and the specified bound (exclusive).
       
   459      *
       
   460      * @param origin the least value returned
       
   461      * @param bound the upper bound (exclusive)
       
   462      * @return a pseudorandom {@code int} value between the origin
       
   463      *         (inclusive) and the bound (exclusive)
       
   464      * @throws IllegalArgumentException if {@code origin} is greater than
       
   465      *         or equal to {@code bound}
       
   466      */
       
   467     public int nextInt(int origin, int bound) {
       
   468         if (origin >= bound)
       
   469             throw new IllegalArgumentException(BAD_RANGE);
       
   470         return internalNextInt(origin, bound);
       
   471     }
       
   472 
       
   473     /**
       
   474      * Returns a pseudorandom {@code long} value.
   280      * Returns a pseudorandom {@code long} value.
   475      *
   281      *
   476      * @return a pseudorandom {@code long} value
   282      * @return a pseudorandom {@code long} value
   477      */
   283      */
   478     public long nextLong() {
   284     public long nextLong() {
   479         return mix64(nextSeed());
   285         return mix64(nextSeed());
   480     }
   286     }
   481 
   287 
   482     /**
   288     static final BigInteger PERIOD = BigInteger.ONE.shiftLeft(64);  // Period is 2**64
   483      * Returns a pseudorandom {@code long} value between zero (inclusive)
   289 
   484      * and the specified bound (exclusive).
   290     public BigInteger period() {
   485      *
   291         return PERIOD;
   486      * @param bound the upper bound (exclusive).  Must be positive.
       
   487      * @return a pseudorandom {@code long} value between zero
       
   488      *         (inclusive) and the bound (exclusive)
       
   489      * @throws IllegalArgumentException if {@code bound} is not positive
       
   490      */
       
   491     public long nextLong(long bound) {
       
   492         if (bound <= 0)
       
   493             throw new IllegalArgumentException(BAD_BOUND);
       
   494         // Specialize internalNextLong for origin 0
       
   495         long r = mix64(nextSeed());
       
   496         long m = bound - 1;
       
   497         if ((bound & m) == 0L) // power of two
       
   498             r &= m;
       
   499         else { // reject over-represented candidates
       
   500             for (long u = r >>> 1;
       
   501                  u + m - (r = u % bound) < 0L;
       
   502                  u = mix64(nextSeed()) >>> 1)
       
   503                 ;
       
   504         }
       
   505         return r;
       
   506     }
       
   507 
       
   508     /**
       
   509      * Returns a pseudorandom {@code long} value between the specified
       
   510      * origin (inclusive) and the specified bound (exclusive).
       
   511      *
       
   512      * @param origin the least value returned
       
   513      * @param bound the upper bound (exclusive)
       
   514      * @return a pseudorandom {@code long} value between the origin
       
   515      *         (inclusive) and the bound (exclusive)
       
   516      * @throws IllegalArgumentException if {@code origin} is greater than
       
   517      *         or equal to {@code bound}
       
   518      */
       
   519     public long nextLong(long origin, long bound) {
       
   520         if (origin >= bound)
       
   521             throw new IllegalArgumentException(BAD_RANGE);
       
   522         return internalNextLong(origin, bound);
       
   523     }
       
   524 
       
   525     /**
       
   526      * Returns a pseudorandom {@code double} value between zero
       
   527      * (inclusive) and one (exclusive).
       
   528      *
       
   529      * @return a pseudorandom {@code double} value between zero
       
   530      *         (inclusive) and one (exclusive)
       
   531      */
       
   532     public double nextDouble() {
       
   533         return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT;
       
   534     }
       
   535 
       
   536     /**
       
   537      * Returns a pseudorandom {@code double} value between 0.0
       
   538      * (inclusive) and the specified bound (exclusive).
       
   539      *
       
   540      * @param bound the upper bound (exclusive).  Must be positive.
       
   541      * @return a pseudorandom {@code double} value between zero
       
   542      *         (inclusive) and the bound (exclusive)
       
   543      * @throws IllegalArgumentException if {@code bound} is not positive
       
   544      */
       
   545     public double nextDouble(double bound) {
       
   546         if (!(bound > 0.0))
       
   547             throw new IllegalArgumentException(BAD_BOUND);
       
   548         double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound;
       
   549         return (result < bound) ?  result : // correct for rounding
       
   550             Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
       
   551     }
       
   552 
       
   553     /**
       
   554      * Returns a pseudorandom {@code double} value between the specified
       
   555      * origin (inclusive) and bound (exclusive).
       
   556      *
       
   557      * @param origin the least value returned
       
   558      * @param bound the upper bound (exclusive)
       
   559      * @return a pseudorandom {@code double} value between the origin
       
   560      *         (inclusive) and the bound (exclusive)
       
   561      * @throws IllegalArgumentException if {@code origin} is greater than
       
   562      *         or equal to {@code bound}
       
   563      */
       
   564     public double nextDouble(double origin, double bound) {
       
   565         if (!(origin < bound))
       
   566             throw new IllegalArgumentException(BAD_RANGE);
       
   567         return internalNextDouble(origin, bound);
       
   568     }
       
   569 
       
   570     /**
       
   571      * Returns a pseudorandom {@code boolean} value.
       
   572      *
       
   573      * @return a pseudorandom {@code boolean} value
       
   574      */
       
   575     public boolean nextBoolean() {
       
   576         return mix32(nextSeed()) < 0;
       
   577     }
       
   578 
       
   579     // stream methods, coded in a way intended to better isolate for
       
   580     // maintenance purposes the small differences across forms.
       
   581 
       
   582     /**
       
   583      * Returns a stream producing the given {@code streamSize} number
       
   584      * of pseudorandom {@code int} values from this generator and/or
       
   585      * one split from it.
       
   586      *
       
   587      * @param streamSize the number of values to generate
       
   588      * @return a stream of pseudorandom {@code int} values
       
   589      * @throws IllegalArgumentException if {@code streamSize} is
       
   590      *         less than zero
       
   591      */
       
   592     public IntStream ints(long streamSize) {
       
   593         if (streamSize < 0L)
       
   594             throw new IllegalArgumentException(BAD_SIZE);
       
   595         return StreamSupport.intStream
       
   596             (new RandomIntsSpliterator
       
   597              (this, 0L, streamSize, Integer.MAX_VALUE, 0),
       
   598              false);
       
   599     }
       
   600 
       
   601     /**
       
   602      * Returns an effectively unlimited stream of pseudorandom {@code int}
       
   603      * values from this generator and/or one split from it.
       
   604      *
       
   605      * @implNote This method is implemented to be equivalent to {@code
       
   606      * ints(Long.MAX_VALUE)}.
       
   607      *
       
   608      * @return a stream of pseudorandom {@code int} values
       
   609      */
       
   610     public IntStream ints() {
       
   611         return StreamSupport.intStream
       
   612             (new RandomIntsSpliterator
       
   613              (this, 0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
       
   614              false);
       
   615     }
       
   616 
       
   617     /**
       
   618      * Returns a stream producing the given {@code streamSize} number
       
   619      * of pseudorandom {@code int} values from this generator and/or one split
       
   620      * from it; each value conforms to the given origin (inclusive) and bound
       
   621      * (exclusive).
       
   622      *
       
   623      * @param streamSize the number of values to generate
       
   624      * @param randomNumberOrigin the origin (inclusive) of each random value
       
   625      * @param randomNumberBound the bound (exclusive) of each random value
       
   626      * @return a stream of pseudorandom {@code int} values,
       
   627      *         each with the given origin (inclusive) and bound (exclusive)
       
   628      * @throws IllegalArgumentException if {@code streamSize} is
       
   629      *         less than zero, or {@code randomNumberOrigin}
       
   630      *         is greater than or equal to {@code randomNumberBound}
       
   631      */
       
   632     public IntStream ints(long streamSize, int randomNumberOrigin,
       
   633                           int randomNumberBound) {
       
   634         if (streamSize < 0L)
       
   635             throw new IllegalArgumentException(BAD_SIZE);
       
   636         if (randomNumberOrigin >= randomNumberBound)
       
   637             throw new IllegalArgumentException(BAD_RANGE);
       
   638         return StreamSupport.intStream
       
   639             (new RandomIntsSpliterator
       
   640              (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
       
   641              false);
       
   642     }
       
   643 
       
   644     /**
       
   645      * Returns an effectively unlimited stream of pseudorandom {@code
       
   646      * int} values from this generator and/or one split from it; each value
       
   647      * conforms to the given origin (inclusive) and bound (exclusive).
       
   648      *
       
   649      * @implNote This method is implemented to be equivalent to {@code
       
   650      * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
       
   651      *
       
   652      * @param randomNumberOrigin the origin (inclusive) of each random value
       
   653      * @param randomNumberBound the bound (exclusive) of each random value
       
   654      * @return a stream of pseudorandom {@code int} values,
       
   655      *         each with the given origin (inclusive) and bound (exclusive)
       
   656      * @throws IllegalArgumentException if {@code randomNumberOrigin}
       
   657      *         is greater than or equal to {@code randomNumberBound}
       
   658      */
       
   659     public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
       
   660         if (randomNumberOrigin >= randomNumberBound)
       
   661             throw new IllegalArgumentException(BAD_RANGE);
       
   662         return StreamSupport.intStream
       
   663             (new RandomIntsSpliterator
       
   664              (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
       
   665              false);
       
   666     }
       
   667 
       
   668     /**
       
   669      * Returns a stream producing the given {@code streamSize} number
       
   670      * of pseudorandom {@code long} values from this generator and/or
       
   671      * one split from it.
       
   672      *
       
   673      * @param streamSize the number of values to generate
       
   674      * @return a stream of pseudorandom {@code long} values
       
   675      * @throws IllegalArgumentException if {@code streamSize} is
       
   676      *         less than zero
       
   677      */
       
   678     public LongStream longs(long streamSize) {
       
   679         if (streamSize < 0L)
       
   680             throw new IllegalArgumentException(BAD_SIZE);
       
   681         return StreamSupport.longStream
       
   682             (new RandomLongsSpliterator
       
   683              (this, 0L, streamSize, Long.MAX_VALUE, 0L),
       
   684              false);
       
   685     }
       
   686 
       
   687     /**
       
   688      * Returns an effectively unlimited stream of pseudorandom {@code
       
   689      * long} values from this generator and/or one split from it.
       
   690      *
       
   691      * @implNote This method is implemented to be equivalent to {@code
       
   692      * longs(Long.MAX_VALUE)}.
       
   693      *
       
   694      * @return a stream of pseudorandom {@code long} values
       
   695      */
       
   696     public LongStream longs() {
       
   697         return StreamSupport.longStream
       
   698             (new RandomLongsSpliterator
       
   699              (this, 0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
       
   700              false);
       
   701     }
       
   702 
       
   703     /**
       
   704      * Returns a stream producing the given {@code streamSize} number of
       
   705      * pseudorandom {@code long} values from this generator and/or one split
       
   706      * from it; each value conforms to the given origin (inclusive) and bound
       
   707      * (exclusive).
       
   708      *
       
   709      * @param streamSize the number of values to generate
       
   710      * @param randomNumberOrigin the origin (inclusive) of each random value
       
   711      * @param randomNumberBound the bound (exclusive) of each random value
       
   712      * @return a stream of pseudorandom {@code long} values,
       
   713      *         each with the given origin (inclusive) and bound (exclusive)
       
   714      * @throws IllegalArgumentException if {@code streamSize} is
       
   715      *         less than zero, or {@code randomNumberOrigin}
       
   716      *         is greater than or equal to {@code randomNumberBound}
       
   717      */
       
   718     public LongStream longs(long streamSize, long randomNumberOrigin,
       
   719                             long randomNumberBound) {
       
   720         if (streamSize < 0L)
       
   721             throw new IllegalArgumentException(BAD_SIZE);
       
   722         if (randomNumberOrigin >= randomNumberBound)
       
   723             throw new IllegalArgumentException(BAD_RANGE);
       
   724         return StreamSupport.longStream
       
   725             (new RandomLongsSpliterator
       
   726              (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
       
   727              false);
       
   728     }
       
   729 
       
   730     /**
       
   731      * Returns an effectively unlimited stream of pseudorandom {@code
       
   732      * long} values from this generator and/or one split from it; each value
       
   733      * conforms to the given origin (inclusive) and bound (exclusive).
       
   734      *
       
   735      * @implNote This method is implemented to be equivalent to {@code
       
   736      * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
       
   737      *
       
   738      * @param randomNumberOrigin the origin (inclusive) of each random value
       
   739      * @param randomNumberBound the bound (exclusive) of each random value
       
   740      * @return a stream of pseudorandom {@code long} values,
       
   741      *         each with the given origin (inclusive) and bound (exclusive)
       
   742      * @throws IllegalArgumentException if {@code randomNumberOrigin}
       
   743      *         is greater than or equal to {@code randomNumberBound}
       
   744      */
       
   745     public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
       
   746         if (randomNumberOrigin >= randomNumberBound)
       
   747             throw new IllegalArgumentException(BAD_RANGE);
       
   748         return StreamSupport.longStream
       
   749             (new RandomLongsSpliterator
       
   750              (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
       
   751              false);
       
   752     }
       
   753 
       
   754     /**
       
   755      * Returns a stream producing the given {@code streamSize} number of
       
   756      * pseudorandom {@code double} values from this generator and/or one split
       
   757      * from it; each value is between zero (inclusive) and one (exclusive).
       
   758      *
       
   759      * @param streamSize the number of values to generate
       
   760      * @return a stream of {@code double} values
       
   761      * @throws IllegalArgumentException if {@code streamSize} is
       
   762      *         less than zero
       
   763      */
       
   764     public DoubleStream doubles(long streamSize) {
       
   765         if (streamSize < 0L)
       
   766             throw new IllegalArgumentException(BAD_SIZE);
       
   767         return StreamSupport.doubleStream
       
   768             (new RandomDoublesSpliterator
       
   769              (this, 0L, streamSize, Double.MAX_VALUE, 0.0),
       
   770              false);
       
   771     }
       
   772 
       
   773     /**
       
   774      * Returns an effectively unlimited stream of pseudorandom {@code
       
   775      * double} values from this generator and/or one split from it; each value
       
   776      * is between zero (inclusive) and one (exclusive).
       
   777      *
       
   778      * @implNote This method is implemented to be equivalent to {@code
       
   779      * doubles(Long.MAX_VALUE)}.
       
   780      *
       
   781      * @return a stream of pseudorandom {@code double} values
       
   782      */
       
   783     public DoubleStream doubles() {
       
   784         return StreamSupport.doubleStream
       
   785             (new RandomDoublesSpliterator
       
   786              (this, 0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
       
   787              false);
       
   788     }
       
   789 
       
   790     /**
       
   791      * Returns a stream producing the given {@code streamSize} number of
       
   792      * pseudorandom {@code double} values from this generator and/or one split
       
   793      * from it; each value conforms to the given origin (inclusive) and bound
       
   794      * (exclusive).
       
   795      *
       
   796      * @param streamSize the number of values to generate
       
   797      * @param randomNumberOrigin the origin (inclusive) of each random value
       
   798      * @param randomNumberBound the bound (exclusive) of each random value
       
   799      * @return a stream of pseudorandom {@code double} values,
       
   800      *         each with the given origin (inclusive) and bound (exclusive)
       
   801      * @throws IllegalArgumentException if {@code streamSize} is
       
   802      *         less than zero, or {@code randomNumberOrigin}
       
   803      *         is greater than or equal to {@code randomNumberBound}
       
   804      */
       
   805     public DoubleStream doubles(long streamSize, double randomNumberOrigin,
       
   806                                 double randomNumberBound) {
       
   807         if (streamSize < 0L)
       
   808             throw new IllegalArgumentException(BAD_SIZE);
       
   809         if (!(randomNumberOrigin < randomNumberBound))
       
   810             throw new IllegalArgumentException(BAD_RANGE);
       
   811         return StreamSupport.doubleStream
       
   812             (new RandomDoublesSpliterator
       
   813              (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
       
   814              false);
       
   815     }
       
   816 
       
   817     /**
       
   818      * Returns an effectively unlimited stream of pseudorandom {@code
       
   819      * double} values from this generator and/or one split from it; each value
       
   820      * conforms to the given origin (inclusive) and bound (exclusive).
       
   821      *
       
   822      * @implNote This method is implemented to be equivalent to {@code
       
   823      * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
       
   824      *
       
   825      * @param randomNumberOrigin the origin (inclusive) of each random value
       
   826      * @param randomNumberBound the bound (exclusive) of each random value
       
   827      * @return a stream of pseudorandom {@code double} values,
       
   828      *         each with the given origin (inclusive) and bound (exclusive)
       
   829      * @throws IllegalArgumentException if {@code randomNumberOrigin}
       
   830      *         is greater than or equal to {@code randomNumberBound}
       
   831      */
       
   832     public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
       
   833         if (!(randomNumberOrigin < randomNumberBound))
       
   834             throw new IllegalArgumentException(BAD_RANGE);
       
   835         return StreamSupport.doubleStream
       
   836             (new RandomDoublesSpliterator
       
   837              (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
       
   838              false);
       
   839     }
       
   840 
       
   841     /**
       
   842      * Spliterator for int streams.  We multiplex the four int
       
   843      * versions into one class by treating a bound less than origin as
       
   844      * unbounded, and also by treating "infinite" as equivalent to
       
   845      * Long.MAX_VALUE. For splits, it uses the standard divide-by-two
       
   846      * approach. The long and double versions of this class are
       
   847      * identical except for types.
       
   848      */
       
   849     private static final class RandomIntsSpliterator
       
   850             implements Spliterator.OfInt {
       
   851         final SplittableRandom rng;
       
   852         long index;
       
   853         final long fence;
       
   854         final int origin;
       
   855         final int bound;
       
   856         RandomIntsSpliterator(SplittableRandom rng, long index, long fence,
       
   857                               int origin, int bound) {
       
   858             this.rng = rng; this.index = index; this.fence = fence;
       
   859             this.origin = origin; this.bound = bound;
       
   860         }
       
   861 
       
   862         public RandomIntsSpliterator trySplit() {
       
   863             long i = index, m = (i + fence) >>> 1;
       
   864             return (m <= i) ? null :
       
   865                 new RandomIntsSpliterator(rng.split(), i, index = m, origin, bound);
       
   866         }
       
   867 
       
   868         public long estimateSize() {
       
   869             return fence - index;
       
   870         }
       
   871 
       
   872         public int characteristics() {
       
   873             return (Spliterator.SIZED | Spliterator.SUBSIZED |
       
   874                     Spliterator.NONNULL | Spliterator.IMMUTABLE);
       
   875         }
       
   876 
       
   877         public boolean tryAdvance(IntConsumer consumer) {
       
   878             if (consumer == null) throw new NullPointerException();
       
   879             long i = index, f = fence;
       
   880             if (i < f) {
       
   881                 consumer.accept(rng.internalNextInt(origin, bound));
       
   882                 index = i + 1;
       
   883                 return true;
       
   884             }
       
   885             return false;
       
   886         }
       
   887 
       
   888         public void forEachRemaining(IntConsumer consumer) {
       
   889             if (consumer == null) throw new NullPointerException();
       
   890             long i = index, f = fence;
       
   891             if (i < f) {
       
   892                 index = f;
       
   893                 SplittableRandom r = rng;
       
   894                 int o = origin, b = bound;
       
   895                 do {
       
   896                     consumer.accept(r.internalNextInt(o, b));
       
   897                 } while (++i < f);
       
   898             }
       
   899         }
       
   900     }
       
   901 
       
   902     /**
       
   903      * Spliterator for long streams.
       
   904      */
       
   905     private static final class RandomLongsSpliterator
       
   906             implements Spliterator.OfLong {
       
   907         final SplittableRandom rng;
       
   908         long index;
       
   909         final long fence;
       
   910         final long origin;
       
   911         final long bound;
       
   912         RandomLongsSpliterator(SplittableRandom rng, long index, long fence,
       
   913                                long origin, long bound) {
       
   914             this.rng = rng; this.index = index; this.fence = fence;
       
   915             this.origin = origin; this.bound = bound;
       
   916         }
       
   917 
       
   918         public RandomLongsSpliterator trySplit() {
       
   919             long i = index, m = (i + fence) >>> 1;
       
   920             return (m <= i) ? null :
       
   921                 new RandomLongsSpliterator(rng.split(), i, index = m, origin, bound);
       
   922         }
       
   923 
       
   924         public long estimateSize() {
       
   925             return fence - index;
       
   926         }
       
   927 
       
   928         public int characteristics() {
       
   929             return (Spliterator.SIZED | Spliterator.SUBSIZED |
       
   930                     Spliterator.NONNULL | Spliterator.IMMUTABLE);
       
   931         }
       
   932 
       
   933         public boolean tryAdvance(LongConsumer consumer) {
       
   934             if (consumer == null) throw new NullPointerException();
       
   935             long i = index, f = fence;
       
   936             if (i < f) {
       
   937                 consumer.accept(rng.internalNextLong(origin, bound));
       
   938                 index = i + 1;
       
   939                 return true;
       
   940             }
       
   941             return false;
       
   942         }
       
   943 
       
   944         public void forEachRemaining(LongConsumer consumer) {
       
   945             if (consumer == null) throw new NullPointerException();
       
   946             long i = index, f = fence;
       
   947             if (i < f) {
       
   948                 index = f;
       
   949                 SplittableRandom r = rng;
       
   950                 long o = origin, b = bound;
       
   951                 do {
       
   952                     consumer.accept(r.internalNextLong(o, b));
       
   953                 } while (++i < f);
       
   954             }
       
   955         }
       
   956 
       
   957     }
       
   958 
       
   959     /**
       
   960      * Spliterator for double streams.
       
   961      */
       
   962     private static final class RandomDoublesSpliterator
       
   963             implements Spliterator.OfDouble {
       
   964         final SplittableRandom rng;
       
   965         long index;
       
   966         final long fence;
       
   967         final double origin;
       
   968         final double bound;
       
   969         RandomDoublesSpliterator(SplittableRandom rng, long index, long fence,
       
   970                                  double origin, double bound) {
       
   971             this.rng = rng; this.index = index; this.fence = fence;
       
   972             this.origin = origin; this.bound = bound;
       
   973         }
       
   974 
       
   975         public RandomDoublesSpliterator trySplit() {
       
   976             long i = index, m = (i + fence) >>> 1;
       
   977             return (m <= i) ? null :
       
   978                 new RandomDoublesSpliterator(rng.split(), i, index = m, origin, bound);
       
   979         }
       
   980 
       
   981         public long estimateSize() {
       
   982             return fence - index;
       
   983         }
       
   984 
       
   985         public int characteristics() {
       
   986             return (Spliterator.SIZED | Spliterator.SUBSIZED |
       
   987                     Spliterator.NONNULL | Spliterator.IMMUTABLE);
       
   988         }
       
   989 
       
   990         public boolean tryAdvance(DoubleConsumer consumer) {
       
   991             if (consumer == null) throw new NullPointerException();
       
   992             long i = index, f = fence;
       
   993             if (i < f) {
       
   994                 consumer.accept(rng.internalNextDouble(origin, bound));
       
   995                 index = i + 1;
       
   996                 return true;
       
   997             }
       
   998             return false;
       
   999         }
       
  1000 
       
  1001         public void forEachRemaining(DoubleConsumer consumer) {
       
  1002             if (consumer == null) throw new NullPointerException();
       
  1003             long i = index, f = fence;
       
  1004             if (i < f) {
       
  1005                 index = f;
       
  1006                 SplittableRandom r = rng;
       
  1007                 double o = origin, b = bound;
       
  1008                 do {
       
  1009                     consumer.accept(r.internalNextDouble(o, b));
       
  1010                 } while (++i < f);
       
  1011             }
       
  1012         }
       
  1013     }
   292     }
  1014 
   293 
  1015 }
   294 }