18万亿投掷硬币,我哪里出错了?

18万亿投掷硬币,我哪里出错了?,第1张

概述为什么以下C代码在我的桌面和服务器上给出了不同的结果,两者都运行类似的 Linux版本? 它在18万亿投币中找到了行序列中最长的同一侧. [见Iain M. Banks的科幻小说考虑Phlebas.] 在服务器上,经过15.7万亿投币(它仍然在运行)之后,到目前为止,行序列中最长的同一侧只有29个.由于2 ^ 44 = 17,592,186,044,416,我希望最长的相同边序列在某个地方. 40 为什么以下C代码在我的桌面和服务器上给出了不同的结果,两者都运行类似的 Linux版本?

它在18万亿投币中找到了行序列中最长的同一侧. [见Iain M. Banks的科幻小说考虑Phlebas.]

在服务器上,经过15.7万亿投币(它仍然在运行)之后,到目前为止,行序列中最长的同一侧只有29个.由于2 ^ 44 = 17,592,186,044,416,我希望最长的相同边序列在某个地方. 40到40年代中期,在完成所有18万亿之后可能达到44.

在仅仅47亿次投掷硬币之后的桌面上,最长的序列已经是31,因为2 ^ 31 = 2,147,483,648,这听起来是正确的.

那么为什么我在15.7万亿投币后只在服务器上获得了29个序列,但在我的桌面上只有47亿的31个序列?

Modulo偏见是我的第一个想法.桌面和服务器上的RAND_MAX是相同的,2,647(32位长签名).所以rand()函数会给我一个数字0< = rand()< = 2,647. 0是偶数,647是奇数,所以除非我非常误以为我的int引入了模偏差rand_num =(rand()%2);代码行. 我知道C标准库的伪随机数生成器不适合加密.当然,这不可能是一个因素,当然产生非常长,零和一系列的序列.可以吗? 这是来源: 使用以下两种机器编译:gcc -O3 -o 18TCT 18TrillionCoinTosses.c

#include <stdio.h>#include <stdlib.h>#include <time.h>int main(int argc,char* argv[]){    srand(time(NulL));    int current_seq = 0;    int longest_seq = 0;    int prev_rand_num = -1;    long long i = 0;    long long total = 18000000000000;    // To serve as a rudimentary progress indicator.    long billion_counter = 0;    long billion = 1000000000;    while (i < total)    {        int rand_num = (rand() % 2);        if (rand_num == prev_rand_num)        {            current_seq++;            if (current_seq >= longest_seq)            {                longest_seq = current_seq;                printf("Longest sequence so far: %d (on iteration %lli)\n",longest_seq,i);            }        }        else            current_seq = 1;        if (billion_counter == billion)        {            billion_counter = 0;            printf("Progress report,current iteration: %lli\n",i);        }        prev_rand_num = rand_num;        i++;        billion_counter++;    }    printf("\nTotal coins tossed: %lli\n",i);    printf("Longest sequence: %d\n",longest_seq);}
解决方法 您的随机数生成器可能在2 ^ 32 = 4294967296次调用后重复,因此您并未真正模拟18万亿次试验.您需要一个更好的RNG,一个保持超过32位内部状态的RNG.在许多系统上,只需调用random()而不是rand()即可访问更好的RNG. (在我的系统上,man随机说“随机 – 更好的随机数发生器”和“这个随机数发生器的周期非常大,大约16 *((2 ** 31)-1)”.虽然那是“唯一的” 34,359,738,352,仍然不到18万亿.)

另外,作为一个侧面点,rand()%2是有风险的,虽然现在大多数RNG没有会把你烧到那里的问题(如果你确实有这个问题,你就会知道它,因为除其他外无论如何,你都会连续获得0分.

附录:您可以在C FAQ列表中找到问题13.15中其他一些更好的随机数生成器的引用:http://c-faq.com/lib/rand.html.

总结

以上是内存溢出为你收集整理的18万亿投掷硬币,我哪里出错了?全部内容,希望文章能够帮你解决18万亿投掷硬币,我哪里出错了?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1221430.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存