Fortran 90种参数
我无法理解Fortran 90的kind
参数。 据我所知,它并不决定变量的精度(即浮点数或双精度),也不决定变量的类型。
那么,它是什么决定的,到底是什么呢?
变量的KIND是一个整数标签,告诉编译器应该使用哪种支持的类型。
请注意,尽管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来寻找例子,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
一个方便的程序,它会告诉你有关编译器的可用类型。
我建议使用Fortran 2008及更高版本; INT8, INT16, INT32, INT64, REAL32, REAL64, REAL128
。 这是通过在Fortran 2003和更高版本中调用ISO_FORTRAN_ENV
来完成的。 种类参数提供了不一致的方式来确保您始终获得适当数量的位表示
从Portland Group Fortran Reference中 , KIND
参数“指定了内在数据类型的精度”。 因此,在声明中
real(kind=4) :: float32 real(kind=8) :: float64
声明为8字节真实(旧Fortran DOUBLE PRECISION
)的变量float64
和声明为4字节真实(旧Fortran REAL
)的变量float32
。
这很好,因为它可以让你修改变量的精度,而不依赖于你正在运行的编译器和机器。 如果您正在运行一个需要更高精度的计算,那么传统的IEEE单精度实数(如果您正在进行数值分析类的话,非常可能),但是将您的变量声明为real :: myVar
,那么您将如果编译器被设置为默认所有real
值为双精度,但是改变编译器选项或者移动你的代码到不同的具有不同的real
和integer
变量的默认大小的机器将会导致一些可能的令人讨厌的惊喜(例如,你的迭代矩阵求解器爆炸)。
Fortran还包含了一些函数,可以帮助您选择一个KIND
参数 – SELECTED_INT_KIND
和SELECTED_REAL_KIND
– 但是如果您刚刚学习的话,我不会担心这个问题。
既然你提到你正在学习Fortran作为一个类的一部分,你也应该在Fortran资源上看到这个问题,也许看看你正在使用的编译器套件中的参考手册(例如Portland Group或Intel)免费提供。
- 在Python中打包遗留的FORTRAN。 可以使用`setuptools`和`numpy.distutils`吗?
- 如何为android-ndk8b(x86 arch Android)构buildi686-linux-android-gfortran?
- 在Fortran中将多个variables的外部函数作为一个variables的函数传递
- 如何在Fortran中别名函数名称
- 在Fortran中正确使用模块,子例程和函数
- 为什么定义PI = 4 * ATAN(1)
- 在Fortran 90中计算两个向量的叉积
- numpy怎么能比我的Fortran程序快得多呢?
- BLAS如何获得如此极致的performance?