Fortran“古老”类型特定的数学函数

时间:2017-12-12 07:22:17

标签: fortran

我正在开展一个几年前开始的项目。最近,该小组中有一位新成员建议用普通的数学函数替换所有古代类型特定形式的数学函数。例如,建议将cdexp(c)dexp(d)替换为exp(c)exp(d)。然而,多年来一直参与该项目的另一名成员不愿意这样做,因为他认为dexp(d)会仔细检查d的类型,并确保我们不会意外地将复杂参数作为真实传递并制作如下代码段中的错误:

program main
  real*8     ::  a = 3.d0
  real*8     ::  b = 2.d0
  complex*16 ::  c = (7.d0, 8.d0)
  a = b + exp(c)
  write(6,*) a                                                                                                                                                                                               
end program main

VS

program main
  real*8     ::  a = 3.d0
  real*8     ::  b = 2.d0
  complex*16 ::  c = (7.d0, 8.d0)
  a = b + dexp(c)
  write(6,*) a                                                                                                                                                                                                
end program main

第一个会给出意想不到的结果而第二个会在编译时给出错误,假设我们期望c是真实的,但可能会不小心将复杂的东西传递给它。上面显示的是一个最小的例子,所以每个人都可以看到c一见钟情。真实情况要比这复杂得多。

我的问题是,这个声明是否证明了使用古代类型特定的数学Fortran函数是合理的,还是我们应该真正听取建议并用更一般的函数替换类型特定的函数?

任何帮助将不胜感激。

我发布前已阅读this question。那里的答案简单地说古老的那些是古老的,而普通人可以自动处理参数类型。根本没有提到,古老的形式对于双重检查类型非常有用,并允许在编译时发现一些错误。我认为这个问题的关注点与那个问题明显不同。

1 个答案:

答案 0 :(得分:1)

我不相信旧表格很有用。错误检查是可疑的。您可以使用编译器选项检查从double到real的隐式转换。

使用旧表单会损害代码的通用性。然后,您不能简单地使用不同类型的参数重新编译代码。但是,当您使用非标准real*4real*8时,您也无法轻易更改种类。这是我的一个主要原因,我只是通过使用不同类型的常量重新编译来定期在单精度和双精度之间进行更改。

例如,使用您的第一个代码,您会收到警告:

> gfortran -Wall dexp.f90 
dexp.f90:5.6:

  a = b + exp(c)
      1
Warning: Possible change of value in conversion from COMPLEX(8) to REAL(8) at (1)

要捕获使用的单个精度变量而不是double,您必须启用Wconversion-extra

> gfortran -Wconversion-extra dexp.f90 
dexp.f90:5.7:

  a =  exp(c)
       1
Warning: Conversion from REAL(4) to REAL(8) at (1)

有些编译器无法捕捉到这一点(英特尔?),你的同事可能会有一些观点,但我不相信它能克服dexp()和类似的丑陋。