Fortran/C中介语问题:结果在第14位不同

Fortran/C中介语问题:结果在第14位不同,c,fortran,floating-accuracy,C,Fortran,Floating Accuracy,我必须一起使用C和Fortran来做一些模拟。在他们的课程中,我在两个编程语言部分使用相同的内存,通过在C中定义一个指针来访问Fortran分配的内存。 问题变量的数据类型为 real(kind=8) 对于Fortran,以及 double 对于C,相同计算的结果在不同的编程语言中有所不同,我需要直接比较它们,得到一个零。所有计算仅在上述精度下进行。差异总是在13-14位之间 解决这个问题的好方法是什么?有编译器标志吗?几位数后就切断了 非常感谢 这是一个浮点数不准确的问题-它们将不准确,并

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

real(kind=8)
对于Fortran,以及

double
对于C,相同计算的结果在不同的编程语言中有所不同,我需要直接比较它们,得到一个零。所有计算仅在上述精度下进行。差异总是在13-14位之间

解决这个问题的好方法是什么?有编译器标志吗?几位数后就切断了


非常感谢

这是一个浮点数不准确的问题-它们将不准确,并且在某个位置。您通常通过将它们四舍五入到您知道将位于准确区域的数字,或通过提供适当值的ε(小到不会影响进一步的计算,大到足以在比较时考虑不准确度)来比较它们。

浮点不是完全准确的。永远


因此,在进行比较时,要考虑到这一点,并允许数值相差一些小的ε值。

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

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

由于您是为x86体系结构编译的,很可能其中一个编译器正在浮点寄存器中维护中间值,它是80位,而C
double的64位是80位


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

浮点计算并不精确。更改处理器、更改编译器、优化标志,或者有趣地看它,都可能会改变结果。在不同的处理器上运行相同的代码时,甚至会出现差异。10^-13精度相当准确。即使是量子力学也不需要那么高的精度。这就像地球直径上的1µm错误。我们可以知道你的程序是做什么的吗?首先,检查这是二进制值的差异,而不是字符串表示。不同的运行时可能会使用不同的方式对某个数字进行文本表示。另一种可能对您有用的解决方案是使用某人对任意精度数字的实现,或者在整数空间中实现您自己的存储和计算机制。我介绍了一个小epsilon,它工作得很好。谢谢由于项目的规模,我无法测试其他建议的解决方案,但我认为它们也值得一试。