C/C++ 中生成特定范围内的随机数
大家在寫 C/C++ 程序時,難免會遇到要求獲取某個范圍內(nèi)的隨機數(shù),我查閱了一些資料后,總結(jié)如下。本文分兩部分,先介紹 C 語言中與隨機數(shù)相關(guān)的兩個函數(shù) srand 和 rand,后介紹 C++ 中的 random 庫,每一部分最后會給出生成特定范圍內(nèi)的隨機數(shù)模板供參考。
1 C 語言中的 srand 和 rand
1.1 實現(xiàn)
下面是 VC 的實現(xiàn),GCC 的實現(xiàn)比 VC 的復(fù)雜,但基本原理是一樣的。 [cpp] view plaincopyprint?第一次接觸 C 語言中的隨機數(shù)時,很疑惑為什么有種子這個玩意,只提供一個產(chǎn)生隨機數(shù)的函數(shù)不就行了嗎,看了上面的源碼后,就明白了,因為計算機不能產(chǎn)生真正的隨機數(shù),只能靠數(shù)學(xué)的方法產(chǎn)生偽隨機數(shù)。srand 函數(shù)的作用是設(shè)置種子,如果不設(shè)置的話種子(上面的 _Randseed)則默認(rèn)初始是1,種子是全局變量。rand 的實現(xiàn)就跟數(shù)論有關(guān)了,上面的實現(xiàn)用的是線性同余法。可以看到它的返回值范圍是 [0, RAND_MAX]。
1.2 time
既然計算機不能產(chǎn)生真正的隨機數(shù),那怎么才能使程序每次運行的結(jié)果不同呢?總得有個隨機的東西,那就借助 time 這個函數(shù)產(chǎn)生種子,引入一個新東西又會帶來一些坑,我早年寫過這種程序:
[cpp] view plaincopyprint?它返回“當(dāng)前時間”,這個“時間“的類型是 time_t,在 VC 中被 typedef 為 unsigned long,標(biāo)準(zhǔn)中只規(guī)定它是個算數(shù)類型,至于它是如何表示時間的未定義。一般是返回?UNIX 時間戳,定義為從格林威治時間1970年01月01日00時00分00秒起至現(xiàn)在的總秒數(shù)。上面的程序執(zhí)行時很快,在一秒內(nèi)完成循環(huán),所以它產(chǎn)生了相同的隨機數(shù)。
1.3 my rand
下面提供兩個生成隨機數(shù)的模板。
[cpp] view plaincopyprint?
2 C++ 中的 random 庫
在 random 庫中有隨機數(shù)發(fā)生器(random engine/generator)和分布(distribution),它們的具體用法我就不在這說了。我個人認(rèn)為 engine 存儲了種子,將 C 語言中的全局種子封裝起來了。uniform distribution 中只存儲了最大值和最小值(即平均分布的兩個參數(shù))。還有個真正的 engine 叫 std::random_device,它根據(jù)機器的各種實時參數(shù)產(chǎn)生隨機數(shù),標(biāo)準(zhǔn)規(guī)定它的實現(xiàn)是可選的,有的編譯器(如 MinGW)目前不支持,產(chǎn)生的還是偽隨機數(shù),不過?VC 及?Linux 平臺上的 GCC?是支持的,下面的程序假設(shè)用戶的編譯器支持。 [cpp] view plaincopyprint?
參考資料
[1] C 標(biāo)準(zhǔn)庫 [2] C 和指針 [3] 隨機數(shù)是騙人的,.Net、Java、C為我作證 [4]?How to generate a random number in C? [5]?Generate random numbers uniformly over an entire range [6]?Generate a random number within range? [7]?C++ random float number generation [8] C++ Primer [9]?How to make sure a function is only called oncefrom: http://blog.csdn.net/Justme0/article/details/41547761
總結(jié)
以上是生活随笔為你收集整理的C/C++ 中生成特定范围内的随机数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C C++编程产生指定范围内的随机数
- 下一篇: python pickle模块