如何在0到n的范围内生成随机数,其中n可以是> 0。 RAND_MAX在c,c ++?
感谢。
答案 0 :(得分:8)
将生成分为两个阶段,然后合并生成的数字。
答案 1 :(得分:5)
随机数是一门非常专业的主题,除非你是数学杂耍,否则很容易出错。所以我建议不要从多个来源构建一个随机数,你应该使用一个好的库。
我先看看boost::Random
如果这不是一个有效的尝试这个小组sci.crypt.random-numbers 在那里提出问题,他们应该能够提供帮助。
答案 2 :(得分:3)
假设你想生成一个64位的随机数,你可以这样做:
uint64_t n = 0;
for(int i = 0; i < 8; ++i) {
uint64_t x = generate_8bit_random_num();
n = (n << (8 * i)) | x;
}
当然,你也可以一次做16/32位,但这说明了这个概念。
如何生成8/16/32位随机数取决于您。它可以像rand() & 0xff
一样简单,也可以更好,这取决于你对随机性的关注程度。
答案 3 :(得分:2)
假设使用C ++,您是否尝试过查看一个像Boost.Random这样的随机数字库。否则,您可能需要组合多个随机数。
答案 4 :(得分:1)
如果您正在寻找统一分布(或任何分配方式),您必须注意输出的统计属性足以满足您的需求。如果您无法直接使用随机数生成器的输出,则应该非常小心地尝试组合数字以满足您的需求。
至少应该确保分发是合适的。如果您正在寻找从0到M的整数均匀分布,并且您有一个统一的随机数生成器g()
来生成小于M的输出,请确保不执行以下操作之一:
除此之外,序列的术语之间存在互相关的可能性(随机数发生器应该产生独立的相同分布的输出)。
阅读计算机程序设计艺术卷。 2(Knuth)和/或Numerical Recipes并提出问题直到你有信心。
答案 5 :(得分:1)
如果你的实现有一个足够大的整数类型来保存你需要的结果,通过简单地使用产生所需范围的生成器而不是尝试组合输出来获得合适的分布通常更容易来自较小的发电机。
当然,在大多数情况下,您只需下载Mersenne Twister或(如果您需要加密质量生成器)Blum-Blum-Shub等代码,并忘记编写自己的代码。
答案 6 :(得分:0)
做x个随机数(从0到RAND_MAX)并将它们加在一起,其中
x = n%RAND_MAX
答案 7 :(得分:0)
有很多方法可以做到这一点。
如果你没有更低的粒度(更高的欺骗机会),那么(在伪代码中)rand() * n / RAND_MAX
之类的东西将有助于将值扩展到更大的范围。问题在于,在您的实际代码中,您需要避免溢出,通过将rand()或n转换为足够大的类型(例如,如果RAND_MAX为0xFFFFFFFF,则为64位int)来保持乘法结果而不溢出,或者使用乘法除法的API(如GNU的MulDiv64或Win32的MulDiv),该API针对此场景进行了优化。
如果你希望将粒度降低到每个整数,你可以多次调用rand()并附加结果。另一个答案建议根据RAND_MAX的大小为每个8位/ 16位/ 32位块调用rand()。
但是,恕我直言,上述想法很快就会变得复杂,不准确或两者兼而有之。生成随机数是其他库中解决的问题,借用现有代码(例如从Boost)可能要比尝试自己编写代码容易得多。如果您想要除Boost之外的其他内容,Open source random number generation algorithm in C++?会有更多链接的答案。
[编辑:忙碌了一天之后进行修改...意味着今天早上回来清理我的快速回答,但是被拉开了,现在才回来。 :-)]
答案 8 :(得分:0)
考虑一个随机变量,它可以使用{0, 1}
取值P(0) = P(1) = 0.5
。如果您想通过对两个独立绘图进行求和来生成0
到2
之间的随机值,您将拥有P(0) = 0.25
,P(1) = 0.5
和P(2) = 0.25
。
因此,除非您根本不关心RNG的PDF,否则请使用适当的库。
另见Numerical Recipes中的第7章。 (这是旧版本的链接,但这是我学习的那个; - )