001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package java.util;
019:
020: import java.io.Serializable;
021:
022: /**
023: * This class provides methods that generates pseudo-random numbers of different
024: * types, such as int, long, double and float using either
025: *
026: * @see Properties
027: * @see PropertyResourceBundle
028: */
029: public class Random implements Serializable {
030:
031: private static final long serialVersionUID = 3905348978240129619L;
032:
033: private static final long multiplier = 0x5deece66dL;
034:
035: /**
036: * The boolean value indicating if the second Gaussian number is available.
037: *
038: * @serial
039: */
040: private boolean haveNextNextGaussian;
041:
042: /**
043: * @serial It is associated with the internal state of this generator.
044: */
045: private long seed;
046:
047: /**
048: * The second Gaussian generated number.
049: *
050: * @serial
051: */
052: private double nextNextGaussian;
053:
054: /**
055: * Construct a random generator with the current time of day in milliseconds
056: * as the initial state.
057: *
058: * @see #setSeed
059: */
060: public Random() {
061: setSeed(System.currentTimeMillis() + hashCode());
062: }
063:
064: /**
065: * Construct a random generator with the given <code>seed</code> as the
066: * initial state.
067: *
068: * @param seed
069: * the seed that will determine the initial state of this random
070: * number generator
071: *
072: * @see #setSeed
073: */
074: public Random(long seed) {
075: setSeed(seed);
076: }
077:
078: /**
079: * Returns a pseudo-random uniformly distributed <code>int</code> value of
080: * the number of bits specified by the argument <code>bits</code>.
081: *
082: * Implements D. H. Lehmer's random number algorithm found in <i>The Art of
083: * Computer Programming, Volume 2: Seminumerical Algorithms</i>, by Donald
084: * E. Knuth (section 3.2.1).
085: *
086: * @return a pseudo-randomly generated int
087: * @param bits
088: * number of bits of the returned value
089: *
090: * @see #nextBytes
091: * @see #nextDouble
092: * @see #nextFloat
093: * @see #nextInt()
094: * @see #nextInt(int)
095: * @see #nextGaussian
096: * @see #nextLong
097: */
098: protected synchronized int next(int bits) {
099: seed = (seed * multiplier + 0xbL) & ((1L << 48) - 1);
100: return (int) (seed >>> (48 - bits));
101: }
102:
103: /**
104: * Answers the next pseudo-random, uniformly distributed boolean value
105: * generated by this generator.
106: *
107: * @return boolean a pseudo-random, uniformly distributed boolean value
108: */
109: public boolean nextBoolean() {
110: return next(1) != 0;
111: }
112:
113: /**
114: * Modifies the byte array by a random sequence of bytes generated by this
115: * random number generator.
116: *
117: * @param buf
118: * non-null array to contain the new random bytes
119: *
120: * @see #next
121: */
122: public void nextBytes(byte[] buf) {
123: int rand = 0, count = 0, loop = 0;
124: while (count < buf.length) {
125: if (loop == 0) {
126: rand = nextInt();
127: loop = 3;
128: } else {
129: loop--;
130: }
131: buf[count++] = (byte) rand;
132: rand >>= 8;
133: }
134: }
135:
136: /**
137: * Generates a normally distributed random double number between 0.0
138: * inclusively and 1.0 exclusively.
139: *
140: * @return a random double between 0.0 and 1.0
141: *
142: * @see #nextFloat
143: */
144: public double nextDouble() {
145: return ((((long) next(26) << 27) + next(27)) / (double) (1L << 53));
146: }
147:
148: /**
149: * Generates a normally distributed random float number between 0.0
150: * inclusively and 1.0 exclusively.
151: *
152: * @return a random float between 0.0 and 1.0
153: *
154: * @see #nextDouble
155: */
156: public float nextFloat() {
157: return (next(24) / 16777216f);
158: }
159:
160: /**
161: * Returns a pseudo-randomly generated, normally distributed
162: * <code>double</code> value with mean 0.0 and a standard deviation value
163: * of <code>1.0</code>.
164: *
165: * Implements G. E. P. Box, M. E. Muller, and G. Marsaglia's polar method
166: * found in <i>The Art of Computer Programming, Volume 2: Seminumerical
167: * Algorithms</i>, by Donald E. Knuth (section 3.4.1).
168: *
169: * @return a pseudo-randomly generated double
170: *
171: * @see #nextDouble
172: */
173: public synchronized double nextGaussian() {
174: if (haveNextNextGaussian) { // if X1 has been returned, return the
175: // second Gaussian
176: haveNextNextGaussian = false;
177: return nextNextGaussian;
178: }
179:
180: double v1, v2, s;
181: do {
182: v1 = 2 * nextDouble() - 1; // Generates two independent random
183: // variables U1, U2
184: v2 = 2 * nextDouble() - 1;
185: s = v1 * v1 + v2 * v2;
186: } while (s >= 1);
187: double norm = Math.sqrt(-2 * Math.log(s) / s);
188: nextNextGaussian = v2 * norm; // should that not be norm instead
189: // of multiplier ?
190: haveNextNextGaussian = true;
191: return v1 * norm; // should that not be norm instead of multiplier
192: // ?
193: }
194:
195: /**
196: * Generates a uniformly distributed 32-bit <code>int</code> value from
197: * the this random number sequence.
198: *
199: * @return a randomly generated <code>int</code>
200: *
201: * @see java.lang.Integer#MAX_VALUE
202: * @see java.lang.Integer#MIN_VALUE
203: * @see #next
204: * @see #nextLong
205: */
206: public int nextInt() {
207: return next(32);
208: }
209:
210: /**
211: * Returns a new pseudo-random integer value which is uniformly distributed
212: * between 0 (inclusively) and <code>n</code> (exclusively).
213: *
214: * @return a randomly generated <code>int</code> between 0 and n
215: * @param n
216: * the upper limit of the values that can be returned
217: */
218: public int nextInt(int n) {
219: if (n > 0) {
220: if ((n & -n) == n) {
221: return (int) ((n * (long) next(31)) >> 31);
222: }
223: int bits, val;
224: do {
225: bits = next(31);
226: val = bits % n;
227: } while (bits - val + (n - 1) < 0);
228: return val;
229: }
230: throw new IllegalArgumentException();
231: }
232:
233: /**
234: * Generates a uniformly distributed 64-bit <code>int</code> value from
235: * the this random number sequence.
236: *
237: * @return 64-bit <code>int</code> random number
238: *
239: * @see java.lang.Integer#MAX_VALUE
240: * @see java.lang.Integer#MIN_VALUE
241: * @see #next
242: * @see #nextInt()
243: * @see #nextInt(int)
244: */
245: public long nextLong() {
246: return ((long) next(32) << 32) + next(32);
247: }
248:
249: /**
250: * Modifies the seed using a linear congruential formula, as found in <i>The
251: * Art of Computer Programming, Volume 2</i>, by Donald E. Knuth (section
252: * 3.2.1).
253: *
254: * @param seed
255: * the seed that alters the state of the random number generator
256: *
257: * @see #next
258: * @see #Random()
259: * @see #Random(long)
260: */
261: public synchronized void setSeed(long seed) {
262: this .seed = (seed ^ multiplier) & ((1L << 48) - 1);
263: haveNextNextGaussian = false;
264: }
265: }
|