我无法理解Fortran 90的kind
参数。据我所知,它不确定变量的精度(即浮点数或双精度数),也不确定变量的类型。
那么,它决定了什么以及它到底是什么?
答案 0 :(得分:50)
变量的KIND是一个整数标签,它告诉编译器应该使用哪种受支持的类型。
请注意,虽然KIND参数的 common 与该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
类似于整数和逻辑类型。
(如果我去挖掘,我可能会找到示例。搜索usenet组comp.lang.fortran以查找示例。对Fortran进行最全面的讨论,其中有一些经验丰富的人员参与其中。 )
因此,如果您不能指望在不同平台上提供相同数据表示的特定类型值,您会怎么做?这就是内在函数kind
和SELECTED_REAL_KIND
的用途。基本上,你告诉函数你需要能够代表什么类型的数字,它将返回你需要使用的那种。
我通常使用这些类型,因为它们通常给我4字节和8字节实数:
SELECTED_INT_KIND
所以我可能随后将变量声明为:
!--! 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
以获得一个方便的程序,该程序将告诉您编译器可用的种类。
答案 1 :(得分:6)
我建议使用Fortran 2008及更高版本; INT8, INT16, INT32, INT64, REAL32, REAL64, REAL128
。这是通过在Fortran 2003及更高版本中调用ISO_FORTRAN_ENV
来完成的。种类参数提供了不一致的方法,以确保您始终获得适当数量的位表示
答案 2 :(得分:2)
只是扩展其他(非常好的)答案,特别是Andrej Panjkov的答案:
变量的KIND是一个告诉编译器的整数标签 它应该使用哪种受支持的种类。
完全。即使对于所有数字内在类型,KIND参数也用于指定处理器上数字的表示和行为的" 模型&#34 ; (标准第16.5节中的文字),在实践中意味着它们的位模型,这不是KIND参数可能代表的唯一内容。
类型的KIND参数在其性质,模型或行为中是任何变体,程序员可以在编译时选择它。例如,对于内在字符类型,kind参数表示处理器上可用的字符集(ASCII,UCS-4,...)。
您甚至可以在定义的派生类型(之后来自Fortran 2003)上定义自己的模型/行为变体。您可以创建一个变换矩阵类型,并为2D空间(其中底层数组为3x3)和KIND = 3(对于3D空间(具有4x4底层数组))具有KIND = 2的版本。请记住,非内在类型没有自动类型转换。
答案 3 :(得分:1)
从 Portland Group Fortran Reference ,KIND
参数“指定内部数据类型的精度。”因此,在声明中
real(kind=4) :: float32
real(kind=8) :: float64
变量float64
声明为8字节实数(旧Fortran DOUBLE PRECISION
),变量float32
声明为4字节实数(旧Fortran {{1 }})。
这很好,因为它允许您修改变量的精度,而不依赖于您运行的编译器和机器。如果您正在运行需要更高精度的计算,那么传统的IEEE单精度实数(如果您正在使用数值分析类很可能),但是将变量声明为REAL
,那么'如果编译器设置为默认所有real :: myVar
值为双精度,但更改编译器选项或将代码移动到具有real
和{{1}的不同默认大小的其他计算机,则可以。变量会导致一些可能令人讨厌的惊喜(例如你的迭代矩阵求解器爆炸)。
Fortran还包含一些有助于选择real
参数的函数 - integer
和KIND
- 但如果你刚刚学习我就不会担心那些在此刻。
由于您提到您正在学习Fortran作为课程的一部分,您还应该在Fortran resources上看到这个问题,也可以查看您正在使用的编译器套件中的参考手册(例如Portland Group或英特尔) - 这些通常是免费提供的。
答案 4 :(得分:-2)
kind 的一个用途是确保对于不同的机器或操作系统,它们确实使用相同的精度并且结果应该相同。所以代码是可移植的。例如,
integer, parameter :: r8 = selected_real_kind(15,9)
real(kind=r8) :: a
现在这个变量 a 总是 r8 类型,这是一个真正的“双精度”(所以它在电子计算机上占用 64 位内存),无论代码运行在什么机器/操作系统上。
此外,因此您可以编写诸如
a = 1.0_r8
并且这个_r8确保1.0被转换为r8类型。
答案 5 :(得分:-3)
总结其他答案:kind参数指定固有数据类型(例如整数和实数)的存储大小(因此间接指定精度)。
但是,现在推荐的方法不是在源代码中指定变量的种类值,而是使用编译器选项来指定所需的精度。例如,我们编写代码:real :: abc
,然后通过使用编译选项-fdefault-real-8
(对于gfortran)指定8字节浮点数来编译代码。对于ifort,相应的选项为-r8
。