1 名前:デフォルトの名無しさん mailto:sage [2007/11/30(金) 09:55:26 ] このスレッドは、他のスレッドでは書き込めない超低レベル、 もしくは質問者自身何が何だか分からない質問を勇気を持って書き込むスレッドです。 FORTRAN使いが優しくコメントを返しますが、 お礼はFORTRANの布教と初心者の救済と次期Fortran2008規格でのCOMEFROM文採用をお願いします。 ●注意事項 ・質問する前にGoogle等の検索サイトで検索しましょう。 ・回答者にわかりやすい様に、質問内容はできる限り詳しく書きましょう。 ・エラーの場合は起きた状況、環境(OS・コンパイラ・バージョン)、エラーメッセージも詳しく書きましょう。 ●前スレ くだすれFORTRAN(超初心者用) pc8.2ch.net/test/read.cgi/tech/1138063703/ くだすれFORTRAN(超初心者用)その2 pc11.2ch.net/test/read.cgi/tech/1164121236/ ●関連スレ FORTRAN W pc8.2ch.net/test/read.cgi/tech/1163319215/
321 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 21:21:57 ] >>320 つ LOGICAL
322 名前:デフォルトの名無しさん mailto:sage [2008/05/16(金) 09:03:44 ] >>321 あったんですか、失礼しました 今まで0、1をfalse、trueとしてやってて、なんかかっこ悪いなぁと思ってまた。というか危険ですよね ありがとうございました
323 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 21:46:14 ] 初歩的な質問で申し訳ないのですが。 資料を読み込む時、上からのn行が全ていりません場合はどうすればいいのですか? 僕はこう考えますが: open(unit=10,file=filename,access="sequential",status="old") do while( .true. ) read(unit=10,fmt="???",iostat=status) ???のところをいじればいいのですか? それとも何か他の書き方にした方がいいのですか?
324 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 22:37:39 ] >>323 DO i = 1, 10 READ(10, *) END DO
325 名前:デフォルトの名無しさん mailto:sage [2008/05/19(月) 12:50:03 ] DO i = 1, 10 READ(10, *) END DO はどこに入れますか? これで10行までの資料が読まれるけど保存されてないですよね? 僕はn行まではいらないけが、 n+1以後の資料はちゃんと読まれて配列に保存したいんです。
326 名前:デフォルトの名無しさん mailto:sage [2008/05/19(月) 19:09:07 ] fortran90で、ターミナルへの出力を一旦停止して、 例えば1分後に再開するという感じにしたいのですが これは pause を使ってできますか? pause だけだと、何か入力しないと再開しないのですよね? 僕は1分後に自動的に再開したいんです。
327 名前:デフォルトの名無しさん mailto:sage [2008/05/20(火) 00:44:47 ] >>325 DO i = 1, n READ(10, *) END DO DO READ(10, *, IOSTAT = io) a, b, c IF (io == -1) EXIT END DO io = -1 は End of File >>326 Fortranの規格の範囲内では基本的には無理。 空ループをまわして、DATE_TIMEで時間を監視してやれば出来ないことは無い。 しかしCPUが無意味に使われるのでお勧めできない。 ただコンパイラの多くは SLEEP() 関数等を用意しているので、マニュアルのコンパイラ独自拡張の所を よく読めば出来る可能性が高い。またはライブラリなどの外部ルーチンを呼ぶという方法も無くは無い。 難易度はやや高い。
328 名前:デフォルトの名無しさん mailto:sage [2008/05/20(火) 09:35:10 ] >>326 、>>327 call system( ' sleep 60 ' ) ってダメかな?
329 名前:デフォルトの名無しさん mailto:sage [2008/05/20(火) 10:37:59 ] >>327 , 328 どうもありがとうございます。がんばってみます。
330 名前:デフォルトの名無しさん mailto:sage [2008/06/02(月) 20:31:19 ] ファイルをEOFまで読む場合、read文にend=99とかして飛ばすようにすればできますが、 行番号使うのはあまりスマートじゃないし、基本的に使うべきじゃないですよね。 他の方法ってないでしょうか?
331 名前:デフォルトの名無しさん mailto:sage [2008/06/03(火) 01:00:15 ] >>330 >>327 に出ている。 IOSTATの番号は機種依存だが、EOFの-1は確定と見ていい(これが規格に定められて いるのか、慣習なのかよく分からんw) それと行番号差別はよくない。行番号だっていい子なんだw 使いたいときは使うがいい。 あとFortran2003では、定数としてEOFやEOL等が定められている。
332 名前:デフォルトの名無しさん mailto:sage [2008/06/03(火) 17:31:23 ] fortranってスコープ内のローカル変数とかって作れないんすかね?
333 名前:デフォルトの名無しさん mailto:sage [2008/06/03(火) 18:48:12 ] >>332 サブルーチン化する
334 名前:デフォルトの名無しさん mailto:sage [2008/06/03(火) 22:12:51 ] NaN を代入したいときってどうしたらいいですか。 たとえば function を作るとき、定義域外の引数を受け取ると NaN を 返すようにしたいんです。 ゼロで割り算すると NaN が返るけど、コンパイラによってはエラーや 警告が出るのでそれは避けたい。
335 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 00:47:24 ] >>334 PROGRAM NAN IMPLICIT NONE REAL(4) :: a ! 12345678901234567890123456789012 a = TRANSFER(B'01111111100000000000000111111110', 0.0) PRINT *, a STOP END PROGRAM NAN a には NaN が入る。NaN は指数部が全ビット立っていて、仮数部が0以外なので 単精度の場合はこれでいい。endian の違いによらないように左右対称にしてみたw TRANSFER関数を使えば任意の型の中に任意の型での値を入れられるので それを用いればよい。ここでは2進表現の整数を入れたが、別に文字列とかでもいいので、 たとえば倍精度で64こ0と1を並べる必要も無い。
336 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 00:51:54 ] >>332 Fortranではスコープ内のローカル変数は無い。 というかスコープという概念は無い。 もともとのFortranは暗黙の型宣言がなされているので、宣言にこだわる必要は無い。 一方Fortran90以降では、ALGOL/Pascal/Modulaの系列の影響を受けたので、 宣言部はプログラム頭部に集中される。 スコープなどは忘れて、早く暗黙の型宣言を信仰するんだ。 最近の言語では型宣言の省略が流行り始めているので、一周遅れでTopに立てるww
337 名前:335 mailto:sage [2008/06/04(水) 00:57:48 ] 補足 PROGRAM NAN IMPLICIT NONE REAL(4) :: a REAL(8) :: d a = TRANSFER(-1_4, a) d = TRANSFER(-1_8, d) PRINT *, a, d STOP END PROGRAM NAN 実行結果 by Intel Fortran NaN NaN Press any key to continue . . . ここで -1_4 と -1_8 はそれぞれ4バイトと8バイトの整数の -1 。 2の補数表現なので整数の -1 は全ビット立ってる。
338 名前:334 mailto:sage [2008/06/04(水) 07:51:04 ] >>337 ありがとうございます。やってみます。 助かりました
339 名前:デフォルトの名無しさん mailto:sage [2008/06/05(木) 18:46:57 ] character*3 str str='ABC' print *,str(1:1) とすると、Aが出力されますが、 character*3 str(1) str(1)='ABC' print *,str(1:1) とすると、ABCが出力されます。 これはどういう仕組みでこうなるんでしょうか? characterは文字の配列で実現されているんですよね?
340 名前:デフォルトの名無しさん mailto:sage [2008/06/05(木) 21:19:30 ] 後者だと str は大きさ1の1次元配列で、配列の各要素は長さ3の文字列。
341 名前:デフォルトの名無しさん mailto:sage [2008/06/06(金) 00:24:53 ] >>339 >characterは文字の配列で実現されているんですよね? ちがう。 それはCとかのやり方。 character*3 str(1) これは>>340 が書いているように長さ3の文字型の全要素数1の配列の宣言。 そこでやりたいことは、これで実現される。 PRINT *, str(1)(1:1) むろん PRINT *, str(1:1)(1:1) でも同じこと。 部分文字列は定数でも指定出来る。 print *, 'abe-san'(1:3) これは abe を出力する。 マニュアルをよく読み返すことをおすすめする。 Fortran90では文字列操作の便利な関数が増えたので読み甲斐ある。
342 名前:339 mailto:sage [2008/06/06(金) 21:33:39 ] >>340 ,341 ありがとうございます。Cとは違うんですね。 Fortranって文字処理苦手な印象持ってましたが、最近は違うんでしょうかね
343 名前:デフォルトの名無しさん [2008/06/07(土) 02:04:05 ] FORTRAN90の質問です。 初心者なので課題が手につきません。お願いします。 「うるう年のプログラム」 「2次方程式の判定プログラム」
344 名前:デフォルトの名無しさん mailto:sage [2008/06/07(土) 04:00:31 ] >>343 Fortran ResQ 閏年 fortran 方程式の実数解 でググレ
345 名前:デフォルトの名無しさん mailto:sage [2008/06/07(土) 11:14:49 ] >>343 先生に聞けよ、授業料払ってるんだろ。
346 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 01:32:43 ] >>343 うるう年の方。結果を確認していないw PROGRAM leap IMPLICIT NONE INTEGER :: iy LOGICAL :: qleap PRINT *, 'INPUT YEAR' READ *, iy qleap = .FALSE. IF ( MOD(iy, 4) == 0 ) qleap = .TRUE. IF ( MOD(iy, 100) == 0 ) qleap = .FALSE. IF ( MOD(iy, 400) == 0 ) qleap = .TRUE. IF ( qleap ) THEN PRINT *, 'LEAP YEAR' ELSE PRINT *, 'ORDINARY YEAR' END IF STOP END PROGRAM leap
347 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 01:42:58 ] >>343 二次方程式の分類 一切チェックをしていないw 英語は適当www PROGRAM quadratic_eq IMPLICIT NONE REAL :: a, b, c, d PRINT *, 'INPUT A, B, C OF A QUADRATIC EQUATION AX**2 + BX + C = 0.' READ *, a, b, c d = b**2 - 4.0 * a * c IF ( a == 0.0 ) THEN IF ( b == 0.0 ) THEN IF ( c == 0.0 ) THEN PRINT *, 'UNDETERMINABLE' ! a=0, b=0, c=0 ELSE PRINT *, 'INCONSISTENT' ! a=0, b=0, c/=0 END IF ELSE PRINT *, 'ONE NON-DEGENERATE SOLUTION' ! a=0, b/=0 END IF ELSE IF (D > 0.0) THEN PRINT *, 'TWO REAL SOLUTIONS' ! D > 0 ELSE IF (D < 0.0) THEN PRINT *, 'TWO COMPLEX SOLUTIONS' ! D < 0 ELSE PRINT *, 'TWO-FOLD DEGENERATE SOLUTIONS' ! D = 0 END IF END IF STOP END PROGRAM quadratic_eq
348 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 02:39:33 ] >>346 オマエさん、凄くいい奴。改訂ユリウス暦ってのもあるんだな。 (第三条件:西暦年を900で割った余りが200または600になる年は閏年) 出題者は、グレゴリオ暦と正確に指示しているんだろうか? 「明治31年勅令第90号に基づき閏年を判定するプログラムを作成すること」 というマニアックな教師がいたら嫌だな。
349 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 02:51:19 ] >>347 IF の分岐、上手いね。不定・不能まで判定してやるとは、さすが。 EPS で0判定したいところだが、READ なら不要かな?
350 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 02:57:12 ] BASICかと思ったぜ FORTRAN90なのか
351 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 02:59:14 ] >>347 追加演習問題として、次のようなのはどう? 「数学的には重解になるが、自らのプログラムで重解と判定されない 二次方程式の係数を一例あげよ。」
352 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 03:00:47 ] >>350 PRINT とあるとBASIC っぽいが、宿題レベルなら十分だろうね。
353 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 04:17:23 ] >>351 ぐはw 0.1 2 1.0 で既に重根判定が崩れているw 0.125 2.0 8.0 とか二進法での有理数なら大丈夫なんだがw a==0.0の類もどうかと思ったが、EPSILONとか使うと初心者らしくないかと思ってチョンボしたが、 Dは掛け算の後の引き算があるから避けられないなw PROGRAM quadratic_eq IMPLICIT NONE REAL :: a, b, c, d WRITE(*, *) 'INPUT A, B, C OF A QUADRATIC EQUATION AX**2 + BX + C = 0.' READ(*, *) a, b, c d = b**2 - 4.0 * a * c IF ( a == 0.0 ) THEN IF ( b == 0.0 ) THEN IF ( c == 0.0 ) THEN WRITE(*, *) 'UNDETERMINABLE' ! a=0, b=0, c=0 ELSE WRITE(*, *) 'INCONSISTENT' ! a=0, b=0, c/=0 END IF ELSE WRITE(*, *) 'ONE NON-DEGENERATE SOLUTION' ! a=0, b/=0 END IF ELSE IF (D < EPSILON(0.0) ) THEN WRITE(*, *) 'TWO-FOLD DEGENERATE SOLUTIONS' ! D = 0 ELSE IF (D > 0.0) THEN WRITE(*, *) 'TWO REAL SOLUTIONS' ! D > 0 ELSE WRITE(*, *) 'TWO COMPLEX SOLUTIONS' ! D < 0 END IF END IF STOP END PROGRAM quadratic_eq
354 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 04:27:57 ] 0.1 2 1.0 →0.1 2.0 10.0 の間違いw PRINT * はデバッグの時使うと便利。 普通のコンソール出力をWRITE(*,*)で書いておけば、後からデバッグ用出力を消し忘れることが無い。 READ * もたまに便利。 一応、宿題なので初心者っぽく、ちぐはぐなところを演出してみましたw >>348 グレゴリオ暦のうるう年のアルゴリズムを確認しにWikipediaを見たときに、下のほうに改訂ユリウス暦と いうのがあったので嫌な予感がしたがw やはりそう来ますかw
355 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 06:10:32 ] >>353 ダメじゃん、学生さんに考えてもらわないとw 初心者だと整数と決め込んでしまいがちだから、 試行錯誤してもらえるかなと。 「丸め誤差に対する考察と、プログラム改良とその改善効果の提示」 A4一枚にまとめてもらえると、講師冥利につきるね。 学年に数人はそういう学生さんがいてほしいな。 不能・不定は、数学的な気配りがないと見過ごしがちだから、 考慮していない学生さんもいるだろうね。 丸め誤差は、数値計算の経験がないと気付かないから、 IF文を習ったばかりなら配慮できっこないねw
356 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 06:18:01 ] >>353 さらに追加演習問題(表現は曖昧)として、次のようなのはどう? 「この二次方程式に解がある場合、その解を出力するように改造せよ。 相異なる二つの実数解をもつ場合、 数学的な厳密解と出力した実数解との誤差が大きい 二次方程式の係数を一例あげよ。」 倍精度実数型や計算手順配慮の必要性を 学生さんに感じてもらえるかな。
357 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 16:42:46 ] 丸め誤差ってコンパイラオプションによっては違った結果になるよね あんま気をつけたことはないけど、精度命な人はその辺も考えてるのかな
358 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 18:45:04 ] 文を改行後も続ける場合、&を行末に付加するって仕様、早く直らないかなぁ。 面倒で仕方ない。
359 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 20:57:27 ] >>358 ? 昔のように頭の方に継続記号を入れろってことか?
360 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 21:34:06 ] 考えようによってはCみたいに文末ごとに ; を付けるよりよっぽどお手軽だぞw
361 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 22:06:47 ] >>358 Fortran文法は行番号があって,しかも予約語がない end = 1 + end print *, end, end; end とか do 10 do= 10, 10 10 end do end いや聞くだけでわくわくする文法ですね
362 名前:デフォルトの名無しさん mailto:sage [2008/06/09(月) 00:42:13 ] PASCALとかCとかって終端文字;を書くのがめんどくさくて死にそう FORTRANはやっぱイイナと思うよ。
363 名前:デフォルトの名無しさん mailto:sage [2008/06/10(火) 12:04:01 ] Fortran77の質問です。初心者なので次の課題がでてよく分かりません。お願いします。 「フィボナッチ数列を配列f()とDo文を使って計算させ、30項までの結果を8i8の書式で出力せよ。 「日本で現在の流通通貨は1万円札から1円玉まで9種類ある(2千円札を除く)。 5桁の金額 kin を最も少ない枚数でそろえるには、それぞれ何枚になるか出力する。 貨幣9種の額はファイル kahei.txt から読み込む。出力の書式は○○yen ○○mai.」
364 名前:デフォルトの名無しさん mailto:sage [2008/06/10(火) 17:28:54 ] >>360 文が複数行に渡るなんてよくあるし、Cみたいな;のほうが良いと思う俺はFortraner失格ですか? 最近遊びでVSのC#を触ったが、色んな意味で感動したw 他の言語触るのはなかなかイイもんですな
365 名前:デフォルトの名無しさん mailto:sage [2008/06/10(火) 18:11:18 ] >>363 フィボナッチらしき(間違えている)ものを作った。 宿題に合わせて、間違えを修正しろ。 program main integer f(10) f(1)=1 f(2)=1 do 10 i=3,10 f(i)=f(i)+f(i) 10 continue write(6,'( 8i8 )') (f(j),j=1,10) end
366 名前:デフォルトの名無しさん mailto:sage [2008/06/10(火) 18:48:57 ] >>363 とりあえず入出力はつくった。 計算式をよく考えろ。 program main integer kahei(9) integer kin open (1,File='kahei.txt') do 10 i=1,9 read(1,*) kahei(i) 10 continue print *, "input kingaku" read *, kin do 20 i=1,9 write(6,'( i5, "yen ", i1, "mai" )') kahei(i), kin/kahei(i) 20 continue end kahei.txt 10000 5000 1000 500 100 50 10 5 1
367 名前:デフォルトの名無しさん mailto:sage [2008/06/11(水) 00:45:49 ] >>363 しばらくぶりに77で書いた。すでに>>365-366 があってがっくしwww PROGRAM FIBONA INTEGER F(0:30) F(0) = 0 F(1) = 1 DO 10 I = 2, 30 F(I) = F(I - 1) + F(I - 2) 10 CONTINUE WRITE(*, '(8I8)') (F(I), I = 0, 30) STOP END PROGRAM KANE INTEGER KAHEI(9), NUM(9) OPEN(9, FILE = 'KAHEI.TXT') DO 10 I = 1, 9 READ(9, '(I8.8)') KAHEI(I) 10 CONTINUE WRITE(*, *) 'INPUT KINGAKU' READ(*, *) KIN DO 20 I = 1, 9 NUM(I) = KIN / KAHEI(I) KIN = MOD(KIN, KAHEI(I)) 20 END DO DO 30 I = 1, 9 WRITE(*, '(I6, A, I5, A)') KAHEI(I), ' YEN ', NUM(I), ' MAI' 30 CONTINUE STOP END
368 名前:デフォルトの名無しさん mailto:sage [2008/06/11(水) 11:32:44 ] >>365-367 どうもありがとうございました。助かりました。
369 名前:デフォルトの名無しさん mailto:sage [2008/06/12(木) 00:12:47 ] >>367 「キルヒアイス、お前は優しいな。」 20ループと30ループ合体できない? DO 20 I = 1, 9 NUM = KIN / KAHEI(I) KIN = MOD(KIN, KAHEI(I)) WRITE(*, '(I6, A, I5, A)') KAHEI(I), ' YEN ', NUM, ' MAI' 20 END DO
370 名前:デフォルトの名無しさん mailto:sage [2008/06/12(木) 02:28:49 ] >>369 それも思ったが、I/Oと主演算は分離すべきかなと思って分けた。 天皇陛下万歳!
371 名前:デフォルトの名無しさん [2008/06/13(金) 01:34:43 ] すいません、初心者なんですが windows上で動くFORTRANのエミュってありますか?
372 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 01:44:23 ] >>371 VMwareにLinux入れてg77使えばおkw
373 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 01:46:34 ] >>371 ある。77も95も。 ぐぐれw
374 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 04:53:55 ] >>373 お勧めの物はないのでしょうか?
375 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 08:01:12 ] fortran のエミュってどういう意味なんだろう? 単に IDE があってコンパイルができればいいなら silverfrost ftn95 でググれば見つかるよ。
376 名前:デフォルトの名無しさん mailto:sage [2008/06/16(月) 02:07:35 ] >>374 G95とかどう? ttp://ftp.g95.org/ Self-extracting Windows x86かそのへん
377 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 01:57:48 ] >>376 cygwin入れるのがだるい。
378 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 02:42:03 ] >>377 まあマジレスすると Self-extracting Windows x86 の方はMinGWだから Cygwin環境が無くても単独で動くわけだが。
379 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 09:13:45 ] しかし Cygwin のインストールがだるいって相当だな
380 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 19:07:53 ] 倍精度計算で、D○.○のようにして出力すると 例えば 0.12345D-3 のように表示されてしまうのですが これを1.2345D-4 と表示する事は可能でしょうか? 試行錯誤しているのですが全然分からず教えて頂きたいです
381 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 19:41:00 ] 昔はcygwin入れるのは当たり前って感じだったが今はな・・・ 最近影薄くて心配になるけど、細々と続いてるようね
382 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 19:51:44 ] >>380 ESでできなかったかな。
383 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 23:44:40 ] >>380 フォーマット指定するだけじゃん・・・
384 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 23:55:47 ] >>382-383 ESとはなんでしょうか・・ ごめんなさい、どのようにしたら良いのかさっぱりで・・
385 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 00:43:11 ] >>384 フォーマットの指定で"D○.○"の所を"ES○.○"にする "D○.○"→0.100D+00 "ES○.○"→1.000E+00 "ES○.○E3"→1.00E+000 試してないから間違ってるかも
386 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 01:20:56 ] >>380 Fortran90でよければ、上にみんなが書いているようにESでおk。 FORTRAN77ならば、1P D○.○ 0P でいける。 P 指定子は破壊力がでかいので、使ったらすぐ 0P で元に戻すが吉。 ま、マニュアル嫁 PROGRAM ppp IMPLICIT NONE REAL(8) :: d d = 1.234567d-2 PRINT '(D15.6, ES15.6, 1P, D15.6, 0P)', d, d, d STOP END PROGRAM ppp 実行出力 0.123457D-01 1.234567E-02 1.234567D-02 Press any key to continue . . .
387 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 11:57:12 ] P指定子ってすごいよな・・・ 今考えるとアリエンけど、昔はああいう仕様は全然平気だったんだろうな
388 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 17:08:36 ] 世の中の処理系のほとんどが対応してると言っていいFortranのバージョンって、95でしょうか? ちょっと前は、95はまだ早いから無難に行くなら90にしとけ、って声を聞きましたが。
389 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 20:44:00 ] >>387 P指定子ってなんでありえないの?? よく使うのだが…
390 名前:デフォルトの名無しさん mailto:sage [2008/06/19(木) 23:07:51 ] 昔、>>380 の様に考えて出力用にP指定子を使ったが、クリアしていなかったので READのところでFフォーマットの値がスケールされて読まれてしまい、とんでもない結果が出て悩んだw たしかEとかベキ記号がついているときはスケールされないので、すげー悩んだ。 Fortran90の勉強を始めたとき、ESフォーマットがあったので、あぁアリガテーと思った。
391 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 12:47:18 ] >>389 マジで言ってんの・・・? まぁ気をつけてれば問題ないけどさ
392 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 16:22:50 ] 学校の課題で次のものが出たんですけど、初心者なのでわかりません。お願いします。ちなみにFORTRAN77です。 今日の月日と曜日を入力し,これを用いて今年の任意の月日の曜日を出力させよ. 各月の日数はファイルから読み込む.ファイル名や変数名は自分で付ける. 曜日は数値で代用してよい.日曜=1,月曜=2,・・・土曜=7. 目標の月日が何日後か(前か)を出す.それから曜日を計算する. today 6 23 2 when 1 1 -174days 3you today 6 23 2 when 12 31 191days 4you
393 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 17:25:50 ] >>392 「今年」と銘打っているのに、曜日の入力を要求するんだな。 今日の月日と曜日に不整合があった場合、どうするんだろう。 まずは次の課題を考えなさい。 今日の月日を入力し、一年の経過日数(正月=1)を出力するプログラムを作成せよ。
394 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 20:34:09 ] わかってるところとわからんことを書かないと、アドバイスのしようがないのでは? 全部かいてもらう気なら別だが。
395 名前:392 mailto:sage [2008/06/23(月) 20:41:37 ] >>394 上にも書きましたが初心者です。 全部わからないので全部書いてください。
396 名前:392 mailto:sage [2008/06/23(月) 20:54:35 ] 上の人は別人です まだFORTRAN77を触り始めて間が無いので表示するプログラムが限界です 勉強のためにコメントをつけてくだされば嬉しいです って言いたいと思う
397 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 21:17:09 ] >>396 本質的には >>395 と言っている事が一緒だね。 さらに解説ヨロってのも凄いが。
398 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 21:36:47 ] まぁとりあえず、作ってみようぜ
399 名前:デフォルトの名無しさん [2008/06/23(月) 23:13:44 ] 学校の課題なんだから必要な構文の説明あるだろ 初心者じゃなくて怠け者だろ
400 名前:デフォルトの名無しさん [2008/06/24(火) 02:33:14 ] この問題がわかりません↓ 0.0 から 1.0 までの 10 個の値、 0.12, 0.32, 0.09, 0.83, 0.58, 0.39, 0.72, 0.44, 0.71, 0.24 を使って、起点 0.0、幅 0.2 としたときの頻度分布 を求めるプログラムを作成せよ。 結果はこのように表示されるようです。 s < 0.2 2 0.2 <= s < 0.4 3 0.4 <= s < 0.6 2 0.6 <= s < 0.8 2 0.8 <= s 1 if文を使うのはわかるのですが、頻度分布をどう求めていいのかわかりません。 fortran77です。 どうかよろしくお願いします。
401 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 09:21:12 ] >>396 初心者には、入出力まわりが一番難しいのだが。
402 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 10:36:12 ] >>400 PROGRAM HIST INTEGER NUM(5) REAL S(10) DATA S / 0.12, 0.32, 0.09, 0.83, 0.58, $ 0.39, 0.72, 0.44, 0.71, 0.24 / DO 10 I = 1, 5 NUM(I) = 0 10 CONTINUE C DO 20 I = 1, 10 IF (S(I) .LT. 0.0) THEN WRITE(*, *) 'INPUT ERROR!' STOP ELSE IF (S(I) .LT. 0.2) THEN NUM(1) = NUM(1) + 1 ELSE IF (S(I) .LT. 0.4) THEN NUM(2) = NUM(2) + 1 ELSE IF (S(I) .LT. 0.6) THEN NUM(3) = NUM(3) + 1 ELSE IF (S(I) .LT. 0.8) THEN NUM(4) = NUM(4) + 1 ELSE IF (S(I) .LE. 1.0) THEN NUM(5) = NUM(5) + 1 ELSE WRITE(*, *) 'INPUT ERROR!' STOP END IF 20 CONTINUE C
403 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 10:36:47 ] WRITE(*, *) 's < 0.2 ', NUM(1) WRITE(*, *) '0.2 <= s < 0.4 ', NUM(2) WRITE(*, *) '0.2 <= s < 0.4 ', NUM(3) WRITE(*, *) '0.6 <= s < 0.8 ', NUM(4) WRITE(*, *) '0.8 <= s ', NUM(5) STOP END s < 0.2 2 0.2 <= s < 0.4 3 0.2 <= s < 0.4 2 0.6 <= s < 0.8 2 0.8 <= s 1 Press any key to continue . . .
404 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 11:20:33 ] >>392 あまりチェックしてない。 曜日求め部分をよく練っていない。 うるう年対応してしまったw 今年限定ならデータいじればよし。 FUNCTION ILEAP(IY) ILEAP = 0 IF (MOD(IY, 4) .EQ. 0) ILEAP = 1 IF (MOD(IY, 100) .EQ. 0) ILEAP = 0 IF (MOD(IY, 400) .EQ. 0) ILEAP = 1 RETURN END C FUNCTION IDAYS(IY, IM, ID) INTEGER MDAYS(12) DATA NFEB /28/ DATA MDAYS /31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/ MDAYS(2) = NFEB + ILEAP(IY) IDAYS = ID DO 10 I = 1, IM - 1 IDAYS = IDAYS + MDAYS(I) 10 CONTINUE RETURN END C
405 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 11:23:50 ] PROGRAM CALEND 1 WRITE(*, *) 'TODAY' READ(*, *) IM0, ID0, IDW0 IF (IM0 .LE. 0) STOP 'NORMAL END' WRITE(*, *) 'WHEN' READ(*, *) IM1, ID1 IDAYS0 = IDAYS(2008, IM0, ID0) IDAYS1 = IDAYS(2008, IM1, ID1) IDIFF = IDAYS1 - IDAYS0 IDW = MOD(IDIFF, 7) + 7 + IDW0 - 1 IDW = MOD(IDW, 7) + 1 WRITE(*, *) IDIFF, 'DAYS', IDW, 'YOU' GOTO 1 STOP END TODAY 6 23 2 WHEN 1 1 -174 DAYS 3 YOU TODAY 6 23 2 WHEN 12 31 191 DAYS 4 YOU TODAY 0 0 0 NORMAL END Press any key to continue . . .
406 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 12:03:44 ] >>404 乙 「各月の日数はファイルから読み込む」となっているね。 最近みかける宿題の出題者は、 無駄にファイル処理をさせようとしていない?
407 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 12:09:14 ] >>406 問題よく読んでなかったw 後で直す。
408 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 13:48:19 ] >>402 ありがとうございました!! NUMを使うんですね。 解決できました。感謝です。
409 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 15:03:32 ] >>408 > NUMを使うんですね。 ピントがずれてないか? 優しい人たち乙。 私なら「宿題は自分でやれ」で放置だな。
410 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 15:47:09 ] >>409 初心者はピントがずれているもんだよ orz
411 名前:デフォルトの名無しさん [2008/06/24(火) 20:20:12 ] 入力データ: test.datの中身 0,10,100,a,b,500, プログラムソース character dmm(10)*10 open(10,file='test.dat',status='old') read(10,*) (dmm(i),i=1,6) do i=1,6 write(*,*) dmm(i) end do stop end 出力結果 0 10 100 a b 500 compaq visual fortran 6.0では たとえば入力データの"b"->"*"に変更した場合のように 文字列にアスタリスクが入っている場合、エラーで落ちてしまいます。 cygwinのg77では問題なく表示されました。 コンパイラによって読めない文字列ってあるのでしょうか?
412 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 23:55:38 ] >>411 漏れのCVF6.6Cはbを*にしてもエラーでない。 単なるVer.6のバグでないか。 おぼろげな記憶ではVer.6→Ver.6.5は有料うpデートで、結構大きな変化があったはず。 Ver.6.0→Ver.6.1 と Ver.6.5→Ver.6.6は無料。
413 名前:407 >>392 mailto:sage [2008/06/25(水) 01:25:17 ] FUNCTION IDAYS(IM, ID, MDAYS) INTEGER MDAYS(12) IDAYS = ID DO 10 I = 1, IM - 1 IDAYS = IDAYS + MDAYS(I) 10 CONTINUE RETURN END C********************************************* FUNCTION IDW(IDIFF, IDW0) K = MOD(IDIFF + IDW0, 7) + 7 - 1 IDW = MOD(K, 7) + 1 RETURN END C********************************************* PROGRAM CALEND INTEGER MDAYS(12) OPEN(9, FILE = 'month.dat') READ(9, *) (MDAYS(I), I = 1, 12) C 1 WRITE(*, *) 'TODAY' READ(*, *) IM0, ID0, IDW0 IF (IM0 .LE. 0) STOP 'NORMAL END' WRITE(*, *) 'WHEN' READ(*, *) IM1, ID1 IDAYS0 = IDAYS(IM0, ID0, MDAYS) IDAYS1 = IDAYS(IM1, ID1, MDAYS) IDIFF = IDAYS1 - IDAYS0 WRITE(*, *) IDIFF, 'DAYS', IDW(IDIFF, IDW0), 'YOU' GOTO 1 STOP END
414 名前:407 >>392 mailto:sage [2008/06/25(水) 01:36:07 ] month.dat 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 >>406 今回は、うるう年を外部データとして与えようという親心なのかもしれない。 >>396 プログラムの解説 FUNCTION IDAYS(IM, ID, MDAYS) 一月一日から特定の月日までの日数を計算する。 FUNCTION IDW(IDIFF, IDW0) 今日からの日数差と今日の曜日から、その日数差の日の曜日を求める。 この計算式は、考えるのが面倒なのでちょっと複雑。 もう少しシンプルな書き方があるかもしれない。 FORTAN77のMOD関数は負数を引数とすると、負の数を返すので+7とかが必要。 Fortran90ならMODULO関数というのが新設されていて便利。 だがいずれにせよ7で割り切れるときは0を返すので、1〜7にするために-1/+1の 人工的な操作をした。自分で決める曜日を0〜6にすれば話はもっと楽になる。 PROGRAM CALEND まず各月の日数をファイルから読み込む。 今年はうるう年なので、うるう年の日数データを用意した。 あとは、I/Oの後、上で用意した関数を使ってやればいい。 ここでループから抜けるために、今日の月が0以下の数の場合終了するようにした。
415 名前:デフォルトの名無しさん mailto:sage [2008/06/25(水) 10:25:23 ] >>414 詳しい説明ありがとうございました。
416 名前:411 mailto:sage [2008/06/25(水) 13:24:19 ] >>412 Ver.6.0から6.1へアップデートしてみました。 今度は*のデータの後にブランクが入るようになりました。 つまり、>>411 の入力データでaを*にすると、 * b と表示されて、500のデータは読めていない。 おっしゃる通り、Ver.6.0とか6.1固有のバグなのかもしれません。 こういうデータ処理には使うなってことでしょうか。 ありがとうございました
417 名前:デフォルトの名無しさん mailto:sage [2008/06/26(木) 02:19:25 ] >>416 俺の予感では、 read(10,*) (dmm(i),i=1,6) をフォーマットつけて read(10,’(A)') にすればおkな気がする。根拠は宇宙からのメッセージ!w
418 名前:デフォルトの名無しさん mailto:sage [2008/06/26(木) 14:08:07 ] FortranってCの/*〜*/みたいな範囲コメントってできないんでしょうか?
419 名前:411 mailto:sage [2008/06/26(木) 14:16:04 ] >>417 そんなこと・・・あるかもなって思って試してみたけど、 だめだわ。エラーで落ちる。 cygwinのg77でもダメ。 その宇宙からのメッセージ、あんまあてに出来んぞ ま気持ちだけは嬉しかったわ。ありがとな(´・ω・`)
420 名前:デフォルトの名無しさん [2008/06/27(金) 00:29:58 ] >>418 fortranは、第1行目に「c」或いは「*」を入れるか、 「!」の後がコメントになる その他のコメントは聞いたことないし見たことない f90以降にそんなフォーマットがあるのかもしれんけど、おれは見たことない
421 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 01:31:33 ] >>418 Fortranは行を基本単位とする言語なので、行毎に指示をするのが自然な形だ。 CやPascalのように、行が意味を持たない代わりに終端符号などをいちいち付ける言語とは 根源的な思想の違いがある。 しかしプリプロセッサを使えば実は範囲コメントも実現出来る。 ただ、プリプロセッサは本来の規格の外にあるので処理系依存の機能になる。 自分の処理系のFortranマニュアルでfppとかを調べてみるべし。 良いニュースとしては将来Fortran2008で、プリプロセッサが規格に入ることになっているので、 それまで、待つという手もある。 10年くらい待つことになると思うがwwwwwww