gpt4 book ai didi

c++ - 在Valgrind下T == long double的std::uniform_real_distribution 和std::numeric_limits ::max()出现问题

转载 作者:行者123 更新时间:2023-12-01 14:38:59 24 4
gpt4 key购买 nike

我对以下代码有疑问:

#include <cassert>
#include <limits>
#include <random>

int main() {
using T = long double;
std::mt19937 engine{ std::random_device{}() };
const auto max = std::numeric_limits<T>::max();
const auto res = std::uniform_real_distribution<T>(0., max)(engine);
assert(res < max);
}
此代码可以作为独立程序正确执行。不幸的是,在瓦尔格朗德统治下,这一主张未能得到满足。仅对于 T == long double会出现问题,即 doublefloat情况不成问题。
您能解释问题的本质吗?
(我在GNU / Linux x86_64上使用GCC 9.3.0和Valgrind 3.15.0。我为-G0和-leak-check = full --show-leak-kinds = all --errors-for使用了-O0 -g标志。 -leak-kinds = all --run-cxx-freeres =是(对于Valgrind)。

最佳答案

这里的问题是Valgrind不完全支持long double。手册reads:

Valgrind has the following limitations in its implementation of x86/AMD64 floating point relative to IEEE754.

There is no support for 80 bit arithmetic. Internally, Valgrind represents all such "long double" numbers in 64 bits, and so there may be some differences in results. ...


考虑以下简单代码:
int main() {
auto max = static_cast<long double>(std::numeric_limits<double>::max());
std::cout << std::hexfloat << max << std::endl;
}
如果在Valgrind下独立运行,则输出是相同的:
0xf.ffffffffffff8p+1020
现在,让我们尝试通过添加以下行来打印下一个可表示的值
max = std::nextafter(max, std::numeric_limits<long double>::max());
在没有Valgrind的情况下,我们得到了预期的输出,但是在Valgrind下得到了不同的输出:
0xf.ffffffffffff801p+1020    // no Valgrind
0xf.ffffffffffff8p+1020 // under Valgrind
如果我们尝试打印 std::numeric_limits<long double>::max()值本身,则会观察到类似的不一致:
0xf.fffffffffffffffp+16380   // no Valgrind
0x8p+16381 // under Valgrind
难怪 std::uniform_real_distribution<long double>会以某种依赖于实现的方式通过 std::numeric_limits<long double>::max()失败。

关于c++ - 在Valgrind下T == long double的std::uniform_real_distribution <T>和std::numeric_limits <T>::max()出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63120330/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com