       1 /*
       2  * Copyright (c) 1995, 2021, 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 import java.io.*;
      28 import java.util.concurrent.atomic.AtomicLong;
      29 import java.util.function.DoubleConsumer;
      30 import java.util.function.IntConsumer;
      31 import java.util.function.LongConsumer;
      32 import java.util.stream.DoubleStream;
      33 import java.util.stream.IntStream;
      34 import java.util.stream.LongStream;
      35 import java.util.stream.StreamSupport;
      36
      37 import jdk.internal.misc.Unsafe;
      38
      39 /**
      40  * An instance of this class is used to generate a stream of
      41  * pseudorandom numbers. The class uses a 48-bit seed, which is
      42  * modified using a linear congruential formula. (See Donald E. Knuth,
      43  * <cite>The Art of Computer Programming, Volume 2, Third
      44  * edition: Seminumerical Algorithms</cite>, Section 3.2.1.)
      45  * <p>
      46  * If two instances of {@code Random} are created with the same
      47  * seed, and the same sequence of method calls is made for each, they
      48  * will generate and return identical sequences of numbers. In order to
      49  * guarantee this property, particular algorithms are specified for the
      50  * class {@code Random}. Java implementations must use all the algorithms
      51  * shown here for the class {@code Random}, for the sake of absolute
      52  * portability of Java code. However, subclasses of class {@code Random}
      53  * are permitted to use other algorithms, so long as they adhere to the
      54  * general contracts for all the methods.
      55  * <p>
      56  * The algorithms implemented by class {@code Random} use a
      57  * {@code protected} utility method that on each invocation can supply
      58  * up to 32 pseudorandomly generated bits.
      59  * <p>
      60  * Many applications will find the method {@link Math#random} simpler to use.
      61  *
      62  * <p>Instances of {@code java.util.Random} are threadsafe.
      63  * However, the concurrent use of the same {@code java.util.Random}
      64  * instance across threads may encounter contention and consequent
      65  * poor performance. Consider instead using
      66  * {@link java.util.concurrent.ThreadLocalRandom} in multithreaded
      67  * designs.
      68  *
      69  * <p>Instances of {@code java.util.Random} are not cryptographically
      70  * secure.  Consider instead using {@link java.security.SecureRandom} to
      71  * get a cryptographically secure pseudo-random number generator for use
      72  * by security-sensitive applications.
      73  *
      74  * @author  Frank Yellin
      75  * @since   1.0
      76  */
      77 public class Random implements java.io.Serializable {
      78     /** use serialVersionUID from JDK 1.1 for interoperability */
      79     @java.io.Serial
      80     static final long serialVersionUID = 3905348978240129619L;
      81
      82     /**
      83      * The internal state associated with this pseudorandom number generator.
      84      * (The specs for the methods in this class describe the ongoing
      85      * computation of this value.)
      86      */
      87     private final AtomicLong seed;
      88
      89     private static final long multiplier = 0x5DEECE66DL;
      90     private static final long addend = 0xBL;
      91     private static final long mask = (1L << 48) - 1;
      92
      93     private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53)
      94
      95     // IllegalArgumentException messages
      96     static final String BadBound = "bound must be positive";
      97     static final String BadRange = "bound must be greater than origin";
      98     static final String BadSize  = "size must be non-negative";
      99
     100     /**
     101      * Creates a new random number generator. This constructor sets
     102      * the seed of the random number generator to a value very likely
     103      * to be distinct from any other invocation of this constructor.
     104      */
     105     public Random() {
     106         this(seedUniquifier() ^ System.nanoTime());
     107     }
     108
     109     private static long seedUniquifier() {
     110         // L'Ecuyer, "Tables of Linear Congruential Generators of
     111         // Different Sizes and Good Lattice Structure", 1999
     112         for (;;) {
     113             long current = seedUniquifier.get();
     114             long next = current * 1181783497276652981L;
     115             if (seedUniquifier.compareAndSet(current, next))
     116                 return next;
     117         }
     118     }
     119
     120     private static final AtomicLong seedUniquifier
     121         = new AtomicLong(8682522807148012L);
     122
     123     /**
     124      * Creates a new random number generator using a single {@code long} seed.
     125      * The seed is the initial value of the internal state of the pseudorandom
     126      * number generator which is maintained by method {@link #next}.
     127      *
     128      * <p>The invocation {@code new Random(seed)} is equivalent to:
     129      *  <pre> {@code
     130      * Random rnd = new Random();
     131      * rnd.setSeed(seed);}</pre>
     132      *
     133      * @param seed the initial seed
     134      * @see   #setSeed(long)
     135      */
     136     public Random(long seed) {
     137         if (getClass() == Random.class)
     138             this.seed = new AtomicLong(initialScramble(seed));
     139         else {
     140             // subclass might have overridden setSeed
     141             this.seed = new AtomicLong();
     142             setSeed(seed);
     143         }
     144     }
     145
     146     private static long initialScramble(long seed) {
     147         return (seed ^ multiplier) & mask;
     148     }
     149
     150     /**
     151      * Sets the seed of this random number generator using a single
     152      * {@code long} seed. The general contract of {@code setSeed} is
     153      * that it alters the state of this random number generator object
     154      * so as to be in exactly the same state as if it had just been
     155      * created with the argument {@code seed} as a seed. The method
     156      * {@code setSeed} is implemented by class {@code Random} by
     157      * atomically updating the seed to
     158      *  <pre>{@code (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1)}</pre>
     159      * and clearing the {@code haveNextNextGaussian} flag used by {@link
     160      * #nextGaussian}.
     161      *
     162      * <p>The implementation of {@code setSeed} by class {@code Random}
     163      * happens to use only 48 bits of the given seed. In general, however,
     164      * an overriding method may use all 64 bits of the {@code long}
     165      * argument as a seed value.
     166      *
     167      * @param seed the initial seed
     168      */
     169     public synchronized void setSeed(long seed) {
     170         this.seed.set(initialScramble(seed));
     171         haveNextNextGaussian = false;
     172     }
     173
     174     /**
     175      * Generates the next pseudorandom number. Subclasses should
     176      * override this, as this is used by all other methods.
     177      *
     178      * <p>The general contract of {@code next} is that it returns an
     179      * {@code int} value and if the argument {@code bits} is between
     180      * {@code 1} and {@code 32} (inclusive), then that many low-order
     181      * bits of the returned value will be (approximately) independently
     182      * chosen bit values, each of which is (approximately) equally
     183      * likely to be {@code 0} or {@code 1}. The method {@code next} is
     184      * implemented by class {@code Random} by atomically updating the seed to
     185      *  <pre>{@code (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)}</pre>
     186      * and returning
     187      *  <pre>{@code (int)(seed >>> (48 - bits))}.</pre>
     188      *
     189      * This is a linear congruential pseudorandom number generator, as
     190      * defined by D. H. Lehmer and described by Donald E. Knuth in
     191      * <cite>The Art of Computer Programming, Volume 2, Third edition:
     192      * Seminumerical Algorithms</cite>, section 3.2.1.
     193      *
     194      * @param  bits random bits
     195      * @return the next pseudorandom value from this random number
     196      *         generator's sequence
     197      * @since  1.1
     198      */
     199     protected int next(int bits) {
     200         long oldseed, nextseed;
     201         AtomicLong seed = this.seed;
     202         do {
     203             oldseed = seed.get();
     204             nextseed = (oldseed * multiplier + addend) & mask;
     205         } while (!seed.compareAndSet(oldseed, nextseed));
     206         return (int)(nextseed >>> (48 - bits));
     207     }
     208
     209     /**
     210      * Generates random bytes and places them into a user-supplied
     211      * byte array.  The number of random bytes produced is equal to
     212      * the length of the byte array.
     213      *
     214      * <p>The method {@code nextBytes} is implemented by class {@code Random}
     215      * as if by:
     216      *  <pre> {@code
     217      * public void nextBytes(byte[] bytes) {
     218      *   for (int i = 0; i < bytes.length; )
     219      *     for (int rnd = nextInt(), n = Math.min(bytes.length - i, 4);
     220      *          n-- > 0; rnd >>= 8)
     221      *       bytes[i++] = (byte)rnd;
     222      * }}</pre>
     223      *
     224      * @param  bytes the byte array to fill with random bytes
     225      * @throws NullPointerException if the byte array is null
     226      * @since  1.1
     227      */
     228     public void nextBytes(byte[] bytes) {
     229         for (int i = 0, len = bytes.length; i < len; )
     230             for (int rnd = nextInt(),
     231                      n = Math.min(len - i, Integer.SIZE/Byte.SIZE);
     232                  n-- > 0; rnd >>= Byte.SIZE)
     233                 bytes[i++] = (byte)rnd;
     234     }
     235
     236     /**
     237      * The form of nextLong used by LongStream Spliterators.  If
     238      * origin is greater than bound, acts as unbounded form of
     239      * nextLong, else as bounded form.
     240      *
     241      * @param origin the least value, unless greater than bound
     242      * @param bound the upper bound (exclusive), must not equal origin
     243      * @return a pseudorandom value
     244      */
     245     final long internalNextLong(long origin, long bound) {
     246         long r = nextLong();
     247         if (origin < bound) {
     248             long n = bound - origin, m = n - 1;
     249             if ((n & m) == 0L)  // power of two
     250                 r = (r & m) + origin;
     251             else if (n > 0L) {  // reject over-represented candidates
     252                 for (long u = r >>> 1;            // ensure nonnegative
     253                      u + m - (r = u % n) < 0L;    // rejection check
     254                      u = nextLong() >>> 1) // retry
     255                     ;
     256                 r += origin;
     257             }
     258             else {              // range not representable as long
     259                 while (r < origin || r >= bound)
     260                     r = nextLong();
     261             }
     262         }
     263         return r;
     264     }
     265
     266     /**
     267      * The form of nextInt used by IntStream Spliterators.
     268      * For the unbounded case: uses nextInt().
     269      * For the bounded case with representable range: uses nextInt(int bound)
     270      * For the bounded case with unrepresentable range: uses nextInt()
     271      *
     272      * @param origin the least value, unless greater than bound
     273      * @param bound the upper bound (exclusive), must not equal origin
     274      * @return a pseudorandom value
     275      */
     276     final int internalNextInt(int origin, int bound) {
     277         if (origin < bound) {
     278             int n = bound - origin;
     279             if (n > 0) {
     280                 return nextInt(n) + origin;
     281             }
     282             else {  // range not representable as int
     283                 int r;
     284                 do {
     285                     r = nextInt();
     286                 } while (r < origin || r >= bound);
     287                 return r;
     288             }
     289         }
     290         else {
     291             return nextInt();
     292         }
     293     }
     294
     295     /**
     296      * The form of nextDouble used by DoubleStream Spliterators.
     297      *
     298      * @param origin the least value, unless greater than bound
     299      * @param bound the upper bound (exclusive), must not equal origin
     300      * @return a pseudorandom value
     301      */
     302     final double internalNextDouble(double origin, double bound) {
     303         double r = nextDouble();
     304         if (origin < bound) {
     305             r = r * (bound - origin) + origin;
     306             if (r >= bound) // correct for rounding
     307                 r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
     308         }
     309         return r;
     310     }
     311
     312     /**
     313      * Returns the next pseudorandom, uniformly distributed {@code int}
     314      * value from this random number generator's sequence. The general
     315      * contract of {@code nextInt} is that one {@code int} value is
     316      * pseudorandomly generated and returned. All 2<sup>32</sup> possible
     317      * {@code int} values are produced with (approximately) equal probability.
     318      *
     319      * <p>The method {@code nextInt} is implemented by class {@code Random}
     320      * as if by:
     321      *  <pre> {@code
     322      * public int nextInt() {
     323      *   return next(32);
     324      * }}</pre>
     325      *
     326      * @return the next pseudorandom, uniformly distributed {@code int}
     327      *         value from this random number generator's sequence
     328      */
     329     public int nextInt() {
     330         return next(32);
     331     }
     332
     333     /**
     334      * Returns a pseudorandom, uniformly distributed {@code int} value
     335      * between 0 (inclusive) and the specified value (exclusive), drawn from
     336      * this random number generator's sequence.  The general contract of
     337      * {@code nextInt} is that one {@code int} value in the specified range
     338      * is pseudorandomly generated and returned.  All {@code bound} possible
     339      * {@code int} values are produced with (approximately) equal
     340      * probability.  The method {@code nextInt(int bound)} is implemented by
     341      * class {@code Random} as if by:
     342      *  <pre> {@code
     343      * public int nextInt(int bound) {
     344      *   if (bound <= 0)
     345      *     throw new IllegalArgumentException("bound must be positive");
     346      *
     347      *   if ((bound & -bound) == bound)  // i.e., bound is a power of 2
     348      *     return (int)((bound * (long)next(31)) >> 31);
     349      *
     350      *   int bits, val;
     351      *   do {
     352      *       bits = next(31);
     353      *       val = bits % bound;
     354      *   } while (bits - val + (bound-1) < 0);
     355      *   return val;
     356      * }}</pre>
     357      *
     358      * <p>The hedge "approximately" is used in the foregoing description only
     359      * because the next method is only approximately an unbiased source of
     360      * independently chosen bits.  If it were a perfect source of randomly
     361      * chosen bits, then the algorithm shown would choose {@code int}
     362      * values from the stated range with perfect uniformity.
     363      * <p>
     364      * The algorithm is slightly tricky.  It rejects values that would result
     365      * in an uneven distribution (due to the fact that 2^31 is not divisible
     366      * by n). The probability of a value being rejected depends on n.  The
     367      * worst case is n=2^30+1, for which the probability of a reject is 1/2,
     368      * and the expected number of iterations before the loop terminates is 2.
     369      * <p>
     370      * The algorithm treats the case where n is a power of two specially: it
     371      * returns the correct number of high-order bits from the underlying
     372      * pseudo-random number generator.  In the absence of special treatment,
     373      * the correct number of <i>low-order</i> bits would be returned.  Linear
     374      * congruential pseudo-random number generators such as the one
     375      * implemented by this class are known to have short periods in the
     376      * sequence of values of their low-order bits.  Thus, this special case
     377      * greatly increases the length of the sequence of values returned by
     378      * successive calls to this method if n is a small power of two.
     379      *
     380      * @param bound the upper bound (exclusive).  Must be positive.
     381      * @return the next pseudorandom, uniformly distributed {@code int}
     382      *         value between zero (inclusive) and {@code bound} (exclusive)
     383      *         from this random number generator's sequence
     384      * @throws IllegalArgumentException if bound is not positive
     385      * @since 1.2
     386      */
     387     public int nextInt(int bound) {
     388         if (bound <= 0)
     389             throw new IllegalArgumentException(BadBound);
     390
     391         int r = next(31);
     392         int m = bound - 1;
     393         if ((bound & m) == 0)  // i.e., bound is a power of 2
     394             r = (int)((bound * (long)r) >> 31);
     395         else {
     396             for (int u = r;
     397                  u - (r = u % bound) + m < 0;
     398                  u = next(31))
     399                 ;
     400         }
     401         return r;
     402     }
     403
     404     /**
     405      * Returns the next pseudorandom, uniformly distributed {@code long}
     406      * value from this random number generator's sequence. The general
     407      * contract of {@code nextLong} is that one {@code long} value is
     408      * pseudorandomly generated and returned.
     409      *
     410      * <p>The method {@code nextLong} is implemented by class {@code Random}
     411      * as if by:
     412      *  <pre> {@code
     413      * public long nextLong() {
     414      *   return ((long)next(32) << 32) + next(32);
     415      * }}</pre>
     416      *
     417      * Because class {@code Random} uses a seed with only 48 bits,
     418      * this algorithm will not return all possible {@code long} values.
     419      *
     420      * @return the next pseudorandom, uniformly distributed {@code long}
     421      *         value from this random number generator's sequence
     422      */
     423     public long nextLong() {
     424         // it's okay that the bottom word remains signed.
     425         return ((long)(next(32)) << 32) + next(32);
     426     }
     427
     428     /**
     429      * Returns the next pseudorandom, uniformly distributed
     430      * {@code boolean} value from this random number generator's
     431      * sequence. The general contract of {@code nextBoolean} is that one
     432      * {@code boolean} value is pseudorandomly generated and returned.  The
     433      * values {@code true} and {@code false} are produced with
     434      * (approximately) equal probability.
     435      *
     436      * <p>The method {@code nextBoolean} is implemented by class {@code Random}
     437      * as if by:
     438      *  <pre> {@code
     439      * public boolean nextBoolean() {
     440      *   return next(1) != 0;
     441      * }}</pre>
     442      *
     443      * @return the next pseudorandom, uniformly distributed
     444      *         {@code boolean} value from this random number generator's
     445      *         sequence
     446      * @since 1.2
     447      */
     448     public boolean nextBoolean() {
     449         return next(1) != 0;
     450     }
     451
     452     /**
     453      * Returns the next pseudorandom, uniformly distributed {@code float}
     454      * value between {@code 0.0} and {@code 1.0} from this random
     455      * number generator's sequence.
     456      *
     457      * <p>The general contract of {@code nextFloat} is that one
     458      * {@code float} value, chosen (approximately) uniformly from the
     459      * range {@code 0.0f} (inclusive) to {@code 1.0f} (exclusive), is
     460      * pseudorandomly generated and returned. All 2<sup>24</sup> possible
     461      * {@code float} values of the form <i>m&nbsp;x&nbsp;</i>2<sup>-24</sup>,
     462      * where <i>m</i> is a positive integer less than 2<sup>24</sup>, are
     463      * produced with (approximately) equal probability.
     464      *
     465      * <p>The method {@code nextFloat} is implemented by class {@code Random}
     466      * as if by:
     467      *  <pre> {@code
     468      * public float nextFloat() {
     469      *   return next(24) / ((float)(1 << 24));
     470      * }}</pre>
     471      *
     472      * <p>The hedge "approximately" is used in the foregoing description only
     473      * because the next method is only approximately an unbiased source of
     474      * independently chosen bits. If it were a perfect source of randomly
     475      * chosen bits, then the algorithm shown would choose {@code float}
     476      * values from the stated range with perfect uniformity.<p>
     477      * [In early versions of Java, the result was incorrectly calculated as:
     478      *  <pre> {@code
     479      *   return next(30) / ((float)(1 << 30));}</pre>
     480      * This might seem to be equivalent, if not better, but in fact it
     481      * introduced a slight nonuniformity because of the bias in the rounding
     482      * of floating-point numbers: it was slightly more likely that the
     483      * low-order bit of the significand would be 0 than that it would be 1.]
     484      *
     485      * @return the next pseudorandom, uniformly distributed {@code float}
     486      *         value between {@code 0.0} and {@code 1.0} from this
     487      *         random number generator's sequence
     488      */
     489     public float nextFloat() {
     490         return next(24) / ((float)(1 << 24));
     491     }
     492
     493     /**
     494      * Returns the next pseudorandom, uniformly distributed
     495      * {@code double} value between {@code 0.0} and
     496      * {@code 1.0} from this random number generator's sequence.
     497      *
     498      * <p>The general contract of {@code nextDouble} is that one
     499      * {@code double} value, chosen (approximately) uniformly from the
     500      * range {@code 0.0d} (inclusive) to {@code 1.0d} (exclusive), is
     501      * pseudorandomly generated and returned.
     502      *
     503      * <p>The method {@code nextDouble} is implemented by class {@code Random}
     504      * as if by:
     505      *  <pre> {@code
     506      * public double nextDouble() {
     507      *   return (((long)next(26) << 27) + next(27))
     508      *     / (double)(1L << 53);
     509      * }}</pre>
     510      *
     511      * <p>The hedge "approximately" is used in the foregoing description only
     512      * because the {@code next} method is only approximately an unbiased
     513      * source of independently chosen bits. If it were a perfect source of
     514      * randomly chosen bits, then the algorithm shown would choose
     515      * {@code double} values from the stated range with perfect uniformity.
     516      * <p>[In early versions of Java, the result was incorrectly calculated as:
     517      *  <pre> {@code
     518      *   return (((long)next(27) << 27) + next(27))
     519      *     / (double)(1L << 54);}</pre>
     520      * This might seem to be equivalent, if not better, but in fact it
     521      * introduced a large nonuniformity because of the bias in the rounding
     522      * of floating-point numbers: it was three times as likely that the
     523      * low-order bit of the significand would be 0 than that it would be 1!
     524      * This nonuniformity probably doesn't matter much in practice, but we
     525      * strive for perfection.]
     526      *
     527      * @return the next pseudorandom, uniformly distributed {@code double}
     528      *         value between {@code 0.0} and {@code 1.0} from this
     529      *         random number generator's sequence
     530      * @see Math#random
     531      */
     532     public double nextDouble() {
     533         return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT;
     534     }
     535
     536     private double nextNextGaussian;
     537     private boolean haveNextNextGaussian = false;
     538
     539     /**
     540      * Returns the next pseudorandom, Gaussian ("normally") distributed
     541      * {@code double} value with mean {@code 0.0} and standard
     542      * deviation {@code 1.0} from this random number generator's sequence.
     543      * <p>
     544      * The general contract of {@code nextGaussian} is that one
     545      * {@code double} value, chosen from (approximately) the usual
     546      * normal distribution with mean {@code 0.0} and standard deviation
     547      * {@code 1.0}, is pseudorandomly generated and returned.
     548      *
     549      * <p>The method {@code nextGaussian} is implemented by class
     550      * {@code Random} as if by a threadsafe version of the following:
     551      *  <pre> {@code
     552      * private double nextNextGaussian;
     553      * private boolean haveNextNextGaussian = false;
     554      *
     555      * public double nextGaussian() {
     556      *   if (haveNextNextGaussian) {
     557      *     haveNextNextGaussian = false;
     558      *     return nextNextGaussian;
     559      *   } else {
     560      *     double v1, v2, s;
     561      *     do {
     562      *       v1 = 2 * nextDouble() - 1;   // between -1.0 and 1.0
     563      *       v2 = 2 * nextDouble() - 1;   // between -1.0 and 1.0
     564      *       s = v1 * v1 + v2 * v2;
     565      *     } while (s >= 1 || s == 0);
     566      *     double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
     567      *     nextNextGaussian = v2 * multiplier;
     568      *     haveNextNextGaussian = true;
     569      *     return v1 * multiplier;
     570      *   }
     571      * }}</pre>
     572      * This uses the <i>polar method</i> of G. E. P. Box, M. E. Muller, and
     573      * G. Marsaglia, as described by Donald E. Knuth in <cite>The Art of
     574      * Computer Programming, Volume 2, third edition: Seminumerical Algorithms</cite>,
     575      * section 3.4.1, subsection C, algorithm P. Note that it generates two
     576      * independent values at the cost of only one call to {@code StrictMath.log}
     577      * and one call to {@code StrictMath.sqrt}.
     578      *
     579      * @return the next pseudorandom, Gaussian ("normally") distributed
     580      *         {@code double} value with mean {@code 0.0} and
     581      *         standard deviation {@code 1.0} from this random number
     582      *         generator's sequence
     583      */
     584     public synchronized double nextGaussian() {
     585         // See Knuth, TAOCP, Vol. 2, 3rd edition, Section 3.4.1 Algorithm C.
     586         if (haveNextNextGaussian) {
     587             haveNextNextGaussian = false;
     588             return nextNextGaussian;
     589         } else {
     590             double v1, v2, s;
     591             do {
     592                 v1 = 2 * nextDouble() - 1; // between -1 and 1
     593                 v2 = 2 * nextDouble() - 1; // between -1 and 1
     594                 s = v1 * v1 + v2 * v2;
     595             } while (s >= 1 || s == 0);
     596             double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
     597             nextNextGaussian = v2 * multiplier;
     598             haveNextNextGaussian = true;
     599             return v1 * multiplier;
     600         }
     601     }
     602
     603     // stream methods, coded in a way intended to better isolate for
     604     // maintenance purposes the small differences across forms.
     605
     606     /**
     607      * Returns a stream producing the given {@code streamSize} number of
     608      * pseudorandom {@code int} values.
     609      *
     610      * <p>A pseudorandom {@code int} value is generated as if it's the result of
     611      * calling the method {@link #nextInt()}.
     612      *
     613      * @param streamSize the number of values to generate
     614      * @return a stream of pseudorandom {@code int} values
     615      * @throws IllegalArgumentException if {@code streamSize} is
     616      *         less than zero
     617      * @since 1.8
     618      */
     619     public IntStream ints(long streamSize) {
     620         if (streamSize < 0L)
     621             throw new IllegalArgumentException(BadSize);
     622         return StreamSupport.intStream
     623                 (new RandomIntsSpliterator
     624                          (this, 0L, streamSize, Integer.MAX_VALUE, 0),
     625                  false);
     626     }
     627
     628     /**
     629      * Returns an effectively unlimited stream of pseudorandom {@code int}
     630      * values.
     631      *
     632      * <p>A pseudorandom {@code int} value is generated as if it's the result of
     633      * calling the method {@link #nextInt()}.
     634      *
     635      * @implNote This method is implemented to be equivalent to {@code
     636      * ints(Long.MAX_VALUE)}.
     637      *
     638      * @return a stream of pseudorandom {@code int} values
     639      * @since 1.8
     640      */
     641     public IntStream ints() {
     642         return StreamSupport.intStream
     643                 (new RandomIntsSpliterator
     644                          (this, 0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
     645                  false);
     646     }
     647
     648     /**
     649      * Returns a stream producing the given {@code streamSize} number
     650      * of pseudorandom {@code int} values, each conforming to the given
     651      * origin (inclusive) and bound (exclusive).
     652      *
     653      * <p>A pseudorandom {@code int} value is generated as if it's the result of
     654      * calling the following method with the origin and bound:
     655      * <pre> {@code
     656      * int nextInt(int origin, int bound) {
     657      *   int n = bound - origin;
     658      *   if (n > 0) {
     659      *     return nextInt(n) + origin;
     660      *   }
     661      *   else {  // range not representable as int
     662      *     int r;
     663      *     do {
     664      *       r = nextInt();
     665      *     } while (r < origin || r >= bound);
     666      *     return r;
     667      *   }
     668      * }}</pre>
     669      *
     670      * @param streamSize the number of values to generate
     671      * @param randomNumberOrigin the origin (inclusive) of each random value
     672      * @param randomNumberBound the bound (exclusive) of each random value
     673      * @return a stream of pseudorandom {@code int} values,
     674      *         each with the given origin (inclusive) and bound (exclusive)
     675      * @throws IllegalArgumentException if {@code streamSize} is
     676      *         less than zero, or {@code randomNumberOrigin}
     677      *         is greater than or equal to {@code randomNumberBound}
     678      * @since 1.8
     679      */
     680     public IntStream ints(long streamSize, int randomNumberOrigin,
     681                           int randomNumberBound) {
     682         if (streamSize < 0L)
     683             throw new IllegalArgumentException(BadSize);
     684         if (randomNumberOrigin >= randomNumberBound)
     685             throw new IllegalArgumentException(BadRange);
     686         return StreamSupport.intStream
     687                 (new RandomIntsSpliterator
     688                          (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
     689                  false);
     690     }
     691
     692     /**
     693      * Returns an effectively unlimited stream of pseudorandom {@code
     694      * int} values, each conforming to the given origin (inclusive) and bound
     695      * (exclusive).
     696      *
     697      * <p>A pseudorandom {@code int} value is generated as if it's the result of
     698      * calling the following method with the origin and bound:
     699      * <pre> {@code
     700      * int nextInt(int origin, int bound) {
     701      *   int n = bound - origin;
     702      *   if (n > 0) {
     703      *     return nextInt(n) + origin;
     704      *   }
     705      *   else {  // range not representable as int
     706      *     int r;
     707      *     do {
     708      *       r = nextInt();
     709      *     } while (r < origin || r >= bound);
     710      *     return r;
     711      *   }
     712      * }}</pre>
     713      *
     714      * @implNote This method is implemented to be equivalent to {@code
     715      * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
     716      *
     717      * @param randomNumberOrigin the origin (inclusive) of each random value
     718      * @param randomNumberBound the bound (exclusive) of each random value
     719      * @return a stream of pseudorandom {@code int} values,
     720      *         each with the given origin (inclusive) and bound (exclusive)
     721      * @throws IllegalArgumentException if {@code randomNumberOrigin}
     722      *         is greater than or equal to {@code randomNumberBound}
     723      * @since 1.8
     724      */
     725     public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
     726         if (randomNumberOrigin >= randomNumberBound)
     727             throw new IllegalArgumentException(BadRange);
     728         return StreamSupport.intStream
     729                 (new RandomIntsSpliterator
     730                          (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
     731                  false);
     732     }
     733
     734     /**
     735      * Returns a stream producing the given {@code streamSize} number of
     736      * pseudorandom {@code long} values.
     737      *
     738      * <p>A pseudorandom {@code long} value is generated as if it's the result
     739      * of calling the method {@link #nextLong()}.
     740      *
     741      * @param streamSize the number of values to generate
     742      * @return a stream of pseudorandom {@code long} values
     743      * @throws IllegalArgumentException if {@code streamSize} is
     744      *         less than zero
     745      * @since 1.8
     746      */
     747     public LongStream longs(long streamSize) {
     748         if (streamSize < 0L)
     749             throw new IllegalArgumentException(BadSize);
     750         return StreamSupport.longStream
     751                 (new RandomLongsSpliterator
     752                          (this, 0L, streamSize, Long.MAX_VALUE, 0L),
     753                  false);
     754     }
     755
     756     /**
     757      * Returns an effectively unlimited stream of pseudorandom {@code long}
     758      * values.
     759      *
     760      * <p>A pseudorandom {@code long} value is generated as if it's the result
     761      * of calling the method {@link #nextLong()}.
     762      *
     763      * @implNote This method is implemented to be equivalent to {@code
     764      * longs(Long.MAX_VALUE)}.
     765      *
     766      * @return a stream of pseudorandom {@code long} values
     767      * @since 1.8
     768      */
     769     public LongStream longs() {
     770         return StreamSupport.longStream
     771                 (new RandomLongsSpliterator
     772                          (this, 0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
     773                  false);
     774     }
     775
     776     /**
     777      * Returns a stream producing the given {@code streamSize} number of
     778      * pseudorandom {@code long}, each conforming to the given origin
     779      * (inclusive) and bound (exclusive).
     780      *
     781      * <p>A pseudorandom {@code long} value is generated as if it's the result
     782      * of calling the following method with the origin and bound:
     783      * <pre> {@code
     784      * long nextLong(long origin, long bound) {
     785      *   long r = nextLong();
     786      *   long n = bound - origin, m = n - 1;
     787      *   if ((n & m) == 0L)  // power of two
     788      *     r = (r & m) + origin;
     789      *   else if (n > 0L) {  // reject over-represented candidates
     790      *     for (long u = r >>> 1;            // ensure nonnegative
     791      *          u + m - (r = u % n) < 0L;    // rejection check
     792      *          u = nextLong() >>> 1) // retry
     793      *         ;
     794      *     r += origin;
     795      *   }
     796      *   else {              // range not representable as long
     797      *     while (r < origin || r >= bound)
     798      *       r = nextLong();
     799      *   }
     800      *   return r;
     801      * }}</pre>
     802      *
     803      * @param streamSize the number of values to generate
     804      * @param randomNumberOrigin the origin (inclusive) of each random value
     805      * @param randomNumberBound the bound (exclusive) of each random value
     806      * @return a stream of pseudorandom {@code long} values,
     807      *         each with the given origin (inclusive) and bound (exclusive)
     808      * @throws IllegalArgumentException if {@code streamSize} is
     809      *         less than zero, or {@code randomNumberOrigin}
     810      *         is greater than or equal to {@code randomNumberBound}
     811      * @since 1.8
     812      */
     813     public LongStream longs(long streamSize, long randomNumberOrigin,
     814                             long randomNumberBound) {
     815         if (streamSize < 0L)
     816             throw new IllegalArgumentException(BadSize);
     817         if (randomNumberOrigin >= randomNumberBound)
     818             throw new IllegalArgumentException(BadRange);
     819         return StreamSupport.longStream
     820                 (new RandomLongsSpliterator
     821                          (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
     822                  false);
     823     }
     824
     825     /**
     826      * Returns an effectively unlimited stream of pseudorandom {@code
     827      * long} values, each conforming to the given origin (inclusive) and bound
     828      * (exclusive).
     829      *
     830      * <p>A pseudorandom {@code long} value is generated as if it's the result
     831      * of calling the following method with the origin and bound:
     832      * <pre> {@code
     833      * long nextLong(long origin, long bound) {
     834      *   long r = nextLong();
     835      *   long n = bound - origin, m = n - 1;
     836      *   if ((n & m) == 0L)  // power of two
     837      *     r = (r & m) + origin;
     838      *   else if (n > 0L) {  // reject over-represented candidates
     839      *     for (long u = r >>> 1;            // ensure nonnegative
     840      *          u + m - (r = u % n) < 0L;    // rejection check
     841      *          u = nextLong() >>> 1) // retry
     842      *         ;
     843      *     r += origin;
     844      *   }
     845      *   else {              // range not representable as long
     846      *     while (r < origin || r >= bound)
     847      *       r = nextLong();
     848      *   }
     849      *   return r;
     850      * }}</pre>
     851      *
     852      * @implNote This method is implemented to be equivalent to {@code
     853      * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
     854      *
     855      * @param randomNumberOrigin the origin (inclusive) of each random value
     856      * @param randomNumberBound the bound (exclusive) of each random value
     857      * @return a stream of pseudorandom {@code long} values,
     858      *         each with the given origin (inclusive) and bound (exclusive)
     859      * @throws IllegalArgumentException if {@code randomNumberOrigin}
     860      *         is greater than or equal to {@code randomNumberBound}
     861      * @since 1.8
     862      */
     863     public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
     864         if (randomNumberOrigin >= randomNumberBound)
     865             throw new IllegalArgumentException(BadRange);
     866         return StreamSupport.longStream
     867                 (new RandomLongsSpliterator
     868                          (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
     869                  false);
     870     }
     871
     872     /**
     873      * Returns a stream producing the given {@code streamSize} number of
     874      * pseudorandom {@code double} values, each between zero
     875      * (inclusive) and one (exclusive).
     876      *
     877      * <p>A pseudorandom {@code double} value is generated as if it's the result
     878      * of calling the method {@link #nextDouble()}.
     879      *
     880      * @param streamSize the number of values to generate
     881      * @return a stream of {@code double} values
     882      * @throws IllegalArgumentException if {@code streamSize} is
     883      *         less than zero
     884      * @since 1.8
     885      */
     886     public DoubleStream doubles(long streamSize) {
     887         if (streamSize < 0L)
     888             throw new IllegalArgumentException(BadSize);
     889         return StreamSupport.doubleStream
     890                 (new RandomDoublesSpliterator
     891                          (this, 0L, streamSize, Double.MAX_VALUE, 0.0),
     892                  false);
     893     }
     894
     895     /**
     896      * Returns an effectively unlimited stream of pseudorandom {@code
     897      * double} values, each between zero (inclusive) and one
     898      * (exclusive).
     899      *
     900      * <p>A pseudorandom {@code double} value is generated as if it's the result
     901      * of calling the method {@link #nextDouble()}.
     902      *
     903      * @implNote This method is implemented to be equivalent to {@code
     904      * doubles(Long.MAX_VALUE)}.
     905      *
     906      * @return a stream of pseudorandom {@code double} values
     907      * @since 1.8
     908      */
     909     public DoubleStream doubles() {
     910         return StreamSupport.doubleStream
     911                 (new RandomDoublesSpliterator
     912                          (this, 0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
     913                  false);
     914     }
     915
     916     /**
     917      * Returns a stream producing the given {@code streamSize} number of
     918      * pseudorandom {@code double} values, each conforming to the given origin
     919      * (inclusive) and bound (exclusive).
     920      *
     921      * <p>A pseudorandom {@code double} value is generated as if it's the result
     922      * of calling the following method with the origin and bound:
     923      * <pre> {@code
     924      * double nextDouble(double origin, double bound) {
     925      *   double r = nextDouble();
     926      *   r = r * (bound - origin) + origin;
     927      *   if (r >= bound) // correct for rounding
     928      *     r = Math.nextDown(bound);
     929      *   return r;
     930      * }}</pre>
     931      *
     932      * @param streamSize the number of values to generate
     933      * @param randomNumberOrigin the origin (inclusive) of each random value
     934      * @param randomNumberBound the bound (exclusive) of each random value
     935      * @return a stream of pseudorandom {@code double} values,
     936      *         each with the given origin (inclusive) and bound (exclusive)
     937      * @throws IllegalArgumentException if {@code streamSize} is
     938      *         less than zero
     939      * @throws IllegalArgumentException if {@code randomNumberOrigin}
     940      *         is greater than or equal to {@code randomNumberBound}
     941      * @since 1.8
     942      */
     943     public DoubleStream doubles(long streamSize, double randomNumberOrigin,
     944                                 double randomNumberBound) {
     945         if (streamSize < 0L)
     946             throw new IllegalArgumentException(BadSize);
     947         if (!(randomNumberOrigin < randomNumberBound))
     948             throw new IllegalArgumentException(BadRange);
     949         return StreamSupport.doubleStream
     950                 (new RandomDoublesSpliterator
     951                          (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
     952                  false);
     953     }
     954
     955     /**
     956      * Returns an effectively unlimited stream of pseudorandom {@code
     957      * double} values, each conforming to the given origin (inclusive) and bound
     958      * (exclusive).
     959      *
     960      * <p>A pseudorandom {@code double} value is generated as if it's the result
     961      * of calling the following method with the origin and bound:
     962      * <pre> {@code
     963      * double nextDouble(double origin, double bound) {
     964      *   double r = nextDouble();
     965      *   r = r * (bound - origin) + origin;
     966      *   if (r >= bound) // correct for rounding
     967      *     r = Math.nextDown(bound);
     968      *   return r;
     969      * }}</pre>
     970      *
     971      * @implNote This method is implemented to be equivalent to {@code
     972      * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
     973      *
     974      * @param randomNumberOrigin the origin (inclusive) of each random value
     975      * @param randomNumberBound the bound (exclusive) of each random value
     976      * @return a stream of pseudorandom {@code double} values,
     977      *         each with the given origin (inclusive) and bound (exclusive)
     978      * @throws IllegalArgumentException if {@code randomNumberOrigin}
     979      *         is greater than or equal to {@code randomNumberBound}
     980      * @since 1.8
     981      */
     982     public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
     983         if (!(randomNumberOrigin < randomNumberBound))
     984             throw new IllegalArgumentException(BadRange);
     985         return StreamSupport.doubleStream
     986                 (new RandomDoublesSpliterator
     987                          (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
     988                  false);
     989     }
     990
     991     /**
     992      * Spliterator for int streams.  We multiplex the four int
     993      * versions into one class by treating a bound less than origin as
     994      * unbounded, and also by treating "infinite" as equivalent to
     995      * Long.MAX_VALUE. For splits, it uses the standard divide-by-two
     996      * approach. The long and double versions of this class are
     997      * identical except for types.
     998      */
     999     static final class RandomIntsSpliterator implements Spliterator.OfInt {
    1000         final Random rng;
    1001         long index;
    1002         final long fence;
    1003         final int origin;
    1004         final int bound;
    1005         RandomIntsSpliterator(Random rng, long index, long fence,
    1006                               int origin, int bound) {
    1007             this.rng = rng; this.index = index; this.fence = fence;
    1008             this.origin = origin; this.bound = bound;
    1009         }
    1010
    1011         public RandomIntsSpliterator trySplit() {
    1012             long i = index, m = (i + fence) >>> 1;
    1013             return (m <= i) ? null :
    1014                    new RandomIntsSpliterator(rng, i, index = m, origin, bound);
    1015         }
    1016
    1017         public long estimateSize() {
    1018             return fence - index;
    1019         }
    1020
    1021         public int characteristics() {
    1022             return (Spliterator.SIZED | Spliterator.SUBSIZED |
    1023                     Spliterator.NONNULL | Spliterator.IMMUTABLE);
    1024         }
    1025
    1026         public boolean tryAdvance(IntConsumer consumer) {
    1027             if (consumer == null) throw new NullPointerException();
    1028             long i = index, f = fence;
    1029             if (i < f) {
    1030                 consumer.accept(rng.internalNextInt(origin, bound));
    1031                 index = i + 1;
    1032                 return true;
    1033             }
    1034             return false;
    1035         }
    1036
    1037         public void forEachRemaining(IntConsumer consumer) {
    1038             if (consumer == null) throw new NullPointerException();
    1039             long i = index, f = fence;
    1040             if (i < f) {
    1041                 index = f;
    1042                 Random r = rng;
    1043                 int o = origin, b = bound;
    1044                 do {
    1045                     consumer.accept(r.internalNextInt(o, b));
    1046                 } while (++i < f);
    1047             }
    1048         }
    1049     }
    1050
    1051     /**
    1052      * Spliterator for long streams.
    1053      */
    1054     static final class RandomLongsSpliterator implements Spliterator.OfLong {
    1055         final Random rng;
    1056         long index;
    1057         final long fence;
    1058         final long origin;
    1059         final long bound;
    1060         RandomLongsSpliterator(Random rng, long index, long fence,
    1061                                long origin, long bound) {
    1062             this.rng = rng; this.index = index; this.fence = fence;
    1063             this.origin = origin; this.bound = bound;
    1064         }
    1065
    1066         public RandomLongsSpliterator trySplit() {
    1067             long i = index, m = (i + fence) >>> 1;
    1068             return (m <= i) ? null :
    1069                    new RandomLongsSpliterator(rng, i, index = m, origin, bound);
    1070         }
    1071
    1072         public long estimateSize() {
    1073             return fence - index;
    1074         }
    1075
    1076         public int characteristics() {
    1077             return (Spliterator.SIZED | Spliterator.SUBSIZED |
    1078                     Spliterator.NONNULL | Spliterator.IMMUTABLE);
    1079         }
    1080
    1081         public boolean tryAdvance(LongConsumer consumer) {
    1082             if (consumer == null) throw new NullPointerException();
    1083             long i = index, f = fence;
    1084             if (i < f) {
    1085                 consumer.accept(rng.internalNextLong(origin, bound));
    1086                 index = i + 1;
    1087                 return true;
    1088             }
    1089             return false;
    1090         }
    1091
    1092         public void forEachRemaining(LongConsumer consumer) {
    1093             if (consumer == null) throw new NullPointerException();
    1094             long i = index, f = fence;
    1095             if (i < f) {
    1096                 index = f;
    1097                 Random r = rng;
    1098                 long o = origin, b = bound;
    1099                 do {
    1100                     consumer.accept(r.internalNextLong(o, b));
    1101                 } while (++i < f);
    1102             }
    1103         }
    1104
    1105     }
    1106
    1107     /**
    1108      * Spliterator for double streams.
    1109      */
    1110     static final class RandomDoublesSpliterator implements Spliterator.OfDouble {
    1111         final Random rng;
    1112         long index;
    1113         final long fence;
    1114         final double origin;
    1115         final double bound;
    1116         RandomDoublesSpliterator(Random rng, long index, long fence,
    1117                                  double origin, double bound) {
    1118             this.rng = rng; this.index = index; this.fence = fence;
    1119             this.origin = origin; this.bound = bound;
    1120         }
    1121
    1122         public RandomDoublesSpliterator trySplit() {
    1123             long i = index, m = (i + fence) >>> 1;
    1124             return (m <= i) ? null :
    1125                    new RandomDoublesSpliterator(rng, i, index = m, origin, bound);
    1126         }
    1127
    1128         public long estimateSize() {
    1129             return fence - index;
    1130         }
    1131
    1132         public int characteristics() {
    1133             return (Spliterator.SIZED | Spliterator.SUBSIZED |
    1134                     Spliterator.NONNULL | Spliterator.IMMUTABLE);
    1135         }
    1136
    1137         public boolean tryAdvance(DoubleConsumer consumer) {
    1138             if (consumer == null) throw new NullPointerException();
    1139             long i = index, f = fence;
    1140             if (i < f) {
    1141                 consumer.accept(rng.internalNextDouble(origin, bound));
    1142                 index = i + 1;
    1143                 return true;
    1144             }
    1145             return false;
    1146         }
    1147
    1148         public void forEachRemaining(DoubleConsumer consumer) {
    1149             if (consumer == null) throw new NullPointerException();
    1150             long i = index, f = fence;
    1151             if (i < f) {
    1152                 index = f;
    1153                 Random r = rng;
    1154                 double o = origin, b = bound;
    1155                 do {
    1156                     consumer.accept(r.internalNextDouble(o, b));
    1157                 } while (++i < f);
    1158             }
    1159         }
    1160     }
    1161
    1162     /**
    1163      * Serializable fields for Random.
    1164      *
    1165      * @serialField    seed long
    1166      *              seed for random computations
    1167      * @serialField    nextNextGaussian double
    1168      *              next Gaussian to be returned
    1169      * @serialField      haveNextNextGaussian boolean
    1170      *              nextNextGaussian is valid
    1171      */
    1172     @java.io.Serial
    1173     private static final ObjectStreamField[] serialPersistentFields = {
    1174         new ObjectStreamField("seed", Long.TYPE),
    1175         new ObjectStreamField("nextNextGaussian", Double.TYPE),
    1176         new ObjectStreamField("haveNextNextGaussian", Boolean.TYPE)
    1177     };
    1178
    1179     /**
    1180      * Reconstitute the {@code Random} instance from a stream (that is,
    1181      * deserialize it).
    1182      *
    1183      * @param  s the {@code ObjectInputStream} from which data is read
    1184      * @throws IOException if an I/O error occurs
    1185      * @throws ClassNotFoundException if a serialized class cannot be loaded
    1186      */
    1187     @java.io.Serial
    1188     private void readObject(java.io.ObjectInputStream s)
    1189         throws java.io.IOException, ClassNotFoundException {
    1190
    1191         ObjectInputStream.GetField fields = s.readFields();
    1192
    1193         // The seed is read in as {@code long} for
    1194         // historical reasons, but it is converted to an AtomicLong.
    1195         long seedVal = fields.get("seed", -1L);
    1196         if (seedVal < 0)
    1197           throw new java.io.StreamCorruptedException(
    1198                               "Random: invalid seed");
    1199         resetSeed(seedVal);
    1200         nextNextGaussian = fields.get("nextNextGaussian", 0.0);
    1201         haveNextNextGaussian = fields.get("haveNextNextGaussian", false);
    1202     }
    1203
    1204     /**
    1205      * Save the {@code Random} instance to a stream.
    1206      *
    1207      * @param  s the {@code ObjectOutputStream} to which data is written
    1208      * @throws IOException if an I/O error occurs
    1209      */
    1210     @java.io.Serial
    1211     private synchronized void writeObject(ObjectOutputStream s)
    1212         throws IOException {
    1213
    1214         // set the values of the Serializable fields
    1215         ObjectOutputStream.PutField fields = s.putFields();
    1216
    1217         // The seed is serialized as a long for historical reasons.
    1218         fields.put("seed", seed.get());
    1219         fields.put("nextNextGaussian", nextNextGaussian);
    1220         fields.put("haveNextNextGaussian", haveNextNextGaussian);
    1221
    1222         // save them
    1223         s.writeFields();
    1224     }
    1225
    1226     // Support for resetting seed while deserializing
    1227     private static final Unsafe unsafe = Unsafe.getUnsafe();
    1228     private static final long seedOffset;
    1229     static {
    1230         try {
    1231             seedOffset = unsafe.objectFieldOffset
    1232                 (Random.class.getDeclaredField("seed"));
    1233         } catch (Exception ex) { throw new Error(ex); }
    1234     }
    1235     private void resetSeed(long seedVal) {
    1236         unsafe.putReferenceVolatile(this, seedOffset, new AtomicLong(seedVal));
    1237     }
    1238 }