FORTRAN功能 [英] FORTRAN functions

查看:190
本文介绍了FORTRAN功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一个需要在FORTRAN中实现少数数值方法的项目。为此,我需要编写一些递归函数。这是我的代码。

 
!文件:main.F95


RECURSIVE FUNCTION integrate(n)RESULT(rv)
IMPLICIT NONE
双精度:: 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
双精度:: rv1
PRINT *,阶乘(5)
PRINT *,集成(2)

!READ *,rv1

END PROGRAM main

对于这个程序,输出是:

  NaN 
1

如果我改变打印语句的顺序(第30行&输出将是:

  1 
-19.000000



输出应该是(对于原始打印语句订单):

  120 
-19

我从维基百科 Fortran 95语言特性页面。
我是FORTRAN的新手,我不知道我的代码有什么问题。请帮助我们。



  • 编译器:使用Cygwin的gfortran 4.5.3

  • IDE:Netbeans 7.0 .1

  • 平台:Windows 7



预先感谢您。

解决方案

您的函数写入正确。问题出在主程序中,你没有明确地声明集成 factorial 函数的类型,所以你有隐式输入,在这种情况下 factorial 被假定为 REAL 集成被假定为 INTEGER 。出于某种原因,你的编译器没有警告你类型不匹配。 Mine did:

  $ gfortran recurs.f90 
recurs.f90:26.22:

(1)(INTEGER(4)/ REAL(8))
recurs.f90:27.22(2)
1


PRINT *,阶乘(5)
1
错误:函数'factorial'在(1)(REAL(4)/ INTEGER(4))的返回类型不匹配

您应该将主程序更改为:

  PROGRAM main 
IMPLICIT NONE
DOUBLE PRECISION,EXTERNAL :: integrate
INTEGER,EXTERNAL :: factorial
PRINT *,factorial(5 )
PRINT *,integrate(2)
END PROGRAM main

注意 IMPLICIT NONE 行。这个声明语句将禁用任何隐式类型,如果不是所有的变量和函数都被显式声明的话,编译器会抛出一个错误。这是每个Fortran程序中非常重要的一行,如果你拥有它,你自己就会发现自己的问题,因为它会迫使你明确地声明程序中的所有东西。



现在的输出是:

  120 
-19.0000000000000

如预期的那样。



另外, DOUBLE PRECISION 类型声明并不像使用 REAL 并指定 KIND 参数那么灵活,例如一个 REAL(KIND = myRealKind)。查看有关如何正确使用 KIND 的问题的答案: Fortran 90种参数


I'm working on a project that needs to implement few numerical methods in FORTRAN. For this, I need to write some recursive functions. Here is my code.

!     
! 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

For this program the output is:

         NaN
       1

If i change the order of the print statements (line 30 & 31), the output will be:

         1
-19.000000

Output should be (for the original print statement order):

  120  
  -19 

I took the factorial function from the Wikipedia Fortran 95 language features page. I'm new in FORTRAN, I don't know what's wrong in my code. Please help me guys.

  • Compiler : gfortran 4.5.3 with Cygwin
  • IDE: Netbeans 7.0.1
  • Platform: Windows 7

Thank you in advance.

解决方案

Your functions are written correctly. The problem is in the main program, where you do not explicitly declare the type of integrate and factorial functions, so you have implicit typing, in which case factorial is assumed REAL and integrate is assumed INTEGER. For some reason, your compiler did not warn you about type mismatch. Mine did:

$ 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))

You should change your main program to:

PROGRAM main
    IMPLICIT NONE
    DOUBLE PRECISION, EXTERNAL :: integrate
    INTEGER, EXTERNAL :: factorial
    PRINT *, factorial(5)
    PRINT *, integrate(2)
END PROGRAM main

Notice the IMPLICIT NONE line. This declaration statement will disable any implicit typing, and the compiler would throw an error if not all variables and functions are explicitly declared. This is a very important line in every Fortran program, and if you had it, you would've figured out your problem yourself, because it would force you to explicitly declare everything in your program.

The output now is:

         120
  -19.0000000000000     

as expected.

As a side note, the DOUBLE PRECISION type declaration is not as flexible as using REAL with KIND parameter specified instead, e.g. anREAL(KIND=myRealKind). See answers to this question about how to use KIND properly: Fortran 90 kind parameter.

这篇关于FORTRAN功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