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

发布于 2024-10-13 18:19:01 字数 336 浏览 3 评论 0原文

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

real(kind=8)

适用于 Fortran 和

double

C。现在,相同计算的结果在各自的编程语言中有所不同,我需要直接比较它们并得到零。所有计算均仅按照上述精度进行。差异始终在第 13-14 位。

解决这个问题的好方法是什么?有编译器标志吗?只是在一些数字之后被截断吗?

非常感谢!

I have to use C and Fortran together to do some simulations. In their course I use the same memory in both programming language parts, by defining a pointer in C to access memory allocated by Fortran.
The datatype of the problematic variable is

real(kind=8)

for Fortran, and

double

for C. The results of the same calculations now differ in the respective programming languages, and I need to directly compare them and get a zero. All calculations are done only with the above accuracies. The difference is always in the 13-14th digit.

What would be a good way to resolve this? Any compiler-flags? Just cut-off after some digits?

Many thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

夏末的微笑 2024-10-20 18:19:01

浮点并不完全准确。曾经。 甚至 cos(x) == cos(y) 也可以如果 x == y 则为 false。

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

Floating point is not perfectly accurate. Ever. Even cos(x) == cos(y) can be false if x == y.

So when doing your comparisons, take this into account, and allow the values to differ by some small epsilon value.

百变从容 2024-10-20 18:19:01

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

This is a problem with the inaccuracy with floating point numbers - they will be inaccurate and a certain place. You usually compare them either by rounding them to a digit that you know will be in the accurate area, or by providing an epsilon of appropiate value (small enough to not impact further calculations, and big enough to take care of the inaccuracy while comparing).

樱&纷飞 2024-10-20 18:19:01

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

One thing you might check is to be sure that the FPU control word is the same in both cases. If it is set to 53-bit precision in one case and 64-bit in the other, it would likely produce different results. You can use the instructions fstcw and fldcw to read and load the control word value. Nonetheless, as others have mentioned, you should not depend on the accuracy being identical even if you can make it work in one situation.

把时间冻结 2024-10-20 18:19:01

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

Perfect portability is very difficult to achieve in floating point operations. Changing the order of the machine instructions might change the rounding. One compiler might keep values in registers, while another copy it to memory, which can change the precision. Currently the Fortran and C languages allow a certain amount of latitude. The IEEE module of Fortran 2008, when implemented, will allow requiring more specific and therefore more portable floating point computations.

用心笑 2024-10-20 18:19:01

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

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

Since you are compiling for an x86 architecture, it's likely that one of the compilers is maintaining intermediate values in floating point registers, which are 80 bits as opposed to the 64 bits of a C double.

For GCC, you can supply the -ffloat-store option to inhibit this optimisation. You may also need to change the code to explicitly store some intermediate results in double variables. Some experimentation is likely in order.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文