implement java.util.Random and java.lang.Math.random in Java

This commit is contained in:
Joel Dice 2008-03-20 18:39:25 -06:00
parent 9fe2cbff43
commit 8e1ec5794f
3 changed files with 47 additions and 39 deletions

View File

@ -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<double>(rand()) / static_cast<double>(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)
{

View File

@ -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);

View File

@ -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);
}
}