/*
* Copyright ( c ) 1995 , 2022 , Oracle and / or its affiliates . All rights reserved .
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* This code is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 only , as
* published by the Free Software Foundation . Oracle designates this
* particular file as subject to the " Classpath " exception as provided
* by Oracle in the LICENSE file that accompanied this code .
*
* This code is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
*/
package java.util;
import java.io.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.random.RandomGenerator;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import jdk.internal.util.random.RandomSupport.*;
import static jdk.internal.util.random.RandomSupport.*;
import jdk.internal.misc.Unsafe;
/**
* An instance of this class is used to generate a stream of
* pseudorandom numbers ; its period is only 2 < sup > 48 < / sup > .
* The class uses a 48 - bit seed , which is
* modified using a linear congruential formula . ( See Donald E . Knuth ,
* < cite > The Art of Computer Programming , Volume 2 , Third
* edition : Seminumerical Algorithms < / cite > , Section 3 . 2 . 1 . )
* < p >
* If two instances of { @ code Random } are created with the same
* seed , and the same sequence of method calls is made for each , they
* will generate and return identical sequences of numbers . In order to
* guarantee this property , particular algorithms are specified for the
* class { @ code Random } . Java implementations must use all the algorithms
* shown here for the class { @ code Random } , for the sake of absolute
* portability of Java code . However , subclasses of class { @ code Random }
* are permitted to use other algorithms , so long as they adhere to the
* general contracts for all the methods .
* < p >
* The algorithms implemented by class { @ code Random } use a
* { @ code protected } utility method that on each invocation can supply
* up to 32 pseudorandomly generated bits .
* < p >
* Many applications will find the method { @ link Math # random } simpler to use .
*
* < p > Instances of { @ code java . util . Random } are threadsafe .
* However , the concurrent use of the same { @ code java . util . Random }
* instance across threads may encounter contention and consequent
* poor performance . Consider instead using
* { @ link java . util . concurrent . ThreadLocalRandom } in multithreaded
* designs .
*
* < p > Instances of { @ code java . util . Random } are not cryptographically
* secure . Consider instead using { @ link java . security . SecureRandom } to
* get a cryptographically secure pseudo - random number generator for use
* by security - sensitive applications .
*
* @ author Frank Yellin
* @ since 1 . 0
*/
@RandomGeneratorProperties(
name = "Random" ,
i = 48 , j = 0 , k = 0 ,
equidistribution = 0
)
public class Random implements RandomGenerator, java.io.Serializable {
/**
* Class used to wrap a { @ link java . util . random . RandomGenerator } to
* { @ link java . util . Random } .
*/
@SuppressWarnings("serial" )
private static final class RandomWrapper extends Random implements RandomGenerator {
private final RandomGenerator generator;
//randomToWrap must never be null
private RandomWrapper(RandomGenerator randomToWrap) {
super (null );
this .generator = randomToWrap;
}
/**
* Throws { @ code NotSerializableException } .
*
* @ param s the object input stream
* @ throws NotSerializableException always
*/
@Serial
private void readObject(ObjectInputStream s) throws NotSerializableException {
throw new NotSerializableException("not serializable" );
}
/**
* Throws { @ code NotSerializableException } .
*
* @ param s the object output stream
* @ throws NotSerializableException always
*/
@Serial
private void writeObject(ObjectOutputStream s) throws NotSerializableException {
throw new NotSerializableException("not serializable" );
}
/**
* setSeed does not exist in { @ link java . util . random . RandomGenerator } so can ' t
* use it .
*/
@Override
public void setSeed(long seed) {
throw new UnsupportedOperationException();
}
@Override
public boolean isDeprecated() {
return generator.isDeprecated();
}
@Override
public void nextBytes(byte [] bytes) {
this .generator.nextBytes(bytes);
}
@Override
public int nextInt() {
return this .generator.nextInt();
}
@Override
public int nextInt(int bound) {
return this .generator.nextInt(bound);
}
@Override
public int nextInt(int origin, int bound) {
return generator.nextInt(origin, bound);
}
@Override
public long nextLong() {
return this .generator.nextLong();
}
@Override
public long nextLong(long bound) {
return generator.nextLong(bound);
}
@Override
public long nextLong(long origin, long bound) {
return generator.nextLong(origin, bound);
}
@Override
public boolean nextBoolean() {
return this .generator.nextBoolean();
}
@Override
public float nextFloat() {
return this .generator.nextFloat();
}
@Override
public float nextFloat(float bound) {
return generator.nextFloat(bound);
}
@Override
public float nextFloat(float origin, float bound) {
return generator.nextFloat(origin, bound);
}
@Override
public double nextDouble() {
return this .generator.nextDouble();
}
@Override
public double nextDouble(double bound) {
return generator.nextDouble(bound);
}
@Override
public double nextDouble(double origin, double bound) {
return generator.nextDouble(origin, bound);
}
@Override
public double nextExponential() {
return generator.nextExponential();
}
@Override
public double nextGaussian() {
return this .generator.nextGaussian();
}
@Override
public double nextGaussian(double mean, double stddev) {
return generator.nextGaussian(mean, stddev);
}
@Override
public IntStream ints(long streamSize) {
return this .generator.ints(streamSize);
}
@Override
public IntStream ints() {
return this .generator.ints();
}
@Override
public IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound) {
return this .generator.ints(streamSize, randomNumberOrigin, randomNumberBound);
}
@Override
public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
return this .generator.ints(randomNumberOrigin, randomNumberBound);
}
@Override
public LongStream longs(long streamSize) {
return this .generator.longs(streamSize);
}
@Override
public LongStream longs() {
return this .generator.longs();
}
@Override
public LongStream longs(long streamSize, long randomNumberOrigin, long randomNumberBound) {
return this .generator.longs(streamSize, randomNumberOrigin, randomNumberBound);
}
@Override
public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
return this .generator.longs(randomNumberOrigin, randomNumberBound);
}
@Override
public DoubleStream doubles(long streamSize) {
return this .generator.doubles(streamSize);
}
@Override
public DoubleStream doubles() {
return this .generator.doubles();
}
@Override
public DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) {
return this .generator.doubles(streamSize, randomNumberOrigin, randomNumberBound);
}
@Override
public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
return this .generator.doubles(randomNumberOrigin, randomNumberBound);
}
//This method should never be reached unless done by reflection so we should throw when tried
@Override
protected int next(int bits) {
throw new UnsupportedOperationException();
}
@Override
public String toString() {
return "RandomWrapper[" + generator + "]" ;
}
}
/** use serialVersionUID from JDK 1.1 for interoperability */
@java.io.Serial
static final long serialVersionUID = 3905348978240129619 L;
/**
* The internal state associated with this pseudorandom number generator .
* ( The specs for the methods in this class describe the ongoing
* computation of this value . )
*/
private final AtomicLong seed;
private static final long multiplier = 0 x5DEECE66DL;
private static final long addend = 0 xBL;
private static final long mask = (1 L << 48 ) - 1 ;
private static final double DOUBLE_UNIT = 0 x1.0 p-53 ; // 1.0 / (1L << Double.PRECISION)
private static final float FLOAT_UNIT = 0 x1.0 p-24 f; // 1.0f / (1 << Float.PRECISION)
/**
* Creates a new random number generator . This constructor sets
* the seed of the random number generator to a value very likely
* to be distinct from any other invocation of this constructor .
*/
public Random() {
this (seedUniquifier() ^ System.nanoTime());
}
private Random(Void unused) {
this .seed = null ;
}
private static long seedUniquifier() {
// L'Ecuyer, "Tables of Linear Congruential Generators of
// Different Sizes and Good Lattice Structure", 1999
for (;;) {
long current = seedUniquifier.get();
long next = current * 1181783497276652981 L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}
private static final AtomicLong seedUniquifier
= new AtomicLong(8682522807148012 L);
/**
* Creates a new random number generator using a single { @ code long } seed .
* The seed is the initial value of the internal state of the pseudorandom
* number generator which is maintained by method { @ link # next } .
*
* @ implSpec The invocation { @ code new Random ( seed ) } is equivalent to :
* < pre > { @ code
* Random rnd = new Random ( ) ;
* rnd . setSeed ( seed ) ;
* } < / pre >
*
* @ param seed the initial seed
* @ see # setSeed ( long )
*/
public Random(long seed) {
if (getClass() == Random.class )
this .seed = new AtomicLong(initialScramble(seed));
else {
// subclass might have overridden setSeed
this .seed = new AtomicLong();
setSeed(seed);
}
}
private static long initialScramble(long seed) {
return (seed ^ multiplier) & mask;
}
/**
* Returns an instance of { @ code Random } that delegates method calls to the { @ link RandomGenerator }
* argument . If the generator is an instance of { @ code Random } , it is returned . Otherwise , this method
* returns an instance of { @ code Random } that delegates all methods except { @ code setSeed } to the generator .
* The returned instance ' s { @ code setSeed } method always throws { @ link UnsupportedOperationException } .
* The returned instance is not serializable .
*
* @ param generator the { @ code RandomGenerator } calls are delegated to
* @ return the delegating { @ code Random } instance
* @ throws NullPointerException if generator is null
* @ since 19
*/
public static Random from(RandomGenerator generator) {
Objects.requireNonNull(generator);
if (generator instanceof Random rand)
return rand;
return new RandomWrapper(generator);
}
/**
* Sets or updates the seed of this random number generator using the
* provided { @ code long } seed value ( optional operation ) .
*
* @ implSpec
* The implementation in this class alters the state of this random number
* generator so that it is in the same state as if it had just been created with
* { @ link # Random ( long ) new Random ( seed ) } . It atomically updates the seed to
* < pre > { @ code ( seed ^ 0 x5DEECE66DL ) & ( ( 1 L < < 48 ) - 1 ) } < / pre >
* and clears the { @ code haveNextNextGaussian } flag used by { @ link # nextGaussian } .
* Note that this uses only 48 bits of the given seed value .
*
* @ param seed the seed value
* @ throws UnsupportedOperationException if the { @ code setSeed }
* operation is not supported by this random number generator
*/
public synchronized void setSeed(long seed) {
this .seed.set(initialScramble(seed));
haveNextNextGaussian = false ;
}
/**
* Generates the next pseudorandom number . This method returns an
* { @ code int } value such that , if the argument { @ code bits } is between
* { @ code 1 } and { @ code 32 } ( inclusive ) , then that many low - order
* bits of the returned value will be ( approximately ) independently
* chosen bit values , each of which is ( approximately ) equally
* likely to be { @ code 0 } or { @ code 1 } .
*
* @ apiNote
* The other random - producing methods in this class are implemented
* in terms of this method , so subclasses can override just this
* method to provide a different source of pseudorandom numbers for
* the entire class .
*
* @ implSpec
* The implementation in this class atomically updates the seed to
* < pre > { @ code ( seed * 0 x5DEECE66DL + 0 xBL ) & ( ( 1 L < < 48 ) - 1 ) } < / pre >
* and returns
* < pre > { @ code ( int ) ( seed > > > ( 48 - bits ) ) } . < / pre >
*
* < p > This is a linear congruential pseudorandom number generator , as
* defined by D . H . Lehmer and described by Donald E . Knuth in
* < cite > The Art of Computer Programming , Volume 2 , Third edition :
* Seminumerical Algorithms < / cite > , section 3 . 2 . 1 .
*
* @ param bits random bits
* @ return the next pseudorandom value from this random number
* generator ' s sequence
* @ since 1 . 1
*/
protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this .seed;
do {
oldseed = seed.get();
nextseed = (oldseed * multiplier + addend) & mask;
} while (!seed.compareAndSet(oldseed, nextseed));
return (int )(nextseed >>> (48 - bits));
}
/**
* Generates random bytes and places them into a user - supplied
* byte array . The number of random bytes produced is equal to
* the length of the byte array .
*
* @ implSpec The method { @ code nextBytes } is
* implemented by class { @ code Random } as if by :
* < pre > { @ code
* public void nextBytes ( byte [ ] bytes ) {
* for ( int i = 0 ; i < bytes . length ; )
* for ( int rnd = nextInt ( ) , n = Math . min ( bytes . length - i , 4 ) ;
* n - - > 0 ; rnd > > = 8 )
* bytes [ i + + ] = ( byte ) rnd ;
* } } < / pre >
*
* @ param bytes the byte array to fill with random bytes
* @ throws NullPointerException if the byte array is null
* @ since 1 . 1
*/
@Override
public void nextBytes(byte [] bytes) {
for (int i = 0 , len = bytes.length; i < len; )
for (int rnd = nextInt(),
n = Math.min(len - i, Integer.SIZE/Byte .SIZE);
n-- > 0 ; rnd >>= Byte .SIZE)
bytes[i++] = (byte )rnd;
}
/**
* Returns the next pseudorandom , uniformly distributed { @ code int }
* value from this random number generator ' s sequence . The general
* contract of { @ code nextInt } is that one { @ code int } value is
* pseudorandomly generated and returned . All 2 < sup > 32 < / sup > possible
* { @ code int } values are produced with ( approximately ) equal probability .
*
* @ implSpec The method { @ code nextInt } is
* implemented by class { @ code Random } as if by :
* < pre > { @ code
* public int nextInt ( ) {
* return next ( 32 ) ;
* } } < / pre >
*
* @ return the next pseudorandom , uniformly distributed { @ code int }
* value from this random number generator ' s sequence
*/
@Override
public int nextInt() {
return next(32 );
}
/**
* Returns a pseudorandom , uniformly distributed { @ code int } value
* between 0 ( inclusive ) and the specified value ( exclusive ) , drawn from
* this random number generator ' s sequence . The general contract of
* { @ code nextInt } is that one { @ code int } value in the specified range
* is pseudorandomly generated and returned . All { @ code bound } possible
* { @ code int } values are produced with ( approximately ) equal
* probability .
*
* @ implSpec The method { @ code nextInt ( int bound ) } is implemented by
* class { @ code Random } as if by :
* < pre > { @ code
* public int nextInt ( int bound ) {
* if ( bound < = 0 )
* throw new IllegalArgumentException ( " bound must be positive " ) ;
*
* if ( ( bound & - bound ) = = bound ) // i.e., bound is a power of 2
* return ( int ) ( ( bound * ( long ) next ( 31 ) ) > > 31 ) ;
*
* int bits , val ;
* do {
* bits = next ( 31 ) ;
* val = bits % bound ;
* } while ( bits - val + ( bound - 1 ) < 0 ) ;
* return val ;
* } } < / pre >
*
* < p > The hedge " approximately " is used in the foregoing description only
* because the next method is only approximately an unbiased source of
* independently chosen bits . If it were a perfect source of randomly
* chosen bits , then the algorithm shown would choose { @ code int }
* values from the stated range with perfect uniformity .
* < p >
* The algorithm is slightly tricky . It rejects values that would result
* in an uneven distribution ( due to the fact that 2 ^ 31 is not divisible
* by n ) . The probability of a value being rejected depends on n . The
* worst case is n = 2 ^ 30 + 1 , for which the probability of a reject is 1 / 2 ,
* and the expected number of iterations before the loop terminates is 2 .
* < p >
* The algorithm treats the case where n is a power of two specially : it
* returns the correct number of high - order bits from the underlying
* pseudo - random number generator . In the absence of special treatment ,
* the correct number of < i > low - order < / i > bits would be returned . Linear
* congruential pseudo - random number generators such as the one
* implemented by this class are known to have short periods in the
* sequence of values of their low - order bits . Thus , this special case
* greatly increases the length of the sequence of values returned by
* successive calls to this method if n is a small power of two .
*
* @ param bound the upper bound ( exclusive ) . Must be positive .
* @ return the next pseudorandom , uniformly distributed { @ code int }
* value between zero ( inclusive ) and { @ code bound } ( exclusive )
* from this random number generator ' s sequence
* @ throws IllegalArgumentException if bound is not positive
* @ since 1 . 2
*/
@Override
public int nextInt(int bound) {
if (bound <= 0 )
throw new IllegalArgumentException(BAD_BOUND);
int r = next(31 );
int m = bound - 1 ;
if ((bound & m) == 0 ) // i.e., bound is a power of 2
r = (int )((bound * (long )r) >> 31 );
else { // reject over-represented candidates
for (int u = r;
u - (r = u % bound) + m < 0 ;
u = next(31 ))
;
}
return r;
}
/**
* Returns the next pseudorandom , uniformly distributed { @ code long }
* value from this random number generator ' s sequence . The general
* contract of { @ code nextLong } is that one { @ code long } value is
* pseudorandomly generated and returned .
*
* @ implSpec The method { @ code nextLong } is implemented by class { @ code Random }
* as if by :
* < pre > { @ code
* public long nextLong ( ) {
* return ( ( long ) next ( 32 ) < < 32 ) + next ( 32 ) ;
* } } < / pre >
*
* Because class { @ code Random } uses a seed with only 48 bits ,
* this algorithm will not return all possible { @ code long } values .
*
* @ return the next pseudorandom , uniformly distributed { @ code long }
* value from this random number generator ' s sequence
*/
@Override
public long nextLong() {
// it's okay that the bottom word remains signed.
return ((long )(next(32 )) << 32 ) + next(32 );
}
/**
* Returns the next pseudorandom , uniformly distributed
* { @ code boolean } value from this random number generator ' s
* sequence . The general contract of { @ code nextBoolean } is that one
* { @ code boolean } value is pseudorandomly generated and returned . The
* values { @ code true } and { @ code false } are produced with
* ( approximately ) equal probability .
*
* @ implSpec The method { @ code nextBoolean } is implemented by class
* { @ code Random } as if by :
* < pre > { @ code
* public boolean nextBoolean ( ) {
* return next ( 1 ) ! = 0 ;
* } } < / pre >
*
* @ return the next pseudorandom , uniformly distributed
* { @ code boolean } value from this random number generator ' s
* sequence
* @ since 1 . 2
*/
@Override
public boolean nextBoolean() {
return next(1 ) != 0 ;
}
/**
* Returns the next pseudorandom , uniformly distributed { @ code float }
* value between { @ code 0 . 0 } and { @ code 1 . 0 } from this random
* number generator ' s sequence .
*
* < p > The general contract of { @ code nextFloat } is that one
* { @ code float } value , chosen ( approximately ) uniformly from the
* range { @ code 0 . 0 f } ( inclusive ) to { @ code 1 . 0 f } ( exclusive ) , is
* pseudorandomly generated and returned . All 2 < sup > 24 < / sup > possible
* { @ code float } values of the form < i > m & nbsp ; x & nbsp ; < / i > 2 < sup > - 24 < / sup > ,
* where < i > m < / i > is a positive integer less than 2 < sup > 24 < / sup > , are
* produced with ( approximately ) equal probability .
*
* @ implSpec The method { @ code nextFloat } is implemented by class
* { @ code Random } as if by :
* < pre > { @ code
* public float nextFloat ( ) {
* return next ( 24 ) / ( ( float ) ( 1 < < 24 ) ) ;
* } } < / pre >
* < p > The hedge " approximately " is used in the foregoing description only
* because the next method is only approximately an unbiased source of
* independently chosen bits . If it were a perfect source of randomly
* chosen bits , then the algorithm shown would choose { @ code float }
* values from the stated range with perfect uniformity . < p >
* [ In early versions of Java , the result was incorrectly calculated as :
* < pre > { @ code return next ( 30 ) / ( ( float ) ( 1 < < 30 ) ) ; } < / pre >
* This might seem to be equivalent , if not better , but in fact it
* introduced a slight nonuniformity because of the bias in the rounding
* of floating - point numbers : it was slightly more likely that the
* low - order bit of the significand would be 0 than that it would be 1 . ]
*
* @ return the next pseudorandom , uniformly distributed { @ code float }
* value between { @ code 0 . 0 f } and { @ code 1 . 0 f } from this
* random number generator ' s sequence
* /
@ Override
public float nextFloat ( ) {
return next ( Float . PRECISION ) * FLOAT_UNIT ;
}
/**
* Returns the next pseudorandom , uniformly distributed
* { @ code double } value between { @ code 0 . 0 } and
* { @ code 1 . 0 } from this random number generator ' s sequence .
*
* < p > The general contract of { @ code nextDouble } is that one
* { @ code double } value , chosen ( approximately ) uniformly from the
* range { @ code 0 . 0 d } ( inclusive ) to { @ code 1 . 0 d } ( exclusive ) , is
* pseudorandomly generated and returned .
*
* @ implSpec The method { @ code nextDouble } is implemented by class
* { @ code Random } as if by :
* < pre > { @ code
* public double nextDouble ( ) {
* return ( ( ( long ) next ( 26 ) < < 27 ) + next ( 27 ) )
* / ( double ) ( 1 L < < 53 ) ;
* } } < / pre >
* < p > The hedge " approximately " is used in the foregoing description only
* because the { @ code next } method is only approximately an unbiased source
* of independently chosen bits . If it were a perfect source of randomly
* chosen bits , then the algorithm shown would choose { @ code double } values
* from the stated range with perfect uniformity .
* < p > [ In early versions of Java , the result was incorrectly calculated as :
* < pre > { @ code return ( ( ( long ) next ( 27 ) < < 27 ) + next ( 27 ) ) / ( double ) ( 1 L < < 54 ) ; } < / pre >
* This might seem to be equivalent , if not better , but in fact it
* introduced a large nonuniformity because of the bias in the rounding of
* floating - point numbers : it was three times as likely that the low - order
* bit of the significand would be 0 than that it would be 1 ! This
* nonuniformity probably doesn ' t matter much in practice , but we strive
* for perfection . ]
*
* @ return the next pseudorandom , uniformly distributed { @ code double }
* value between { @ code 0 . 0 } and { @ code 1 . 0 } from this
* random number generator ' s sequence
* @ see Math # random
*/
@Override
public double nextDouble() {
return (((long )(next(Double .PRECISION - 27 )) << 27 ) + next(27 )) * DOUBLE_UNIT;
}
private double nextNextGaussian;
private boolean haveNextNextGaussian = false ;
/**
* Returns the next pseudorandom , Gaussian ( " normally " ) distributed
* { @ code double } value with mean { @ code 0 . 0 } and standard
* deviation { @ code 1 . 0 } from this random number generator ' s sequence .
* < p >
* The general contract of { @ code nextGaussian } is that one
* { @ code double } value , chosen from ( approximately ) the usual
* normal distribution with mean { @ code 0 . 0 } and standard deviation
* { @ code 1 . 0 } , is pseudorandomly generated and returned .
*
* @ implSpec The method { @ code nextGaussian } is implemented by class
* { @ code Random } as if by a threadsafe version of the following :
* < pre > { @ code
* private double nextNextGaussian ;
* private boolean haveNextNextGaussian = false ;
*
* public double nextGaussian ( ) {
* if ( haveNextNextGaussian ) {
* haveNextNextGaussian = false ;
* return nextNextGaussian ;
* } else {
* double v1 , v2 , s ;
* do {
* v1 = 2 * nextDouble ( ) - 1 ; // between -1.0 and 1.0
* v2 = 2 * nextDouble ( ) - 1 ; // between -1.0 and 1.0
* s = v1 * v1 + v2 * v2 ;
* } while ( s > = 1 | | s = = 0 ) ;
* double multiplier = StrictMath . sqrt ( - 2 * StrictMath . log ( s ) / s ) ;
* nextNextGaussian = v2 * multiplier ;
* haveNextNextGaussian = true ;
* return v1 * multiplier ;
* }
* } } < / pre >
*
* This uses the < i > polar method < / i > of G . E . P . Box , M . E . Muller , and
* G . Marsaglia , as described by Donald E . Knuth in < cite > The Art of
* Computer Programming , Volume 2 , third edition : Seminumerical Algorithms < / cite > ,
* section 3 . 4 . 1 , subsection C , algorithm P . Note that it generates two
* independent values at the cost of only one call to { @ code StrictMath . log }
* and one call to { @ code StrictMath . sqrt } .
*
* @ return the next pseudorandom , Gaussian ( " normally " ) distributed
* { @ code double } value with mean { @ code 0 . 0 } and
* standard deviation { @ code 1 . 0 } from this random number
* generator ' s sequence
*/
@Override
public synchronized double nextGaussian() {
// See Knuth, TAOCP, Vol. 2, 3rd edition, Section 3.4.1 Algorithm C.
if (haveNextNextGaussian) {
haveNextNextGaussian = false ;
return nextNextGaussian;
} else {
double v1, v2, s;
do {
v1 = 2 * nextDouble() - 1 ; // between -1 and 1
v2 = 2 * nextDouble() - 1 ; // between -1 and 1
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s == 0 );
double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
nextNextGaussian = v2 * multiplier;
haveNextNextGaussian = true ;
return v1 * multiplier;
}
}
/**
* Serializable fields for Random .
*
* @ serialField seed long
* seed for random computations
* @ serialField nextNextGaussian double
* next Gaussian to be returned
* @ serialField haveNextNextGaussian boolean
* nextNextGaussian is valid
*/
@java.io.Serial
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("seed" , Long .TYPE),
new ObjectStreamField("nextNextGaussian" , Double .TYPE),
new ObjectStreamField("haveNextNextGaussian" , Boolean .TYPE)
};
/**
* Reconstitute the { @ code Random } instance from a stream ( that is ,
* deserialize it ) .
*
* @ param s the { @ code ObjectInputStream } from which data is read
*
* @ throws IOException if an I / O error occurs
* @ throws ClassNotFoundException if a serialized class cannot be loaded
*/
@java.io.Serial
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
ObjectInputStream.GetField fields = s.readFields();
// The seed is read in as {@code long} for
// historical reasons, but it is converted to an AtomicLong.
long seedVal = fields.get("seed" , -1 L);
if (seedVal < 0 )
throw new java.io.StreamCorruptedException(
"Random: invalid seed" );
resetSeed(seedVal);
nextNextGaussian = fields.get("nextNextGaussian" , 0 .0 );
haveNextNextGaussian = fields.get("haveNextNextGaussian" , false );
}
/**
* Save the { @ code Random } instance to a stream .
*
* @ param s the { @ code ObjectOutputStream } to which data is written
*
* @ throws IOException if an I / O error occurs
*/
@java.io.Serial
private synchronized void writeObject(ObjectOutputStream s)
throws IOException {
// set the values of the Serializable fields
ObjectOutputStream.PutField fields = s.putFields();
// The seed is serialized as a long for historical reasons.
fields.put("seed" , seed.get());
fields.put("nextNextGaussian" , nextNextGaussian);
fields.put("haveNextNextGaussian" , haveNextNextGaussian);
// save them
s.writeFields();
}
// Support for resetting seed while deserializing
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long seedOffset;
static {
try {
seedOffset = unsafe.objectFieldOffset
(Random.class .getDeclaredField("seed" ));
} catch (Exception ex) { throw new Error(ex); }
}
private void resetSeed(long seedVal) {
unsafe.putReferenceVolatile(this , seedOffset, new AtomicLong(seedVal));
}
/**
* Returns a stream producing the given { @ code streamSize } number of
* pseudorandom { @ code int } values .
*
* < p > A pseudorandom { @ code int } value is generated as if it ' s the result of
* calling the method { @ link # nextInt ( ) } .
*
* @ param streamSize the number of values to generate
* @ return a stream of pseudorandom { @ code int } values
* @ throws IllegalArgumentException if { @ code streamSize } is
* less than zero
* @ since 1 . 8
*/
@Override
public IntStream ints(long streamSize) {
return AbstractSpliteratorGenerator.ints(this , streamSize);
}
/**
* Returns an effectively unlimited stream of pseudorandom { @ code int }
* values .
*
* < p > A pseudorandom { @ code int } value is generated as if it ' s the result of
* calling the method { @ link # nextInt ( ) } .
*
* @ implNote This method is implemented to be equivalent to { @ code
* ints ( Long . MAX_VALUE ) } .
*
* @ return a stream of pseudorandom { @ code int } values
* @ since 1 . 8
*/
@Override
public IntStream ints() {
return AbstractSpliteratorGenerator.ints(this );
}
/**
* Returns a stream producing the given { @ code streamSize } number
* of pseudorandom { @ code int } values , each conforming to the given
* origin ( inclusive ) and bound ( exclusive ) .
*
* < p > A pseudorandom { @ code int } value is generated as if it ' s the result of
* calling the following method with the origin and bound :
* < pre > { @ code
* int nextInt ( int origin , int bound ) {
* int n = bound - origin ;
* if ( n > 0 ) {
* return nextInt ( n ) + origin ;
* }
* else { // range not representable as int
* int r ;
* do {
* r = nextInt ( ) ;
* } while ( r < origin | | r > = bound ) ;
* return r ;
* }
* } } < / pre >
*
* @ param streamSize the number of values to generate
* @ param randomNumberOrigin the origin ( inclusive ) of each random value
* @ param randomNumberBound the bound ( exclusive ) of each random value
* @ return a stream of pseudorandom { @ code int } values ,
* each with the given origin ( inclusive ) and bound ( exclusive )
* @ throws IllegalArgumentException if { @ code streamSize } is
* less than zero , or { @ code randomNumberOrigin }
* is greater than or equal to { @ code randomNumberBound }
* @ since 1 . 8
*/
@Override
public IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound) {
return AbstractSpliteratorGenerator.ints(this , streamSize, randomNumberOrigin, randomNumberBound);
}
/**
* Returns an effectively unlimited stream of pseudorandom { @ code
* int } values , each conforming to the given origin ( inclusive ) and bound
* ( exclusive ) .
*
* < p > A pseudorandom { @ code int } value is generated as if it ' s the result of
* calling the following method with the origin and bound :
* < pre > { @ code
* int nextInt ( int origin , int bound ) {
* int n = bound - origin ;
* if ( n > 0 ) {
* return nextInt ( n ) + origin ;
* }
* else { // range not representable as int
* int r ;
* do {
* r = nextInt ( ) ;
* } while ( r < origin | | r > = bound ) ;
* return r ;
* }
* } } < / pre >
*
* @ implNote This method is implemented to be equivalent to { @ code
* ints ( Long . MAX_VALUE , randomNumberOrigin , randomNumberBound ) } .
*
* @ param randomNumberOrigin the origin ( inclusive ) of each random value
* @ param randomNumberBound the bound ( exclusive ) of each random value
* @ return a stream of pseudorandom { @ code int } values ,
* each with the given origin ( inclusive ) and bound ( exclusive )
* @ throws IllegalArgumentException if { @ code randomNumberOrigin }
* is greater than or equal to { @ code randomNumberBound }
* @ since 1 . 8
*/
@Override
public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
return AbstractSpliteratorGenerator.ints(this , randomNumberOrigin, randomNumberBound);
}
/**
* Returns a stream producing the given { @ code streamSize } number of
* pseudorandom { @ code long } values .
*
* < p > A pseudorandom { @ code long } value is generated as if it ' s the result
* of calling the method { @ link # nextLong ( ) } .
*
* @ param streamSize the number of values to generate
* @ return a stream of pseudorandom { @ code long } values
* @ throws IllegalArgumentException if { @ code streamSize } is
* less than zero
* @ since 1 . 8
*/
@Override
public LongStream longs(long streamSize) {
return AbstractSpliteratorGenerator.longs(this , streamSize);
}
/**
* Returns an effectively unlimited stream of pseudorandom { @ code long }
* values .
*
* < p > A pseudorandom { @ code long } value is generated as if it ' s the result
* of calling the method { @ link # nextLong ( ) } .
*
* @ implNote This method is implemented to be equivalent to { @ code
* longs ( Long . MAX_VALUE ) } .
*
* @ return a stream of pseudorandom { @ code long } values
* @ since 1 . 8
*/
@Override
public LongStream longs() {
return AbstractSpliteratorGenerator.longs(this );
}
/**
* Returns a stream producing the given { @ code streamSize } number of
* pseudorandom { @ code long } , each conforming to the given origin
* ( inclusive ) and bound ( exclusive ) .
*
* < p > A pseudorandom { @ code long } value is generated as if it ' s the result
* of calling the following method with the origin and bound :
* < pre > { @ code
* long nextLong ( long origin , long bound ) {
* long r = nextLong ( ) ;
* long n = bound - origin , m = n - 1 ;
* if ( ( n & m ) = = 0 L ) // power of two
* r = ( r & m ) + origin ;
* else if ( n > 0 L ) { // reject over-represented candidates
* for ( long u = r > > > 1 ; // ensure nonnegative
* u + m - ( r = u % n ) < 0 L ; // rejection check
* u = nextLong ( ) > > > 1 ) // retry
* ;
* r + = origin ;
* }
* else { // range not representable as long
* while ( r < origin | | r > = bound )
* r = nextLong ( ) ;
* }
* return r ;
* } } < / pre >
*
* @ param streamSize the number of values to generate
* @ param randomNumberOrigin the origin ( inclusive ) of each random value
* @ param randomNumberBound the bound ( exclusive ) of each random value
* @ return a stream of pseudorandom { @ code long } values ,
* each with the given origin ( inclusive ) and bound ( exclusive )
* @ throws IllegalArgumentException if { @ code streamSize } is
* less than zero , or { @ code randomNumberOrigin }
* is greater than or equal to { @ code randomNumberBound }
* @ since 1 . 8
*/
@Override
public LongStream longs(long streamSize, long randomNumberOrigin, long randomNumberBound) {
return AbstractSpliteratorGenerator.longs(this , streamSize, randomNumberOrigin, randomNumberBound);
}
/**
* Returns an effectively unlimited stream of pseudorandom { @ code
* long } values , each conforming to the given origin ( inclusive ) and bound
* ( exclusive ) .
*
* < p > A pseudorandom { @ code long } value is generated as if it ' s the result
* of calling the following method with the origin and bound :
* < pre > { @ code
* long nextLong ( long origin , long bound ) {
* long r = nextLong ( ) ;
* long n = bound - origin , m = n - 1 ;
* if ( ( n & m ) = = 0 L ) // power of two
* r = ( r & m ) + origin ;
* else if ( n > 0 L ) { // reject over-represented candidates
* for ( long u = r > > > 1 ; // ensure nonnegative
* u + m - ( r = u % n ) < 0 L ; // rejection check
* u = nextLong ( ) > > > 1 ) // retry
* ;
* r + = origin ;
* }
* else { // range not representable as long
* while ( r < origin | | r > = bound )
* r = nextLong ( ) ;
* }
* return r ;
* } } < / pre >
*
* @ implNote This method is implemented to be equivalent to { @ code
* longs ( Long . MAX_VALUE , randomNumberOrigin , randomNumberBound ) } .
*
* @ param randomNumberOrigin the origin ( inclusive ) of each random value
* @ param randomNumberBound the bound ( exclusive ) of each random value
* @ return a stream of pseudorandom { @ code long } values ,
* each with the given origin ( inclusive ) and bound ( exclusive )
* @ throws IllegalArgumentException if { @ code randomNumberOrigin }
* is greater than or equal to { @ code randomNumberBound }
* @ since 1 . 8
*/
@Override
public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
return AbstractSpliteratorGenerator.longs(this , randomNumberOrigin, randomNumberBound);
}
/**
* Returns a stream producing the given { @ code streamSize } number of
* pseudorandom { @ code double } values , each between zero
* ( inclusive ) and one ( exclusive ) .
*
* < p > A pseudorandom { @ code double } value is generated as if it ' s the result
* of calling the method { @ link # nextDouble ( ) } .
*
* @ param streamSize the number of values to generate
* @ return a stream of { @ code double } values
* @ throws IllegalArgumentException if { @ code streamSize } is
* less than zero
* @ since 1 . 8
*/
@Override
public DoubleStream doubles(long streamSize) {
return AbstractSpliteratorGenerator.doubles(this , streamSize);
}
/**
* Returns an effectively unlimited stream of pseudorandom { @ code
* double } values , each between zero ( inclusive ) and one
* ( exclusive ) .
*
* < p > A pseudorandom { @ code double } value is generated as if it ' s the result
* of calling the method { @ link # nextDouble ( ) } .
*
* @ implNote This method is implemented to be equivalent to { @ code
* doubles ( Long . MAX_VALUE ) } .
*
* @ return a stream of pseudorandom { @ code double } values
* @ since 1 . 8
*/
@Override
public DoubleStream doubles() {
return AbstractSpliteratorGenerator.doubles(this );
}
/**
* Returns a stream producing the given { @ code streamSize } number of
* pseudorandom { @ code double } values , each conforming to the given origin
* ( inclusive ) and bound ( exclusive ) .
*
* @ param streamSize the number of values to generate
* @ param randomNumberOrigin the origin ( inclusive ) of each random value
* @ param randomNumberBound the bound ( exclusive ) of each random value
* @ return a stream of pseudorandom { @ code double } values ,
* each with the given origin ( inclusive ) and bound ( exclusive )
* @ throws IllegalArgumentException { @ inheritDoc }
* @ since 1 . 8
*/
@Override
public DoubleStream doubles(long streamSize, double randomNumberOrigin, double randomNumberBound) {
return AbstractSpliteratorGenerator.doubles(this , streamSize, randomNumberOrigin, randomNumberBound);
}
/**
* Returns an effectively unlimited stream of pseudorandom { @ code
* double } values , each conforming to the given origin ( inclusive ) and bound
* ( exclusive ) .
* @ implNote This method is implemented to be equivalent to { @ code
* doubles ( Long . MAX_VALUE , randomNumberOrigin , randomNumberBound ) } .
*
* @ param randomNumberOrigin the origin ( inclusive ) of each random value
* @ param randomNumberBound the bound ( exclusive ) of each random value
* @ return a stream of pseudorandom { @ code double } values ,
* each with the given origin ( inclusive ) and bound ( exclusive )
* @ throws IllegalArgumentException { @ inheritDoc }
* @ since 1 . 8
*/
@Override
public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
return AbstractSpliteratorGenerator.doubles(this , randomNumberOrigin, randomNumberBound);
}
}
Messung V0.5 in Prozent C=94 H=88 G=90
¤ Dauer der Verarbeitung: 0.50 Sekunden
¤
*© Formatika GbR, Deutschland