Home | History | Annotate | Download | only in util
      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