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/
263 名前:デフォルトの名無しさん mailto:sage [2008/04/25(金) 10:39:23 ] 改行コードって、一行のバイト数合計値を一行の前後にサンドイッチするやつだよね? od -t x4で覗いたら、この値って4バイトだけど、これだと一行4Gバイトまでしか書けないことにならない?
264 名前:デフォルトの名無しさん mailto:sage [2008/04/25(金) 11:14:27 ] >>263 処理系依存だろうけど、今まで一語4バイトが主流だったから、そのくらいなんじゃない。 10年位前まではスパコンでも1配列のMaxが4Gだったし。
265 名前:デフォルトの名無しさん mailto:sage [2008/04/25(金) 15:07:14 ] >>264 そっか でもそろそろ拡張してもいいような
266 名前:デフォルトの名無しさん mailto:sage [2008/04/26(土) 23:34:36 ] アナル拡張
267 名前:デフォルトの名無しさん mailto:sage [2008/04/28(月) 13:05:57 ] *
268 名前:助けてください [2008/04/29(火) 14:17:32 ] あの〜私FORTRAN90初心者なんですが、ガウスの消去法のプログラムを作りたいのですが、 どなたか簡単に作っていただけないでしょうか? ちなみに格子点の間隔は0.25で格子点9個です。 時間が無いので本当にお願いします。
269 名前:助けてください [2008/04/29(火) 14:51:02 ] マルチポストしています。
270 名前:デフォルトの名無しさん mailto:sage [2008/04/29(火) 16:05:54 ] >>268 ググレカスでございます www.tnb.sd.kanagawa-it.ac.jp/home/lec/FEM/fortran.html
271 名前:デフォルトの名無しさん [2008/04/29(火) 19:02:53 ] 複素数のべき乗の計算はどのようにすればいいのでしょうか
272 名前:デフォルトの名無しさん mailto:sage [2008/05/01(木) 00:52:00 ] >>271 複素数の実数べきか?実数の複素数べきか?
273 名前:デフォルトの名無しさん mailto:sage [2008/05/01(木) 10:28:55 ] いえ10の100乗のタンジェントです
274 名前:デフォルトの名無しさん [2008/05/06(火) 01:05:31 ] 行列を作って対角化するプログラムを作っています。 行列を作るプログラムが動いたので それをサブルーチンに入れると コンパイルできるのですが、実行すると Segmentation fault (core dumped)のエラーが出ます。 行列の大きさは1000×1000です。 試しに行列のサイズを小さくすると350×350では動きました。 使ってるOSはvistaでcygwin上でg77でコンパイルしています。 メモリは2Gです。 行列サイズを大きいままで動かすことはできないでしょうか?
275 名前:274 [2008/05/06(火) 01:07:44 ] 行列を作るプログラムは 1000×1000でもちゃんと動きます。
276 名前:デフォルトの名無しさん mailto:sage [2008/05/06(火) 03:06:32 ] >>274 これだけでは、なんとも言えんなw g77だから動的にメモリー取ったりはしていないんだろうし? とりあえず、 -fbounds-check -ffortran-bounds-check この辺のオプションで配列はみだしチェックを。 もう少しヒントを呉。 たとえば行列は実対称の単精度の密行列で、ライブラリはLAPACK、呼んでるルーチンは、某。 呼び出し行は CALL xxxxx(xxxxxx) 使用変数の宣言行は、カクカクしかじか REAL H(1000, 1000), xxxxxxxxxxxx ぐらいあるとありがたい。
277 名前:274 mailto:sage [2008/05/06(火) 04:16:04 ] >>276 -fbounds-check をオプションにしてコンパイルしたらエラーは出ませんでした コンパイルしてできたexeを実行したら Segmentation fault (core dumped)のエラーが出ました 配列のはみ出しチェックのしかたがよくわからないのですが これでいいんですかね? あと行列は実対称の倍精度です。 今は対角化する以前の段階でプログラムは以下のような感じで作っています。 implicit none integer m parameter (m=1000) real*8 a(m,m) ・・・ call matrix(a,m,mm ・・・) write(*,*) mm (mmは実際に行列が書かれている行数) stop end subroutine matrix(a,m,mm ・・・) implicit none integer m, mm, ・・・ real*8 a(m,m), b(m,m), ・・・ ・・・ (行列を作る) return end
278 名前:274 mailto:sage [2008/05/06(火) 04:22:23 ] 上のようなプログラムです。 subroutineに入れなければm=2000でもきちんと動いたのですが 入れるとコンパイルはとおりますが 実行するとSegmentation fault (core dumped)のエラーが出ます(上に書いたとうりです) このくらいの情報でよろしいでしょうか? 足りないのなら付け足します。 よろしくお願いします。
279 名前:274 mailto:sage [2008/05/06(火) 17:18:06 ] 自己解決しました。 subroutine の中の大きい行列(>>277 のa(m,m)、b(m,m)など)全部を メインプログラムので定義してやるとm=1000でも動きました。 subroutineの中にだけでかい行列を何個も定義したらダメなんですね。 知らなかった。
280 名前:デフォルトの名無しさん mailto:sage [2008/05/06(火) 18:48:57 ] >>279 それは多分スタックオーバーフローだな。 g77エラーメッセージは不親切だな。
281 名前:デフォルトの名無しさん mailto:sage [2008/05/06(火) 19:02:33 ] >>277 よく分からないのだけど mm はメインで定義しなくてイイの?
282 名前:274 mailto:sage [2008/05/06(火) 21:25:45 ] >>280 スタックオーバーフローと思います。 今まででかい行列はメインで定義しないと スタックからあふれるということを知らなかったです。 >>281 すいません、メインでmmは定義してます。
283 名前:281 mailto:sage [2008/05/06(火) 22:25:27 ] 下のコードを g77 でオプション無しでコンパイルした時も -ffortran-bounds-check を付けてコンパイルした時も 正常に動作したけど。もぅワカリマセン。 program call_matrix implicit none integer m ,i ,j parameter (m=1000) real*8 a(m,m) call matrix( a, m ) do i = 1, m , 1 do j = 1, m , 1 write(*,*)"a(",i,",",j,")=",a(i,j) end do end do stop end program call_matrix subroutine matrix( a, m ) implicit none integer m, i,j real*8 a(1:m,1:m), b(1:m,1:m) do i = 1, m , 1 do j = 1, m , 1 a(i,j) = dble( i+j ) b(i,j) = dble( i*j ) end do end do return end subroutine matrix
284 名前:274 mailto:sage [2008/05/07(水) 04:21:21 ] >>283 さんのプログラムをg77でオプション無しでコンパイルして実行したところ Segmentation fault (core dumped)のエラーが出ました。 mの値を変えてコンパイルして実行を繰り返したところ m=509以上だとSegmentation fault (core dumped)のエラーがでます。 何か異常があるんですかね? 関係あるかどうかわかりませんがcygwinで ulimit -a を実行した結果を下に書きます。 core file size (blocks, -c) unlimited data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited open files (-n) 256 pipe size (512 bytes, -p) 8 stack size (kbytes, -s) 2033 cpu time (seconds, -t) unlimited max user processes (-u) 63 virtual memory (kbytes, -v) 2097152
285 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 09:54:02 ] >>284 509 * 509 * 8byte(倍精度) = 2,072,648 なので virtual memory の MAX超えてるのかもしれんな。Cygwin はよく知らんが、こんな小さい初期値なのか?
286 名前:285 mailto:sage [2008/05/07(水) 09:55:53 ] ごめんw よく見たら単位が kbytes だったw だからメモリーはまだ余裕だwwwwww
287 名前:281 mailto:sage [2008/05/07(水) 12:09:31 ] コンパイラを変えてみたらどうでしょうか? g95 と gfortran くらいしか思いつきませんが。
288 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 16:16:23 ] 配列サイズを引数で渡さずにサブルーチン内で定義すれば? んで、common 文をつかって、コンパイラに 「いちいちallocateしなくてもいいよ」と教えてあげる。 「common文は使っちゃだめ教」があるのは知ってるけど 試してみてちょ。
289 名前:288 mailto:sage [2008/05/07(水) 16:16:54 ] program call_matrix implicit none integer m ,i ,j parameter (m=1000) real*8 a(m,m) common /gyouretu/ a ! <-- ここ加えた call matrix( ) ! <-- ここ変えた do i = 1, m , 1 do j = 1, m , 1 write(*,*)"a(",i,",",j,")=",a(i,j) end do end do stop end program call_matrix subroutine matrix( ) ! <-- ここ変えた implicit none integer m parameter (m=1000) ! <-- ここ加えた integer m, i,j real*8 a(1:m,1:m), b(1:m,1:m) common /gyouretu/ a ! <-- ここ加えた do i = 1, m , 1 do j = 1, m , 1 a(i,j) = dble( i+j ) b(i,j) = dble( i*j ) end do end do return end subroutine matrix
290 名前:288 mailto:sage [2008/05/07(水) 16:19:57 ] あと、関係なとは思うけど多重ループはこの例の場合、 ループ制御のincrementalの整数は 内側をi 外側をj にする習慣を付けていた方が良いよ。知ってたらごめん。
291 名前:288 mailto:sage [2008/05/07(水) 16:25:02 ] コンパイル通らなかったw サブルーチンの中でmを2回定義しているから後のはとってね。 自分の所の g77 on linux (バージョン不明) だと動いたよ。 がんばってね。
292 名前:288 [2008/05/07(水) 16:48:44 ] 更にお節介。 parameter文で定義した変数を subroutineの引数に使うのはよした方が良いよ。 ・・・・ cygwin 最近使ってないなぁ。 274さんはhostのOSは何?もうvistaに対応してる?
293 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 18:10:04 ] OS :Windows Vista gfortranをインストールしてコンパイルしようとしたのですが、 下記のようなメッセージが出てコンパイルできません。 ld: crtbegin.o: No such file: No such file or directory どうすれば、コンパイルできるようになりますか?
294 名前:293 mailto:sage [2008/05/07(水) 18:20:36 ] 下記のページを参考にして、コンパイルを行いました。 ttp://www.esst.kyushu-u.ac.jp/~space/kumashiro/fortran.html
295 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 18:41:31 ] >>293 可能性は3つある。 インストールしたバイナリに問題がある。 インストール方法に問題がある。 コンパイルしようとしたプログラムソースに問題がある。 あとは任せた。君なら出来る。
296 名前:281 mailto:sage [2008/05/07(水) 19:11:08 ] >>292 > 更にお節介。 > parameter文で定義した変数を > subroutineの引数に使うのはよした方が良いよ。 ココ詳しく。実はよくやってます。
297 名前:293 mailto:sage [2008/05/07(水) 19:35:54 ] >>295 g95をインストールしてコンパイルしたら、できました。 ありがとうございました。
298 名前:デフォルトの名無しさん mailto:sage [2008/05/08(木) 11:51:23 ] >>296 281さんが例として出したプログラムだと問題ないんだけど、 何かの拍子にサブルーチン内でmの値を変更してしまう場合にややこしい。 おおざっぱに言って、メインレベルで定義された固定変数はコンパイラによって m = 1000 の代入処理+メインレベルでmが変更されていないかを監視するだけか、 前処理の段階でメインレベルでの変数mを1000に置き換えるかのどちらかをするんだけど 前者の場合、副プログラムで値が変わる場合までチェックしないので面倒。たとえば parameter(m=1000) call foo(m) write(*,*) m で副プログラムfoo中でm=1という代入文があるばあいに結果が保証されなくなっちゃう。 出力はコンパイラによって1000だったり1だったり、浮動小数点なら値がエンディアンレベルで壊れていたりする。 ぜったいmを副プログラムで変えない(intent文でチェックするとか)ならいいけど、 習慣として引数渡しせずに副プログラムでも parameter(m=1000)と定義してやった方が安全。 mの値の変更はたいていのエディタなら一括置換で出来るしね。 あるいはm2=mとかして非固定変数に値を移してからそれを引数にするとかすると良いと思う。 似た理由で do i = 1, 100 call foo(i) enddo みたいにループ制御の(整数)変数も引数に使わない方が安心。 あくまで「安心と安全」という気分の問題だけどね。コードが大きくなるとデバッグするときに こういう部分ががボディブローよろしく効いてくるので。老婆心。
299 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 18:09:15 ] 100×100くらいの大きな対称行列の逆行列を求める方法を探しています。 どのような方法が一番精度が良いでしょうか?お知恵をお貸し頂ければ幸いです。
300 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 20:46:45 ] >>299 対象の行列に因ると思う。実対称とか色々。 私は考えるのがメンドーなので lapack に丸投げしてるが。
301 名前:デフォルトの名無しさん mailto:sage [2008/05/10(土) 20:59:38 ] lapack 丸投げでいいと思う。 lapack は誤差減らす工夫してたと思うし。 対称行列なら対角化を経由する方法がいいかと。 数値誤差で対称性がくずれるなんてこともないし。 三角行列で扱うから。
302 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 22:23:14 ] やっぱ極力ライブラリ使うべきだよね 大抵のはあるし
303 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 01:02:12 ] Fortranでは何次元配列で何要素数あつかえるのでしょうか。 メモリとCPUによる? ちなみにFloatの4次元で、130559044000個(1ファイルで50GBのデータサイズ)を処理したい。
304 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 01:16:18 ] 確実にメモリには載らない。 1. 小出しに処理する 2. 圧縮する のどちらかになるな。
305 名前:299 mailto:sage [2008/05/12(月) 04:37:39 ] 300,301,302さん、レスどうもありがとうございます。 自分の素人っぷりが恥ずかしい限りなのですが 扱う行列が倍精度でもLAPACKで大丈夫でしょうか? 何はともあれ、試行錯誤してみます
306 名前:助けてください [2008/05/13(火) 13:59:50 ] 今FORTRANで「ガウスの消去法のプログラムを作れ」とのことなのですが、サブルーチンを 使ったプログラムが作れません。ALLOCATABLEを使ったプログラムなら作れたのですが、誰か ひとつ例として作って頂けませんか?お願いします。
307 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 16:29:56 ] >>306 宿題スレではないぞよ。
308 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 16:48:18 ] では宿題スレを紹介してください
309 名前:299 mailto:sage [2008/05/13(火) 19:27:04 ] >>305 DSYTRF、DSYTRIを使ったのですがうまくいきませんでした ...orz
310 名前:300 mailto:sage [2008/05/13(火) 19:47:51 ] >>309 DSYSV で B = 単位行列ってしたらダメ?やったコト無いけど(私は固有値問題しか解かないし)。 上手くいかないというなら何が可笑しいか。INFO の値は? 多くの場合、INFO=0 は正常終了の筈。 man を見る限り、DSYTRF は目的に合ってないように思うが、それはきっと私の気のせいだ。 ということで、もちっと何か晒せません?(差し障りの無い範囲で)
311 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 23:47:10 ] >>310 丁寧な指導ありがとうございます。 いま扱っている対称行列Aは倍精度で、次元が40×40です。 各要素の値には8桁ぐらいのバラつきがあります。 DSYSVでAX=EとなるようなXを求めて、その後実際に matmulでAXの積を計算して出力しているのですが 対角部分以外の値が全く0に近づきません。 infoは0で出てきてます。 WinXp、cygwin、g95でやってます。これがまずいのでしょか
312 名前:300 mailto:sage [2008/05/14(水) 00:21:48 ] >>311 dsysv() から出た後の A が最初の A のままという保証は無いような。その所為では? つまり dsysv() の中で A の中身が書き変わっている可能性がある。 だとしたら AX =E が成立しなくても可笑しくはない。
313 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 00:29:11 ] 説明不足ですみません。 DSYSVにはAをコピーしたA'を入力しています。 matmulには元のAを使っています。
314 名前:300 mailto:sage [2008/05/14(水) 00:41:25 ] B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) On entry, the N-by-NRHS right hand side matrix B. On exit, if INFO = 0, the N-by-NRHS solution matrix X. だから、実行前に A のコピーを取って(C とでもする)、実行後に B と C の積を見れば? やってみたら A の中身変わってた。あと (2,2) の実対称でやったら、ソレっぽい結果が出てた。 まぁアレだ、頑張れ。
315 名前:313 mailto:sage [2008/05/14(水) 02:03:19 ] >>300 アドバイスどうもありがとうございまs。 もすこし頑張ってみます
316 名前:名 無し [2008/05/14(水) 18:06:09 ] 質問があります。 linux上でFortran77を使えるようにするにはどうすればいいのですか? 何かインストールすべきコンパイラがあったりしたら教えて下さい。
317 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 00:00:21 ] >>316 大抵のディス鳥はg77が含まれているだろうから $ which g77 で見つからなかったら # yum install gcc-g77 とか # apt-get install gcc-g77 とか # yum install compat-gcc-34-g77 みたいな感じで。
318 名前:名 無し [2008/05/15(木) 15:47:37 ] >>316 $ which g77で見つかったんですけど開けませんでした・・・
319 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 17:24:18 ] >>318 which g77 で見つかったなら、Fortran77が使える準備が出来てるってことよん。 g77は開くものじゃない。
320 名前:デフォルトの名無しさん mailto:sage [2008/05/15(木) 21:15:39 ] fortranってブール型ないんですか?
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.」