均匀实分布的范围限制是多少?

时间:2016-11-27 07:20:28

标签: c++ random c++14

我想在double浮点范围的数字限制内创建一个随机数。我觉得这很容易:

#include <random>                                                                   
#include <cassert>                                                                  
#include <math.h>                                                                

int main()                                                                          
{                                                                                   
    double a = std::numeric_limits<double>::lowest();                               
    double b = std::numeric_limits<double>::max();                                  

    std::default_random_engine engine;                                           

    std::uniform_real_distribution<double> dist(a, b);                           
    assert(std::isfinite(dist(engine))); // this triggers!

    return 0;                                                                    
}                                                                                   

clang 3.8.0gcc 5.4.0的断言失败,因为dist(engine)的结果显然是inf。在构建nextafter(a,0)时,我尝试使用nextafter(b,0)a代替bdist,但得到的结果相同。

根据std::uniform_real_distribution,方法minmax应提供将返回的数字范围,但显然不是这样:

std::cout << dist.min() << ", " << dist.max() << std::endl;

这个输出是:

  

-1.79769e + 308,1.79769e + 308

并且,正如预期的那样,以下断言触发,证明了矛盾:

const auto rand = dist(engine);
assert(rand <= dist.max() && rand >= dist.min());

同样,两个编译器的结果相同。根据{{​​1}}和min的定义,上述断言不应该触发。发生了什么事?

1 个答案:

答案 0 :(得分:7)

您的代码显示未定义的行为,因为它违反了以下条件:

  

N4140§26.5.8.2.2[rand.dist.uni.real]

explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0);
     

需要: a ≤ bb − a ≤ numeric_limits<RealType>::max()

要回答您的问题,uniform_real_distribution的范围限制为[a/2,b/2],其中ablowestmax数字限制浮点类型的值。