为什么std :: uniform_real_distribution :: max()返回互斥上限?

时间:2018-09-16 14:07:17

标签: c++

我问的主要是出于学术兴趣。

documentationstd::uniform_real_distribution生成[a,b)范围内的数字,其中ab是构造函数参数。

由于上限是互斥的,因此我希望.max()返回小于.b()最大可表示值。

但是我在GCC,Clang和MSVC上都得到了.b() == .max()。 (对于floatdoublelong double。)为什么?

#include <iostream>
#include <iomanip>
#include <random>

int main()
{
    auto d = std::uniform_real_distribution<long double>(0, 1);
    std::cout << std::setprecision(1000);
    std::cout << d.min() << '\n'; // 0
    std::cout << d.a() << '\n';   // 0 
    std::cout << d.max() << '\n'; // 1 <- Here I expect 0.99999...
    std::cout << d.b() << '\n';   // 1
}

我发现this note说一些常见的实现仅将[a,b]范围用于float。它可以为.b() == .max()解释float,但不能解释doublelong double


  

我认为也可以打印std::nextafter(d.b(), d.a())。 – StoryTeller

对于long double,其计算结果为0.9999999999999999999457898913757247782996273599565029144287109375,这是我期望从.max()得到的结果。

2 个答案:

答案 0 :(得分:1)

我不认为该错误与浮点数有关,而是与一般的浮点数有关。

该错误已在 VS-Dev-Community双打方面解决了这个问题。 但是,他们声称已于 2021 年 1 月 26 日修复此问题。

附注: 此外,我无法重现您为 long double 获得的 max() 值。在所有其他情况下,我得到 1。 如前所述,它只是随机噪声,因为 setprecision(n) 似乎对 n > numeric_limits::max_digits10 产生了噪声。

答案 1 :(得分:0)

这是一个已知的错误,由二进制格式的实数表示引起。可能会有舍入错误。

您已经自己给出了答案。

您正在链接到cppreference。在注释中,这里是指向LWG issue 2524

的进一步链接

这再次链接到提出解决方案的P0952

请检查结果值。如果为1,则再次调用该函数。这将使理想分布的统计偏差很小。但是比通过计算1 /(1-r)并使下一个月球火箭坠毁而获得inf问题更好。 。 。