【发布时间】:2010-10-24 17:03:09
【问题描述】:
我无法理解 Fortran 90 的 kind 参数。据我所知,它不能确定变量的精度(即浮点数或双精度),也不能确定变量的类型。
那么,它决定什么,它到底是干什么用的?
【问题讨论】:
-
你指的是种类符号吗?
标签: fortran
我无法理解 Fortran 90 的 kind 参数。据我所知,它不能确定变量的精度(即浮点数或双精度),也不能确定变量的类型。
那么,它决定什么,它到底是干什么用的?
【问题讨论】:
标签: fortran
总结其他答案:kind 参数指定内在数据类型(例如整数和实数)的存储大小(因此间接地指定精度)。
但是,现在推荐的方法是不要在源代码中指定变量的种类值,而是使用编译器选项来指定我们想要的精度。例如,我们在代码中写入:real :: abc,然后使用编译选项-fdefault-real-8(对于 gfortran)指定一个 8 字节浮点数来编译代码。对于ifort,对应的选项是-r8。
更新:
这里的 Fortran 专家似乎强烈反对上述推荐的方式。尽管如此,我仍然认为上述方法是一种很好的做法,有助于减少在 Fortran 代码中引入错误的机会,因为它保证您在整个程序中使用相同的 kind-value(您确实需要使用不同的代码不同部分的种类值很少),从而避免了函数调用中虚拟参数和实际参数之间种类值不匹配的常见错误。
【讨论】:
selected_real_kind。如果您关心特定的存储大小,请使用iso_fortran_env 种类常量。详情请参阅this answer。
-fdefault-real-8 是邪恶的,我是说这不是 Fortran 社区最推荐的方法,因为它隐式地改变了您在看看代码。帮助论坛充满了:“当函数的签名似乎与传递的参数匹配时,为什么我对库(Lapack、mkl...)的调用失败或给出错误的结果?”。哦,这是因为makefile中有一行(完全远离源代码)说,在这个项目中,double precision实际上意味着double double precision... ¬¬
种类的一个用途可能是确保对于不同的机器或操作系统,它们真正使用相同的精度并且结果应该相同。所以代码是可移植的。例如,
integer, parameter :: r8 = selected_real_kind(15,9)
real(kind=r8) :: a
现在这个变量 a 始终是 r8 类型,这是一个真正的“双精度”(因此它在电子计算机上占用 64 位内存),无论代码运行在什么机器/操作系统上。
此外,因此您可以编写如下内容,
a = 1.0_r8
这个_r8确保1.0转换为r8类型。
【讨论】:
a 对于每个处理器都保证为 8 字节实数?
selected_real_kind 根本与存储大小无关。您在 HPC 中做什么并不重要。它与数值精度有关。它说明了数字的大小和精确度。我再说一遍,一个符合 Fortran 的处理器可以存在于一台机器上,甚至不需要任何 8 字节类型。那些拥有它的人将在iso_fortran_env 中定义real64,这是定义真正的8 字节实数的真正方法。如果有符合 IEEE 的 8-type 可用,则可以使用 ieee_selected_real_kind,其中数值精度和存储大小的对应关系更加确定。
selected_real_kind 您已要求最小的十进制精度和范围。您没有要求存储大小、基数、IEEE 一致性或确切的范围和精度。 Fortran 语言中没有任何内容表明您将使用此类参数获得 8 字节实数。
只是扩展其他(非常好的)答案,特别是Andrej Panjkov的答案:
变量的种类是一个整数标签,它告诉编译器 它应该使用哪些受支持的类型。
没错。尽管对于所有 numeric intrinsic 类型,KIND 参数用于指定“处理器上数字的表示和行为模型”(来自第16.5 的标准),实际上是指他们的位模型,这不是 KIND 参数可能代表的唯一内容。
类型的 KIND 参数是在其性质、模型或行为方面任何变化,可供程序员在编译时选择。例如,对于固有字符类型,kind 参数表示处理器上可用的字符集(ASCII、UCS-4、...)。
您甚至可以在定义的派生类型上定义您自己的模型/行为变体(之后从 Fortran 2003 开始)。您可以创建一个 Transform Matrix 类型,并为 2D 空间(其中基础数组为 3x3)和 KIND=3 的 3D 空间(具有 4x4 基础数组)提供 KIND=2 的版本。请记住,非固有类型没有自动类型转换。
【讨论】:
变量的种类是一个整数标签,它告诉编译器它应该使用它支持的种类。
请注意,虽然常见 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
对于整数和逻辑类型也是如此。
(如果我去挖掘,我可能会找到示例。在 usenet 组 comp.lang.fortran 中搜索 kind 以查找示例。关于 Fortran 的最有见地的讨论发生在那里,一些经验丰富的人做出了贡献。)
所以,如果您不能指望某个特定类型的值在不同平台上为您提供相同的数据表示,您会怎么做?这就是 SELECTED_REAL_KIND 和 SELECTED_INT_KIND 的内在函数的用途。基本上,你告诉函数你需要能够表示什么样的数字,它会返回你需要使用的那种。
我通常使用这些类型,因为它们通常给我 4 字节和 8 字节实数:
!--! 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 手册。
REAL(n) 和 REAL(kind=n) 他们总是一样的,对吧?
real(kind=dp) 和 real(dp) 声明,看来它们的意思是一样的。
我建议使用 Fortran 2008 及更高版本; INT8, INT16, INT32, INT64, REAL32, REAL64, REAL128。这是通过在 Fortran 2003 及更高版本中调用 ISO_FORTRAN_ENV 来完成的。种类参数提供了不一致的方式来确保您始终获得适当数量的位表示
【讨论】:
int8 确实(如果有适当的种类可用)指定种类参数。我怀疑你的意思是应该更喜欢这个而不是一个明确的数字,比如int(kind=1)? [无论如何,后者都是不好的做法。]也许你可以澄清一下?
SELECTED_REAL_KIND()
来自 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 变量将导致一些可能令人讨厌惊喜(例如,您的迭代矩阵求解器崩溃了)。
Fortran 还包括一些函数,可以帮助您选择 KIND 参数来满足您的需求 - SELECTED_INT_KIND 和 SELECTED_REAL_KIND - 但如果您只是在学习,我现在不会担心这些。
既然您提到您正在学习 Fortran 作为课程的一部分,您还应该在 Fortran resources 上看到这个问题,并且可能查看您正在使用的编译器套件(例如 Portland Group 或 Intel)中的参考手册- 这些通常是免费提供的。
【讨论】: