Sam*_*Sam 55 fortran language-lawyer
我正在尝试学习Fortran,我看到很多不同的定义被传递,我想知道他们是否想要完成同样的事情.以下有什么区别?
integer*4 integer(4) integer(kind=4)M. *_* B. 61
在Fortran> = 90中,最好的方法是使用内部函数来指定所需的精度 - 这既保证了可移植性,又保证了您所需的精度.例如,要获得整数i并且my_int支持至少8位小数,您可以使用:
integer, parameter :: RegInt_K = selected_int_kind (8)
integer (kind=RegInt_K) :: i, my_int
Run Code Online (Sandbox Code Playgroud)
定义RegInt_K(或您选择的任何名称)作为a 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=44字节整数 - 对于这些编译器integer*4并integer(4)提供相同的整数类型 - 但也有例外,因此integer(4)不可移植且最好避免.
实物的方法是类似的.
更新:如果您不希望按所需的精度指定数字类型,而是通过它们将使用的存储指定,Fortran 2008提供了一种方法.实数和整数可以通过存储的比特数之后指定use荷兰国际集团的ISO_FORTRAN_ENV模块中,例如,对于一个4字节(32位)整数:
use ISO_FORTRAN_ENV
integer (int32) :: MyInt
Run Code Online (Sandbox Code Playgroud)
gfortran手册在"内部模块"下有文档.
Vla*_*r F 26
还有一个明确的解释是什么.编译器有一个包含不同数字类型的表.所有整数类型是不同种类的基本类型- integer.假设编译器有1字节,2字节,4字节,8字节和16字节integer(或real)种类.在表中,编译器具有每种类型的索引 - 该索引是种类编号.
许多编译器选择这个编号:
kind number number of bytes
1 1
2 2
4 4
8 8
16 16
Run Code Online (Sandbox Code Playgroud)
但他们可以选择任何其他编号.其中一个显而易见的可能性是
kind number number of bytes
1 1
2 2
3 4
4 8
5 16
Run Code Online (Sandbox Code Playgroud)
确实有编制者(至少g77和NAG)选择这种方法.还有一些选项可以改变这种状况.因此,kind数字不是可移植的,integer(kind=4)或者integer(4)意味着4字节整数或8字节整数,具体取决于编译器.
integer*4从某种意义上说它是便携式的,总是意味着4个字 但另一方面,它不可移植,因为它从未成为任何标准的一部分.使用此表示法的程序无效Fortran 77,90或任何其他Fortran.
要查看正确的选项如何设置种类编号,请参阅MSB的答案.
对于real数据类型,同样的概念也适用.请参阅Fortran 90种参数(mataap的答案).
我将参考@SteveLionel 最近撰写的这篇有启发性的文章,并尝试涵盖迄今为止其他答案中未出现的一些细节:
integer*nor中显示的语法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)or Even integer(n),其中n是与编译器支持的一种整数相对应的常量值。对于文字常量,语法为12_nor 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的功能,以及诸如和 之类的内在函数bit_size。Fortran 2003 修订版的另一个新增内容是iso_c_binding内在模块,它提供了类型参数值以保证在存储、精度和范围方面与 C 类型的兼容性。内部模块 ISO_C_BINDING 声明可与 C 类型互操作的 Fortran 类型常量,例如 C_FLOAT 和 C_INT。如果您要声明可与 C 互操作的变量和接口,请使用它们。
iso_fortran_env命名常量int8、int16、int32m int64、real32和,其值对应于占用指定位数的整数和实数类型。问题是这些常量仅保证存储大小,而不保证精度或范围。仅当这正是您想要的时才使用它们。real64real128在我看来,这比旧的 *n 扩展好不了多少,因为它告诉您一个类型适合那么多位,但除此之外什么也没有。举个例子,有一个编译器,其中 REAL128 以 128 位存储,但实际上是旧 x86 浮点堆栈寄存器中使用的 80 位“扩展精度”实数。如果您使用这些功能,您可能会认为您正在使用便携式功能,但实际上您并非如此,并且当您获得的功能不具备您所需的功能时,您可能会被咬伤。
| 归档时间: |
|
| 查看次数: |
26615 次 |
| 最近记录: |