fortran - 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
解决方案
不同之处在于使用不同的运行时库。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 吗?)。您可能会尝试从那里获取日志功能并将其与您的程序链接,但您必须深入挖掘内部结构。
推荐阅读
- php - mysqli_fetch_array() 期望参数 1 为 mysqli_result - 需要 helpsssss
- laravel - Laravel Eloquent 获取仅属于属于 shop 的用户的日志
- output - Azure 流分析:SQL 输出不起作用
- c - 如何将结构指向特定地址
- c++ - 为什么我将矢量保存到文件然后再次读取它的方法不起作用?
- c - 在内存分配过程中,“void*”指针声明和“void”关键字有什么关系?
- python - Docker 和 pip install:避免在已经安装了一些包的情况下安装所有包
- python - 使用两列作为变量的从长到宽的数据框
- azure - 从 Azure Functions / Azure VM 远程触发 Jenkins 作业
- python - 使用 Docker 运行文件夹中的每个文件