这个神奇数字的目的是什么?

时间:2014-05-04 08:22:55

标签: actionscript-3 random magic-numbers

以下代码段摘自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中是否有必要,或者它是否有不同的用途?

3 个答案:

答案 0 :(得分:3)

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

公平地说,我在六年多前写过这段代码,所以我可能记得错了,但我确信这是推理。

答案 1 :(得分:1)

算法的大部分是well-known素数模乘法线性同余生成器。所有这些前缀形容词意味着它实现了最大周期长度而没有广义LCG所具有的附加项,因此PMMLCG可以追溯到1950年代,因为每次调用只减少了一次操作。你永远不应该将_currentSeed初始化为零,并且如果正确实现和播种,算法的设计永远不会产生零或负数,因为它基于整数算术,这是精确的。 (正确的实现意味着确保结果不受整数溢出的影响。一个可移植的算法是由Linus Schrage在1959年在FORTRAN中编写的,还有一个简单的测试,包括1000次迭代后种子值应该是什么。 )

幻数比(1/2) / 0x7fffffff略大,所以它不应该将返回值超过1.因为它没有被添加到_currentSeed,所以它在避免修复时没有任何作用 - 如果将_currentSeed设置为零,则会发生点行为。老实说,我看不出它正在完成任何事情。

答案 2 :(得分:-1)

我认为,出于某种原因,_currentSeed可能是负值,因为_currentSeed是有符号整数。将0.0000000002330.5/0x7fffffff)添加到该值可以避免这种情况。