我问的主要是出于学术兴趣。
documentation说std::uniform_real_distribution
生成[a,b)
范围内的数字,其中a
和b
是构造函数参数。
由于上限是互斥的,因此我希望.max()
返回小于.b()
的最大可表示值。
但是我在GCC,Clang和MSVC上都得到了.b() == .max()
。 (对于float
,double
和long 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
,但不能解释double
和long double
。
我认为也可以打印
std::nextafter(d.b(), d.a())
。 – StoryTeller
对于long double
,其计算结果为0.9999999999999999999457898913757247782996273599565029144287109375
,这是我期望从.max()
得到的结果。
答案 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问题更好。 。 。