2011-03-10 79 views
3

我有一个非常大的代码,它设置并迭代地求解用fortran编写的非线性偏微分方程组。我需要所有变量为双精度。在我为代码编写的附加模块中,我将所有变量声明为双精度类型,但我的模块仍使用旧的源代码中声明为真实类型的变量。所以我的问题是,在fortran中单精度变量乘以双精度变量会发生什么?如果用于存储该值的变量被声明为双精度,那么结果是双精度的吗?那么如果一个双精度值在最后没有“D0”的情况下乘以一个常数呢?我可以在英特尔11.1中设置一个编译器选项来制作双精度的所有实数/双精度/常量吗?使用英特尔11.1编译器在Fortran 90中获得双精度

回答

3

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

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

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

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

现在,如果你把结果存储在一个较低精度浮点变量,它会得到再次向下转换。但是,如果您将它存储在更高精度的变量中,它将保持其精度。

如果有,你担心自己的单精度浮点变量导致问题的任何情况下,你可以强制其转换为双精度 使用DBLE()内部:

DBLE(真正的变量) - >双重

1

Jonathan Dursi's answer是正确的 - 你的问题的另一部分是如果有一种方法,使所有的实际变量双精度。

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

4

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

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

如果一个双精度值乘以一个常数而末尾没有“D0”会怎样?这就像第一个问题一样,常数将被提升为双精度并且以双精度完成计算。 然而,,该常数仍然是单精度,即使您记下许多数字作为双精度常数,内部存储是单精度,并不能表示该精度。例如,DoubleVar * 3.14159265359将以双精度计算,但会以双精度完成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 
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 
相关问题