現在Fortranを使いプログラムをしていますが、円の面積を計算するため変数を定義しているところでおかしな問題が出てきました。円周率を定義するところで自分でつけた変数名 PAI の値が入力データと違うことに気づきました。以下のように簡単なプログラムを作って試したのですが結果は同じくおかしな値が出てきました。
IMPLICIT REAL*8(A-Z)
PAI=3.14159265
WRITE(*,1)PAI
1 FORMAT(E30.22)
PAUSE
END
結果は
0.3141592741012573000000E+01
とディスプレイに表示され、このあとにPAIを使った計算があるならこの値で計算されます。私としては、PAI=3.14159265と出力し、計算もしたいのですが...
これは FORTRAN 自体の特有の性質なのでしょうか、それともソフト、ハード的な問題なのでしょうか?
尚、変数 PAI をファイルから読み込んだり、PAI=4.0*ATAN(1.0) (PAI=3.1415926535897930 となりますが)、PAI=3.14159265D+00などにすると正確に表示、計算出来ます。
No.1ベストアンサー
- 回答日時:
こんにちはuni050というものです。
実際に試してみてわかった事を一つ。
i686、g77でコンパイルを行って試したところ実際にこの様になりました。で、次にalpha(OSF1)、g77で試してみたところ同じようになりました。そこで今度は、alpha、f77で試してみたら
0.3141592650000000208621E+01
となりました。そのほかにもいろいろ試してみたことから得られた結論として、数字がおかしくなるのはコンパイラの方の問題かと。
あと、ためしに
double precision pai
pai = 3.14159265
でg77でやってみたらうまくいきませんでした。おそらく入力する数字が単精度になっているから下の方の桁がうまく入らないのではないかと。これは推測なのであまり当てになさらずに。
何かいろいろなコンパイラがあるみたいですね。
いろいろ調べてみた結果コンパイラにも「あまく」コンパイルするのもあるみたいですね。ありがとうございました。
No.6
- 回答日時:
IMPLICIT REAL*8(A-Z)
より.単精度の宣言の宣言をしていますので.有効桁は7.2桁になります。
3.14159265
より.7.2桁を超える数値を指定していますから.この値は倍精度です。定数ですから.コンパイラーは7.2桁に丸めた数値を変数PAIに設定します。
(E30.22)
より.E形式の出力を指定していますので.変数PAIの内容を単精度に換算して.その後に.30.22桁で表示します。
今のコンパイラーは型変換を自動でやってくれますから.このようなおかしな事になるのです(昔のコンパイラーでは型変換をせずメモリーから直接読み取るので.明らかに間違った答(0とか不の和とか)を出す)。簡単な方法としては
IMPLICIT REAL*8(A-Z)
を倍精度の宣言.たとえばダブルリアル(スペル忘却)宣言に直す方法があります。
いやー質問の最初に書いておくべきだったんですけど、どうしてこのような問題が起こったかというと、WARKSTATION (CPU:R10000,64bit)でコンパイル(Fortran は古い)して走らせるちゃんとPAI=3.1415926540000・・・と結果が出てくるんですよ。やっぱりbit数の関係ですかねー.(でもコンパイラは64bit対応か解らないんですけど。)
IMPLICIT REAL*8(A-Z)とIMPLICIT DOUBLE PRECISION(A-Z)は何か違うのですか?どちらも同じ意味と私は思っているんですけど。
どうもありがとうございました。
No.5
- 回答日時:
> これは FORTRAN 自体の特有の性質なのでしょうか、それともソフト、ハード的な問題なのでしょうか?
どれでもありません。数学の問題です。つまり、2進数と10進数の間で、小数点数の変換を行なうと(ほとんどの場合)わずかな誤差が出てしまうのです。これを完璧に防ぐ方法は(特殊な方法を使う以外)ありません。FORTRANなどの技術計算用言語では、極端に言うとこれをあきらめています。倍精度を使ってもそれ以上の精度を採用しても誤差が小さくなるだけで、ゼロには決してなりません。
特殊な方法というのは10進数で計算を行なうのです。汎用の大型計算機では10進計算のハード(命令語)をもっていますし、商業計算が得意なCOBOL言語では、ハードがなくてもソフトで10進計算をやっています。
質問の答えにはならないかも知れませんが、(歯がゆい事ながら)技術計算では、色々工夫しながらFORTRANやCを使っていくしかないと思います。
確かに数学の話ですね。右辺を単精度で定義していたならこうなりますね。
10進数計算の話ですが最近は(昔からあるのかな?)BASIC にも2進数、10進数どちらでけいさんするのかを選ぶのもあるみたいですね。
どうもありがとうございました。
No.4
- 回答日時:
No.3 の回答に補足。
コンパイルオプションで、定数を倍精度で扱うコンパイラもある(→参考URL)ので、
そっちの方も気にして見てください。
参考URL:http://www.compaq.co.jp/products/dvf/docs/vf-htm …
No.3
- 回答日時:
> PAI=3.14159265
の右辺が *単精度* の表現であるから、なのだと思います。
コンパイラによっていろいろな表現があるのだと思いますが、例えば、参考URLに
よれば、
> 倍精度(8バイト)の実数定数は,定数値_8 で与える。
とありますので、
PAI=3.14159265_8
とすると、お望みの結果になりそうです。
まずは、お手持ちのコンパイラのマニュアルでデータ型とか定数とかの項を
読むことをお勧めします。
参考URL:http://www.media.kyoto-u.ac.jp/htomita/sec4.html …
あまりマニュアルを信用していない私ですが、のぞいてみたところ確かにそのように書いてありました。(倍精度型実数にはDをつけると)
どうもありがとうございました。
No.2
- 回答日時:
PAI=3.14159265 の部分ですが左辺は倍精度実数、右辺は単精度実数(REAL*4)
です。
単精度実数の場合10進数にした場合有効桁数が6桁強程度しかありません。
倍精度実数は有効桁数が10進数で13桁程度ありますので代入した場合、単精
度実数で表せない部分にごみがはいります。
これを避ける為には右辺も倍精度実数にする必要があり、それが後編で試された
内容です。
FORTRANに限りませんが(C言語も同じです)、代入時の型に注意しないとこの
ような事がよくおこり原因不明の精度低下ということがあります。
なれると大丈夫なのですけどね。がんばって下さい。
本当に変数の定義のときには注意が必要ですね。
今までの私のプログラムは倍精度実数にすることなく定義しているので、これから一時はそれを直すのに時間がかかりそうです。(大変だーー)
どうもありがとうございます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
O(n log n)について2
-
”/”を使わずに割り算したいんで...
-
100桁の計算ができなくて困って...
-
PICマイコンのアセンブラについて
-
C18(PIC18)でのシフト演算など
-
BCD・HEX・BINについて
-
2の補数について
-
c languageで 簡単な質問があ...
-
2÷3などの余りについて
-
信頼区間の1.96や1.65ってどこ...
-
std::set<int> で、ある値が何...
-
「Aに対するBの割合」と「Aに対...
-
ウィンドウハンドルがメッセー...
-
プログラムでの数字につく”f”の...
-
ある商品のロス率を5%見込み、...
-
10進数からN進数に変換するプロ...
-
ループを途中で抜けたいのですが。
-
C#のコンパイルエラーCS0120に...
-
float型とdouble型の変数の違い...
-
数学のテストからの質問(反比例)
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
O(n log n)について2
-
VB.net Double と...
-
c languageで 簡単な質問があ...
-
ExcelのINT関数の計算結果がお...
-
有効数字について 以前質問をし...
-
ExcelでPC(パソコン)によって...
-
三菱シーケンサ(Aシリーズ)で...
-
除算を使わずに10で割りたい。
-
16進数 加算 減算 C言語
-
EXCELの関数"STDEV(標準偏差)"...
-
VB6.0での小数点の扱いについて
-
”/”を使わずに割り算したいんで...
-
距離から緯度経度を求める方法
-
VBAでミリ秒まで出力する方法
-
floatの有効桁数
-
コンピューターは指数関数をど...
-
時刻の比較
-
計算の丸め誤差の解消について
-
Double型について
-
powf を使わずにべき乗を計算
おすすめ情報