【发布时间】:2021-02-13 14:10:29
【问题描述】:
我做了一个Pong 游戏,我必须随机投球。为此,我使用了内置的随机数生成器,并在 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)制表和计算)如下:
结果不言自明。虽然 clang 版本存在随机性,但与 RAND_MAX 的值相比,随机性很差,标准差为 0,而 gcc 的标准差为 0.328。
rand() 在 clang 上的这种不良行为的原因是什么?我还想在头文件中看到这个函数的参考实现。这似乎是不标准的,而且我一定不是唯一一个在使用这种方法将程序移植到 Mac 时遇到问题的人。在使用/依赖随机数生成器时,还有哪些其他设计原则是好的做法?
【问题讨论】:
-
根据 Mac 自己的说法,他们对
rand()的实现很糟糕:developer.apple.com/library/archive/documentation/System/… ... 并被random()淘汰 -
我很想看看这个 srand() 和 rand() 实现的源代码。
-
我想说最重要的原则是选择一个经得起分析并且今天仍然受到尊重的随机数生成器。
rand()唯一追求的就是便携性。请注意,没有要求rand()实现不佳,只是似乎经常如此。 -
在调用
srand()后多次调用rand()会发生什么?它仍然只是略有不同吗? -
不怪clang,不夸gcc;随机数生成器是系统标准库的一部分,而不是编译器。相反,它是 MacOS 与 glibc。
标签: c gcc random numbers clang