gpt4 book ai didi

clang - 糟糕的 rand() 实现

转载 作者:行者123 更新时间:2023-12-04 15:14:12 27 4
gpt4 key购买 nike

我做了一个Pong我不得不随机 throw 球的游戏。为此,我使用了内置的随机数生成器,并在 Ubuntu/GCC 中获得了不错的结果。在将代码移植到 Mac 并编译时,球只会朝一个方向转换,这意味着 clang 中的 rand() 函数没有按预期工作。

我已经恢复到自定义数字生成器,但这是游戏中最初有问题的代码:

srand(time(NULL));
float ang = ((float)rand())/RAND_MAX * 120 - 60;
int side = (int)(((float)rand())/RAND_MAX * 2);

经过进一步检查,我创建了以下测试程序并在两个平台上编译和运行它。

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char** argv) {
while (1) {
int now = time(NULL);
printf("Time now is %d\n", now);
srand(now);
int random = rand();
printf("Random number generated is %d\n", random);
sleep(1);
}
}

结果(根据 RAND_MAX 制表和计算,在两个系统上都是 2147483647)如下:

enter image description here

结果不言而喻。虽然 clang 版本中存在随机性,但与 RAND_MAX 的值相比,随机性非常差,标准差为 0 证明了这一点,而 gcc 上的标准差为 0.328。

rand() 在 clang 上的这种不良行为的原因是什么?我还想在头文件中看到这个函数的引用实现。这似乎是不标准的,而且我一定不是唯一一个在使用这种方法将程序移植到 Mac 时遇到问题的人。在使用/依赖随机数生成器时,还有哪些其他设计原则是好的做法?

最佳答案

行为不当的原因:

所以我不知道 apple 的 rand clang 实现的确切实现,但我知道它是作为 LCG 或线性同余生成器完成的。它的工作方式基本上是一个公式:

在公式中, 将是 RAND_MAX  是由编译器定义的一些常量。 Apple 的 Clang 分别使用了 168070

rand() 的返回值是  ,最后返回的 rand() 或您在 srand() 中输入的值将是  .

如果你只是想要一个有点随机的数字序列,这很好用,因为它最终会返回 0RAND_MAX 之间的所有数字,没有人类明显的模式。

然而,通过一些计算,你可以很容易地发现如果你只是用一个连续的数字序列代替  会有一些问题。在那个公式中(这就是你所做的)。 rand() 的每次调用之间的差异将恰好等于  , 除非  实际上接近 RAND_MAX


正确使用方法:

通过rand()函数获取随机数的正确方法是一开始只调用一次srand(),并且只使用rand() 在循环中。

或者,您可以寻找许多其他随机生成公式,您可能可以在这里找到一些:How to generate a random int in C?

关于clang - 糟糕的 rand() 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64619808/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com