我观察到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,试试这个:

int rnumb = rand()%(INT_MAX-1)+1;

你需要包括限制。h。

其他回答

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()是我脑海中迅速出现的肮脏解决方案。

一个简单的解决方案(好吧,称之为“黑客”),永远不会产生零结果,永远不会溢出:

x=(rand()/2)+1    // using divide  -or-
x=(rand()>>1)+1   // using shift which may be faster
                  // compiler optimization may use shift in both cases

这将限制最大值,但如果您不关心这一点,那么这应该可以为您工作。

rand()被定义为返回0到RAND_MAX之间的整数。

rand() + rand()

可能会溢出。您所观察到的可能是由整数溢出引起的未定义行为的结果。

要避免0,试试这个:

int rnumb = rand()%(INT_MAX-1)+1;

你需要包括限制。h。

也许你可以尝试一种比较棘手的方法,确保2 rand()的sum返回的值永远不会超过RAND_MAX的值。一种可能的方法是sum = rand()/2 + rand()/2;这将确保对于RAND_MAX值为32767的16位编译器,即使两个rand都返回32767,即使(32767/2 = 16383)16383+16383 = 32766,也不会产生负和。