home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1998 February / VPR9802A.ISO / APP_DEMO / VC / MAIN.BIN / Random.java < prev    next >
Text File  |  1997-10-27  |  7KB  |  208 lines

  1. /*
  2.  * @(#)Random.java    1.16 97/02/20
  3.  * 
  4.  * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  * CopyrightVersion 1.1_beta
  20.  * 
  21.  */
  22.  
  23. package java.util;
  24.  
  25. /**
  26.  * An instance of this class is used to generate a stream of 
  27.  * pseudorandom numbers. The class uses a 48-bit seed, which is 
  28.  * modified using a linear congruential formula. (See Donald Knuth, 
  29.  * <i>The Art of Computer Programming, Volume 2</i>, Section 3.2.1.) 
  30.  * <p>
  31.  * If two instances of <code>Random</code> are created with the same 
  32.  * seed, and the same sequence of method calls is made for each, they 
  33.  * will generate and return identical sequences of numbers. 
  34.  * <p>
  35.  * Many applications will find the <code>random</code> method in 
  36.  * class <code>Math</code> simpler to use.
  37.  *
  38.  * @author  Frank Yellin
  39.  * @version 1.16, 02/20/97
  40.  * @see     java.lang.Math#random()
  41.  * @since   JDK1.0
  42.  */
  43. public
  44. class Random implements java.io.Serializable {
  45.     private long seed;
  46.     private final static long multiplier = 0x5DEECE66DL;
  47.     private final static long addend = 0xBL;
  48.     private final static long mask = (1L << 48) - 1;
  49.  
  50.     /** 
  51.      * Creates a new random number generator. Its seed is initialized to 
  52.      * a value based on the current time. 
  53.      *
  54.      * @see     java.lang.System#currentTimeMillis()
  55.      * @since   JDK1.0
  56.      */
  57.     public Random() { this(System.currentTimeMillis()); }
  58.  
  59.     /** 
  60.      * Creates a new random number generator using a single 
  61.      * <code>long</code> seed. 
  62.      *
  63.      * @param   seed   the initial seed.
  64.      * @see     java.util.Random#setSeed(long)
  65.      * @since   JDK1.0
  66.      */
  67.     public Random(long seed) {
  68.         setSeed(seed);
  69.     }
  70.  
  71.     /**
  72.      * Sets the seed of this random number generator using a single 
  73.      * <code>long</code> seed. 
  74.      *
  75.      * @param   seed   the initial seed.
  76.      * @since   JDK1.0
  77.      */
  78.     synchronized public void setSeed(long seed) {
  79.         this.seed = (seed ^ multiplier) & mask;
  80.         haveNextNextGaussian = false;
  81.     }
  82.  
  83.     /**
  84.      * Generates the next pseudorandom number. Subclass should
  85.      * override this, as this is used by all other methods.
  86.      *
  87.      * @param   bits random bits
  88.      * @return  the next pseudorandom value from this random number generator's sequence.
  89.      * @since   JDK1.1
  90.      */
  91.     synchronized protected int next(int bits) {
  92.         long nextseed = (seed * multiplier + addend) & mask;
  93.         seed = nextseed;
  94.         return (int)(nextseed >>> (48 - bits));
  95.     }
  96.  
  97.     private static final int BITS_PER_BYTE = 8;
  98.     private static final int BYTES_PER_INT = 4;
  99.  
  100.     /**
  101.      * Generates a user specified number of random bytes.
  102.      *
  103.      * @since   JDK1.1
  104.      */
  105.     public void nextBytes(byte[] bytes) {
  106.     int numRequested = bytes.length;
  107.  
  108.     int numGot = 0, rnd = 0;
  109.  
  110.     while (true) {
  111.         for (int i = 0; i < BYTES_PER_INT; i++) {
  112.         if (numGot == numRequested)
  113.             return;
  114.  
  115.         rnd = (i==0 ? next(BITS_PER_BYTE * BYTES_PER_INT)
  116.                     : rnd >> BITS_PER_BYTE);
  117.         bytes[numGot++] = (byte)rnd;
  118.         }
  119.     }
  120.     }
  121.  
  122.     /**
  123.      * Returns the next pseudorandom, uniformly distributed <code>int</code>
  124.      * value from this random number generator's sequence.
  125.      *
  126.      * @return  the next pseudorandom, uniformly distributed <code>int</code>
  127.      *          value from this random number generator's sequence.
  128.      * @since   JDK1.0
  129.      */
  130.     public int nextInt() {  return next(32); }
  131.  
  132.     /**
  133.      * Returns the next pseudorandom, uniformly distributed <code>long</code>
  134.      * value from this random number generator's sequence.
  135.      *
  136.      * @return  the next pseudorandom, uniformly distributed <code>long</code>
  137.      *          value from this random number generator's sequence.
  138.      * @since   JDK1.0
  139.      */
  140.     public long nextLong() {
  141.         // it's okay that the bottom word remains signed.
  142.         return ((long)(next(32)) << 32) + next(32);
  143.     }
  144.  
  145.     /**
  146.      * Returns the next pseudorandom, uniformly distributed <code>float</code>
  147.      * value between <code>0.0</code> and <code>1.0</code> from this random
  148.      * number generator's sequence.
  149.      *
  150.      * @return  the next pseudorandom, uniformly distributed <code>float</code>
  151.      *          value between <code>0.0</code> and <code>1.0</code> from this
  152.      *          random number generator's sequence.
  153.      * @since   JDK1.0
  154.      */
  155.     public float nextFloat() {
  156.         int i = next(24);
  157.         return i / ((float)(1 << 24));
  158.     }
  159.  
  160.     /**
  161.      * Returns the next pseudorandom, uniformly distributed 
  162.      * <code>double</code> value between <code>0.0</code> and
  163.      * <code>1.0</code> from this random number generator's sequence.
  164.      *
  165.      * @return  the next pseudorandom, uniformly distributed 
  166.      *          <code>double</code> value between <code>0.0</code> and
  167.      *          <code>1.0</code> from this random number generator's sequence.
  168.      * @since   JDK1.0
  169.      */
  170.     public double nextDouble() {
  171.         long l = ((long)(next(26)) << 27) + next(27);
  172.         return l / (double)(1L << 53);
  173.     }
  174.  
  175.     private double nextNextGaussian;
  176.     private boolean haveNextNextGaussian = false;
  177.  
  178.     /**
  179.      * Returns the next pseudorandom, Gaussian ("normally") distributed
  180.      * <code>double</code> value with mean <code>0.0</code> and standard
  181.      * deviation <code>1.0</code> from this random number generator's sequence.
  182.      *
  183.      * @return  the next pseudorandom, Gaussian ("normally") distributed
  184.      *          <code>double</code> value with mean <code>0.0</code> and
  185.      *          standard deviation <code>1.0</code> from this random number
  186.      *          generator's sequence.
  187.      * @since   JDK1.0
  188.      */
  189.     synchronized public double nextGaussian() {
  190.         // See Knuth, ACP, Section 3.4.1 Algorithm C.
  191.         if (haveNextNextGaussian) {
  192.             haveNextNextGaussian = false;
  193.             return nextNextGaussian;
  194.         } else {
  195.             double v1, v2, s;
  196.             do { 
  197.                 v1 = 2 * nextDouble() - 1; // between -1 and 1
  198.                 v2 = 2 * nextDouble() - 1; // between -1 and 1 
  199.                 s = v1 * v1 + v2 * v2;
  200.             } while (s >= 1);
  201.             double multiplier = Math.sqrt(-2 * Math.log(s)/s);
  202.             nextNextGaussian = v2 * multiplier;
  203.             haveNextNextGaussian = true;
  204.             return v1 * multiplier;
  205.         }
  206.     }
  207. }     
  208.