c++ - 関数内 - srand time_t



rand()は時々同じものを連続して返しますか? (3)

私は研究をした

私のコンパイラ( msvc10 )のrand実装が他のc / c ++コンパイラと同じようにLinear合同ジェネレータを使用していることを発見しました

線形合同ジェネレータ

線形合同ジェネレータは、繰り返しメソッドを使用します。

ptd - > _ holdrand(n)はptd - > _ holdrand(n + 1)と決して等しくありませんが、modの結果は等しくなります。

msvcの実装

@nosは結果を示します

return( ((ptd->_holdrand = ptd->_holdrand * 214013L + 2531011L) >> 16) & 0x7fff );

ptd->_holdrand = 2375716238;
return 3482; (2375716238 >> 16) % 32768
ptd->_holdrand = 228240921;
return 3482; (228240921 >> 16) % 32768

最終的な答えはrand()が私の本能と同じ値を何回か返すということです。

私はちょうど興味があります、シングルスレッドプログラムは、 rand()への2回の連続した呼び出しに対して同じ戻り値を得ることができますか?

だから、この主張はいつまでも発火するだろうか?

assert(rand() != rand());

Answer #1

理想的にランダムなrand()関数は、2回呼び出された場合、毎回1.0 / RAND_MAX確率で同じ結果を1.0 / RAND_MAXます。

しかし、 rand()は真の乱数ジェネレータではありません。 通常、 線形合同型の擬似乱数生成器 (PRNG)です。

連続した呼び出しでPRNGの内部状態を繰り返さないでください。 もしそうであれば、 rand()は永遠に同じ番号に固執するでしょう。 これは、 ミドルスクエア法のように設計されていないアルゴリズムで起こる可能性があります。

しかし、PRNG実装の一部(ただしすべてではない)は、内部状態が出力よりも多くのビットを持ちます。 たとえば、 java.util.Randomは48ビットの内部状態を使用しますが、その出力には最上位32ビットしか含まれません。 この場合、同じ内部状態を持たずに同じ出力を連続して2回得ることは(少なくとも論理的に)可能です。


Answer #2

良い乱数ジェネレータ 、同じ値を2回連続して返すことがあります。 0 <= r <2 ^ 31の正の整数を返します。 2つの連続する数字が同じである可能性は、完全な乱数生成器の場合、約20億分の1になります。 1000億回のコールで同じ2つの連続した番号が得られない可能性は、10 ^ 15に1つです。





random