25 |
|
|
26 |
|
package java.util; |
27 |
|
|
28 |
+ |
import java.security.SecureRandom; |
29 |
|
import java.util.concurrent.atomic.AtomicLong; |
30 |
|
import java.util.Spliterator; |
31 |
|
import java.util.function.IntConsumer; |
52 |
|
* href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> version |
53 |
|
* 3.31.1</a>.) These tests validate only the methods for certain |
54 |
|
* types and ranges, but similar properties are expected to hold, at |
55 |
< |
* least approximately, for others as well. </li> |
55 |
> |
* least approximately, for others as well. The <em>period</em> |
56 |
> |
* (length of any series of generated values before it repeats) is at |
57 |
> |
* least 2<sup>64</sup>. </li> |
58 |
|
* |
59 |
|
* <li> Method {@link #split} constructs and returns a new |
60 |
|
* SplittableRandom instance that shares no mutable state with the |
122 |
|
* this generator as nextSplit, and uses mix64(nextSplit) as its |
123 |
|
* own gamma value. Computations of gammas themselves use a fixed |
124 |
|
* constant as the second argument to the addGammaModGeorge |
125 |
< |
* function, GAMMA_GAMMA, a "genuinely random" number from a |
126 |
< |
* radioactive decay reading (obtained from |
127 |
< |
* http://www.fourmilab.ch/hotbits/) meeting the above range |
128 |
< |
* constraint. Using a fixed constant maintains the invariant that |
126 |
< |
* the value of gamma is the same for every instance that is at |
127 |
< |
* the same split-distance from their common root. (Note: there is |
128 |
< |
* nothing especially magic about obtaining this constant from a |
129 |
< |
* "truly random" physical source rather than just choosing one |
130 |
< |
* arbitrarily; using "hotbits" was merely an aesthetically pleasing |
131 |
< |
* choice. In either case, good statistical behavior of the |
132 |
< |
* algorithm should be, and was, verified by using the DieHarder |
133 |
< |
* test suite.) |
125 |
> |
* function, GAMMA_GAMMA. The value of GAMMA_GAMMA is arbitrary |
126 |
> |
* (except must be at least 13), but because it serves as the base |
127 |
> |
* of split sequences, should be subject to validation of |
128 |
> |
* consequent random number quality metrics. |
129 |
|
* |
130 |
|
* The mix64 bit-mixing function called by nextLong and other |
131 |
|
* methods computes the same value as the "64-bit finalizer" |
151 |
|
* SplittableRandom. Unlike other cases, this split must be |
152 |
|
* performed in a thread-safe manner. We use |
153 |
|
* AtomicLong.compareAndSet as the (typically) most efficient |
154 |
< |
* mechanism. To bootstrap, we start off using System.nanotime(), |
155 |
< |
* and update using another "genuinely random" constant |
154 |
> |
* mechanism. To bootstrap, we start off using a SecureRandom |
155 |
> |
* initial default seed, and update using a fixed |
156 |
|
* DEFAULT_SEED_GAMMA. The default constructor uses GAMMA_GAMMA, |
157 |
|
* not 0, for its splitSeed argument (addGammaModGeorge(0, |
158 |
|
* GAMMA_GAMMA) == GAMMA_GAMMA) to reflect that each is split from |
161 |
|
*/ |
162 |
|
|
163 |
|
/** |
164 |
< |
* The "genuinely random" value for producing new gamma values. |
165 |
< |
* The value is arbitrary, subject to the requirement that it be |
166 |
< |
* greater or equal to 13. |
164 |
> |
* The value for producing new gamma values. Must be greater or |
165 |
> |
* equal to 13. Otherwise, the value is arbitrary subject to |
166 |
> |
* validation of the resulting statistical quality of splits. |
167 |
|
*/ |
168 |
|
private static final long GAMMA_GAMMA = 0xF2281E2DBA6606F3L; |
169 |
|
|
170 |
|
/** |
171 |
< |
* The "genuinely random" seed update value for default constructors. |
172 |
< |
* The value is arbitrary, subject to the requirement that it be |
178 |
< |
* greater or equal to 13. |
171 |
> |
* The seed update value for default constructors. Must be |
172 |
> |
* greater or equal to 13. Otherwise, the value is arbitrary. |
173 |
|
*/ |
174 |
|
private static final long DEFAULT_SEED_GAMMA = 0xBD24B73A95FB84D9L; |
175 |
|
|
176 |
|
/** |
177 |
+ |
* The value 13 with 64bit sign bit set. Used in the signed |
178 |
+ |
* comparison in addGammaModGeorge. |
179 |
+ |
*/ |
180 |
+ |
private static final long BOTTOM13 = 0x800000000000000DL; |
181 |
+ |
|
182 |
+ |
/** |
183 |
|
* The least non-zero value returned by nextDouble(). This value |
184 |
|
* is scaled by a random value of 53 bits to produce a result. |
185 |
|
*/ |
189 |
|
* The next seed for default constructors. |
190 |
|
*/ |
191 |
|
private static final AtomicLong defaultSeedGenerator = |
192 |
< |
new AtomicLong(System.nanoTime()); |
192 |
> |
new AtomicLong(getInitialDefaultSeed()); |
193 |
|
|
194 |
|
/** |
195 |
|
* The seed, updated only via method nextSeed. |
217 |
|
* George < 2^64; thus we need only a conditional, not a loop, |
218 |
|
* to be sure of getting a representable value. |
219 |
|
* |
220 |
< |
* @param s a seed value |
220 |
> |
* Because Java comparison operators are signed, we implement this |
221 |
> |
* by conceptually offsetting seed values downwards by 2^63, so |
222 |
> |
* 0..13 is represented as Long.MIN_VALUE..BOTTOM13. |
223 |
> |
* |
224 |
> |
* @param s a seed value, viewed as a signed long |
225 |
|
* @param g a gamma value, 13 <= g (as unsigned) |
226 |
|
*/ |
227 |
|
private static long addGammaModGeorge(long s, long g) { |
228 |
|
long p = s + g; |
229 |
< |
if (Long.compareUnsigned(p, g) >= 0) |
226 |
< |
return p; |
227 |
< |
long q = p - 13L; |
228 |
< |
return (Long.compareUnsigned(p, 13L) >= 0) ? q : (q + g); |
229 |
> |
return (p >= s) ? p : ((p >= BOTTOM13) ? p : p + g) - 13L; |
230 |
|
} |
231 |
|
|
232 |
|
/** |
265 |
|
do { // ensure gamma >= 13, considered as an unsigned integer |
266 |
|
s = addGammaModGeorge(s, GAMMA_GAMMA); |
267 |
|
g = mix64(s); |
268 |
< |
} while (Long.compareUnsigned(g, 13L) < 0); |
268 |
> |
} while (g >= 0L && g < 13L); |
269 |
|
this.gamma = g; |
270 |
|
this.nextSplit = s; |
271 |
|
} |
290 |
|
return mix64(newSeed); |
291 |
|
} |
292 |
|
|
293 |
+ |
/** |
294 |
+ |
* Returns an initial default seed. |
295 |
+ |
*/ |
296 |
+ |
private static long getInitialDefaultSeed() { |
297 |
+ |
byte[] seedBytes = java.security.SecureRandom.getSeed(8); |
298 |
+ |
long s = (long)(seedBytes[0]) & 0xffL; |
299 |
+ |
for (int i = 1; i < 8; ++i) |
300 |
+ |
s = (s << 8) | ((long)(seedBytes[i]) & 0xffL); |
301 |
+ |
return s; |
302 |
+ |
} |
303 |
+ |
|
304 |
|
/* |
305 |
|
* Internal versions of nextX methods used by streams, as well as |
306 |
|
* the public nextX(origin, bound) methods. These exist mainly to |
415 |
|
/** |
416 |
|
* Creates a new SplittableRandom instance using the specified |
417 |
|
* initial seed. SplittableRandom instances created with the same |
418 |
< |
* seed generate identical sequences of values. |
418 |
> |
* seed in the same program generate identical sequences of values. |
419 |
|
* |
420 |
|
* @param seed the initial seed |
421 |
|
*/ |
565 |
|
* (inclusive) and one (exclusive) |
566 |
|
*/ |
567 |
|
public double nextDouble() { |
568 |
< |
return (nextLong() >>> 11) * DOUBLE_UNIT; |
568 |
> |
return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT; |
569 |
|
} |
570 |
|
|
571 |
|
/** |
581 |
|
public double nextDouble(double bound) { |
582 |
|
if (!(bound > 0.0)) |
583 |
|
throw new IllegalArgumentException("bound must be positive"); |
584 |
< |
double result = nextDouble() * bound; |
584 |
> |
double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound; |
585 |
|
return (result < bound) ? result : // correct for rounding |
586 |
|
Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1); |
587 |
|
} |
603 |
|
return internalNextDouble(origin, bound); |
604 |
|
} |
605 |
|
|
606 |
+ |
/** |
607 |
+ |
* Returns a pseudorandom {@code boolean} value. |
608 |
+ |
* |
609 |
+ |
* @return a pseudorandom {@code boolean} value |
610 |
+ |
*/ |
611 |
+ |
public boolean nextBoolean() { |
612 |
+ |
return mix32(nextSeed()) < 0; |
613 |
+ |
} |
614 |
+ |
|
615 |
|
// stream methods, coded in a way intended to better isolate for |
616 |
|
// maintenance purposes the small differences across forms. |
617 |
|
|
875 |
|
* approach. The long and double versions of this class are |
876 |
|
* identical except for types. |
877 |
|
*/ |
878 |
< |
static class RandomIntsSpliterator implements Spliterator.OfInt { |
878 |
> |
static final class RandomIntsSpliterator implements Spliterator.OfInt { |
879 |
|
final SplittableRandom rng; |
880 |
|
long index; |
881 |
|
final long fence; |
929 |
|
/** |
930 |
|
* Spliterator for long streams. |
931 |
|
*/ |
932 |
< |
static class RandomLongsSpliterator implements Spliterator.OfLong { |
932 |
> |
static final class RandomLongsSpliterator implements Spliterator.OfLong { |
933 |
|
final SplittableRandom rng; |
934 |
|
long index; |
935 |
|
final long fence; |
984 |
|
/** |
985 |
|
* Spliterator for double streams. |
986 |
|
*/ |
987 |
< |
static class RandomDoublesSpliterator implements Spliterator.OfDouble { |
987 |
> |
static final class RandomDoublesSpliterator implements Spliterator.OfDouble { |
988 |
|
final SplittableRandom rng; |
989 |
|
long index; |
990 |
|
final long fence; |