Java将两个整数从1转换为0

时间:2016-08-31 22:15:32

标签: java random int double gaussian

我正在使用生成随机整数的ISAAC实现。我需要用这些整数创建一个高斯值。首先,我需要将它们从0改为1。我怎么能用Java做到这一点?这是我到目前为止将int转换为double的内容,但它仍然需要处于正态分布状态。我也使用java.util.Random.nextGaussian()逻辑将double转换为Gaussian。

public double nextDouble() {
    long l = ((long)(nextInt()) << 32) + nextInt();
    return Double.longBitsToDouble(l);
}

执行此操作的最快方式(cpu周期)是什么?

2 个答案:

答案 0 :(得分:3)

如果您想一直使用ISAAC,请使用64位版本,它将nextLong()作为基元。然后生成一个双精简单

protected static final double DOUBLE_NORM = 1.0 / (1L << 53);

public double nextDouble() {
    return (nextLong() >>> 11) * DOUBLE_NORM;
}

从那里开始,你可以继续使用Marsaglia的极性方法来实现nextGaussian()方法,就像在java.util.Random中一样。

编辑:我测试了32位&amp;几年前64位ISAAC。当然,我不记得确切的数字,但如果你真的需要64位随机位,你可能会惊讶地发现使用64位版本可以获得更多的吞吐量。

编辑2 :如果整数也需要32个随机位,那么你当然会浪费大量的64位算法(32位在这里肯定更快)。在我的工作中,我需要大多数双打,因此64bit是可行的方式(对我而言)。

编辑3 nextFloat()将是

protected static final float FLOAT_NORM = 1.0F / (1 << 24);

public float nextFloat() {
    return (nextLong() >>> 40) * FLOAT_NORM;
}

答案 1 :(得分:2)

将64位长转换为U(0,1)并不是一项简单的任务。我建议您阅读here

据我所知,在Java世界scalb相当于ldexp,所以代码将是

public double nextDouble() {
    return Math.scalb((double)nextLong(), -64);
}