为什么 stdlib 中的 rand 不遵循大数定律?
Why does rand from stdlib not follow law of large numbers?
在下面的代码中,我希望骰子作用数十亿次,平均结果恰好是 3.5,高于 3.5 的百分比有时约为 5%,而其他时候(当然有不同的种子) ) 就像 95。但是即使你达到 6040M thows,你也永远不会超过 50%,低于 3.5 的 50%?显然 rand() 有点偏差...
我知道 'real random' 不存在,但真的有这么明显吗?
典型的输出是:
Average: 3.50003 counter: 3427000000 Percentage above: 83.2554 Perc abs above counter: 50.0011
Average: 3.49999 counter: 1093000000 Percentage above: 92.6983 Perc abs above counter: 50.0003
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <unistd.h>
#include <iostream>
using namespace std;
int main ()
{
long long int this_nr;
long long int counter = 0;
long long int above_counter = 0;
long long int below_counter = 0;
long long int above_counter_this = 0;
long long int below_counter_this = 0;
long long int interval_counter = 0;
double avg = 0.0;
srand (time(NULL));
srand (time(NULL));
srand (time(NULL));
cout.precision(6);
while(1) {
this_nr = rand() % 6 + 1; // 0,1,2,3,4,5 or 6
avg = ((double) this_nr + ((double)counter * (double) avg))
/ ((double) counter+1.0);
if (this_nr <= 3) below_counter_this++;
if (this_nr >= 4) above_counter_this++;
if (avg < 3.5) below_counter++;
if (avg > 3.5) above_counter++;
if (interval_counter >= 1000000) {
cout << "Average: " << avg << " counter: " << counter << " Percentage above: "
<< (double) above_counter / (double) counter * 100.0
<< " Perc abs above counter: " << 100.0 * above_counter_this / counter
<< " \r";
interval_counter = 0;
}
//usleep(1);
counter++;
interval_counter++;
}
}
rand()
众所周知是一个糟糕的生成器,它在低位尤其糟糕。执行 % 6
仅选择低位。您也有可能遇到一些 modulo bias,但我希望这种影响相对较小。
在下面的代码中,我希望骰子作用数十亿次,平均结果恰好是 3.5,高于 3.5 的百分比有时约为 5%,而其他时候(当然有不同的种子) ) 就像 95。但是即使你达到 6040M thows,你也永远不会超过 50%,低于 3.5 的 50%?显然 rand() 有点偏差...
我知道 'real random' 不存在,但真的有这么明显吗?
典型的输出是:
Average: 3.50003 counter: 3427000000 Percentage above: 83.2554 Perc abs above counter: 50.0011
Average: 3.49999 counter: 1093000000 Percentage above: 92.6983 Perc abs above counter: 50.0003
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <unistd.h>
#include <iostream>
using namespace std;
int main ()
{
long long int this_nr;
long long int counter = 0;
long long int above_counter = 0;
long long int below_counter = 0;
long long int above_counter_this = 0;
long long int below_counter_this = 0;
long long int interval_counter = 0;
double avg = 0.0;
srand (time(NULL));
srand (time(NULL));
srand (time(NULL));
cout.precision(6);
while(1) {
this_nr = rand() % 6 + 1; // 0,1,2,3,4,5 or 6
avg = ((double) this_nr + ((double)counter * (double) avg))
/ ((double) counter+1.0);
if (this_nr <= 3) below_counter_this++;
if (this_nr >= 4) above_counter_this++;
if (avg < 3.5) below_counter++;
if (avg > 3.5) above_counter++;
if (interval_counter >= 1000000) {
cout << "Average: " << avg << " counter: " << counter << " Percentage above: "
<< (double) above_counter / (double) counter * 100.0
<< " Perc abs above counter: " << 100.0 * above_counter_this / counter
<< " \r";
interval_counter = 0;
}
//usleep(1);
counter++;
interval_counter++;
}
}
rand()
众所周知是一个糟糕的生成器,它在低位尤其糟糕。执行 % 6
仅选择低位。您也有可能遇到一些 modulo bias,但我希望这种影响相对较小。