【问题标题】:What is the purpose of this magic number?这个神奇数字的目的是什么?
【发布时间】:2014-05-04 08:22:54
【问题描述】:

以下sn-p代码取自a Pseudo-random number generator (written in ActionScript 3)

public function random():Number {
    _currentSeed = (_currentSeed * 16807) % 2147483647);
    return (_currentSeed/0x7FFFFFFF) + 0.000000000233;
}

第一行代码很容易理解,是标准的linear congruential generator,乘数为16807。第二行的第一部分将生成的整数转换为大致介于01 之间的浮点数。

但是,第二行的最后一部分+ 0.000000000233 的目的是什么?在这样的 RNG 中是否有必要,还是有不同的目的?

【问题讨论】:

  • 我已经为 AS3 标记了这个,但我确信这个问题也适用于许多其他编程语言。
  • Psstt 从不问魔法;这很神奇。

标签: actionscript-3 random magic-numbers


【解决方案1】:

如果您查看公式的其余部分,您会发现_currentSeed 的值0 将始终产生相同的0 值。添加(0.5/0x7fffffff) 可以防止它卡在0 上,但也足够小以防止它返回值>= 1

公平地说,我在 6 年多前编写了该代码,所以我可能记错了,但我很确定这是原因所在。

【讨论】:

  • 嗯,这在理论上是有道理的,但是,0.000000000233 的值实际上从未添加到 _currentSeed 的值中,它只是添加到函数返回的浮点数中。事实上,如果_currentSeed 曾经设置为0,它仍然会一直返回0,即使你的“保护”到位。
【解决方案2】:

算法的主体是well-known 素数模乘法线性同余生成器。所有这些前缀形容词都意味着它在没有泛化 LCGs 所具有的附加术语的情况下实现了最大循环长度,因此 PMMLCG 可以追溯到 1950 年代,因为您每次调用少做一次操作。您永远不应该将_currentSeed 初始化为零,并且该算法被设计为在正确实施和播种的情况下永远不会产生零或负数,因为它基于整数运算,这是精确的。 (正确的实现意味着确保结果不受整数溢出的影响。早在 1959 年,Linus Schrage 就用 FORTRAN 编写了一个可移植的算法来实现这一点,同时还有一个简单的测试,其中包含 1000 次迭代后种子值应该是多少。 )

幻数略大于(1/2) / 0x7fffffff,因此它不应将返回值推高超过 1。由于它没有被添加到 _currentSeed,因此它在避免定点行为方面没有任何作用如果 _currentSeed 曾被设置为零,则会发生这种情况。老实说,我看不出它完成了很多事情。

【讨论】:

    【解决方案3】:

    我认为,出于某种原因,_currentSeed 可能是负值,因为_currentSeed 是有符号整数。在值中添加0.000000000233 (0.5/0x7fffffff) 可以避免这种情况。

    【讨论】:

    • 嗯,实际上,看看我链接到的其余代码,_currentSeed 是一个 无符号 整数。即使它已签署,并且一直是负数,添加这么小的值也永远不足以使其成为正数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 2021-12-17
    • 1970-01-01
    • 2014-01-19
    • 1970-01-01
    • 2012-12-30
    相关资源
    最近更新 更多