Fortran / C Interlanguage问题:第14位数字的结果不同

时间:2011-01-24 20:46:17

标签: c fortran floating-accuracy

我必须一起使用C和Fortran进行一些模拟。在他们的课程中,我在两个编程语言部分使用相同的内存,通过在C中定义一个指针来访问Fortran分配的内存。 有问题的变量的数据类型是

real(kind=8)

表示Fortran,

double
对于C,

现在,相同的计算结果在各自的编程语言中有所不同,我需要直接比较它们并获得零。所有计算仅在上述精度的情况下完成。差异始终在13-14位。

解决这个问题的好方法是什么?任何编译器标志?只是在一些数字后截止?

非常感谢!

5 个答案:

答案 0 :(得分:2)

这是浮点数不准确的问题 - 它们将是不准确的和某个地方。您通常通过将它们四舍五入到您知道将在准确区域中的数字进行比较,或者通过提供适当值的epsilon(小到足以不影响进一步的计算,并且大到足以在比较时处理不准确性)来比较它们

答案 1 :(得分:2)

浮点不完全准确。永远。 Even cos(x) == cos(y) can be false if x == y.

因此,在进行比较时,请考虑到这一点,并允许值因某些小的epsilon值而异。

答案 2 :(得分:2)

您可以检查的一件事是确保FPU control word在两种情况下都相同。如果在一种情况下设置为53位精度而在另一种情况下设置为64位,则可能会产生不同的结果。您可以使用说明fstcwfldcw来读取和加载控制字值。尽管如此,正如其他人所提到的,即使你可以在一种情况下使其工作,你也不应该依赖于相同的准确性。

答案 3 :(得分:1)

在浮点运算中很难实现完美的可移植性。更改机器指令的顺序可能会更改舍入。一个编译器可能将值保留在寄存器中,而另一个编译器将其复制到内存中,这可以改变精度。目前,Fortran和C语言允许一定的纬度。 Fortran 2008的IEEE模块在实现时,将允许更具体,因此更便携的浮点计算。

答案 4 :(得分:1)

由于您正在编译x86架构,因此其中一个编译器可能在浮点寄存器中维护中间值,这些值是80位而不是C double的64位。

对于GCC,您可以提供-ffloat-store选项来禁止此优化。您可能还需要更改代码以在double变量中显式存储一些中间结果。有些实验可能是有序的。