51 |
|
* href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> version |
52 |
|
* 3.31.1</a>.) These tests validate only the methods for certain |
53 |
|
* types and ranges, but similar properties are expected to hold, at |
54 |
< |
* least approximately, for others as well. </li> |
54 |
> |
* least approximately, for others as well. The <em>period</em> |
55 |
> |
* (length of any series of generated values before it repeats) is at |
56 |
> |
* least 2<sup>64</sup>. </li> |
57 |
|
* |
58 |
|
* <li> Method {@link #split} constructs and returns a new |
59 |
|
* SplittableRandom instance that shares no mutable state with the |
158 |
|
* SplittableRandom. Unlike other cases, this split must be |
159 |
|
* performed in a thread-safe manner. We use |
160 |
|
* AtomicLong.compareAndSet as the (typically) most efficient |
161 |
< |
* mechanism. To bootstrap, we start off using System.nanotime(), |
162 |
< |
* and update using another "genuinely random" constant |
163 |
< |
* DEFAULT_SEED_GAMMA. The default constructor uses GAMMA_GAMMA, |
164 |
< |
* not 0, for its splitSeed argument (addGammaModGeorge(0, |
165 |
< |
* GAMMA_GAMMA) == GAMMA_GAMMA) to reflect that each is split from |
166 |
< |
* this root generator, even though the root is not explicitly |
167 |
< |
* represented as a SplittableRandom. |
161 |
> |
* mechanism. To bootstrap, we start off using a function of the |
162 |
> |
* current System time as seed, and update using another |
163 |
> |
* "genuinely random" constant DEFAULT_SEED_GAMMA. The default |
164 |
> |
* constructor uses GAMMA_GAMMA, not 0, for its splitSeed argument |
165 |
> |
* (addGammaModGeorge(0, GAMMA_GAMMA) == GAMMA_GAMMA) to reflect |
166 |
> |
* that each is split from this root generator, even though the |
167 |
> |
* root is not explicitly represented as a SplittableRandom. When |
168 |
> |
* establishing the initial seed, we use both |
169 |
> |
* System.currentTimeMillis and System.nanoTime(), to avoid |
170 |
> |
* regularities that may occur if using either alone. |
171 |
|
*/ |
172 |
|
|
173 |
|
/** |
185 |
|
private static final long DEFAULT_SEED_GAMMA = 0xBD24B73A95FB84D9L; |
186 |
|
|
187 |
|
/** |
188 |
+ |
* The value 13 with 64bit sign bit set. Used in the signed |
189 |
+ |
* comparison in addGammaModGeorge. |
190 |
+ |
*/ |
191 |
+ |
private static final long BOTTOM13 = 0x800000000000000DL; |
192 |
+ |
|
193 |
+ |
/** |
194 |
|
* The least non-zero value returned by nextDouble(). This value |
195 |
|
* is scaled by a random value of 53 bits to produce a result. |
196 |
|
*/ |
200 |
|
* The next seed for default constructors. |
201 |
|
*/ |
202 |
|
private static final AtomicLong defaultSeedGenerator = |
203 |
< |
new AtomicLong(System.nanoTime()); |
203 |
> |
new AtomicLong(mix64(System.currentTimeMillis()) ^ |
204 |
> |
mix64(System.nanoTime())); |
205 |
|
|
206 |
|
/** |
207 |
|
* The seed, updated only via method nextSeed. |
229 |
|
* George < 2^64; thus we need only a conditional, not a loop, |
230 |
|
* to be sure of getting a representable value. |
231 |
|
* |
232 |
< |
* @param s a seed value |
232 |
> |
* Because Java comparison operators are signed, we implement this |
233 |
> |
* by conceptually offsetting seed values downwards by 2^63, so |
234 |
> |
* 0..13 is represented as Long.MIN_VALUE..BOTTOM13. |
235 |
> |
* |
236 |
> |
* @param s a seed value, viewed as a signed long |
237 |
|
* @param g a gamma value, 13 <= g (as unsigned) |
238 |
|
*/ |
239 |
|
private static long addGammaModGeorge(long s, long g) { |
240 |
|
long p = s + g; |
241 |
< |
if (Long.compareUnsigned(p, g) >= 0) |
226 |
< |
return p; |
227 |
< |
long q = p - 13L; |
228 |
< |
return (Long.compareUnsigned(p, 13L) >= 0) ? q : (q + g); |
241 |
> |
return (p >= s) ? p : ((p >= BOTTOM13) ? p : p + g) - 13L; |
242 |
|
} |
243 |
|
|
244 |
|
/** |
277 |
|
do { // ensure gamma >= 13, considered as an unsigned integer |
278 |
|
s = addGammaModGeorge(s, GAMMA_GAMMA); |
279 |
|
g = mix64(s); |
280 |
< |
} while (Long.compareUnsigned(g, 13L) < 0); |
280 |
> |
} while (g >= 0L && g < 13L); |
281 |
|
this.gamma = g; |
282 |
|
this.nextSplit = s; |
283 |
|
} |
416 |
|
/** |
417 |
|
* Creates a new SplittableRandom instance using the specified |
418 |
|
* initial seed. SplittableRandom instances created with the same |
419 |
< |
* seed generate identical sequences of values. |
419 |
> |
* seed in the same program generate identical sequences of values. |
420 |
|
* |
421 |
|
* @param seed the initial seed |
422 |
|
*/ |
566 |
|
* (inclusive) and one (exclusive) |
567 |
|
*/ |
568 |
|
public double nextDouble() { |
569 |
< |
return (nextLong() >>> 11) * DOUBLE_UNIT; |
569 |
> |
return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT; |
570 |
|
} |
571 |
|
|
572 |
|
/** |
582 |
|
public double nextDouble(double bound) { |
583 |
|
if (!(bound > 0.0)) |
584 |
|
throw new IllegalArgumentException("bound must be positive"); |
585 |
< |
double result = nextDouble() * bound; |
585 |
> |
double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound; |
586 |
|
return (result < bound) ? result : // correct for rounding |
587 |
|
Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1); |
588 |
|
} |
604 |
|
return internalNextDouble(origin, bound); |
605 |
|
} |
606 |
|
|
607 |
+ |
/** |
608 |
+ |
* Returns a pseudorandom {@code boolean} value. |
609 |
+ |
* |
610 |
+ |
* @return a pseudorandom {@code boolean} value |
611 |
+ |
*/ |
612 |
+ |
public boolean nextBoolean() { |
613 |
+ |
return mix32(nextSeed()) < 0; |
614 |
+ |
} |
615 |
+ |
|
616 |
|
// stream methods, coded in a way intended to better isolate for |
617 |
|
// maintenance purposes the small differences across forms. |
618 |
|
|
876 |
|
* approach. The long and double versions of this class are |
877 |
|
* identical except for types. |
878 |
|
*/ |
879 |
< |
static class RandomIntsSpliterator implements Spliterator.OfInt { |
879 |
> |
static final class RandomIntsSpliterator implements Spliterator.OfInt { |
880 |
|
final SplittableRandom rng; |
881 |
|
long index; |
882 |
|
final long fence; |
930 |
|
/** |
931 |
|
* Spliterator for long streams. |
932 |
|
*/ |
933 |
< |
static class RandomLongsSpliterator implements Spliterator.OfLong { |
933 |
> |
static final class RandomLongsSpliterator implements Spliterator.OfLong { |
934 |
|
final SplittableRandom rng; |
935 |
|
long index; |
936 |
|
final long fence; |
985 |
|
/** |
986 |
|
* Spliterator for double streams. |
987 |
|
*/ |
988 |
< |
static class RandomDoublesSpliterator implements Spliterator.OfDouble { |
988 |
> |
static final class RandomDoublesSpliterator implements Spliterator.OfDouble { |
989 |
|
final SplittableRandom rng; |
990 |
|
long index; |
991 |
|
final long fence; |