在 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
我在代码中的变量精度方面遇到了一些问题...
一段时间以来,我一直将变量声明为 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