2010-06-09 57 views
2

我可以编译,但是当我运行我得到这个错误“forrtl:严重(40):递归I/O操作,单元-1,文件未知”如果我设置n = 29或更多......任何人都可以帮助我可能出错了?谢谢。Fortran严重(40)错误...帮助?

PROGRAM SOLUTION 
IMPLICIT NONE 

! Variable Declaration 

INTEGER :: i 
REAL :: dt 
DOUBLE PRECISION :: st(0:9) 
DOUBLE PRECISION :: stmean(0:9) 
DOUBLE PRECISION :: first_argument 
DOUBLE PRECISION :: second_argument 
DOUBLE PRECISION :: lci, uci, mean 
REAL :: exp1, n 
REAL :: r, segma 

! Get inputs 

WRITE(*,*) 'Please enter number of trials: ' 
READ(*,*) n 

WRITE(*,*) 
dt=1.0 
segma=0.2 
r=0.1 

! For n Trials 

st(0)=35.0 
stmean(0)=35.0 
mean = stmean(0) 

PRINT *, 'For ', n ,' Trials' 
PRINT *,'   1  ',st(0) 

! Calculate results 

DO i=0, n-2 
    first_argument = r-(1/2*(segma*segma))*dt 
    exp1 = -(1/2)*(i*i) 
    second_argument = segma*sqrt(dt)*((1/sqrt(2*3.1416))*exp(exp1)) 
    st(i+1) = st(i) * exp(first_argument+second_argument) 

    IF(st(i+1)<=20) THEN 
     stmean(i+1) = 0.0 
     st(i+1) = st(i) 
     else 
     stmean(i+1) = st(i+1) 
    ENDIF 

    PRINT *,i+2,'  ',stmean(i+1) 
    mean = mean+stmean(i+1) 
END DO 

! Output results 

uci = mean+(1.96*(segma/sqrt(n))) 
lci = mean-(1.96*(segma/sqrt(n))) 
PRINT *,'95% Confidence Interval for ', n, ' trials is between ', lci, ' and ', uci 
PRINT *,'' 

END PROGRAM解决方案

+0

+1纯粹的怜悯和同情 – 2010-06-09 14:34:58

回答

1

我承认,我还没有考虑,试图理解程序在做什么的时候,但基础上“快速”编译,有几个错误是明显的:
- 首先,我还没有能够重现你的错误 - 相当期待,因为我没有看到你在哪里分配任何单位的文件。你会介意仔细检查这是否确实是你得到的错误,并说明什么是编译器?
- n大于10的数组超出界限
- 第二个WRITE是否刚刚abov“dt”试图写出?
- 为什么你需要双精度?
- 另外,如果您在循环中使用“n”作为索引,则明智地将其声明为整数而不是实数
- 您使用“n”作为索引,但也使用平方根。 ..将其转换为真正的数值,然后再用FLOAT(n)函数以平方根的形式使用它。

除了那个(也许还有其他一些事情我不介意),我没有看到任何问题。对于n < = 10它给出了结果。虽然我再说一遍,但我没有花时间来分析它们,所以它们可能是不正确的,但它确实会将它们分发出去。


program solution; implicit none 

    !variable declaration 
    integer :: i, n 
    real :: dt, first_argument, second_argument, lci, uci, mean, exp1, r, segma 
    real, dimension(0:99) :: st, stmean 

    WRITE(*,'("Please enter number of trials: ",\)'); read(*,*)n 
    dt=1.0; segma=0.2; r=0.1 

    st(0)=35.0; stmean(0)=35.0; mean=stmean(0) 

    write(*,'("For ",i2.2," trials")')n 
    write(*,'("   1 ",f14.5)')st(0) 

    DO i=0, n-2 
     first_argument = r-(1/2*(segma*segma))*dt 
     exp1 = -(1/2)*(i*i) 
     second_argument = segma*sqrt(dt)*((1/sqrt(2*3.1416))*exp(exp1)) 
     st(i+1) = st(i) * exp(first_argument+second_argument) 

     IF(st(i+1)<=20) THEN 
     stmean(i+1) = 0.0 
     st(i+1) = st(i) 
     else 
     stmean(i+1) = st(i+1) 
     ENDIF 

     PRINT *,i+2,'  ',stmean(i+1) 
     mean = mean+stmean(i+1) 
    END DO 

    uci = mean+(1.96*(segma/sqrt(float(n)))) 
    lci = mean-(1.96*(segma/sqrt(float(n)))) 
    PRINT *,'95% Confidence Interval for ', n, ' trials is between ', lci, ' and ', uci 
    END PROGRAM SOLUTION 
+0

感谢您的帮助。 我使用intel/fc与ifort进行编译。 当你说如果n大于10的数组超出界限 - 你在哪里可以看到? – Taka 2010-06-09 12:51:31

+0

@Taka - 呃,如果我用n> 10编译它,那是编译器给我的错误之一。我不知道它的确切的命令行开关,但它应该在“ifort /?”下的某处。帮帮我。它也可以从你的数组声明中看到,它们是从0到9,但是在DO循环中,你试图给数组中的元素赋值,从0到n-2 ... st(i + 1 )部分初学者... //你是从命令行还是从IDE使用ifort? – Rook 2010-06-09 12:55:30

+0

ifort/check:bounds Source1.f90 ...“check”部分将在运行时检查是否出现界限错误。 – Rook 2010-06-09 12:58:54

0

由于@Idigas标识,一个问题是都被索引过了边界阵列。在开发Fortran程序时,1)总是打开所有的编译器调试选项,特别是边界检查,以及2)将子程序和函数放入模块并“使用”它们是有用的 - 这将允许编译器检查一致性实际参数和虚拟参数。这两个步骤将会遇到很大一部分错误。

优雅的方式来处理现代的Fortran数组大小的问题是声明数组作为分配然后设置其大小在运行时,接收用户输入,而不是猜测的最大大小时后您编写程序。如果您有理由在编译时设置大小,并且用户输入可能导致超出范围,则测试该输入是明智的。

可分配的部分解决方案的草图:

real, dimension (:), allocatable :: st, stmean 

read (*, *) n 

allocate (st (0:n)) 
allocate (stmean (0:n))