psalong
psalong

Reputation: 519

GCC compiles program differently in 32-bit machine

I run into a situation that same program compiled on 32-bit machine gives different result than compiling it on 64-bit machine. Piece of code is like this

#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;
} 

I would expect a result as 1, but on 32-bit Linux I get the result 0. Probably the result of coef * (max - min) is 0.9999999... and assigned to int leads to 0. Two friends tried the same code on 64-bit machine and they got the result as 1. Why does it give the result 0 on 32-bit? May it be related to virtual machine? Test environment on my machine:

Upvotes: 2

Views: 2000

Answers (1)

that other guy
that other guy

Reputation: 123410

I can reproduce the problem on 64-bit Ubuntu 14.04 with gcc 4.8.4:

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

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

I believe @void_ptr is right. It's caused by x87 using 80bit math internally, while SSE2 uses 64bit.

This is what happens if you compile the 32bit executable with -ffloat-store to force 64bit floating point precision:

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

Here's what man gcc says about the issue:

   -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.

In any case, never rely on floating point being mathematically accurate.

Upvotes: 4

Related Questions