Back to index

plt-scheme  4.2.1
Random.java
Go to the documentation of this file.
00001 /* Random.java -- a pseudo-random number generator
00002    Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
00003 
00004 This file is part of GNU Classpath.
00005 
00006 GNU Classpath is free software; you can redistribute it and/or modify
00007 it under the terms of the GNU General Public License as published by
00008 the Free Software Foundation; either version 2, or (at your option)
00009 any later version.
00010 
00011 GNU Classpath is distributed in the hope that it will be useful, but
00012 WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with GNU Classpath; see the file COPYING.  If not, write to the
00018 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019 02111-1307 USA.
00020 
00021 Linking this library statically or dynamically with other modules is
00022 making a combined work based on this library.  Thus, the terms and
00023 conditions of the GNU General Public License cover the whole
00024 combination.
00025 
00026 As a special exception, the copyright holders of this library give you
00027 permission to link this library with independent modules to produce an
00028 executable, regardless of the license terms of these independent
00029 modules, and to copy and distribute the resulting executable under
00030 terms of your choice, provided that you also meet, for each linked
00031 independent module, the terms and conditions of the license of that
00032 module.  An independent module is a module which is not derived from
00033 or based on this library.  If you modify this library, you may extend
00034 this exception to your version of the library, but you are not
00035 obligated to do so.  If you do not wish to do so, delete this
00036 exception statement from your version. */
00037 
00038 
00039 package java.util;
00040 
00041 import java.io.Serializable;
00042 
00076 public class Random implements Serializable
00077 {
00087   private boolean haveNextNextGaussian;
00088 
00098   private double nextNextGaussian;
00099 
00107   private long seed;
00108 
00112   private static final long serialVersionUID = 3905348978240129619L;
00113 
00121   public Random()
00122   {
00123     this(System.currentTimeMillis());
00124   }
00125 
00132   public Random(long seed)
00133   {
00134     setSeed(seed);
00135   }
00136 
00151   public synchronized void setSeed(long seed)
00152   {
00153     this.seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
00154     haveNextNextGaussian = false;
00155   }
00156 
00173   protected synchronized int next(int bits)
00174   {
00175     seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
00176     return (int) (seed >>> (48 - bits));
00177   }
00178 
00201   public void nextBytes(byte[] bytes)
00202   {
00203     int random;
00204     // Do a little bit unrolling of the above algorithm.
00205     int max = bytes.length & ~0x3;
00206     for (int i = 0; i < max; i += 4)
00207       {
00208         random = next(32);
00209         bytes[i] = (byte) random;
00210         bytes[i + 1] = (byte) (random >> 8);
00211         bytes[i + 2] = (byte) (random >> 16);
00212         bytes[i + 3] = (byte) (random >> 24);
00213       }
00214     if (max < bytes.length)
00215       {
00216         random = next(32);
00217         for (int j = max; j < bytes.length; j++)
00218           {
00219             bytes[j] = (byte) random;
00220             random >>= 8;
00221           }
00222       }
00223   }
00224 
00238   public int nextInt()
00239   {
00240     return next(32);
00241   }
00242 
00290   public int nextInt(int n)
00291   {
00292     if (n <= 0)
00293       throw new IllegalArgumentException("n must be positive");
00294     if ((n & -n) == n) // i.e., n is a power of 2
00295       return (int) ((n * (long) next(31)) >> 31);
00296     int bits, val;
00297     do
00298       {
00299         bits = next(31);
00300         val = bits % n;
00301       }
00302     while (bits - val + (n - 1) < 0);
00303     return val;
00304   }
00305 
00318   public long nextLong()
00319   {
00320     return ((long) next(32) << 32) + next(32);
00321   }
00322 
00335   public boolean nextBoolean()
00336   {
00337     return next(1) != 0;
00338   }
00339 
00352   public float nextFloat()
00353   {
00354     return next(24) / (float) (1 << 24);
00355   }
00356 
00369   public double nextDouble()
00370   {
00371     return (((long) next(26) << 27) + next(27)) / (double) (1L << 53);
00372   }
00373 
00409   public synchronized double nextGaussian()
00410   {
00411     if (haveNextNextGaussian)
00412       {
00413         haveNextNextGaussian = false;
00414         return nextNextGaussian;
00415       }
00416     double v1, v2, s;
00417     do
00418       {
00419         v1 = 2 * nextDouble() - 1; // Between -1.0 and 1.0.
00420         v2 = 2 * nextDouble() - 1; // Between -1.0 and 1.0.
00421         s = v1 * v1 + v2 * v2;
00422       }
00423     while (s >= 1);
00424     double norm = Math.sqrt(-2 * Math.log(s) / s);
00425     nextNextGaussian = v2 * norm;
00426     haveNextNextGaussian = true;
00427     return v1 * norm;
00428   }
00429 }