c++ - GCC在32位机器上编译程序的方式不同

标签 c++ linux gcc

我遇到了这样的情况:在 32 位机器上编译的同一程序与在 64 位机器上编译的结果不同。一段代码是这样的

#include <iostream>

int main(int argc, char *argv[])
{
  int index = 1;
  int total = 21;
  int min = 79;
  int max = 100;

  double coef = index / (double)total;
  int ret1 = coef * (max - min);
  std::cout << ret1 << "\n";

  return 0;
} 

我期望结果为 1,但在 32 位 Linux 上我得到结果 0。可能 coef * (max - min) 的结果是 0.9999999...并且分配给 int 导致 0。两个 friend 尝试过相同的代码在 64 位机器上得到的结果是 1。为什么在 32 位机器上得到的结果是 0?可能和虚拟机有关? 我的机器上的测试环境:

  • 在 VMWare 6.0.7 上运行的 32 位 Linux Mint 17.2
  • 海湾合作委员会4.8.4
  • 用于构建的命令:g++ main.cpp -o main

最佳答案

我可以使用 gcc 4.8.4 在 64 位 Ubuntu 14.04 上重现该问题:

$ g++ -m32 main.c -o main && ./main
0

$ g++ -m64 main.c -o main && ./main
1

我相信@void_ptr是对的。 这是由于 x87 内部使用 80 位数学,而 SSE2 使用 64 位造成的。

如果使用 -ffloat-store 编译 32 位可执行文件以强制使用 64 位浮点精度,则会发生以下情况:

$ g++ -m32 -ffloat-store main.c -o main && ./main 
1

以下是 man gcc 关于该问题的说法:

   -ffloat-store
       Do not store floating-point variables in registers, and inhibit
       other options that might change whether a floating-point value is
       taken from a register or memory.

       This option prevents undesirable excess precision on machines such
       as the 68000 where the floating registers (of the 68881) keep more
       precision than a "double" is supposed to have.  Similarly for the
       x86 architecture.  For most programs, the excess precision does
       only good, but a few programs rely on the precise definition of
       IEEE floating point.  Use -ffloat-store for such programs, after
       modifying them to store all pertinent intermediate computations
       into variables.

无论如何,never rely on floating point being mathematically accurate

关于c++ - GCC在32位机器上编译程序的方式不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34644606/

相关文章:

c++ - 在 C++ 中双冒号前的符号是什么意思?

c++ - 如何强制 g++ 链接器加载不直接调用的符号 - 避免 undefined reference

c++ - Boost 仅序列化 std::wstring 的第一个字符

c++ - 如何在 Linux 上注册/捕获终端内鼠标单击的位置?

linux - 是否有任何工具可以在 linux 上进行命令行调试,而不是 gdb?

c - 如果在参数列表中使用了另一个类型定义的名称,则发出警告

C++ Google Protocol Buffer 打开 http 套接字

linux - Linux 中的远程桌面,如 Team Viewer

linux - 在 Linux 中查找静态系统库的路径

c++ - 如何在 gcc 错误消息中隐藏默认模板参数?