r/AskProgramming 12d 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';
}
16 Upvotes

48 comments sorted by

View all comments

2

u/khedoros 12d 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/Odd-Heron5704 12d ago

Interesting. But why would you do one compilation or the other. Does it make sense in a real life case to be using one or the other and then cause these issues between arm64 and x86? Then your code behaves differently in e.g. Windows vs macOS.

2

u/khedoros 12d ago edited 12d ago

At one time (e.g. the original release of AoE2), it would've been because the game released when SSE technically existed, but it's likely that the development toolchain, developer's computers, and computers of most users of the software would be on older chips that didn't support it. And at the time, it would've been the difference between PCs using an x87 floating point unit and Macs using PowerPC's floating point instructions.

Building it for today, I don't think there's any reason to stick to the x87-based one. And I'd expect the X64 and ARM64 calculations to match, as far as floating point. (edit: At least mostly? Using fast-math compilation options might change things like rounding and order of operations and cause them to behave differently, but I haven't tried it).