错误:不支持旧式类型声明REAL * 16

时间:2017-05-05 17:08:03

标签: fortran

我获得了一些遗留代码来编译。不幸的是,我只能访问f95编译器并且对Fortran有0知识。编译了一些模块,但其他模块我收到了这个错误:

Error: Old-style type declaration REAL*16 not supported at (1)

我的计划是至少尝试修复此错误,看看还会发生什么。所以这是我的两个问题。

  1. 我为Fortran 75编写的代码与Fortran 95编译器兼容的可能性有多大? (在/ usr / bin中我的编译器是f95 - 所以我假设它是Fortran 95)

  2. 如何解决此错误?我尝试使用Google搜索,但无法找到明确清晰的答案。

4 个答案:

答案 0 :(得分:4)

您看到的错误是由于在Fortran 90之前经常出现的旧声明样式,但从未成为标准。因此,编译器不接受(正式错误的)代码。

在Fortran 90之前的旧时代,您只有两种类型的实数:REALDOUBLE PRECISION。这些类型与平台有关,但现在大多数编译器 将它们映射到IEEE754 formats binary32和binary64。

然而,有些机器提供不同的格式,通常具有额外的精度。为了使它们可以访问Fortran代码,REAL*n类型被发明,其中n是一组依赖于编译器的值的整数文字。这种语法从来都不是标准的,因此如果不阅读其文档,您无法确定它对给定编译器意味着什么。

在现实世界中,大多数未被要求严格遵守标准的编译器(使用某些选项,如-std=f95)将至少识别REAL*4REAL*8,映射它们到前面提到的binary32 / 64格式,但其他一切都完全取决于平台。您的编译器可能对于x86 387 FPU使用的80位算法具有REAL*10类型,对于某些128位浮点数学具有REAL*16类型。但是,重要的是要强调,由于语法不是标准的,因此该类型的含义可能会从编译器变为编译器。

最后,在Fortran 90中,一种引用实数和整数类型的不同的方法是标准的。新语法为REAL(n)REAL(kind=n),并且所有符合标准的编译器都支持该语法。但是, n 的值仍然依赖于编译器,但标准提供了三种获取特定可重复结果的方法:

  • SELECTED_REAL_KIND函数,它允许您在系统中查询n的值,以指定是否需要具有特定精度和范围要求的实数类型。通常,您所做的就是要求它一次并将结果存储在您声明所讨论的真实变量时使用的INTEGER, PARAMETER变量中。例如,您将声明一个至少包含15位精度(十进制)和指数范围至少为100的类型,如下所示:

    INTEGER, PARAMETER :: rk = SELECTED_REAL_KIND(15, 100)
    REAL(rk) :: v
    
  • 在Fortran 2003及更高版本中,ISO_C_BINDING模块包含一系列常量,旨在为您提供相同于同一编译器系列的C类型的类型(例如gcc为gfortran,icc为ifort)等)。它们被称为C_FLOATC_DOUBLEC_LONG_DOUBLE。因此,您可以将一个等同于C double的变量声明为REAL(C_DOUBLE) :: d
  • 在Fortran 2008及更高版本中,ISO_FORTRAN_ENV模块包含一系列不同的常量REAL32REAL64REAL128,它们将为您提供相应的浮点类型width - 如果某个平台不支持其中一种类型,则常量将为负数。因此,您可以将128位浮点数声明为REAL(real128) :: q

答案 1 :(得分:2)

哈维尔对你眼前的问题给出了很好的答案。但是我只是简单地想要解决这个问题:我为Fortran 77编写的代码在Fortran 95编译器中兼容的可能性有多大?"有明显的拼写错误。

Fortran,如果程序员遵守标准,就会向后兼容。除了极少数例外,符合标准的Fortran 77符合Fortran 2008标准。问题是,在您的情况下,原始程序员似乎没有遵守国际标准:真正的* 8和类似的不是,并且从未成为任何此类标准的一部分,您所看到的问题正是这些形式永远不应该的原因应该永远不应该使用。也就是说,如果原来的程序员只犯了这个错误,很可能其余的代码都没问题,但是如果没有详细说明则无法分辨

TL; DR:国际标准很重要,坚持下去!

答案 2 :(得分:1)

当我们猜测而不是请求正确的代码和完整的细节时,我会冒昧地说其他两个答案都不正确。

错误消息

Error: Old-style type declaration REAL*16 not supported at (1)

DOES NOT 表示不支持REAL * n语法。

错误消息具有误导性。它实际上意味着不支持16字节实数。如果OP通过种类符号(在返回gfortran类型16的许多方式中的任何一种)中请求相同的真实,则错误消息将是:

Error: Kind 16 not supported for type REAL at (1)

在某些gfortran版本中可能会发生这种情况。特别是在MS Windows中。

只需非常快速地搜索错误消息即可找到此解释:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56850#c1

它并没有抱怨旧的语法是问题,它只是提到它,因为提及种类可能会更加混乱(特别是对于16类的COMPLEX * 32)。

主要信息是:我们真的应该关闭这些问题并等待正确的细节,而不是猜测和提出OP甚至无法复制编译器已有的完整消息的问题吐。

答案 3 :(得分:0)

如果您使用的是GNU gfortran,请尝试" real(kind = 10)",这将为您提供10个字节(80位)的扩展精度。我正在转换一些旧的F77代码来运行浮点数学测试 - 它具有四精度(你提到的真正的* 16)定义但未使用,因为正确指出的其他答案指出(扩展精度格式倾向是机器/编译器特定的)。我使用的gfortran 5.2不支持真实(kind = 16),令人惊讶。但是gfortran(可用于64位MacOS和64位Linux机器)确实拥有" real(kind = 10)"这将为您提供超越典型的真实* 8或"双精度"正如在一些Fortran编译器中调用的那样 如果您的旧Fortran代码正在调用C程序和/或可能假设如何处理精度并表示浮点数,请小心。您可能必须深入了解正在发生的事情,并仔细检查代码,以确保事情按预期工作,特别是如果fortran和C例程正在相互调用。以下是关于四精度的GNU gfortran信息的网址:https://people.sc.fsu.edu/~jburkardt/f77_src/gfortran_quadmath/gfortran_quadmath.html 希望这会有所帮助。