2010-06-09 55 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))