【发布时间】:2011-11-25 11:36:29
【问题描述】:
我想在 C++ 中生成某个范围内的随机数,比如说我想要 25 到 63 之间的数字。
我怎样才能拥有它?
【问题讨论】:
-
即使有循环也能完美运行:输出 = min + (rand() % (int)(max - min + 1))
我想在 C++ 中生成某个范围内的随机数,比如说我想要 25 到 63 之间的数字。
我怎样才能拥有它?
【问题讨论】:
int range = max - min + 1;
int num = rand() % range + min;
【讨论】:
rand() % range 相对统一,我希望添加一个常量可以保持统一。或者你是说rand() 本身并不是一个真正随机数的好选择?没错,但取决于 OP 想要做什么, rand() 可能就足够了。
Johannes Rudolph 抱怨的原因是 % 不起作用,除非右边的值是 RAND_MAX 的精确除数。如果不是,那么某些值的概率会稍小(非常轻微)。示例: RAND_MAX (32767) r = rand()%3; 概率为 0(10923/32767) 1(10922/32767) 2(10922/32767) 请注意,0 的概率略高。正如 'Benjamin Lindley' 指出的那样,这在大多数情况下是微不足道的,但是当你做像密码学这样的事情时,这样的事情就会成为一个问题。所以很多人在使用这种方法时都会哭。
num = rand() * 1.0 / RAND_MAX * (max-min+1) + min;
您可以使用添加到标准库 (TR1) 中的随机功能。或者您可以使用在普通 C 中工作的相同旧技术:
25 + ( std::rand() % ( 63 - 25 + 1 ) )
【讨论】:
std::rand() 返回从0 到RAND_MAX(包含)的均匀分布的整数。现在,假设您通过使用std::rand() % RAND_MAX 获得了从0 到RAND_MAX - 1(包括)范围内的整数,现在获得0 的机会将加倍,因为这将是std::rand() 返回时的结果要么 0 要么 RAND_MAX。任何其他数字只有在std::rand() 直接返回时才会获得。这同样适用于不是 RAND_MAX + 1 的除数的每个模数。
float RandomFloat(float min, float max)
{
float r = (float)rand() / (float)RAND_MAX;
return min + r * (max - min);
}
【讨论】:
max的几率是多少?
使用rand函数:
http://www.cplusplus.com/reference/clibrary/cstdlib/rand/
引用:
A typical way to generate pseudo-random numbers in a determined range using rand is to use the modulo of the returned value by the range span and add the initial value of the range:
( value % 100 ) is in the range 0 to 99
( value % 100 + 1 ) is in the range 1 to 100
( value % 30 + 1985 ) is in the range 1985 to 2014
【讨论】:
Benjamin Lindley 答案和我的相关 cmets,了解 C++11 之前的方法。但是我上面的评论是错误的(我想念你的答案)。所以我会删除它。网站 cplusplus.com 对我来说还可以(并且不时供快速参考),但我不会将其用作权威来源。
int random(int min, int max) //range : [min, max]
{
static bool first = true;
if (first)
{
srand( time(NULL) ); //seeding for the first time only!
first = false;
}
return min + rand() % (( max + 1 ) - min);
}
【讨论】:
由于还没有人发布现代 C++ 方法,
#include <iostream>
#include <random>
int main()
{
std::random_device rd; // obtain a random number from hardware
std::mt19937 gen(rd()); // seed the generator
std::uniform_int_distribution<> distr(25, 63); // define the range
for(int n=0; n<40; ++n)
std::cout << distr(gen) << ' '; // generate numbers
}
【讨论】:
mt19937 类型的黑客是什么?!” - A Mersenne Twister pseudo-random generator of 32-bit numbers with a state size of 19937 bits. 它是带有预设参数的“mersenne_twister_engine”模板 (cplusplus.com/reference/random/mersenne_twister_engine) 的“包装器”。
std::uniform_int_distribution<> 包含在内——在上面的示例中,[25,63]。
-std=c++11 编译器标志切换到 C++11 .由于 C++11 不向后兼容,所有符合标准的编译器(GCC、clang、...)都需要显式激活 C++11。