首页 > 解决方案 > 为什么 std::uniform_real_distribution::max() 返回独占上限?

问题描述

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

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

由于上限是独占的,我希望.max()返回小于的最大可表示值.b()

但相反,我.b() == .max()同时使用 GCC、Clang 和 MSVC。(对于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
}

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


我认为 print 也可能具有教育意义std::nextafter(d.b(), d.a())。- 说故事的人

因为long double它评估为0.9999999999999999999457898913757247782996273599565029144287109375,这是我期望从中得到的.max()

标签: c++

解决方案


我不认为这个错误是关于浮点数的,而是关于浮点数的。

该错误已在 VS-Dev-Community中提到, 其中针对doubles解决了此问题。但是,他们声称自 2021 年 1 月 26 日起将其修复。

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


推荐阅读