我对Fortran 90中的kind
参数感到困惑。据我所知,它既不能确定变量的精度(即float或double),也不能确定变量的类型。
那么,它到底是用来干什么的?它确定了什么?
我对Fortran 90中的kind
参数感到困惑。据我所知,它既不能确定变量的精度(即float或double),也不能确定变量的类型。
那么,它到底是用来干什么的?它确定了什么?
变量的KIND是一个整数标签,告诉编译器应该使用其支持的哪种类型。
请注意,尽管在KIND参数与该类型的变量中存储的字节数相同是常见的,但这不是Fortran标准所要求的。
也就是说,在许多系统上,
REAl(KIND=4) :: xs ! 4 byte ieee float
REAl(KIND=8) :: xd ! 8 byte ieee float
REAl(KIND=16) :: xq ! 16 byte ieee float
但是可能会有编译器例如:
REAL(KIND=1) :: XS ! 4 BYTE FLOAT
REAL(KIND=2) :: XD ! 8 BYTE FLOAT
REAL(KIND=3) :: XQ ! 16 BYTE FLOAT
同样适用于整数和逻辑类型。!--! specific precisions, usually same as real and double precision
integer, parameter :: r6 = selected_real_kind(6)
integer, parameter :: r15 = selected_real_kind(15)
那么我之后可能会声明一个变量,例如:
real(kind=r15) :: xd
请注意,这可能会在使用混合语言程序且需要绝对指定变量占用的字节数时导致问题。如果您需要确保,有查询内部函数可以告诉您每种类型的信息,从中您可以推断出变量的内存占用、精度、指数范围等等。或者,您可以回退到非标准但常见的real * 4
,real * 8
等声明样式。kindfinder.f90
,获取一个便利程序,以告诉您编译器可用的类型。real32
kind值,64位的real64
等等。这些类型的优点是可移植性强,至少只要有Fortran 2003或2008编译器即可。请参考gfortran手册中这两个模块中kind的列表。 - M. S. B.REAL(n)
和REAL(kind=n)
它们总是同一个东西,对吗? - Eularreal(kind=dp)
和 real(dp)
声明了 a 和 b,它们看起来意思相同。 - ZeroTwocharacter(4)
表示长度为 4 的字符串。character(c_char)
表示长度为 c_char 的字符串。character(kind=c_char)
表示长度为 1 的单个字符。 - Vladimir F Героям слава我建议使用Fortran 2008或更新版本; INT8, INT16, INT32, INT64, REAL32, REAL64, REAL128
。这可以通过在Fortran 2003或更新版本中调用ISO_FORTRAN_ENV
来实现。Kind参数提供的方式不一致,无法确保总是获得适当的位数表示。
int8
会指定一个类型参数。我猜你的意思是应该优先选择它,而不是像 int(kind=1)
这样显式地使用数字?(无论如何,后者都是不好的实践。)也许你可以澄清一下? - francescalusSELECTED_REAL_KIND()
。 - André Chalella从《Portland Group Fortran参考手册》中可以得知,KIND
参数“指定了内置数据类型的精度”。因此,在声明中:
real(kind=4) :: float32
real(kind=8) :: float64
float64
声明为8字节实数(旧的 Fortran DOUBLE PRECISION
),变量 float32
声明为4字节实数(旧的 Fortran REAL
)。这样做很好,因为它允许您独立于编译器和计算机设置变量的精度。如果您运行需要比传统的 IEEE 单精度实数更高精度的计算(如果您正在学习数值分析课程,这是非常可能的),但将您的变量声明为 real :: myVar
,那么如果编译器将所有real
值默认为双精度,则不会出现问题,但更改编译器选项或将代码移动到具有不同默认大小的real
和integer
变量的不同机器上可能会导致一些可能令人不快的惊喜(例如,您的迭代矩阵求解器爆炸)。KIND
参数-SELECTED_INT_KIND
和 SELECTED_REAL_KIND
,但如果您刚开始学习,我不会在这个时候担心这些。kind 的一个用途是确保在不同的机器或操作系统上,它们真正使用相同的精度,并且结果应该是相同的。因此代码是可移植的。例如:
integer, parameter :: r8 = selected_real_kind(15,9)
real(kind=r8) :: a
现在这个变量a始终是r8类型,这是真正的“双精度”(因此它在电子计算机上占用64位内存),无论代码运行在什么机器/操作系统上。
因此,您可以编写类似以下的内容:
a = 1.0_r8
而这个 _r8 确保将 1.0 转换为 r8 类型。
selected_real_kind
,你要求的是最小十进制精度和范围。你并没有要求存储大小、基数、IEEE 符合性或完全的范围和精度。在 Fortran 语言中,并没有规定你将会得到一个具有此种类参数的 8 字节实数。 - francescalusselected_real_kind()
不会返回字节数。storage_size()
返回的是位数。我再说一遍,selected_real_kind()
不是用于选择任何字节的,而是用于选择数字精度、基数等。这就是最高得票答案,我也点赞了,非常好地解释了这一点。请再次阅读它,因为你还没有理解它。 - Vladimir F Героям славаreal :: abc
,然后使用编译选项-fdefault-real-8
(对于gfortran)编译代码,以指定一个8字节的浮点数。对于ifort,相应的选项是-r8
。selected_real_kind
。如果您关心特定的存储大小,请使用iso_fortran_env
类型常量。有关更多详细信息,请参阅此答案。 - Rodrigo Rodrigues-fdefault-real-8
是邪恶的,我是在说这不是Fortran社区最推荐的方法,因为当你查看代码时,它隐含地改变了你期望的行为。求助论坛上到处都是这样的问题:_“为什么我的库调用(Lapack、mkl等)在函数签名似乎匹配传递的参数时失败或给出错误的结果?”_哦,这是因为在makefile中有一行(与源代码完全不相关),它说在这个项目中,double precision
实际上意味着double double precision
... ¬¬ - Rodrigo Rodrigues