• 締切済み

VisualBasic と Fortran の計算結果の相違

以下のような技術的な計算式があります。 C=8.9×107[7:べき数]×S/(X-Xa)2[2:べき数]×exp(-35.1×(Y-Ya)2[2:べき数]/(X-Xa)2[2:べき数]))- 221.1×H2[2:べき数] /(X-Xa)2 [2:べき数] 使用変数などの値の大まかな範囲   C : 求める変数   X,Y,Xa,Ya:0~20000 S:0~500   H:10~200 この式をVISUAL BASIC FOR EXCELとFORTRANでそれぞれ単精度計算した場合では,結果が小数点第3位ぐらいで相違があるのですが,当方のプログラムミスか言語が違うことによることなのか,どなたか教えてください。結構困っています。  よろしくお願いします。

みんなの回答

  • nag0720
  • ベストアンサー率58% (1093/1860)
回答No.2

#1で述べたのはあくまで一般論です。 実際にどのくらいの誤差がでるかはやってみないと分かりません。 >exp(X)の計算では,Xの値が同じであれば,VisualBasicとFortranは同じ結果になるのでしょうか。 有効桁数までは同じだとは思いますが、その先はどうなるか分かりません。(違うかもしれないし、同じかもしれない) プログラムはマシン語に翻訳されて実行されます。 マシン語の計算は加減乗除しかありませんからexp(X)のような関数は、コンパイラによって加減乗除だけの式に変換されます。どのような式に変換されるかはコンパイラによって違いますから、計算結果が同じになるとは期待しないほうがいいでしょう。

magurored
質問者

お礼

大変参考になり,頭の中が整理できました。 お忙しい中,ご回答ありがとうございました。

  • nag0720
  • ベストアンサー率58% (1093/1860)
回答No.1

結果が小数点第3位ぐらいで相違とありますが、同じ数字の桁数はどのくらいなのでしょうか? 単精度の有効桁数は6~7桁です。 この有効桁数は加減乗除などの計算を繰り返すことによってだんだんと少なくなっていきます。 また、計算式によっては、この有効桁数が大幅に減少する場合があります。例えば、 1000012312 - 1000012105 = 207 この計算結果の207は精度的には全く意味を持ちません。 VisualBasicとFortranで全く同じ計算をしたとしても、それぞれのコンパイラは独自に計算式を最適化をしていますから、有効桁数以降の桁については微妙に違ってきます。 その誤差は計算を繰り返すことによってさらに広がっていきますから、最終結果にどのくらいの誤差が出るは常に考えておく必要があります。 (誤算論という分野があるくらい難しい問題です) 技術計算などで複雑な計算をする場合は、少なくとも単精度ではなく倍精度を使うべきだと思います。

magurored
質問者

お礼

ご回答ありがとうございました。 例えば,(Y-Ya)2[2:べき数]で,YとYaとの値の関係から,0~15000の範囲で変化します。  exp(X)の計算では,Xの値が同じであれば,VisualBasicとFortranは同じ結果になるのでしょうか。  出来ましたらご教授お願いします。

