4

論文から FORTRAN IV プログラムをコピーしたので、それが書かれた時点ではおそらく動作していたでしょう。gfortranでコンパイルしました。実行中は、統合サブルーチンで停止します。残留物を緩和しようとしましたが、役に立ちませんでした。(コードに間違いがないことを前提として) gfortran は古風な 66/IV コードを好まない可能性があり、それを更新することは私の能力を超えているため、私は助けを求めています。

プログラムは 9 行目でスタックするので、DO ループが原因なのだろうか。',1' が末尾に追加されているため、1 行目と 6 行目は私には珍しいことに注意してください。たとえば、=1,N,1 です。

5 行目で呼び出される FUNC サブルーチンを表示する必要はないと思いますが、必要に応じて喜んで表示します。

より詳細な情報が必要な場合は、喜んで提供します。

00000001 13  DO 22 TDP=QDP,7,1
00000002     TD=TDP-1
00000003     X=X0+H0
00000004     IF(TD.EQ.QD) GOTO 15
00000005     CALL FUNC(N,DY,X,Y,J)   
00000006 15  DO 21 RD=1,N,1
00000007     GOTO (120,121,122,123,124,125,126),TDP
00000008 120     RK(5*N*RD)=Y(RD)
00000009     GOTO 21
00000010 121     RK(RD)=HD*DY(RD)
00000011     H0=0.5*HD
00000012     F0=0.5*RK(RD)
00000013     GOTO 20
00000014 122     RK(N+RD)=HD*DY(RD)
00000015     F0=0.25*(RK(RD)+RK(N+RD))
00000016     GOTO 20
00000017 123     RK(2*N+RD)=HD*DY(RD)
00000018     H0=HD
00000019     F0=-RK(N+RD)+2.*RK(2*N+RD)
00000020     GOTO 20
00000021 124     RK(3*N+RD)=HD*DY(RD)
00000022     H0=0.66666666667*HD
00000023     F0=(7.*RK(RD)+10.*RK(N+RD)+RK(3*N+RD))/27.
00000024     GOTO 20
00000025 125     RK(4*N+RD)=HD*DY(RD)
00000026     H0=0.2*HD
00000027     F0=(28.*RK(RD)-125.*RK(N+RD)+546.*RK(2*N+RD)+54.*RK(3*N+RD)-
00000028    1378.*RK(4*N+RD))/625.
00000029     GOTO 20
00000030 126     RK(6*N+RD)=HD*DY(RD)
00000031     F0=0.1666666667*(RK(RD)+4.*RK(2*N+RD)+RK(3*N+RD))
00000032     X=X0+HD
00000033     ER=(-42.*RK(RD)-224.*RK(2*N+RD)-21.*RK(3*N+RD)+162.*RK(4*N+RD)
00000034    1+125.*RK(6*N+RD))/67.2
00000035     YN=RK(5*N+RD)+F0
00000036     IF(ABS(YN).LT.1E-8) YN=1
00000037     ER=ABS(ER/YN)
00000038     IF(ER.GT.G0) GOTO 115
00000039     IF(ED.GT.ER) GOTO 20
00000040     QD=-1
00000041 20  Y(RD)=RK(5*N+RD)+F0
00000042 21  CONTINUE
00000043 22  CONTINUE
4

3 に答える 3

3

確実にすることは困難ですが (スニペットがソース ファイルと完全に一致するかどうかは完全にはわかりません)、問題は古い FORTRAN の問題から発生する可能性があり0ます。6 桁目のその他の (空白以外の) 文字は、継続標識として扱われますが、. ではありません0

于 2013-06-07T12:51:57.567 に答える
1

すべての f66 コンパイラが、ループを少なくとも 1 回実行するという規則に準拠しているわけではありませんが、これは一般的な (移植性のない) 仮定でした。同様に、すべての静的変数の仮定は移植可能なものではありませんでしたが、f77 で始まる SAVE ステートメントを追加することで実装できます。SAVE 変数がゼロで初期化されるというさらなる前提は、さらに移植性がありませんが、ほとんどのコンパイラにはそれを実装するオプションがあります。

古いコードを復活させようとする試みが行われている場合、より自己文書化できるように段階的に最新化する前に、それを機能させることはおそらく価値があります。計算された goto は、最適化の可能性を犠牲にして、選択ケースに置き換えることができる比較的健全なもののように見えます。ここで、「近代化」という言葉の最近の使用は矛盾しています。

于 2015-10-09T14:00:36.663 に答える
0

,1 ビットは、コンパイラにエラーを検出させるためのものです。次のことを行うのは非常に一般的です

DO 10 I = 1.7

変数名にはスペースが許可されているため、これは完全に合法です。それを避けたい場合は、余分な数を入れてください。以下はエラーを生成します

DO 10 I = 1.7,1
DO 10 I = 1,7.1
DO 10 I = 1.7.1

プログラムで問題が発生した場合は、ラベル 21 と 22 の間に継続行を挿入してみてください。if-goto は、Fortran の新しいバージョンの if-not-then と同じであり、計算された goto は select ステートメントと同じです。再コーディングする必要はありません。若者が goto を見るたびに混乱すること以外には何も問題はありません。あなたがする必要があるのは、インデントするだけで、それが明らかになります。だからあなたが持っているのは

    DO 22 TDP = QDP, 7, 1
       ...
       DO 23 RD = 1, N, 1
          GOTO (...) TDP
             ...
             GOTO 21
             ...
             GOTO 20
             ...
             GOTO 20
             ...
20        CONTINUE
          Y(RD) = ...
21        CONTINUE
23      CONTINUE
22   CONTINUE

再コーディングしようとすると、おそらくはるかに多くのコードになるでしょう。goto が別の単語に置き換えられていることを除けば、見た目はまったく同じです。コンパイラが間違ったコードを生成している可能性があるため、いくつかのダミー (CONTINUE) ステートメントを追加してください。

于 2013-06-06T23:08:50.047 に答える