为什么(rand()%中的任何东西)在C ++中总是0?

时间:2010-01-25 01:31:55

标签: c++ random

我无法让rand()在C ++中工作。 rand()通常给我一个非常大的数字。当我尝试使用模运算符(%)给它一个范围时,它总是返回0,无论如何。

在程序开头播种随机数生成器也无济于事。

3 个答案:

答案 0 :(得分:8)

我认为如果随机生成器算法将某个位模式保留为零,这种情况很常见。 (例如,如果低位为零,则某个低常量的数字mod将始终为零。)

也许你应该尝试类似的东西:

const int desired_maximum = /* ... */;

int r = (((double)rand()) / RAND_MAX) * desired_maximum;

例如在this manpage link中,它说:

C中的数字食谱:科学计算的艺术(William H. Press,Brian P. Flannery,Saul A. Teukolsky,William T. Vetterling; New York:Cambridge University Press,1992(2nd ed。,p。 277)),提出以下意见:

“如果要生成1到10之间的随机整数,则应始终使用高位来执行此操作,如

    
j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));
从来没有任何类似的东西
    
j = 1 + (rand() % 10);
(使用低阶位)。“

答案 1 :(得分:7)

以下代码对我来说效果很好(每次运行时发出0到0和1000之间的随机数):

#include <cstdlib>
#include <ctime>
#include <iostream>

int main()
{
    std::srand(time(0));
    std::cout<<(std::rand() % 1000)<<std::endl;
    return 0;
}

答案 2 :(得分:4)

看来您的问题已经得到解决,但我认为还值得一提。使用余数将rand的输出钳位到指定范围通常会导致结果出现偏差。具体而言,如果发生器的范围(在C或C ++的情况下为RAND_MAX)不是您要钳制的范围的倍数,则某些输出将比其他输出更频繁地发生。为了比较,考虑尝试在3个孩子之间平均分配11个糖果(不破坏任何碎片)。你能做到的唯一方法就是不要分发一些糖果。同样,使用随机数生成器,在输出中获得均匀分布的唯一方法是不使用某些输入。

int rand_lim(int limit) {
/* return a random number between 0 and limit inclusive.
 */
    int divisor = RAND_MAX/(limit+1);
    int retval;

    do { 
        retval = rand() / divisor;
    } while (retval > limit);

    return retval;
}

正如asveikau在帖子中指出的那样,你通常想要使用典型线性同余生成器的高位。较低的位通常更容易预测。通过划分而不是取余数,这保留了高位。虽然这确实有一个while循环,但它通常只执行一次,很少超过两次,所以它对性能的影响非常小。

这是否值得取决于你对你产生的数字的使用 - 如果你想要一个游戏的骰子或卡片,你的孩子会玩几次,使用剩余部分通常不会伤害到事情。如果您正在尝试进行某种蒙特卡罗模拟(例如),您可能想要更加小心一点......