【问题标题】:Getting double precision in fortran 90 using intel 11.1 compiler使用 intel 11.1 编译器在 fortran 90 中获得双精度
【发布时间】:2011-07-12 21:35:09
【问题描述】:

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

【问题讨论】:

    标签: double fortran precision


    【解决方案1】:

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

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

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

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

    等等

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

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

    DBLE(实变量)-> 双精度

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

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

        如果一个双精度值乘以一个末尾没有“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
        

        【讨论】:

          【解决方案4】:

          如果你写成 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
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-03
            • 2011-02-04
            • 2010-12-04
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多