関連するQ&A

  • Fortranで不連続な関数を計算するとき

    Fortranで、y=exp(-x) (x≧0)、y=-exp(x) (x<0)を計算して、結果をグラフにするソフトで出力したとき、グラフはどのようになるのでしょうか? 不連続な場合、無理やり?連続にするようなことを聞いたのですが・・・

  • fortranのプログラム

    fortranのプログラム 現在、fortranの勉強をしております。 そこで、質問があるのですが、 ある関数f(x,y,z)の座標(x,y,z)の値がデータとして与えられているとき、 S=10+f をfortranで計算したいと考えております。 ただ、関数fは複数(f1、f2、f3)あり、次々とfに代入してSを計算したいのですが、どのようにプログラムしたらいいか思いつきません。 どなたか、ヒントだけでもいいので、教えてください。 ちなみに、私が考えたプログラムは(下のプログラムはポイントだけ書いてあります。endやその他関係ないと思われるところは省いております。) do 100 k=1,3 S=S+fk(x,y,z) continue function f1 f1(s,t,u)=・・・ return end f2(s,t,u)=・・・ return end 使用しているバージョンは、fortran77(本当は90を使っているのですが、77だけで書いています)です。

  • 直角座標系の回転の計算方法

    下の計算は直角座標系の回転の計算(∇×A)の一部です。 i_x(∂/∂x) × (i_yA_y) i_x × ((∂i_y/∂x)Ay + i_y(∂A_y/∂x)) =i_z(∂A_y/∂x) という風に計算したのですが、 この計算手順はあっていますでしょうか? 答えはあっていると想うので、計算手順があっているかどうか知りたいのですが・・。 i_x、i_y、i_zは単位ベクトルです。 ベクトルA = i_xA_x + i_yA_y + i_zA_zで表されます。

  • Fortranでの記号「./」について

    Fortran 90で書かれた数値計算プログラムを、より専門的な言語に書き換える作業を行っています。 Fortranを学んだことがないのでインターネット等で関数の意味や書式を調べながら作業しているのですが、 「X./Y」という式の意味がわからずに困っています。 単純に「X/Y」とはどう違うのでしょうか。 初歩的な質問で申し訳ありませんが、よろしくお願いします。

  • FORTRANのプログラムについて

    program dat real x(100), y(100) s2=0 read(*,*) m,h open(7,file='test2.txt') do i=1,m read(7,*,end=200) x(i),y(i) s1=h/2*(y(1)+y(m)) s2=s2+h*(y(i)) s3=h*y(1) end do 200 close(7) sum=s1+s2-s3 write(*,*) 'sum=',sum end 台形公式を求めるプログラムを書いています。 テキスト形式でまずデータを取り込みます。 刻み幅はhです。ただしデータ数は未知数です。 上のようにプログラムを書いたのですが、うまく働きません。どうすればよろしいでしょうか? ご教授お願いします

  • FORTRAN→Cに翻訳

     どなたか、次のFORTRANのプログラムを、Cに、翻訳して頂けないでしょうか。C++ではなく、Cです。ANSI準拠のCでお願いします。  プログラムの内容は、最小二乗法による計算プログラムです。MS-DOS Ver3.3~6.0の頃の、MS FORTRANコンパイラ仕様のものです。その頃持っていたFORTRANの本も処分してしまい、今からFORTRANを学びなおすのにも多大な労力と時間がかかりそうなので、Cに翻訳して頂ければ大変ありがたいです。よろしくお願いします。 (“□”はタブ) ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆ C□LEAST SQUARE APPROXIMATION □PROGRAM MAIN9 □DIMENSION X(100),Y(100),S(0:18),T(0:9),SM(10,10),TV(10),AV(10) □WRITE(*,*) 'N ?' □READ(*,*) N □WRITE(*,*) 'x1,x2,..,xn ?' □READ(*,*) ( X(I),I=1,N ) □WRITE(*,*) 'y1,y2,..,yn ?' □READ(*,*) ( Y(I),I=1,N ) □WRITE(*,*) 'M ?' □READ(*,*) M □DO 110 K=0,M*2 □□VS=0. □□DO 100 I=1,N □100□VS=VS+X(I)**K □□S(K)=VS □110□CONTINUE □□DO 130 K=0,M □□□VS=0. □□□DO 120 I=1,N □120□VS=VS+Y(I)*X(I)**K □□□T(K)=VS □130 CONTINUE □□DO 140 I=1,M+1 □□□DO 140 J=1,M+1 □□□□K=I+J-2 □□□□SM(I,J)=S(K) □140 CONTINUE □□DO 150 I=1,M+1 □150 TV(I)=T(I-1) □□CALL SIMULE( AV, SM, TV, M+1 ) □□DO 160 I=1,M+1 □160 WRITE(*,1000) I-1,AV(I) □1000 FORMAT(1H ,'A',I1,'=',F10.5) □□STOP □□END ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆

  • 任意定数を消去して微分方程式を作る途中計算が不明

    y=a*exp(x)+bx*exp(-x) の a と b を消去して x と y の微分方程式が作れません 未知数が2個あるので2階微分まで計算して、a について計算して、b について計算して y(x) の式に代入して計算する方法は分かっています。 解答には y"-2y'+y=0 と書いてありますが、実際に計算しても解答と一致しません y'=a*exp(x)+b(1-x)*exp(-x) y"=a*exp(x)+b(x-2)*exp(-x) y'-y"=b(3-2x)*exp(-x) b=(y'-y")*exp(x)/(3-2x) (x-2)y'-(1-x)y"=(2x-3)a*exp(x) a=(x-2)y'-(1-x)y"/((2x-3)*exp(x)) この後 aとbを y(x) に代入しても解答と一致しません。計算間違いしていると 思いますが、分かる人は教えてください。

  • Fortranで出力したファイルの内容を並べ替えたいです

    いま、Fortranをつかって統計物理の解析を行っています。計算結果は --- 時刻T1 AのX座標 AのY座標 AのZ座標 BのX座標 ・・・ 時刻T2 AのX座標 AのY座標 AのZ座標 BのX座標 ・・・ ・ ・ ・ --- という具合に出力されるのですが、この形式では都合が悪いことがあって --- A T1 X Y Z T2 X Y Z ・ ・ ・ B T1 X Y Z T2 X Y Z ・ ・ ・ C --- と言う感じに出力したいのですが、それぞれの物体が独立して運動するわけではないので、どうしても上の形式で一度出力してからほしい形式に変換しなればなりません。私はFortranしか使ったことがないのでできればFortranで並び替えを行いたいのですが、このようなことがFortranでできますか?また、Fortranでこのような並び替えをするにはどうすれば良いのでしょうか。御教授よろしくお願いします。

  • ベクトルの積分『∫(A→B)Fdr』の計算の仕方を教えてください。

    皆様、こんにちは。 ベクトル積分『∫(A→B)Fdr』の計算の仕方を教えて頂きたいのですが。 A、Bは空間の座標でそれぞれ(Xa、Ya、Za)、(Xb、Yb、Zc)。 F、rも3次元のベクトルで、 rは空間の位置のベクトルです。 Fの例として Fx(Fのx座標)=Cx/(x^2+y^2+z^2)^(3/2) Fy(Fのy座標)=Cy/(x^2+y^2+z^2)^(3/2) Fz(Fのz座標)=Cz/(x^2+y^2+z^2)^(3/2) (Cはただの定数です。) で教えて頂けるとありがたいです。 (この例だと答えが分かっていますので。) 多分この例の答えは ーC/(Xa^2+Ya^2+Za^2)^(1/2)+C/(Xb^2+Yb^2+Zb^2)^(1/2)です。 少し数値が複雑そうですが、物理の保存力の基本問題です。 ベクトルの積分の計算方法をご存知の方やり方を教えて頂けないでしょうか。よろしくお願いします。(2次元の時は何となく分かった気になっていたのですが、3次元になって全く分からなくなってしまいました。)

  • C++ファイルからデータ入力して計算、ファイル出力

    C++初心者です。 ファイルの数値データを入力して、それらを計算してからファイルに出力する方法がわかりません。 たとえば、 入力ファイル   出力ファイル 行数  x y z (1)  1 1 6   y(1)*exp(z(1)-x(1))+y(2)*exp(z(2)-x(1))+... (2)  3 5 2   y(1)*exp(z(1)-x(2))+y(2)*exp(z(2)-x(2))+... (3)  5 6 9  y(1)*exp(z(1)-x(3))+y(2)*exp(z(2)-x(3))+... (4)  9 1 3   y(1)*exp(z(1)-x(4))+y(2)*exp(z(2)-x(4))+… (5)  1 7 8   y(1)*exp(z(1)-x(5))+y(2)*exp(z(2)-x(5))+... 入力したデータを上記のように計算してから出力ファイルにしたいのですが、複雑なのでプログラムをどう組み立てれば良いのかわかりません。 ちょっとしたことでも結構です、参考になりそうなサイトや、ロジック、プログラムに関するアドバイスいただけませんか。