我观察到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))。
基本上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;
}
While what everyone else has said about the likely overflow could very well be the cause of the negative, even when you use unsigned integers. The real problem is actually using time/date functionality as the seed. If you have truly become familiar with this functionality you will know exactly why I say this. As what it really does is give a distance (elapsed time) since a given date/time. While the use of the date/time functionality as the seed to a rand(), is a very common practice, it really is not the best option. You should search better alternatives, as there are many theories on the topic and I could not possibly go into all of them. You add into this equation the possibility of overflow and this approach was doomed from the beginning.
那些发布rand()+1的人正在使用最常用的解决方案,以确保他们不会得到负数。但是,这种方法也不是最好的方法。
您能做的最好的事情是花费额外的时间来编写和使用适当的异常处理,如果和/或当您最终得到零结果时,只添加到rand()数字。正确处理负数。rand()功能并不完美,因此需要与异常处理一起使用,以确保最终得到所需的结果。
花费额外的时间和精力来调查、研究和正确地实现rand()功能是非常值得的。这只是我的个人意见。祝你好运……
谢谢。我添加的原因是为了避免在我的代码中使用“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;
}
}