我想指出,在常量表达式的部分,标准规定
常量表达式是...
(1) 常量或常量的子对象。
那么在哪些地方可以使用 P1
而不能使用 P(1)
?当然,P(1)
可以在 P1
不能使用的地方使用。
在我看来,数组方法真的很有吸引力,因为数组表达式更容易理解 -- 在嵌套的表达式中可能会有一些不规则性,读者可能会忽略它们,但在数组公式中不会。
program polyval
use ISO_C_BINDING, only:C_DOUBLE
implicit none
integer, parameter :: wp = C_DOUBLE
real(wp), parameter :: P(0:*) = &
[0.5_wp,0.8_wp,-0.1_wp,-0.7_wp,-0.4_wp,-0.6_wp,-0.2_wp]
real(wp) a, x
integer i
a = 10
x = sum([(a**i*P(i),i=0,ubound(P,1))])
write(*,*) x
end program polyval
编辑:我认为现在Fortran编译器可能已经足够聪明,能够识别上述多项式求值的习惯用语,但显然我错了。我本以为
function poly1(x)
use ISO_FORTRAN_ENV, only: wp=> REAL64
real(wp) x
real(wp) poly1
real(wp), parameter :: P0 = 0.5_wp, P1 = 0.8_wp, P2 = -0.1_wp, &
P3 = -0.7_wp, P4 = -0.4_wp, P5 = -0.6_wp, P6 = -0.2_wp
poly1 = (((((P6*x+P5)*x+P4)*x+P3)*x+P2)*x+P1)*x+P0
end function poly1
并且
function poly2(x)
use ISO_FORTRAN_ENV, only: wp=> REAL64
real(wp) x
real(wp) poly2
real(wp), parameter :: P(0:6) = &
[0.5_wp,0.8_wp,-0.1_wp,-0.7_wp,-0.4_wp,-0.6_wp,-0.2_wp]
integer i
poly2 = sum([(x**i*P(i),i=0,ubound(P,1))])
end function poly2
希望得到相似的代码,但是使用 gfortran -S -O3 -ffast-math -funroll-loops poly2.f90
和 ifort /Fa /c /fast /Qipo- poly2.f90
命令都计算了 x
的幂和有效的 DOT_PRODUCT
,而没有使用高效的方法。因此,在这种情况下,可能需要像汇编语言一样将表达式写成长格式,而不是使用高级语言,以获得合理的性能。
编辑: 好吧,似乎有一种情况可以使用 REAL 命名常量,但不能使用 REAL 常量表达式。
program test2
use ISO_FORTRAN_ENV, only:wp=>REAL64
implicit none
complex(wp) x
real(wp), parameter :: P1 = 4*atan(1.0_wp)
real(wp), parameter :: P(1) = exp(1.0_wp)
x = (P1,0)
write(*,*) x
write(*,*) x
end program test2
但是在查阅标准后,我认为这是唯一的情况。在f2003中,是否首次允许在complex-literal-constant中使用命名常量?为了完整起见,我提供一个例子,其中常量表达式可以工作,但命名常量不能:
module mymod
use ISO_FORTRAN_ENV,only:wp=>REAL64
implicit none
contains
subroutine sub(x)
real(wp) x(*)
write(*,*) x(1)
end subroutine sub
end module mymod
program test3
use mymod
implicit none
real(wp), parameter :: P1 = 4*atan(1.0_wp)
real(wp), parameter :: P(1) = exp(1.0_wp)
call sub(P(1))
end program test3