C++ std::uniform_real_distribution 应该<double>只产生正数吗?

Should C++ std::uniform_real_distribution<double> only generate positive numbers?

本文关键字:gt lt uniform std real distribution C++ 应该 double      更新时间:2023-10-16

我试图在c++ (MSVC,虽然这对我来说不是太重要-我只是没有另一个编译器来测试)中生成一些随机双精度,我注意到我的快速程序从未生成负数:

#include <iostream>
#include <random>
#include <ctime>
int main() {
    std::mt19937 generator(clock());
    std::uniform_real_distribution<double>
        rand_dbl(std::numeric_limits<double>::min(),
                 std::numeric_limits<double>::max());
    std::cout << "Double Limits: (" << std::numeric_limits<double>::min()
              << "," << std::numeric_limits<double>::max() << ")"
              << std::endl << std::endl;
    int total_neg = 0;
    for (int i=0; i<100; i++) {
        double d = rand_dbl(generator);
        if (d<0) total_neg++;
        std::cout << d << " ";
    }
    std::cout << std::endl << std::endl
              << "Total negative random double is: " << total_neg << std::endl;
    return 0;
}

不管我让它生成多少个数,它永远不会生成一个负的。我理解为什么生成的大多数数字都在10307 - 10308范围内(这不是我想要的),但不是为什么这些数字总是正的。我尝试了几个不同的生成器(默认是mt19937, minstd_rand0),在这方面没有任何区别。

谁能描述一下为什么会这样?

按照您提供的限制设置它。std::numeric_limits<double>::min()给出最小的双精度,并将其用作分布的下界。

std::numeric_limits<double>::min()

将返回DBL_MIN,这是双精度体可以保存的最接近0的最小值。如果你想要最大的负值,那么你需要使用

std::numeric_limits<double>::lowest()

返回-DBL_MAX,这是双精度体所能保存的最大的负值

From cppreference:

对于非规范化的浮点类型,min返回规范化后的最小值。

(强调我的)

所以很正常你只能得到正的值

你能告诉我这些行显示了什么吗?

std::cout << "Double Limits: (" << std::numeric_limits<double>::min()
          << "," << std::numeric_limits<double>::max() << ")"
          << std::endl << std::endl;