Saj*_*sad 6 recursion fortran function fortran95
我正在开发一个需要在FORTRAN中实现很少数值方法的项目.为此,我需要编写一些递归函数.这是我的代码.
!
! File: main.F95
!
RECURSIVE FUNCTION integrate(n) RESULT(rv)
IMPLICIT NONE
DOUBLE PRECISION :: rv
INTEGER, INTENT(IN) :: n
DOUBLE PRECISION, PARAMETER :: minusone = -1.0
IF (n == 1) THEN
rv = 10 !exp(minusone)
RETURN
ELSE
rv = 1 - (n * integrate(n - 1))
RETURN
END IF
END FUNCTION integrate
RECURSIVE FUNCTION factorial(n) RESULT(res)
INTEGER res, n
IF (n .EQ. 0) THEN
res = 1
ELSE
res = n * factorial(n - 1)
END IF
END
PROGRAM main
DOUBLE PRECISION :: rv1
PRINT *, factorial(5)
PRINT *, integrate(2)
!READ *, rv1
END PROGRAM main
Run Code Online (Sandbox Code Playgroud)
对于此程序,输出为:
NaN
1
Run Code Online (Sandbox Code Playgroud)
如果我改变了打印语句的顺序(第30和31行),输出将是:
1
-19.000000
Run Code Online (Sandbox Code Playgroud)
输出应该是(对于原始的打印语句顺序):
120
-19
Run Code Online (Sandbox Code Playgroud)
我从维基百科Fortran 95语言功能页面中获取了阶乘函数.我是FORTRAN的新手,我不知道我的代码有什么问题.请帮帮我们.
先感谢您.
M. *_* B. 10
正如其中一条评论所提到的,更好的解决方案是将子程序和函数放入模块中,然后使用主程序中的该模块.这将使调用者知道这些过程的接口 - 在Fortran术语中是"显式的".编译器不仅可以正确处理函数的类型,还可以检查调用中的参数与被调用者中的参数("伪参数")之间的类型一致性,以确保一致性.
如果您使用尽可能多的调试选项,编译器将帮助您找到错误.使用gfortran,尝试:-O2 -fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck = all -std = f2008 -pedantic -fbacktrace
module factorial_procs
IMPLICIT NONE
contains
RECURSIVE FUNCTION integrate(n) RESULT(rv)
DOUBLE PRECISION :: rv
INTEGER, INTENT(IN) :: n
IF (n == 1) THEN
rv = 10
RETURN
ELSE
rv = 1 - (n * integrate(n - 1))
RETURN
END IF
END FUNCTION integrate
RECURSIVE FUNCTION factorial(n) RESULT(res)
INTEGER res, n
IF (n .EQ. 0) THEN
res = 1
ELSE
res = n * factorial(n - 1)
END IF
END
end module factorial_procs
PROGRAM main
use factorial_procs
implicit none
PRINT *, factorial(5)
PRINT *, integrate(2)
END PROGRAM main
Run Code Online (Sandbox Code Playgroud)
您可能会发现只能使用常规整数通过直接乘法计算非常小的整数的阶乘.一个修复是使用更大的整数类型,例如,
integer, parameter :: BigInt_K = selected_int_kind (18)
Run Code Online (Sandbox Code Playgroud)
就像你可以现代化并使用selected_real_kind而不是Double Precision一样.
您的功能写得正确.问题出在主程序中,你没有明确地声明类型integrate和factorial函数,所以你有隐式类型,在这种情况下factorial假定REAL并integrate假设INTEGER.出于某种原因,您的编译器没有警告您类型不匹配.我做了:
$ gfortran recurs.f90
recurs.f90:26.22:
PRINT *, integrate(2)
1
Error: Return type mismatch of function 'integrate' at (1) (INTEGER(4)/REAL(8))
recurs.f90:27.22:
PRINT *, factorial(5)
1
Error: Return type mismatch of function 'factorial' at (1) (REAL(4)/INTEGER(4))
Run Code Online (Sandbox Code Playgroud)
您应该将主程序更改为:
PROGRAM main
IMPLICIT NONE
DOUBLE PRECISION, EXTERNAL :: integrate
INTEGER, EXTERNAL :: factorial
PRINT *, factorial(5)
PRINT *, integrate(2)
END PROGRAM main
Run Code Online (Sandbox Code Playgroud)
注意这IMPLICIT NONE条线.此声明语句将禁用任何隐式类型,如果未显式声明所有变量和函数,编译器将抛出错误.这是每个Fortran程序中非常重要的一行,如果你有它,你会自己弄清楚你的问题,因为它会强迫你明确地声明程序中的所有内容.
现在的输出是:
120
-19.0000000000000
Run Code Online (Sandbox Code Playgroud)
正如所料.
作为边注,该DOUBLE PRECISION类型声明并不像使用如柔性REAL带KIND,而不是指定的参数,例如一个REAL(KIND=myRealKind).查看有关如何KIND正确使用的问题的答案:Fortran 90种参数.
| 归档时间: |
|
| 查看次数: |
11926 次 |
| 最近记录: |