Приведенный ниже код работает в Visual Studio 2008 с оптимизацией и без нее. Но работает только на g ++ без оптимизации (O0).
#include
#include
#include
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;
}
Результат должен быть:
4.5
4.6
Но g ++ с оптимизацией ( O1
- O3
) выведет:
4.5
4.5
Если я добавлю ключевое слово volatile
до t он работает, так что может быть какая-то ошибка оптимизации?
Протестируйте на g ++ 4.1.2 и 4.4.4.
Вот результат на ideone: http://ideone.com/Rz937
И вариант, который я тестирую на g ++, прост:
g++ -O2 round.cpp
Более интересный результат, даже я включите параметр / fp: fast
в Visual Studio 2008, результат все равно будет правильным.
Дополнительный вопрос:
Мне было интересно, всегда ли мне включать параметр -ffloat-store
?
Поскольку протестированная мной версия g ++ поставляется с CentOS / Red Hat Linux 5 и CentOS / Redhat 6 .
Я скомпилировал многие свои программы для этих платформ и опасаюсь, что это вызовет неожиданные ошибки в моих программах. Кажется немного сложным исследовать весь мой код C ++ и используемые библиотеки, есть ли у них такие проблемы. Есть предложения?
Кого-нибудь интересует, почему даже / fp: fast
включен, Visual Studio 2008 все еще работает? Кажется, Visual Studio 2008 более надежен в решении этой проблемы, чем g ++?