Fortranの倍精度実数について

このQ&Aのポイント
  • Fortran 90での整数の倍精度実数への型変換について疑問があります。
  • プログラムAとプログラムBのどちらがより速く、より精度よく計算できるのか知りたいです。
  • 回答をお願いします。
回答を見る
  • ベストアンサー

Fortranの倍精度実数について

こんにちは。 現在、Fortran 90でプログラムを作成しています。 その中で、整数の倍精度実数への型変換についての疑問がわきましたので、質問させていただきます。 以下の2つのプログラムで、計算がより速く、より精度よくできるのはAとBどちらなのでしょうか。 実際は下記のプログラムが、ループの中に入っているので少しでも計算時間を短くしたいのです。 よろしくお願いいたします。 program A(毎回dxを足す) ----------------------------- real(8) :: pi, dx real(8), dimension(1000) :: x integer i, j pi=atan(1d0)*4d0 dx=pi/5000d0 x=0d0 j=1 do i=1, 1000 x(i)=x(j)+dx j=i write(*,*)x(i) end do ----------------------------- program B(毎回dx*ループ回数を計算する) ----------------------------- real(8) :: pi, dx real(8), dimension(1000) :: x integer i, j pi=atan(1d0)*4d0 dx=pi/5000d0 x=0d0 do i=1, 1000 x(i)=dx*dble(i) write(*,*)x(i) end do -----------------------------

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

速度は難しいけど A の方が速そう. 精度は B の方が上. dx が固定値なら B を選ぶね.

irisiya2
質問者

お礼

お礼が遅くなって申し訳ありません。 ありがとうございました。 助かりました。 結局精度を重視してBを選択しました。

