使用intel 11.1编译器在fortran 90中获得双精度

时间:2011-03-10 17:06:18

标签: double fortran precision

我有一个非常大的代码,它设置并迭代地解决了用fortran编写的非线性偏微分方程组。我需要所有变量都是双精度。在我为代码编写的附加模块中,我将所有变量声明为双精度类型,但我的模块仍然使用旧源代码中声明为真实类型的变量。所以我的问题是,当一个单精度变量乘以fortran中的双精度变量时会发生什么?如果用于存储值的变量声明为双精度,结果是否为双精度?如果双精度值乘以一个常数而没有“D0”结尾怎么办?我是否可以在Intel 11.1中设置编译器选项以使所有实数/双精度/常数具有双精度?

4 个答案:

答案 0 :(得分:4)

所以我的问题是,当单精度变量乘以fortran中的双精度变量时会发生什么?单精度提升为双精度,操作以双精度完成。

如果用于存储值的变量声明为双精度,结果是否为双精度?不一定。右侧是一个表达式,它不会“知道”左侧的变量的精度,它将存储在该变量中。如果你有Double = SingleA * SingleB(使用名称来表示类型),计算将以单精度执行,然后转换为double进行存储。这不会获得额外的计算精度!

如果双精度值乘以一个不带“D0”的常量怎么办?这就像第一个问题一样,常量将被提升为双精度和计算以双精度完成。 然而,常量仍然是单精度,即使您记下双精度常量的多位数,内部存储也是单精度,不能表示精度。例如,DoubleVar * 3.14159265359将以双精度计算,但是将以Double精度完成Doublevar * 3.14159的近似值。

如果要让编译器在常量中保留多个数字,则必须指定常量的精度。 Fortran 90这样做的方法是用你需要的精度来定义你自己的真实类型,例如,要求至少14个十进制数字:

integer, parameter :: DoubleReal_K = selected_real_kind (14)
real (DoubleReal_K) :: A
A = 5.0_DoubleReal_K
A = A * 3.14159265359_DoubleReal_K

答案 1 :(得分:3)

Fortran标准对此非常具体;其他语言也是这样,它真的是你所期待的。如果表达式包含对两个不同精度的浮点变量的操作,则表达式具有更高精度操作数的类型。例如,

(实变量)+(双变量) - > (双)

(双变量)*(实变量) - > (双)

(双变量)*(实常数) - > (双)

现在,如果将结果存储在精度较低的浮点变量中,它将再次进行下转换。但是如果你将它存储在更高精度的变量中,它将保持它的精度。

如果您担心单精度浮点变量导致问题,您可以强制将其转换为双精度 使用DBLE()内在函数:

DBLE(实变量) - >双

答案 2 :(得分:2)

如果以0.1D0的形式写入数字,则将其视为双精度数,否则如果写入0.1,则转换中的精度将丢失。 这是一个例子:

program main
implicit none
real(8) a,b,c
a=0.2D0
b=0.2
c=0.1*a
print *,a,b,c
end program

使用

编译时
ifort main.f90

我得到了结果:

0.200000000000000       0.200000002980232       2.000000029802322E-002

使用

编译时
ifort -r8 main.f90

我得到了结果:

0.200000000000000       0.200000000000000       2.000000000000000E-002

如果使用IBM XLF编译器,则等效性为

xlf -qautodbl=dbl4 main.f90

答案 3 :(得分:1)

Jonathan Dursi's answer是正确的 - 问题的另一部分是,是否有办法使所有实变量具有双精度。

您可以使用ifort编译器通过-i8(对于整数)和-r8(对于reals)选项来完成此操作。我不确定是否有办法强制编译器将文字解释为双精度而不指定它们(例如通过将3.14159265359更改为3.14159265359D0) - 我们不久前遇到了这个问题。