/[classpath]/classpath/java/util/Random.java
ViewVC logotype

Diff of /classpath/java/util/Random.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.10 by mark, Tue Jan 22 22:27:01 2002 UTC revision 1.11 by ericb, Fri Feb 22 02:09:40 2002 UTC
# Line 1  Line 1 
1  /* java.util.Random  /* Random.java -- a pseudo-random number generator
2     Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.     Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 38  exception statement from your version. * Line 38  exception statement from your version. *
38    
39  package java.util;  package java.util;
40    
41    import java.io.Serializable;
42    
43  /**  /**
44   * This class generates pseudorandom numbers.  It uses the same   * This class generates pseudorandom numbers.  It uses the same
45   * algorithm as the original JDK-class, so that your programs behave   * algorithm as the original JDK-class, so that your programs behave
46   * exactly the same way, if started with the same seed.   * exactly the same way, if started with the same seed.
47   *   *
48   * The algorithm is described in <em>The Art of Computer Programming,   * The algorithm is described in <em>The Art of Computer Programming,
49   * Volume 2</em> by Donald Knuth in Section 3.2.1.   * Volume 2</em> by Donald Knuth in Section 3.2.1.  It is a 48-bit seed,
50     * linear congruential formula.
51   *   *
52   * If two instances of this class are created with the same seed and   * If two instances of this class are created with the same seed and
53   * the same calls to these classes are made, they behave exactly the   * the same calls to these classes are made, they behave exactly the
# Line 57  package java.util; Line 60  package java.util;
60   * <code>setSeed(long)</code> method.  In that case the above   * <code>setSeed(long)</code> method.  In that case the above
61   * paragraph doesn't apply to you.   * paragraph doesn't apply to you.
62   *   *
63   * This class shouldn't be used for security sensitive purposes (like   * This class shouldn't be used for security sensitive purposes (like
64   * generating passwords or encryption keys.  See <code>SecureRandom</code>   * generating passwords or encryption keys.  See <code>SecureRandom</code>
65   * in package <code>java.security</code> for this purpose.   * in package <code>java.security</code> for this purpose.
66   *   *
# Line 66  package java.util; Line 69  package java.util;
69   *   *
70   * @see java.security.SecureRandom   * @see java.security.SecureRandom
71   * @see Math#random()   * @see Math#random()
72   * @author Jochen Hoenicke */   * @author Jochen Hoenicke
73  public class Random implements java.io.Serializable   * @author Eric Blake <ebb9@email.byu.edu>
74     * @status updated to 1.4
75     */
76    public class Random implements Serializable
77  {  {
78    /**    /**
79     * True if the next nextGaussian is available.  This is used by     * True if the next nextGaussian is available.  This is used by
80     * nextGaussian, which generates two gaussian numbers by one call,     * nextGaussian, which generates two gaussian numbers by one call,
81     * and returns the second on the second call.       * and returns the second on the second call.
82     * @see #nextGaussian.  */     *
83       * @serial whether nextNextGaussian is available
84       * @see #nextGaussian()
85       * @see #nextNextGaussian
86       */
87    private boolean haveNextNextGaussian;    private boolean haveNextNextGaussian;
88    
89    /**    /**
90     * The next nextGaussian if available.  This is used by nextGaussian,     * The next nextGaussian, when available.  This is used by nextGaussian,
91     * which generates two gaussian numbers by one call, and returns the     * which generates two gaussian numbers by one call, and returns the
92     * second on the second call.     * second on the second call.
93     * @see #nextGaussian.     *
94       * @serial the second gaussian of a pair
95       * @see #nextGaussian()
96       * @see #haveNextNextGaussian
97     */     */
98    private double nextNextGaussian;    private double nextNextGaussian;
99    
100    /**    /**
101     * The seed.  This is the number set by setSeed and which is used     * The seed.  This is the number set by setSeed and which is used
102     * in next.     * in next.
103     * @see #next     *
104       * @serial the internal state of this generator
105       * @see #next()
106     */     */
107    private long seed;    private long seed;
108    
109      /**
110       * Compatible with JDK 1.0+.
111       */
112    private static final long serialVersionUID = 3905348978240129619L;    private static final long serialVersionUID = 3905348978240129619L;
113    
114    /**    /**
115     * Creates a new pseudorandom number generator.  The seed is initialized     * Creates a new pseudorandom number generator.  The seed is initialized
116     * to the current time as follows.     * to the current time, as if by
117     * <pre>     * <code>setSeed(System.currentTimeMillis());</code>.
118     * setSeed(System.currentTimeMillis());     *
    * </pre>  
119     * @see System#currentTimeMillis()     * @see System#currentTimeMillis()
120     */     */
121    public Random()    public Random()
122    {    {
123      setSeed(System.currentTimeMillis());      this(System.currentTimeMillis());
124    }    }
125    
126    /**    /**
127     * Creates a new pseudorandom number generator, starting with the     * Creates a new pseudorandom number generator, starting with the
128     * specified seed. This does:     * specified seed, using <code>setSeed(seed);</code>.
129     * <pre>     *
130     * setSeed(seed);     * @param seed the initial seed
    * </pre>  
    * @param seed the initial seed.  
131     */     */
132    public Random(long seed)    public Random(long seed)
133    {    {
# Line 128  public class Random implements java.io.S Line 145  public class Random implements java.io.S
145     *     haveNextNextGaussian = false;     *     haveNextNextGaussian = false;
146     * }     * }
147     * </pre>     * </pre>
148       *
149       * @param seed the new seed
150     */     */
151    public synchronized void setSeed(long seed)    public synchronized void setSeed(long seed)
152    {    {
# Line 146  public class Random implements java.io.S Line 165  public class Random implements java.io.S
165     *     return (int) (seed >>> (48 - bits));     *     return (int) (seed >>> (48 - bits));
166     * }     * }
167     * </pre>     * </pre>
168     * @param bits the number of random bits to generate.  Must be in range     *
169     * 1..32.     * @param bits the number of random bits to generate, in the range 1..32
170     * @return the next pseudorandom value.     * @return the next pseudorandom value
171     * @since JDK1.1     * @since 1.1
172     */     */
173    protected synchronized int next(int bits)    protected synchronized int next(int bits)
     /*{ require { 1 <= bits && bits <=32 ::  
        "bits "+bits+" not in range [1..32]" } } */  
174    {    {
175      seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);      seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
176      return (int) (seed >>> (48 - bits));      return (int) (seed >>> (48 - bits));
# Line 174  public class Random implements java.io.S Line 191  public class Random implements java.io.S
191     *     }     *     }
192     * }     * }
193     * </pre>     * </pre>
194     * @param bytes The byte array that should be filled.     *
195     * @since JDK1.1     * @param bytes the byte array that should be filled
196       * @throws NullPointerException if bytes is null
197       * @since 1.1
198     */     */
199    public void nextBytes(byte[] bytes)    public void nextBytes(byte[] bytes)
     /*{ require { bytes != null :: "bytes is null"; } } */  
