在 Fortran 中定义指数

Defining Exponent in Fortran

我在代码中的变量精度方面遇到了一些问题... 一段时间以来,我一直将变量声明为 real(kind=8) :: var,我现在明白这不是很便携并且有一些其他的复杂性,但基本上我在数值计算中有很多不精确之处。

现在我正在使用:

INTEGER,  PARAMETER :: R8 = SELECTED_REAL_KIND (30, 300)
with variable declaration: real(R8) :: var1,var2.

之前我通常将变量初始化为var1 = 1.0D0,现在我使用var1 = 1.0_R8,但我应该如何处理var1 = 1.0D-20?我有 运行 一个简单的代码,它证明 1.0D-20 不会给我一个准确的结果,但像 10.0_r8**(-20.0_r8) 这样的东西会。有没有更简单的方法来定义变量?我知道 1D-20 非常小,但我使用的代码确实需要 30 位小写精度。

感谢您的帮助!

这里确实发生了两件事。首先,使用 d 表示法声明指数与将其声明为类型 double precision.

相同

其次,您声明的 r8 变量需要比大多数(所有?)8 字节表示更精确。所以你 实际上 将你的大部分变量声明为 quad,然后将它们初始化为 double,这就是问题的根源。

如评论中所述,您明确问题的答案是使用以下符号声明指数

real(mytype) :: a = 1.23e-20_mytype

这种表示法很麻烦,但很容易习惯常量声明。

这是我用来测试您的类型的一些示例代码:

program main
   use ISO_FORTRAN_ENV, only : REAL64 => REAL64, REAL128
   implicit none

   INTEGER,  PARAMETER :: R8 = SELECTED_REAL_KIND (30, 300)
   real(r8) :: x, y, z
   real(REAL64) :: a, b, c

   x = 1.23d-20
   y = 1.23e-20_r8
   z = 1.23_r8*(10._r8**-20)

   write(*,*) x
   write(*,*) y
   write(*,*) z


   a = 1.23d-20
   b = 1.23e-20_REAL64
   c = 1.23_REAL64*(10._REAL64**-20)

   write(*,*) a
   write(*,*) b
   write(*,*) c

   write(*,*) 'Types: ', REAL64, R8, REAL128

end program main

对于 Intel 16.0,这给出:

mach5% ifort main.f90 && ./a.out
  1.230000000000000057423043720037598E-0020
  1.230000000000000000000000000000000E-0020
  1.230000000000000000000000000000002E-0020
  1.230000000000000E-020
  1.230000000000000E-020
  1.230000000000000E-020
 Types:            8          16          16