Fortran:整数*4 vs 整数(4) vs 整数(kind=4)
我正在尝试学习 Fortran,并且看到了很多不同的定义,我想知道他们是否正在尝试完成同样的事情。以下有什么区别?
整数*4
整数(4)
整数(kind=4)
I'm trying to learn Fortran and I'm seeing a lot of different definitions being passed around and I'm wondering if they're trying to accomplish the same thing. What is the difference between the following?
integer*4
integer(4)
integer(kind=4)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在 Fortran >=90 中,最好的方法是使用内部函数来指定所需的精度——这既保证了可移植性,又保证了您获得所需的精度。例如,要获取支持至少 8 位十进制数字的整数
i
和my_int
,您可以使用:定义了
RegInt_K
(或任何名称)当您选择)作为参数
时,您可以在整个代码中将其用作符号。这也使得改变精度变得容易。请求 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 提供了一种方法。实数和整数可以通过
使用
ISO_FORTRAN_ENV模块后的存储位数来指定,例如,对于 4 字节(32 位)整数: gfortran 手册在“内在模块”下有文档。
In Fortran >=90, the best approach is use intrinsic functions to specify the precision you need -- this guarantees both portability and that you get the precision that you need. For example, to obtain integers
i
andmy_int
that will support at least 8 decimal digits, you could use:Having defined
RegInt_K
(or whatever name you select) as aparameter
, you can use it throughout your code as a symbol. This also makes it easy to change the precision.Requesting 8 or 9 decimal digits will typically obtain a 4-byte integer.
integer*4
is an common extension going back to old FORTRAN to specify a 4-byte integer. Although, this syntax isn't and was never standard Fortran.integer (4)
orinteger (RegInt_K)
are short forinteger (kind=4)
orinteger (kind=RegInt_K)
.integer (4)
is not the same asinteger*4
and is non-portable -- the language standard does not specify the numeric values of kinds. Most compilers use thekind=4
for 4-byte integers -- for these compilersinteger*4
andinteger(4)
will provide the same integer type -- but there are exceptions, sointeger(4)
is non-portable and best avoided.The approach for reals is similar.
UPDATE: if you don't want to specify numeric types by the required precision, but instead by the storage that they will use, Fortran 2008 provides a method. reals and integers can be specified by the number of bits of storage after
use
ing theISO_FORTRAN_ENV
module, for example, for a 4-byte (32-bit) integer:The gfortran manual has documentation under "intrinsic modules".
只是一个更明确的解释是什么类型。编译器有一个不同数值类型的表。所有整数类型都是基本类型的不同种类——
整数
。假设编译器有 1 字节、2 字节、4 字节、8 字节和 16 字节整数(或实数)类型。在表中,编译器对每种类型都有一个索引——该索引是类型号。许多编译器选择此编号:
但他们可以选择任何其他编号。明显的可能性之一是
确实有编译器(至少 g77 和 NAG)选择了这种方法。还有一些选项可以更改此设置。因此
kind
数字不可移植integer(kind=4)
或integer(4)
表示 4 字节整数或 8 字节整数,具体取决于在编译器上。integer*4
是可移植的,因为它始终表示 4 个字节。但另一方面,它不可移植,因为它从未成为任何标准的一部分。使用此表示法的程序在 Fortran 77、90 或任何其他 Fortran 中无效。要了解如何设置种类数字的正确选项,请参阅 MSB 的答案。
同样的概念也适用于
real
数据类型。请参阅Fortran 90 kind参数(mataap的答案)。Just one more explicit explanation what the kind is. The compiler has a table of different numerical types. All integer types are different kinds of the basic type --
integer
. Let's say the compiler has 1 byte, 2 byte, 4 byte, 8 byte and 16 byteinteger
(orreal
) kinds. In the table the compiler has an index to each of this kind -- this index is the kind number.Many compilers choose this numbering:
But they can choose any other numbering. One of the obvious possibilities is
There are indeed compilers (at least g77 and NAG) which choose this approach. There are also options to change this. Therefore
kind
numbers are not portableinteger(kind=4)
orinteger(4)
means a 4 byte integer or a 8-bytes integer depending on the compiler.integer*4
is portable in the sense it always means 4 bytes. But on the other hand it is not portable because it has never been part of any standard. Programs using this notation are not valid Fortran 77, 90 or any other Fortran.To see the right options how to set the kind numbers see M.S.B.'s answer.
The same concept holds for
real
data types. See Fortran 90 kind parameter (the mataap's answer).我将参考这个启发性的内容文章,最近由 @SteveLionel 撰写,并尝试涵盖迄今为止其他答案中未出现的一些细节:
integer*n
或real*n< 中显示的语法/code> 是很久以前编译器提供的常见扩展,当时不同的计算机体系结构开始对整数和实数值的内存格式有不同的设计,其中
n
是 存储值的字节数。然而,这并没有说明这些值的范围或精度:例如,16 位整数的不同实现可以提供不同的范围和极限值。当 Fortran 90 发布时,
kind
参数以及内在查询函数(特别是kind
、selected_int_kind
和 < code>selected_real_kind,还有其他,如precision
、digits
、epsilon
...)来帮助程序员指定最小对数字类型的精度和范围的要求(仍然没有正式提及存储模型或字节)。语法为integer(kind=n)
甚至integer(n)
,其中n
是与支持的整数类型相对应的常量值由编译器。对于文字常量,语法为12_n
或3.4e-2_n
。这个解决方案的优点是,除了用于选择类型的查询函数的结果之外,Fortran 没有(现在仍然没有)对数据类型的实现细节做出任何假设,因此代码是由要解决的问题来参数化,而不是由语言或硬件来参数化。正如其他答案中所述,问题是每个编译器都可以选择自己的类型数字,因此假设像
integer(4)
这样的幻数不可移植。iso_fortran_env
内部模块,该模块具有查询编译器实现的类型存储大小的功能,以及诸如numeric_storage_size
之类的内部函数> 和bit_size
。 Fortran 2003 修订版的另一个新增内容是iso_c_binding
内部模块,它提供种类参数值以保证在存储、精度和范围方面与 C 类型的兼容性。iso_fortran_env
以包含命名常量int8,
int16
,int32
mint64
,real32
,real64
和real128
,其值对应于占用指定位数的整数类型和实数类型。问题是这些常量仅保证存储大小,而不是精度或范围。仅当这正是您想要的时才使用它们。I will make reference to this enlightening article, wrote recently by @SteveLionel, and try cover some details that are not present in the other answers so far:
integer*n
orreal*n
was a common extension provided by compilers long time ago, when different computer architectures started to have different designs for in-memory format of integer and real values, wheren
was the size in bytes of the value stored. However, that said nothing about range or precision of those values: different implementations of a 16bit integer, for example, could provide different ranges and limit values.When Fortran 90 came out,
kind
parameters were added to the language, along with intrinsic inquiry functions (speciallykind
,selected_int_kind
andselected_real_kind
, but also others, likeprecision
,digits
,epsilon
...) to aid the programmer to specify minimun requirements for precision and range of numeric types (still, no official mention to storage model or bytes). The syntax isinteger(kind=n)
or eveninteger(n)
, wheren
is a constant value corresponding to a kind of integer supported by the compiler. For literal constants, the syntax is12_n
or3.4e-2_n
.The advantage of this solution was that Fortran didn't (and still don't) make any assumptions about the implementation details of data-types other than the results of the inquiry functions used to choose the type, so the code is parameterized by the problem being solved, not by the language or the hardware. The gotcha is, as said in other answers, each compiler can choose their kind numbers, thus assuming magic number like
integer(4)
is not portable.ieee_arithmetic
, you can inquire and select a real type with IEEE floating point capabilities, if avaliable.iso_fortran_env
intrinsic module, that had functions to inquire the storage size of the types implemented by a compiler, with intrinsics likenumeric_storage_size
andbit_size
. Another addition of Fortran 2003 revision was theiso_c_binding
intrinsic module, that provided kind parameter values to guarantee compatibility with C types, in storage, precision and range.iso_fortran_env
to include named constantsint8
,int16
,int32
mint64
,real32
,real64
andreal128
, whose values correspond to the kinds of integer and real kinds that occupy the stated number of bits. The gotcha is that those constants only assure storage size, not precision or range. Only use them when this is exactly what you want.