以下代码每秒输出一个随机数:

int main ()
{
    srand(time(NULL)); // Seeds number generator with execution time.

    while (true)
    {
        int rawRand = rand();

        std::cout << rawRand << std::endl;

        sleep(1);
    }
}

我如何减少这些数字,以便它们总是在0-100的范围内?

有帮助吗?

解决方案

如果您使用的是C ++,并且担心良好的分发,则可以使用 TR1 C ++ 11 <random>.

#include <random>

std::random_device rseed;
std::mt19937 rgen(rseed()); // mersenne_twister
std::uniform_int_distribution<int> idist(0,100); // [0,100]

std::cout << idist(rgen) << std::endl;

其他提示

到目前为止发布的所有示例实际上给出了分布不佳的结果。经常执行代码并创建统计量,以查看值如何偏斜。

产生真实的更好方法 制服 随机数分布在任何范围内[0, n]是以下内容(假设 rand 实际上遵循统一的分布,这远非显而易见):

unsigned result;
do {
    result = rand();
} while (result > N);

当然,这种方法很慢,但是 产生良好的分布。这样做的一种稍聪明的方法是找到 n 比小于 RAND_MAX 并将其用作上限。之后,可以安全地接受 result % (N + 1).

用于解释 为什么 幼稚的模量法是不好的,为什么上述更好, 请参阅朱利安(Julienne)的出色文章 使用 rand.

int rawRand = rand() % 101;

请参阅(有关更多详细信息):

兰德-C ++参考

其他人还指出,这不会为您提供最佳的随机数分布。如果这种事情在您的代码中很重要,则必须这样做:

int rawRand = (rand() * 1.0 / RAND_MAX) * 100;

编辑

三年过去了,我正在编辑。正如其他人提到的 rand() 有很多问题。显然,当有更好的替代方案前进时,我不建议它使用它。您可以在此处阅读有关详细信息和建议的所有信息:

兰德()认为有害| 2013年

你可以做

cout << rawRand % 100 << endl; // Outputs between 0 and 99

cout << rawRand % 101 << endl; // outputs between 0 and 100

对于人民降价;注意最初发布后一分钟,我留下了评论:

http://www.cplusplus.com/reference/clibrary/cstdlib/rand “请注意,尽管此模型操作不会在跨越中产生真正均匀分布的随机数(因为在大多数情况下,较低的数字可能稍微稍微稍微降低),但对于短跨度来说,这通常是一个很好的近似值。”

具有64位INT并使用100个数字作为输出,数字0-16代表了数字的1.000000000000000455%-18),而数字为17-99的代表为0.99999999999999999913%。是的,不是完美的分布,而是小跨度非常好的近似值。

另请注意,OP在哪里要求分布相同的数字?就我们所知)。

编辑 - 对于真正关注随机数均匀分布的人,以下代码作用。请注意,这不一定像64位随机INT一样最佳,它将需要两个调用 rand() 一次每10^18呼叫。

unsigned N = 100; // want numbers 0-99
unsigned long randTruncation = (RAND_MAX / N) * N; 
// include every number the N times by ensuring rawRand is between 0 and randTruncation - 1 or regenerate.
unsigned long rawRand = rand();

while (rawRand >= randTruncation) {
    rawRand = rand();  
// with 64-bit int and range of 0-99 will need to generate two random numbers
// about 1 in every (2^63)/16 ~ 10^18 times (1 million million times)

// with 32-bit int and range of 0-99 will need to generate two random numbers 
// once every 46 million times.

}
cout << rawRand % N << stdl::endl;

man 3 rand - 您需要通过分裂来扩展 RAND_MAX 要获得范围[0,1],然后您可以为目标范围乘以100。

对于最大范围的最小值(包含),请使用: int result = rand() % (max - min + 1) + min;

您想要多长时间的答案。

最简单的是将剩余的转换除以101:

int value = rawRand % 101;

半司师将使用双打恢复:

double dbl = 100 * ((double)rawRand / RAND_MAX);
int ivalue = (int)(dbl + 0.5);   // round up for above 0.5

纯粹主义者会说兰德不会产生随机数。

对于您的信息,通过采取一系列数字,然后计算该序列的源是随机的数学概率来衡量随机数的质量。如果您是随机性,则使用其余部分的简单骇客是一个非常糟糕的选择。

有些人将以下代码发布为示例:

int rawRand = (rand() / RAND_MAX) * 100;

这是解决问题的一种无效方法,因为rand()和rand_max都是整数。在C ++中,这会导致整体分裂,这将截断结果小数点。作为rand_max> = rand(),该操作的结果为1或0,这意味着Rawrand只能是0或100。正确执行此操作的方法是以下内容:

int rawRand = (rand() / static_cast<double>(RAND_MAX)) * 100;

由于操作数现在是双重的,因此使用了浮点划分,将返回0到1之间的适当值。

RAWRAND%101将给出[0-100],包括。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top