src/java.base/share/classes/java/util/random/RandomSupport.java
branchJDK-8193209-branch
changeset 57547 56cbdc3ea079
child 57684 7cb325557832
equal deleted inserted replaced
57546:1ca1cfdcb451 57547:56cbdc3ea079
       
     1 /*
       
     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.
       
     4  *
       
     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
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    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
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package java.util.random;
       
    27 
       
    28 import java.util.function.Consumer;
       
    29 import java.util.function.DoubleConsumer;
       
    30 import java.util.function.IntConsumer;
       
    31 import java.util.function.LongConsumer;
       
    32 import java.util.random.RandomGenerator.SplittableGenerator;
       
    33 import java.util.Spliterator;
       
    34 import java.util.stream.DoubleStream;
       
    35 import java.util.stream.IntStream;
       
    36 import java.util.stream.LongStream;
       
    37 import java.util.stream.Stream;
       
    38 import java.util.stream.StreamSupport;
       
    39 
       
    40 /**
       
    41  * Low-level utility methods helpful for implementing pseudorandom number generators.
       
    42  *
       
    43  * This class is mostly for library writers creating specific implementations of the
       
    44  * interface {@link RandomGenerator}.
       
    45  *
       
    46  * @since 14
       
    47  */
       
    48 public class RandomSupport {
       
    49 
       
    50     /*
       
    51      * Implementation Overview.
       
    52      *
       
    53      * This class provides utility methods and constants frequently
       
    54      * useful in the implentation of pseudorandom number generators
       
    55      * that satisfy the interface {@link RandomGenerator}.
       
    56      *
       
    57      * File organization: First some message strings, then the main
       
    58      * public methods, followed by a non-public base spliterator class.
       
    59      */
       
    60 
       
    61     // IllegalArgumentException messages
       
    62     static final String BAD_SIZE = "size must be non-negative";
       
    63     static final String BAD_DISTANCE = "jump distance must be finite, positive, and an exact integer";
       
    64     static final String BAD_BOUND = "bound must be positive";
       
    65     static final String BAD_FLOATING_BOUND = "bound must be finite and positive";
       
    66     static final String BAD_RANGE = "bound must be greater than origin";
       
    67 
       
    68     /* ---------------- public methods ---------------- */
       
    69 
       
    70     /**
       
    71      * Check a {@code long} proposed stream size for validity.
       
    72      *
       
    73      * @param streamSize the proposed stream size
       
    74      *
       
    75      * @throws IllegalArgumentException if {@code streamSize} is negative
       
    76      */
       
    77     public static void checkStreamSize(long streamSize) {
       
    78         if (streamSize < 0L)
       
    79             throw new IllegalArgumentException(BAD_SIZE);
       
    80     }
       
    81 
       
    82     /**
       
    83      * Check a {@code double} proposed jump distance for validity.
       
    84      *
       
    85      * @param distance the proposed jump distance
       
    86      *
       
    87      * @throws IllegalArgumentException if {@code size} not positive, finite, and an exact integer
       
    88      */
       
    89     public static void checkJumpDistance(double distance) {
       
    90         if (!(distance > 0.0 && distance < Float.POSITIVE_INFINITY
       
    91                              && distance == Math.floor(distance))) {
       
    92             throw new IllegalArgumentException(BAD_DISTANCE);
       
    93         }
       
    94     }
       
    95 
       
    96     /**
       
    97      * Checks a {@code float} upper bound value for validity.
       
    98      *
       
    99      * @param bound the upper bound (exclusive)
       
   100      *
       
   101      * @throws IllegalArgumentException if {@code bound} is not positive and finite
       
   102      */
       
   103     public static void checkBound(float bound) {
       
   104         if (!(bound > 0.0 && bound < Float.POSITIVE_INFINITY)) {
       
   105             throw new IllegalArgumentException(BAD_FLOATING_BOUND);
       
   106         }
       
   107     }
       
   108 
       
   109     /**
       
   110      * Checks a {@code double} upper bound value for validity.
       
   111      *
       
   112      * @param bound the upper bound (exclusive)
       
   113      *
       
   114      * @throws IllegalArgumentException if {@code bound} is not positive and finite
       
   115      */
       
   116     public static void checkBound(double bound) {
       
   117         if (!(bound > 0.0 && bound < Double.POSITIVE_INFINITY)) {
       
   118             throw new IllegalArgumentException(BAD_FLOATING_BOUND);
       
   119         }
       
   120     }
       
   121 
       
   122     /**
       
   123      * Checks an {@code int} upper bound value for validity.
       
   124      *
       
   125      * @param bound the upper bound (exclusive)
       
   126      *
       
   127      * @throws IllegalArgumentException if {@code bound} is not positive
       
   128      */
       
   129     public static void checkBound(int bound) {
       
   130         if (bound <= 0) {
       
   131             throw new IllegalArgumentException(BAD_BOUND);
       
   132         }
       
   133     }
       
   134 
       
   135     /**
       
   136      * Checks a {@code long} upper bound value for validity.
       
   137      *
       
   138      * @param bound the upper bound (exclusive)
       
   139      *
       
   140      * @throws IllegalArgumentException if {@code bound} is not positive
       
   141      */
       
   142     public static void checkBound(long bound) {
       
   143         if (bound <= 0) {
       
   144             throw new IllegalArgumentException(BAD_BOUND);
       
   145         }
       
   146     }
       
   147 
       
   148     /**
       
   149      * Checks a {@code float} range for validity.
       
   150      *
       
   151      * @param origin the least value (inclusive) in the range
       
   152      * @param bound  the upper bound (exclusive) of the range
       
   153      *
       
   154      * @throws IllegalArgumentException unless {@code origin} is finite, {@code bound} is finite,
       
   155      *                                  and {@code bound - origin} is finite
       
   156      */
       
   157     public static void checkRange(float origin, float bound) {
       
   158         if (!(origin < bound && (bound - origin) < Float.POSITIVE_INFINITY)) {
       
   159             throw new IllegalArgumentException(BAD_RANGE);
       
   160         }
       
   161     }
       
   162 
       
   163     /**
       
   164      * Checks a {@code double} range for validity.
       
   165      *
       
   166      * @param origin the least value (inclusive) in the range
       
   167      * @param bound  the upper bound (exclusive) of the range
       
   168      *
       
   169      * @throws IllegalArgumentException unless {@code origin} is finite, {@code bound} is finite,
       
   170      *                                  and {@code bound - origin} is finite
       
   171      */
       
   172     public static void checkRange(double origin, double bound) {
       
   173         if (!(origin < bound && (bound - origin) < Double.POSITIVE_INFINITY)) {
       
   174             throw new IllegalArgumentException(BAD_RANGE);
       
   175         }
       
   176     }
       
   177 
       
   178     /**
       
   179      * Checks an {@code int} range for validity.
       
   180      *
       
   181      * @param origin the least value that can be returned
       
   182      * @param bound  the upper bound (exclusive) for the returned value
       
   183      *
       
   184      * @throws IllegalArgumentException if {@code origin} is greater than or equal to {@code bound}
       
   185      */
       
   186     public static void checkRange(int origin, int bound) {
       
   187         if (origin >= bound) {
       
   188             throw new IllegalArgumentException(BAD_RANGE);
       
   189         }
       
   190     }
       
   191 
       
   192     /**
       
   193      * Checks a {@code long} range for validity.
       
   194      *
       
   195      * @param origin the least value that can be returned
       
   196      * @param bound  the upper bound (exclusive) for the returned value
       
   197      *
       
   198      * @throws IllegalArgumentException if {@code origin} is greater than or equal to {@code bound}
       
   199      */
       
   200     public static void checkRange(long origin, long bound) {
       
   201         if (origin >= bound) {
       
   202             throw new IllegalArgumentException(BAD_RANGE);
       
   203         }
       
   204     }
       
   205 
       
   206     /**
       
   207      * Given an array of seed bytes of any length, construct an array
       
   208      * of {@code long} seed values of length {@code n}, such that the
       
   209      * last {@code z} values are not all zero.
       
   210      *
       
   211      * @param seed an array of {@code byte} values
       
   212      * @param n the length of the result array (should be nonnegative)
       
   213      * @param z the number of trailing result elements that are required
       
   214      *        to be not all zero (should be nonnegative but not larger
       
   215      *        than {@code n})
       
   216      *
       
   217      * @return an array of length {@code n} containing {@code long} seed values
       
   218      */
       
   219     public static long[] convertSeedBytesToLongs(byte[] seed, int n, int z) {
       
   220         final long[] result = new long[n];
       
   221         final int m = Math.min(seed.length, n << 3);
       
   222         // Distribute seed bytes into the words to be formed.
       
   223         for (int j = 0; j < m; j++) {
       
   224             result[j>>3] = (result[j>>3] << 8) | seed[j];
       
   225         }
       
   226         // If there aren't enough seed bytes for all the words we need,
       
   227         // use a SplitMix-style PRNG to fill in the rest.
       
   228         long v = result[0];
       
   229         for (int j = (m + 7) >> 3; j < n; j++) {
       
   230             result[j] = mixMurmur64(v += SILVER_RATIO_64);
       
   231         }
       
   232         // Finally, we need to make sure the last z words are not all zero.
       
   233         search: {
       
   234             for (int j = n - z; j < n; j++) {
       
   235                 if (result[j] != 0) break search;
       
   236             }
       
   237             // If they are, fill in using a SplitMix-style PRNG.
       
   238             // Using "& ~1L" in the next line defends against the case z==1
       
   239             // by guaranteeing that the first generated value will be nonzero.
       
   240             long w = result[0] & ~1L;
       
   241             for (int j = n - z; j < n; j++) {
       
   242                 result[j] = mixMurmur64(w += SILVER_RATIO_64);
       
   243             }
       
   244         }
       
   245         return result;
       
   246     }
       
   247 
       
   248     /**
       
   249      * Given an array of seed bytes of any length, construct an array
       
   250      * of {@code int} seed values of length {@code n}, such that the
       
   251      * last {@code z} values are not all zero.
       
   252      *
       
   253      * @param seed an array of {@code byte} values
       
   254      * @param n the length of the result array (should be nonnegative)
       
   255      * @param z the number of trailing result elements that are required
       
   256      *        to be not all zero (should be nonnegative but not larger
       
   257      *        than {@code n})
       
   258      *
       
   259      * @return an array of length {@code n} containing {@code int} seed values
       
   260      */
       
   261     public static int[] convertSeedBytesToInts(byte[] seed, int n, int z) {
       
   262         final int[] result = new int[n];
       
   263         final int m = Math.min(seed.length, n << 2);
       
   264         // Distribute seed bytes into the words to be formed.
       
   265         for (int j = 0; j < m; j++) {
       
   266             result[j>>2] = (result[j>>2] << 8) | seed[j];
       
   267         }
       
   268         // If there aren't enough seed bytes for all the words we need,
       
   269         // use a SplitMix-style PRNG to fill in the rest.
       
   270         int v = result[0];
       
   271         for (int j = (m + 3) >> 2; j < n; j++) {
       
   272             result[j] = mixMurmur32(v += SILVER_RATIO_32);
       
   273         }
       
   274         // Finally, we need to make sure the last z words are not all zero.
       
   275         search: {
       
   276             for (int j = n - z; j < n; j++) {
       
   277                 if (result[j] != 0) break search;
       
   278             }
       
   279             // If they are, fill in using a SplitMix-style PRNG.
       
   280             // Using "& ~1" in the next line defends against the case z==1
       
   281             // by guaranteeing that the first generated value will be nonzero.
       
   282             int w = result[0] & ~1;
       
   283             for (int j = n - z; j < n; j++) {
       
   284                 result[j] = mixMurmur32(w += SILVER_RATIO_32);
       
   285             }
       
   286         }
       
   287         return result;
       
   288     }
       
   289 
       
   290     /*
       
   291      * Bounded versions of nextX methods used by streams, as well as
       
   292      * the public nextX(origin, bound) methods.  These exist mainly to
       
   293      * avoid the need for multiple versions of stream spliterators
       
   294      * across the different exported forms of streams.
       
   295      */
       
   296 
       
   297     /**
       
   298      * This is the form of {@code nextLong} used by a {@link LongStream}
       
   299      * {@link Spliterator} and by the public method
       
   300      * {@code nextLong(origin, bound)}.  If {@code origin} is greater
       
   301      * than {@code bound}, then this method simply calls the unbounded
       
   302      * version of {@code nextLong()}, choosing pseudorandomly from
       
   303      * among all 2<sup>64</sup> possible {@code long} values}, and
       
   304      * otherwise uses one or more calls to {@code nextLong()} to
       
   305      * choose a value pseudorandomly from the possible values
       
   306      * between {@code origin} (inclusive) and {@code bound} (exclusive).
       
   307      *
       
   308      * @implNote This method first calls {@code nextLong()} to obtain
       
   309      * a {@code long} value that is assumed to be pseudorandomly
       
   310      * chosen uniformly and independently from the 2<sup>64</sup>
       
   311      * possible {@code long} values (that is, each of the 2<sup>64</sup>
       
   312      * possible long values is equally likely to be chosen).
       
   313      * Under some circumstances (when the specified range is not
       
   314      * a power of 2), {@code nextLong()} may be called additional times
       
   315      * to ensure that that the values in the specified range are
       
   316      * equally likely to be chosen (provided the assumption holds).
       
   317      * <p>
       
   318      * The implementation considers four cases:
       
   319      * <ol>
       
   320      *
       
   321      * <li> If the {@code} bound} is less than or equal to the {@code origin}
       
   322      *      (indicated an unbounded form), the 64-bit {@code long} value
       
   323      *      obtained from {@code nextLong()} is returned directly.
       
   324      *
       
   325      * <li> Otherwise, if the length <i>n</i> of the specified range is an
       
   326      *      exact power of two 2<sup><i>m</i></sup> for some integer
       
   327      *      <i>m</i>, then return the sum of {@code origin} and the
       
   328      *      <i>m</i> lowest-order bits of the value from {@code nextLong()}.
       
   329      *
       
   330      * <li> Otherwise, if the length <i>n</i> of the specified range
       
   331      *      is less than 2<sup>63</sup>, then the basic idea is to use the
       
   332      *      remainder modulo <i>n</i> of the value from {@code nextLong()},
       
   333      *      but with this approach some values will be over-represented.
       
   334      *      Therefore a loop is used to avoid potential bias by rejecting
       
   335      *      candidates that are too large.  Assuming that the results from
       
   336      *      {@code nextLong()} are truly chosen uniformly and independently,
       
   337      *      the expected number of iterations will be somewhere between
       
   338      *      1 and 2, depending on the precise value of <i>n</i>.
       
   339      *
       
   340      * <li> Otherwise, the length <i>n</i> of the specified range
       
   341      *      cannot be represented as a positive {@code long} value.
       
   342      *      A loop repeatedly calls {@code nextlong()} until obtaining
       
   343      *      a suitable candidate,  Again, the expected number of iterations
       
   344      *      is less than 2.
       
   345      *
       
   346      * </ol>
       
   347      *
       
   348      * @param rng a random number generator to be used as a
       
   349      *        source of pseudorandom {@code long} values
       
   350      * @param origin the least value that can be produced,
       
   351      *        unless greater than or equal to {@code bound}
       
   352      * @param bound the upper bound (exclusive), unless {@code origin}
       
   353      *        is greater than or equal to {@code bound}
       
   354      *
       
   355      * @return a pseudorandomly chosen {@code long} value,
       
   356      *         which will be between {@code origin} (inclusive) and
       
   357      *         {@code bound} exclusive unless {@code origin}
       
   358      *         is greater than or equal to {@code bound}
       
   359      */
       
   360     public static long boundedNextLong(RandomGenerator rng, long origin, long bound) {
       
   361         long r = rng.nextLong();
       
   362         if (origin < bound) {
       
   363             // It's not case (1).
       
   364             final long n = bound - origin;
       
   365             final long m = n - 1;
       
   366             if ((n & m) == 0L) {
       
   367                 // It is case (2): length of range is a power of 2.
       
   368                 r = (r & m) + origin;
       
   369             } else if (n > 0L) {
       
   370                 // It is case (3): need to reject over-represented candidates.
       
   371                 /* This loop takes an unlovable form (but it works):
       
   372                    because the first candidate is already available,
       
   373                    we need a break-in-the-middle construction,
       
   374                    which is concisely but cryptically performed
       
   375                    within the while-condition of a body-less for loop. */
       
   376                 for (long u = r >>> 1;            // ensure nonnegative
       
   377                      u + m - (r = u % n) < 0L;    // rejection check
       
   378                      u = rng.nextLong() >>> 1) // retry
       
   379                     ;
       
   380                 r += origin;
       
   381             }
       
   382             else {
       
   383                 // It is case (4): length of range not representable as long.
       
   384                 while (r < origin || r >= bound)
       
   385                     r = rng.nextLong();
       
   386             }
       
   387         }
       
   388         return r;
       
   389     }
       
   390 
       
   391     /**
       
   392      * This is the form of {@code nextLong} used by the public method
       
   393      * {@code nextLong(bound)}.  This is essentially a version of
       
   394      * {@code boundedNextLong(origin, bound)} that has been
       
   395      * specialized for the case where the {@code origin} is zero
       
   396      * and the {@code bound} is greater than zero.  The value
       
   397      * returned is chosen pseudorandomly from nonnegative integer
       
   398      * values less than {@code bound}.
       
   399      *
       
   400      * @implNote This method first calls {@code nextLong()} to obtain
       
   401      * a {@code long} value that is assumed to be pseudorandomly
       
   402      * chosen uniformly and independently from the 2<sup>64</sup>
       
   403      * possible {@code long} values (that is, each of the 2<sup>64</sup>
       
   404      * possible long values is equally likely to be chosen).
       
   405      * Under some circumstances (when the specified range is not
       
   406      * a power of 2), {@code nextLong()} may be called additional times
       
   407      * to ensure that that the values in the specified range are
       
   408      * equally likely to be chosen (provided the assumption holds).
       
   409      * <p>
       
   410      * The implementation considers two cases:
       
   411      * <ol>
       
   412      *
       
   413      * <li> If {@code bound} is an exact power of two 2<sup><i>m</i></sup>
       
   414      *      for some integer <i>m</i>, then return the sum of {@code origin}
       
   415      *      and the <i>m</i> lowest-order bits of the value from
       
   416      *      {@code nextLong()}.
       
   417      *
       
   418      * <li> Otherwise, the basic idea is to use the remainder modulo
       
   419      *      <i>bound</i> of the value from {@code nextLong()},
       
   420      *      but with this approach some values will be over-represented.
       
   421      *      Therefore a loop is used to avoid potential bias by rejecting
       
   422      *      candidates that vare too large.  Assuming that the results from
       
   423      *      {@code nextLong()} are truly chosen uniformly and independently,
       
   424      *      the expected number of iterations will be somewhere between
       
   425      *      1 and 2, depending on the precise value of <i>bound</i>.
       
   426      *
       
   427      * </ol>
       
   428      *
       
   429      * @param rng a random number generator to be used as a
       
   430      *        source of pseudorandom {@code long} values
       
   431      * @param bound the upper bound (exclusive); must be greater than zero
       
   432      *
       
   433      * @return a pseudorandomly chosen {@code long} value
       
   434      */
       
   435     public static long boundedNextLong(RandomGenerator rng, long bound) {
       
   436         // Specialize boundedNextLong for origin == 0, bound > 0
       
   437         final long m = bound - 1;
       
   438         long r = rng.nextLong();
       
   439         if ((bound & m) == 0L) {
       
   440             // The bound is a power of 2.
       
   441             r &= m;
       
   442         } else {
       
   443             // Must reject over-represented candidates
       
   444             /* This loop takes an unlovable form (but it works):
       
   445                because the first candidate is already available,
       
   446                we need a break-in-the-middle construction,
       
   447                which is concisely but cryptically performed
       
   448                within the while-condition of a body-less for loop. */
       
   449             for (long u = r >>> 1;
       
   450                  u + m - (r = u % bound) < 0L;
       
   451                  u = rng.nextLong() >>> 1)
       
   452                 ;
       
   453         }
       
   454         return r;
       
   455     }
       
   456 
       
   457     /**
       
   458      * This is the form of {@code nextInt} used by an {@link IntStream}
       
   459      * {@link Spliterator} and by the public method
       
   460      * {@code nextInt(origin, bound)}.  If {@code origin} is greater
       
   461      * than {@code bound}, then this method simply calls the unbounded
       
   462      * version of {@code nextInt()}, choosing pseudorandomly from
       
   463      * among all 2<sup>64</sup> possible {@code int} values}, and
       
   464      * otherwise uses one or more calls to {@code nextInt()} to
       
   465      * choose a value pseudorandomly from the possible values
       
   466      * between {@code origin} (inclusive) and {@code bound} (exclusive).
       
   467      *
       
   468      * @param rng a random number generator to be used as a
       
   469      *        source of pseudorandom {@code int} values
       
   470      * @param origin the least value that can be produced,
       
   471      *        unless greater than or equal to {@code bound}
       
   472      * @param bound the upper bound (exclusive), unless {@code origin}
       
   473      *        is greater than or equal to {@code bound}
       
   474      *
       
   475      * @return a pseudorandomly chosen {@code int} value,
       
   476      *         which will be between {@code origin} (inclusive) and
       
   477      *         {@code bound} exclusive unless {@code origin}
       
   478      *         is greater than or equal to {@code bound}
       
   479      *
       
   480      * @implNote The implementation of this method is identical to
       
   481      *           the implementation of {@code nextLong(origin, bound)}
       
   482      *           except that {@code int} values and the {@code nextInt()}
       
   483      *           method are used rather than {@code long} values and the
       
   484      *           {@code nextLong()} method.
       
   485      */
       
   486     public static int boundedNextInt(RandomGenerator rng, int origin, int bound) {
       
   487         int r = rng.nextInt();
       
   488         if (origin < bound) {
       
   489             // It's not case (1).
       
   490             final int n = bound - origin;
       
   491             final int m = n - 1;
       
   492             if ((n & m) == 0) {
       
   493                 // It is case (2): length of range is a power of 2.
       
   494                 r = (r & m) + origin;
       
   495             } else if (n > 0) {
       
   496                 // It is case (3): need to reject over-represented candidates.
       
   497                 for (int u = r >>> 1;
       
   498                      u + m - (r = u % n) < 0;
       
   499                      u = rng.nextInt() >>> 1)
       
   500                     ;
       
   501                 r += origin;
       
   502             }
       
   503             else {
       
   504                 // It is case (4): length of range not representable as long.
       
   505                 while (r < origin || r >= bound) {
       
   506                     r = rng.nextInt();
       
   507                 }
       
   508             }
       
   509         }
       
   510         return r;
       
   511     }
       
   512 
       
   513     /**
       
   514      * This is the form of {@code nextInt} used by the public method
       
   515      * {@code nextInt(bound)}.  This is essentially a version of
       
   516      * {@code boundedNextInt(origin, bound)} that has been
       
   517      * specialized for the case where the {@code origin} is zero
       
   518      * and the {@code bound} is greater than zero.  The value
       
   519      * returned is chosen pseudorandomly from nonnegative integer
       
   520      * values less than {@code bound}.
       
   521      *
       
   522      * @param rng a random number generator to be used as a
       
   523      *        source of pseudorandom {@code long} values
       
   524      * @param bound the upper bound (exclusive); must be greater than zero
       
   525      *
       
   526      * @return a pseudorandomly chosen {@code long} value
       
   527      *
       
   528      * @implNote The implementation of this method is identical to
       
   529      *           the implementation of {@code nextLong(bound)}
       
   530      *           except that {@code int} values and the {@code nextInt()}
       
   531      *           method are used rather than {@code long} values and the
       
   532      *           {@code nextLong()} method.
       
   533      */
       
   534     public static int boundedNextInt(RandomGenerator rng, int bound) {
       
   535         // Specialize boundedNextInt for origin == 0, bound > 0
       
   536         final int m = bound - 1;
       
   537         int r = rng.nextInt();
       
   538         if ((bound & m) == 0) {
       
   539             // The bound is a power of 2.
       
   540             r &= m;
       
   541         } else {
       
   542             // Must reject over-represented candidates
       
   543             for (int u = r >>> 1;
       
   544                  u + m - (r = u % bound) < 0;
       
   545                  u = rng.nextInt() >>> 1)
       
   546                 ;
       
   547         }
       
   548         return r;
       
   549     }
       
   550 
       
   551     /**
       
   552      * This is the form of {@code nextDouble} used by a {@link DoubleStream}
       
   553      * {@link Spliterator} and by the public method
       
   554      * {@code nextDouble(origin, bound)}.  If {@code origin} is greater
       
   555      * than {@code bound}, then this method simply calls the unbounded
       
   556      * version of {@code nextDouble()}, and otherwise scales and translates
       
   557      * the result of a call to {@code nextDouble()} so that it lies
       
   558      * between {@code origin} (inclusive) and {@code bound} (exclusive).
       
   559      *
       
   560      * @implNote The implementation considers two cases:
       
   561      * <ol>
       
   562      *
       
   563      * <li> If the {@code bound} is less than or equal to the {@code origin}
       
   564      *      (indicated an unbounded form), the 64-bit {@code double} value
       
   565      *      obtained from {@code nextDouble()} is returned directly.
       
   566      *
       
   567      * <li> Otherwise, the result of a call to {@code nextDouble} is
       
   568      *      multiplied by {@code (bound - origin)}, then {@code origin}
       
   569      *      is added, and then if this this result is not less than
       
   570      *      {@code bound} (which can sometimes occur because of rounding),
       
   571      *      it is replaced with the largest {@code double} value that
       
   572      *      is less than {@code bound}.
       
   573      *
       
   574      * </ol>
       
   575      *
       
   576      * @param rng a random number generator to be used as a
       
   577      *        source of pseudorandom {@code double} values
       
   578      * @param origin the least value that can be produced,
       
   579      *        unless greater than or equal to {@code bound}; must be finite
       
   580      * @param bound the upper bound (exclusive), unless {@code origin}
       
   581      *        is greater than or equal to {@code bound}; must be finite
       
   582      * @return a pseudorandomly chosen {@code double} value,
       
   583      *         which will be between {@code origin} (inclusive) and
       
   584      *         {@code bound} exclusive unless {@code origin}
       
   585      *         is greater than or equal to {@code bound},
       
   586      *         in which case it will be between 0.0 (inclusive)
       
   587      *         and 1.0 (exclusive)
       
   588      */
       
   589     public static double boundedNextDouble(RandomGenerator rng, double origin, double bound) {
       
   590         double r = rng.nextDouble();
       
   591         if (origin < bound) {
       
   592             r = r * (bound - origin) + origin;
       
   593             if (r >= bound)  // may need to correct a rounding problem
       
   594                 r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
       
   595         }
       
   596         return r;
       
   597     }
       
   598 
       
   599     /**
       
   600      * This is the form of {@code nextDouble} used by the public method
       
   601      * {@code nextDouble(bound)}.  This is essentially a version of
       
   602      * {@code boundedNextDouble(origin, bound)} that has been
       
   603      * specialized for the case where the {@code origin} is zero
       
   604      * and the {@code bound} is greater than zero.
       
   605      *
       
   606      * @implNote The result of a call to {@code nextDouble} is
       
   607      *      multiplied by {@code bound}, and then if this result is
       
   608      *      not less than {@code bound} (which can sometimes occur
       
   609      *      because of rounding), it is replaced with the largest
       
   610      *      {@code double} value that is less than {@code bound}.
       
   611      *
       
   612      * @param rng a random number generator to be used as a
       
   613      *        source of pseudorandom {@code double} values
       
   614      * @param bound the upper bound (exclusive); must be finite and
       
   615      *        greater than zero
       
   616      * @return a pseudorandomly chosen {@code double} value
       
   617      *         between zero (inclusive) and {@code bound} (exclusive)
       
   618      */
       
   619     public static double boundedNextDouble(RandomGenerator rng, double bound) {
       
   620         // Specialize boundedNextDouble for origin == 0, bound > 0
       
   621         double r = rng.nextDouble();
       
   622         r = r * bound;
       
   623         if (r >= bound)  // may need to correct a rounding problem
       
   624             r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
       
   625         return r;
       
   626     }
       
   627 
       
   628     /**
       
   629      * This is the form of {@code nextFloat} used by a {@code Stream<Float>}
       
   630      * {@link Spliterator} (if there were any) and by the public method
       
   631      * {@code nextFloat(origin, bound)}.  If {@code origin} is greater
       
   632      * than {@code bound}, then this method simply calls the unbounded
       
   633      * version of {@code nextFloat()}, and otherwise scales and translates
       
   634      * the result of a call to {@code nextFloat()} so that it lies
       
   635      * between {@code origin} (inclusive) and {@code bound} (exclusive).
       
   636      *
       
   637      * @implNote The implementation of this method is identical to
       
   638      *     the implementation of {@code nextDouble(origin, bound)}
       
   639      *     except that {@code float} values and the {@code nextFloat()}
       
   640      *     method are used rather than {@code double} values and the
       
   641      *     {@code nextDouble()} method.
       
   642      *
       
   643      * @param rng a random number generator to be used as a
       
   644      *        source of pseudorandom {@code float} values
       
   645      * @param origin the least value that can be produced,
       
   646      *        unless greater than or equal to {@code bound}; must be finite
       
   647      * @param bound the upper bound (exclusive), unless {@code origin}
       
   648      *        is greater than or equal to {@code bound}; must be finite
       
   649      * @return a pseudorandomly chosen {@code float} value,
       
   650      *         which will be between {@code origin} (inclusive) and
       
   651      *         {@code bound} exclusive unless {@code origin}
       
   652      *         is greater than or equal to {@code bound},
       
   653      *         in which case it will be between 0.0 (inclusive)
       
   654      *         and 1.0 (exclusive)
       
   655      */
       
   656     public static float boundedNextFloat(RandomGenerator rng, float origin, float bound) {
       
   657         float r = rng.nextFloat();
       
   658         if (origin < bound) {
       
   659             r = r * (bound - origin) + origin;
       
   660             if (r >= bound) // may need to correct a rounding problem
       
   661                 r = Float.intBitsToFloat(Float.floatToIntBits(bound) - 1);
       
   662         }
       
   663         return r;
       
   664     }
       
   665 
       
   666     /**
       
   667      * This is the form of {@code nextFloat} used by the public method
       
   668      * {@code nextFloat(bound)}.  This is essentially a version of
       
   669      * {@code boundedNextFloat(origin, bound)} that has been
       
   670      * specialized for the case where the {@code origin} is zero
       
   671      * and the {@code bound} is greater than zero.
       
   672      *
       
   673      * @implNote The implementation of this method is identical to
       
   674      *     the implementation of {@code nextDouble(bound)}
       
   675      *     except that {@code float} values and the {@code nextFloat()}
       
   676      *     method are used rather than {@code double} values and the
       
   677      *     {@code nextDouble()} method.
       
   678      *
       
   679      * @param rng a random number generator to be used as a
       
   680      *        source of pseudorandom {@code float} values
       
   681      * @param bound the upper bound (exclusive); must be finite and
       
   682      *        greater than zero
       
   683      * @return a pseudorandomly chosen {@code float} value
       
   684      *         between zero (inclusive) and {@code bound} (exclusive)
       
   685      */
       
   686     public static float boundedNextFloat(RandomGenerator rng, float bound) {
       
   687         // Specialize boundedNextFloat for origin == 0, bound > 0
       
   688         float r = rng.nextFloat();
       
   689         r = r * bound;
       
   690         if (r >= bound) // may need to correct a rounding problem
       
   691             r = Float.intBitsToFloat(Float.floatToIntBits(bound) - 1);
       
   692         return r;
       
   693     }
       
   694 
       
   695     // The following decides which of two strategies initialSeed() will use.
       
   696     private static boolean secureRandomSeedRequested() {
       
   697         String pp = java.security.AccessController.doPrivileged(
       
   698                 new sun.security.action.GetPropertyAction(
       
   699                         "java.util.secureRandomSeed"));
       
   700         return (pp != null && pp.equalsIgnoreCase("true"));
       
   701     }
       
   702 
       
   703     private static final boolean useSecureRandomSeed = secureRandomSeedRequested();
       
   704 
       
   705     /**
       
   706      * Returns a {@code long} value (chosen from some
       
   707      * machine-dependent entropy source) that may be useful for
       
   708      * initializing a source of seed values for instances of {@link RandomGenerator}
       
   709      * created by zero-argument constructors.  (This method should
       
   710      * <i>not</i> be called repeatedly, once per constructed
       
   711      * object; at most it should be called once per class.)
       
   712      *
       
   713      * @return a {@code long} value, randomly chosen using
       
   714      *         appropriate environmental entropy
       
   715      */
       
   716     public static long initialSeed() {
       
   717         if (useSecureRandomSeed) {
       
   718             byte[] seedBytes = java.security.SecureRandom.getSeed(8);
       
   719             long s = (long)(seedBytes[0]) & 0xffL;
       
   720             for (int i = 1; i < 8; ++i)
       
   721                 s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
       
   722             return s;
       
   723         }
       
   724         return (mixStafford13(System.currentTimeMillis()) ^
       
   725                 mixStafford13(System.nanoTime()));
       
   726     }
       
   727 
       
   728     /**
       
   729      * The first 32 bits of the golden ratio (1+sqrt(5))/2, forced to be odd.
       
   730      * Useful for producing good Weyl sequences or as an arbitrary nonzero odd value.
       
   731      */
       
   732     public static final int  GOLDEN_RATIO_32 = 0x9e3779b9;
       
   733 
       
   734     /**
       
   735      * The first 64 bits of the golden ratio (1+sqrt(5))/2, forced to be odd.
       
   736      * Useful for producing good Weyl sequences or as an arbitrary nonzero odd value.
       
   737      */
       
   738     public static final long GOLDEN_RATIO_64 = 0x9e3779b97f4a7c15L;
       
   739 
       
   740     /**
       
   741      * The first 32 bits of the silver ratio 1+sqrt(2), forced to be odd.
       
   742      * Useful for producing good Weyl sequences or as an arbitrary nonzero odd value.
       
   743      */
       
   744     public static final int  SILVER_RATIO_32 = 0x6A09E667;
       
   745 
       
   746     /**
       
   747      * The first 64 bits of the silver ratio 1+sqrt(2), forced to be odd.
       
   748      * Useful for producing good Weyl sequences or as an arbitrary nonzero odd value.
       
   749      */
       
   750     public static final long SILVER_RATIO_64 = 0x6A09E667F3BCC909L;
       
   751 
       
   752     /**
       
   753      * Computes the 64-bit mixing function for MurmurHash3.
       
   754      * This is a 64-bit hashing function with excellent avalanche statistics.
       
   755      * https://github.com/aappleby/smhasher/wiki/MurmurHash3
       
   756      *
       
   757      * Note that if the argument {@code z} is 0, the result is 0.
       
   758      *
       
   759      * @param z any long value
       
   760      *
       
   761      * @return the result of hashing z
       
   762      */
       
   763     public static long mixMurmur64(long z) {
       
   764         z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
       
   765         z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
       
   766         return z ^ (z >>> 33);
       
   767     }
       
   768 
       
   769     /**
       
   770      * Computes Stafford variant 13 of the 64-bit mixing function for MurmurHash3.
       
   771      * This is a 64-bit hashing function with excellent avalanche statistics.
       
   772      * http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html
       
   773      *
       
   774      * Note that if the argument {@code z} is 0, the result is 0.
       
   775      *
       
   776      * @param z any long value
       
   777      *
       
   778      * @return the result of hashing z
       
   779      */
       
   780     public static long mixStafford13(long z) {
       
   781         z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L;
       
   782         z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
       
   783         return z ^ (z >>> 31);
       
   784     }
       
   785 
       
   786     /**
       
   787      * Computes Doug Lea's 64-bit mixing function.
       
   788      * This is a 64-bit hashing function with excellent avalanche statistics.
       
   789      * It has the advantages of using the same multiplicative constant twice
       
   790      * and of using only 32-bit shifts.
       
   791      *
       
   792      * Note that if the argument {@code z} is 0, the result is 0.
       
   793      *
       
   794      * @param z any long value
       
   795      *
       
   796      * @return the result of hashing z
       
   797      */
       
   798     public static long mixLea64(long z) {
       
   799         z = (z ^ (z >>> 32)) * 0xdaba0b6eb09322e3L;
       
   800         z = (z ^ (z >>> 32)) * 0xdaba0b6eb09322e3L;
       
   801         return z ^ (z >>> 32);
       
   802     }
       
   803 
       
   804     /**
       
   805      * Computes the 32-bit mixing function for MurmurHash3.
       
   806      * This is a 32-bit hashing function with excellent avalanche statistics.
       
   807      * https://github.com/aappleby/smhasher/wiki/MurmurHash3
       
   808      *
       
   809      * Note that if the argument {@code z} is 0, the result is 0.
       
   810      *
       
   811      * @param z any long value
       
   812      *
       
   813      * @return the result of hashing z
       
   814      */
       
   815     public static int mixMurmur32(int z) {
       
   816         z = (z ^ (z >>> 16)) * 0x85ebca6b;
       
   817         z = (z ^ (z >>> 13)) * 0xc2b2ae35;
       
   818         return z ^ (z >>> 16);
       
   819     }
       
   820 
       
   821     /**
       
   822      * Computes Doug Lea's 32-bit mixing function.
       
   823      * This is a 32-bit hashing function with excellent avalanche statistics.
       
   824      * It has the advantages of using the same multiplicative constant twice
       
   825      * and of using only 16-bit shifts.
       
   826      *
       
   827      * Note that if the argument {@code z} is 0, the result is 0.
       
   828      *
       
   829      * @param z any long value
       
   830      *
       
   831      * @return the result of hashing z
       
   832      */
       
   833     public static int mixLea32(int z) {
       
   834         z = (z ^ (z >>> 16)) * 0xd36d884b;
       
   835         z = (z ^ (z >>> 16)) * 0xd36d884b;
       
   836         return z ^ (z >>> 16);
       
   837     }
       
   838 
       
   839     // Non-public (package only) support for spliterators needed by AbstractSplittableGenerator
       
   840     // and AbstractArbitrarilyJumpableGenerator and AbstractSharedGenerator
       
   841 
       
   842     /**
       
   843      * Base class for making Spliterator classes for streams of randomly chosen values.
       
   844      */
       
   845     public abstract static class RandomSpliterator {
       
   846 
       
   847         /** low range value */
       
   848         public long index;
       
   849 
       
   850         /** high range value */
       
   851         public final long fence;
       
   852 
       
   853         /**
       
   854          * Constructor
       
   855          *
       
   856          * @param index  low range value
       
   857          * @param fence  high range value
       
   858          */
       
   859         public RandomSpliterator(long index, long fence) {
       
   860             this.index = index; this.fence = fence;
       
   861         }
       
   862 
       
   863         /**
       
   864          * Returns estimated size.
       
   865          *
       
   866          * @return estimated size
       
   867          */
       
   868         public long estimateSize() {
       
   869             return fence - index;
       
   870         }
       
   871 
       
   872         /**
       
   873          * Returns characteristics.
       
   874          *
       
   875          * @return characteristics
       
   876          */
       
   877         public int characteristics() {
       
   878             return (Spliterator.SIZED | Spliterator.SUBSIZED |
       
   879                     Spliterator.NONNULL | Spliterator.IMMUTABLE);
       
   880         }
       
   881     }
       
   882 
       
   883 
       
   884     /*
       
   885      * Implementation support for nextExponential() and nextGaussian() methods of RandomGenerator.
       
   886      *
       
   887      * Each is implemented using McFarland's fast modified ziggurat algorithm (largely
       
   888      * table-driven, with rare cases handled by computation and rejection sampling).
       
   889      * Walker's alias method for sampling a discrete distribution also plays a role.
       
   890      *
       
   891      * The tables themselves, as well as a number of associated parameters, are defined
       
   892      * in class java.util.DoubleZigguratTables, which is automatically generated by the
       
   893      * program create_ziggurat_tables.c (which takes only a few seconds to run).
       
   894      *
       
   895      * For more information about the algorithms, see these articles:
       
   896      *
       
   897      * Christopher D. McFarland.  2016 (published online 24 Jun 2015).  A modified ziggurat
       
   898      * algorithm for generating exponentially and normally distributed pseudorandom numbers.
       
   899      * Journal of Statistical Computation and Simulation 86 (7), pages 1281-1294.
       
   900      * https://www.tandfonline.com/doi/abs/10.1080/00949655.2015.1060234
       
   901      * Also at https://arxiv.org/abs/1403.6870 (26 March 2014).
       
   902      *
       
   903      * Alastair J. Walker.  1977.  An efficient method for generating discrete random
       
   904      * variables with general distributions. ACM Trans. Math. Software 3, 3
       
   905      * (September 1977), 253-256. DOI: https://doi.org/10.1145/355744.355749
       
   906      *
       
   907      * Certain details of these algorithms depend critically on the quality of the
       
   908      * low-order bits delivered by NextLong().  These algorithms should not be used
       
   909      * with RNG algorithms (such as a simple Linear Congruential Generator) whose
       
   910      * low-order output bits do not have good statistical quality.
       
   911      */
       
   912 
       
   913     // Implementation support for nextExponential()
       
   914 
       
   915     static double computeNextExponential(RandomGenerator rng) {
       
   916         long U1 = rng.nextLong();
       
   917         // Experimentation on a variety of machines indicates that it is overall much faster
       
   918         // to do the following & and < operations on longs rather than first cast U1 to int
       
   919         // (but then we need to cast to int before doing the array indexing operation).
       
   920         long i = U1 & DoubleZigguratTables.exponentialLayerMask;
       
   921         if (i < DoubleZigguratTables.exponentialNumberOfLayers) {
       
   922             // This is the fast path (occurring more than 98% of the time).  Make an early exit.
       
   923             return DoubleZigguratTables.exponentialX[(int)i] * (U1 >>> 1);
       
   924         }
       
   925         // We didn't use the upper part of U1 after all.  We'll be able to use it later.
       
   926 
       
   927         for (double extra = 0.0; ; ) {
       
   928             // Use Walker's alias method to sample an (unsigned) integer j from a discrete
       
   929             // probability distribution that includes the tail and all the ziggurat overhangs;
       
   930             // j will be less than DoubleZigguratTables.exponentialNumberOfLayers + 1.
       
   931             long UA = rng.nextLong();
       
   932             int j = (int)UA & DoubleZigguratTables.exponentialAliasMask;
       
   933             if (UA >= DoubleZigguratTables.exponentialAliasThreshold[j]) {
       
   934                 j = DoubleZigguratTables.exponentialAliasMap[j] & DoubleZigguratTables.exponentialSignCorrectionMask;
       
   935             }
       
   936             if (j > 0) {   // Sample overhang j
       
   937                 // For the exponential distribution, every overhang is convex.
       
   938                 final double[] X = DoubleZigguratTables.exponentialX;
       
   939                 final double[] Y = DoubleZigguratTables.exponentialY;
       
   940                 for (;; U1 = (rng.nextLong() >>> 1)) {
       
   941                     long U2 = (rng.nextLong() >>> 1);
       
   942                     // Compute the actual x-coordinate of the randomly chosen point.
       
   943                     double x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
       
   944                     // Does the point lie below the curve?
       
   945                     long Udiff = U2 - U1;
       
   946                     if (Udiff < 0) {
       
   947                         // We picked a point in the upper-right triangle.  None of those can be accepted.
       
   948                         // So remap the point into the lower-left triangle and try that.
       
   949                         // In effect, we swap U1 and U2, and invert the sign of Udiff.
       
   950                         Udiff = -Udiff;
       
   951                         U2 = U1;
       
   952                         U1 -= Udiff;
       
   953                     }
       
   954                     if (Udiff >= DoubleZigguratTables.exponentialConvexMargin) {
       
   955                         return x + extra;   // The chosen point is way below the curve; accept it.
       
   956                     }
       
   957                     // Compute the actual y-coordinate of the randomly chosen point.
       
   958                     double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
       
   959                     // Now see how that y-coordinate compares to the curve
       
   960                     if (y <= Math.exp(-x)) {
       
   961                         return x + extra;   // The chosen point is below the curve; accept it.
       
   962                     }
       
   963                     // Otherwise, we reject this sample and have to try again.
       
   964                 }
       
   965             }
       
   966             // We are now committed to sampling from the tail.  We could do a recursive call
       
   967             // and then add X[0] but we save some time and stack space by using an iterative loop.
       
   968             extra += DoubleZigguratTables.exponentialX0;
       
   969             // This is like the first five lines of this method, but if it returns, it first adds "extra".
       
   970             U1 = rng.nextLong();
       
   971             i = U1 & DoubleZigguratTables.exponentialLayerMask;
       
   972             if (i < DoubleZigguratTables.exponentialNumberOfLayers) {
       
   973                 return DoubleZigguratTables.exponentialX[(int)i] * (U1 >>> 1) + extra;
       
   974             }
       
   975         }
       
   976     }
       
   977 
       
   978     // Implementation support for nextGaussian()
       
   979 
       
   980     static double computeNextGaussian(RandomGenerator rng) {
       
   981         long U1 = rng.nextLong();
       
   982         // Experimentation on a variety of machines indicates that it is overall much faster
       
   983         // to do the following & and < operations on longs rather than first cast U1 to int
       
   984         // (but then we need to cast to int before doing the array indexing operation).
       
   985         long i = U1 & DoubleZigguratTables.normalLayerMask;
       
   986 
       
   987         if (i < DoubleZigguratTables.normalNumberOfLayers) {
       
   988             // This is the fast path (occurring more than 98% of the time).  Make an early exit.
       
   989             return DoubleZigguratTables.normalX[(int)i] * U1;   // Note that the sign bit of U1 is used here.
       
   990         }
       
   991         // We didn't use the upper part of U1 after all.
       
   992         // Pull U1 apart into a sign bit and a 63-bit value for later use.
       
   993         double signBit = (U1 >= 0) ? 1.0 : -1.0;
       
   994         U1 = (U1 << 1) >>> 1;
       
   995 
       
   996         // Use Walker's alias method to sample an (unsigned) integer j from a discrete
       
   997         // probability distribution that includes the tail and all the ziggurat overhangs;
       
   998         // j will be less than DoubleZigguratTables.normalNumberOfLayers + 1.
       
   999         long UA = rng.nextLong();
       
  1000         int j = (int)UA & DoubleZigguratTables.normalAliasMask;
       
  1001         if (UA >= DoubleZigguratTables.normalAliasThreshold[j]) {
       
  1002             j = DoubleZigguratTables.normalAliasMap[j] & DoubleZigguratTables.normalSignCorrectionMask;
       
  1003         }
       
  1004 
       
  1005         double x;
       
  1006         // Now the goal is to choose the result, which will be multiplied by signBit just before return.
       
  1007 
       
  1008         // There are four kinds of overhangs:
       
  1009         //
       
  1010         //  j == 0                          :  Sample from tail
       
  1011         //  0 < j < normalInflectionIndex   :  Overhang is convex; can reject upper-right triangle
       
  1012         //  j == normalInflectionIndex      :  Overhang includes the inflection point
       
  1013         //  j > normalInflectionIndex       :  Overhang is concave; can accept point in lower-left triangle
       
  1014         //
       
  1015         // Choose one of four loops to compute x, each specialized for a specific kind of overhang.
       
  1016         // Conditional statements are arranged such that the more likely outcomes are first.
       
  1017 
       
  1018         // In the three cases other than the tail case:
       
  1019         // U1 represents a fraction (scaled by 2**63) of the width of rectangle measured from the left.
       
  1020         // U2 represents a fraction (scaled by 2**63) of the height of rectangle measured from the top.
       
  1021         // Together they indicate a randomly chosen point within the rectangle.
       
  1022 
       
  1023         final double[] X = DoubleZigguratTables.normalX;
       
  1024         final double[] Y = DoubleZigguratTables.normalY;
       
  1025         if (j > DoubleZigguratTables.normalInflectionIndex) {   // Concave overhang
       
  1026             for (;; U1 = (rng.nextLong() >>> 1)) {
       
  1027                 long U2 = (rng.nextLong() >>> 1);
       
  1028                 // Compute the actual x-coordinate of the randomly chosen point.
       
  1029                 x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
       
  1030                 // Does the point lie below the curve?
       
  1031                 long Udiff = U2 - U1;
       
  1032                 if (Udiff >= 0) {
       
  1033                     break;   // The chosen point is in the lower-left triangle; accept it.
       
  1034                 }
       
  1035                 if (Udiff <= -DoubleZigguratTables.normalConcaveMargin) {
       
  1036                     continue;   // The chosen point is way above the curve; reject it.
       
  1037                 }
       
  1038                 // Compute the actual y-coordinate of the randomly chosen point.
       
  1039                 double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
       
  1040                 // Now see how that y-coordinate compares to the curve
       
  1041                 if (y <= Math.exp(-0.5*x*x)) {
       
  1042                     break;   // The chosen point is below the curve; accept it.
       
  1043                 }
       
  1044                 // Otherwise, we reject this sample and have to try again.
       
  1045             }
       
  1046         } else if (j == 0) {   // Tail
       
  1047             // Tail-sampling method of Marsaglia and Tsang.  See any one of:
       
  1048             // Marsaglia and Tsang. 1984. A fast, easily implemented method for sampling from decreasing
       
  1049             //    or symmetric unimodal density functions. SIAM J. Sci. Stat. Comput. 5, 349-359.
       
  1050             // Marsaglia and Tsang. 1998. The Monty Python method for generating random variables.
       
  1051             //    ACM Trans. Math. Softw. 24, 3 (September 1998), 341-350.  See page 342, step (4).
       
  1052             //    http://doi.org/10.1145/292395.292453
       
  1053             // Thomas, Luk, Leong, and Villasenor. 2007. Gaussian random number generators.
       
  1054             //    ACM Comput. Surv. 39, 4, Article 11 (November 2007).  See Algorithm 16.
       
  1055             //    http://doi.org/10.1145/1287620.1287622
       
  1056             // Compute two separate random exponential samples and then compare them in certain way.
       
  1057             do {
       
  1058                 x = (1.0 / DoubleZigguratTables.normalX0) * computeNextExponential(rng);
       
  1059             } while (computeNextExponential(rng) < 0.5*x*x);
       
  1060             x += DoubleZigguratTables.normalX0;
       
  1061         } else if (j < DoubleZigguratTables.normalInflectionIndex) {   // Convex overhang
       
  1062             for (;; U1 = (rng.nextLong() >>> 1)) {
       
  1063                 long U2 = (rng.nextLong() >>> 1);
       
  1064                 // Compute the actual x-coordinate of the randomly chosen point.
       
  1065                 x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
       
  1066                 // Does the point lie below the curve?
       
  1067                 long Udiff = U2 - U1;
       
  1068                 if (Udiff < 0) {
       
  1069                     // We picked a point in the upper-right triangle.  None of those can be accepted.
       
  1070                     // So remap the point into the lower-left triangle and try that.
       
  1071                     // In effect, we swap U1 and U2, and invert the sign of Udiff.
       
  1072                     Udiff = -Udiff;
       
  1073                     U2 = U1;
       
  1074                     U1 -= Udiff;
       
  1075                 }
       
  1076                 if (Udiff >= DoubleZigguratTables.normalConvexMargin) {
       
  1077                     break;   // The chosen point is way below the curve; accept it.
       
  1078                 }
       
  1079                 // Compute the actual y-coordinate of the randomly chosen point.
       
  1080                 double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
       
  1081                 // Now see how that y-coordinate compares to the curve
       
  1082                 if (y <= Math.exp(-0.5*x*x)) break;                // The chosen point is below the curve; accept it.
       
  1083                 // Otherwise, we reject this sample and have to try again.
       
  1084             }
       
  1085         } else {
       
  1086             // The overhang includes the inflection point, so the curve is both convex and concave
       
  1087             for (;; U1 = (rng.nextLong() >>> 1)) {
       
  1088                 long U2 = (rng.nextLong() >>> 1);
       
  1089                 // Compute the actual x-coordinate of the randomly chosen point.
       
  1090                 x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
       
  1091                 // Does the point lie below the curve?
       
  1092                 long Udiff = U2 - U1;
       
  1093                 if (Udiff >= DoubleZigguratTables.normalConvexMargin) {
       
  1094                     break;   // The chosen point is way below the curve; accept it.
       
  1095                 }
       
  1096                 if (Udiff <= -DoubleZigguratTables.normalConcaveMargin) {
       
  1097                     continue;   // The chosen point is way above the curve; reject it.
       
  1098                 }
       
  1099                 // Compute the actual y-coordinate of the randomly chosen point.
       
  1100                 double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
       
  1101                 // Now see how that y-coordinate compares to the curve
       
  1102                 if (y <= Math.exp(-0.5*x*x)) {
       
  1103                     break;   // The chosen point is below the curve; accept it.
       
  1104                 }
       
  1105                 // Otherwise, we reject this sample and have to try again.
       
  1106             }
       
  1107         }
       
  1108         return signBit*x;
       
  1109     }
       
  1110 
       
  1111     /**
       
  1112      * This class overrides the stream-producing methods (such as {@code ints()})
       
  1113      * in class {@link AbstractGenerator} to provide {@link Spliterator}-based
       
  1114      * implmentations that support potentially parallel execution.
       
  1115      *
       
  1116      * To implement a pseudorandom number generator, the programmer needs
       
  1117      * only to extend this class and provide implementations for the methods
       
  1118      * {@code nextInt()}, {@code nextLong()}, {@code makeIntsSpliterator},
       
  1119      * {@code makeLongsSpliterator}, and {@code makeDoublesSpliterator}.
       
  1120      *
       
  1121      * This class is not public; it provides shared code to the public
       
  1122      * classes {@link AbstractSplittableGenerator}, {@link AbstractSharedGenerator},
       
  1123      * and {@link AbstractArbitrarilyJumpableGenerator}.
       
  1124      *
       
  1125      * @since 14
       
  1126      */
       
  1127     public abstract static class AbstractSpliteratorGenerator implements RandomGenerator {
       
  1128         /*
       
  1129          * Implementation Overview.
       
  1130          *
       
  1131          * This class provides most of the "user API" methods needed to
       
  1132          * satisfy the interface RandomGenerator.  An implementation of this
       
  1133          * interface need only extend this class and provide implementations
       
  1134          * of six methods: nextInt, nextLong, and nextDouble (the versions
       
  1135          * that take no arguments) and makeIntsSpliterator,
       
  1136          * makeLongsSpliterator, and makeDoublesSpliterator.
       
  1137          *
       
  1138          * File organization: First the non-public abstract methods needed
       
  1139          * to create spliterators, then the main public methods.
       
  1140          */
       
  1141 
       
  1142         /**
       
  1143          * Needs comment (was made public to be overridden out of package.)
       
  1144          *
       
  1145          * @param index low
       
  1146          * @param fence high
       
  1147          * @param origin low
       
  1148          * @param bound high
       
  1149          * @return result
       
  1150          */
       
  1151         public abstract Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound);
       
  1152 
       
  1153         /**
       
  1154          * Needs comment (was made public to be overridden out of package.)
       
  1155          *
       
  1156          * @param index low
       
  1157          * @param fence high
       
  1158          * @param origin low
       
  1159          * @param bound high
       
  1160          * @return result
       
  1161          */
       
  1162         public abstract Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound);
       
  1163 
       
  1164         /**
       
  1165          * Needs comment (was made public to be overridden out of package.)
       
  1166          *
       
  1167          * @param index low
       
  1168          * @param fence high
       
  1169          * @param origin low
       
  1170          * @param bound high
       
  1171          * @return result
       
  1172          */
       
  1173         public abstract Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound);
       
  1174 
       
  1175         /* ---------------- public methods ---------------- */
       
  1176 
       
  1177         // stream methods, coded in a way intended to better isolate for
       
  1178         // maintenance purposes the small differences across forms.
       
  1179 
       
  1180         private static IntStream intStream(Spliterator.OfInt srng) {
       
  1181             return StreamSupport.intStream(srng, false);
       
  1182         }
       
  1183 
       
  1184         private static LongStream longStream(Spliterator.OfLong srng) {
       
  1185             return StreamSupport.longStream(srng, false);
       
  1186         }
       
  1187 
       
  1188         private static DoubleStream doubleStream(Spliterator.OfDouble srng) {
       
  1189             return StreamSupport.doubleStream(srng, false);
       
  1190         }
       
  1191 
       
  1192         /**
       
  1193          * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code int}
       
  1194          * values from this generator and/or one split from it.
       
  1195          *
       
  1196          * @param streamSize the number of values to generate
       
  1197          *
       
  1198          * @return a stream of pseudorandom {@code int} values
       
  1199          *
       
  1200          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1201          */
       
  1202         public IntStream ints(long streamSize) {
       
  1203             RandomSupport.checkStreamSize(streamSize);
       
  1204             return intStream(makeIntsSpliterator(0L, streamSize, Integer.MAX_VALUE, 0));
       
  1205         }
       
  1206 
       
  1207         /**
       
  1208          * Returns an effectively unlimited stream of pseudorandomly chosen
       
  1209          * {@code int} values.
       
  1210          *
       
  1211          * @implNote The implementation of this method is effectively
       
  1212          * equivalent to {@code ints(Long.MAX_VALUE)}.
       
  1213          *
       
  1214          * @return a stream of pseudorandomly chosen {@code int} values
       
  1215          */
       
  1216 
       
  1217         public IntStream ints() {
       
  1218             return intStream(makeIntsSpliterator(0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0));
       
  1219         }
       
  1220 
       
  1221         /**
       
  1222          * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code int}
       
  1223          * values from this generator and/or one split from it; each value conforms to the given origin
       
  1224          * (inclusive) and bound (exclusive).
       
  1225          *
       
  1226          * @param streamSize         the number of values to generate
       
  1227          * @param randomNumberOrigin the origin (inclusive) of each random value
       
  1228          * @param randomNumberBound  the bound (exclusive) of each random value
       
  1229          *
       
  1230          * @return a stream of pseudorandom {@code int} values, each with the given origin (inclusive)
       
  1231          *         and bound (exclusive)
       
  1232          *
       
  1233          * @throws IllegalArgumentException if {@code streamSize} is less than zero, or {@code
       
  1234          *                                  randomNumberOrigin} is greater than or equal to {@code
       
  1235          *                                  randomNumberBound}
       
  1236          */
       
  1237         public IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound) {
       
  1238             RandomSupport.checkStreamSize(streamSize);
       
  1239             RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
  1240             return intStream(makeIntsSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
       
  1241         }
       
  1242 
       
  1243         /**
       
  1244          * Returns an effectively unlimited stream of pseudorandom {@code int} values from this
       
  1245          * generator and/or one split from it; each value conforms to the given origin (inclusive) and
       
  1246          * bound (exclusive).
       
  1247          *
       
  1248          * @param randomNumberOrigin the origin (inclusive) of each random value
       
  1249          * @param randomNumberBound  the bound (exclusive) of each random value
       
  1250          *
       
  1251          * @return a stream of pseudorandom {@code int} values, each with the given origin (inclusive)
       
  1252          *         and bound (exclusive)
       
  1253          *
       
  1254          * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
       
  1255          *                                  {@code randomNumberBound}
       
  1256          *
       
  1257          * @implNote This method is implemented to be equivalent to {@code ints(Long.MAX_VALUE,
       
  1258          *         randomNumberOrigin, randomNumberBound)}.
       
  1259          */
       
  1260         public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
       
  1261             RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
  1262             return intStream(makeIntsSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound));
       
  1263         }
       
  1264 
       
  1265         /**
       
  1266          * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code long}
       
  1267          * values from this generator and/or one split from it.
       
  1268          *
       
  1269          * @param streamSize the number of values to generate
       
  1270          *
       
  1271          * @return a stream of pseudorandom {@code long} values
       
  1272          *
       
  1273          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1274          */
       
  1275         public LongStream longs(long streamSize) {
       
  1276             RandomSupport.checkStreamSize(streamSize);
       
  1277             return longStream(makeLongsSpliterator(0L, streamSize, Long.MAX_VALUE, 0L));
       
  1278         }
       
  1279 
       
  1280         /**
       
  1281          * Returns an effectively unlimited stream of pseudorandom {@code long} values from this
       
  1282          * generator and/or one split from it.
       
  1283          *
       
  1284          * @return a stream of pseudorandom {@code long} values
       
  1285          *
       
  1286          * @implNote This method is implemented to be equivalent to {@code
       
  1287          *         longs(Long.MAX_VALUE)}.
       
  1288          */
       
  1289         public LongStream longs() {
       
  1290             return longStream(makeLongsSpliterator(0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L));
       
  1291         }
       
  1292 
       
  1293         /**
       
  1294          * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code long}
       
  1295          * values from this generator and/or one split from it; each value conforms to the given origin
       
  1296          * (inclusive) and bound (exclusive).
       
  1297          *
       
  1298          * @param streamSize         the number of values to generate
       
  1299          * @param randomNumberOrigin the origin (inclusive) of each random value
       
  1300          * @param randomNumberBound  the bound (exclusive) of each random value
       
  1301          *
       
  1302          * @return a stream of pseudorandom {@code long} values, each with the given origin (inclusive)
       
  1303          *         and bound (exclusive)
       
  1304          *
       
  1305          * @throws IllegalArgumentException if {@code streamSize} is less than zero, or {@code
       
  1306          *                                  randomNumberOrigin} is greater than or equal to {@code
       
  1307          *                                  randomNumberBound}
       
  1308          */
       
  1309         public LongStream longs(long streamSize, long randomNumberOrigin,
       
  1310                                  long randomNumberBound) {
       
  1311             RandomSupport.checkStreamSize(streamSize);
       
  1312             RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
  1313             return longStream(makeLongsSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
       
  1314         }
       
  1315 
       
  1316         /**
       
  1317          * Returns an effectively unlimited stream of pseudorandom {@code long} values from this
       
  1318          * generator and/or one split from it; each value conforms to the given origin (inclusive) and
       
  1319          * bound (exclusive).
       
  1320          *
       
  1321          * @param randomNumberOrigin the origin (inclusive) of each random value
       
  1322          * @param randomNumberBound  the bound (exclusive) of each random value
       
  1323          *
       
  1324          * @return a stream of pseudorandom {@code long} values, each with the given origin (inclusive)
       
  1325          *         and bound (exclusive)
       
  1326          *
       
  1327          * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
       
  1328          *                                  {@code randomNumberBound}
       
  1329          *
       
  1330          * @implNote This method is implemented to be equivalent to {@code longs(Long.MAX_VALUE,
       
  1331          *         randomNumberOrigin, randomNumberBound)}.
       
  1332          */
       
  1333         public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
       
  1334             RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
  1335             return StreamSupport.longStream
       
  1336                 (makeLongsSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
       
  1337                  false);
       
  1338         }
       
  1339 
       
  1340         /**
       
  1341          * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code double}
       
  1342          * values from this generator and/or one split from it; each value is between zero (inclusive)
       
  1343          * and one (exclusive).
       
  1344          *
       
  1345          * @param streamSize the number of values to generate
       
  1346          *
       
  1347          * @return a stream of {@code double} values
       
  1348          *
       
  1349          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1350          */
       
  1351         public DoubleStream doubles(long streamSize) {
       
  1352             RandomSupport.checkStreamSize(streamSize);
       
  1353             return doubleStream(makeDoublesSpliterator(0L, streamSize, Double.MAX_VALUE, 0.0));
       
  1354         }
       
  1355 
       
  1356         /**
       
  1357          * Returns an effectively unlimited stream of pseudorandom {@code double} values from this
       
  1358          * generator and/or one split from it; each value is between zero (inclusive) and one
       
  1359          * (exclusive).
       
  1360          *
       
  1361          * @return a stream of pseudorandom {@code double} values
       
  1362          *
       
  1363          * @implNote This method is implemented to be equivalent to {@code
       
  1364          *         doubles(Long.MAX_VALUE)}.
       
  1365          */
       
  1366         public DoubleStream doubles() {
       
  1367             return doubleStream(makeDoublesSpliterator(0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0));
       
  1368         }
       
  1369 
       
  1370         /**
       
  1371          * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code double}
       
  1372          * values from this generator and/or one split from it; each value conforms to the given origin
       
  1373          * (inclusive) and bound (exclusive).
       
  1374          *
       
  1375          * @param streamSize         the number of values to generate
       
  1376          * @param randomNumberOrigin the origin (inclusive) of each random value
       
  1377          * @param randomNumberBound  the bound (exclusive) of each random value
       
  1378          *
       
  1379          * @return a stream of pseudorandom {@code double} values, each with the given origin
       
  1380          *         (inclusive) and bound (exclusive)
       
  1381          *
       
  1382          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1383          * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
       
  1384          *                                  {@code randomNumberBound}
       
  1385          */
       
  1386         public DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) {
       
  1387             RandomSupport.checkStreamSize(streamSize);
       
  1388             RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
  1389             return doubleStream(makeDoublesSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
       
  1390         }
       
  1391 
       
  1392         /**
       
  1393          * Returns an effectively unlimited stream of pseudorandom {@code double} values from this
       
  1394          * generator and/or one split from it; each value conforms to the given origin (inclusive) and
       
  1395          * bound (exclusive).
       
  1396          *
       
  1397          * @param randomNumberOrigin the origin (inclusive) of each random value
       
  1398          * @param randomNumberBound  the bound (exclusive) of each random value
       
  1399          *
       
  1400          * @return a stream of pseudorandom {@code double} values, each with the given origin
       
  1401          *         (inclusive) and bound (exclusive)
       
  1402          *
       
  1403          * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
       
  1404          *                                  {@code randomNumberBound}
       
  1405          *
       
  1406          * @implNote This method is implemented to be equivalent to {@code
       
  1407          *         doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
       
  1408          */
       
  1409         public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
       
  1410             RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
  1411             return doubleStream(makeDoublesSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound));
       
  1412         }
       
  1413 
       
  1414     }
       
  1415 
       
  1416     /**
       
  1417      * This class provides much of the implementation of the
       
  1418      * {@link ArbitrarilyJumpableGenerator} interface, to minimize the effort
       
  1419      * required to implement that interface.
       
  1420      *
       
  1421      * To implement a pseudorandom number generator, the programmer needs
       
  1422      * only to extend this class and provide implementations for the
       
  1423      * methods {@link #nextInt()}, {@link #nextLong()}, {@link #copy()},
       
  1424      * {@link #jump(double)}, {@link #jumpPowerOfTwo(int)},
       
  1425      * {@link #defaultJumpDistance()}, and {@link #defaultLeapDistance()}.
       
  1426      *
       
  1427      * (If the pseudorandom number generator also has the ability to split,
       
  1428      * then the programmer may wish to consider instead extending
       
  1429      * {@link AbstractSplittableGenerator}.)
       
  1430      *
       
  1431      * The programmer should generally provide at least three constructors:
       
  1432      * one that takes no arguments, one that accepts a {@code long}
       
  1433      * seed value, and one that accepts an array of seed {@code byte} values.
       
  1434      * This class provides a public {@code initialSeed()} method that may
       
  1435      * be useful in initializing some static state from which to derive
       
  1436      * defaults seeds for use by the no-argument constructor.
       
  1437      *
       
  1438      * For the stream methods (such as {@code ints()} and {@code splits()}),
       
  1439      * this class provides {@link Spliterator}-based implementations that
       
  1440      * allow parallel execution when appropriate.  In this respect
       
  1441      * {@link ArbitrarilyJumpableGenerator} differs from {@link JumpableGenerator},
       
  1442      * which provides very simple implementations that produce
       
  1443      * sequential streams only.
       
  1444      *
       
  1445      * <p>An implementation of the {@link AbstractArbitrarilyJumpableGenerator} class
       
  1446      * must provide concrete definitions for the methods {@code nextInt()},
       
  1447      * {@code nextLong}, {@code period()}, {@code copy()}, {@code jump(double)},
       
  1448      * {@code defaultJumpDistance()}, and {@code defaultLeapDistance()}.
       
  1449      * Default implementations are provided for all other methods.
       
  1450      *
       
  1451      * The documentation for each non-abstract method in this class
       
  1452      * describes its implementation in detail. Each of these methods may
       
  1453      * be overridden if the pseudorandom number generator being
       
  1454      * implemented admits a more efficient implementation.
       
  1455      *
       
  1456      * @since 14
       
  1457      */
       
  1458     public abstract static class AbstractArbitrarilyJumpableGenerator
       
  1459         extends AbstractSpliteratorGenerator implements RandomGenerator.ArbitrarilyJumpableGenerator {
       
  1460 
       
  1461         /*
       
  1462          * Implementation Overview.
       
  1463          *
       
  1464          * This class provides most of the "user API" methods needed to satisfy
       
  1465          * the interface ArbitrarilyJumpableGenerator.  Most of these methods
       
  1466          * are in turn inherited from AbstractGenerator and the non-public class
       
  1467          * AbstractSpliteratorGenerator; this file implements four versions of the
       
  1468          * jumps method and defines the spliterators necessary to support them.
       
  1469          *
       
  1470          * File organization: First the non-public methods needed by the class
       
  1471          * AbstractSpliteratorGenerator, then the main public methods, followed by some
       
  1472          * custom spliterator classes needed for stream methods.
       
  1473          */
       
  1474 
       
  1475         // IllegalArgumentException messages
       
  1476         static final String BadLogDistance  = "logDistance must be non-negative";
       
  1477 
       
  1478         // Methods required by class AbstractSpliteratorGenerator
       
  1479         public Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) {
       
  1480             return new RandomIntsSpliterator(this, index, fence, origin, bound);
       
  1481         }
       
  1482         public Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound) {
       
  1483             return new RandomLongsSpliterator(this, index, fence, origin, bound);
       
  1484         }
       
  1485         public Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound) {
       
  1486             return new RandomDoublesSpliterator(this, index, fence, origin, bound);
       
  1487         }
       
  1488 
       
  1489         // Similar methods used by this class
       
  1490         Spliterator<RandomGenerator> makeJumpsSpliterator(long index, long fence, double distance) {
       
  1491             return new RandomJumpsSpliterator(this, index, fence, distance);
       
  1492         }
       
  1493         Spliterator<JumpableGenerator> makeLeapsSpliterator(long index, long fence, double distance) {
       
  1494             return new RandomLeapsSpliterator(this, index, fence, distance);
       
  1495         }
       
  1496         Spliterator<ArbitrarilyJumpableGenerator> makeArbitraryJumpsSpliterator(long index, long fence, double distance) {
       
  1497             return new RandomArbitraryJumpsSpliterator(this, index, fence, distance);
       
  1498         }
       
  1499 
       
  1500         /* ---------------- public methods ---------------- */
       
  1501 
       
  1502         /**
       
  1503          * Returns a new generator whose internal state is an exact copy
       
  1504          * of this generator (therefore their future behavior should be
       
  1505          * identical if subjected to the same series of operations).
       
  1506          *
       
  1507          * @return a new object that is a copy of this generator
       
  1508          */
       
  1509         public abstract AbstractArbitrarilyJumpableGenerator copy();
       
  1510 
       
  1511         // Stream methods for jumping
       
  1512 
       
  1513         private static <T> Stream<T> stream(Spliterator<T> srng) {
       
  1514             return StreamSupport.stream(srng, false);
       
  1515         }
       
  1516 
       
  1517         /**
       
  1518          * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
       
  1519          * implements the {@link RandomGenerator} interface, produced by jumping copies of this
       
  1520          * generator by different integer multiples of the default jump distance.
       
  1521          *
       
  1522          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1523          *
       
  1524          * @implNote This method is implemented to be equivalent to {@code
       
  1525          *         jumps(Long.MAX_VALUE)}.
       
  1526          */
       
  1527         public Stream<RandomGenerator> jumps() {
       
  1528             return stream(makeJumpsSpliterator(0L, Long.MAX_VALUE, defaultJumpDistance()));
       
  1529         }
       
  1530 
       
  1531         /**
       
  1532          * Returns a stream producing the given {@code streamSize} number of
       
  1533          * new pseudorandom number generators, each of which implements the
       
  1534          * {@link RandomGenerator} interface, produced by jumping copies of this generator
       
  1535          * by different integer multiples of the default jump distance.
       
  1536          *
       
  1537          * @param streamSize the number of generators to generate
       
  1538          *
       
  1539          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1540          *
       
  1541          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1542          */
       
  1543         public Stream<RandomGenerator> jumps(long streamSize) {
       
  1544             RandomSupport.checkStreamSize(streamSize);
       
  1545             return stream(makeJumpsSpliterator(0L, streamSize, defaultJumpDistance()));
       
  1546         }
       
  1547 
       
  1548         /**
       
  1549          * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
       
  1550          * implements the {@link RandomGenerator} interface, produced by jumping copies of this
       
  1551          * generator by different integer multiples of the specified jump distance.
       
  1552          *
       
  1553          * @param distance a distance to jump forward within the state cycle
       
  1554          *
       
  1555          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1556          *
       
  1557          * @implNote This method is implemented to be equivalent to {@code
       
  1558          *         jumps(Long.MAX_VALUE)}.
       
  1559          */
       
  1560         public Stream<ArbitrarilyJumpableGenerator> jumps(double distance) {
       
  1561             return stream(makeArbitraryJumpsSpliterator(0L, Long.MAX_VALUE, distance));
       
  1562         }
       
  1563 
       
  1564         /**
       
  1565          * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
       
  1566          * generators, each of which implements the {@link RandomGenerator} interface, produced by
       
  1567          * jumping copies of this generator by different integer multiples of the specified jump
       
  1568          * distance.
       
  1569          *
       
  1570          * @param streamSize the number of generators to generate
       
  1571          * @param distance   a distance to jump forward within the state cycle
       
  1572          *
       
  1573          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1574          *
       
  1575          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1576          */
       
  1577         public Stream<ArbitrarilyJumpableGenerator> jumps(long streamSize, double distance) {
       
  1578             RandomSupport.checkStreamSize(streamSize);
       
  1579             return stream(makeArbitraryJumpsSpliterator(0L, streamSize, distance));
       
  1580         }
       
  1581 
       
  1582         /**
       
  1583          * Alter the state of this pseudorandom number generator so as to
       
  1584          * jump forward a very large, fixed distance (typically 2<sup>128</sup>
       
  1585          * or more) within its state cycle.  The distance used is that
       
  1586          * returned by method {@code defaultLeapDistance()}.
       
  1587          */
       
  1588         public void leap() {
       
  1589             jump(defaultLeapDistance());
       
  1590         }
       
  1591 
       
  1592         // Stream methods for leaping
       
  1593 
       
  1594         /**
       
  1595          * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
       
  1596          * implements the {@link RandomGenerator} interface, produced by jumping copies of this
       
  1597          * generator by different integer multiples of the default leap distance.
       
  1598          *
       
  1599          * @implNote This method is implemented to be equivalent to {@code leaps(Long.MAX_VALUE)}.
       
  1600          *
       
  1601          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1602          */
       
  1603         public Stream<JumpableGenerator> leaps() {
       
  1604             return stream(makeLeapsSpliterator(0L, Long.MAX_VALUE, defaultLeapDistance()));
       
  1605         }
       
  1606 
       
  1607         /**
       
  1608          * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
       
  1609          * generators, each of which implements the {@link RandomGenerator} interface, produced by
       
  1610          * jumping copies of this generator by different integer multiples of the default leap
       
  1611          * distance.
       
  1612          *
       
  1613          * @param streamSize the number of generators to generate
       
  1614          *
       
  1615          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1616          *
       
  1617          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1618          */
       
  1619         public Stream<JumpableGenerator> leaps(long streamSize) {
       
  1620             return stream(makeLeapsSpliterator(0L, streamSize, defaultLeapDistance()));
       
  1621         }
       
  1622 
       
  1623 
       
  1624         /**
       
  1625          * Spliterator for int streams.  We multiplex the four int versions into one class by treating a
       
  1626          * bound less than origin as unbounded, and also by treating "infinite" as equivalent to
       
  1627          * {@code Long.MAX_VALUE}. For splits, we choose to override the method {@code trySplit()} to
       
  1628          * try to optimize execution speed: instead of dividing a range in half, it breaks off the
       
  1629          * largest possible chunk whose size is a power of two such that the remaining chunk is not
       
  1630          * empty. In this way, the necessary jump distances will tend to be powers of two.  The long
       
  1631          * and double versions of this class are identical except for types.
       
  1632          */
       
  1633         static class RandomIntsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfInt {
       
  1634             final ArbitrarilyJumpableGenerator generatingGenerator;
       
  1635             final int origin;
       
  1636             final int bound;
       
  1637 
       
  1638             RandomIntsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, int origin, int bound) {
       
  1639                 super(index, fence);
       
  1640                 this.origin = origin; this.bound = bound;
       
  1641                 this.generatingGenerator = generatingGenerator;
       
  1642             }
       
  1643 
       
  1644             public Spliterator.OfInt trySplit() {
       
  1645                 long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
       
  1646                 if (m <= i) return null;
       
  1647                 index = m;
       
  1648                 ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1649                 return new RandomIntsSpliterator(r.copyAndJump((double)delta), i, m, origin, bound);
       
  1650             }
       
  1651 
       
  1652             public boolean tryAdvance(IntConsumer consumer) {
       
  1653                 if (consumer == null) throw new NullPointerException();
       
  1654                 long i = index, f = fence;
       
  1655                 if (i < f) {
       
  1656                     consumer.accept(RandomSupport.boundedNextInt(generatingGenerator, origin, bound));
       
  1657                     index = i + 1;
       
  1658                     return true;
       
  1659                 }
       
  1660                 else return false;
       
  1661             }
       
  1662 
       
  1663             public void forEachRemaining(IntConsumer consumer) {
       
  1664                 if (consumer == null) throw new NullPointerException();
       
  1665                 long i = index, f = fence;
       
  1666                 if (i < f) {
       
  1667                     index = f;
       
  1668                     ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1669                     int o = origin, b = bound;
       
  1670                     do {
       
  1671                         consumer.accept(RandomSupport.boundedNextInt(r, o, b));
       
  1672                     } while (++i < f);
       
  1673                 }
       
  1674             }
       
  1675         }
       
  1676 
       
  1677         /**
       
  1678          * Spliterator for long streams.
       
  1679          */
       
  1680         static class RandomLongsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfLong {
       
  1681             final ArbitrarilyJumpableGenerator generatingGenerator;
       
  1682             final long origin;
       
  1683             final long bound;
       
  1684 
       
  1685             RandomLongsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, long origin, long bound) {
       
  1686                 super(index, fence);
       
  1687                 this.generatingGenerator = generatingGenerator;
       
  1688                 this.origin = origin; this.bound = bound;
       
  1689             }
       
  1690 
       
  1691             public Spliterator.OfLong trySplit() {
       
  1692                 long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
       
  1693                 if (m <= i) return null;
       
  1694                 index = m;
       
  1695                 ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1696                 return new RandomLongsSpliterator(r.copyAndJump((double)delta), i, m, origin, bound);
       
  1697             }
       
  1698 
       
  1699             public boolean tryAdvance(LongConsumer consumer) {
       
  1700                 if (consumer == null) throw new NullPointerException();
       
  1701                 long i = index, f = fence;
       
  1702                 if (i < f) {
       
  1703                     consumer.accept(RandomSupport.boundedNextLong(generatingGenerator, origin, bound));
       
  1704                     index = i + 1;
       
  1705                     return true;
       
  1706                 }
       
  1707                 else return false;
       
  1708             }
       
  1709 
       
  1710             public void forEachRemaining(LongConsumer consumer) {
       
  1711                 if (consumer == null) throw new NullPointerException();
       
  1712                 long i = index, f = fence;
       
  1713                 if (i < f) {
       
  1714                     index = f;
       
  1715                     ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1716                     long o = origin, b = bound;
       
  1717                     do {
       
  1718                         consumer.accept(RandomSupport.boundedNextLong(r, o, b));
       
  1719                     } while (++i < f);
       
  1720                 }
       
  1721             }
       
  1722         }
       
  1723 
       
  1724         /**
       
  1725          * Spliterator for double streams.
       
  1726          */
       
  1727         static class RandomDoublesSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfDouble {
       
  1728             final ArbitrarilyJumpableGenerator generatingGenerator;
       
  1729             final double origin;
       
  1730             final double bound;
       
  1731 
       
  1732             RandomDoublesSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, double origin, double bound) {
       
  1733                 super(index, fence);
       
  1734                 this.generatingGenerator = generatingGenerator;
       
  1735                 this.origin = origin; this.bound = bound;
       
  1736             }
       
  1737 
       
  1738             public Spliterator.OfDouble trySplit() {
       
  1739 
       
  1740                 long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
       
  1741                 if (m <= i) return null;
       
  1742                 index = m;
       
  1743                 ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1744                 return new RandomDoublesSpliterator(r.copyAndJump((double)delta), i, m, origin, bound);
       
  1745             }
       
  1746 
       
  1747             public boolean tryAdvance(DoubleConsumer consumer) {
       
  1748                 if (consumer == null) throw new NullPointerException();
       
  1749                 long i = index, f = fence;
       
  1750                 if (i < f) {
       
  1751                     consumer.accept(RandomSupport.boundedNextDouble(generatingGenerator, origin, bound));
       
  1752                     index = i + 1;
       
  1753                     return true;
       
  1754                 }
       
  1755                 else return false;
       
  1756             }
       
  1757 
       
  1758             public void forEachRemaining(DoubleConsumer consumer) {
       
  1759                 if (consumer == null) throw new NullPointerException();
       
  1760                 long i = index, f = fence;
       
  1761                 if (i < f) {
       
  1762                     index = f;
       
  1763                     ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1764                     double o = origin, b = bound;
       
  1765                     do {
       
  1766                         consumer.accept(RandomSupport.boundedNextDouble(r, o, b));
       
  1767                     } while (++i < f);
       
  1768                 }
       
  1769             }
       
  1770         }
       
  1771 
       
  1772         // Spliterators for producing new generators by jumping or leaping.  The
       
  1773         // complete implementation of each of these spliterators is right here.
       
  1774         // In the same manner as for the preceding spliterators, the method trySplit() is
       
  1775         // coded to optimize execution speed: instead of dividing a range
       
  1776         // in half, it breaks off the largest possible chunk whose
       
  1777         // size is a power of two such that the remaining chunk is not
       
  1778         // empty.  In this way, the necessary jump distances will tend to be
       
  1779         // powers of two.
       
  1780 
       
  1781         /**
       
  1782          * Spliterator for stream of generators of type RandomGenerator produced by jumps.
       
  1783          */
       
  1784         static class RandomJumpsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator<RandomGenerator> {
       
  1785             ArbitrarilyJumpableGenerator generatingGenerator;
       
  1786             final double distance;
       
  1787 
       
  1788             RandomJumpsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, double distance) {
       
  1789                 super(index, fence);
       
  1790                 this.generatingGenerator = generatingGenerator; this.distance = distance;
       
  1791             }
       
  1792 
       
  1793             public Spliterator<RandomGenerator> trySplit() {
       
  1794                 long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
       
  1795                 if (m <= i) return null;
       
  1796                 index = m;
       
  1797                 ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1798                 // Because delta is a power of two, (distance * (double)delta) can always be computed exactly.
       
  1799                 return new RandomJumpsSpliterator(r.copyAndJump(distance * (double)delta), i, m, distance);
       
  1800             }
       
  1801 
       
  1802             public boolean tryAdvance(Consumer<? super RandomGenerator> consumer) {
       
  1803                 if (consumer == null) throw new NullPointerException();
       
  1804                 long i = index, f = fence;
       
  1805                 if (i < f) {
       
  1806                     consumer.accept(generatingGenerator.copyAndJump(distance));
       
  1807                     index = i + 1;
       
  1808                     return true;
       
  1809                 }
       
  1810                 return false;
       
  1811             }
       
  1812 
       
  1813             public void forEachRemaining(Consumer<? super RandomGenerator> consumer) {
       
  1814                 if (consumer == null) throw new NullPointerException();
       
  1815                 long i = index, f = fence;
       
  1816                 if (i < f) {
       
  1817                     index = f;
       
  1818                     ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1819                     do {
       
  1820                         consumer.accept(r.copyAndJump(distance));
       
  1821                     } while (++i < f);
       
  1822                 }
       
  1823             }
       
  1824         }
       
  1825 
       
  1826         /**
       
  1827          * Spliterator for stream of generators of type RandomGenerator produced by leaps.
       
  1828          */
       
  1829         static class RandomLeapsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator<JumpableGenerator> {
       
  1830             ArbitrarilyJumpableGenerator generatingGenerator;
       
  1831             final double distance;
       
  1832 
       
  1833             RandomLeapsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, double distance) {
       
  1834                 super(index, fence);
       
  1835                 this.generatingGenerator = generatingGenerator; this.distance = distance;
       
  1836             }
       
  1837 
       
  1838             public Spliterator<JumpableGenerator> trySplit() {
       
  1839                 long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
       
  1840                 if (m <= i) return null;
       
  1841                 index = m;
       
  1842                 // Because delta is a power of two, (distance * (double)delta) can always be computed exactly.
       
  1843                 return new RandomLeapsSpliterator(generatingGenerator.copyAndJump(distance * (double)delta), i, m, distance);
       
  1844             }
       
  1845 
       
  1846             public boolean tryAdvance(Consumer<? super JumpableGenerator> consumer) {
       
  1847                 if (consumer == null) throw new NullPointerException();
       
  1848                 long i = index, f = fence;
       
  1849                 if (i < f) {
       
  1850                     consumer.accept(generatingGenerator.copyAndJump(distance));
       
  1851                     index = i + 1;
       
  1852                     return true;
       
  1853                 }
       
  1854                 return false;
       
  1855             }
       
  1856 
       
  1857             public void forEachRemaining(Consumer<? super JumpableGenerator> consumer) {
       
  1858                 if (consumer == null) throw new NullPointerException();
       
  1859                 long i = index, f = fence;
       
  1860                 if (i < f) {
       
  1861                     index = f;
       
  1862                     ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1863                     do {
       
  1864                         consumer.accept(r.copyAndJump(distance));
       
  1865                     } while (++i < f);
       
  1866                 }
       
  1867             }
       
  1868         }
       
  1869 
       
  1870         /**
       
  1871          * Spliterator for stream of generators of type RandomGenerator produced by arbitrary jumps.
       
  1872          */
       
  1873         static class RandomArbitraryJumpsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator<ArbitrarilyJumpableGenerator> {
       
  1874             ArbitrarilyJumpableGenerator generatingGenerator;
       
  1875             final double distance;
       
  1876 
       
  1877             RandomArbitraryJumpsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, double distance) {
       
  1878                 super(index, fence);
       
  1879                 this.generatingGenerator = generatingGenerator; this.distance = distance;
       
  1880             }
       
  1881 
       
  1882             public Spliterator<ArbitrarilyJumpableGenerator> trySplit() {
       
  1883                 long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
       
  1884                 if (m <= i) return null;
       
  1885                 index = m;
       
  1886                 // Because delta is a power of two, (distance * (double)delta) can always be computed exactly.
       
  1887                 return new RandomArbitraryJumpsSpliterator(generatingGenerator.copyAndJump(distance * (double)delta), i, m, distance);
       
  1888             }
       
  1889 
       
  1890             public boolean tryAdvance(Consumer<? super ArbitrarilyJumpableGenerator> consumer) {
       
  1891                 if (consumer == null) throw new NullPointerException();
       
  1892                 long i = index, f = fence;
       
  1893                 if (i < f) {
       
  1894                     consumer.accept(generatingGenerator.copyAndJump(distance));
       
  1895                     index = i + 1;
       
  1896                     return true;
       
  1897                 }
       
  1898                 return false;
       
  1899             }
       
  1900 
       
  1901             public void forEachRemaining(Consumer<? super ArbitrarilyJumpableGenerator> consumer) {
       
  1902                 if (consumer == null) throw new NullPointerException();
       
  1903                 long i = index, f = fence;
       
  1904                 if (i < f) {
       
  1905                     index = f;
       
  1906                     ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1907                     do {
       
  1908                         consumer.accept(r.copyAndJump(distance));
       
  1909                     } while (++i < f);
       
  1910                 }
       
  1911             }
       
  1912         }
       
  1913 
       
  1914     }
       
  1915 
       
  1916     /**
       
  1917      * This class provides much of the implementation of the {@link SplittableGenerator} interface, to
       
  1918      * minimize the effort required to implement this interface.
       
  1919      * <p>
       
  1920      * To implement a pseudorandom number generator, the programmer needs only to extend this class and
       
  1921      * provide implementations for the methods {@code nextInt()}, {@code nextLong()}, {@code period()},
       
  1922      * and {@code split(SplittableGenerator)}.
       
  1923      * <p>
       
  1924      * (If the pseudorandom number generator also has the ability to jump, then the programmer may wish
       
  1925      * to consider instead extending the class {@link ArbitrarilyJumpableGenerator}.  But if the pseudorandom
       
  1926      * number generator furthermore has the ability to jump an arbitrary specified distance, then the
       
  1927      * programmer may wish to consider instead extending the class {@link
       
  1928      * AbstractArbitrarilyJumpableGenerator}.)
       
  1929      * <p>
       
  1930      * The programmer should generally provide at least three constructors: one that takes no arguments,
       
  1931      * one that accepts a {@code long} seed value, and one that accepts an array of seed {@code byte}
       
  1932      * values. This class provides a public {@code initialSeed()} method that may be useful in
       
  1933      * initializing some static state from which to derive defaults seeds for use by the no-argument
       
  1934      * constructor.
       
  1935      * <p>
       
  1936      * For the stream methods (such as {@code ints()} and {@code splits()}), this class provides {@link
       
  1937      * Spliterator} based implementations that allow parallel execution when appropriate.
       
  1938      * <p>
       
  1939      * The documentation for each non-abstract method in this class describes its implementation in
       
  1940      * detail. Each of these methods may be overridden if the pseudorandom number generator being
       
  1941      * implemented admits a more efficient implementation.
       
  1942      *
       
  1943      * @since 14
       
  1944      */
       
  1945     public abstract static class AbstractSplittableGenerator extends AbstractSpliteratorGenerator implements SplittableGenerator {
       
  1946 
       
  1947         /*
       
  1948          * Implementation Overview.
       
  1949          *
       
  1950          * This class provides most of the "user API" methods needed to
       
  1951          * satisfy the interface JumpableGenerator.  Most of these methods
       
  1952          * are in turn inherited from AbstractGenerator and the non-public class
       
  1953          * AbstractSpliteratorGenerator; this file implements two versions of the
       
  1954          * splits method and defines the spliterators necessary to support
       
  1955          * them.
       
  1956          *
       
  1957          * The abstract split() method from interface SplittableGenerator is redeclared
       
  1958          * here so as to narrow the return type to AbstractSplittableGenerator.
       
  1959          *
       
  1960          * File organization: First the non-public methods needed by the class
       
  1961          * AbstractSpliteratorGenerator, then the main public methods, followed by some
       
  1962          * custom spliterator classes.
       
  1963          */
       
  1964 
       
  1965         public Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) {
       
  1966             return new RandomIntsSpliterator(this, index, fence, origin, bound);
       
  1967         }
       
  1968 
       
  1969         public Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound) {
       
  1970             return new RandomLongsSpliterator(this, index, fence, origin, bound);
       
  1971         }
       
  1972 
       
  1973         public Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound) {
       
  1974             return new RandomDoublesSpliterator(this, index, fence, origin, bound);
       
  1975         }
       
  1976 
       
  1977         Spliterator<SplittableGenerator> makeSplitsSpliterator(long index, long fence, SplittableGenerator source) {
       
  1978             return new RandomSplitsSpliterator(source, index, fence, this);
       
  1979         }
       
  1980 
       
  1981         /* ---------------- public methods ---------------- */
       
  1982 
       
  1983         /**
       
  1984          * Implements the @code{split()} method as {@code this.split(this) }.
       
  1985          *
       
  1986          * @return the new {@link AbstractSplittableGenerator} instance
       
  1987          */
       
  1988         public SplittableGenerator split() {
       
  1989             return this.split(this);
       
  1990         }
       
  1991 
       
  1992         // Stream methods for splittings
       
  1993 
       
  1994         /**
       
  1995          * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
       
  1996          * implements the {@link SplittableGenerator} interface.
       
  1997          * <p>
       
  1998          * This pseudorandom number generator provides the entropy used to seed the new ones.
       
  1999          *
       
  2000          * @return a stream of {@link SplittableGenerator} objects
       
  2001          *
       
  2002          * @implNote This method is implemented to be equivalent to {@code splits(Long.MAX_VALUE)}.
       
  2003          */
       
  2004         public Stream<SplittableGenerator> splits() {
       
  2005             return this.splits(Long.MAX_VALUE, this);
       
  2006         }
       
  2007 
       
  2008         /**
       
  2009          * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
       
  2010          * generators, each of which implements the {@link SplittableGenerator} interface.
       
  2011          * <p>
       
  2012          * This pseudorandom number generator provides the entropy used to seed the new ones.
       
  2013          *
       
  2014          * @param streamSize the number of values to generate
       
  2015          *
       
  2016          * @return a stream of {@link SplittableGenerator} objects
       
  2017          *
       
  2018          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  2019          */
       
  2020         public Stream<SplittableGenerator> splits(long streamSize) {
       
  2021             return this.splits(streamSize, this);
       
  2022         }
       
  2023 
       
  2024         /**
       
  2025          * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
       
  2026          * implements the {@link SplittableGenerator} interface.
       
  2027          *
       
  2028          * @param source a {@link SplittableGenerator} instance to be used instead of this one as a source of
       
  2029          *               pseudorandom bits used to initialize the state of the new ones.
       
  2030          *
       
  2031          * @return a stream of {@link SplittableGenerator} objects
       
  2032          *
       
  2033          * @implNote This method is implemented to be equivalent to {@code splits(Long.MAX_VALUE)}.
       
  2034          */
       
  2035         public Stream<SplittableGenerator> splits(SplittableGenerator source) {
       
  2036             return this.splits(Long.MAX_VALUE, source);
       
  2037         }
       
  2038 
       
  2039         /**
       
  2040          * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
       
  2041          * generators, each of which implements the {@link SplittableGenerator} interface.
       
  2042          *
       
  2043          * @param streamSize the number of values to generate
       
  2044          * @param source     a {@link SplittableGenerator} instance to be used instead of this one as a source
       
  2045          *                   of pseudorandom bits used to initialize the state of the new ones.
       
  2046          *
       
  2047          * @return a stream of {@link SplittableGenerator} objects
       
  2048          *
       
  2049          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  2050          */
       
  2051         public Stream<SplittableGenerator> splits(long streamSize, SplittableGenerator source) {
       
  2052             RandomSupport.checkStreamSize(streamSize);
       
  2053             return StreamSupport.stream(makeSplitsSpliterator(0L, streamSize, source), false);
       
  2054         }
       
  2055 
       
  2056         /**
       
  2057          * Spliterator for int streams.  We multiplex the four int versions into one class by treating a
       
  2058          * bound less than origin as unbounded, and also by treating "infinite" as equivalent to
       
  2059          * {@code Long.MAX_VALUE}. For splits, it uses the standard divide-by-two approach. The long and
       
  2060          * double versions of this class are identical except for types.
       
  2061          */
       
  2062         static class RandomIntsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfInt {
       
  2063             final SplittableGenerator generatingGenerator;
       
  2064             final int origin;
       
  2065             final int bound;
       
  2066 
       
  2067             RandomIntsSpliterator(SplittableGenerator generatingGenerator, long index, long fence, int origin, int bound) {
       
  2068                 super(index, fence);
       
  2069                 this.generatingGenerator = generatingGenerator;
       
  2070                 this.origin = origin; this.bound = bound;
       
  2071             }
       
  2072 
       
  2073             public Spliterator.OfInt trySplit() {
       
  2074                 long i = index, m = (i + fence) >>> 1;
       
  2075                 if (m <= i) return null;
       
  2076                 index = m;
       
  2077                 return new RandomIntsSpliterator(generatingGenerator.split(), i, m, origin, bound);
       
  2078             }
       
  2079 
       
  2080             public boolean tryAdvance(IntConsumer consumer) {
       
  2081                 if (consumer == null) throw new NullPointerException();
       
  2082                 long i = index, f = fence;
       
  2083                 if (i < f) {
       
  2084                     consumer.accept(RandomSupport.boundedNextInt(generatingGenerator, origin, bound));
       
  2085                     index = i + 1;
       
  2086                     return true;
       
  2087                 }
       
  2088                 else return false;
       
  2089             }
       
  2090 
       
  2091             public void forEachRemaining(IntConsumer consumer) {
       
  2092                 if (consumer == null) throw new NullPointerException();
       
  2093                 long i = index, f = fence;
       
  2094                 if (i < f) {
       
  2095                     index = f;
       
  2096                     RandomGenerator r = generatingGenerator;
       
  2097                     int o = origin, b = bound;
       
  2098                     do {
       
  2099                         consumer.accept(RandomSupport.boundedNextInt(r, o, b));
       
  2100                     } while (++i < f);
       
  2101                 }
       
  2102             }
       
  2103         }
       
  2104 
       
  2105         /**
       
  2106          * Spliterator for long streams.
       
  2107          */
       
  2108         static class RandomLongsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfLong {
       
  2109             final SplittableGenerator generatingGenerator;
       
  2110             final long origin;
       
  2111             final long bound;
       
  2112 
       
  2113             RandomLongsSpliterator(SplittableGenerator generatingGenerator, long index, long fence, long origin, long bound) {
       
  2114                 super(index, fence);
       
  2115                 this.generatingGenerator = generatingGenerator;
       
  2116                 this.origin = origin; this.bound = bound;
       
  2117             }
       
  2118 
       
  2119             public Spliterator.OfLong trySplit() {
       
  2120                 long i = index, m = (i + fence) >>> 1;
       
  2121                 if (m <= i) return null;
       
  2122                 index = m;
       
  2123                 return new RandomLongsSpliterator(generatingGenerator.split(), i, m, origin, bound);
       
  2124             }
       
  2125 
       
  2126             public boolean tryAdvance(LongConsumer consumer) {
       
  2127                 if (consumer == null) throw new NullPointerException();
       
  2128                 long i = index, f = fence;
       
  2129                 if (i < f) {
       
  2130                     consumer.accept(RandomSupport.boundedNextLong(generatingGenerator, origin, bound));
       
  2131                     index = i + 1;
       
  2132                     return true;
       
  2133                 }
       
  2134                 else return false;
       
  2135             }
       
  2136 
       
  2137             public void forEachRemaining(LongConsumer consumer) {
       
  2138                 if (consumer == null) throw new NullPointerException();
       
  2139                 long i = index, f = fence;
       
  2140                 if (i < f) {
       
  2141                     index = f;
       
  2142                     RandomGenerator r = generatingGenerator;
       
  2143                     long o = origin, b = bound;
       
  2144                     do {
       
  2145                         consumer.accept(RandomSupport.boundedNextLong(r, o, b));
       
  2146                     } while (++i < f);
       
  2147                 }
       
  2148             }
       
  2149         }
       
  2150 
       
  2151         /**
       
  2152          * Spliterator for double streams.
       
  2153          */
       
  2154         static class RandomDoublesSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfDouble {
       
  2155             final SplittableGenerator generatingGenerator;
       
  2156             final double origin;
       
  2157             final double bound;
       
  2158 
       
  2159             RandomDoublesSpliterator(SplittableGenerator generatingGenerator, long index, long fence, double origin, double bound) {
       
  2160                 super(index, fence);
       
  2161                 this.generatingGenerator = generatingGenerator;
       
  2162                 this.origin = origin; this.bound = bound;
       
  2163             }
       
  2164 
       
  2165             public Spliterator.OfDouble trySplit() {
       
  2166                 long i = index, m = (i + fence) >>> 1;
       
  2167                 if (m <= i) return null;
       
  2168                 index = m;
       
  2169                 return new RandomDoublesSpliterator(generatingGenerator.split(), i, m, origin, bound);
       
  2170             }
       
  2171 
       
  2172             public boolean tryAdvance(DoubleConsumer consumer) {
       
  2173                 if (consumer == null) throw new NullPointerException();
       
  2174                 long i = index, f = fence;
       
  2175                 if (i < f) {
       
  2176                     consumer.accept(RandomSupport.boundedNextDouble(generatingGenerator, origin, bound));
       
  2177                     index = i + 1;
       
  2178                     return true;
       
  2179                 }
       
  2180                 else return false;
       
  2181             }
       
  2182 
       
  2183             public void forEachRemaining(DoubleConsumer consumer) {
       
  2184                 if (consumer == null) throw new NullPointerException();
       
  2185                 long i = index, f = fence;
       
  2186                 if (i < f) {
       
  2187                     index = f;
       
  2188                     RandomGenerator r = generatingGenerator;
       
  2189                     double o = origin, b = bound;
       
  2190                     do {
       
  2191                         consumer.accept(RandomSupport.boundedNextDouble(r, o, b));
       
  2192                     } while (++i < f);
       
  2193                 }
       
  2194             }
       
  2195         }
       
  2196 
       
  2197         /**
       
  2198          * Spliterator for stream of generators of type SplittableGenerator.  We multiplex the two
       
  2199          * versions into one class by treating "infinite" as equivalent to Long.MAX_VALUE.
       
  2200          * For splits, it uses the standard divide-by-two approach.
       
  2201          */
       
  2202         static class RandomSplitsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator<SplittableGenerator> {
       
  2203             final SplittableGenerator generatingGenerator;
       
  2204             final SplittableGenerator constructingGenerator;
       
  2205 
       
  2206             RandomSplitsSpliterator(SplittableGenerator generatingGenerator, long index, long fence, SplittableGenerator constructingGenerator) {
       
  2207                 super(index, fence);
       
  2208                 this.generatingGenerator = generatingGenerator;
       
  2209                 this.constructingGenerator = constructingGenerator;
       
  2210             }
       
  2211 
       
  2212             public Spliterator<SplittableGenerator> trySplit() {
       
  2213                 long i = index, m = (i + fence) >>> 1;
       
  2214                 if (m <= i) return null;
       
  2215                 index = m;
       
  2216                 return new RandomSplitsSpliterator(generatingGenerator.split(), i, m, constructingGenerator);
       
  2217             }
       
  2218 
       
  2219             public boolean tryAdvance(Consumer<? super SplittableGenerator> consumer) {
       
  2220                 if (consumer == null) throw new NullPointerException();
       
  2221                 long i = index, f = fence;
       
  2222                 if (i < f) {
       
  2223                     consumer.accept(constructingGenerator.split(generatingGenerator));
       
  2224                     index = i + 1;
       
  2225                     return true;
       
  2226                 }
       
  2227                 else return false;
       
  2228             }
       
  2229 
       
  2230             public void forEachRemaining(Consumer<? super SplittableGenerator> consumer) {
       
  2231                 if (consumer == null) throw new NullPointerException();
       
  2232                 long i = index, f = fence;
       
  2233                 if (i < f) {
       
  2234                     index = f;
       
  2235                     SplittableGenerator c = constructingGenerator;
       
  2236                     SplittableGenerator r = generatingGenerator;
       
  2237                     do {
       
  2238                         consumer.accept(c.split(r));
       
  2239                     } while (++i < f);
       
  2240                 }
       
  2241             }
       
  2242         }
       
  2243 
       
  2244     }
       
  2245 
       
  2246 }
       
  2247