質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
FORTRAN

FORTRAN(フォートラン)は科学時術計算に向いた手続き型プログラミング言語です。 並列計算の最適化が行いやすい特性上、数値予報および気候モデルなどの大規模な計算を行う分野のスーパーコンピュータで使われています。

Q&A

解決済

1回答

1369閲覧

FORTRANの型変換で値が変わる

退会済みユーザー

退会済みユーザー

総合スコア0

FORTRAN

FORTRAN(フォートラン)は科学時術計算に向いた手続き型プログラミング言語です。 並列計算の最適化が行いやすい特性上、数値予報および気候モデルなどの大規模な計算を行う分野のスーパーコンピュータで使われています。

0グッド

0クリップ

投稿2018/09/11 13:14

編集2018/09/11 15:54

FORTRANで
REAL(8) の変数に REAL(4)の変数の値を代入して値が変わらないようにすることが可能なのかをご教示頂きたいです。

REAL(8)はVsualStudioのウォッチで見てみた時の型で、宣言はdouble precisionです。

REAL(4)もウォッチで見た際のもので、
宣言はDIMENSIONです。

発生している問題・エラーメッセージ

小数点で誤差が出ます。

変数A:REAL(8) = 変数B:REAL(4)

↑この時点で7.9901などの値が7.89908のように変わってしまう。

変数A:REAL(8) = 変数A:REAL(8) / 変数C:REAL(4)

該当のソースコード

現在正確なものが提示出来ないので、
後ほど記載します。
上記のものと大きくは変わりません。

補足

DIMENSIONの宣言を合わせる事も検討しましたが、多数その宣言があり影響が大きいと考えそれ以外の方法があるか探しています。

ググってみてメモリの問題というものも出てきましたが、4byteから8byteへの代入なので先頭アドレスの問題ではないと思っているのですが・・・、勉強不足で確信が持てていない状態です。(帰宅したら参考サイトを追記します)

Fortrunも初めて触れるレベルで、ネットのドキュメントも少なく、自身の力不足も重なって行き詰まってしまいました。
何か情報の不足や至らない点があれば御指摘頂けますと幸いです。

よろしくお願い致します。

参考サイト
先頭メモリアドレスについての参考サイト
型についての参考サイト

【追記(1)】
こちらのサイトを参考に、
小数点部分に誤差が出る可能性があることはなんとなくイメージできたのですが

代入時に桁数が違うもの(メモリのbyte数が違うもの)に変換しているため、変換前の値と異なることははあり得る。

という理解であっているでしょうか・・・?
ですが4byteから8byteと領域が増えていてもそれは起きるもの・・?

【追記(2)】
原因として、
倍精度実数から単精度実数への代入を行っているので丸め誤差が発生している。

解決方法として、以下のものがある。
・有効桁数を増やす。(両方Doubleにする。= 型を合わせる。)
・直接計算を行って精度の高い計算を行った後、REAL(4)に丸める or 有効桁数で切り捨てる。

しかし今回のケースで、許容可能な誤差範囲が小数点7桁の丸めを許容しないので以上の二つは有効な手段にならない。

参考にしたサイト1
参考にしたサイト2

なので、

FORTRANで
REAL(8) の変数に REAL(4)の変数の値を代入して値が変わらないようにすることが可能なのかをご教示頂きたいです。

の内容は現在の演算方法では有効桁数を超える限り実現できない。

ご回答いただいた内容の通りでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/09/11 14:39

ご指摘ありがとうございます、綴りが違っていましたね。 正しくはFORTRANでした。
guest

回答1

0

ベストアンサー

10進数表現にしたときに、末尾に差異が出ることはあるでしょうけど、1%以上の差が出ることはあり得ないので、プログラムバグでしょう。

投稿2018/09/11 13:27

otn

総合スコア84505

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/09/11 14:00

ご回答ありがとうございます。 1%未満なら有り得るということは例えば 0.123456 → 0.12555 といったことは有り得るということでしょうか? 浮動小数点?などが関係してますか?
otn

2018/09/11 16:07

> 1%未満なら有り得る 違います。質問の例で1%以上の差がでてるので、それはあり得ないと言うだけです。 2進単精度→10進数表記 2進単精度→2進倍精度→10進数表記 で必ず同じ10進数表記になるとは限らないということです。 浮動小数点について勉強するか、深く考えないか、どちらかにしましょう。 > 0.123456 → 0.12555 といったことは有り得るということでしょうか? これもあり得ないでしょう。
退会済みユーザー

退会済みユーザー

2018/09/13 14:35

ご返信ありがとうございます。 >2進単精度→10進数表記 >2進単精度→2進倍精度→10進数表記 型変換で発生する誤差ということなのですね。(あってますかね…?) 演算部分とごちゃまぜになっていました…。 Dim sng As Single = 1.23456789 Dim dbl As Double = 1.23456789 Dim convDbl As Double = CDbl(sng) Console.WriteLine("sng={0}", sng) Console.WriteLine("dbl={0}", dbl) Console.WriteLine("convDbl={0}", convDbl) ''sng=1.234568 ''dbl=1.23456789 ''convDbl=1.23456788063049 誤差が発生した値で演算して10進数表記、もしくは演算後の10進数表記で微妙な誤差が発生した為に プログラムごとの型の違いによる結果の違いが出てきた。と考えました。 (それはそれでバグではありますが…。) 参考サイト↓ http://math-koshimizu.hatenablog.jp/entry/2016/12/04/224208 現状テキストとして読めているだけなので、二進数の部分まで噛み砕けるまで浮動小数点について勉強してみます。 振り返ってみると後だしの情報もあり、ご迷惑をかけてしまいました。気を付けます。 重ねてお礼申し上げます、ありがとうございました。
otn

2018/09/13 16:40

Cとかでプログラムを書けば、sng と convDbl のそれぞれの内部表現が16進数とか2進数とかで表示できるので、convDblの仮数部は、sngの仮数部の後ろに0を並べただけというのが分かると思います。 普通に桁数おまかせでsngを10進数に直すと、単精度の有効桁数は7桁強なので、8桁目を四捨五入して表示されると思います。倍精度だと、16桁目を四捨五入ですね。 倍精度数値も10進変換して8桁目を四捨五入すれば、元の単精度数値を10進変換して8桁目を四捨五入したものと同じになると思います。 また、1.23456789のような、2進数で無限小数になる値じゃなくて、24bit以内の2進数で正確に表現できる値を使えば、10進→2進→10進 で誤差は出ないはずです。10進→単精度→倍精度→10進でもです。 あまり10進桁数が長いと処理系が面倒見てくれなくなるかも知れないですが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問