fortran中的参数精度

时间:2018-03-20 08:03:36

标签: fortran

我正在使用intel fortran 2016.我已经定义了一些精确变量如下:

 ! definition of single, double and quad precision
        integer, parameter :: SINGLE_PRECISION = selected_real_kind(6, 37)
        integer, parameter :: DOUBLE_PRECISION = selected_real_kind(15, 307) ! is used as standard precision
        integer, parameter :: QUAD_PRECISION = selected_real_kind(33, 4931)

        ! definition of variable precision for REAL, INTEGER
        integer, parameter :: REAL_TYPE = DOUBLE_PRECISION
        integer, parameter :: INTEGER_TYPE = 4

我现在想用这些来控制在子程序中声明的参数的精度,如下所示:

  SUBROUTINE SKIP(IUNIT,NBYTS)

  IMPLICIT DOUBLE PRECISION (A-H,O-Z)
  Character c*1
  Parameter(n1 = 1024, nT1 = 8*n1)

我尝试了以下内容:

Parameter(INTEGER_TYPE)((n1 = 1024, nT1 = 8*n1)
Parameter(INTEGER_TYPE)((n1 = 1024, nT1 = 8*n1, kind = INTEGER_TYPE)

一切都无济于事。在Fortran中定义参数精度的正确方法是什么?

由于

3 个答案:

答案 0 :(得分:2)

注意:这与Francescalus' answer基本相同,但有一些额外的长笛。

此处的问题与IMPLICIT声明有关。

Fortran standard发表以下声明:

  

5.5 IMPLICIT声明

     
      
  1. 在作用域单元中,IMPLICIT语句指定类型,和   可能的类型参数,用于所有隐式类型化的数据实体   名称以语句中指定的字母之一开头。   或者,它可以指示没有隐式类型规则   适用于特定的范围单位。

  2.   
  3. <snip>

  4.   
  5. 在每个作用域单元中,都有一个映射,可以为空   每个字母A, B, ..., Z和一个类型(和类型参数)。   IMPLICIT语句指定其中字母的映射   信中说明列表。 IMPLICIT NONE指定所有的空映射   这些信。如果没有为字母指定映射,则   程序单元或接口主体的默认值是默认的整数if   这封信是I, J,...或N,默认是真实的,而且是   内部或模块过程的默认值是主机中的映射   范围单位。

  6.   

所以简而言之,默认情况下,所有内容都是默认REAL类型,除非它以IJ,...,N开头,然后才是类型默认INTEGER

在问题的示例中,变量n1nT1因此默认为INTEGER,除非另有说明。因此,以下可能是一个解决方案:

subroutine skip(IUNIT,NBYTS)
   implicit double precision (A-H,O-Z)
   character c*1
   integer(kind=integer_kind), parameter :: n1 = 1024, nT1 = 8*n1
   ...
end subroutine skip

作为关于变量声明的一般性评论,我想发表以下意见:

  • 默认使用implicit none。它使调试更容易
  • 避免使用星号表示法,除了字符外,它不是标准的一部分,对于字符,它被宣布为过时。
  • 使用内部模块kind
  • 中声明的iso_fortran_env个参数
  • 请注意double precision并不一定意味着文字或IEEE意义上的“双精度”。它只是意味着,real的存储量是real的两倍,精度高于foo。 (更高的精度可以是一位数)。

答案 1 :(得分:1)

您可以使用

定义特定种类的参数
TYPE, PARAMETER :: name = value_kind

因此,要定义一个整数n1,其类型为INTEGER_TYPE

integer(kind=INTEGER_TYPE), parameter :: n1 = 1024_INTEGER_TYPE

答案 2 :(得分:1)

您有一个答案,它提供了指定命名常量类型的最佳方法。您可以在this question找到更多详细信息。

但是,我会添加一些有关parameter声明的详细信息。

parameter语句使对象成为命名常量并指定其值。它没有指定该对象的类型或种类。

问题的示例使用n1nT1的隐式类型。这些是隐式默认整数。

可以更改隐式规则(我不会显示如何),但也可以明确给出类型:

integer(INTEGER_TYPE) n1, nT1
parameter (n1=1024, nT1=8*n1)

但是,另一个答案的形式更可取。并且,如前所述,如果需要,也可以在parameter语句中给出文字常量的类型。