Niezgodność zmiennoprzecinkowa między kompilatorami (Visual Studio 2010 i GCC)
Próbuję rozwiązać problem międzyplatformowy, który pojawia się i nie jestem pewien, jak to zrobić. Oto program demonstracyjny:
#include <cmath>
#include <cstdio>
int main()
{
int xm = 0x3f18492a;
float x = *(float*)&xm;
x = (sqrt(x) + 1) / 2.0f;
printf("%f %x\n", x, *(int*)&x);
}
Dane wyjściowe systemu Windows po skompilowaniu w VS2010 to:
0.885638 3f62b92a
Wyjście po skompilowaniu z GCC 4.8.1(próbka ideone.com)jest:
0.885638 3f62b92b
Te małe niedopasowania kończą balonowanie w poważny problem w trakcie programu, który musi działać identycznie na wielu platformach. Nie przejmuję się tak bardzo „dokładnością”, jak wynikamipasują do siebie. Próbowałem zmienić/fp
tryb w VS dostrict
zprecise
, ale to nie wydaje się to naprawiać.
Na jakie inne sposoby należy zwrócić uwagę, aby obliczenia miały taki sam wynik na obu platformach?
AKTUALIZACJA: Co ciekawe, jeśli zmienię ten kod, pasuje on do różnych platform:
#include <cmath>
#include <cstdio>
int main()
{
int xm = 0x3f18492a;
float x = *(float*)&xm;
//x = (sqrt(x) + 1) / 2.0f;
float y = sqrt(x);
float z = y + 1;
float w = z / 2.0f;
printf("%f %x %f %x %f %x %f %x\n", x, *(int*)&x, y, *(int*)&y, z, *(int*)&z, w, *(int*)&w);
}
Nie jestem jednak pewien, czy realistycznie jest przechodzić przez kod i zmieniać wszystkie operacje zmiennoprzecinkowe takie jak ta!