我观察到rand()库函数在循环中只被调用一次时,它几乎总是产生正数。
for (i = 0; i < 100; i++) {
printf("%d\n", rand());
}
但是当我添加两次rand()调用时,生成的数字现在有更多的负数。
for (i = 0; i < 100; i++) {
printf("%d = %d\n", rand(), (rand() + rand()));
}
有人能解释一下为什么我在第二种情况下看到负数吗?
PS:我在循环之前将种子初始化为srand(time(NULL))。
谢谢。我添加的原因是为了避免在我的代码中使用“0”作为随机数。Rand ()+ Rand()是我脑海中迅速出现的肮脏解决方案
对我来说,这听起来像是一个XY问题,为了从rand()中不得到0,你调用rand()两次,使程序变慢,有一个新的挫折,得到0的可能性仍然存在。
另一个解决方案是使用uniform_int_distribution,它在定义的间隔内创建一个随机且均匀分布的数字:
https://wandbox.org/permlink/QKIHG4ghwJf1b7ZN
#include <random>
#include <array>
#include <iostream>
int main()
{
const int MAX_VALUE=50;
const int MIN_VALUE=1;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> distrib(MIN_VALUE, MAX_VALUE);
std::array<int,MAX_VALUE-MIN_VALUE> weight={0};
for(int i=0; i<50000; i++) {
weight[distrib(gen)-MIN_VALUE]++;
}
for(int i=0;i<(int)weight.size();i++) {
std::cout << "value: " << MIN_VALUE+i << " times: " << weight[i] << std::endl;
}
}
基本上rand()生成0和RAND_MAX之间的数字,在您的情况下生成2 RAND_MAX > INT_MAX。
可以对数据类型的最大值进行模数处理,以防止溢出。这当然会破坏随机数的分布,但rand只是一种快速获得随机数的方法。
#include <stdio.h>
#include <limits.h>
int main(void)
{
int i=0;
for (i=0; i<100; i++)
printf(" %d : %d \n", rand(), ((rand() % (INT_MAX/2))+(rand() % (INT_MAX/2))));
for (i=0; i<100; i++)
printf(" %d : %ld \n", rand(), ((rand() % (LONG_MAX/2))+(rand() % (LONG_MAX/2))));
return 0;
}