Erlang - 随机数生成器

发布于 2024-10-16 23:11:11 字数 293 浏览 1 评论 0原文

我正在使用以下内容生成一个近乎随机的数字。

3> erlang:ref_to_list(make_ref()).

"#Ref<0.0.0.36>"

我想要的是 00036

嗯,这是我在上一篇文章中被告知我可以做的。我发现从 make ref 中提取数字并不那么容易。

任何人都可以展示它是如何轻松完成的,或者可能推荐另一种解决方案。

请记住,在相同的几纳秒内调用时,使用 random:seed() 并不是随机的。

问候

I am using the following to generate a near random number.

3> erlang:ref_to_list(make_ref()).

"#Ref<0.0.0.36>"

What I want is 00036

Well it was what I had been informed I could do in a previous post. It occurred to me that it is not so easy to extract the numbers from make ref.

Can anyone show how it is easily done, or possibly recommend another solution.

Keep in mind that using random:seed() is not random when called within the same few nano seconds.

Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

相思故 2024-10-23 23:11:11

注意:从 OTP 18 开始 erlang:now/0 random 模块已弃用,OTP 20将删除 随机 模块。请参阅Erlang 中的时间和时间校正 了解更多详细信息。此外,如果您使用 rand:uniform/0,则不再需要执行每个进程的种子设定。以下内容保留原样,供参考。


问题是您错误地使用了randomrandom:seed/0 将始终使用相同的种子为随机数生成器提供种子。这对你想要的东西来说并不好。相反,您可以使用 random:seed(erlang:now()) 来使用另一个数字(即当前时间)作为种子。

“如果两个电话非常接近,会发生什么?”你可能会问。好吧,Erlang 的人考虑到了这一点,所以 now/0 保证总是返回递增的数字:

返回元组 {MegaSecs, Secs, MicroSecs}
自 1970 年 1 月 1 日 00:00 GMT(零时)起经过的时间
假设底层操作系统支持这一点。否则,一些
选择其他时间点。 还可以保证子
对此 BIF 的频繁调用会返回不断增加的值。

因此,now()的返回值可用于生成
唯一的时间戳,并且如果在紧密循环中调用它
快速机器节点的时间可能会出现偏差。

(强调我的)

另请注意,random PRNG 是每个进程的,因此您应该始终通过播种器调用来启动进程:

init([..]) ->
  random:seed(erlang:now()),
  [..]
  {ok, #state { [..] }}.

为此使用引用也许是可能的,但我认为不可能是一个可行的。该解决方案经过了 erlang:ref_to_list/1 并且它并不漂亮。

Note: from OTP 18 erlang:now/0 and random module are deprecated, and OTP 20 will remove the random module. See Time and Time Correction in Erlang for the further details. Also, you no longer need to do the per-process seeding if you use rand:uniform/0. The following is left as is for reference.


The problem is that you are using random incorrectly. random:seed/0 will seed the random number generator with the very same seed always. This is not good for what you want. Rather, you can use random:seed(erlang:now()) to seed it with another number, namely the current time.

"What happens if two calls come very close?" you may ask. Well, the Erlang guys thought about this, so now/0 is guaranteed to always return increasing numbers:

Returns the tuple {MegaSecs, Secs, MicroSecs} which is the
elapsed time since 00:00 GMT, January 1, 1970 (zero hour) on the
assumption that the underlying OS supports this. Otherwise, some
other point in time is chosen. It is also guaranteed that subse‐
quent calls to this BIF returns continuously increasing values.

Hence, the return value from now() can be used to generate
unique time-stamps, and if it is called in a tight loop on a
fast machine the time of the node can become skewed.

(emphasis mine)

Also note that the random PRNG is per-process, so you should always start your process up with a seeder call:

init([..]) ->
  random:seed(erlang:now()),
  [..]
  {ok, #state { [..] }}.

Using references for this is perhaps possible, but I don't think it is a viable one. The solution goes over erlang:ref_to_list/1 and it is not pretty.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文