問題描述
盡管通過 srand()
使用種子,但通常不贊成使用 rand()
.為什么會是這樣?有哪些更好的替代方案?
Usage of rand()
is usually frowned upon despite using a seed via srand()
. Why would that be the case? What better alternatives are available?
推薦答案
這個故事有兩個部分.
首先,rand
是一個偽隨機數(shù)生成器.這意味著它取決于種子.對于給定的種子,它總是給出相同的序列(假設(shè)實現(xiàn)相同).這使得它不適合某些安全性非常重要的應(yīng)用程序.但是這并不特定于rand
.這是任何偽隨機生成器的問題.并且肯定有很多類別的問題可以接受偽隨機生成器.真隨機生成器有其自身的問題(效率、實現(xiàn)、熵),因此對于與安全無關(guān)的問題,通常使用偽隨機生成器.
First, rand
is a pseudorandom number generator. This means it depends on a seed. For a given seed it will always give the same sequence (assuming the same implementation). This makes it not suitable for certain applications where security is of a great concern. But this is not specific to rand
. It's an issue with any pseudo-random generator. And there are most certainly a lot of classes of problems where a pseudo-random generator is acceptable. A true random generator has its own issues (efficiency, implementation, entropy) so for problems that are not security related most often a pseudo-random generator is used.
所以您分析了您的問題并得出結(jié)論,偽隨機生成器是解決方案.在這里,我們遇到了 C 隨機庫(包括 rand
和 srand
)的真正麻煩,這些庫是特定于它的,并使其過時(又名:您應(yīng)該從不使用 rand
和 C 隨機庫的原因).
So you analyzed your problem and you conclude a pseudo-random generator is the solution. And here we arrive to the real troubles with the C random library (which includes rand
and srand
) that are specific to it and make it obsolete (a.k.a.: the reasons you should never use rand
and the C random library).
一個問題是它有全局狀態(tài)(由
srand
設(shè)置).這使得無法同時使用多個隨機引擎.它還使多線程任務(wù)變得非常復(fù)雜.
One issue is that it has a global state (set by
srand
). This makes it impossible to use multiple random engines at the same time. It also greatly complicates multithreaded tasks.
其中最明顯的問題是缺少分發(fā)引擎:rand
給你一個區(qū)間[0 RAND_MAX]代碼>.在這個區(qū)間是一致的,也就是說這個區(qū)間的每個數(shù)字出現(xiàn)的概率都是一樣的.但大多數(shù)情況下,您需要一個特定時間間隔內(nèi)的隨機數(shù).假設(shè)
[0, 1017]
.一個常用的(也很簡單的)公式是 rand() % 1018
.但問題在于,除非 RAND_MAX
是 1018
的精確倍數(shù),否則您不會得到均勻分布.
The most visible problem of it is that it lacks a distribution engine: rand
gives you a number in interval [0 RAND_MAX]
. It is uniform in this interval, which means that each number in this interval has the same probability to appear. But most often you need a random number in a specific interval. Let's say [0, 1017]
. A commonly (and naive) used formula is rand() % 1018
. But the issue with this is that unless RAND_MAX
is an exact multiple of 1018
you won't get an uniform distribution.
另一個問題是rand
的實現(xiàn)質(zhì)量.這里還有其他答案比我更詳細地說明了這一點,所以請閱讀它們.
Another issue is the Quality of Implementation of rand
. There are other answers here detailing this better than I could, so please read them.
在現(xiàn)代 C++ 中,您絕對應(yīng)該使用 <random>
中的 C++ 庫,它帶有多個定義良好的隨機引擎以及整數(shù)和浮點類型的各種分布.
In modern C++ you should definitely use the C++ library from <random>
which comes with multiple random well-defined engines and various distributions for integer and floating point types.
這篇關(guān)于為什么 rand() 的使用被認為是不好的?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!