home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 October / Chip_1997-10_cd.bin / tema / sybase / powerj / java.z / Random.java < prev    next >
Text File  |  1996-05-03  |  5KB  |  171 lines

  1. /*
  2.  * @(#)Random.java    1.6 95/12/04  
  3.  *
  4.  * Copyright (c) 1995 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19.  
  20. package java.util;
  21.  
  22. /**
  23.  * A Random class generates a stream of pseudo-random numbers.<p>
  24.  *
  25.  * To create a new random number generator, use one of the following methods:
  26.  * <pre>
  27.  *     new Random()       
  28.  *     new Random(long seed)
  29.  * </pre>
  30.  * The form <CODE>new Random()</CODE> initializes the generator
  31.  * to a value based on the current time.  The form 
  32.  * <CODE>new Random(long seed)</CODE> seeds the random number generator with
  33.  * a specific initial value;  use this if an application requires a repeatable
  34.  * stream of pseudo-random numbers. <p>
  35.  *
  36.  * The random number generator uses a 48-bit seed, which is modified using
  37.  * a linear congruential formula. See Donald Knuth, <CITE>The Art of Computer 
  38.  * Programming, Volume 2</CITE>, Section 3.2.1.
  39.  * The generator's seed can be reset with the following method:
  40.  * <pre>
  41.  *    setSeed(long seed)
  42.  * </pre>
  43.  *
  44.  * To create a pseudo-random number, use one of the following functions:
  45.  * <pre>
  46.  *    nextInt()
  47.  *    nextLong()
  48.  *    nextFloat()
  49.  *    nextDouble()
  50.  *    nextGaussian()
  51.  * </pre>
  52.  *
  53.  * @see Math#random
  54.  * @version     1.1, 27 Jul 1995
  55.  * @author    Frank Yellin
  56.  
  57.  */
  58. public
  59. class Random {
  60.     private long seed;
  61.     private final static long multiplier = 0x5DEECE66DL;
  62.     private final static long addend = 0xBL;
  63.     private final static long mask = (1L << 48) - 1;
  64.  
  65.     /** 
  66.      * Creates a new random number generator.  Its seed will be 
  67.      * initialized to a value based on the current time.
  68.      */
  69.     public Random() { this(System.currentTimeMillis()); }
  70.  
  71.     /** 
  72.      * Creates a new random number generator using a single 
  73.      * <CODE>long</CODE> seed.
  74.      * @param seed the initial seed
  75.      * @see Random#setSeed
  76.      */
  77.     public Random(long seed) {
  78.         setSeed(seed);
  79.         haveNextNextGaussian = false;
  80.     }
  81.  
  82.  
  83.     /**
  84.      * Sets the seed of the random number generator using a single 
  85.      * <CODE>long</CODE> seed.
  86.      * @param seed the initial seed
  87.      */
  88.     synchronized public void setSeed(long seed) {
  89.         this.seed = (seed ^ multiplier) & mask;
  90.     }
  91.  
  92.  
  93.     /**
  94.      * Generates the next pseudorandom number.
  95.      * @param bits random bits
  96.      */
  97.     synchronized private int next(int bits) {
  98.         long nextseed = (seed * multiplier + addend) & mask;
  99.         seed = nextseed;
  100.         return (int)(nextseed >>> (48 - bits));
  101.     }
  102.  
  103.     /**
  104.      * Generates a pseudorandom uniformally distributed 
  105.      * <CODE>int</CODE> value.
  106.      * @return an integer value.
  107.      */
  108.     public int nextInt() {  return next(32); }
  109.  
  110.     /**
  111.      * Generate a pseudorandom uniformally distributed <CODE>long</CODE> value.
  112.      * @return A long integer value
  113.      */
  114.     public long nextLong() {
  115.         // it's okay that the bottom word remains signed.
  116.         return (next(32) << 32L) + next(32);
  117.     }
  118.  
  119.     /**
  120.      * Generates a pseudorandom uniformally distributed 
  121.      * <CODE>float</CODE> value between 0.0 and 1.0.
  122.      * @return a <CODE>float</CODE> between 0.0 and 1.0 .
  123.      */
  124.     public float nextFloat() {
  125.         int i = next(30);
  126.         return i / ((float)(1 << 30));
  127.     }
  128.  
  129.     /**
  130.      * Generates a pseudorandom uniformally distributed 
  131.      * <CODE>double</CODE> value between 0.0 and 1.0.
  132.      * @return a <CODE>float</CODE> between 0.0 and 1.0 .
  133.      */
  134.     public double nextDouble() {
  135.         long l = ((long)(next(27)) << 27) + next(27);
  136.         return l / (double)(1L << 54);
  137.     }
  138.  
  139.     private double nextNextGaussian;
  140.     private boolean haveNextNextGaussian = false;
  141.  
  142.     /**
  143.      * Generates a pseudorandom Gaussian distributed 
  144.      * <CODE>double</CODE> value with mean 0.0 and standard 
  145.      * deviation 1.0.
  146.      * @return a Gaussian distributed <CODE>double</CODE>.
  147.      */
  148.     synchronized public double nextGaussian() {
  149.         // See Knuth, ACP, Section 3.4.1 Algorithm C.
  150.         if (haveNextNextGaussian) {
  151.             haveNextNextGaussian = false;
  152.             return nextNextGaussian;
  153.         } else {
  154.             double v1, v2, s;
  155.             do { 
  156.                 v1 = 2 * nextDouble() - 1; // between -1 and 1
  157.                 v2 = 2 * nextDouble() - 1; // between -1 and 1 
  158.                 s = v1 * v1 + v2 * v2;
  159.             } while (s >= 1);
  160.             double multiplier = Math.sqrt(-2 * Math.log(s)/s);
  161.             nextNextGaussian = v2 * multiplier;
  162.             haveNextNextGaussian = true;
  163.             return v1 * multiplier;
  164.         }
  165.     }
  166. }     
  167.  
  168.  
  169.  
  170.  
  171.