Poniższy kod działa w programie Visual Studio 2008 z optymalizacją i bez niej. Ale działa tylko na g ++ bez optymalizacji (O0).
#include <cstdlib>
#include <iostream>
#include <cmath>
double round(double v, double digit)
{
double pow = std::pow(10.0, digit);
double t = v * pow;
//std::cout << "t:" << t << std::endl;
double r = std::floor(t + 0.5);
//std::cout << "r:" << r << std::endl;
return r / pow;
}
int main(int argc, char *argv[])
{
std::cout << round(4.45, 1) << std::endl;
std::cout << round(4.55, 1) << std::endl;
}
Wynik powinien być:
4.5
4.6
Ale g ++ z optymalizacją ( O1
- O3
) wyświetli:
4.5
4.5
Jeśli dodam volatile
słowo kluczowe przed t, to działa, więc czy może wystąpić jakiś błąd optymalizacji?
Test na g ++ 4.1.2 i 4.4.4.
Oto wynik na ideone: http://ideone.com/Rz937
Opcja, którą testuję na g ++, jest prosta:
g++ -O2 round.cpp
Ciekawszy wynik, nawet jeśli włączę /fp:fast
opcję na Visual Studio 2008, wynik nadal jest poprawny.
Kolejne pytanie:
Zastanawiałem się, czy zawsze powinienem włączać -ffloat-store
opcję?
Ponieważ testowana przeze mnie wersja g ++ jest dostarczana z CentOS / Red Hat Linux 5 i CentOS / Redhat 6 .
Skompilowałem wiele moich programów na tych platformach i obawiam się, że spowoduje to nieoczekiwane błędy w moich programach. Wydaje się, że trochę trudno jest zbadać cały mój kod C ++ i używane biblioteki, czy mają takie problemy. Jakieś sugestie?
Czy ktoś jest zainteresowany tym, dlaczego nawet /fp:fast
włączony, Visual Studio 2008 nadal działa? Wygląda na to, że Visual Studio 2008 jest bardziej niezawodny w tym problemie niż g ++?