18万亿次硬币抛掷,我哪里错了? [关闭]

2023-12-01

为什么以下 C 代码在运行相似版本 Linux 的桌面和服务器上给出不同的结果?

它在 18 万亿次抛硬币中找到连续序列中最长的同边。 [参见 Iain M. Banks 的科幻小说考虑弗莱巴斯.]

在服务器上,经过 15.7 万亿次硬币抛掷(仍在运行),到目前为止,行序列中最长的同边只有 29。2^44 = 17,592,186,044,416,我预计最长的同侧序列将在 40 左右,在 18 万亿已经完成之后可能是 44。

在桌面上,仅抛了 47 亿次硬币后,最长的序列就已经是 31,因为2^31 = 2,147,483,648,这听起来不错。

那么,为什么在 15.7 万亿次硬币抛掷后,我在服务器上得到的序列只有 29,而在我的桌面上只有 47 亿次硬币抛掷后,得到的序列却只有 31?

模偏差是我的第一个想法。RAND_MAX在桌面和服务器上都是相同的,2,147,483,647(32 位有符号长)。所以rand()函数会给我一个数字0 <= rand() <= 2,147,483,647。 0 是偶数,2,147,483,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 位的内部状态。在许多系统上,您只需调用即可访问更好的 RNGrandom()代替rand()。 (在我的系统上,man random说“随机——更好的随机数生成器”和“这个随机数生成器的周期非常大,大约为 16*((2**31)-1)”。虽然这“仅仅”是 34,359,738,352,但距离你的 18 万亿还差。)

另外,作为一个侧面,rand() % 2是有风险的,尽管现在大多数 RNG 都不存在会烧伤你的问题(如果你确实遇到了这个问题,你就会知道,因为除其他外,无论如何你都会连续得到 0) 。


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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

18万亿次硬币抛掷,我哪里错了? [关闭] 的相关文章

  • json.net自定义jobject反序列化

    我正在尝试使用 JsonConvert DeserializeObject string 将字符串反序列化为可与动态一起使用的 jobject 来动态访问 json 文档 但是我想避免知道文档的大小写 以便我可以输入 dynamic doc
  • 将 new 与 decltype 一起使用

    T t T is an implementation detail t new T want to avoid naming T to allow for flexibility t new decltype t error cannot
  • 单元测试验证失败

    我正在运行我的单元测试PostMyModel路线 然而 在PostMyModel 我用的是线Validate
  • 在路由mvc 4中添加公司名称

    我一直在尝试为 Facebook 等用户提供在 URL 中添加公司名称的选项 http localhost 50753 MyCompany Login 我尝试过不同的网址 但没有成功 routes MapRoute name Default
  • 如何在另一个应用程序中挂钩 api 调用

    我正在尝试挂钩另一个应用程序的 ExtTextOut 和 DrawTextExt GDI 方法调用 我知道我需要使用 GetProcAddress 来查找 gdi32 dll 中那些方法的地址 并用我的函数的地址覆盖我想要挂钩的进程中的地址
  • 在 C# 中调用 C++ 库 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有很多用 C 编写的库 我想从 C 调用这些库 但是 我遇到了很多问题 我想知道是否有书籍或指南告诉我如何做到这一点 Dll导入 htt
  • 计算另一个表达式中的 C# 表达式

    我想在另一个表达式中使用一个表达式 Expression
  • C# 开源 NMEA 解析器 [已关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找 C 开源 NMEA 解析器 嗯 我自己也不熟悉 但是一些快速搜索显示了一个代码项目 htt
  • 增强精神、递归和堆栈溢出

    为什么下面的代码在运行时崩溃 它会给出堆栈溢出错误 include
  • C# 编译器不会优化不必要的强制转换

    前几天 在写答案的时候这个问题 https stackoverflow com questions 2208315 why is any slower than contains在这里 关于溢出 我对 C 编译器感到有点惊讶 它没有按照我的
  • 将接口转换为其具体实现对象,反之亦然?

    在 C 中 当我有一个接口和几个具体实现时 我可以将接口强制转换为具体类型 还是将具体类型强制转换为接口 这种情况下的规则是什么 Java 和 C 中都允许这两个方向 向下转型需要显式转型 如果对象类型不正确 可能会抛出异常 然而 向上转换
  • 根据对象变量搜索对象列表

    我有一个对象列表 这些对象具有三个变量 ID 名称和值 这个列表中可能有很多对象 我需要根据ID或Name找到一个对象 并更改值 例子 class objec public string Name public int UID public
  • 如何对 NServiceBus.Configure.WithWeb() 进行单元测试?

    我正在构建一个 WCF 服务 该服务接收外部 IP 上的请求并将其转换为通过 NServiceBus 发送的消息 我的单元测试之一调用Global Application Start 它执行应用程序的配置 然后尝试将 Web 服务解析为 验
  • 如何在三个 IEnumerable 上使用 Zip [重复]

    这个问题在这里已经有答案了 可能的重复 使用 Linq 从 3 个集合创建项目 https stackoverflow com questions 5284315 create items from 3 collections using
  • 使用 GCC 生成可读的程序集?

    我想知道如何使用GCC http en wikipedia org wiki GNU Compiler Collection在我的 C 源文件中转储机器代码的助记符版本 这样我就可以看到我的代码被编译成什么 你可以使用 Java 来做到这一
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • ASP.NET MVC 路由:如何从 URL 中省略“索引”

    我有一个名为 StuffController 的控制器 具有无参数索引操作 我希望从表单中的 URL 调用此操作mysite com stuff 我的控制器定义为 public class StuffController BaseContr
  • 使用 jQuery 从 ASP.Net JSON 服务获取数据

    我正在尝试调用 Google 地图地理编码 API 从纬度 经度对中获取格式化的地址 然后将其记录到控制台 我正在尝试获取为给定位置返回的第一个 formatted address 项目 我很简单无法从 JSON 中提取该项目 我不知道为什
  • 通过 Tab 键浏览 XML 文档字段

    In VB NET you can move through the fields in the XML member documentation with the Tab key 这在 C 中不起作用 还有其他方法吗 除了用鼠标将光标放在
  • 使用未分配的局部变量

    我遇到了一个错误 尽管声明了变量 failturetext 和 userName 错误仍然出现 谁能帮帮我吗 Use of Unassigned local variable FailureText Use of Unassigned lo

随机推荐