Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows和Linux上Fortran中LOG10的不同结果_Fortran_Precision_Gfortran - Fatal编程技术网

Windows和Linux上Fortran中LOG10的不同结果

Windows和Linux上Fortran中LOG10的不同结果,fortran,precision,gfortran,Fortran,Precision,Gfortran,我一直在研究需要在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 = L

我一直在研究需要在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.09053850,Windows上会出现2.09053874。这一差异足以导致测试出现实质性问题。如何在两个平台上获得相同的答案

我正在使用其他人的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库GNULIBC(GLIBC)(在libm部分)

其他编译器的做法将有所不同。英特尔Fortran有自己的运行库,它在Linux上给出了答案2.0905387401580801546875000

在Windows上,它可能取决于您使用的GCC发行版。如果您使用的是MinGW,那么将使用MicrosoftC运行时库而不是GNUC库


据我所知,GLIBC在Windows上根本不可用()。您可以尝试从此处获取log函数并将其与程序链接,但您必须深入挖掘内部结构。

应通过将log10函数的参数提升为双精度,然后将结果转换回单精度,从而获得跨平台的一致答案。请尝试以下函数

`

`


对于Linux上的Intel和gfortran,我得到了
2.0905387401580801546875000
。如果在数组上工作,您甚至可以将函数
设置为elemental

可能是由于不同的默认线程状态。这不是同一个问题,而是相关的:这很有趣,并引发了一系列关于跨平台编写数字一致性代码的问题。更复杂的是,我的HP计算器给出2.0905386406923961539363101503375651,将结果之间的差异分开。@AndreasYankopolus计算器值的精度将是两倍甚至更高。为了在Fortran中获得更高的数值精度,可以使用双精度,在有限的情况下,甚至可以使用四倍精度。“种类”表示法是最好的方法,我希望GLIBC和Microsoft之间仍然会有一些差异,即使在双精度方面也是如此。谢谢,这就是我最终解决问题的原因。由于各种原因,我不想更改FORTRAN代码,所以我用<代码> -fDebug T-8/EXECUT>编译了它,并在调用C++代码中执行了浮点>双->浮点转换。
real function mylog10(rarg)
integer, parameter :: dp = selected_real_kind(15,9)
real, intent(in) :: rarg
mylog10=log10(real(rarg,kind=dp))
end function mylog10