蒙特卡洛大都会的 RNG 浮动范围

计算科学 浮点 蒙特卡洛 随机数生成
2021-12-02 00:27:28

我有一个强大的 RNG,可以生成随机的 32 位(无符号)整数。众所周知,对于 Metropolis MC 模拟,需要 0 到 1 之间的随机数来确定移动的接受/拒绝,因此我需要将我的 32 位 int 转换为(双精度)浮点值。

我的问题是将我的 32 位 int 转换为浮点数的最佳实践是什么?我想我有以下两个选择:

  • (double) getRandomNumber() / 4294967295(2^32 - 1); 范围 [0,1]
  • (double) getRandomNumber() / 4294967296(2^32); 范围 [0,1)

第一个选项看起来很简单,范围为 [0,1]。在 [0,0.5) 范围内将有 2147483648 个值,在 (0.5, 1] 范围内将有 2147483648 个值。

在第二个选项中,我们有一个 [0,1) 的范围,并且 0.5 在 2^32 个可能的浮点数中精确表示。对称性在于 50% 的值在 [0, .49999999977] 范围内,而其他 50% 在 [0.5, .99999999977] 范围内。

我缺少的 int->double 转换中是否有详细信息?这种类型的概率模拟范围的标准做法是什么?是 [0,1]、(0,1]、[0,1) 还是 (0,1)?还是我为一件小事而发火?

注意我已经读过除法比乘法效率低,所以我打算在我的实际实现中预先计算倒数并乘以那个值。

1个回答

我认为你在琐碎的事情上分裂头发。也许对于加密 RNG,这个细节可能很重要,但如果你在这里的选择影响了任何结果,我会感到惊讶。一方面,这种大小的偏差只有在你一次生成 2^30 个数字时才能被检测到,此时你应该考虑使用更长周期的 RNG 序列。

我只会使用 [0,1] 方法,因为恰好得到 0.5 可能会导致一些以后很难找到的讨厌的错误(部分代码使用 <0.5 表示拒绝/接受,其他部分使用 >0.5,几乎每个随机数这仍然可以工作,但是这个错误将是难以重现的东西,并且只能在长时间(因此很重要)运行中抬头)。