首页 > 解决方案 > Windows 和 Linux 上 Fortran 中 LOG10 的不同结果

问题描述

我一直在研究需要在 Windows 和 Linux 上运行的混合 C++/Fortran 数字代码,并追踪到 LOG10 函数的差异。我在 Linux 上使用 gcc/gfortran,在 Windows 上使用 MinGW。

这是一个例子:

PROGRAM FP
REAL VAL1, VAL2, ARG

DATA VAR1 / 12.5663710 /
DATA VAR2 / 10.6640625 /
DATA VAR3 / 1.08791232 /

ARG = VAR1 * VAR2 / VAR3
VAL1 = LOG10 (VAR1 * VAR2 / VAR3)
VAL2 = LOG10 (ARG)

WRITE (*,"(F30.25)") ARG
WRITE (*,"(F30.25)") LOG10(ARG)
WRITE (*,"(F30.25)") VAL1
WRITE (*,"(F30.25)") VAL2

END PROGRAM FP

在 Linux 上,我得到:

 123.1795578002929687500000000
   2.0905385017395019531250000
   2.0905385017395019531250000
   2.0905385017395019531250000

在 Windows 上,我得到

 123.1795578002929687500000000
   2.0905387401580810546875000
   2.0905387401580810546875000
   2.0905387401580810546875000

相同的值将进入 LOG10,但在 Linux 上出现 2.090538 50 ,在 Windows上出现 2.090538 74。这足以导致测试出现实质性问题。我该怎么做才能在两个平台上获得相同的答案?

我正在使用其他人的 Fortran 代码,并且不是其浮点实现细节方面的专家,但通过并排跟踪代码直到值出现分歧,我发现了问题。LOG10 似乎是罪魁祸首。

至于编译器版本,在 Linux 上我得到:

$ gfortran --version
GNU Fortran (Ubuntu 9.2.1-9ubuntu2) 9.2.1 20191008

在 Windows 上:

> gfortran --version
GNU Fortran (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0

标签: fortranprecisiongfortran

解决方案


不同之处在于使用不同的运行时库。log10函数实现并非来自 libgfortran 运行时库。相反,在 Linux 上,标准 C 库 GNU libc (GLIBC) 称为https://www.gnu.org/software/libc/manual/html_node/Exponents-and-Logarithms.html(它位于 libm 部分)。

其他编译器会做不同的事情。Intel Fortran 有自己的运行时库,它实际上在 Linux 上给出了答案 2.0905387401580810546875000。

在 Windows 上,它可能取决于您使用的 GCC 发行版。如果您使用的是 MinGW,则使用 Microsoft C 运行时库而不是 GNU C 库。

据我所知,GLIBC 在 Windows 上根本不可用(我可以在 windows 下使用 glibc 吗?)。您可能会尝试从那里获取日志功能并将其与您的程序链接,但您必须深入挖掘内部结构。


推荐阅读