200    {    {
201      int random;      int random;
202      /* Do a little bit unrolling of the above algorithm. */      // Do a little bit unrolling of the above algorithm.
203      int max = bytes.length & ~0x3;      int max = bytes.length & ~0x3;
204      for (int i = 0; i < max; i += 4)      for (int i = 0; i < max; i += 4)
205        {        {
206          random = next(32);          random = next(32);
207          bytes[i] = (byte) random;          bytes[i] = (byte) random;
208          bytes[i + 1] = (byte) (random >> 8);          bytes[i + 1] = (byte) (random >> 8);
209          bytes[i + 2] = (byte) (random >> 16);          bytes[i + 2] = (byte) (random >> 16);
210          bytes[i + 3] = (byte) (random >> 24);          bytes[i + 3] = (byte) (random >> 24);
211        }        }
212      if (max < bytes.length)      if (max < bytes.length)
213        {        {
214          random = next(32);          random = next(32);
215          for (int j = max; j < bytes.length; j++)          for (int j = max; j < bytes.length; j++)
216            {            {
217              bytes[j] = (byte) random;              bytes[j] = (byte) random;
218              random >>= 8;              random >>= 8;
219            }            }
220        }        }
221    }    }
222    
# Line 213  public class Random implements java.io.S Line 231  public class Random implements java.io.S
231     * }     * }
232     * </pre>     * </pre>
233     *     *
234     * @return the next pseudorandom value.  */     * @return the next pseudorandom value
235       */
236    public int nextInt()    public int nextInt()
237    {    {
238      return next(32);      return next(32);
# Line 239  public class Random implements java.io.S Line 258  public class Random implements java.io.S
258     *     return val;     *     return val;
259     * }     * }
260     * </pre>     * </pre>
261     * This algorithm would return every value with exactly the same     * This algorithm would return every value with exactly the same
262     * probability, if the next()-method would be a perfect random number     * probability, if the next()-method would be a perfect random number
263     * generator.     * generator.
264     *     *
265     * The loop at the bottom only accepts a value, if the random     * The loop at the bottom only accepts a value, if the random
266     * number was between 0 and the highest number less then 1<<31,     * number was between 0 and the highest number less then 1<<31,
267     * which is divisible by n.  The probability for this is high for small     * which is divisible by n.  The probability for this is high for small
268     * n, and the worst case is 1/2 (for n=(1<<30)+1).     * n, and the worst case is 1/2 (for n=(1<<30)+1).
269     *     *
270     * The special treatment for n = power of 2, selects the high bits of     * The special treatment for n = power of 2, selects the high bits of
271     * the random number (the loop at the bottom would select the low order     * the random number (the loop at the bottom would select the low order
272     * bits).  This is done, because the low order bits of linear congruential     * bits).  This is done, because the low order bits of linear congruential
273     * number generators (like the one used in this class) are known to be     * number generators (like the one used in this class) are known to be
274     * ``less random'' than the high order bits.     * ``less random'' than the high order bits.
275     *     *
276     * @param n the upper bound.     * @param n the upper bound
277     * @exception IllegalArgumentException if the given upper bound is negative     * @throws IllegalArgumentException if the given upper bound is negative
278     * @return the next pseudorandom value.       * @return the next pseudorandom value
279       * @since 1.2
280     */     */
281    public int nextInt(int n)    public int nextInt(int n)
     /*{ require { n > 0 :: "n must be positive"; } } */  