関連するQ&A

  • FORTRAN subroutineと配列と繰り返し

     以下のように二次元配列の場合でsubroutineを使うときに、主プログラムで2重Doループ(iとj)で繰り返しをしているのですが、すでにsubroutineでDoループ(i)を用いて計算しています。これではsubroutineの利点をうまく使えていないと思うのですが、subroutineを使って配列、Doループをきれいにする方法をどなたか教えていただけませんか。  実際は4重ループ、4次元配列なので、プログラムをわかりやすくするためにサブルーチンを使いたいと思っています。 -------------------------------------------------------------- program S real,dimension(5,5) :: B real,dimension(5) :: A integer :: i,j do j=1,5 CALL sub1(A) do i=1,3 B(i,j)=A(i)*j write(*,*) B(i,j) end do end do end program S subroutine sub1(A) real,dimension(5) :: A integer :: i do i=1,3 A(i)=3.*i end do end subroutine sub1

  • fortran モンテカルロ法

    モンテカルロ法により円周率πを計算するプログラムを作ったのですが、以下のプログラムでモンテカルロ法から推定された円周率piの値が実行すると大きな数字になってしまって、うまく計算できてない見たです。式に問題があるのでしょうか?教えて下さい。 rogram list1_9 implicit none real(8) x, y, pi, pi0 integer :: n, i, im = 2**20 pi0 = 2.0d0*acos(0.0d0) n = 0 do i = i, im call random_number(x) call random_number(y) if(x ** 2 + y ** 2 <= 1.0d0) n = n + 1 enddo pi = 4.0d0*dble(n)/dble(im) write(*,*) ' pi, pi0, er = ', pi, pi0, pi-pi0 end program list1_9

  • fortran 行列ベクトル積

    行列ベクトル積を計算するプログラムを下のように書いたのですが、実行した結果の答えが実際計算した答えと異なります。初期の要素の設定がおかしいのでしょうか?教えて下さい。よろしくお願いします。 program list2_14 implicit none integer , parameter :: n = 2 real(8) a(n,n), x(n), y(n) integer i, j, k, l a(1,1:2) = (/1.2d0,3.4d0/) a(2,1:2) = (/5.6d0,7.8d0/) x(:) = (/9.0d0,10.0d0/) do i = 1, n y(i) = 0.0d0 do j = 1, n y(i) = y(i) + a(i,j) * x(j) enddo enddo do k = 1, n write(*,*) (a(k,l), l = 1, n) enddo write(*,*) x(:) write(*,*) y(n) end program list2_14 実行結果 1.2 3.4 5.6 7.8 9. 10. 128.4

  • FortranをCに書き直すにはどうしたらいいでしょうか?

    Foratranで書かれている下記のコードをCのコードに置き換えたいのですが、分かりません。 お願いします=(^v^)= C *---------------------------------------------------------* C サブルーチンWGEN C *---------------------------------------------------------* SUBROUTINE WGEN(EM,R,NN,IR,ACC,ND,DT,AMAX,VMAX,MXCYCL,ERR,UW1, * UW2) C implicit real*8(a-h,o-z) COMPLEX*16 C(4096) DIMENSION ACC(ND),UW1(ND),UW2(ND) DIMENSION E(33),X(33),EE(33) DIMENSION PDIF(2046),PHI(2049),F(2049),T(2049),SV(2049),H(1), * RES(2049,1),RR(2049) PARAMETER (PI2=6.283185) DATA DX/0.03125/,H0/0./,H/0.05/ C C DO 150 K=1,NN2-2 P=RAND2(IR) C DO 130 J=2,33 IF(P.LE.EE(J)) GO TO 140 C 130 CONTINUE C 140 PDIF(K)=-(X(J-1)+(P-EE(J-1))/(EE(J)-EE(J-1))*DX)*PI2 C 150 CONTINUE C C *---------------------------------------------------------* C ファンクションRAND01 C *---------------------------------------------------------* REAL*8 FUNCTION RAND2(I) C INTEGER*4 L,C,T30 REAL MU PARAMETER(L=843314861,C=453816693,T30=2**30,MU=2.0**31) C I=L*I+C IF(I.LT.0) I=(I+T30)+T30 RAND2=REAL(I)/MU END C

  • 質問(Fortran)について

    おはようございます。 下記のFortranでここから~ここまでと---で囲んでいる 部分の意味が分かりません。 乱数Pを発生させてPがEE以下になったら、140へ行けとあるのですが。。 それと(1)の部分をCに書き換えるとどうなるか、知っている方教えてください。 よろしくお願いいたします。 C *---------------------------------------------------------* C サブルーチンWGEN C *---------------------------------------------------------* SUBROUTINE WGEN(EM,R,NN,IR,ACC,ND,DT,AMAX,VMAX,MXCYCL,ERR,UW1, * UW2) C implicit real*8(a-h,o-z) COMPLEX*16 C(4096) DIMENSION ACC(ND),UW1(ND),UW2(ND) DIMENSION E(33),X(33),EE(33) DIMENSION PDIF(2046),PHI(2049),F(2049),T(2049),SV(2049),H(1), * RES(2049,1),RR(2049) PARAMETER (PI2=6.283185) DATA DX/0.03125/,H0/0./,H/0.05/,IR/101/ C C ------------------- ここから ------------------- DO 150 K=1,NN2-2 P=RAND2(IR) ← (1) C DO 130 J=2,33 IF(P.LE.EE(J)) GO TO 140 C 130 CONTINUE C 140 PDIF(K)=-(X(J-1)+(P-EE(J-1))/(EE(J)-EE(J-1))*DX)*PI2 C 150 CONTINUE C ------------------- ここまで ------------------- C *---------------------------------------------------------* C ファンクションRAND01 C *---------------------------------------------------------* REAL*8 FUNCTION RAND2(I) C INTEGER*4 L,C,T30 REAL MU PARAMETER(L=843314861,C=453816693,T30=2**30,MU=2.0**31) C I=L*I+C IF(I.LT.0) I=(I+T30)+T30 RAND2=REAL(I)/MU END C

  • 【fortran】フーリエ級数について

    こんばんは。 早速ですが、質問させて頂きます。 学校の課題で一次元熱伝導方程式のプログラムを組みなさいという課題が出たのですが、入力、出力のプログラムが上手く書けずに困っています。 自分で何回もやってみたのですが、「ループがベクトル化されました」としか出ず、どこが間違っているのかも分からない状況です。 詳しい方、教えて頂ければ幸いです。 下に自分が作成したプログラムを載せておきます。 program heat implicit none integer i, n, nmax real(8) t0, t1, d, time, a, h, p, q, an0, kn, bn, en integer, parameter :: id = 100 real(8), parameter :: pi = 3.1415926535d0 real(8), parameter :: lambda = 2.5d-6, rho = 2500.d0, c = 2.35d-7 real(8), parameter :: expmax = 50.d0 real(8) x(0:id), t(0:id) ! ! Data input part (t0,t1,d,a,time,nmax) ! t0=300.0d0 ! degrees t1=200.0d0 ! degrees d =100.0d0 ! m time=1.0 ! year time = time *365.0d0*24.0d0 ! year --> hour nmax=1000 a = 1.0d6 ! Area of rock surface [m^2] h=d/id do i=0,id x(i)=i*h t(i)=t1 end do p=0.0d0 q=0.0d0 do n=1,nmax,2 an0=4.0d0/(n*pi)*(t0-t1) kn=n*pi/d bn=lambda*kn*kn/(rho*c) if(bn*time.le.expmax) then en=exp(-bn*time) else en=0.0d0 endif do i=0,id t(i)=t(1)+an0*sin(kn*x(i))*en enddo p=p+an0*kn*en q=q+an0*kn/bn*(1.0d0-en) enddo p=lambda*a*p q=lambda*a*q open(20,file=‘output.dat’) write(20,*) ‘x(i),t(i),p,q' = ‘, ‘x(i),t(i),p,q' close(20) stop end program heat

  • FORTRAN 初心者です

    以下の連立一次方程式をSOR法で解く問題です。 初心者なりにガウスザイデル法を応用してプログラムしたつもりですが、やはり難しいです(答えは違います)。 どこをどうすれば良いのか分かりませんので、よろしければヒントや助言をいただきたいです。 PROGRAM SOR REAL A(10,10),B(10),X(10),X0(10) INTEGER N,I,J,K,Kmax,w N=3 A(1,1)=4 ;A(1,2)=1 ;A(1,3)=2 A(2,1)=1 ;A(2,2)=3 ;A(2,3)=1 A(3,1)=1 ;A(3,2)=2 ;A(3,3)=5 B(1)=16 B(2)=10 B(3)=12 X0(1)=1 ;X0(2)=1 ;X0(3)=2 w=1.2 Kmax=50 EPS=1.D-5 DO I=1,N D=A(I,I) S=B(I) B(I)=B(I)/D END DO DO K=1,Kmax DO I=1,N DO J=1,N if(J<I) X0(J)=X(J) S=S-A(I,J)*X0(J) END DO X(I)=(1-w)*X(I)+w*S END DO DO I=1,N S=S-(X(I)-X0(I))**2 END DO IF(S<EPS) GOTO 10 DO I=1,N X0(I)=X(I) END DO END DO 10 WRITE(*,*) K DO I=1,N WRITE(*,*) 'SOR法で求めた解は' WRITE(*,*) 'X(',I,')=',X(I) END DO END PROGRAM SOR !------------------------------------ ※wは緩和係数です

  • Fortranの問題3問目です。急いでます><

    以下のプログラムを実行すると結果がNAN(数値エラー)となり、表示されない。 これは、ガウスの消去法における、ある問題に起因する。 正しい結果がでるようにするには、どうしたらよいか? 答えが正しく表示されない原因を究明し、正しい結果を表示する、 修正済みソースコードを提出しなさい。 ヒント: 一般に、どのような行列でも計算できるプログラムにするためには、 「ピボット」と呼ばれる操作を行う必要があるが、 今回は、ピボットをあらかじめ人間が行うことで回避してよい. プログラムの処理内容(アルゴリズム)を修正する必要はない。 program gauss implicit none c aは係数行列(4x3)、xは解、w は一時変数 double precision a(5,4),x(4),w integer i,j,k c キーボードから読み込む場合 write(6,*) 'input a(5,4)' c read(5,*) a c data文で一括初期化(代入)する方法 data a / & 0d0, 3d0, 7d0, 2d0, 65d0, & 2d0, 8d0, 5d0, 1d0, 65.4d0, & 5d0, 3d0,-5d0, 2d0, 3.8d0, & -2d0, 4d0, 0d0, -6d0, -35.6d0 & / write(6,*) 'データの確認表示' write(6,'(f8.2,f8.2,f8.2,f8.2,f8.2)') a c 前進消去 do k=1,3 do j=k+1,4 w = -a(k,j)/a(k,k) write(6,*) w,'*行',k,'を、行',j,'に足すと' do i=1,5 a(i,j) = a(i,j) + w*a(i,k) end do write(6,'(f8.2,f8.2,f8.2,f8.2,f8.2)') a write(6,*) '' end do end do write(6,*) '前進消去 終了' write(6,'(f8.2,f8.2,f8.2,f8.2,f8.2)') a c 後退代入 do k=4,1,-1 x(k) = a(5,k) do i=k+1,4 c 注:k=3のとき, do i=4,3 となるためループ内は1回も実行しない c k=2のとき, do i=3,3 となり、ループ内はi=3 で1回だけ実行 x(k) = x(k) - a(i,k)*x(i) end do x(k) = x(k) / a(k,k) end do c 解を表示 write(6,*) 'x = ',x stop end

  • FORTRANの質問

    FORTRANのプログラムについての質問です。 プログラム中に以下の文がありました。 PI=8*ATAN(1.DO) 1.DOの意味がわからずに困っています。 もしご存知の方がいましたら教えていただけないでしょうか? よろしくお願いいたします。

  • fortran errorについて

    fortranを勉強していたのですがエラーがでてしまい、何時間かけても理解できなかったので質問させてください。 以下プログラム program test !ここからメインルーチン !前準備 配列の用意 implicit none integer N integer,dimension(0:N,0:N) :: A integer :: i,j,k read * ,N !初期状態の代入 do i=0,N do j=0,N A(i,j)=0 end do end do do i=N/2,N-1 A(N/2,i)=1 end do do i=N/2,N-1 A(N/2+1,i)=-1 end do !ループ 50回ループさせる do k=0,50 !状態の表示 call visualize !サブルーチン visualize subroutine visualize do i=0,N do j=0,N if(A(i,j)== 1) write(*,'(A1)',advance='NO') "*" if(A(i,j)== 0) write(*,'(A1)',advance='NO') " " if(A(i,j)==-1) write(*,'(A1)',advance='NO') "+" end do write(*,*) end do !end subroutine visualize call insert !サブルーチン insert subroutine insert do i=0,N do j=0,N if(A(i,j)== 1) A(i,j)=-1 if(A(i,j)== 0) A(i,j)=max(0,A(i-1,j),A(i,j-1),A(i,j+1),A(i+1,j)) if(A(i,j)==-1) A(i,j)=0 end do end do !end subroutine insert end do end program test これでコンパイラすると In file test.f90:48 subroutine visualize 1 Error: Unclassifiable statement at (1) In file test.f90:69 subroutine insert 1 Error: Unclassifiable statement at (1) とでます いろいろ調べたのですが全くわかりませんでした できればよろしくお願いします

専門家に質問してみよう