ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/SplittableRandom.java
Revision: 1.33
Committed: Sat Nov 12 00:12:05 2016 UTC (7 years, 5 months ago) by dl
Branch: MAIN
Changes since 1.32: +14 -0 lines
Log Message:
Implement and Document useless next(int)

File Contents

# User Rev Content
1 dl 1.1 /*
2     * Copyright (c) 2013, 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;
27    
28     import java.util.concurrent.atomic.AtomicLong;
29 jsr166 1.26 import java.util.function.DoubleConsumer;
30 dl 1.1 import java.util.function.IntConsumer;
31     import java.util.function.LongConsumer;
32 jsr166 1.26 import java.util.stream.DoubleStream;
33 dl 1.1 import java.util.stream.IntStream;
34     import java.util.stream.LongStream;
35 jsr166 1.26 import java.util.stream.StreamSupport;
36 dl 1.1
37     /**
38     * A generator of uniform pseudorandom values applicable for use in
39     * (among other contexts) isolated parallel computations that may
40 dl 1.18 * generate subtasks. Class {@code SplittableRandom} supports methods for
41 jsr166 1.3 * producing pseudorandom numbers of type {@code int}, {@code long},
42 dl 1.1 * and {@code double} with similar usages as for class
43 jsr166 1.9 * {@link java.util.Random} but differs in the following ways:
44     *
45     * <ul>
46 dl 1.1 *
47     * <li>Series of generated values pass the DieHarder suite testing
48     * independence and uniformity properties of random number generators.
49     * (Most recently validated with <a
50     * href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> version
51     * 3.31.1</a>.) These tests validate only the methods for certain
52     * types and ranges, but similar properties are expected to hold, at
53 dl 1.11 * least approximately, for others as well. The <em>period</em>
54     * (length of any series of generated values before it repeats) is at
55 jsr166 1.27 * least 2<sup>64</sup>.
56 dl 1.1 *
57 jsr166 1.27 * <li>Method {@link #split} constructs and returns a new
58 dl 1.1 * SplittableRandom instance that shares no mutable state with the
59 dl 1.7 * current instance. However, with very high probability, the
60     * values collectively generated by the two objects have the same
61 dl 1.1 * statistical properties as if the same quantity of values were
62     * generated by a single thread using a single {@code
63 jsr166 1.27 * SplittableRandom} object.
64 dl 1.1 *
65     * <li>Instances of SplittableRandom are <em>not</em> thread-safe.
66     * They are designed to be split, not shared, across threads. For
67     * example, a {@link java.util.concurrent.ForkJoinTask
68     * fork/join-style} computation using random numbers might include a
69     * construction of the form {@code new
70     * Subtask(aSplittableRandom.split()).fork()}.
71     *
72     * <li>This class provides additional methods for generating random
73     * streams, that employ the above techniques when used in {@code
74 jsr166 1.27 * stream.parallel()} mode.
75 dl 1.1 *
76     * </ul>
77     *
78 dl 1.18 * <p>Instances of {@code SplittableRandom} are not cryptographically
79     * secure. Consider instead using {@link java.security.SecureRandom}
80     * in security-sensitive applications. Additionally,
81     * default-constructed instances do not use a cryptographically random
82     * seed unless the {@linkplain System#getProperty system property}
83     * {@code java.util.secureRandomSeed} is set to {@code true}.
84     *
85 dl 1.1 * @author Guy Steele
86 dl 1.2 * @author Doug Lea
87 dl 1.1 * @since 1.8
88     */
89 dl 1.23 public final class SplittableRandom {
90 dl 1.1
91     /*
92     * Implementation Overview.
93     *
94     * This algorithm was inspired by the "DotMix" algorithm by
95     * Leiserson, Schardl, and Sukha "Deterministic Parallel
96     * Random-Number Generation for Dynamic-Multithreading Platforms",
97 dl 1.15 * PPoPP 2012, as well as those in "Parallel random numbers: as
98     * easy as 1, 2, 3" by Salmon, Morae, Dror, and Shaw, SC 2011. It
99     * differs mainly in simplifying and cheapening operations.
100     *
101     * The primary update step (method nextSeed()) is to add a
102     * constant ("gamma") to the current (64 bit) seed, forming a
103     * simple sequence. The seed and the gamma values for any two
104     * SplittableRandom instances are highly likely to be different.
105     *
106     * Methods nextLong, nextInt, and derivatives do not return the
107     * sequence (seed) values, but instead a hash-like bit-mix of
108     * their bits, producing more independently distributed sequences.
109 dl 1.21 * For nextLong, the mix64 function is based on David Stafford's
110     * (http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html)
111     * "Mix13" variant of the "64-bit finalizer" function in Austin
112 dl 1.24 * Appleby's MurmurHash3 algorithm (see
113     * http://code.google.com/p/smhasher/wiki/MurmurHash3). The mix32
114 dl 1.21 * function is based on Stafford's Mix04 mix function, but returns
115     * the upper 32 bits cast as int.
116 dl 1.15 *
117     * The split operation uses the current generator to form the seed
118     * and gamma for another SplittableRandom. To conservatively
119     * avoid potential correlations between seed and value generation,
120 dl 1.21 * gamma selection (method mixGamma) uses different
121     * (Murmurhash3's) mix constants. To avoid potential weaknesses
122     * in bit-mixing transformations, we restrict gammas to odd values
123     * with at least 24 0-1 or 1-0 bit transitions. Rather than
124     * rejecting candidates with too few or too many bits set, method
125     * mixGamma flips some bits (which has the effect of mapping at
126     * most 4 to any given gamma value). This reduces the effective
127     * set of 64bit odd gamma values by about 2%, and serves as an
128 dl 1.15 * automated screening for sequence constant selection that is
129     * left as an empirical decision in some other hashing and crypto
130     * algorithms.
131     *
132     * The resulting generator thus transforms a sequence in which
133     * (typically) many bits change on each step, with an inexpensive
134     * mixer with good (but less than cryptographically secure)
135     * avalanching.
136     *
137     * The default (no-argument) constructor, in essence, invokes
138 dl 1.21 * split() for a common "defaultGen" SplittableRandom. Unlike
139     * other cases, this split must be performed in a thread-safe
140     * manner, so we use an AtomicLong to represent the seed rather
141     * than use an explicit SplittableRandom. To bootstrap the
142 dl 1.25 * defaultGen, we start off using a seed based on current time
143     * unless the java.util.secureRandomSeed property is set. This
144     * serves as a slimmed-down (and insecure) variant of SecureRandom
145     * that also avoids stalls that may occur when using /dev/random.
146 dl 1.15 *
147     * It is a relatively simple matter to apply the basic design here
148     * to use 128 bit seeds. However, emulating 128bit arithmetic and
149     * carrying around twice the state add more overhead than appears
150     * warranted for current usages.
151 dl 1.13 *
152 dl 1.15 * File organization: First the non-public methods that constitute
153     * the main algorithm, then the main public methods, followed by
154     * some custom spliterator classes needed for stream methods.
155 dl 1.1 */
156    
157     /**
158 dl 1.21 * The golden ratio scaled to 64bits, used as the initial gamma
159     * value for (unsplit) SplittableRandoms.
160 dl 1.1 */
161 dl 1.21 private static final long GOLDEN_GAMMA = 0x9e3779b97f4a7c15L;
162 dl 1.11
163     /**
164 dl 1.5 * The least non-zero value returned by nextDouble(). This value
165 dl 1.7 * is scaled by a random value of 53 bits to produce a result.
166 dl 1.5 */
167 dl 1.24 private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53);
168 dl 1.5
169     /**
170 dl 1.15 * The seed. Updated only via method nextSeed.
171 dl 1.1 */
172     private long seed;
173    
174     /**
175 dl 1.15 * The step value.
176 dl 1.1 */
177     private final long gamma;
178    
179     /**
180 dl 1.15 * Internal constructor used by all others except default constructor.
181 dl 1.1 */
182 dl 1.15 private SplittableRandom(long seed, long gamma) {
183     this.seed = seed;
184     this.gamma = gamma;
185 dl 1.1 }
186    
187     /**
188 dl 1.21 * Computes Stafford variant 13 of 64bit mix function.
189 dl 1.1 */
190     private static long mix64(long z) {
191 dl 1.24 z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L;
192     z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
193     return z ^ (z >>> 31);
194 dl 1.21 }
195    
196 dl 1.1 /**
197 dl 1.21 * Returns the 32 high bits of Stafford variant 4 mix64 function as int.
198 dl 1.1 */
199     private static int mix32(long z) {
200 dl 1.24 z = (z ^ (z >>> 33)) * 0x62a9d9ed799705f5L;
201 dl 1.21 return (int)(((z ^ (z >>> 28)) * 0xcb24d0a5c88c35b3L) >>> 32);
202 dl 1.1 }
203    
204     /**
205 dl 1.15 * Returns the gamma value to use for a new split instance.
206 dl 1.13 */
207 dl 1.21 private static long mixGamma(long z) {
208 dl 1.24 z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL; // MurmurHash3 mix constants
209 dl 1.21 z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
210     z = (z ^ (z >>> 33)) | 1L; // force to be odd
211     int n = Long.bitCount(z ^ (z >>> 1)); // ensure enough transitions
212     return (n < 24) ? z ^ 0xaaaaaaaaaaaaaaaaL : z;
213 dl 1.13 }
214    
215     /**
216 dl 1.15 * Adds gamma to seed.
217 dl 1.7 */
218 dl 1.15 private long nextSeed() {
219     return seed += gamma;
220 dl 1.7 }
221    
222 jsr166 1.32 // IllegalArgumentException messages
223     static final String BAD_BOUND = "bound must be positive";
224     static final String BAD_RANGE = "bound must be greater than origin";
225     static final String BAD_SIZE = "size must be non-negative";
226    
227 dl 1.7 /**
228 dl 1.15 * The seed generator for default constructors.
229 dl 1.7 */
230 jsr166 1.32 private static final AtomicLong defaultGen
231     = new AtomicLong(mix64(System.currentTimeMillis()) ^
232     mix64(System.nanoTime()));
233 dl 1.7
234 jsr166 1.32 // at end of <clinit> to survive static initialization circularity
235     static {
236 jsr166 1.31 if (java.security.AccessController.doPrivileged(
237     new java.security.PrivilegedAction<Boolean>() {
238     public Boolean run() {
239     return Boolean.getBoolean("java.util.secureRandomSeed");
240     }})) {
241 dl 1.21 byte[] seedBytes = java.security.SecureRandom.getSeed(8);
242 jsr166 1.30 long s = (long)seedBytes[0] & 0xffL;
243 dl 1.21 for (int i = 1; i < 8; ++i)
244 jsr166 1.30 s = (s << 8) | ((long)seedBytes[i] & 0xffL);
245 jsr166 1.32 defaultGen.set(s);
246 dl 1.18 }
247 dl 1.1 }
248    
249     /*
250     * Internal versions of nextX methods used by streams, as well as
251     * the public nextX(origin, bound) methods. These exist mainly to
252     * avoid the need for multiple versions of stream spliterators
253     * across the different exported forms of streams.
254     */
255    
256     /**
257     * The form of nextLong used by LongStream Spliterators. If
258     * origin is greater than bound, acts as unbounded form of
259     * nextLong, else as bounded form.
260     *
261     * @param origin the least value, unless greater than bound
262     * @param bound the upper bound (exclusive), must not equal origin
263     * @return a pseudorandom value
264     */
265     final long internalNextLong(long origin, long bound) {
266     /*
267     * Four Cases:
268     *
269     * 1. If the arguments indicate unbounded form, act as
270     * nextLong().
271     *
272     * 2. If the range is an exact power of two, apply the
273     * associated bit mask.
274     *
275     * 3. If the range is positive, loop to avoid potential bias
276     * when the implicit nextLong() bound (2<sup>64</sup>) is not
277     * evenly divisible by the range. The loop rejects candidates
278     * computed from otherwise over-represented values. The
279     * expected number of iterations under an ideal generator
280 dl 1.4 * varies from 1 to 2, depending on the bound. The loop itself
281     * takes an unlovable form. Because the first candidate is
282     * already available, we need a break-in-the-middle
283     * construction, which is concisely but cryptically performed
284     * within the while-condition of a body-less for loop.
285 dl 1.1 *
286     * 4. Otherwise, the range cannot be represented as a positive
287 dl 1.4 * long. The loop repeatedly generates unbounded longs until
288     * obtaining a candidate meeting constraints (with an expected
289     * number of iterations of less than two).
290 dl 1.1 */
291    
292     long r = mix64(nextSeed());
293     if (origin < bound) {
294     long n = bound - origin, m = n - 1;
295 dl 1.7 if ((n & m) == 0L) // power of two
296 dl 1.1 r = (r & m) + origin;
297 dl 1.7 else if (n > 0L) { // reject over-represented candidates
298 dl 1.1 for (long u = r >>> 1; // ensure nonnegative
299 dl 1.7 u + m - (r = u % n) < 0L; // rejection check
300 dl 1.1 u = mix64(nextSeed()) >>> 1) // retry
301     ;
302     r += origin;
303     }
304 dl 1.7 else { // range not representable as long
305 dl 1.1 while (r < origin || r >= bound)
306     r = mix64(nextSeed());
307     }
308     }
309     return r;
310     }
311    
312     /**
313     * The form of nextInt used by IntStream Spliterators.
314     * Exactly the same as long version, except for types.
315     *
316     * @param origin the least value, unless greater than bound
317     * @param bound the upper bound (exclusive), must not equal origin
318     * @return a pseudorandom value
319     */
320     final int internalNextInt(int origin, int bound) {
321     int r = mix32(nextSeed());
322     if (origin < bound) {
323     int n = bound - origin, m = n - 1;
324 dl 1.13 if ((n & m) == 0)
325 dl 1.1 r = (r & m) + origin;
326     else if (n > 0) {
327     for (int u = r >>> 1;
328 dl 1.7 u + m - (r = u % n) < 0;
329 dl 1.1 u = mix32(nextSeed()) >>> 1)
330     ;
331     r += origin;
332     }
333     else {
334     while (r < origin || r >= bound)
335     r = mix32(nextSeed());
336     }
337     }
338     return r;
339     }
340    
341     /**
342     * The form of nextDouble used by DoubleStream Spliterators.
343     *
344     * @param origin the least value, unless greater than bound
345     * @param bound the upper bound (exclusive), must not equal origin
346     * @return a pseudorandom value
347     */
348     final double internalNextDouble(double origin, double bound) {
349 dl 1.24 double r = (nextLong() >>> 11) * DOUBLE_UNIT;
350 dl 1.1 if (origin < bound) {
351     r = r * (bound - origin) + origin;
352 dl 1.7 if (r >= bound) // correct for rounding
353 dl 1.1 r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
354     }
355     return r;
356     }
357    
358     /* ---------------- public methods ---------------- */
359    
360     /**
361 dl 1.7 * Creates a new SplittableRandom instance using the specified
362     * initial seed. SplittableRandom instances created with the same
363 dl 1.11 * seed in the same program generate identical sequences of values.
364 dl 1.1 *
365     * @param seed the initial seed
366     */
367     public SplittableRandom(long seed) {
368 dl 1.21 this(seed, GOLDEN_GAMMA);
369 dl 1.1 }
370    
371     /**
372     * Creates a new SplittableRandom instance that is likely to
373     * generate sequences of values that are statistically independent
374     * of those of any other instances in the current program; and
375     * may, and typically does, vary across program invocations.
376     */
377 dl 1.21 public SplittableRandom() { // emulate defaultGen.split()
378 dl 1.23 long s = defaultGen.getAndAdd(2 * GOLDEN_GAMMA);
379 dl 1.21 this.seed = mix64(s);
380     this.gamma = mixGamma(s + GOLDEN_GAMMA);
381 dl 1.1 }
382    
383     /**
384     * Constructs and returns a new SplittableRandom instance that
385     * shares no mutable state with this instance. However, with very
386     * high probability, the set of values collectively generated by
387     * the two objects has the same statistical properties as if the
388     * same quantity of values were generated by a single thread using
389     * a single SplittableRandom object. Either or both of the two
390     * objects may be further split using the {@code split()} method,
391     * and the same expected statistical properties apply to the
392     * entire set of generators constructed by such recursive
393     * splitting.
394     *
395     * @return the new SplittableRandom instance
396     */
397     public SplittableRandom split() {
398 dl 1.21 return new SplittableRandom(nextLong(), mixGamma(nextSeed()));
399 dl 1.1 }
400    
401     /**
402     * Returns a pseudorandom {@code int} value.
403     *
404 dl 1.7 * @return a pseudorandom {@code int} value
405 dl 1.1 */
406     public int nextInt() {
407     return mix32(nextSeed());
408     }
409    
410     /**
411 dl 1.7 * Returns a pseudorandom {@code int} value between zero (inclusive)
412 dl 1.1 * and the specified bound (exclusive).
413     *
414 dl 1.18 * @param bound the upper bound (exclusive). Must be positive.
415 dl 1.7 * @return a pseudorandom {@code int} value between zero
416 jsr166 1.10 * (inclusive) and the bound (exclusive)
417 dl 1.16 * @throws IllegalArgumentException if {@code bound} is not positive
418 dl 1.1 */
419     public int nextInt(int bound) {
420     if (bound <= 0)
421 jsr166 1.28 throw new IllegalArgumentException(BAD_BOUND);
422 dl 1.1 // Specialize internalNextInt for origin 0
423     int r = mix32(nextSeed());
424     int m = bound - 1;
425 dl 1.13 if ((bound & m) == 0) // power of two
426 dl 1.1 r &= m;
427     else { // reject over-represented candidates
428     for (int u = r >>> 1;
429 dl 1.7 u + m - (r = u % bound) < 0;
430 dl 1.1 u = mix32(nextSeed()) >>> 1)
431     ;
432     }
433     return r;
434     }
435    
436     /**
437     * Returns a pseudorandom {@code int} value between the specified
438     * origin (inclusive) and the specified bound (exclusive).
439     *
440     * @param origin the least value returned
441     * @param bound the upper bound (exclusive)
442     * @return a pseudorandom {@code int} value between the origin
443 jsr166 1.10 * (inclusive) and the bound (exclusive)
444 dl 1.7 * @throws IllegalArgumentException if {@code origin} is greater than
445 dl 1.1 * or equal to {@code bound}
446     */
447     public int nextInt(int origin, int bound) {
448     if (origin >= bound)
449 jsr166 1.28 throw new IllegalArgumentException(BAD_RANGE);
450 dl 1.1 return internalNextInt(origin, bound);
451     }
452    
453     /**
454     * Returns a pseudorandom {@code long} value.
455     *
456 dl 1.7 * @return a pseudorandom {@code long} value
457 dl 1.1 */
458     public long nextLong() {
459     return mix64(nextSeed());
460     }
461    
462     /**
463 dl 1.7 * Returns a pseudorandom {@code long} value between zero (inclusive)
464 dl 1.1 * and the specified bound (exclusive).
465     *
466 dl 1.18 * @param bound the upper bound (exclusive). Must be positive.
467 dl 1.7 * @return a pseudorandom {@code long} value between zero
468 jsr166 1.10 * (inclusive) and the bound (exclusive)
469 dl 1.16 * @throws IllegalArgumentException if {@code bound} is not positive
470 dl 1.1 */
471     public long nextLong(long bound) {
472     if (bound <= 0)
473 jsr166 1.28 throw new IllegalArgumentException(BAD_BOUND);
474 dl 1.1 // Specialize internalNextLong for origin 0
475     long r = mix64(nextSeed());
476     long m = bound - 1;
477     if ((bound & m) == 0L) // power of two
478     r &= m;
479     else { // reject over-represented candidates
480     for (long u = r >>> 1;
481     u + m - (r = u % bound) < 0L;
482     u = mix64(nextSeed()) >>> 1)
483     ;
484     }
485     return r;
486     }
487    
488     /**
489     * Returns a pseudorandom {@code long} value between the specified
490     * origin (inclusive) and the specified bound (exclusive).
491     *
492     * @param origin the least value returned
493     * @param bound the upper bound (exclusive)
494     * @return a pseudorandom {@code long} value between the origin
495 jsr166 1.10 * (inclusive) and the bound (exclusive)
496 dl 1.7 * @throws IllegalArgumentException if {@code origin} is greater than
497 dl 1.1 * or equal to {@code bound}
498     */
499     public long nextLong(long origin, long bound) {
500     if (origin >= bound)
501 jsr166 1.28 throw new IllegalArgumentException(BAD_RANGE);
502 dl 1.1 return internalNextLong(origin, bound);
503     }
504    
505     /**
506 dl 1.7 * Returns a pseudorandom {@code double} value between zero
507     * (inclusive) and one (exclusive).
508 dl 1.1 *
509 dl 1.7 * @return a pseudorandom {@code double} value between zero
510 dl 1.18 * (inclusive) and one (exclusive)
511 dl 1.1 */
512     public double nextDouble() {
513 dl 1.24 return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT;
514 dl 1.1 }
515    
516     /**
517     * Returns a pseudorandom {@code double} value between 0.0
518     * (inclusive) and the specified bound (exclusive).
519     *
520 dl 1.18 * @param bound the upper bound (exclusive). Must be positive.
521 dl 1.7 * @return a pseudorandom {@code double} value between zero
522 jsr166 1.10 * (inclusive) and the bound (exclusive)
523 dl 1.16 * @throws IllegalArgumentException if {@code bound} is not positive
524 dl 1.1 */
525     public double nextDouble(double bound) {
526 dl 1.7 if (!(bound > 0.0))
527 jsr166 1.28 throw new IllegalArgumentException(BAD_BOUND);
528 dl 1.24 double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound;
529 dl 1.1 return (result < bound) ? result : // correct for rounding
530     Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
531     }
532    
533 dl 1.33 /**
534     * Generates a pseudorandom number with the indicated number of
535     * bits. Unlike in superclass @{link Random}, this method is never
536     * internally called or used by any other publicly accessible
537     * method.
538     *
539     * @param bits random bits
540     * @return the next pseudorandom value from this random number
541     * generator's sequence
542     */
543     protected int next(int bits) {
544     return (int)(nextLong() >>> (64 - bits));
545     }
546    
547 dl 1.1 /**
548 dl 1.7 * Returns a pseudorandom {@code double} value between the specified
549 dl 1.1 * origin (inclusive) and bound (exclusive).
550     *
551     * @param origin the least value returned
552 dl 1.18 * @param bound the upper bound (exclusive)
553 dl 1.1 * @return a pseudorandom {@code double} value between the origin
554 jsr166 1.10 * (inclusive) and the bound (exclusive)
555 dl 1.1 * @throws IllegalArgumentException if {@code origin} is greater than
556     * or equal to {@code bound}
557     */
558     public double nextDouble(double origin, double bound) {
559 dl 1.7 if (!(origin < bound))
560 jsr166 1.28 throw new IllegalArgumentException(BAD_RANGE);
561 dl 1.1 return internalNextDouble(origin, bound);
562     }
563    
564 dl 1.11 /**
565     * Returns a pseudorandom {@code boolean} value.
566     *
567     * @return a pseudorandom {@code boolean} value
568     */
569     public boolean nextBoolean() {
570     return mix32(nextSeed()) < 0;
571     }
572    
573 dl 1.1 // stream methods, coded in a way intended to better isolate for
574     // maintenance purposes the small differences across forms.
575    
576     /**
577 dl 1.16 * Returns a stream producing the given {@code streamSize} number
578     * of pseudorandom {@code int} values from this generator and/or
579     * one split from it.
580 dl 1.1 *
581     * @param streamSize the number of values to generate
582     * @return a stream of pseudorandom {@code int} values
583     * @throws IllegalArgumentException if {@code streamSize} is
584 dl 1.7 * less than zero
585 dl 1.1 */
586     public IntStream ints(long streamSize) {
587     if (streamSize < 0L)
588 jsr166 1.28 throw new IllegalArgumentException(BAD_SIZE);
589 dl 1.1 return StreamSupport.intStream
590     (new RandomIntsSpliterator
591     (this, 0L, streamSize, Integer.MAX_VALUE, 0),
592     false);
593     }
594    
595     /**
596     * Returns an effectively unlimited stream of pseudorandom {@code int}
597 dl 1.16 * values from this generator and/or one split from it.
598 dl 1.1 *
599     * @implNote This method is implemented to be equivalent to {@code
600     * ints(Long.MAX_VALUE)}.
601     *
602     * @return a stream of pseudorandom {@code int} values
603     */
604     public IntStream ints() {
605     return StreamSupport.intStream
606     (new RandomIntsSpliterator
607     (this, 0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
608     false);
609     }
610    
611     /**
612 dl 1.16 * Returns a stream producing the given {@code streamSize} number
613 dl 1.18 * of pseudorandom {@code int} values from this generator and/or one split
614     * from it; each value conforms to the given origin (inclusive) and bound
615     * (exclusive).
616 dl 1.1 *
617     * @param streamSize the number of values to generate
618 dl 1.18 * @param randomNumberOrigin the origin (inclusive) of each random value
619     * @param randomNumberBound the bound (exclusive) of each random value
620 dl 1.1 * @return a stream of pseudorandom {@code int} values,
621 dl 1.18 * each with the given origin (inclusive) and bound (exclusive)
622 dl 1.1 * @throws IllegalArgumentException if {@code streamSize} is
623 dl 1.7 * less than zero, or {@code randomNumberOrigin}
624 dl 1.1 * is greater than or equal to {@code randomNumberBound}
625     */
626     public IntStream ints(long streamSize, int randomNumberOrigin,
627     int randomNumberBound) {
628     if (streamSize < 0L)
629 jsr166 1.28 throw new IllegalArgumentException(BAD_SIZE);
630 dl 1.1 if (randomNumberOrigin >= randomNumberBound)
631 jsr166 1.28 throw new IllegalArgumentException(BAD_RANGE);
632 dl 1.1 return StreamSupport.intStream
633     (new RandomIntsSpliterator
634     (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
635     false);
636     }
637    
638     /**
639     * Returns an effectively unlimited stream of pseudorandom {@code
640 dl 1.18 * int} values from this generator and/or one split from it; each value
641     * conforms to the given origin (inclusive) and bound (exclusive).
642 dl 1.1 *
643     * @implNote This method is implemented to be equivalent to {@code
644     * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
645     *
646 dl 1.18 * @param randomNumberOrigin the origin (inclusive) of each random value
647     * @param randomNumberBound the bound (exclusive) of each random value
648 dl 1.1 * @return a stream of pseudorandom {@code int} values,
649 dl 1.18 * each with the given origin (inclusive) and bound (exclusive)
650 dl 1.1 * @throws IllegalArgumentException if {@code randomNumberOrigin}
651     * is greater than or equal to {@code randomNumberBound}
652     */
653     public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
654     if (randomNumberOrigin >= randomNumberBound)
655 jsr166 1.28 throw new IllegalArgumentException(BAD_RANGE);
656 dl 1.1 return StreamSupport.intStream
657     (new RandomIntsSpliterator
658     (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
659     false);
660     }
661    
662     /**
663 dl 1.16 * Returns a stream producing the given {@code streamSize} number
664     * of pseudorandom {@code long} values from this generator and/or
665     * one split from it.
666 dl 1.1 *
667     * @param streamSize the number of values to generate
668 dl 1.7 * @return a stream of pseudorandom {@code long} values
669 dl 1.1 * @throws IllegalArgumentException if {@code streamSize} is
670 dl 1.7 * less than zero
671 dl 1.1 */
672     public LongStream longs(long streamSize) {
673     if (streamSize < 0L)
674 jsr166 1.28 throw new IllegalArgumentException(BAD_SIZE);
675 dl 1.1 return StreamSupport.longStream
676     (new RandomLongsSpliterator
677     (this, 0L, streamSize, Long.MAX_VALUE, 0L),
678     false);
679     }
680    
681     /**
682 dl 1.16 * Returns an effectively unlimited stream of pseudorandom {@code
683     * long} values from this generator and/or one split from it.
684 dl 1.1 *
685     * @implNote This method is implemented to be equivalent to {@code
686     * longs(Long.MAX_VALUE)}.
687     *
688     * @return a stream of pseudorandom {@code long} values
689     */
690     public LongStream longs() {
691     return StreamSupport.longStream
692     (new RandomLongsSpliterator
693     (this, 0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
694     false);
695     }
696    
697     /**
698 dl 1.7 * Returns a stream producing the given {@code streamSize} number of
699 dl 1.18 * pseudorandom {@code long} values from this generator and/or one split
700     * from it; each value conforms to the given origin (inclusive) and bound
701     * (exclusive).
702 dl 1.1 *
703     * @param streamSize the number of values to generate
704 dl 1.18 * @param randomNumberOrigin the origin (inclusive) of each random value
705     * @param randomNumberBound the bound (exclusive) of each random value
706 dl 1.1 * @return a stream of pseudorandom {@code long} values,
707 dl 1.18 * each with the given origin (inclusive) and bound (exclusive)
708 dl 1.1 * @throws IllegalArgumentException if {@code streamSize} is
709 dl 1.7 * less than zero, or {@code randomNumberOrigin}
710 dl 1.1 * is greater than or equal to {@code randomNumberBound}
711     */
712     public LongStream longs(long streamSize, long randomNumberOrigin,
713     long randomNumberBound) {
714     if (streamSize < 0L)
715 jsr166 1.28 throw new IllegalArgumentException(BAD_SIZE);
716 dl 1.1 if (randomNumberOrigin >= randomNumberBound)
717 jsr166 1.28 throw new IllegalArgumentException(BAD_RANGE);
718 dl 1.1 return StreamSupport.longStream
719     (new RandomLongsSpliterator
720     (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
721     false);
722     }
723    
724     /**
725     * Returns an effectively unlimited stream of pseudorandom {@code
726 dl 1.18 * long} values from this generator and/or one split from it; each value
727     * conforms to the given origin (inclusive) and bound (exclusive).
728 dl 1.1 *
729     * @implNote This method is implemented to be equivalent to {@code
730     * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
731     *
732 dl 1.18 * @param randomNumberOrigin the origin (inclusive) of each random value
733     * @param randomNumberBound the bound (exclusive) of each random value
734 dl 1.1 * @return a stream of pseudorandom {@code long} values,
735 dl 1.18 * each with the given origin (inclusive) and bound (exclusive)
736 dl 1.1 * @throws IllegalArgumentException if {@code randomNumberOrigin}
737     * is greater than or equal to {@code randomNumberBound}
738     */
739     public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
740     if (randomNumberOrigin >= randomNumberBound)
741 jsr166 1.28 throw new IllegalArgumentException(BAD_RANGE);
742 dl 1.1 return StreamSupport.longStream
743     (new RandomLongsSpliterator
744     (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
745     false);
746     }
747    
748     /**
749 dl 1.7 * Returns a stream producing the given {@code streamSize} number of
750 dl 1.18 * pseudorandom {@code double} values from this generator and/or one split
751     * from it; each value is between zero (inclusive) and one (exclusive).
752 dl 1.1 *
753     * @param streamSize the number of values to generate
754     * @return a stream of {@code double} values
755     * @throws IllegalArgumentException if {@code streamSize} is
756 dl 1.7 * less than zero
757 dl 1.1 */
758     public DoubleStream doubles(long streamSize) {
759     if (streamSize < 0L)
760 jsr166 1.28 throw new IllegalArgumentException(BAD_SIZE);
761 dl 1.1 return StreamSupport.doubleStream
762     (new RandomDoublesSpliterator
763     (this, 0L, streamSize, Double.MAX_VALUE, 0.0),
764     false);
765     }
766    
767     /**
768     * Returns an effectively unlimited stream of pseudorandom {@code
769 dl 1.18 * double} values from this generator and/or one split from it; each value
770     * is between zero (inclusive) and one (exclusive).
771 dl 1.1 *
772     * @implNote This method is implemented to be equivalent to {@code
773     * doubles(Long.MAX_VALUE)}.
774     *
775     * @return a stream of pseudorandom {@code double} values
776     */
777     public DoubleStream doubles() {
778     return StreamSupport.doubleStream
779     (new RandomDoublesSpliterator
780     (this, 0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
781     false);
782     }
783    
784     /**
785 dl 1.7 * Returns a stream producing the given {@code streamSize} number of
786 dl 1.18 * pseudorandom {@code double} values from this generator and/or one split
787     * from it; each value conforms to the given origin (inclusive) and bound
788     * (exclusive).
789 dl 1.1 *
790     * @param streamSize the number of values to generate
791 dl 1.18 * @param randomNumberOrigin the origin (inclusive) of each random value
792     * @param randomNumberBound the bound (exclusive) of each random value
793 dl 1.1 * @return a stream of pseudorandom {@code double} values,
794 dl 1.18 * each with the given origin (inclusive) and bound (exclusive)
795 dl 1.1 * @throws IllegalArgumentException if {@code streamSize} is
796 dl 1.18 * less than zero
797 dl 1.1 * @throws IllegalArgumentException if {@code randomNumberOrigin}
798     * is greater than or equal to {@code randomNumberBound}
799     */
800     public DoubleStream doubles(long streamSize, double randomNumberOrigin,
801     double randomNumberBound) {
802     if (streamSize < 0L)
803 jsr166 1.28 throw new IllegalArgumentException(BAD_SIZE);
804 dl 1.7 if (!(randomNumberOrigin < randomNumberBound))
805 jsr166 1.28 throw new IllegalArgumentException(BAD_RANGE);
806 dl 1.1 return StreamSupport.doubleStream
807     (new RandomDoublesSpliterator
808     (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
809     false);
810     }
811    
812     /**
813     * Returns an effectively unlimited stream of pseudorandom {@code
814 dl 1.18 * double} values from this generator and/or one split from it; each value
815     * conforms to the given origin (inclusive) and bound (exclusive).
816 dl 1.1 *
817     * @implNote This method is implemented to be equivalent to {@code
818     * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
819     *
820 dl 1.18 * @param randomNumberOrigin the origin (inclusive) of each random value
821     * @param randomNumberBound the bound (exclusive) of each random value
822 dl 1.1 * @return a stream of pseudorandom {@code double} values,
823 dl 1.18 * each with the given origin (inclusive) and bound (exclusive)
824 dl 1.1 * @throws IllegalArgumentException if {@code randomNumberOrigin}
825     * is greater than or equal to {@code randomNumberBound}
826     */
827     public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
828 dl 1.7 if (!(randomNumberOrigin < randomNumberBound))
829 jsr166 1.28 throw new IllegalArgumentException(BAD_RANGE);
830 dl 1.1 return StreamSupport.doubleStream
831     (new RandomDoublesSpliterator
832     (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
833     false);
834     }
835    
836     /**
837     * Spliterator for int streams. We multiplex the four int
838 dl 1.7 * versions into one class by treating a bound less than origin as
839 dl 1.1 * unbounded, and also by treating "infinite" as equivalent to
840     * Long.MAX_VALUE. For splits, it uses the standard divide-by-two
841     * approach. The long and double versions of this class are
842     * identical except for types.
843     */
844 jsr166 1.29 private static final class RandomIntsSpliterator
845     implements Spliterator.OfInt {
846 dl 1.1 final SplittableRandom rng;
847     long index;
848     final long fence;
849     final int origin;
850     final int bound;
851     RandomIntsSpliterator(SplittableRandom rng, long index, long fence,
852     int origin, int bound) {
853     this.rng = rng; this.index = index; this.fence = fence;
854     this.origin = origin; this.bound = bound;
855     }
856    
857     public RandomIntsSpliterator trySplit() {
858     long i = index, m = (i + fence) >>> 1;
859     return (m <= i) ? null :
860     new RandomIntsSpliterator(rng.split(), i, index = m, origin, bound);
861     }
862    
863     public long estimateSize() {
864     return fence - index;
865     }
866    
867     public int characteristics() {
868     return (Spliterator.SIZED | Spliterator.SUBSIZED |
869 dl 1.4 Spliterator.NONNULL | Spliterator.IMMUTABLE);
870 dl 1.1 }
871    
872     public boolean tryAdvance(IntConsumer consumer) {
873     if (consumer == null) throw new NullPointerException();
874     long i = index, f = fence;
875     if (i < f) {
876     consumer.accept(rng.internalNextInt(origin, bound));
877     index = i + 1;
878     return true;
879     }
880     return false;
881     }
882    
883     public void forEachRemaining(IntConsumer consumer) {
884     if (consumer == null) throw new NullPointerException();
885     long i = index, f = fence;
886     if (i < f) {
887     index = f;
888 dl 1.15 SplittableRandom r = rng;
889 dl 1.1 int o = origin, b = bound;
890     do {
891 dl 1.15 consumer.accept(r.internalNextInt(o, b));
892 dl 1.1 } while (++i < f);
893     }
894     }
895     }
896    
897     /**
898     * Spliterator for long streams.
899     */
900 jsr166 1.29 private static final class RandomLongsSpliterator
901     implements Spliterator.OfLong {
902 dl 1.1 final SplittableRandom rng;
903     long index;
904     final long fence;
905     final long origin;
906     final long bound;
907     RandomLongsSpliterator(SplittableRandom rng, long index, long fence,
908     long origin, long bound) {
909     this.rng = rng; this.index = index; this.fence = fence;
910     this.origin = origin; this.bound = bound;
911     }
912    
913     public RandomLongsSpliterator trySplit() {
914     long i = index, m = (i + fence) >>> 1;
915     return (m <= i) ? null :
916     new RandomLongsSpliterator(rng.split(), i, index = m, origin, bound);
917     }
918    
919     public long estimateSize() {
920     return fence - index;
921     }
922    
923     public int characteristics() {
924     return (Spliterator.SIZED | Spliterator.SUBSIZED |
925 dl 1.4 Spliterator.NONNULL | Spliterator.IMMUTABLE);
926 dl 1.1 }
927    
928     public boolean tryAdvance(LongConsumer consumer) {
929     if (consumer == null) throw new NullPointerException();
930     long i = index, f = fence;
931     if (i < f) {
932     consumer.accept(rng.internalNextLong(origin, bound));
933     index = i + 1;
934     return true;
935     }
936     return false;
937     }
938    
939     public void forEachRemaining(LongConsumer consumer) {
940     if (consumer == null) throw new NullPointerException();
941     long i = index, f = fence;
942     if (i < f) {
943     index = f;
944 dl 1.15 SplittableRandom r = rng;
945 dl 1.1 long o = origin, b = bound;
946     do {
947 dl 1.15 consumer.accept(r.internalNextLong(o, b));
948 dl 1.1 } while (++i < f);
949     }
950     }
951    
952     }
953    
954     /**
955     * Spliterator for double streams.
956     */
957 jsr166 1.29 private static final class RandomDoublesSpliterator
958     implements Spliterator.OfDouble {
959 dl 1.1 final SplittableRandom rng;
960     long index;
961     final long fence;
962     final double origin;
963     final double bound;
964     RandomDoublesSpliterator(SplittableRandom rng, long index, long fence,
965     double origin, double bound) {
966     this.rng = rng; this.index = index; this.fence = fence;
967     this.origin = origin; this.bound = bound;
968     }
969    
970     public RandomDoublesSpliterator trySplit() {
971     long i = index, m = (i + fence) >>> 1;
972     return (m <= i) ? null :
973     new RandomDoublesSpliterator(rng.split(), i, index = m, origin, bound);
974     }
975    
976     public long estimateSize() {
977     return fence - index;
978     }
979    
980     public int characteristics() {
981     return (Spliterator.SIZED | Spliterator.SUBSIZED |
982 dl 1.4 Spliterator.NONNULL | Spliterator.IMMUTABLE);
983 dl 1.1 }
984    
985     public boolean tryAdvance(DoubleConsumer consumer) {
986     if (consumer == null) throw new NullPointerException();
987     long i = index, f = fence;
988     if (i < f) {
989     consumer.accept(rng.internalNextDouble(origin, bound));
990     index = i + 1;
991     return true;
992     }
993     return false;
994     }
995    
996     public void forEachRemaining(DoubleConsumer consumer) {
997     if (consumer == null) throw new NullPointerException();
998     long i = index, f = fence;
999     if (i < f) {
1000     index = f;
1001 dl 1.15 SplittableRandom r = rng;
1002 dl 1.1 double o = origin, b = bound;
1003     do {
1004 dl 1.15 consumer.accept(r.internalNextDouble(o, b));
1005 dl 1.1 } while (++i < f);
1006     }
1007     }
1008     }
1009    
1010     }