由于在C ++ std :: vector中使用内联函数而使用g ++ 4.4.7 20120313(32位)导致精度变化

时间:2013-11-15 08:34:36

标签: c++ gcc g++

我正在编译centos5.9 32位(在64位机器上运行),目标是32位。 g ++版本是4.4.7,它不是默认情况下在centos5.9上提供的版本,但它可以用yum下载并作为发行版的一部分提供。

我有一个非常简单的循环如下

std::vector<double> result(n);
std::vector<double> values(n);
// here I compute values(). They are correct and I extensively noted 
// that there's nothing wrong there. The problem is here
result[0] = 0.0;
for ( int i = 0 ; i < n-1 ; ++i ) {
    result[i+1] = result[i]+values[i];
    // printf("x");
}

在这个代码的一个更复杂的版本中(显示了完全相同的问题)我使用以下运算符将类封装std :: vector作为passthrough的类RealVector

inline double & operator[] (int index) { return data_[index]; }

问题在于我在结果中发现了一个微小但相关的数值差异,这取决于运算符[]是否内联。 同样,如果我取消注释上面给出的printf()行,我也会更改结果。 请注意,在具有相同配置的centos59 64位中不会出现此问题,或者如果出现问题,则该问题低于可检测性。

这是一个编译器错误,还是有一些微妙的魔法?我试图检查asm和解析树,但它太复杂了,无法理解。我通常使用C管理,但在C ++中,生成的文件中会出现太多黑暗魔法。

1 个答案:

答案 0 :(得分:8)

可能旧的x87有趣功能,80位寄存器。将该寄存器溢出到内存会导致四舍五入到64位,并且会在不可预测的时刻发生。完全不是C ++独有的,C也有同样的问题。在Java中它是“复杂的”

通过移动到64位版本和SSE来修复。