模数和rand()是如何工作的?

所以,我一直坚持这一点。

rand()%6将始终生成0-5之间的结果。

但是当我需要时,比如说6-12。

我应该有rand()%6 + 6

0+6 = 6. 1+6 = 7. ... 5+6 = 11. ??? 

所以我需要+7如果我想要6-12的时间间隔? 但是,0 + 7 = 7。 什么时候将6随机分配?

我在这里错过了什么? 哪一个是6到12之间的随机数字的正确方法? 为什么? 这似乎是我在这里失去了一些东西。

如果C ++ 11是一个选项,那么你应该使用随机头和uniform_int_distrubution 。 正如詹姆斯在使用兰德的评论中指出的那样, %有很多问题,包括有偏见的分布:

 #include <iostream> #include <random> int main() { std::random_device rd; std::mt19937 e2(rd()); std::uniform_int_distribution<int> dist(6, 12); for (int n = 0; n < 10; ++n) { std::cout << dist(e2) << ", " ; } std::cout << std::endl ; } 

如果你不得不使用兰德,那么这应该做的:

 rand() % 7 + 6 

更新

使用rand的更好方法如下:

 6 + rand() / (RAND_MAX / (12 - 6 + 1) + 1) 

我从C FAQ获得了这个,并解释了如何获得一定范围内的随机整数? 题。

更新2

提升也是一个select:

 #include <iostream> #include <boost/random/mersenne_twister.hpp> #include <boost/random/uniform_int_distribution.hpp> int main() { boost::random::mt19937 gen; boost::random::uniform_int_distribution<> dist(6, 12); for (int n = 0; n < 10; ++n) { std::cout << dist(gen) << ", "; } std::cout << std::endl ; } 

你需要rand()%7 + 6。

最低数量从兰特()%7:0最高数字兰特()%7:6。

0 + 6 = 6.6 + 6 = 12。

模数运算a % b计算除法a / b的余数。 显然,一个除法的余数必须小于b ,如果a是一个随机正整数,那么a%b是一个在0 ..(b-1)范围内的随机整数。


在你提到的评论中:

兰特()%(最大 – 最小)+分钟

该algorithm产生半开范围[min,max)的值。 (也就是说,max在范围之外,只是表示边界,因为我们谈的是整数范围,所以这个范围相当于封闭范围[min,max-1])。

当你写'0 – 5'或'6 – 12'这些是封闭的范围。 要使用上述公式,您必须使用表示等效半开范围的值:[0,6]或[6,13]。

 rand() % (6-0) + 0 rand() % (13-6) + 6 

请注意, rand() % (max-min) + min只是您明显已经学会的规则的推广: rand() % n产生范围为0 – (n-1)的值。 等效的半开范围是[0,n)和rand() % n == rand() % (n-0) + 0

所以教训是:不要混淆封闭范围的半开范围。


第二个教训是,这显示了<random>rand()更容易使用并手动计算自己的分布的另一种方式。 内置的uniform_int_distribution允许您直接声明所需的包含范围。 如果你想要的范围是0-5,你可以说uniform_int_distibution<>(0, 5) ,如果你想要范围6-12,那么你可以说uniform_int_distribution<>(6, 12)

 #include <random> #include <iostream> int main() { std::default_random_engine eng; std::uniform_int_distribution<> dist(6, 12); for (int i=0; i<10; ++i) std::cout << dist(eng) << " "; } 

rand()%7+6更简洁,但这并不意味着它更易于使用。

这里有几个概念。

首先是范围: [表示包含。 )表示独占。

模运算符%n产生[0,n) – 0,…,n-1

当您为该结果添加值时,您将在范围的两端添加相同的值:

%n + 6 = [n,n+6)

现在,如果n是6,就像你的情况一样,你的输出将是[0,6)

%6 + 6 = [6,12)

现在你想要的是[6,13)

从中减去6:

[0,7) + 6 => n%7 + 6

其次,有使用rand()的问题。 这取决于你是否真的关心你的数据是否是随机的。 如果你真的关心它是随机的,我强烈build议你看看Stefan T Lavalej谈到今年在2013年本土使用rand()的陷阱 。 他也进入你应该使用的东西。

如果rand()的随机性对你无关紧要,那就千方百计使用它。