所以,我一直对此很着迷。
rand() % 6 将始终产生 0-5 之间的结果。
但是,当我需要介于两者之间时,比如说 6-12。
我应该有 rand() % 6 + 6
0+6 = 6.
1+6 = 7.
...
5+6 = 11. ???
如果我想要 6-12 的区间,我需要 + 7 吗?但是,0+7 = 7。什么时候会随机化 6?
我在这里想念什么?哪一种是在 6 到 12 之间获得随机数的正确方法?为什么?好像我在这里遗漏了一些东西。
如果C++11是一个选项,那么您应该使用随机标头和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 常见问题解答中获得了这个,并解释了如何获得一定范围内的随机整数?问题。
更新 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 ;
}
你需要 rand() % 7 + 6。
rand() %7 中的最小数字:0。 rand() %7 中的最大数字:6。
0 + 6 = 6。6 + 6 = 12。
模运算a % b
计算除法的余数a / b
。显然,除法的余数必须小于b
,如果a
是一个随机正整数,那么a%b
它是一个在 0 .. (b-1) 范围内的随机整数
在您提到的评论中:
rand()%(最大-最小)+最小
该算法产生半开范围 [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() 的问题。这取决于您是否真的关心您的数据是否是随机的。如果你真的很在意它是随机的,我强烈建议在今年的 Going Native 2013上观看 Stefan T Lavalej 关于使用 rand() 的陷阱的演讲。他还谈到了你应该使用什么。
如果 rand() 的随机性对你来说并不重要,那么一定要使用它。