The below code works on Visual Studio 2008 with and without optimization. But it only works on g++ without optimization (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;
}
The output should be:
4.5
4.6
But g++ with optimization (O1
- O3
) will output:
4.5
4.5
If I add the volatile
keyword before t, it works, so might there be some kind of optimization bug?
Test on g++ 4.1.2, and 4.4.4.
Here is the result on ideone: http://ideone.com/Rz937
And the option I test on g++ is simple:
g++ -O2 round.cpp
The more interesting result, even I turn on /fp:fast
option on Visual Studio 2008, the result still is correct.
Further question:
I was wondering, should I always turn on the -ffloat-store
option?
Because the g++ version I tested is shipped with CentOS/Red Hat Linux 5 and CentOS/Redhat 6.
I compiled many of my programs under these platforms, and I am worried it will cause unexpected bugs inside my programs. It seems a little difficult to investigate all my C++ code and used libraries whether they have such problems. Any suggestion?
Is anyone interested in why even /fp:fast
turned on, Visual Studio 2008 still works? It seems like Visual Studio 2008 is more reliable at this problem than g++?
-std=c++0x
and with any of-O0
,-O1
,-O2
and-O3
. – Slowdowng++ 4.4.3
on 64-bit Ubuntu 10.04. This prints out4.5 4.6
with and without-O1
..-O3
. – Revoltg++ -O3 x.cpp
, same for-O[012]
) – Peccavi