我无法让rand()在C++中工作.rand()通常给我一个非常大的数字.当我尝试使用模运算符(%)给它一个范围时,它总是返回0,无论如何.
在程序开头播种随机数生成器也无济于事.
我认为如果随机生成器算法将某个位模式保留为零,这种情况很常见.(例如,如果低位为零,则某个低常量的数字mod将始终为零.)
也许你应该尝试类似的东西:
const int desired_maximum = /* ... */;
int r = (((double)rand()) / RAND_MAX) * desired_maximum;
Run Code Online (Sandbox Code Playgroud)
例如,在此联机帮助页链接中,它说:
C:Numerical Recipes in C:The Scientific of Scientific Computing(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);
以下代码对我来说很合适(每次运行时发出一个介于0和0之间的随机数):
#include <cstdlib>
#include <ctime>
#include <iostream>
int main()
{
std::srand(time(0));
std::cout<<(std::rand() % 1000)<<std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
看来您的迫在眉睫的问题已经解决了,但我认为仍然值得一提。使用余数将兰特的输出钳位到指定范围通常会导致结果偏差。具体来说,如果生成器的范围(对于C或C ++,则为RAND_MAX)不是您要限制的范围的倍数,则某些输出将比其他输出更频繁地出现。为了进行比较,请考虑尝试将11个糖果平均分配给3个孩子(不分成任何一个)。唯一的方法就是不要分发一些糖果。同样,对于随机数生成器,在输出中获得均匀分布的唯一方法是不使用某些输入。
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;
}
Run Code Online (Sandbox Code Playgroud)
正如asveikau在其文章中指出的那样,您通常希望使用典型线性同余生成器中的高位。较低的位通常更可预测。通过除法而不是取余数,可以保留高位。尽管确实有一个while循环,但它通常只执行一次,很少执行两次以上,因此对性能的影响很小。
这是否值得取决于您对所生成数字的使用-如果您想要骰子或孩子们将玩几次的游戏纸牌,那么使用余数通常不会有什么坏处。如果您尝试进行某种形式的蒙特卡洛模拟(例如),则可能需要多加注意。