C++ randomizer - 第一个随机数总是 7 的一个因素

标签 c++ random

我有一个简单的 C++ 程序,用于与我的学生演示数组元素的随机选择。

像往常一样,我在使用 rand() 生成数字之前使用 srand (time (0)); 进行播种。

数组有7个条目,选中的条目是第一个-下标0。

我现在已经在四十分钟内运行了该程序十五次,第一个随机生成的数字是七的倍数,例如:

1258771276 1258586399 1229409447 1257140997 1256216612 1260855344 1262973026 1266351233

我更改了程序以在播种后选择五个随机数,并且(在生成 7 的初始倍数之后),后续数字表现得更好。

我理解“随机”意味着我无法预测数字不同,就像我无法预测它们相同一样。

我也明白这些是伪随机数。

我也理解 rand() 预计不会是顶级密码随机化。

不过,这种行为太奇怪了,我完全目瞪口呆。我是否陷入了 C++ 运行时的一些奇怪的裂缝?这是在完全修补到 Mojave 10.14.1 的 MacOS 上使用 Xcode。

最佳答案

这里是有问题的随机生成器的源代码:

static int
do_rand(unsigned long *ctx)
{
/*
 * Compute x = (7^5 * x) mod (2^31 - 1)
 * without overflowing 31 bits:
 *      (2^31 - 1) = 127773 * (7^5) + 2836
 * From "Random number generators: good ones are hard to find",
 * Park and Miller, Communications of the ACM, vol. 31, no. 10,
 * October 1988, p. 1195.
 */
    long hi, lo, x;

    /* Can't be initialized with 0, so use another value. */
    if (*ctx == 0)
        *ctx = 123459876;
    hi = *ctx / 127773;
    lo = *ctx % 127773;
    x = 16807 * lo - 2836 * hi;
    if (x < 0)
        x += 0x7fffffff;
    return ((*ctx = x) % ((unsigned long)0x7fffffff + 1));
}

考虑到当前最先进的生成器,这不是一个质量很好的生成器。然而,它也没有那么糟糕。

但是,它的播种机制是最糟糕的:它只是设置 ctx作为种子。因此,如果您将种子设置为相似的值(就像您的示例一样,您随时间播种,这意味着它将具有相似的值),它生成的下一个数字将与种子具有非常强的相关性。

该问题的一种解决方案是在播种后生成“一些”数字。然而,它不会完美地解决问题(通常种子与生成的数字有很强的相关性,即使在非常的距离)。

或者,更好的解决方案是忘记 rand() ,并使用更现代(也更难使用)的随机数, 这是在 #include <random> . 查看 cppreference 的 documentation关于它。

关于C++ randomizer - 第一个随机数总是 7 的一个因素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53267067/

相关文章:

python - 如何选择范围内的随机数 - + 转换为 ms

c++ - QGraphicsItem绘图问题

c++ - 如何就地修改一维数组的每个元素?

c++ - VC++ win32 API编程 : how can I get the image out of the clipboard and display it in a windows?

c++ - Qt - QVBoxLayout 中的重叠标签

c# - 为什么序列化类中的 Random 实例会重复生成同一组数字?

java - 为什么 Random 中的 next 方法使用 compareAndSet?

c++ - 除了更改环境变量 "PATH"之外,您还需要做什么才能让 Eclipse 识别 MinGW ?

java - 如何生成当前日期的随机时间?

Java随机值和重复项