微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决如何在 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 举报,一经查实,本站将立刻删除。