所以,我一直很坚定。
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之间随机数的正确方法?为什么?好像我在这里遗漏了一些东西。
答案 0 :(得分:10)
如果 C ++ 11 是一个选项,那么您应该使用random header和uniform_int_distrubution。正如詹姆斯在评论中指出的那样使用 rand 和%
有很多问题,包括有偏见的分布:
#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,那么应该这样做:
rand() % 7 + 6
更新
使用rand
的更好方法如下:
6 + rand() / (RAND_MAX / (12 - 6 + 1) + 1)
我是从 C FAQ 获得的,并解释了How can I get random integers in a certain range?问题。
更新2
Boost也是一个选项:
#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 ;
}
答案 1 :(得分:4)
你需要rand()%7 + 6。
rand()%7:0中的最小数字。 来自rand()%7:6的最高数字。
0 + 6 = 6。 6 + 6 = 12。
答案 2 :(得分:4)
模数运算a % b
计算除法a / b
的余数。显然,除法的余数必须小于b
,如果a
是随机正整数,则a%b
是0 ...(b-1)范围内的随机整数
在你提到的评论中:
兰特()%(最大 - 最小)+分钟
该算法产生半开范围[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
更简洁,但这并不意味着它更容易使用。
答案 3 :(得分:1)
这里有几个概念。
首先,范围是:[
表示包容性。 )
表示排他性。
模数运算符%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()的问题。这取决于您是否真的关心您的数据是否随机。如果你确实关心它是随机的,我强烈建议今年在Going Native 2013上观看Stefan T Lavalej关于the pitfalls of using rand()的演讲。他也会介绍你应该使用的东西。
如果rand()的随机性对你无关紧要,那么一定要使用它。