プロが教える店舗&オフィスのセキュリティ対策術

プログラム(C++)について質問があります.
浮動小数演算を用いると,実行環境の変化に応じて結果が変わってしまうのでしょうか?

プログラム中ではdouble演算を頻繁に用いています.
(ソースコードは膨大すぎるため,申し訳ありませんが載せることが出来ません.)

小数演算をするために何気なくdouble(もしくはfloat)を使っていました.
しかし,コンパイル後の実行ファイルを実行する環境に応じて結果が変わってしまうのでは・・・と思い始めました.

そこで,ご質問なのですが,
・浮動小数を扱うと,実行環境(プロセッサ?)に応じて,結果は変わってしまいますか?

また,もし誤差が生じてしまうならば,何か対処する方法はありますでしょうか?
(整数演算にしろ!・・・と言うのは無しにさせて頂きます.)

初歩的な質問だと思いますが,宜しくお願い致します.

A 回答 (6件)

内容はちょっと古いが、説明しているサイトがある、



http://www.jpcert.or.jp/sc-rules/c-flp00-c.html

この辺で事情わかるはず。そこのサンプルをよくみると、特定の桁数までは同じ。

それ以後は、そこに書いてある事情ということ。計算が違ってくる事はない。

科学計算以外で、18桁ぐらい以上の精度を求められる事はまずない。

これは、コンピューターの2000年問題と同じレベルの問題で、CPUの進化と共に、精度が上がってくるのでしょう。
(20年前のチップだと年号を4桁で扱うのも、もったいない。はしおりたくなるわけ)
    • good
    • 0

組み込み系ではよくある話ですが、コンパイラによってはfloatとdoubleのサイズが同じだったり、floatが16ビットだったりする事が有ります。


私が良く使っているコンパイラでは、オプションによりdoubleのサイズが32ビットと64ビットを選択できます。
(組み込み系では intが8ビットだったり、charが16ビットだったり、オプションによりintがsignedだったりunsigendだったりする事が有ります)

浮動小数演算で注意する必要があるのは値が非常に近い数値の差を取ったり、大きさの非常に違う数値の和や差を取る時です。
例えば仮数部の桁数が3桁しかないシステムでは大きさが3桁以上違う数値を加算しても結果に反映されません。
例: 1.23+0.00123 → 1.23123 →1.23 (表現できるのは3桁まで)
例: 1.23-1.22 → 0.01 (有効数字が1桁になってしまう)

扱う数値の大きさがあらかじめ分かっている場合では大きさの近いもの同士で演算をすることで対策出来ます。
例えばデジタルフィルタの計算では入力に対して大きさの異なる係数を掛けてから積算しますが、この場合、小さい値の係数から積算する事で誤差を小さく出来ます。
    • good
    • 0

処理系によって浮動少数の扱いが違うために、実行環境で計算結果が変わることはあるようですね。



また、たとえば、

float f = 1;
bool b = (sinf(f)==sinf(f));

これで環境によってb==falseとなることがあります。
(gcc + corei5で確認)

これは、ハードウェア上で浮動少数点数を計算するときに64bit以上の幅があるレジスタを使用しており、結果をメモリ等に値を移すときにダウンコンバートが発生するため、処理系や最適化による計算順序の違いによって微妙に計算結果が変わってしまう、というのが主な原因のようです(とどこかに書いていたような...)。


コンピュータを使っている以上浮動小数点を使えば間違いなく誤差は発生しますので、信頼する桁数を安全な範囲に設定して四捨五入するなりして対応するのが良いのではないでしょうか。
    • good
    • 0

まず、何をもって正解とするのでしょうか



1÷3×3=
これの答えが1が正解でしょうか
0.999999999999999が正解でしょうか

A=0.333333333333333
A×3=
これの答えは0.999999999999999が正解でしょうか
1が正解でしょうか
    • good
    • 0

> 浮動小数を扱うと,実行環境(プロセッサ?)に応じて,結果は変わってしまいますか?


 コンパイラや処理系が違えば、結果は同じになるとは限りません。同じコンパイラでも、最適化のレベルが違えば結果が変わってしまうこともあります。

> もし誤差が生じてしまうならば,何か対処する方法はありますでしょうか?
 数値計算の種類によりいろいろな対処法が採られています。
参照URLに挙げた参考書など数値計算の解法と誤差についての書籍はたくさんあります。
 

参考URL:http://www.kyoritsu-pub.co.jp/bookhtml/0303/0027 …
    • good
    • 0

>初歩的な質問だと思いますが



と言うことは、まだ作り始めて、日が浅いのでしょう。

>実行環境(プロセッサ?)に応じて,結果は変わってしまいますか

それだと、もはやコンピューター(計算機)とは言えないでしょう。最先端のAI、てことになる。

マルチスレッドなどC++などの構造化、オブジェクト化プログラミングでは、よくある、最初にする勘違いの一種です。
(継承とか、イベントによる不活性など)

もう一度、デバックして、どこがどのように実行されるかチャート図を作って確かめましょう。

ちなみに、通常「丸める」とかの処理を入れると思いますが、それだと確かに変わる可能性はあります(ごくごく、まれです)。言語やコンパイラーなどの保障範囲では、起こりえません。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!