1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.util; 19 20 21 import java.io.Serializable; 22 23 /** 24 * This class provides methods that generates pseudo-random numbers of different 25 * types, such as {@code int}, {@code long}, {@code double}, and {@code float}. 26 * 27 * @see Properties 28 * @see PropertyResourceBundle 29 */ 30 public class Random implements Serializable { 31 32 private static final long serialVersionUID = 3905348978240129619L; 33 34 private static final long multiplier = 0x5deece66dL; 35 36 /** 37 * The boolean value indicating if the second Gaussian number is available. 38 * 39 * @serial 40 */ 41 private boolean haveNextNextGaussian; 42 43 /** 44 * @serial It is associated with the internal state of this generator. 45 */ 46 private long seed; 47 48 /** 49 * The second Gaussian generated number. 50 * 51 * @serial 52 */ 53 private double nextNextGaussian; 54 55 /** 56 * Constructs a random generator with an initial state that is 57 * unlikely to be duplicated by a subsequent instantiation. 58 * 59 * <p>The initial state (that is, the seed) is <i>partially</i> based 60 * on the current time of day in milliseconds.</p> 61 * 62 * @see #setSeed 63 */ 64 public Random() { 65 // Note: Using identityHashCode() to be hermetic wrt subclasses. 66 setSeed(System.currentTimeMillis() + System.identityHashCode(this)); 67 } 68 69 /** 70 * Construct a random generator with the given {@code seed} as the 71 * initial state. Equivalent to {@code Random r = new Random(); r.setSeed(seed);}. 72 * 73 * @param seed 74 * the seed that will determine the initial state of this random 75 * number generator. 76 * @see #setSeed 77 */ 78 public Random(long seed) { 79 setSeed(seed); 80 } 81 82 /** 83 * Returns a pseudo-random uniformly distributed {@code int} value of 84 * the number of bits specified by the argument {@code bits} as 85 * described by Donald E. Knuth in <i>The Art of Computer Programming, 86 * Volume 2: Seminumerical Algorithms</i>, section 3.2.1. 87 * 88 * @param bits 89 * number of bits of the returned value. 90 * @return a pseudo-random generated int number. 91 * @see #nextBytes 92 * @see #nextDouble 93 * @see #nextFloat 94 * @see #nextInt() 95 * @see #nextInt(int) 96 * @see #nextGaussian 97 * @see #nextLong 98 */ 99 protected synchronized int next(int bits) { 100 seed = (seed * multiplier + 0xbL) & ((1L << 48) - 1); 101 return (int) (seed >>> (48 - bits)); 102 } 103 104 /** 105 * Returns the next pseudo-random, uniformly distributed {@code boolean} value 106 * generated by this generator. 107 * 108 * @return a pseudo-random, uniformly distributed boolean value. 109 */ 110 public boolean nextBoolean() { 111 return next(1) != 0; 112 } 113 114 /** 115 * Modifies the {@code byte} array by a random sequence of {@code byte}s generated by this 116 * random number generator. 117 * 118 * @param buf 119 * non-null array to contain the new random {@code byte}s. 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 {@code double} number between 0.0 138 * inclusively and 1.0 exclusively. 139 * 140 * @return a random {@code double} in the range [0.0 - 1.0) 141 * @see #nextFloat 142 */ 143 public double nextDouble() { 144 return ((((long) next(26) << 27) + next(27)) / (double) (1L << 53)); 145 } 146 147 /** 148 * Generates a normally distributed random {@code float} number between 0.0 149 * inclusively and 1.0 exclusively. 150 * 151 * @return float a random {@code float} number between [0.0 and 1.0) 152 * @see #nextDouble 153 */ 154 public float nextFloat() { 155 return (next(24) / 16777216f); 156 } 157 158 /** 159 * Pseudo-randomly generates (approximately) a normally distributed 160 * {@code double} value with mean 0.0 and a standard deviation value 161 * of {@code 1.0} using the <i>polar method<i> of G. E. P. Box, M. 162 * E. Muller, and G. Marsaglia, as described by Donald E. Knuth in <i>The 163 * Art of Computer Programming, Volume 2: Seminumerical Algorithms</i>, 164 * section 3.4.1, subsection C, algorithm P. 165 * 166 * @return a random {@code double} 167 * @see #nextDouble 168 */ 169 public synchronized double nextGaussian() { 170 if (haveNextNextGaussian) { // if X1 has been returned, return the 171 // second Gaussian 172 haveNextNextGaussian = false; 173 return nextNextGaussian; 174 } 175 176 double v1, v2, s; 177 do { 178 v1 = 2 * nextDouble() - 1; // Generates two independent random 179 // variables U1, U2 180 v2 = 2 * nextDouble() - 1; 181 s = v1 * v1 + v2 * v2; 182 } while (s >= 1); 183 double norm = Math.sqrt(-2 * Math.log(s) / s); 184 nextNextGaussian = v2 * norm; // should that not be norm instead 185 // of multiplier ? 186 haveNextNextGaussian = true; 187 return v1 * norm; // should that not be norm instead of multiplier 188 // ? 189 } 190 191 /** 192 * Generates a uniformly distributed 32-bit {@code int} value from 193 * the random number sequence. 194 * 195 * @return a uniformly distributed {@code int} value. 196 * @see java.lang.Integer#MAX_VALUE 197 * @see java.lang.Integer#MIN_VALUE 198 * @see #next 199 * @see #nextLong 200 */ 201 public int nextInt() { 202 return next(32); 203 } 204 205 /** 206 * Returns a new pseudo-random {@code int} value which is uniformly distributed 207 * between 0 (inclusively) and the value of {@code n} (exclusively). 208 * 209 * @param n 210 * the exclusive upper border of the range [0 - n). 211 * @return a random {@code int}. 212 */ 213 public int nextInt(int n) { 214 if (n > 0) { 215 if ((n & -n) == n) { 216 return (int) ((n * (long) next(31)) >> 31); 217 } 218 int bits, val; 219 do { 220 bits = next(31); 221 val = bits % n; 222 } while (bits - val + (n - 1) < 0); 223 return val; 224 } 225 throw new IllegalArgumentException(); 226 } 227 228 /** 229 * Generates a uniformly distributed 64-bit integer value from 230 * the random number sequence. 231 * 232 * @return 64-bit random integer. 233 * @see java.lang.Integer#MAX_VALUE 234 * @see java.lang.Integer#MIN_VALUE 235 * @see #next 236 * @see #nextInt() 237 * @see #nextInt(int) 238 */ 239 public long nextLong() { 240 return ((long) next(32) << 32) + next(32); 241 } 242 243 /** 244 * Modifies the seed a using linear congruential formula presented in <i>The 245 * Art of Computer Programming, Volume 2</i>, Section 3.2.1. 246 * 247 * @param seed 248 * the seed that alters the state of the random number generator. 249 * @see #next 250 * @see #Random() 251 * @see #Random(long) 252 */ 253 public synchronized void setSeed(long seed) { 254 this.seed = (seed ^ multiplier) & ((1L << 48) - 1); 255 haveNextNextGaussian = false; 256 } 257 } 258