【问题标题】:Java convert two integers to a double from 1 to 0Java 将两个整数转换为从 1 到 0 的双精度数
【发布时间】:2016-08-31 22:15:31
【问题描述】:

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

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

最快的方法是什么(cpu 周期)?

【问题讨论】:

  • 你的问题不清楚。试着举几个例子。此外,正态分布 mu=0 sigma=1 可能会产生 (-1, 1) 范围之外的值。
  • 我会使用 64 位 ISAAC,然后你可以简单地使用 (nextLong() &gt;&gt;&gt; 11) * (1.0 / (1L &lt;&lt; 53))
  • 另一个问题是您为什么要使用 ISAAC。速度?您的随机数需要具备什么质量?我不会推荐 ISAAC 用于高维科学模拟(更不用说密码学了)。
  • @StefanZobel 这可以与我原始帖子中的“long l”结合起来创建所需的双精度值。请改写为答案,我将奖励。谢谢!
  • 当然。但是你有 64 位的 ISAAC 吗?调用 32 位 ISAAC 两次只是为了生成一个 long 是非常低效的。

标签: java random int double gaussian


【解决方案1】:

如果您想通过任何方式使用 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 位和 64 位 ISAAC。当然,我不记得确切的数字,但如果你真的需要 64 个随机位,你可能会惊讶于 64 位版本可以获得多少吞吐量。

编辑 2:如果您还需要 32 个随机位来表示整数,那么您当然会在 64 位算法上浪费大量工作(这里 32 位肯定更快)。在我的工作中,我主要需要双打,所以 64 位(对我来说)是要走的路。

编辑 3nextFloat() 将是

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

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

【讨论】:

  • 为了清楚起见,您能否将整数转换为浮点数添加到您的答案中?谢谢!
  • 谢谢,但你可以让它使用 int 吗?我对运营商感到困惑。示例:return (nextInt() >>> 16???) * FLOAT_NORM;
  • @Colby 一个浮点数需要 24 个随机位,所以应该是 32 - 8 = 24。
  • @Colby 因此(nextInt() &gt;&gt;&gt; 8) * FLOAT_NORM
【解决方案2】:

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

据我所知,在 Java 世界中,scalb 等同于 ldexp,所以代码是

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

【讨论】:

  • 感谢您的链接,这很有趣。然而,老实说,我从来没有见过关心这个的 Java PRNG 实现 :) 知道性能差异有多大也会很有趣。你知道吗?
  • @StefanZobel On light RNG ldexp/scalb 让它慢了很多。在像 Mersenne Twister 这样的重型 RNG 上,它会增加几个百分比的 RNG 跟注。但整体应用程序放缓是在噪音中。我说的是在 Fortran/C/C++ 中的蒙特卡洛经验。不知道 Java 的好坏...
  • 是的,这是有道理的。谢谢提供信息。我打算为 Java 运行一点 JMH 微基准测试。 AFAIK,scalb 目前不是 JVM HotSpot intrinsic,所以我很好奇。那么,使用ldexp/scalb 而不是头脑简单的方法,对于像 MC(MC) 这样的事情真的有影响吗?
猜你喜欢
  • 1970-01-01
  • 2014-11-10
  • 1970-01-01
  • 2014-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-13
相关资源
最近更新 更多