Java 将两个整数转换为从 1 到 0 的双精度数
Java convert two integers to a double from 1 to 0
我正在使用生成随机整数的 ISAAC 实现。我需要用这些整数创建一个高斯值。首先,我需要将它们更改为从 0 到 1 的双精度值。我如何在 Java 中执行此操作?到目前为止,这是我将整数转换为双精度的内容,但它仍然需要处于正态分布中。我还使用 java.util.Random.nextGaussian() 逻辑将双精度转换为高斯。
public double nextDouble() {
long l = ((long)(nextInt()) << 32) + nextInt();
return Double.longBitsToDouble(l);
}
最快的方法(cpu 循环方式)是什么?
如果您一定要使用 ISAAC,请使用为您提供 nextLong()
作为原语的 64 位版本。然后生成一个双精度
protected static final double DOUBLE_NORM = 1.0 / (1L << 53);
public double nextDouble() {
return (nextLong() >>> 11) * DOUBLE_NORM;
}
从那里您可以继续对 nextGaussian()
方法使用 Marsaglia 的极坐标方法,与 java.util.Random
中的方法相同
编辑:几年前我测试过 32 位和 64 位 ISAAC。当然,我不记得确切的数字,但如果您真的需要 64 个随机位,您可能会惊讶于 64 位版本可以获得多少吞吐量。
编辑 2:如果您还需要 32 个随机位作为整数,您当然会浪费 64 位算法的大量工作(这里 32 位算法肯定更快)。在我的工作中,我主要需要双打,所以 64 位是可行的(对我来说)。
编辑 3:nextFloat()
将是
protected static final float FLOAT_NORM = 1.0F / (1 << 24);
public float nextFloat() {
return (nextLong() >>> 40) * FLOAT_NORM;
}
将 64 位长转换为 U(0,1) 不是一项简单的任务。我建议阅读 here.
据我所知,在 Java 世界中 scalb
等同于 ldexp
,因此代码为
public double nextDouble() {
return Math.scalb((double)nextLong(), -64);
}
我正在使用生成随机整数的 ISAAC 实现。我需要用这些整数创建一个高斯值。首先,我需要将它们更改为从 0 到 1 的双精度值。我如何在 Java 中执行此操作?到目前为止,这是我将整数转换为双精度的内容,但它仍然需要处于正态分布中。我还使用 java.util.Random.nextGaussian() 逻辑将双精度转换为高斯。
public double nextDouble() {
long l = ((long)(nextInt()) << 32) + nextInt();
return Double.longBitsToDouble(l);
}
最快的方法(cpu 循环方式)是什么?
如果您一定要使用 ISAAC,请使用为您提供 nextLong()
作为原语的 64 位版本。然后生成一个双精度
protected static final double DOUBLE_NORM = 1.0 / (1L << 53);
public double nextDouble() {
return (nextLong() >>> 11) * DOUBLE_NORM;
}
从那里您可以继续对 nextGaussian()
方法使用 Marsaglia 的极坐标方法,与 java.util.Random
编辑:几年前我测试过 32 位和 64 位 ISAAC。当然,我不记得确切的数字,但如果您真的需要 64 个随机位,您可能会惊讶于 64 位版本可以获得多少吞吐量。
编辑 2:如果您还需要 32 个随机位作为整数,您当然会浪费 64 位算法的大量工作(这里 32 位算法肯定更快)。在我的工作中,我主要需要双打,所以 64 位是可行的(对我来说)。
编辑 3:nextFloat()
将是
protected static final float FLOAT_NORM = 1.0F / (1 << 24);
public float nextFloat() {
return (nextLong() >>> 40) * FLOAT_NORM;
}
将 64 位长转换为 U(0,1) 不是一项简单的任务。我建议阅读 here.
据我所知,在 Java 世界中 scalb
等同于 ldexp
,因此代码为
public double nextDouble() {
return Math.scalb((double)nextLong(), -64);
}