282    {    {
283      if (n <= 0)      if (n <= 0)
284        throw new IllegalArgumentException("n must be positive");        throw new IllegalArgumentException("n must be positive");
285      if ((n & -n) == n)          // i.e., n is a power of 2      if ((n & -n) == n) // i.e., n is a power of 2
286        return (int) ((n * (long) next(31)) >> 31);        return (int) ((n * (long) next(31)) >> 31);
287      int bits, val;      int bits, val;
288      do      do
289        {        {
290          bits = next(32);          bits = next(32);
291          val = bits % n;          val = bits % n;
292        }        }
293      while (bits - val + (n - 1) < 0);      while (bits - val + (n - 1) < 0);
294      return val;      return val;
# Line 284  public class Random implements java.io.S Line 303  public class Random implements java.io.S
303     *     return ((long)next(32) << 32) + next(32);     *     return ((long)next(32) << 32) + next(32);
304     * }     * }
305     * </pre>     * </pre>
306     * @return the next pseudorandom value.       *
307       * @return the next pseudorandom value
308     */     */
309    public long nextLong()    public long nextLong()
310    {    {
# Line 299  public class Random implements java.io.S Line 319  public class Random implements java.io.S
319     *     return next(1) != 0;     *     return next(1) != 0;
320     * }     * }
321     * </pre>     * </pre>
322     * @return the next pseudorandom boolean.     *
323       * @return the next pseudorandom boolean
324       * @since 1.2
325     */     */
326    public boolean nextBoolean()    public boolean nextBoolean()
327    {    {
# Line 308  public class Random implements java.io.S Line 330  public class Random implements java.io.S
330    
331    /**    /**
332     * Generates the next pseudorandom float uniformly distributed     * Generates the next pseudorandom float uniformly distributed
333     * between 0.0f (inclusive) and 1.0 (exclusive).  The     * between 0.0f (inclusive) and 1.0f (exclusive).  The
334     * implementation is as follows.     * implementation is as follows.
335     * <pre>     * <pre>
336     * public float nextFloat() {     * public float nextFloat() {
337     *     return next(24) / ((float)(1 << 24));     *     return next(24) / ((float)(1 << 24));
338     * }     * }
339     * </pre>     * </pre>
340     * @return the next pseudorandom float.  */     *
341       * @return the next pseudorandom float
342       */
343    public float nextFloat()    public float nextFloat()
344    {    {
345      return next(24) / ((float) (1 << 24));      return next(24) / (float) (1 << 24);
346    }    }
347    
348    /**    /**
349     * Generates the next pseudorandom double uniformly distributed     * Generates the next pseudorandom double uniformly distributed
350     * between 0.0f (inclusive) and 1.0 (exclusive).  The     * between 0.0 (inclusive) and 1.0 (exclusive).  The
351     * implementation is as follows.     * implementation is as follows.
352     * <pre>     * <pre>
353     * public double nextDouble() {     * public double nextDouble() {
354     *     return (((long)next(26) << 27) + next(27)) / (double)(1 << 53);     *     return (((long)next(26) << 27) + next(27)) / (double)(1L << 53);
355     * }     * }
356     * </pre>     * </pre>
357     * @return the next pseudorandom double.  */     *
358       * @return the next pseudorandom double
359       */
360    public double nextDouble()    public double nextDouble()
361    {    {
362      return (((long) next(26) << 27) + next(27)) / (double) (1L << 53);      return (((long) next(26) << 27) + next(27)) / (double) (1L << 53);
363    }    }
364    
365    /**    /**
366     * Generates the next pseudorandom, Gaussian (normally) distributed     * Generates the next pseudorandom, Gaussian (normally) distributed
367     * double value, with mean 0.0 and standard deviation 1.0.     * double value, with mean 0.0 and standard deviation 1.0.
368     * The algorithm is as follows.     * The algorithm is as follows.
369     * <pre>     * <pre>
# Line 362  public class Random implements java.io.S Line 388  public class Random implements java.io.S
388     * This is described in section 3.4.1 of <em>The Art of Computer     * This is described in section 3.4.1 of <em>The Art of Computer
389     * Programming, Volume 2</em> by Donald Knuth.     * Programming, Volume 2</em> by Donald Knuth.
390     *     *
391     * @return the next pseudorandom Gaussian distributed double.       * @return the next pseudorandom Gaussian distributed double
392     */     */
393    public synchronized double nextGaussian()    public synchronized double nextGaussian()
394    {    {
395      if (haveNextNextGaussian)      if (haveNextNextGaussian)
396        {        {
397          haveNextNextGaussian = false;          haveNextNextGaussian = false;
398          return nextNextGaussian;          return nextNextGaussian;
399        }        }
400      else      double v1, v2, s;
401        do
402        {        {
403          double v1, v2, s;          v1 = 2 * nextDouble() - 1; // Between -1.0 and 1.0.
404          do          v2 = 2 * nextDouble() - 1; // Between -1.0 and 1.0.
405            {          s = v1 * v1 + v2 * v2;
             v1 = 2 * nextDouble() - 1;  // between -1.0 and 1.0  
             v2 = 2 * nextDouble() - 1;  // between -1.0 and 1.0  
             s = v1 * v1 + v2 * v2;  
           }  
         while (s >= 1);  
         double norm = Math.sqrt(-2 * Math.log(s) / s);  
         nextNextGaussian = v2 * norm;  
         haveNextNextGaussian = true;  
         return v1 * norm;  
406        }        }
407        while (s >= 1);
408        double norm = Math.sqrt(-2 * Math.log(s) / s);
409        nextNextGaussian = v2 * norm;
410        haveNextNextGaussian = true;
411        return v1 * norm;
412    }    }
413  }  }

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26