保存/恢复PHP的rand状态()
为了防止长时间运行的预渲染脚本中的内存损坏,我希望能够对我的程序说“好吧,呈现前1000步”。然后我可以看看输出,检查它等。然后我想说“现在生成步骤1,001到10,000”。保存/恢复PHP的rand状态()
我的工作几乎完美。只有一件事我正在努力。
渲染脚本使用rand()
向生成的输出添加熵,srand()
在开始时确保它在重新渲染中保持不变。目前我通过计算调用次数rand()
来“解决”这个问题,然后在开始实际生成之前多次调用它。问题在于它可能非常缓慢,尤其是当我生成了几百万个随机数时。
是否有任何方法可以确定我需要传递给srand()
以继续生成序列的值?这甚至有可能吗?
如果没有,是否有任何方法可以找出确切的算法rand()
正在使用?我真的很喜欢我从srand(43)
得到的地图,并希望尽可能保留它!
编辑:使用Patashu的答案,这是我想出来的:
function rnd() {
static $seed = 42;
$seed = $seed*214013+2531011;
$mod = pow(2,32);
while($seed > $mod) $seed -= $mod;
$rs = floor($seed/65536)&0x7fff;
return floor(2*$rs/0x8000);
}
它依赖于使用花车因为据我可以告诉尾数的51位足够容易以完美的精度存储数字,如果使用位操作符,则整数会被截断或环绕。
这里http://cod.ifies.com/2008/05/php-rand01-on-windows-openssl-rand-on.html本页说明
被警告了PHP的兰特()的源代码,这是不是很漂亮,它是依赖于PHP的怪癖和兰特的OS()实现:)
非常有用的链接,因为它似乎我可以再现这里使用的实际RNG。编辑我的问题以显示我正在使用的代码,它看起来是否适合您? – 2013-02-25 05:06:53
这不是直接回答你的问题,但因为它看起来像你不需要特别“好”随机数,为什么不看看写自己的伪随机数发生器?这样,您可以随时轻松地序列化和反序列化其状态。
像http://en.wikipedia.org/wiki/Random_number_generation#Computational_methods算法的东西,甚至可能会做的伎俩。无论何时开始新的序列,您都可以使用当前时间播种。
这可能是我最好的选择。我会失去我喜欢的地图,但我相信我会找到另一张地图。毕竟只有40亿种子可供选择:p – 2013-02-25 04:23:54
因此,如果我理解正确,我可以使用类似的东西? 'function rnd(){static $ seed = 42; $ seed =(($ seed * 0x43fd43fd + 0xc39ec3)>> 4)&0xffffff;返回$ seed%2;}'得到一个随机的布尔值? – 2013-02-25 04:49:21
@Kolink当然,对我来说很好。它可能不是*非常“随意”的,但它不应该比PHP所做的更糟,并且应该适合您的需求。你也可以尝试一下,看看你得到了什么样的发行。如果你想要更好的东西,你可以尝试实现http://en.wikipedia.org/wiki/Mersenne_twister – 2013-02-25 04:55:25
实际'rand'的实现取决于底层操作系统。这个事实可以有[令人惊讶的效果](http://cod.ifies.com/2008/05/php-rand01-on-windows-openssl-rand-on.html)。 – Gumbo 2013-02-25 04:22:23