我正在尝试学习Fortran,我看到很多不同的定义被传递,我想知道他们是否正在努力完成同样的事情。以下是什么区别?
integer*4
integer(4)
integer(kind=4)
答案 0 :(得分:51)
在Fortran> = 90中,最好的方法是使用内部函数来指定所需的精度 - 这既保证了可移植性,又保证了您所需的精度。例如,要获得支持至少8位小数的整数i
和my_int
,您可以使用:
integer, parameter :: RegInt_K = selected_int_kind (8)
integer (kind=RegInt_K) :: i, my_int
将RegInt_K
(或您选择的任何名称)定义为parameter
后,您可以在整个代码中将其用作符号。这也可以很容易地改变精度。
请求8位或9位十进制数通常会获得4字节整数。
integer*4
是一个常见的扩展,可以追溯到旧的FORTRAN,指定一个4字节的整数。虽然,这种语法不是,而且从来都不是标准的Fortran。
integer (4)
或integer (RegInt_K)
是integer (kind=4)
或integer (kind=RegInt_K)
的缩写。 integer (4)
与integer*4
不同且不可移植 - 语言标准未指定种类的数值。大多数编译器使用kind=4
表示4字节整数 - 对于这些编译器integer*4
和integer(4)
将提供相同的整数类型 - 但也有例外,因此integer(4)
是非便携式,最好避免使用。
实物的方法类似。
更新:如果您不想按要求的精度指定数字类型,而是通过它们将使用的存储指定数字类型,Fortran 2008提供了一种方法。实例和整数可以通过use
ISO_FORTRAN_ENV
模块之后的存储位数来指定,例如,对于4字节(32位)整数:
use ISO_FORTRAN_ENV
integer (int32) :: MyInt
gfortran手册中有“内在模块”下的文档。
答案 1 :(得分:23)
再一个明确的解释是什么类型。编译器有一个包含不同数字类型的表。所有整数类型都是基本类型的不同种 - integer
。假设编译器有1字节,2字节,4字节,8字节和16字节integer
(或real
)种类。在表中,编译器具有每种类型的索引 - 该索引是种类数。
许多编译器选择此编号:
kind number number of bytes
1 1
2 2
4 4
8 8
16 16
但他们可以选择任何其他编号。其中一个显而易见的可能性是
kind number number of bytes
1 1
2 2
3 4
4 8
5 16
确实有编制者(至少是g77和NAG)选择这种方法。还有一些选项可以改变这种状况。因此kind
数字不可移植integer(kind=4)
或integer(4)
表示4字节整数或8字节整数,具体取决于编译器。
integer*4
是可移植的,它总是意味着4个字节。但另一方面,它不可移植,因为它从未成为任何标准的一部分。使用此表示法的程序无效Fortran 77,90或任何其他Fortran。
要查看正确的选项,如何设置种类编号,请参阅M.S.B.的回答。
同样的概念适用于real
数据类型。见Fortran 90 kind parameter(mataap的回答)。
答案 2 :(得分:1)
我将参考@SteveLionel最近写的this enlightening article,并尝试介绍到目前为止其他答案中未提供的一些细节:
integer*n
或real*n
中显示的语法是很久以前由编译器提供的通用扩展,当时不同的计算机体系结构开始针对整数和实数值的内存格式进行不同的设计,其中n
是所存储值的字节大小。但是,这些值的范围或精度什么也没说:例如,一个16位整数的不同实现可以提供不同的范围和极限值。寄存器大小可以是8、12、16、30、32、36、48、60或64位,某些CDC机器具有补数整数(允许整数减去零!),PDP-11行具有根据系列,几种不同的浮点格式,IBM 360/370的浮点具有“十六进制标准化”,等等。这些扩展是如此流行,以至于许多程序员认为(甚至今天很多人都认为)这种语法是标准的Fortran;不是!
当Fortran 90推出时,kind
参数以及固有的查询功能(特别是kind
,selected_int_kind
和selected_real_kind
)被添加到了语言中,但是还有其他precision
,digits
,epsilon
...)可帮助程序员为数字类型的精度和范围指定最低要求(仍然,没有正式提及存储模型或字节)。语法为integer(kind=n)
甚至integer(n)
,其中n
是一个常量值,对应于编译器支持的一种整数。对于文字常量,语法为12_n
或3.4e-2_n
。
此解决方案的优势在于,除了用于选择类型的查询功能的结果之外,Fortran并没有(而且仍然没有)对数据类型的实现细节做任何假设。由要解决的问题参数化,而不是由语言或硬件参数化。如其他答案所述,问题在于,每个编译器都可以选择它们的种类编号,因此假设像integer(4)
这样的幻数是不可移植的。
默认种类取决于实现,尽管直到Fortran 2008为止,编译器仅需要支持一种整数种类和两种实数种类。 (在Fortran 2018中仍然是这样,但是有一个额外的要求,即至少一个整数类型必须支持18个十进制数字。)如果编写不带类型说明符的常量文字,则会得到默认的类型。
ieee_arithmetic
,您可以查询并选择具有IEEE浮点功能的实类型(如果有)。有些架构可以同时使用IEEE和非IEEE浮点类型,例如HP(以前称为Compaq,以前是DEC)Alpha。在这种情况下,可以使用内部模块IEEE_ARITHMETIC的IEEE_SELECTED_REAL_KIND来获取IEEE浮点类型。如果没有满足要求的受支持种类,该怎么办?在这种情况下,内部函数返回一个负数,这通常会根据上下文而触发编译时错误。
iso_fortran_env
内在模块,该模块具有查询由编译器实现的类型的存储大小的功能,内在函数例如为numeric_storage_size
和{ {1}}。 Fortran 2003修订版的另一个新增功能是bit_size
内部模块,该模块提供了种类参数值以确保与C类型在存储,精度和范围方面的兼容性。内部模块ISO_C_BINDING为与C类型(例如C_FLOAT和C_INT)可互操作的Fortran类型声明常量。如果要声明与C互操作的变量和接口,请使用这些。
iso_c_binding
,以包括命名常量iso_fortran_env
,int8
,int16
m {{ 1}},int32
,int64
和real32
,它们的值对应于占据指定位数的整数和实数的种类。问题在于这些常量只能确保存储大小,而不能保证精度或范围。仅在您真正想要的时候使用它们。在我看来,这比旧的* n扩展稍好一点,因为它告诉您类型可以容纳很多位,但没有其他内容。例如,有一个编译器,其中REAL128以128位存储,但实际上是旧x86浮点堆栈寄存器中实际使用的80位“扩展精度”。如果使用这些功能,您可能会认为您正在使用便携式功能,但实际上您并未使用它,并且当您获得的种类不具备所需功能时可能会被咬伤。