src/java.base/share/classes/java/util/random/RandomSupport.java
branchJDK-8193209-branch
changeset 59088 da026c172c1e
equal deleted inserted replaced
59087:effb66aab08b 59088:da026c172c1e
       
     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 implementation 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} fails to be 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} fails to be 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} fails to be 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 if {@code origin} is not finite, {@code bound} is not finite,
       
   155      *                                  or {@code bound - origin} is not 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 if {@code origin} is not finite, {@code bound} is not finite,
       
   170      *                                  or {@code bound - origin} is not 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] &
       
   935                     DoubleZigguratTables.exponentialSignCorrectionMask;
       
   936             }
       
   937             if (j > 0) {   // Sample overhang j
       
   938                 // For the exponential distribution, every overhang is convex.
       
   939                 final double[] X = DoubleZigguratTables.exponentialX;
       
   940                 final double[] Y = DoubleZigguratTables.exponentialY;
       
   941                 for (;; U1 = (rng.nextLong() >>> 1)) {
       
   942                     long U2 = (rng.nextLong() >>> 1);
       
   943                     // Compute the actual x-coordinate of the randomly chosen point.
       
   944                     double x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
       
   945                     // Does the point lie below the curve?
       
   946                     long Udiff = U2 - U1;
       
   947                     if (Udiff < 0) {
       
   948                         // We picked a point in the upper-right triangle.  None of those can be
       
   949                         // accepted.  So remap the point into the lower-left triangle and try that.
       
   950                         // In effect, we swap U1 and U2, and invert the sign of Udiff.
       
   951                         Udiff = -Udiff;
       
   952                         U2 = U1;
       
   953                         U1 -= Udiff;
       
   954                     }
       
   955                     if (Udiff >= DoubleZigguratTables.exponentialConvexMargin) {
       
   956                         return x + extra;   // The chosen point is way below the curve; accept it.
       
   957                     }
       
   958                     // Compute the actual y-coordinate of the randomly chosen point.
       
   959                     double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
       
   960                     // Now see how that y-coordinate compares to the curve
       
   961                     if (y <= Math.exp(-x)) {
       
   962                         return x + extra;   // The chosen point is below the curve; accept it.
       
   963                     }
       
   964                     // Otherwise, we reject this sample and have to try again.
       
   965                 }
       
   966             }
       
   967             // We are now committed to sampling from the tail.  We could do a recursive call
       
   968             // and then add X[0] but we save some time and stack space by using an iterative loop.
       
   969             extra += DoubleZigguratTables.exponentialX0;
       
   970             // This is like the first five lines of this method, but if it returns, it first adds "extra".
       
   971             U1 = rng.nextLong();
       
   972             i = U1 & DoubleZigguratTables.exponentialLayerMask;
       
   973             if (i < DoubleZigguratTables.exponentialNumberOfLayers) {
       
   974                 return DoubleZigguratTables.exponentialX[(int)i] * (U1 >>> 1) + extra;
       
   975             }
       
   976         }
       
   977     }
       
   978 
       
   979     // Implementation support for nextGaussian()
       
   980 
       
   981     static double computeNextGaussian(RandomGenerator rng) {
       
   982         long U1 = rng.nextLong();
       
   983         // Experimentation on a variety of machines indicates that it is overall much faster
       
   984         // to do the following & and < operations on longs rather than first cast U1 to int
       
   985         // (but then we need to cast to int before doing the array indexing operation).
       
   986         long i = U1 & DoubleZigguratTables.normalLayerMask;
       
   987 
       
   988         if (i < DoubleZigguratTables.normalNumberOfLayers) {
       
   989             // This is the fast path (occurring more than 98% of the time).  Make an early exit.
       
   990             return DoubleZigguratTables.normalX[(int)i] * U1;   // Note that the sign bit of U1 is used here.
       
   991         }
       
   992         // We didn't use the upper part of U1 after all.
       
   993         // Pull U1 apart into a sign bit and a 63-bit value for later use.
       
   994         double signBit = (U1 >= 0) ? 1.0 : -1.0;
       
   995         U1 = (U1 << 1) >>> 1;
       
   996 
       
   997         // Use Walker's alias method to sample an (unsigned) integer j from a discrete
       
   998         // probability distribution that includes the tail and all the ziggurat overhangs;
       
   999         // j will be less than DoubleZigguratTables.normalNumberOfLayers + 1.
       
  1000         long UA = rng.nextLong();
       
  1001         int j = (int)UA & DoubleZigguratTables.normalAliasMask;
       
  1002         if (UA >= DoubleZigguratTables.normalAliasThreshold[j]) {
       
  1003             j = DoubleZigguratTables.normalAliasMap[j] & DoubleZigguratTables.normalSignCorrectionMask;
       
  1004         }
       
  1005 
       
  1006         double x;
       
  1007         // Now the goal is to choose the result, which will be multiplied by signBit just before return.
       
  1008 
       
  1009         // There are four kinds of overhangs:
       
  1010         //
       
  1011         //  j == 0                          :  Sample from tail
       
  1012         //  0 < j < normalInflectionIndex   :  Overhang is convex; can reject upper-right triangle
       
  1013         //  j == normalInflectionIndex      :  Overhang includes the inflection point
       
  1014         //  j > normalInflectionIndex       :  Overhang is concave; can accept point in lower-left triangle
       
  1015         //
       
  1016         // Choose one of four loops to compute x, each specialized for a specific kind of overhang.
       
  1017         // Conditional statements are arranged such that the more likely outcomes are first.
       
  1018 
       
  1019         // In the three cases other than the tail case:
       
  1020         // U1 represents a fraction (scaled by 2**63) of the width of rectangle measured from the left.
       
  1021         // U2 represents a fraction (scaled by 2**63) of the height of rectangle measured from the top.
       
  1022         // Together they indicate a randomly chosen point within the rectangle.
       
  1023 
       
  1024         final double[] X = DoubleZigguratTables.normalX;
       
  1025         final double[] Y = DoubleZigguratTables.normalY;
       
  1026         if (j > DoubleZigguratTables.normalInflectionIndex) {   // Concave overhang
       
  1027             for (;; U1 = (rng.nextLong() >>> 1)) {
       
  1028                 long U2 = (rng.nextLong() >>> 1);
       
  1029                 // Compute the actual x-coordinate of the randomly chosen point.
       
  1030                 x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
       
  1031                 // Does the point lie below the curve?
       
  1032                 long Udiff = U2 - U1;
       
  1033                 if (Udiff >= 0) {
       
  1034                     break;   // The chosen point is in the lower-left triangle; accept it.
       
  1035                 }
       
  1036                 if (Udiff <= -DoubleZigguratTables.normalConcaveMargin) {
       
  1037                     continue;   // The chosen point is way above the curve; reject it.
       
  1038                 }
       
  1039                 // Compute the actual y-coordinate of the randomly chosen point.
       
  1040                 double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
       
  1041                 // Now see how that y-coordinate compares to the curve
       
  1042                 if (y <= Math.exp(-0.5*x*x)) {
       
  1043                     break;   // The chosen point is below the curve; accept it.
       
  1044                 }
       
  1045                 // Otherwise, we reject this sample and have to try again.
       
  1046             }
       
  1047         } else if (j == 0) {   // Tail
       
  1048             // Tail-sampling method of Marsaglia and Tsang.  See any one of:
       
  1049             // Marsaglia and Tsang. 1984. A fast, easily implemented method for sampling from decreasing
       
  1050             //    or symmetric unimodal density functions. SIAM J. Sci. Stat. Comput. 5, 349-359.
       
  1051             // Marsaglia and Tsang. 1998. The Monty Python method for generating random variables.
       
  1052             //    ACM Trans. Math. Softw. 24, 3 (September 1998), 341-350.  See page 342, step (4).
       
  1053             //    http://doi.org/10.1145/292395.292453
       
  1054             // Thomas, Luk, Leong, and Villasenor. 2007. Gaussian random number generators.
       
  1055             //    ACM Comput. Surv. 39, 4, Article 11 (November 2007).  See Algorithm 16.
       
  1056             //    http://doi.org/10.1145/1287620.1287622
       
  1057             // Compute two separate random exponential samples and then compare them in certain way.
       
  1058             do {
       
  1059                 x = (1.0 / DoubleZigguratTables.normalX0) * computeNextExponential(rng);
       
  1060             } while (computeNextExponential(rng) < 0.5*x*x);
       
  1061             x += DoubleZigguratTables.normalX0;
       
  1062         } else if (j < DoubleZigguratTables.normalInflectionIndex) {   // Convex overhang
       
  1063             for (;; U1 = (rng.nextLong() >>> 1)) {
       
  1064                 long U2 = (rng.nextLong() >>> 1);
       
  1065                 // Compute the actual x-coordinate of the randomly chosen point.
       
  1066                 x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
       
  1067                 // Does the point lie below the curve?
       
  1068                 long Udiff = U2 - U1;
       
  1069                 if (Udiff < 0) {
       
  1070                     // We picked a point in the upper-right triangle.  None of those can be accepted.
       
  1071                     // So remap the point into the lower-left triangle and try that.
       
  1072                     // In effect, we swap U1 and U2, and invert the sign of Udiff.
       
  1073                     Udiff = -Udiff;
       
  1074                     U2 = U1;
       
  1075                     U1 -= Udiff;
       
  1076                 }
       
  1077                 if (Udiff >= DoubleZigguratTables.normalConvexMargin) {
       
  1078                     break;   // The chosen point is way below the curve; accept it.
       
  1079                 }
       
  1080                 // Compute the actual y-coordinate of the randomly chosen point.
       
  1081                 double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
       
  1082                 // Now see how that y-coordinate compares to the curve
       
  1083                 if (y <= Math.exp(-0.5*x*x)) break; // The chosen point is below the curve; accept it.
       
  1084                 // Otherwise, we reject this sample and have to try again.
       
  1085             }
       
  1086         } else {
       
  1087             // The overhang includes the inflection point, so the curve is both convex and concave
       
  1088             for (;; U1 = (rng.nextLong() >>> 1)) {
       
  1089                 long U2 = (rng.nextLong() >>> 1);
       
  1090                 // Compute the actual x-coordinate of the randomly chosen point.
       
  1091                 x = (X[j] * 0x1.0p63) + ((X[j-1] - X[j]) * (double)U1);
       
  1092                 // Does the point lie below the curve?
       
  1093                 long Udiff = U2 - U1;
       
  1094                 if (Udiff >= DoubleZigguratTables.normalConvexMargin) {
       
  1095                     break;   // The chosen point is way below the curve; accept it.
       
  1096                 }
       
  1097                 if (Udiff <= -DoubleZigguratTables.normalConcaveMargin) {
       
  1098                     continue;   // The chosen point is way above the curve; reject it.
       
  1099                 }
       
  1100                 // Compute the actual y-coordinate of the randomly chosen point.
       
  1101                 double y = (Y[j] * 0x1.0p63) + ((Y[j] - Y[j-1]) * (double)U2);
       
  1102                 // Now see how that y-coordinate compares to the curve
       
  1103                 if (y <= Math.exp(-0.5*x*x)) {
       
  1104                     break;   // The chosen point is below the curve; accept it.
       
  1105                 }
       
  1106                 // Otherwise, we reject this sample and have to try again.
       
  1107             }
       
  1108         }
       
  1109         return signBit*x;
       
  1110     }
       
  1111 
       
  1112     /**
       
  1113      * This class overrides the stream-producing methods (such as {@code ints()})
       
  1114      * in class {@link AbstractGenerator} to provide {@link Spliterator}-based
       
  1115      * implmentations that support potentially parallel execution.
       
  1116      *
       
  1117      * To implement a pseudorandom number generator, the programmer needs
       
  1118      * only to extend this class and provide implementations for the methods
       
  1119      * {@code nextInt()}, {@code nextLong()}, {@code makeIntsSpliterator},
       
  1120      * {@code makeLongsSpliterator}, and {@code makeDoublesSpliterator}.
       
  1121      *
       
  1122      * This class is not public; it provides shared code to the public
       
  1123      * classes {@link AbstractSplittableGenerator}, {@link AbstractSharedGenerator},
       
  1124      * and {@link AbstractArbitrarilyJumpableGenerator}.
       
  1125      *
       
  1126      * @since 14
       
  1127      */
       
  1128     public abstract static class AbstractSpliteratorGenerator implements RandomGenerator {
       
  1129         /*
       
  1130          * Implementation Overview.
       
  1131          *
       
  1132          * This class provides most of the "user API" methods needed to
       
  1133          * satisfy the interface RandomGenerator.  An implementation of this
       
  1134          * interface need only extend this class and provide implementations
       
  1135          * of six methods: nextInt, nextLong, and nextDouble (the versions
       
  1136          * that take no arguments) and makeIntsSpliterator,
       
  1137          * makeLongsSpliterator, and makeDoublesSpliterator.
       
  1138          *
       
  1139          * File organization: First the non-public abstract methods needed
       
  1140          * to create spliterators, then the main public methods.
       
  1141          */
       
  1142 
       
  1143         /**
       
  1144          * Create an instance of {@link Spliterator.OfInt} that for each traversal position
       
  1145 	 * between the specified index (inclusive) and the specified fence (exclusive) generates
       
  1146 	 * a pseudorandomly chosen {@code int} value between the specified origin (inclusive) and
       
  1147 	 * the specified bound (exclusive).
       
  1148          *
       
  1149          * @param index the (inclusive) lower bound on traversal positions
       
  1150          * @param fence the (exclusive) upper bound on traversal positions
       
  1151          * @param origin the (inclusive) lower bound on the pseudorandom values to be generated
       
  1152          * @param bound the (exclusive) upper bound on the pseudorandom values to be generated
       
  1153          * @return an instance of {@link Spliterator.OfInt}
       
  1154          */
       
  1155         public abstract Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound);
       
  1156 
       
  1157         /**
       
  1158          * Create an instance of {@link Spliterator.OfLong} that for each traversal position
       
  1159 	 * between the specified index (inclusive) and the specified fence (exclusive) generates
       
  1160 	 * a pseudorandomly chosen {@code long} value between the specified origin (inclusive) and
       
  1161 	 * the specified bound (exclusive).
       
  1162          *
       
  1163          * @param index the (inclusive) lower bound on traversal positions
       
  1164          * @param fence the (exclusive) upper bound on traversal positions
       
  1165          * @param origin the (inclusive) lower bound on the pseudorandom values to be generated
       
  1166          * @param bound the (exclusive) upper bound on the pseudorandom values to be generated
       
  1167          * @return an instance of {@link Spliterator.OfLong}
       
  1168          */
       
  1169         public abstract Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound);
       
  1170 
       
  1171         /**
       
  1172          * Create an instance of {@link Spliterator.OfDouble} that for each traversal position
       
  1173 	 * between the specified index (inclusive) and the specified fence (exclusive) generates
       
  1174 	 * a pseudorandomly chosen {@code double} value between the specified origin (inclusive) and
       
  1175 	 * the specified bound (exclusive).
       
  1176          *
       
  1177          * @param index the (inclusive) lower bound on traversal positions
       
  1178          * @param fence the (exclusive) upper bound on traversal positions
       
  1179          * @param origin the (inclusive) lower bound on the pseudorandom values to be generated
       
  1180          * @param bound the (exclusive) upper bound on the pseudorandom values to be generated
       
  1181          * @return an instance of {@link Spliterator.OfDouble}
       
  1182          */
       
  1183         public abstract Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound);
       
  1184 
       
  1185         /* ---------------- public methods ---------------- */
       
  1186 
       
  1187         // stream methods, coded in a way intended to better isolate for
       
  1188         // maintenance purposes the small differences across forms.
       
  1189 
       
  1190         private static IntStream intStream(Spliterator.OfInt srng) {
       
  1191             return StreamSupport.intStream(srng, false);
       
  1192         }
       
  1193 
       
  1194         private static LongStream longStream(Spliterator.OfLong srng) {
       
  1195             return StreamSupport.longStream(srng, false);
       
  1196         }
       
  1197 
       
  1198         private static DoubleStream doubleStream(Spliterator.OfDouble srng) {
       
  1199             return StreamSupport.doubleStream(srng, false);
       
  1200         }
       
  1201 
       
  1202         /**
       
  1203          * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code int}
       
  1204          * values from this generator and/or one split from it.
       
  1205          *
       
  1206          * @param streamSize the number of values to generate
       
  1207          *
       
  1208          * @return a stream of pseudorandom {@code int} values
       
  1209          *
       
  1210          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1211          */
       
  1212         public IntStream ints(long streamSize) {
       
  1213             RandomSupport.checkStreamSize(streamSize);
       
  1214             return intStream(makeIntsSpliterator(0L, streamSize, Integer.MAX_VALUE, 0));
       
  1215         }
       
  1216 
       
  1217         /**
       
  1218          * Returns an effectively unlimited stream of pseudorandomly chosen
       
  1219          * {@code int} values.
       
  1220          *
       
  1221          * @implNote The implementation of this method is effectively
       
  1222          * equivalent to {@code ints(Long.MAX_VALUE)}.
       
  1223          *
       
  1224          * @return a stream of pseudorandomly chosen {@code int} values
       
  1225          */
       
  1226 
       
  1227         public IntStream ints() {
       
  1228             return intStream(makeIntsSpliterator(0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0));
       
  1229         }
       
  1230 
       
  1231         /**
       
  1232          * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code int}
       
  1233          * values from this generator and/or one split from it; each value conforms to the given origin
       
  1234          * (inclusive) and bound (exclusive).
       
  1235          *
       
  1236          * @param streamSize         the number of values to generate
       
  1237          * @param randomNumberOrigin the origin (inclusive) of each random value
       
  1238          * @param randomNumberBound  the bound (exclusive) of each random value
       
  1239          *
       
  1240          * @return a stream of pseudorandom {@code int} values, each with the given origin (inclusive)
       
  1241          *         and bound (exclusive)
       
  1242          *
       
  1243          * @throws IllegalArgumentException if {@code streamSize} is less than zero, or {@code
       
  1244          *                                  randomNumberOrigin} is greater than or equal to {@code
       
  1245          *                                  randomNumberBound}
       
  1246          */
       
  1247         public IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound) {
       
  1248             RandomSupport.checkStreamSize(streamSize);
       
  1249             RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
  1250             return intStream(makeIntsSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
       
  1251         }
       
  1252 
       
  1253         /**
       
  1254          * Returns an effectively unlimited stream of pseudorandom {@code int} values from this
       
  1255          * generator and/or one split from it; each value conforms to the given origin (inclusive) and
       
  1256          * bound (exclusive).
       
  1257          *
       
  1258          * @param randomNumberOrigin the origin (inclusive) of each random value
       
  1259          * @param randomNumberBound  the bound (exclusive) of each random value
       
  1260          *
       
  1261          * @return a stream of pseudorandom {@code int} values, each with the given origin (inclusive)
       
  1262          *         and bound (exclusive)
       
  1263          *
       
  1264          * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
       
  1265          *                                  {@code randomNumberBound}
       
  1266          *
       
  1267          * @implNote This method is implemented to be equivalent to {@code ints(Long.MAX_VALUE,
       
  1268          *         randomNumberOrigin, randomNumberBound)}.
       
  1269          */
       
  1270         public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
       
  1271             RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
  1272             return intStream(makeIntsSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound));
       
  1273         }
       
  1274 
       
  1275         /**
       
  1276          * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code long}
       
  1277          * values from this generator and/or one split from it.
       
  1278          *
       
  1279          * @param streamSize the number of values to generate
       
  1280          *
       
  1281          * @return a stream of pseudorandom {@code long} values
       
  1282          *
       
  1283          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1284          */
       
  1285         public LongStream longs(long streamSize) {
       
  1286             RandomSupport.checkStreamSize(streamSize);
       
  1287             return longStream(makeLongsSpliterator(0L, streamSize, Long.MAX_VALUE, 0L));
       
  1288         }
       
  1289 
       
  1290         /**
       
  1291          * Returns an effectively unlimited stream of pseudorandom {@code long} values from this
       
  1292          * generator and/or one split from it.
       
  1293          *
       
  1294          * @return a stream of pseudorandom {@code long} values
       
  1295          *
       
  1296          * @implNote This method is implemented to be equivalent to {@code
       
  1297          *         longs(Long.MAX_VALUE)}.
       
  1298          */
       
  1299         public LongStream longs() {
       
  1300             return longStream(makeLongsSpliterator(0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L));
       
  1301         }
       
  1302 
       
  1303         /**
       
  1304          * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code long}
       
  1305          * values from this generator and/or one split from it; each value conforms to the given origin
       
  1306          * (inclusive) and bound (exclusive).
       
  1307          *
       
  1308          * @param streamSize         the number of values to generate
       
  1309          * @param randomNumberOrigin the origin (inclusive) of each random value
       
  1310          * @param randomNumberBound  the bound (exclusive) of each random value
       
  1311          *
       
  1312          * @return a stream of pseudorandom {@code long} values, each with the given origin (inclusive)
       
  1313          *         and bound (exclusive)
       
  1314          *
       
  1315          * @throws IllegalArgumentException if {@code streamSize} is less than zero, or {@code
       
  1316          *                                  randomNumberOrigin} is greater than or equal to {@code
       
  1317          *                                  randomNumberBound}
       
  1318          */
       
  1319         public LongStream longs(long streamSize, long randomNumberOrigin,
       
  1320                                  long randomNumberBound) {
       
  1321             RandomSupport.checkStreamSize(streamSize);
       
  1322             RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
  1323             return longStream(makeLongsSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
       
  1324         }
       
  1325 
       
  1326         /**
       
  1327          * Returns an effectively unlimited stream of pseudorandom {@code long} values from this
       
  1328          * generator and/or one split from it; each value conforms to the given origin (inclusive) and
       
  1329          * bound (exclusive).
       
  1330          *
       
  1331          * @param randomNumberOrigin the origin (inclusive) of each random value
       
  1332          * @param randomNumberBound  the bound (exclusive) of each random value
       
  1333          *
       
  1334          * @return a stream of pseudorandom {@code long} values, each with the given origin (inclusive)
       
  1335          *         and bound (exclusive)
       
  1336          *
       
  1337          * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
       
  1338          *                                  {@code randomNumberBound}
       
  1339          *
       
  1340          * @implNote This method is implemented to be equivalent to {@code longs(Long.MAX_VALUE,
       
  1341          *         randomNumberOrigin, randomNumberBound)}.
       
  1342          */
       
  1343         public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
       
  1344             RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
  1345             return StreamSupport.longStream
       
  1346                 (makeLongsSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
       
  1347                  false);
       
  1348         }
       
  1349 
       
  1350         /**
       
  1351          * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code double}
       
  1352          * values from this generator and/or one split from it; each value is between zero (inclusive)
       
  1353          * and one (exclusive).
       
  1354          *
       
  1355          * @param streamSize the number of values to generate
       
  1356          *
       
  1357          * @return a stream of {@code double} values
       
  1358          *
       
  1359          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1360          */
       
  1361         public DoubleStream doubles(long streamSize) {
       
  1362             RandomSupport.checkStreamSize(streamSize);
       
  1363             return doubleStream(makeDoublesSpliterator(0L, streamSize, Double.MAX_VALUE, 0.0));
       
  1364         }
       
  1365 
       
  1366         /**
       
  1367          * Returns an effectively unlimited stream of pseudorandom {@code double} values from this
       
  1368          * generator and/or one split from it; each value is between zero (inclusive) and one
       
  1369          * (exclusive).
       
  1370          *
       
  1371          * @return a stream of pseudorandom {@code double} values
       
  1372          *
       
  1373          * @implNote This method is implemented to be equivalent to {@code
       
  1374          *         doubles(Long.MAX_VALUE)}.
       
  1375          */
       
  1376         public DoubleStream doubles() {
       
  1377             return doubleStream(makeDoublesSpliterator(0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0));
       
  1378         }
       
  1379 
       
  1380         /**
       
  1381          * Returns a stream producing the given {@code streamSize} number of pseudorandom {@code double}
       
  1382          * values from this generator and/or one split from it; each value conforms to the given origin
       
  1383          * (inclusive) and bound (exclusive).
       
  1384          *
       
  1385          * @param streamSize         the number of values to generate
       
  1386          * @param randomNumberOrigin the origin (inclusive) of each random value
       
  1387          * @param randomNumberBound  the bound (exclusive) of each random value
       
  1388          *
       
  1389          * @return a stream of pseudorandom {@code double} values, each with the given origin
       
  1390          *         (inclusive) and bound (exclusive)
       
  1391          *
       
  1392          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1393          * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
       
  1394          *                                  {@code randomNumberBound}
       
  1395          */
       
  1396         public DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) {
       
  1397             RandomSupport.checkStreamSize(streamSize);
       
  1398             RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
  1399             return doubleStream(makeDoublesSpliterator(0L, streamSize, randomNumberOrigin, randomNumberBound));
       
  1400         }
       
  1401 
       
  1402         /**
       
  1403          * Returns an effectively unlimited stream of pseudorandom {@code double} values from this
       
  1404          * generator and/or one split from it; each value conforms to the given origin (inclusive) and
       
  1405          * bound (exclusive).
       
  1406          *
       
  1407          * @param randomNumberOrigin the origin (inclusive) of each random value
       
  1408          * @param randomNumberBound  the bound (exclusive) of each random value
       
  1409          *
       
  1410          * @return a stream of pseudorandom {@code double} values, each with the given origin
       
  1411          *         (inclusive) and bound (exclusive)
       
  1412          *
       
  1413          * @throws IllegalArgumentException if {@code randomNumberOrigin} is greater than or equal to
       
  1414          *                                  {@code randomNumberBound}
       
  1415          *
       
  1416          * @implNote This method is implemented to be equivalent to {@code
       
  1417          *         doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
       
  1418          */
       
  1419         public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
       
  1420             RandomSupport.checkRange(randomNumberOrigin, randomNumberBound);
       
  1421             return doubleStream(makeDoublesSpliterator(0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound));
       
  1422         }
       
  1423 
       
  1424     }
       
  1425 
       
  1426     /**
       
  1427      * This class provides much of the implementation of the
       
  1428      * {@link ArbitrarilyJumpableGenerator} interface, to minimize the effort
       
  1429      * required to implement that interface.
       
  1430      *
       
  1431      * To implement a pseudorandom number generator, the programmer needs
       
  1432      * only to extend this class and provide implementations for the
       
  1433      * methods {@link #nextInt()}, {@link #nextLong()}, {@link #copy()},
       
  1434      * {@link #jump(double)}, {@link #jumpPowerOfTwo(int)},
       
  1435      * {@link #defaultJumpDistance()}, and {@link #defaultLeapDistance()}.
       
  1436      *
       
  1437      * (If the pseudorandom number generator also has the ability to split,
       
  1438      * then the programmer may wish to consider instead extending
       
  1439      * {@link AbstractSplittableGenerator}.)
       
  1440      *
       
  1441      * The programmer should generally provide at least three constructors:
       
  1442      * one that takes no arguments, one that accepts a {@code long}
       
  1443      * seed value, and one that accepts an array of seed {@code byte} values.
       
  1444      * This class provides a public {@code initialSeed()} method that may
       
  1445      * be useful in initializing some static state from which to derive
       
  1446      * defaults seeds for use by the no-argument constructor.
       
  1447      *
       
  1448      * For the stream methods (such as {@code ints()} and {@code splits()}),
       
  1449      * this class provides {@link Spliterator}-based implementations that
       
  1450      * allow parallel execution when appropriate.  In this respect
       
  1451      * {@link ArbitrarilyJumpableGenerator} differs from {@link JumpableGenerator},
       
  1452      * which provides very simple implementations that produce
       
  1453      * sequential streams only.
       
  1454      *
       
  1455      * <p>An implementation of the {@link AbstractArbitrarilyJumpableGenerator} class
       
  1456      * must provide concrete definitions for the methods {@code nextInt()},
       
  1457      * {@code nextLong}, {@code period()}, {@code copy()}, {@code jump(double)},
       
  1458      * {@code defaultJumpDistance()}, and {@code defaultLeapDistance()}.
       
  1459      * Default implementations are provided for all other methods.
       
  1460      *
       
  1461      * The documentation for each non-abstract method in this class
       
  1462      * describes its implementation in detail. Each of these methods may
       
  1463      * be overridden if the pseudorandom number generator being
       
  1464      * implemented admits a more efficient implementation.
       
  1465      *
       
  1466      * @since 14
       
  1467      */
       
  1468     public abstract static class AbstractArbitrarilyJumpableGenerator
       
  1469         extends AbstractSpliteratorGenerator implements RandomGenerator.ArbitrarilyJumpableGenerator {
       
  1470 
       
  1471         /*
       
  1472          * Implementation Overview.
       
  1473          *
       
  1474          * This class provides most of the "user API" methods needed to satisfy
       
  1475          * the interface ArbitrarilyJumpableGenerator.  Most of these methods
       
  1476          * are in turn inherited from AbstractGenerator and the non-public class
       
  1477          * AbstractSpliteratorGenerator; this file implements four versions of the
       
  1478          * jumps method and defines the spliterators necessary to support them.
       
  1479          *
       
  1480          * File organization: First the non-public methods needed by the class
       
  1481          * AbstractSpliteratorGenerator, then the main public methods, followed by some
       
  1482          * custom spliterator classes needed for stream methods.
       
  1483          */
       
  1484 
       
  1485         // IllegalArgumentException messages
       
  1486         static final String BadLogDistance  = "logDistance must be non-negative";
       
  1487 
       
  1488         // Methods required by class AbstractSpliteratorGenerator
       
  1489         public Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) {
       
  1490             return new RandomIntsSpliterator(this, index, fence, origin, bound);
       
  1491         }
       
  1492         public Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound) {
       
  1493             return new RandomLongsSpliterator(this, index, fence, origin, bound);
       
  1494         }
       
  1495         public Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound) {
       
  1496             return new RandomDoublesSpliterator(this, index, fence, origin, bound);
       
  1497         }
       
  1498 
       
  1499         // Similar methods used by this class
       
  1500         Spliterator<RandomGenerator> makeJumpsSpliterator(long index, long fence, double distance) {
       
  1501             return new RandomJumpsSpliterator(this, index, fence, distance);
       
  1502         }
       
  1503         Spliterator<JumpableGenerator> makeLeapsSpliterator(long index, long fence, double distance) {
       
  1504             return new RandomLeapsSpliterator(this, index, fence, distance);
       
  1505         }
       
  1506         Spliterator<ArbitrarilyJumpableGenerator> makeArbitraryJumpsSpliterator(long index, long fence, double distance) {
       
  1507             return new RandomArbitraryJumpsSpliterator(this, index, fence, distance);
       
  1508         }
       
  1509 
       
  1510         /* ---------------- public methods ---------------- */
       
  1511 
       
  1512         /**
       
  1513          * Returns a new generator whose internal state is an exact copy
       
  1514          * of this generator (therefore their future behavior should be
       
  1515          * identical if subjected to the same series of operations).
       
  1516          *
       
  1517          * @return a new object that is a copy of this generator
       
  1518          */
       
  1519         public abstract AbstractArbitrarilyJumpableGenerator copy();
       
  1520 
       
  1521         // Stream methods for jumping
       
  1522 
       
  1523         private static <T> Stream<T> stream(Spliterator<T> srng) {
       
  1524             return StreamSupport.stream(srng, false);
       
  1525         }
       
  1526 
       
  1527         /**
       
  1528          * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
       
  1529          * implements the {@link RandomGenerator} interface, produced by jumping copies of this
       
  1530          * generator by different integer multiples of the default jump distance.
       
  1531          *
       
  1532          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1533          *
       
  1534          * @implNote This method is implemented to be equivalent to {@code
       
  1535          *         jumps(Long.MAX_VALUE)}.
       
  1536          */
       
  1537         public Stream<RandomGenerator> jumps() {
       
  1538             return stream(makeJumpsSpliterator(0L, Long.MAX_VALUE, defaultJumpDistance()));
       
  1539         }
       
  1540 
       
  1541         /**
       
  1542          * Returns a stream producing the given {@code streamSize} number of
       
  1543          * new pseudorandom number generators, each of which implements the
       
  1544          * {@link RandomGenerator} interface, produced by jumping copies of this generator
       
  1545          * by different integer multiples of the default jump distance.
       
  1546          *
       
  1547          * @param streamSize the number of generators to generate
       
  1548          *
       
  1549          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1550          *
       
  1551          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1552          */
       
  1553         public Stream<RandomGenerator> jumps(long streamSize) {
       
  1554             RandomSupport.checkStreamSize(streamSize);
       
  1555             return stream(makeJumpsSpliterator(0L, streamSize, defaultJumpDistance()));
       
  1556         }
       
  1557 
       
  1558         /**
       
  1559          * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
       
  1560          * implements the {@link RandomGenerator} interface, produced by jumping copies of this
       
  1561          * generator by different integer multiples of the specified jump distance.
       
  1562          *
       
  1563          * @param distance a distance to jump forward within the state cycle
       
  1564          *
       
  1565          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1566          *
       
  1567          * @implNote This method is implemented to be equivalent to {@code
       
  1568          *         jumps(Long.MAX_VALUE)}.
       
  1569          */
       
  1570         public Stream<ArbitrarilyJumpableGenerator> jumps(double distance) {
       
  1571             return stream(makeArbitraryJumpsSpliterator(0L, Long.MAX_VALUE, distance));
       
  1572         }
       
  1573 
       
  1574         /**
       
  1575          * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
       
  1576          * generators, each of which implements the {@link RandomGenerator} interface, produced by
       
  1577          * jumping copies of this generator by different integer multiples of the specified jump
       
  1578          * distance.
       
  1579          *
       
  1580          * @param streamSize the number of generators to generate
       
  1581          * @param distance   a distance to jump forward within the state cycle
       
  1582          *
       
  1583          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1584          *
       
  1585          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1586          */
       
  1587         public Stream<ArbitrarilyJumpableGenerator> jumps(long streamSize, double distance) {
       
  1588             RandomSupport.checkStreamSize(streamSize);
       
  1589             return stream(makeArbitraryJumpsSpliterator(0L, streamSize, distance));
       
  1590         }
       
  1591 
       
  1592         /**
       
  1593          * Alter the state of this pseudorandom number generator so as to
       
  1594          * jump forward a very large, fixed distance (typically 2<sup>128</sup>
       
  1595          * or more) within its state cycle.  The distance used is that
       
  1596          * returned by method {@code defaultLeapDistance()}.
       
  1597          */
       
  1598         public void leap() {
       
  1599             jump(defaultLeapDistance());
       
  1600         }
       
  1601 
       
  1602         // Stream methods for leaping
       
  1603 
       
  1604         /**
       
  1605          * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
       
  1606          * implements the {@link RandomGenerator} interface, produced by jumping copies of this
       
  1607          * generator by different integer multiples of the default leap distance.
       
  1608          *
       
  1609          * @implNote This method is implemented to be equivalent to {@code leaps(Long.MAX_VALUE)}.
       
  1610          *
       
  1611          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1612          */
       
  1613         public Stream<JumpableGenerator> leaps() {
       
  1614             return stream(makeLeapsSpliterator(0L, Long.MAX_VALUE, defaultLeapDistance()));
       
  1615         }
       
  1616 
       
  1617         /**
       
  1618          * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
       
  1619          * generators, each of which implements the {@link RandomGenerator} interface, produced by
       
  1620          * jumping copies of this generator by different integer multiples of the default leap
       
  1621          * distance.
       
  1622          *
       
  1623          * @param streamSize the number of generators to generate
       
  1624          *
       
  1625          * @return a stream of objects that implement the {@link RandomGenerator} interface
       
  1626          *
       
  1627          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  1628          */
       
  1629         public Stream<JumpableGenerator> leaps(long streamSize) {
       
  1630             return stream(makeLeapsSpliterator(0L, streamSize, defaultLeapDistance()));
       
  1631         }
       
  1632 
       
  1633 
       
  1634         /**
       
  1635          * Spliterator for int streams.  We multiplex the four int versions into one class by treating a
       
  1636          * bound less than origin as unbounded, and also by treating "infinite" as equivalent to
       
  1637          * {@code Long.MAX_VALUE}. For splits, we choose to override the method {@code trySplit()} to
       
  1638          * try to optimize execution speed: instead of dividing a range in half, it breaks off the
       
  1639          * largest possible chunk whose size is a power of two such that the remaining chunk is not
       
  1640          * empty. In this way, the necessary jump distances will tend to be powers of two.  The long
       
  1641          * and double versions of this class are identical except for types.
       
  1642          */
       
  1643         static class RandomIntsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfInt {
       
  1644             final ArbitrarilyJumpableGenerator generatingGenerator;
       
  1645             final int origin;
       
  1646             final int bound;
       
  1647 
       
  1648             RandomIntsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, int origin, int bound) {
       
  1649                 super(index, fence);
       
  1650                 this.origin = origin; this.bound = bound;
       
  1651                 this.generatingGenerator = generatingGenerator;
       
  1652             }
       
  1653 
       
  1654             public Spliterator.OfInt trySplit() {
       
  1655                 long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
       
  1656                 if (m <= i) return null;
       
  1657                 index = m;
       
  1658                 ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1659                 return new RandomIntsSpliterator(r.copyAndJump((double)delta), i, m, origin, bound);
       
  1660             }
       
  1661 
       
  1662             public boolean tryAdvance(IntConsumer consumer) {
       
  1663                 if (consumer == null) throw new NullPointerException();
       
  1664                 long i = index, f = fence;
       
  1665                 if (i < f) {
       
  1666                     consumer.accept(RandomSupport.boundedNextInt(generatingGenerator, origin, bound));
       
  1667                     index = i + 1;
       
  1668                     return true;
       
  1669                 }
       
  1670                 else return false;
       
  1671             }
       
  1672 
       
  1673             public void forEachRemaining(IntConsumer consumer) {
       
  1674                 if (consumer == null) throw new NullPointerException();
       
  1675                 long i = index, f = fence;
       
  1676                 if (i < f) {
       
  1677                     index = f;
       
  1678                     ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1679                     int o = origin, b = bound;
       
  1680                     do {
       
  1681                         consumer.accept(RandomSupport.boundedNextInt(r, o, b));
       
  1682                     } while (++i < f);
       
  1683                 }
       
  1684             }
       
  1685         }
       
  1686 
       
  1687         /**
       
  1688          * Spliterator for long streams.
       
  1689          */
       
  1690         static class RandomLongsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfLong {
       
  1691             final ArbitrarilyJumpableGenerator generatingGenerator;
       
  1692             final long origin;
       
  1693             final long bound;
       
  1694 
       
  1695             RandomLongsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, long origin, long bound) {
       
  1696                 super(index, fence);
       
  1697                 this.generatingGenerator = generatingGenerator;
       
  1698                 this.origin = origin; this.bound = bound;
       
  1699             }
       
  1700 
       
  1701             public Spliterator.OfLong trySplit() {
       
  1702                 long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
       
  1703                 if (m <= i) return null;
       
  1704                 index = m;
       
  1705                 ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1706                 return new RandomLongsSpliterator(r.copyAndJump((double)delta), i, m, origin, bound);
       
  1707             }
       
  1708 
       
  1709             public boolean tryAdvance(LongConsumer consumer) {
       
  1710                 if (consumer == null) throw new NullPointerException();
       
  1711                 long i = index, f = fence;
       
  1712                 if (i < f) {
       
  1713                     consumer.accept(RandomSupport.boundedNextLong(generatingGenerator, origin, bound));
       
  1714                     index = i + 1;
       
  1715                     return true;
       
  1716                 }
       
  1717                 else return false;
       
  1718             }
       
  1719 
       
  1720             public void forEachRemaining(LongConsumer consumer) {
       
  1721                 if (consumer == null) throw new NullPointerException();
       
  1722                 long i = index, f = fence;
       
  1723                 if (i < f) {
       
  1724                     index = f;
       
  1725                     ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1726                     long o = origin, b = bound;
       
  1727                     do {
       
  1728                         consumer.accept(RandomSupport.boundedNextLong(r, o, b));
       
  1729                     } while (++i < f);
       
  1730                 }
       
  1731             }
       
  1732         }
       
  1733 
       
  1734         /**
       
  1735          * Spliterator for double streams.
       
  1736          */
       
  1737         static class RandomDoublesSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfDouble {
       
  1738             final ArbitrarilyJumpableGenerator generatingGenerator;
       
  1739             final double origin;
       
  1740             final double bound;
       
  1741 
       
  1742             RandomDoublesSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, double origin, double bound) {
       
  1743                 super(index, fence);
       
  1744                 this.generatingGenerator = generatingGenerator;
       
  1745                 this.origin = origin; this.bound = bound;
       
  1746             }
       
  1747 
       
  1748             public Spliterator.OfDouble trySplit() {
       
  1749 
       
  1750                 long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
       
  1751                 if (m <= i) return null;
       
  1752                 index = m;
       
  1753                 ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1754                 return new RandomDoublesSpliterator(r.copyAndJump((double)delta), i, m, origin, bound);
       
  1755             }
       
  1756 
       
  1757             public boolean tryAdvance(DoubleConsumer consumer) {
       
  1758                 if (consumer == null) throw new NullPointerException();
       
  1759                 long i = index, f = fence;
       
  1760                 if (i < f) {
       
  1761                     consumer.accept(RandomSupport.boundedNextDouble(generatingGenerator, origin, bound));
       
  1762                     index = i + 1;
       
  1763                     return true;
       
  1764                 }
       
  1765                 else return false;
       
  1766             }
       
  1767 
       
  1768             public void forEachRemaining(DoubleConsumer consumer) {
       
  1769                 if (consumer == null) throw new NullPointerException();
       
  1770                 long i = index, f = fence;
       
  1771                 if (i < f) {
       
  1772                     index = f;
       
  1773                     ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1774                     double o = origin, b = bound;
       
  1775                     do {
       
  1776                         consumer.accept(RandomSupport.boundedNextDouble(r, o, b));
       
  1777                     } while (++i < f);
       
  1778                 }
       
  1779             }
       
  1780         }
       
  1781 
       
  1782         // Spliterators for producing new generators by jumping or leaping.  The
       
  1783         // complete implementation of each of these spliterators is right here.
       
  1784         // In the same manner as for the preceding spliterators, the method trySplit() is
       
  1785         // coded to optimize execution speed: instead of dividing a range
       
  1786         // in half, it breaks off the largest possible chunk whose
       
  1787         // size is a power of two such that the remaining chunk is not
       
  1788         // empty.  In this way, the necessary jump distances will tend to be
       
  1789         // powers of two.
       
  1790 
       
  1791         /**
       
  1792          * Spliterator for stream of generators of type RandomGenerator produced by jumps.
       
  1793          */
       
  1794         static class RandomJumpsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator<RandomGenerator> {
       
  1795             ArbitrarilyJumpableGenerator generatingGenerator;
       
  1796             final double distance;
       
  1797 
       
  1798             RandomJumpsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, double distance) {
       
  1799                 super(index, fence);
       
  1800                 this.generatingGenerator = generatingGenerator; this.distance = distance;
       
  1801             }
       
  1802 
       
  1803             public Spliterator<RandomGenerator> trySplit() {
       
  1804                 long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
       
  1805                 if (m <= i) return null;
       
  1806                 index = m;
       
  1807                 ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1808                 // Because delta is a power of two, (distance * (double)delta) can always be computed exactly.
       
  1809                 return new RandomJumpsSpliterator(r.copyAndJump(distance * (double)delta), i, m, distance);
       
  1810             }
       
  1811 
       
  1812             public boolean tryAdvance(Consumer<? super RandomGenerator> consumer) {
       
  1813                 if (consumer == null) throw new NullPointerException();
       
  1814                 long i = index, f = fence;
       
  1815                 if (i < f) {
       
  1816                     consumer.accept(generatingGenerator.copyAndJump(distance));
       
  1817                     index = i + 1;
       
  1818                     return true;
       
  1819                 }
       
  1820                 return false;
       
  1821             }
       
  1822 
       
  1823             public void forEachRemaining(Consumer<? super RandomGenerator> consumer) {
       
  1824                 if (consumer == null) throw new NullPointerException();
       
  1825                 long i = index, f = fence;
       
  1826                 if (i < f) {
       
  1827                     index = f;
       
  1828                     ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1829                     do {
       
  1830                         consumer.accept(r.copyAndJump(distance));
       
  1831                     } while (++i < f);
       
  1832                 }
       
  1833             }
       
  1834         }
       
  1835 
       
  1836         /**
       
  1837          * Spliterator for stream of generators of type RandomGenerator produced by leaps.
       
  1838          */
       
  1839         static class RandomLeapsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator<JumpableGenerator> {
       
  1840             ArbitrarilyJumpableGenerator generatingGenerator;
       
  1841             final double distance;
       
  1842 
       
  1843             RandomLeapsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, double distance) {
       
  1844                 super(index, fence);
       
  1845                 this.generatingGenerator = generatingGenerator; this.distance = distance;
       
  1846             }
       
  1847 
       
  1848             public Spliterator<JumpableGenerator> trySplit() {
       
  1849                 long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
       
  1850                 if (m <= i) return null;
       
  1851                 index = m;
       
  1852                 // Because delta is a power of two, (distance * (double)delta) can always be computed exactly.
       
  1853                 return new RandomLeapsSpliterator(generatingGenerator.copyAndJump(distance * (double)delta), i, m, distance);
       
  1854             }
       
  1855 
       
  1856             public boolean tryAdvance(Consumer<? super JumpableGenerator> consumer) {
       
  1857                 if (consumer == null) throw new NullPointerException();
       
  1858                 long i = index, f = fence;
       
  1859                 if (i < f) {
       
  1860                     consumer.accept(generatingGenerator.copyAndJump(distance));
       
  1861                     index = i + 1;
       
  1862                     return true;
       
  1863                 }
       
  1864                 return false;
       
  1865             }
       
  1866 
       
  1867             public void forEachRemaining(Consumer<? super JumpableGenerator> consumer) {
       
  1868                 if (consumer == null) throw new NullPointerException();
       
  1869                 long i = index, f = fence;
       
  1870                 if (i < f) {
       
  1871                     index = f;
       
  1872                     ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1873                     do {
       
  1874                         consumer.accept(r.copyAndJump(distance));
       
  1875                     } while (++i < f);
       
  1876                 }
       
  1877             }
       
  1878         }
       
  1879 
       
  1880         /**
       
  1881          * Spliterator for stream of generators of type RandomGenerator produced by arbitrary jumps.
       
  1882          */
       
  1883         static class RandomArbitraryJumpsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator<ArbitrarilyJumpableGenerator> {
       
  1884             ArbitrarilyJumpableGenerator generatingGenerator;
       
  1885             final double distance;
       
  1886 
       
  1887             RandomArbitraryJumpsSpliterator(ArbitrarilyJumpableGenerator generatingGenerator, long index, long fence, double distance) {
       
  1888                 super(index, fence);
       
  1889                 this.generatingGenerator = generatingGenerator; this.distance = distance;
       
  1890             }
       
  1891 
       
  1892             public Spliterator<ArbitrarilyJumpableGenerator> trySplit() {
       
  1893                 long i = index, delta = Long.highestOneBit((fence - i) - 1), m = i + delta;
       
  1894                 if (m <= i) return null;
       
  1895                 index = m;
       
  1896                 // Because delta is a power of two, (distance * (double)delta) can always be computed exactly.
       
  1897                 return new RandomArbitraryJumpsSpliterator(generatingGenerator.copyAndJump(distance * (double)delta), i, m, distance);
       
  1898             }
       
  1899 
       
  1900             public boolean tryAdvance(Consumer<? super ArbitrarilyJumpableGenerator> consumer) {
       
  1901                 if (consumer == null) throw new NullPointerException();
       
  1902                 long i = index, f = fence;
       
  1903                 if (i < f) {
       
  1904                     consumer.accept(generatingGenerator.copyAndJump(distance));
       
  1905                     index = i + 1;
       
  1906                     return true;
       
  1907                 }
       
  1908                 return false;
       
  1909             }
       
  1910 
       
  1911             public void forEachRemaining(Consumer<? super ArbitrarilyJumpableGenerator> consumer) {
       
  1912                 if (consumer == null) throw new NullPointerException();
       
  1913                 long i = index, f = fence;
       
  1914                 if (i < f) {
       
  1915                     index = f;
       
  1916                     ArbitrarilyJumpableGenerator r = generatingGenerator;
       
  1917                     do {
       
  1918                         consumer.accept(r.copyAndJump(distance));
       
  1919                     } while (++i < f);
       
  1920                 }
       
  1921             }
       
  1922         }
       
  1923 
       
  1924     }
       
  1925 
       
  1926     /**
       
  1927      * This class provides much of the implementation of the {@link SplittableGenerator} interface, to
       
  1928      * minimize the effort required to implement this interface.
       
  1929      * <p>
       
  1930      * To implement a pseudorandom number generator, the programmer needs only to extend this class and
       
  1931      * provide implementations for the methods {@code nextInt()}, {@code nextLong()}, {@code period()},
       
  1932      * and {@code split(SplittableGenerator)}.
       
  1933      * <p>
       
  1934      * (If the pseudorandom number generator also has the ability to jump an arbitrary
       
  1935      * specified distance, then the programmer may wish to consider instead extending the
       
  1936      * class {@link AbstractArbitrarilyJumpableGenerator}.  See also the class
       
  1937      * {@link AbstractSplittableWithBrineGenerator}.)
       
  1938      * <p>
       
  1939      * The programmer should generally provide at least three constructors: one that takes no arguments,
       
  1940      * one that accepts a {@code long} seed value, and one that accepts an array of seed {@code byte}
       
  1941      * values. This class provides a public {@code initialSeed()} method that may be useful in
       
  1942      * initializing some static state from which to derive defaults seeds for use by the no-argument
       
  1943      * constructor.
       
  1944      * <p>
       
  1945      * For the stream methods (such as {@code ints()} and {@code splits()}), this class provides
       
  1946      * {@link Spliterator}-based implementations that allow parallel execution when appropriate.
       
  1947      * <p>
       
  1948      * The documentation for each non-abstract method in this class describes its implementation in
       
  1949      * detail. Each of these methods may be overridden if the pseudorandom number generator being
       
  1950      * implemented admits a more efficient implementation.
       
  1951      *
       
  1952      * @since 14
       
  1953      */
       
  1954     public abstract static class AbstractSplittableGenerator extends AbstractSpliteratorGenerator implements SplittableGenerator {
       
  1955 
       
  1956         /*
       
  1957          * Implementation Overview.
       
  1958          *
       
  1959          * This class provides most of the "user API" methods needed to
       
  1960          * satisfy the interface SplittableGenerator.  Most of these methods
       
  1961          * are in turn inherited from AbstractGenerator and the non-public class
       
  1962          * AbstractSpliteratorGenerator; this class provides two versions of the
       
  1963          * splits method and defines the spliterators necessary to support
       
  1964          * them.
       
  1965          *
       
  1966          * File organization: First the non-public methods needed by the class
       
  1967          * AbstractSpliteratorGenerator, then the main public methods, followed by some
       
  1968          * custom spliterator classes.
       
  1969          */
       
  1970 
       
  1971         public Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) {
       
  1972             return new RandomIntsSpliterator(this, index, fence, origin, bound);
       
  1973         }
       
  1974 
       
  1975         public Spliterator.OfLong makeLongsSpliterator(long index, long fence, long origin, long bound) {
       
  1976             return new RandomLongsSpliterator(this, index, fence, origin, bound);
       
  1977         }
       
  1978 
       
  1979         public Spliterator.OfDouble makeDoublesSpliterator(long index, long fence, double origin, double bound) {
       
  1980             return new RandomDoublesSpliterator(this, index, fence, origin, bound);
       
  1981         }
       
  1982 
       
  1983         Spliterator<SplittableGenerator> makeSplitsSpliterator(long index, long fence, SplittableGenerator source) {
       
  1984             return new RandomSplitsSpliterator(source, index, fence, this);
       
  1985         }
       
  1986 
       
  1987         /* ---------------- public methods ---------------- */
       
  1988 
       
  1989         /**
       
  1990          * Implements the @code{split()} method as {@code this.split(this)}.
       
  1991          *
       
  1992          * @return the new {@link SplittableGenerator} instance
       
  1993          */
       
  1994         public SplittableGenerator split() {
       
  1995             return this.split(this);
       
  1996         }
       
  1997 
       
  1998         // Stream methods for splittings
       
  1999 
       
  2000         /**
       
  2001          * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
       
  2002          * implements the {@link SplittableGenerator} interface.
       
  2003          * <p>
       
  2004          * This pseudorandom number generator provides the entropy used to seed the new ones.
       
  2005          *
       
  2006          * @return a stream of {@link SplittableGenerator} objects
       
  2007          *
       
  2008          * @implNote This method is implemented to be equivalent to {@code splits(Long.MAX_VALUE)}.
       
  2009          */
       
  2010         public Stream<SplittableGenerator> splits() {
       
  2011             return this.splits(Long.MAX_VALUE, this);
       
  2012         }
       
  2013 
       
  2014         /**
       
  2015          * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
       
  2016          * generators, each of which implements the {@link SplittableGenerator} interface.
       
  2017          * <p>
       
  2018          * This pseudorandom number generator provides the entropy used to seed the new ones.
       
  2019          *
       
  2020          * @param streamSize the number of values to generate
       
  2021          *
       
  2022          * @return a stream of {@link SplittableGenerator} objects
       
  2023          *
       
  2024          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  2025          */
       
  2026         public Stream<SplittableGenerator> splits(long streamSize) {
       
  2027             return this.splits(streamSize, this);
       
  2028         }
       
  2029 
       
  2030         /**
       
  2031          * Returns an effectively unlimited stream of new pseudorandom number generators, each of which
       
  2032          * implements the {@link SplittableGenerator} interface.
       
  2033          *
       
  2034          * @param source a {@link SplittableGenerator} instance to be used instead of this one as a source of
       
  2035          *               pseudorandom bits used to initialize the state of the new ones.
       
  2036          *
       
  2037          * @return a stream of {@link SplittableGenerator} objects
       
  2038          *
       
  2039          * @implNote This method is implemented to be equivalent to {@code splits(Long.MAX_VALUE)}.
       
  2040          */
       
  2041         public Stream<SplittableGenerator> splits(SplittableGenerator source) {
       
  2042             return this.splits(Long.MAX_VALUE, source);
       
  2043         }
       
  2044 
       
  2045         /**
       
  2046          * Returns a stream producing the given {@code streamSize} number of new pseudorandom number
       
  2047          * generators, each of which implements the {@link SplittableGenerator} interface.
       
  2048          *
       
  2049          * @param streamSize the number of values to generate
       
  2050          * @param source     a {@link SplittableGenerator} instance to be used instead of this one as a source
       
  2051          *                   of pseudorandom bits used to initialize the state of the new ones.
       
  2052          *
       
  2053          * @return a stream of {@link SplittableGenerator} objects
       
  2054          *
       
  2055          * @throws IllegalArgumentException if {@code streamSize} is less than zero
       
  2056          */
       
  2057         public Stream<SplittableGenerator> splits(long streamSize, SplittableGenerator source) {
       
  2058             RandomSupport.checkStreamSize(streamSize);
       
  2059             return StreamSupport.stream(makeSplitsSpliterator(0L, streamSize, source), false);
       
  2060         }
       
  2061 
       
  2062         /**
       
  2063          * Spliterator for int streams.  We multiplex the four int versions into one class by treating a
       
  2064          * bound less than origin as unbounded, and also by treating "infinite" as equivalent to
       
  2065          * {@code Long.MAX_VALUE}. For splits, it uses the standard divide-by-two approach. The long and
       
  2066          * double versions of this class are identical except for types.
       
  2067          */
       
  2068         static class RandomIntsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfInt {
       
  2069             final SplittableGenerator generatingGenerator;
       
  2070             final int origin;
       
  2071             final int bound;
       
  2072 
       
  2073             RandomIntsSpliterator(SplittableGenerator generatingGenerator, long index, long fence, int origin, int bound) {
       
  2074                 super(index, fence);
       
  2075                 this.generatingGenerator = generatingGenerator;
       
  2076                 this.origin = origin; this.bound = bound;
       
  2077             }
       
  2078 
       
  2079             public Spliterator.OfInt trySplit() {
       
  2080                 long i = index, m = (i + fence) >>> 1;
       
  2081                 if (m <= i) return null;
       
  2082                 index = m;
       
  2083                 return new RandomIntsSpliterator(generatingGenerator.split(), i, m, origin, bound);
       
  2084             }
       
  2085 
       
  2086             public boolean tryAdvance(IntConsumer consumer) {
       
  2087                 if (consumer == null) throw new NullPointerException();
       
  2088                 long i = index, f = fence;
       
  2089                 if (i < f) {
       
  2090                     consumer.accept(RandomSupport.boundedNextInt(generatingGenerator, origin, bound));
       
  2091                     index = i + 1;
       
  2092                     return true;
       
  2093                 }
       
  2094                 else return false;
       
  2095             }
       
  2096 
       
  2097             public void forEachRemaining(IntConsumer consumer) {
       
  2098                 if (consumer == null) throw new NullPointerException();
       
  2099                 long i = index, f = fence;
       
  2100                 if (i < f) {
       
  2101                     index = f;
       
  2102                     RandomGenerator r = generatingGenerator;
       
  2103                     int o = origin, b = bound;
       
  2104                     do {
       
  2105                         consumer.accept(RandomSupport.boundedNextInt(r, o, b));
       
  2106                     } while (++i < f);
       
  2107                 }
       
  2108             }
       
  2109         }
       
  2110 
       
  2111         /**
       
  2112          * Spliterator for long streams.
       
  2113          */
       
  2114         static class RandomLongsSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfLong {
       
  2115             final SplittableGenerator generatingGenerator;
       
  2116             final long origin;
       
  2117             final long bound;
       
  2118 
       
  2119             RandomLongsSpliterator(SplittableGenerator generatingGenerator, long index, long fence, long origin, long bound) {
       
  2120                 super(index, fence);
       
  2121                 this.generatingGenerator = generatingGenerator;
       
  2122                 this.origin = origin; this.bound = bound;
       
  2123             }
       
  2124 
       
  2125             public Spliterator.OfLong trySplit() {
       
  2126                 long i = index, m = (i + fence) >>> 1;
       
  2127                 if (m <= i) return null;
       
  2128                 index = m;
       
  2129                 return new RandomLongsSpliterator(generatingGenerator.split(), i, m, origin, bound);
       
  2130             }
       
  2131 
       
  2132             public boolean tryAdvance(LongConsumer consumer) {
       
  2133                 if (consumer == null) throw new NullPointerException();
       
  2134                 long i = index, f = fence;
       
  2135                 if (i < f) {
       
  2136                     consumer.accept(RandomSupport.boundedNextLong(generatingGenerator, origin, bound));
       
  2137                     index = i + 1;
       
  2138                     return true;
       
  2139                 }
       
  2140                 else return false;
       
  2141             }
       
  2142 
       
  2143             public void forEachRemaining(LongConsumer consumer) {
       
  2144                 if (consumer == null) throw new NullPointerException();
       
  2145                 long i = index, f = fence;
       
  2146                 if (i < f) {
       
  2147                     index = f;
       
  2148                     RandomGenerator r = generatingGenerator;
       
  2149                     long o = origin, b = bound;
       
  2150                     do {
       
  2151                         consumer.accept(RandomSupport.boundedNextLong(r, o, b));
       
  2152                     } while (++i < f);
       
  2153                 }
       
  2154             }
       
  2155         }
       
  2156 
       
  2157         /**
       
  2158          * Spliterator for double streams.
       
  2159          */
       
  2160         static class RandomDoublesSpliterator extends RandomSupport.RandomSpliterator implements Spliterator.OfDouble {
       
  2161             final SplittableGenerator generatingGenerator;
       
  2162             final double origin;
       
  2163             final double bound;
       
  2164 
       
  2165             RandomDoublesSpliterator(SplittableGenerator generatingGenerator, long index, long fence, double origin, double bound) {
       
  2166                 super(index, fence);
       
  2167                 this.generatingGenerator = generatingGenerator;
       
  2168                 this.origin = origin; this.bound = bound;
       
  2169             }
       
  2170 
       
  2171             public Spliterator.OfDouble trySplit() {
       
  2172                 long i = index, m = (i + fence) >>> 1;
       
  2173                 if (m <= i) return null;
       
  2174                 index = m;
       
  2175                 return new RandomDoublesSpliterator(generatingGenerator.split(), i, m, origin, bound);
       
  2176             }
       
  2177 
       
  2178             public boolean tryAdvance(DoubleConsumer consumer) {
       
  2179                 if (consumer == null) throw new NullPointerException();
       
  2180                 long i = index, f = fence;
       
  2181                 if (i < f) {
       
  2182                     consumer.accept(RandomSupport.boundedNextDouble(generatingGenerator, origin, bound));
       
  2183                     index = i + 1;
       
  2184                     return true;
       
  2185                 }
       
  2186                 else return false;
       
  2187             }
       
  2188 
       
  2189             public void forEachRemaining(DoubleConsumer consumer) {
       
  2190                 if (consumer == null) throw new NullPointerException();
       
  2191                 long i = index, f = fence;
       
  2192                 if (i < f) {
       
  2193                     index = f;
       
  2194                     RandomGenerator r = generatingGenerator;
       
  2195                     double o = origin, b = bound;
       
  2196                     do {
       
  2197                         consumer.accept(RandomSupport.boundedNextDouble(r, o, b));
       
  2198                     } while (++i < f);
       
  2199                 }
       
  2200             }
       
  2201         }
       
  2202 
       
  2203         /**
       
  2204          * Spliterator for stream of generators of type SplittableGenerator.  We multiplex the two
       
  2205          * versions into one class by treating "infinite" as equivalent to Long.MAX_VALUE.
       
  2206          * For splits, it uses the standard divide-by-two approach.
       
  2207          */
       
  2208         static class RandomSplitsSpliterator extends RandomSpliterator implements Spliterator<SplittableGenerator> {
       
  2209             final SplittableGenerator generatingGenerator;
       
  2210             final SplittableGenerator constructingGenerator;
       
  2211 
       
  2212             RandomSplitsSpliterator(SplittableGenerator generatingGenerator,
       
  2213 				    long index, long fence,
       
  2214 				    SplittableGenerator constructingGenerator) {
       
  2215                 super(index, fence);
       
  2216                 this.generatingGenerator = generatingGenerator;
       
  2217                 this.constructingGenerator = constructingGenerator;
       
  2218             }
       
  2219 
       
  2220             public Spliterator<SplittableGenerator> trySplit() {
       
  2221                 long i = index, m = (i + fence) >>> 1;
       
  2222                 if (m <= i) return null;
       
  2223                 index = m;
       
  2224                 return new RandomSplitsSpliterator(generatingGenerator.split(), i, m, constructingGenerator);
       
  2225             }
       
  2226 
       
  2227             public boolean tryAdvance(Consumer<? super SplittableGenerator> consumer) {
       
  2228                 if (consumer == null) throw new NullPointerException();
       
  2229                 long i = index, f = fence;
       
  2230                 if (i < f) {
       
  2231                     consumer.accept(constructingGenerator.split(generatingGenerator));
       
  2232                     index = i + 1;
       
  2233                     return true;
       
  2234                 }
       
  2235                 else return false;
       
  2236             }
       
  2237 
       
  2238             public void forEachRemaining(Consumer<? super SplittableGenerator> consumer) {
       
  2239                 if (consumer == null) throw new NullPointerException();
       
  2240                 long i = index, f = fence;
       
  2241                 if (i < f) {
       
  2242                     index = f;
       
  2243                     SplittableGenerator c = constructingGenerator;
       
  2244                     SplittableGenerator r = generatingGenerator;
       
  2245                     do {
       
  2246                         consumer.accept(c.split(r));
       
  2247                     } while (++i < f);
       
  2248                 }
       
  2249             }
       
  2250         }
       
  2251 
       
  2252     }
       
  2253 
       
  2254     /**
       
  2255      * This class provides much of the implementation of the {@link SplittableGenerator} interface, to
       
  2256      * minimize the effort required to implement this interface.  It is similar to the class
       
  2257      * {@link AbstractSplittableGenerator} but makes use of the brine technique for ensuring that
       
  2258      * distinct generators created by a single call to a {@code splits} method have distinct state cycles.
       
  2259      * <p>
       
  2260      * To implement a pseudorandom number generator, the programmer needs only to extend this class and
       
  2261      * provide implementations for the methods {@code nextInt()}, {@code nextLong()}, {@code period()},
       
  2262      * and {@code split(SplittableGenerator, long)}.
       
  2263      * <p>
       
  2264      * The programmer should generally provide at least three constructors: one that takes no arguments,
       
  2265      * one that accepts a {@code long} seed value, and one that accepts an array of seed {@code byte}
       
  2266      * values. This class provides a public {@code initialSeed()} method that may be useful in
       
  2267      * initializing some static state from which to derive defaults seeds for use by the no-argument
       
  2268      * constructor.
       
  2269      * <p>
       
  2270      * For the stream methods (such as {@code ints()} and {@code splits()}), this class provides
       
  2271      * {@link Spliterator}-based implementations that allow parallel execution when appropriate.
       
  2272      * <p>
       
  2273      * The documentation for each non-abstract method in this class describes its implementation in
       
  2274      * detail. Each of these methods may be overridden if the pseudorandom number generator being
       
  2275      * implemented admits a more efficient implementation.
       
  2276      *
       
  2277      * @since 14
       
  2278      */
       
  2279     public abstract static class AbstractSplittableWithBrineGenerator
       
  2280 	extends AbstractSplittableGenerator {
       
  2281 
       
  2282 	/*
       
  2283 	 * Implementation Overview.
       
  2284 	 *
       
  2285          * This class provides most of the "user API" methods needed to
       
  2286          * satisfy the interface SplittableGenerator.  Most of these methods
       
  2287          * are in turn inherited from AbstractSplittableGenerator and the non-public class
       
  2288          * AbstractSpliteratorGenerator; this class provides four versions of the
       
  2289          * splits method and defines the spliterators necessary to support
       
  2290          * them.
       
  2291 	 *
       
  2292 	 * File organization: First the non-public methods needed by the class
       
  2293 	 * AbstractSplittableWithBrineGenerator, then the main public methods,
       
  2294 	 * followed by some custom spliterator classes needed for stream methods.
       
  2295 	 */
       
  2296 
       
  2297 	// The salt consists groups of bits each SALT_SHIFT in size, starting from
       
  2298 	// the left-hand (high-order) end of the word.  We can regard them as
       
  2299 	// digits base (1 << SALT_SHIFT).  If SALT_SHIFT does not divide 64
       
  2300 	// evenly, then any leftover bits at the low end of the word are zero.
       
  2301 	// The lowest digit of the salt is set to the largest possible digit
       
  2302 	// (all 1-bits, or ((1 << SALT_SHIFT) - 1)); all other digits are set
       
  2303 	// to a randomly chosen value less than that largest possible digit.
       
  2304 	// The salt may be shifted left by SALT_SHIFT any number of times.
       
  2305 	// If any salt remains in the word, its right-hand end can be identified
       
  2306 	// by searching from left to right for an occurrence of a digit that is
       
  2307 	// all 1-bits (not that we ever do that; this is simply a proof that one
       
  2308 	// can identify the boundary between the salt and the index if any salt
       
  2309 	// remains in the word).  The idea is that before computing the bitwise OR
       
  2310 	// of an index and the salt, one can first check to see whether the
       
  2311 	// bitwise AND is nonzero; if so, one can shift the salt left by
       
  2312 	// SALT_SHIFT and try again.  In this way, when the bitwise OR is
       
  2313 	// computed, if the salt is nonzero then its rightmost 1-bit is to the
       
  2314 	// left of the leftmost 1-bit of the index.
       
  2315 
       
  2316 	// We need 2 <= SALT_SHIFT <= 63 (3 through 8 are good values; 4 is probably best)
       
  2317 	static final int SALT_SHIFT = 4;
       
  2318 
       
  2319 	// Methods required by class AbstractSpliteratorGenerator (override)
       
  2320 	Spliterator<SplittableGenerator> makeSplitsSpliterator(long index, long fence, SplittableGenerator source) {
       
  2321 	    // This little algorithm to generate a new salt value is carefully
       
  2322 	    // designed to work even if SALT_SHIFT does not evenly divide 64
       
  2323 	    // (the number of bits in a long value).
       
  2324 	    long bits = nextLong();
       
  2325 	    long multiplier = (1 << SALT_SHIFT) - 1;
       
  2326 	    long salt = multiplier << (64 - SALT_SHIFT);
       
  2327 	    while ((salt & multiplier) != 0) {
       
  2328 		long digit = Math.multiplyHigh(bits, multiplier);
       
  2329 		salt = (salt >>> SALT_SHIFT) | (digit << (64 - SALT_SHIFT));
       
  2330 		bits *= multiplier;
       
  2331 	    }
       
  2332 	    // This is the point at which newly generated salt gets injected into
       
  2333 	    // the root of a newly created brine-generating splits-spliterator.
       
  2334 	    return new RandomSplitsSpliteratorWithSalt(source, index, fence, this, salt);
       
  2335 	}
       
  2336 
       
  2337 	/* ---------------- public methods ---------------- */
       
  2338 
       
  2339 	// Stream methods for splitting
       
  2340 
       
  2341 	/**
       
  2342 	 * Constructs and returns a new instance of {@code AbstractSplittableWithBrineGenerator}
       
  2343 	 * that shares no mutable state with this instance. However, with very high
       
  2344 	 * probability, the set of values collectively generated by the two objects
       
  2345 	 * should have the same statistical properties as if the same quantity of
       
  2346 	 * values were generated by a single thread using a single may be
       
  2347 	 * {@code AbstractSplittableWithBrineGenerator} object. Either or both of the two objects
       
  2348 	 * further split using the {@code split()} method, and the same expected
       
  2349 	 * statistical properties apply to the entire set of generators constructed
       
  2350 	 * by such recursive splitting.
       
  2351 	 *
       
  2352 	 * @param brine a long value, of which the low 63 bits provide a unique id
       
  2353 	 * among calls to this method for constructing a single series of Generator objects.
       
  2354 	 *
       
  2355 	 * @return the new {@code AbstractSplittableWithBrineGenerator} instance
       
  2356 	 */
       
  2357 	public SplittableGenerator split(long brine) {
       
  2358 	    return this.split(this, brine);
       
  2359 	}
       
  2360 
       
  2361 	/**
       
  2362 	 * Constructs and returns a new instance of {@code L64X128MixRandom}
       
  2363 	 * that shares no mutable state with this instance.
       
  2364 	 * However, with very high probability, the set of values collectively
       
  2365 	 * generated by the two objects has the same statistical properties as if
       
  2366 	 * same the quantity of values were generated by a single thread using
       
  2367 	 * a single {@code L64X128MixRandom} object.  Either or both of the two
       
  2368 	 * objects may be further split using the {@code split} method,
       
  2369 	 * and the same expected statistical properties apply to the
       
  2370 	 * entire set of generators constructed by such recursive splitting.
       
  2371 	 *
       
  2372 	 * @param source a {@code SplittableGenerator} instance to be used instead
       
  2373 	 *               of this one as a source of pseudorandom bits used to
       
  2374 	 *               initialize the state of the new ones.
       
  2375 	 * @return a new instance of {@code L64X128MixRandom}
       
  2376 	 */
       
  2377 	public SplittableGenerator split(SplittableGenerator source) {
       
  2378 	    // It's a one-off: supply randomly chosen brine
       
  2379 	    return this.split(source, source.nextLong());
       
  2380 	}
       
  2381 
       
  2382 	/**
       
  2383 	 * Constructs and returns a new instance of {@code AbstractSplittableWithBrineGenerator}
       
  2384 	 * that shares no mutable state with this instance. However, with very high
       
  2385 	 * probability, the set of values collectively generated by the two objects
       
  2386 	 * should have the same statistical properties as if the same quantity of
       
  2387 	 * values were generated by a single thread using a single may be
       
  2388 	 * {@code AbstractSplittableWithBrineGenerator} object. Either or both of the two objects
       
  2389 	 * further split using the {@code split()} method, and the same expected
       
  2390 	 * statistical properties apply to the entire set of generators constructed
       
  2391 	 * by such recursive splitting.
       
  2392 	 *
       
  2393 	 * @param source a {@code SplittableGenerator} instance to be used instead
       
  2394 	 *               of this one as a source of pseudorandom bits used to
       
  2395 	 *               initialize the state of the new ones.
       
  2396 	 * @param brine a long value, of which the low 63 bits provide a unique id
       
  2397 	 *              among calls to this method for constructing a single series of
       
  2398 	 *              {@code RandomGenerator} objects.
       
  2399 	 *
       
  2400 	 * @return the new {@code AbstractSplittableWithBrineGenerator} instance
       
  2401 	 */
       
  2402 	public abstract SplittableGenerator split(SplittableGenerator source, long brine);
       
  2403 
       
  2404 
       
  2405 	/* ---------------- spliterator ---------------- */
       
  2406 	/**
       
  2407 	 * Alternate spliterator for stream of generators of type SplittableGenerator.  We multiplex
       
  2408 	 * the two versions into one class by treating "infinite" as equivalent to Long.MAX_VALUE.
       
  2409 	 * For splits, it uses the standard divide-by-two approach.
       
  2410 	 *
       
  2411 	 * This differs from {@code SplittableGenerator.RandomSplitsSpliterator} in that it provides
       
  2412 	 * a brine argument (a mixture of salt and an index) when calling the {@code split} method.
       
  2413 	 */
       
  2414 	static class RandomSplitsSpliteratorWithSalt
       
  2415 	    extends RandomSpliterator implements Spliterator<SplittableGenerator> {
       
  2416 
       
  2417 	    final SplittableGenerator generatingGenerator;
       
  2418 	    final AbstractSplittableWithBrineGenerator constructingGenerator;
       
  2419 	    long salt;
       
  2420 
       
  2421 	    // Important invariant: 0 <= index <= fence
       
  2422 
       
  2423 	    // Important invariant: if salt and index are both nonzero,
       
  2424 	    // the rightmost 1-bit of salt is to the left of the leftmost 1-bit of index.
       
  2425 	    // If necessary, the salt can be leftshifted by SALT_SHIFT as many times as
       
  2426 	    // necessary to maintain the invariant.
       
  2427 
       
  2428 	    RandomSplitsSpliteratorWithSalt(SplittableGenerator generatingGenerator, long index, long fence,
       
  2429 					    AbstractSplittableWithBrineGenerator constructingGenerator, long salt) {
       
  2430 		super(index, fence);
       
  2431 		this.generatingGenerator = generatingGenerator;
       
  2432 		this.constructingGenerator = constructingGenerator;
       
  2433 		while ((salt != 0) && (Long.compareUnsigned(salt & -salt, index) <= 0)) {
       
  2434 		    salt = salt << SALT_SHIFT;
       
  2435 		}
       
  2436 		this.salt = salt;
       
  2437 	    }
       
  2438 
       
  2439             public Spliterator<SplittableGenerator> trySplit() {
       
  2440                 long i = index, m = (i + fence) >>> 1;
       
  2441                 if (m <= i) return null;
       
  2442 		RandomSplitsSpliteratorWithSalt result =
       
  2443 		    new RandomSplitsSpliteratorWithSalt(generatingGenerator.split(), i, m, constructingGenerator, salt);
       
  2444                 index = m;
       
  2445 		while ((salt != 0) && (Long.compareUnsigned(salt & -salt, index) <= 0)) {
       
  2446 		    salt = salt << SALT_SHIFT;
       
  2447 		}
       
  2448 		return result;
       
  2449             }
       
  2450 
       
  2451 	    public boolean tryAdvance(Consumer<? super SplittableGenerator> consumer) {
       
  2452 		if (consumer == null) throw new NullPointerException();
       
  2453 		long i = index, f = fence;
       
  2454 		if (i < f) {
       
  2455 		    consumer.accept(constructingGenerator.split(generatingGenerator, salt | i));
       
  2456 		    ++i;
       
  2457 		    index = i;
       
  2458 		    if ((i & salt) != 0) salt <<= SALT_SHIFT;
       
  2459 		    return true;
       
  2460 		}
       
  2461 		return false;
       
  2462 	    }
       
  2463 
       
  2464 	    public void forEachRemaining(Consumer<? super SplittableGenerator> consumer) {
       
  2465 		if (consumer == null) throw new NullPointerException();
       
  2466 		long i = index, f = fence;
       
  2467 		if (i < f) {
       
  2468 		    index = f;
       
  2469 		    AbstractSplittableWithBrineGenerator c = constructingGenerator;
       
  2470 		    SplittableGenerator r = generatingGenerator;
       
  2471 		    do {
       
  2472 			consumer.accept(c.split(r, salt | i));
       
  2473 			++i;
       
  2474 			if ((i & salt) != 0) salt <<= SALT_SHIFT;
       
  2475 		    } while (i < f);
       
  2476 		}
       
  2477 	    }
       
  2478 	}
       
  2479 
       
  2480     }
       
  2481 
       
  2482 }