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 return pseudo-random values.
     25  *
     26  * <p>It is dangerous to seed {@code Random} with the current time because
     27  * that value is more predictable to an attacker than the default seed.
     28  *
     29  * <p>This class is thread-safe.
     30  *
     31  * @see java.security.SecureRandom
     32  */
     33 public class Random implements Serializable {
     34 
     35     private static final long serialVersionUID = 3905348978240129619L;
     36 
     37     private static final long multiplier = 0x5deece66dL;
     38 
     39     /**
     40      * The boolean value indicating if the second Gaussian number is available.
     41      *
     42      * @serial
     43      */
     44     private boolean haveNextNextGaussian;
     45 
     46     /**
     47      * @serial It is associated with the internal state of this generator.
     48      */
     49     private long seed;
     50 
     51     /**
     52      * The second Gaussian generated number.
     53      *
     54      * @serial
     55      */
     56     private double nextNextGaussian;
     57 
     58     /**
     59      * Constructs a random generator with an initial state that is
     60      * unlikely to be duplicated by a subsequent instantiation.
     61      *
     62      * <p>The initial state (that is, the seed) is <i>partially</i> based
     63      * on the current time of day in milliseconds.
     64      */
     65     public Random() {
     66         // Note: Using identityHashCode() to be hermetic wrt subclasses.
     67         setSeed(System.currentTimeMillis() + System.identityHashCode(this));
     68     }
     69 
     70     /**
     71      * Construct a random generator with the given {@code seed} as the
     72      * initial state. Equivalent to {@code Random r = new Random(); r.setSeed(seed);}.
     73      *
     74      * <p>This constructor is mainly useful for <i>predictability</i> in tests.
     75      * The default constructor is likely to provide better randomness.
     76      */
     77     public Random(long seed) {
     78         setSeed(seed);
     79     }
     80 
     81     /**
     82      * Returns a pseudo-random uniformly distributed {@code int} value of
     83      * the number of bits specified by the argument {@code bits} as
     84      * described by Donald E. Knuth in <i>The Art of Computer Programming,
     85      * Volume 2: Seminumerical Algorithms</i>, section 3.2.1.
     86      *
     87      * <p>Most applications will want to use one of this class' convenience methods instead.
     88      */
     89     protected synchronized int next(int bits) {
     90         seed = (seed * multiplier + 0xbL) & ((1L << 48) - 1);
     91         return (int) (seed >>> (48 - bits));
     92     }
     93 
     94     /**
     95      * Returns a pseudo-random uniformly distributed {@code boolean}.
     96      */
     97     public boolean nextBoolean() {
     98         return next(1) != 0;
     99     }
    100 
    101     /**
    102      * Fills {@code buf} with random bytes.
    103      */
    104     public void nextBytes(byte[] buf) {
    105         int rand = 0, count = 0, loop = 0;
    106         while (count < buf.length) {
    107             if (loop == 0) {
    108                 rand = nextInt();
    109                 loop = 3;
    110             } else {
    111                 loop--;
    112             }
    113             buf[count++] = (byte) rand;
    114             rand >>= 8;
    115         }
    116     }
    117 
    118     /**
    119      * Returns a pseudo-random uniformly distributed {@code double}
    120      * in the half-open range [0.0, 1.0).
    121      */
    122     public double nextDouble() {
    123         return ((((long) next(26) << 27) + next(27)) / (double) (1L << 53));
    124     }
    125 
    126     /**
    127      * Returns a pseudo-random uniformly distributed {@code float}
    128      * in the half-open range [0.0, 1.0).
    129      */
    130     public float nextFloat() {
    131         return (next(24) / 16777216f);
    132     }
    133 
    134     /**
    135      * Returns a pseudo-random (approximately) normally distributed
    136      * {@code double} with mean 0.0 and standard deviation 1.0.
    137      * This method uses the <i>polar method</i> of G. E. P. Box, M.
    138      * E. Muller, and G. Marsaglia, as described by Donald E. Knuth in <i>The
    139      * Art of Computer Programming, Volume 2: Seminumerical Algorithms</i>,
    140      * section 3.4.1, subsection C, algorithm P.
    141      */
    142     public synchronized double nextGaussian() {
    143         if (haveNextNextGaussian) {
    144             haveNextNextGaussian = false;
    145             return nextNextGaussian;
    146         }
    147 
    148         double v1, v2, s;
    149         do {
    150             v1 = 2 * nextDouble() - 1;
    151             v2 = 2 * nextDouble() - 1;
    152             s = v1 * v1 + v2 * v2;
    153         } while (s >= 1 || s == 0);
    154 
    155         // The specification says this uses StrictMath.
    156         double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s) / s);
    157         nextNextGaussian = v2 * multiplier;
    158         haveNextNextGaussian = true;
    159         return v1 * multiplier;
    160     }
    161 
    162     /**
    163      * Returns a pseudo-random uniformly distributed {@code int}.
    164      */
    165     public int nextInt() {
    166         return next(32);
    167     }
    168 
    169     /**
    170      * Returns a pseudo-random uniformly distributed {@code int}
    171      * in the half-open range [0, n).
    172      */
    173     public int nextInt(int n) {
    174         if (n <= 0) {
    175             throw new IllegalArgumentException("n <= 0: " + n);
    176         }
    177         if ((n & -n) == n) {
    178             return (int) ((n * (long) next(31)) >> 31);
    179         }
    180         int bits, val;
    181         do {
    182             bits = next(31);
    183             val = bits % n;
    184         } while (bits - val + (n - 1) < 0);
    185         return val;
    186     }
    187 
    188     /**
    189      * Returns a pseudo-random uniformly distributed {@code long}.
    190      */
    191     public long nextLong() {
    192         return ((long) next(32) << 32) + next(32);
    193     }
    194 
    195     /**
    196      * Modifies the seed using a linear congruential formula presented in <i>The
    197      * Art of Computer Programming, Volume 2</i>, Section 3.2.1.
    198      */
    199     public synchronized void setSeed(long seed) {
    200         this.seed = (seed ^ multiplier) & ((1L << 48) - 1);
    201         haveNextNextGaussian = false;
    202     }
    203 }
    204