如何在 Windows 上的 Microsoft C++ 和 Linux 上的 GCC 之间获得相同的算术结果?

问题描述

我有一个非常简单的 C++ 程序示例,它在编译和执行时会在 MS C++ 和 GCC 之间产生不同的结果

#include <iomanip>
#include <iostream>
#include <limits>
#include <math.h>

int main()
{
  double arg = -65.101613720114472;
  double result = std::exp2(arg);
  std::cout << std::setprecision(std::numeric_limits<double>::max_digits10) << result << std::endl;
  return 0;
}

在 Windows 上,我使用命令 Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29334 for x64 使用 cl example.cpp 编译它,并运行生成的可执行文件生成 2.5261637809256962e-20 作为文本输出

在 Linux 上,我使用命令 gcc version 9.3.0 (Ubuntu 9.3.0-10ubuntu2) 使用 g++ example.cpp 编译它并运行可执行文件生成 2.5261637809256965e-20 作为文本输出。注意最低有效位的区别

我尝试编译 32/64 位版本、不同级别的优化,在 Windows 上我尝试了 /fp: 标志的不同值,而在 Linux 上,-frounding、-mfpmath 等标志没有产生与上面的。

是否可以让我的上述程序在 Windows 和 Linux 上通过 std::exp2() 调用产生相同的结果?

如果没有,差异在哪里?它是特定于编译器实现的东西,还是 math.h 库的实现,还是我缺少的其他一些微妙之处?

编辑:只是为了澄清;

这不是关于双打的文本表示的问题。

arg double 的按位表示在两个平台上是相同的。结果 double 的按位表示在两个平台之间的最低有效位是不同的。 Windows 和 Linux 可执行文件都在同一台机器上运行,因此在相同的处理器架构上。

我最好的猜测是,由于编译器优化或 math.h 实现差异,exp2() 函数的实现在两个平台之间以稍微不同的顺序执行一些计算。

如果有人知道实现差异在哪里,或者是否可以在任一编译期间使用编译器标志使它们匹配,那么这就是这个问题的答案。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)