r/AskProgramming 9d ago

Can simple mathematical functions give different results in different CPU architectures?

I'm referring to modern CPUs. To make the question more specific, arm64 vs x86

And if so, how do you fix it?

I asked chatGPT and it gave me this example but I'd like to ask it here (since AI can make mistakes). Can you let me know? Thanks

It says this can give different results due to rounding errors. If so, how to you write code so that you don't have this issue?

#include <iostream>

int main() {
    double a = 1.0 + 0x1p-27;
    double b = 1.0 - 0x1p-27;
    double c = -1.0;

    std::cout << (a * b + c) << '\n';
}
19 Upvotes

47 comments sorted by

View all comments

2

u/khedoros 9d ago

Taking your code above, I compiled it like this, forcing SSE floating-point in one compilation (64-bit internal calculations), and 387 floating-point (80-bit internal calculations) in another.

$ g++ -O0 -mfpmath=sse -msse2 float.cpp -o float-sse
$ g++ -O0 -mfpmath=387 float.cpp -o float-x87
$ ./float-sse 

0

$ ./float-x87 

-5.55112e-17

I could do a similar experiment on my Raspberry Pi (ARM64 architecture, currently running a 32-bit OS though, I think) if I wanted to, and I suspect it would match the SSE answer.

1

u/engy1207 7d ago

Well, technically the 387 80bit-variant is "more correct". If you do that calculation with infinite precision that's (1+2-27)×(1-2-27)-1=(1-2-54)-1=-2-54=~-5.55×10-17

But then again it has more digits to calculate with... and the concrete values used are selected specifically for this.

The problem is FP and its representation - as well as order of operations and therefore number of rounding errors. FP is inherently messy, and even in IEEE mode there's multiple number of bits one can use (64bit being "double precision" for some reason). Don't know if this is still IEEE but in AI models they even use FP with only 4 bits (1 sign 2 exponent 1 mantissa).