模数和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()的随机性对你无关紧要,那就千方百计使用它。