home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1997 October
/
Chip_1997-10_cd.bin
/
tema
/
sybase
/
powerj
/
java.z
/
Random.java
< prev
next >
Wrap
Text File
|
1996-05-03
|
5KB
|
171 lines
/*
* @(#)Random.java 1.6 95/12/04
*
* Copyright (c) 1995 Sun Microsystems, Inc. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*/
package java.util;
/**
* A Random class generates a stream of pseudo-random numbers.<p>
*
* To create a new random number generator, use one of the following methods:
* <pre>
* new Random()
* new Random(long seed)
* </pre>
* The form <CODE>new Random()</CODE> initializes the generator
* to a value based on the current time. The form
* <CODE>new Random(long seed)</CODE> seeds the random number generator with
* a specific initial value; use this if an application requires a repeatable
* stream of pseudo-random numbers. <p>
*
* The random number generator uses a 48-bit seed, which is modified using
* a linear congruential formula. See Donald Knuth, <CITE>The Art of Computer
* Programming, Volume 2</CITE>, Section 3.2.1.
* The generator's seed can be reset with the following method:
* <pre>
* setSeed(long seed)
* </pre>
*
* To create a pseudo-random number, use one of the following functions:
* <pre>
* nextInt()
* nextLong()
* nextFloat()
* nextDouble()
* nextGaussian()
* </pre>
*
* @see Math#random
* @version 1.1, 27 Jul 1995
* @author Frank Yellin
*/
public
class Random {
private long seed;
private final static long multiplier = 0x5DEECE66DL;
private final static long addend = 0xBL;
private final static long mask = (1L << 48) - 1;
/**
* Creates a new random number generator. Its seed will be
* initialized to a value based on the current time.
*/
public Random() { this(System.currentTimeMillis()); }
/**
* Creates a new random number generator using a single
* <CODE>long</CODE> seed.
* @param seed the initial seed
* @see Random#setSeed
*/
public Random(long seed) {
setSeed(seed);
haveNextNextGaussian = false;
}
/**
* Sets the seed of the random number generator using a single
* <CODE>long</CODE> seed.
* @param seed the initial seed
*/
synchronized public void setSeed(long seed) {
this.seed = (seed ^ multiplier) & mask;
}
/**
* Generates the next pseudorandom number.
* @param bits random bits
*/
synchronized private int next(int bits) {
long nextseed = (seed * multiplier + addend) & mask;
seed = nextseed;
return (int)(nextseed >>> (48 - bits));
}
/**
* Generates a pseudorandom uniformally distributed
* <CODE>int</CODE> value.
* @return an integer value.
*/
public int nextInt() { return next(32); }
/**
* Generate a pseudorandom uniformally distributed <CODE>long</CODE> value.
* @return A long integer value
*/
public long nextLong() {
// it's okay that the bottom word remains signed.
return (next(32) << 32L) + next(32);
}
/**
* Generates a pseudorandom uniformally distributed
* <CODE>float</CODE> value between 0.0 and 1.0.
* @return a <CODE>float</CODE> between 0.0 and 1.0 .
*/
public float nextFloat() {
int i = next(30);
return i / ((float)(1 << 30));
}
/**
* Generates a pseudorandom uniformally distributed
* <CODE>double</CODE> value between 0.0 and 1.0.
* @return a <CODE>float</CODE> between 0.0 and 1.0 .
*/
public double nextDouble() {
long l = ((long)(next(27)) << 27) + next(27);
return l / (double)(1L << 54);
}
private double nextNextGaussian;
private boolean haveNextNextGaussian = false;
/**
* Generates a pseudorandom Gaussian distributed
* <CODE>double</CODE> value with mean 0.0 and standard
* deviation 1.0.
* @return a Gaussian distributed <CODE>double</CODE>.
*/
synchronized public double nextGaussian() {
// See Knuth, ACP, 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);
double multiplier = Math.sqrt(-2 * Math.log(s)/s);
nextNextGaussian = v2 * multiplier;
haveNextNextGaussian = true;
return v1 * multiplier;
}
}
}