From 8e1ec5794f75608201ec9c31ae1fe3be3a522a50 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 20 Mar 2008 18:39:25 -0600 Subject: [PATCH] implement java.util.Random and java.lang.Math.random in Java --- classpath/java-lang.cpp | 25 ------------------ classpath/java/lang/Math.java | 14 +++------- classpath/java/util/Random.java | 47 ++++++++++++++++++++++++++++++--- 3 files changed, 47 insertions(+), 39 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 82ad349756..967deaadb4 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -519,31 +519,6 @@ Java_java_lang_Math_pow(JNIEnv*, jclass, jdouble val, jdouble exp) return pow(val, exp); } -extern "C" JNIEXPORT void JNICALL -Java_java_lang_Math_natRandomInitialize(JNIEnv*, jclass, jlong val) -{ -#ifdef WIN32 - srand(val); -#else - srand48(val); -#endif -} - -extern "C" JNIEXPORT jdouble JNICALL -Java_java_lang_Math_natRandom(JNIEnv*, jclass) -{ -#ifdef WIN32 - double r = static_cast(rand()) / static_cast(RAND_MAX); - if (r < 0 or r >= 1) { - return 0; - } else { - return r; - } -#else - return drand48(); -#endif -} - extern "C" JNIEXPORT jdouble JNICALL Java_java_lang_Math_floor(JNIEnv*, jclass, jdouble val) { diff --git a/classpath/java/lang/Math.java b/classpath/java/lang/Math.java index 705bd6f948..44eea9db17 100644 --- a/classpath/java/lang/Math.java +++ b/classpath/java/lang/Math.java @@ -10,10 +10,12 @@ package java.lang; +import java.util.Random; + public final class Math { public static final double E = 2.718281828459045; public static final double PI = 3.141592653589793; - private static boolean randomInitialized = false; + private static final Random random = new Random(); private Math() { } @@ -74,17 +76,9 @@ public final class Math { } public static double random() { - if (randomInitialized) { - natRandomInitialize(System.currentTimeMillis()); - randomInitialized = true; - } - return natRandom(); + return random.nextDouble(); } - public static native void natRandomInitialize(long val); - - public static native double natRandom(); - public static native double floor(double v); public static native double ceil(double v); diff --git a/classpath/java/util/Random.java b/classpath/java/util/Random.java index 2ab3f95a45..a513fd5522 100644 --- a/classpath/java/util/Random.java +++ b/classpath/java/util/Random.java @@ -11,15 +11,54 @@ package java.util; public class Random { - public int nextInt(int n) { - return nextInt() % n; + private static final long Mask = 0x5DEECE66DL; + + private static long nextSeed = 0; + + private long seed; + + public Random(long seed) { + setSeed(seed); + } + + public Random() { + setSeed((nextSeed++) ^ System.currentTimeMillis()); + } + + public void setSeed(long seed) { + this.seed = (seed ^ Mask) & ((1L << 48) - 1); + } + + protected int next(int bits) { + seed = ((seed * Mask) + 0xBL) & ((1L << 48) - 1); + return (int) (seed >>> (48 - bits)); + } + + public int nextInt(int limit) { + if (limit <= 0) { + throw new IllegalArgumentException(); + } + + if ((limit & -limit) == limit) { + // limit is a power of two + return (int) ((limit * (long) next(31)) >> 31); + } + + int bits; + int value; + do { + bits = next(31); + value = bits % limit; + } while (bits - value + (limit - 1) < 0); + + return value; } public int nextInt() { - return (int)(Math.random()*Integer.MAX_VALUE); + return next(32); } public double nextDouble() { - return Math.random(); + return (((long) next(26) << 27) + next(27)) / (double) (1L << 53); } }