C++ rand()介于0和1之间

C++ rand()介于0和1之间,c++,random,C++,Random,所以下面的代码使0>32)}; 种子(ss); //初始化0和1之间的均匀分布 标准:均匀实分布unif(0,1); //准备好生成随机数了吗 const int nSimulations=10; 对于(int i=0;i0;i--)//尝试一千次 { int randnum=(双)rand()/(双)rand_MAX+1); std::不能尝试在最后一个之后添加1)注意,无论如何都应该使用它。如果没有C++11,请使用.Algebra错误。如果r是从零到m范围内的随机数,则比率r/m将在(0,

所以下面的代码使0
r = ((double) rand() / (RAND_MAX))
为什么拥有
r=((double)rand()/(rand_MAX+1))
会使-1 在RAND_MAX中添加一个不应该使1 编辑:我收到一条警告:表达式中存在整数溢出


在那条线上,所以这可能是问题所在。我只是做了
coutNo,因为RAND_MAX通常被扩展为MAX_INT。所以添加一个(显然)将其设置为MIN_INT(尽管我被告知它应该是未定义的行为),因此符号颠倒

要获得所需内容,需要将+1移到计算之外:

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

没有。它使
0我的猜测是
RAND_MAX
等于
INT_MAX
,所以你将其溢出为负值

只要这样做:

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

<>或更好,使用C++ 11的随机数生成器。

< P>这完全是<强>实现特定< /强>,但是似乎在C++环境中工作,<代码> RANDMAX等于InthMax < /C> > < /P> 因此,
RAND_MAX+1
表现出未定义的(溢出)行为,并成为
INT_MIN
。当您的初始语句被除(随机#在0和
INT_MAX
)/(
INT_MAX
)并生成值
0时,这是正确的方法:

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

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

  • 可以生成的不同随机数太少:32768。如果需要更多不同的随机数,则需要不同的方法(下面给出了一个代码示例)
  • 生成的数字过于粗粒度:可以得到1/32768、2/32768、3/32768,但这两者之间不能有任何差别
  • 随机数生成器引擎的有限状态:生成RAND_MAX随机数后,实现通常开始重复相同的随机数序列
  • 由于rand()的上述限制,生成0(包括)和1(排除)之间的随机数的更好选择是以下代码段(类似于中的示例):

    #包括
    #包括
    #包括
    int main()
    {
    标准:mt19937\U 64 rng;
    //使用时间相关种子初始化随机数生成器
    uint64_t timeSeed=std::chrono::高分辨率_clock::now().time_自_epoch().count();
    std::seed_seq ss{uint32_t(timeSeed&0xffffffff),uint32_t(timeSeed>>32)};
    种子(ss);
    //初始化0和1之间的均匀分布
    标准:均匀实分布unif(0,1);
    //准备好生成随机数了吗
    const int nSimulations=10;
    对于(int i=0;i
    
    #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 ;
        }
    } 
    
    #包括“pch.h”
    #包括
    #包括
    #包括
    int main()
    {
    srand(时间(空));
    for(int i=1000;i>0;i--)//尝试一千次
    {
    int randnum=(双)rand()/(双)rand_MAX+1);
    
    std::不能尝试在最后一个
    之后添加
    1
    注意,无论如何都应该使用它。如果没有C++11,请使用.Algebra错误。如果
    r
    是从零到
    m
    范围内的随机数,则比率
    r/m
    将在
    (0,1)
    范围内,但
    r/(m+1)
    将位于范围
    (0,m/(m+1))
    而不是范围
    (1,2)
    。如果
    m
    非常大(与1相比),则
    m/(m+1)
    大约为1,因此表达式
    r=((double)rand()/(rand_MAX+1))
    将给出一个大约在范围(0,1)内的随机数-也就是说,如果没有溢出。添加一个可能会使其处于最小值,但它仍然是UB。添加一个会导致未定义的行为,就像所有溢出一样。这是错误的和误导性的,因为它似乎有效。请更正您的答案或删除它。我同意,我已相应地进行了编辑。但这似乎是观察到的行为。@LuchianGrigore:只是为了澄清,仅针对签名溢出。为什么要在
    RAND_MAX
    周围加括号?@ssc以强调与OP代码的区别。这些括号没有技术原因。OP尝试使用它的理由是错误的,但如果这是必要的,则可以通过添加
    1.0
    而不是1来避免UB,这将导致Erc>代码> RANDMAX < /代码>到代码>双< /代码>类型,因此避免整数溢出。@ SSC因为它是宏。除非你确切地知道它是如何定义的,否则你应该总是用宏来做它。考虑这样一个定义,定义RANDMAX 1 + 100,上面表达式的结果是什么?;- -)MAD物理学家,除非你确切地知道,宏I。它不是一个表达式,而是一个数字。RAND_MAX不能使无符号类型溢出,因此可以将其强制转换为无符号类型,就像您小心地“将其溢出为负数”这只是OP观察到的情况下发生的情况,并不是一个可靠的描述,因为溢出是UB,因此结果程序可能会执行任何操作。这修复了有符号整数溢出UB,同时保留OP的其余语义不变,但通过阅读他们真正尝试执行的操作的描述,我们可以清楚地看到它仍在执行esn无法产生期望的结果,因为他们将加法放在该位置是错误的。为什么是+1?假设RAND_MAX=2,那么RAND()如果你想让它返回一个介于0和1之间的数字,那么就返回0或1或2,你不应该将它除以2而不是3吗?0是包含的,1是独占的。如果1是包含的,1的概率非常小。天哪。我一直在尝试找出一个0到1的随机数生成器,在while循环中使用,这可能真的有效。我尝试了
    random_设备
    每种可能的方式,但都得到了相同的输出。我没有id
    double randd() {
      return (double)rand() / (RAND_MAX + 1.0);
    }
    
    #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;
    }
    
    #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 ;
        }
    }