rand()介于0和1之间

时间:2012-03-26 20:04:00

标签: c++ random

以下代码使0< r< 1

r = ((double) rand() / (RAND_MAX))

为什么让r = ((double) rand() / (RAND_MAX + 1))使-1< r< 0?

不应该向RAND_MAX添加一个使1< r< 2?

编辑:我收到警告:表达式中的整数溢出

在那一行,所以这可能是问题所在。我刚刚做了cout << r << endl,它肯定给了我介于-1和0之间的值

7 个答案:

答案 0 :(得分:73)

这完全是特定于实现的,但似乎在您正在使用的C ++环境中,RAND_MAX等于INT_MAX

因此,RAND_MAX + 1表现出未定义(溢出)行为,并变为INT_MIN。虽然您的初始陈述是划分(随机#在0和INT_MAX之间)/(INT_MAX)并生成值0 <= r < 1,但现在它正在划分(随机#在0和INT_MAX之间)/(INT_MIN),生成值-1 < r <= 0

为了生成随机数1 <= r < 2,您需要

r = ((double) rand() / (RAND_MAX)) + 1

答案 1 :(得分:21)

rand() / double(RAND_MAX)生成0(包括)和1(包含)之间的浮点随机数,但由于以下原因,它不是一个好方法(因为RAND_MAX通常是32767):

  1. 可生成的不同随机数的数量太少:32768。如果您需要更多不同的随机数,则需要采用不同的方式(下面给出一个代码示例)
  2. 生成的数字太粗糙:你可以得到1/32768,2 / 32768,3 / 32768,但两者之间绝不会有任何内容。
  3. 随机数生成器引擎的有限状态:在生成RAND_MAX随机数后,实现通常会重复相同的随机数序列。
  4. 由于rand()的上述限制,在0(包括)和1(独占)之间生成随机数的更好选择将是以下代码段(类似于{的示例{3}}):

    #include <iostream>
    #include <random>
    #include <chrono>
    
    int main()
    {
        std::mt19937_64 rng;
        // initialize the random number generator with time-dependent seed
        uint64_t timeSeed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
        std::seed_seq ss{uint32_t(timeSeed & 0xffffffff), uint32_t(timeSeed>>32)};
        rng.seed(ss);
        // initialize a uniform distribution between 0 and 1
        std::uniform_real_distribution<double> unif(0, 1);
        // ready to generate random numbers
        const int nSimulations = 10;
        for (int i = 0; i < nSimulations; i++)
        {
            double currentRandomNumber = unif(rng);
            std::cout << currentRandomNumber << std::endl;
        }
        return 0;
    }
    

    通过将unif(0, 1)替换为unif(1, 2),可以轻松修改以生成1(包括)和2(不包括)之间的随机数。

答案 2 :(得分:16)

不,因为RAND_MAX通常会扩展为MAX_INT。所以添加一个(显然)将它放在MIN_INT(虽然它应该是我所说的未定义的行为),因此标志的反转。

要获得你想要的东西,你需要在计算之外移动+1:

r = ((double) rand() / (RAND_MAX)) + 1;

答案 3 :(得分:3)

没有。它会生成0 <= r < 1,但您的原始版本为0 <= r <= 1

请注意,如果RAND_MAX + 1溢出,这可能会导致未定义的行为

答案 4 :(得分:2)

我的猜测是RAND_MAX等于INT_MAX,因此您将其溢出为负数。

这样做:

r = ((double) rand() / (RAND_MAX)) + 1;

甚至更好,使用C ++ 11的随机数生成器。

答案 5 :(得分:1)

这是正确的方法:

double randd() {
  return (double)rand() / ((double)RAND_MAX + 1);
}

double randd() {
  return (double)rand() / (RAND_MAX + 1.0);
}

答案 6 :(得分:0)

就我而言(我正在使用VS 2017),以下简单代码可以正常工作:

#include "pch.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>

int main()
{
    srand(time(NULL));

    for (int i = 1000; i > 0; i--) //try it thousand times
    {
        int randnum = (double)rand() / ((double)RAND_MAX + 1);
        std::cout << " rnum: " << rand()%2 ;
    }
} 
相关问题