Fortran:integer*4 vs integer(4)vs integer(种类=4)

Fortran:integer*4 vs integer(4)vs integer(种类=4),fortran,language-lawyer,Fortran,Language Lawyer,我正在努力学习Fortran,我看到很多不同的定义被传来传去,我想知道他们是否在尝试完成同样的事情。以下两者之间的区别是什么 integer*4 整数(4) 整数(种类=4) 在Fortran>=90中,最好的方法是使用内部函数来指定所需的精度——这既保证了可移植性,又保证了获得所需的精度。例如,要获取至少支持8位十进制数字的整数i和my_int,可以使用: integer, parameter :: RegInt_K = selected_int_kind (8) integer (kind

我正在努力学习Fortran,我看到很多不同的定义被传来传去,我想知道他们是否在尝试完成同样的事情。以下两者之间的区别是什么

  • integer*4
  • 整数(4)
  • 整数(种类=4)

    • 在Fortran>=90中,最好的方法是使用内部函数来指定所需的精度——这既保证了可移植性,又保证了获得所需的精度。例如,要获取至少支持8位十进制数字的整数
      i
      my_int
      ,可以使用:

      integer, parameter :: RegInt_K = selected_int_kind (8)
      integer (kind=RegInt_K) :: i, my_int
      
      RegInt_K
      (或您选择的任何名称)定义为
      参数后,您可以在整个代码中将其用作符号。这也使得更改精度变得容易

      请求8或9位十进制数字通常将获得4字节整数

      integer*4
      是一个常见的扩展,可以返回到旧的FORTRAN来指定一个4字节的整数。虽然,这种语法不是,也从来不是标准的Fortran

      integer(4)
      integer(RegInt\u K)
      integer(kind=4)
      integer(kind=RegInt\u K)
      的缩写
      integer(4)
      integer*4
      不同,并且是不可移植的——语言标准没有指定各种类型的数值。大多数编译器对4字节整数使用
      kind=4
      ——对于这些编译器
      integer*4
      integer(4)
      将提供相同的整数类型——但也有例外,因此
      integer(4)
      是不可移植的,最好避免

      reals的方法类似

      更新:如果您不想按要求的精度指定数字类型,而是按它们将使用的存储指定,Fortran 2008提供了一种方法。reals和integer可以通过
      使用
      ISO_FORTRAN_ENV
      模块后的存储位数指定,例如,对于4字节(32位)整数:


      gfortran手册在“内部模块”下有文档。只需对这类模块做一个更明确的解释。编译器有一个不同数字类型的表。所有整数类型都是基本类型的不同类型--
      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
      
      确实有编译器(至少77国集团和NAG)选择了这种方法。还有一些选项可以改变这一点。因此,
      kind
      数字不可移植
      integer(kind=4)
      integer(4)
      表示4字节整数或8字节整数,具体取决于编译器

      integer*4
      是可移植的,因为它总是意味着4个字节。但另一方面,它是不可移植的,因为它从未成为任何标准的一部分。使用此符号的程序不是有效的Fortran 77、90或任何其他Fortran

      要了解正确的选项如何设置种类编号,请参阅M.S.B.的答案

      同样的概念适用于
      real
      数据类型。请参阅(mataap的答案)。

      我将参考@SteveLionel最近写的一篇文章,并尝试介绍一些迄今为止其他答案中没有的细节:


    • 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\u int\u kind
      selected\u real\u kind
      ,还有其他一些,如
      精度
      数字
      εcode>等)帮助程序员指定数字类型的精度和范围的最低要求(仍然没有正式提及存储模型或字节)。语法是
      integer(kind=n)
      甚至
      integer(n)
      ,其中
      n
      是一个常量值,对应于编译器支持的整数类型。对于文字常量,语法为
      12\n
      3.4e-2\n

      此解决方案的优点是Fortran除了用于选择类型的查询函数的结果之外,没有(现在仍然没有)对数据类型的实现细节做出任何假设,因此代码是根据要解决的问题进行参数化的,而不是语言或硬件。正如在其他答案中所说,问题的症结在于,每个编译器都可以选择它们的类数,因此假设像
      integer(4)
      这样的幻数是不可移植的


    • Fortran 90还引入了默认种类的概念,这是在不指定种类时得到的
    • 默认的种类依赖于实现,尽管从上到下都是
      kind number    number of bytes
      1              1
      2              2
      3              4
      4              8
      5              16