Reputation: 519
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
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