std::cos 使用 valgrind 运行时给出不同的结果

问题描述 投票:0回答:1

我发现了一个影响我工作中的多个单元测试的问题,这种问题仅在使用 valgrind 运行单元测试时才会发生,因为对于相同的输入,从 std::cos 和 std::sin 返回的值是不同的,具体取决于 if单元测试是独立运行的,而不是在 valgrind 下运行。

这个问题似乎只发生在某些特定的输入上,因为许多单元测试都通过了相同的代码。

这是一个最低限度可重现的示例(稍微恶化,以便我的编译器不会优化任何逻辑):

#include <complex>
#include <iomanip>
#include <iostream>

int main()
{
    std::complex<long double> input(0,0), output(0,0);

    input = std::complex<long double>(39.21460183660255L, -40);
    std::cout << "input: " << std::setprecision(20) << input << std::endl;

    output = std::cos(input);
    std::cout << "output: " << std::setprecision(20) << output << std::endl;

    if (std::abs(output) < 5.0)
    {
        std::cout << "TEST FAIL" << std::endl;
        return 1;
    }

    std::cout << "TEST PASS" << std::endl;
    return 0;
}

正常运行时输出:

input: (39.21460183660254728,-40)
output: (6505830161375283.1118,117512680740825220.91)
TEST PASS

在 valgrind 下运行时的输出:

input: (39.21460183660254728,-40)
output: (0.18053126362312540976,3.2608771240037195405)
TEST FAIL

备注:

  • 操作系统:红帽企业 Linux 7
  • 编译器:Intel OneAPI 2022 下一代 DPP/C++ 编译器
  • Valgrind:3.20(使用相同的编译器构建),也出现在 3.17 的官方发行版上
  • 当使用 GCC-7(无法返回到该编译器)或 GCC-11 构建单元测试时,问题并未显现(boost 的另一个较大错误阻止我们将其与 valgrind 一起使用)
  • -O0/1/2/3 在这个问题上没有区别
  • 我设置的唯一编译器标志是“-fp-speculation=safe”,否则如果未设置会导致其他单元测试中的数值精度问题

有没有更好的方法可以弄清楚发生了什么事情来解决这种情况,或者我应该向 valgrind 提交错误报告?我希望这个问题是良性的,但我希望能够相信我的 valgrind 输出。

c++ floating-point precision valgrind c++-standard-library
1个回答
0
投票

Valgrind 不支持 long double,并将所有值截断为 double。请参阅 Valgrind 手册中有关其核心限制的部分

来源:Valgrind 导致长双打的数字问题

© www.soinside.com 2019 - 2024. All rights reserved.