C ++生成随机数

时间:2012-02-28 15:20:15

标签: c++

我的输出是20个随机1,不在10和1之间,任何人都可以解释为什么会发生这种情况吗?

#include <iostream> 
#include <ctime> 
#include <cstdlib>

using namespace std;

int main() 
{ 
    srand((unsigned)time(0)); 
    int random_integer; 
    int lowest=1, highest=10; 
    int range=(highest-lowest)+1; 
    for(int index=0; index<20; index++){ 
        random_integer = lowest+int(range*rand()/(RAND_MAX + 1.0)); 
        cout << random_integer << endl; 
    } 
}
  

输出:       1       1       1       1       1       1       1       1       1       1       1       1       1       1       1       1       1       1       1

11 个答案:

答案 0 :(得分:38)

因为在您的平台上RAND_MAX == INT_MAX

表达式range*rand()永远不会采用大于INT_MAX的值。如果数学表达式大于INT_MAX,则整数溢出会将其减少到INT_MININT_MAX之间的数字。将其除以RAND_MAX将始终为零。

试试这个表达式:

random_integer = lowest+int(range*(rand()/(RAND_MAX + 1.0)))

答案 1 :(得分:16)

正确使用<random>库要比rand容易得多(假设你对C ++的熟悉程度不高,语法不会引起你的注意)。

#include <random>
#include <iostream>

int main() {
  std::random_device r;
  std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
  std::mt19937 eng(seed);

  std::uniform_int_distribution<> dist(1, 10);

  for(int i = 0; i < 20; ++i)
    std::cout << dist(eng) << " ";
}

答案 2 :(得分:11)

random_integer = (rand() % 10) + 1 

那应该给你一个介于1和1之间的伪随机数。 10。

答案 3 :(得分:9)

一个稍晚的答案,但它应该提供一些额外的 信息如果代的质量很重要。 (不是全部 应用程序需要这一点 - 轻微的偏差通常不是问题。)

首先,当然,原始代码中的问题是这样的事实 range * rand()优先于以下分区,并且已完成 使用整数运算。根据{{​​1}},这很容易 导致溢出,实现定义结果;所有 我知道的实现,如果它确实导致溢出(因为 RAND_MAX,实际结果几乎可以肯定 小于RAND_MAX > INT_MAX / range,除法将导致a 值小于RAND_MAX + 1.0。有几种方法可以避免这种情况: 最简单,最可靠的只是1.0

请注意,这假设rand() % range + lowest质量合理。许多 早期的实现不是,我已经看到至少一个在哪里 rand()模拟骰子投掷交替奇数和偶数。该 这里唯一正确的解决方案是获得更好的实现 rand() % 6 + 1;它导致人们尝试替代解决方案,例如 rand()。这掩盖了 问题,但它不会将坏的发电机变成一个好的发电机。

第二个问题,,如果代的质量很重要,是 当生成随机整数时,你就是离散的:如果你是 例如,模拟掷骰子,你有六种可能 您希望以相同的概率发生的值。随机 生成器将生成(range * (rand() / (RAND_MAX + 1.0))) + lowest个不同的值,具有相同的值 可能性。如果RAND_MAX + 1不是6的倍数,那就没有 分配价值的可能方式等于所需的6 值。想象一下RAND_MAX + 1为10的简单情况。使用 上面的RAND_MAX + 1方法,值1-4的可能性是其中的两倍 值5和6.如果使用更复杂的公式%(在1 + int(6 * (rand() / (RAND_MAX + 1.0)))的情况下, 事实证明,3和6只是其他值的一半。 在数学上,根本没有办法分配10种不同的 将值分配到6个槽中,每个槽中具有相同数量的元素。

当然,RAND_MAX + 1 == 10总是比10大得多,而且 引入的偏差将会大大减少;如果范围是 显着低于RAND_MAX,这是可以接受的。如果它是 但是,通常的程序不是这样的:

RAND_MAX

(有几种方法可以确定丢弃的值。这个 碰巧是我使用的那个,但我记得Andy Koenig使用的东西 完全不同 - 但导致相同的价值观 最后抛出。)

请注意,大多数情况下,您不会进入循环;最糟糕的情况是 当int limit = (RAND_MAX + 1LL) - (RAND_MAX + 1LL) % range; // 1LL will prevent overflow on most machines. int result = rand(); while ( result >= limit ) { result = rand(); } return result % range + lowest; range时,在这种情况下,您仍然会 通过循环平均不到一次。

请注意,这些注释仅适用于您需要固定数量的注释 离散的结果。对于生成随机的(其他)常见情况 (RAND_MAX + 1) / 2 + 1范围内的浮点数,[0,1)与您将得到的一样好。

答案 4 :(得分:1)

我建议您将rand()/(RAND_MAX + 1.0)替换为range*double(rand())/(RAND_MAX + 1.0))。因为我的解决方案似乎令人头疼......

可能的参数组合:

  • range*rand()是一个整数并溢出。
  • double(range*rand())在将其转换为double之前溢出。
  • range*double(rand())没有溢出并产生预期结果。

我的原帖有两个大括号,但它们没有改变任何东西(结果是一样的)。

答案 5 :(得分:1)

Visual Studio 2008对该程序没有任何问题,并且愉快地生成大量随机数。

我要小心的是/(RAND_MAX +1.0),因为这可能会导致整数问题,并最终导致大量的零点。

在分割之前强制转换为double,然后再将其转换为int

答案 6 :(得分:1)

(rand() % highest) + lowest + 1

答案 7 :(得分:0)

您正在生成一个随机数(即(range*rand()/(RAND_MAX + 1.0))),其值介于-1和1之间(]-1,1[),然后将其转换为整数。此数字的整数值始终为0,因此您最终得到lower + 0

编辑:添加公式以使我的回答更清晰

答案 8 :(得分:0)

可能“10 * rand()”小于“RAND_MAX + 1.0”,因此您的计算值为0.

答案 9 :(得分:0)

这是最简单的逻辑之一,从博客中获取。在这个逻辑中,您可以使用for循环中给定的模数(%)运算符限制随机数,它只是来自该博客的copoy和粘贴,但无论如何都要检查它:

// random numbers generation in C++ using builtin functions
#include <iostream>

using namespace std;

#include <iomanip>

using std::setw;

#include <cstdlib>   // contains function prototype for rand

int main()
{
// loop 20 times
for ( int counter = 1; counter <= 20; counter++ ) {

    // pick random number from 1 to 6 and output it
    cout << setw( 10 ) << ( 1 + rand() % 6 );

    // if counter divisible by 5, begin new line of output
    if ( counter % 5 == 0 )
        cout << endl;

}

return 0;  // indicates successful termination

} // end main

- 详情请见:http://www.programmingtunes.com/generation-of-random-numbers-c/#sthash.BTZoT5ot.dpuf

答案 10 :(得分:0)

如果使用条件检查最后一个数字是否与当前数字相同?如果满足条件,则生成另一个随机数。这个解决方案有效,但需要更多时间。