不同的浮点结果与启用优化 - 编译器错误? [英] Different floating point result with optimization enabled - compiler bug?

查看:187
本文介绍了不同的浮点结果与启用优化 - 编译器错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码适用于带有和不带优化的Visual Studio 2008。但它只适用于没有优化(O0)的g ++。

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;
}

输出应为:

4.5
4.6

与优化( O1 - O3 )将输出:

But g++ with optimization (O1 - O3) will output:

4.5
4.5

code> volatile 关键字在t之前,它的工作原理,所以可能会有某种优化bug吗?

If I add the volatile keyword before t, it works, so might there be some kind of optimization bug?

在g ++ 4.1上测试。 2和4.4.4。

Test on g++ 4.1.2, and 4.4.4.

以下是ideone的搜索结果:
http ://ideone.com/Rz937

Here is the result on ideone: http://ideone.com/Rz937

我在g ++上测试的选项很简单:

And the option I test on g++ is simple:

g++ -O2 round.cpp

,即使我在Visual Studio 2008上打开 / fp:fast 选项,结果仍然是正确的。

The more interesting result, even I turn on /fp:fast option on Visual Studio 2008, the result still is correct.

strong>进一步的问题:

Further question:

我想知道,是否应该始终打开 -ffloat-store 选项?

I was wondering, should I always turn on the -ffloat-store option?

因为我测试的g ++版本是 CentOS / Red Hat Linux 5和CentOS / Redhat 6

Because the g++ version I tested is shipped with CentOS/Red Hat Linux 5 and CentOS/Redhat 6.

我在这些平台下编译了许多程序,我担心会在我的程序中导致意外的错误。看起来有点难以调查所有我的C ++代码和使用的库,无论他们是否有这样的问题。任何建议?

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?

有人对为什么甚至 / fp:fast 开启感兴趣,Visual Studio 2008仍然工作?看起来Visual Visual Studio 2008在这个问题上比g ++更可靠?

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++?

推荐答案

Intel x86处理器使用80位扩展精度在内部,而 double 通常为64位宽。不同的优化级别影响CPU的浮点值保存到内存中的频率,从而从80位精度到64位精度。

Intel x86 processors use 80-bit extended precision internally, whereas double is normally 64-bit wide. Different optimization levels affect how often floating point values from CPU get saved into memory and thus rounded from 80-bit precision to 64-bit precision.

使用<$ c $

或者,使用<$ c $

Alternatively, use the long double type, which is normally 80-bit wide on gcc to avoid rounding from 80-bit to 64-bit precision.

man gcc 说:

   -ffloat-store
       Do not store floating point variables in registers, and inhibit
       other options that might change whether a floating point value is
       taken from a register or memory.

       This option prevents undesirable excess precision on machines such
       as the 68000 where the floating registers (of the 68881) keep more
       precision than a "double" is supposed to have.  Similarly for the
       x86 architecture.  For most programs, the excess precision does
       only good, but a few programs rely on the precise definition of
       IEEE floating point.  Use -ffloat-store for such programs, after
       modifying them to store all pertinent intermediate computations
       into variables.

这篇关于不同的浮点结果与启用优化 - 编译器错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