
プログラム上で計算するときに丸め誤差が発生し、困っています。
丸め誤差が発生している計算は
-0.004+0.006+0.002
なのですが、
-0.004+0.006+0.002=0
となるところが、 =8.47E-09
となってしまっています。
オーダーの異なる計算ではないにもかかわらず、どうして誤差が発生するのかが理解できず困っています。
上の数値(左辺の方)の算出は、10^(-1)のオーダーの数値から計算されています。
多分、浮動小数点を使っているからだろうと考えているのですが、どのように解消したらよろしいでしょうか?
固定小数点を用いると、浮動小数点より誤差が少ないとありましたが、Cで固定小数点を用いる方法もわからないです。
よろしくお願いします。
No.2ベストアンサー
- 回答日時:
コンピュータは2進数なので仕方がないです。
10進数では有限小数であっても、2進数に変換すると循環小数等になってしまい、正確に計算することはできません。
試しに0.1を2進数に変換してみると一目瞭然。
これはC言語やそのほか多くのプログラミング言語の制限事項です。
COBOLとかではきちんと計算できます。(だから昔から小数をきちんと計算する必要のある銀行系のシステムにCOBOLが多いのです。)
数値を文字列として読み込んで、計算ロジックは自作するのが一番簡単です。
確かに、基数変換をしてみると、0.1は2進数で表せませんでした。
このような制限があるとは知らず、プログラミングしていたので、それを解消する、また別の方法を再考します。
回答ありがとうございます。
No.6
- 回答日時:
命題の真偽について
「浮動小数点は最後の数が0もしくは5で終わる数値以外は常に誤差が生じます」
0は間違いとして
5で終わる数値以外は常に誤差が生じます
という命題が真でもその裏命題の
5で終わる数値は常に誤差が生じない
が成り立たつとは限りませんよ
0.05に誤差があっても本命題には違反しません
No.5
- 回答日時:
「上の数値(左辺の方)の算出は、10^(-1)のオーダーの数値から計算されています。
」というのはどういう意味でしょうか? 本当にそうなら, この数値が得られた時点で (ある程度) 桁落ちは避けられないと思うのですが.
実際問題として浮動小数を使う限りこのような誤差の発生は避けられないし, 「誤差が発生する」ことは前提にしないとダメ.
解析を行うためのプログラミングをしているのですが、解析を行う前の準備段階での誤差でしたので、解消を考えてました。
浮動小数点を用いる限り丸め誤差を避けられないのは仕方のないことだとは思うのですが、どうしても誤差を避けたく思っていました。
この誤差の評価も含めて、解析したいと考えています。
回答ありがとうございました。
No.4
- 回答日時:
【補足依頼】
質問者さんに確認したいことがあります。
「-0.004+0.006+0.002」は0.004になると思いますが実際にはどんなソースコードで計算されていますか?ソース開示出来る場合は開示をお願いします。
あと質問にある「オーダー」というのは基数とか小数点の位置を言っているのでしょうか,すいません補足説明が可能であればお教え下さい。
【アドバイス】
小数の桁数が3桁くらいなら,回答者#1さんの回答にある整数計算というのでこの計算はできます。
-0.004は1000倍して-4,0.006は1000倍して6,0.002は1000倍して2
あとは整数の足し算 -4+6+2=4
最後に小数に戻すために足し算した値を1000で割り0.004と答えが出ます。
この方法の問題点は(小数を含む値 × 10^小数桁数)が整数型に収まる必要があります。また,その値を使った計算もオーバーフローしない事が条件となります。
No.1
- 回答日時:
浮動小数点は最後の数が0もしくは5で終わる数値以外は常に誤差が生じます
0.625だと誤差はないのですが
0.63だと浮動小数点では誤差が生じます
Cで固定小数点(10進ライブラリ)を扱えなくはないのですが
(そういうライブラリを手に入れる必要あり)
計算が非常に面倒です
(以下、あくまでも例です)
例)
decimal a;
a = toDecimal(0.630);
decimal b;
b = toDecimal(0.12);
decimal c;
c = addDecimal(a, b);
同様の事がC++であれば、クラスを使えるので
だいぶ簡単になります
(こちらもライブラリを手に入れる必要あり)
decimal a = 0.630;
decimal b = 0.12;
decimal c = a+b;
で、結論ですが、そもそもどんな計算をしたいのかがわからないので
勝手に推測して答えます
1.ゲームを作成する等で計算したい
そもそも誤差が出るのを考慮して計算する必要がある
if (a == 0.12)は駄目で、
if (abs(a-0.12) < 0.0001)のようにする
2.金額の計算に使う
小数点はやめて、整数で計算すべき
(金利などで小数が必要であれば、値を100倍、1000倍などして計算する等)
有限要素解析を行う場合の、有限要素行列作成のために計算される必要がある定数に関しての計算において、このような誤差が発生しました。
解析的に計算される値に対して、丸め誤差の発生を承知して解析を行うことに対して、かなり抵抗感があり、ここでの誤差を解消できるかを考えていました。
計算コストはできるだけ減らしたいのこともあり、丸め誤差の発生については再考します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 高校 有効数字計算 確定した値を含む 2 2023/01/18 06:03
- 物理学 誤差の問題についでです。 yがy=A+Bxの上に乗ると予想でき、以下の4個の測定値 (2,3.2±1 2 2023/04/25 00:54
- 統計学 標準誤差の求め方 2 2022/07/04 19:59
- 統計学 t検定について教えてください 2 2023/02/23 16:35
- その他(プログラミング・Web制作) VBA 1 2023/01/19 16:19
- 物理学 RC直列回路の実験で理論値と測定値の時定数を計算した結果±12%と大きな誤差が生じたのですがその原因 3 2022/09/29 22:32
- 統計学 不偏分散を計算するときに標準偏差和をn-1で割りますが、なぜ-1なのでしょうか? 「なぜnでなくn- 5 2022/07/04 14:54
- その他(ビジネス・キャリア) 今時の派遣社員って仕事が出来ないだけじゃなく計算も出来ないのか? 8 2022/07/22 20:53
- 物理学 誤差についてです 誤差の逐次伝播の問題を出されたのですが、どのように解けば良いかわからず困っています 2 2023/04/22 21:54
- 物理学 特殊相対性理論を、完全否定に成功~ガンマの数式は、成立しない。 2 2023/03/08 19:30
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
O(n log n)について2
-
VS2010でのint float数値について
-
有効数字について 以前質問をし...
-
c languageで 簡単な質問があ...
-
C言語でセルオートマトンを作成...
-
4096bitを95種類で表現すると何...
-
2進数 → 10進数変換 模範解答と...
-
計算が合わない
-
計算の丸め誤差の解消について
-
2進数の足し算(C言語)
-
データ型 double の桁数について
-
MATLABでの行列の全要素の和
-
三菱シーケンサ(Aシリーズ)で...
-
2進数データのビット演算
-
このC言語プログラムでどこをい...
-
C言語の実数型の足し算
-
if文がうまく回りません。
-
2の補数について
-
Excelで小数点以下の値が正常に...
-
EXCELの関数"STDEV(標準偏差)"...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
O(n log n)について2
-
有効数字について 以前質問をし...
-
三菱シーケンサ(Aシリーズ)で...
-
ExcelでPC(パソコン)によって...
-
c languageで 簡単な質問があ...
-
ExcelのINT関数の計算結果がお...
-
VB.net Double と...
-
VBAでミリ秒まで出力する方法
-
16進数 加算 減算 C言語
-
EXCELの関数"STDEV(標準偏差)"...
-
floatの有効桁数
-
除算を使わずに10で割りたい。
-
計算の丸め誤差の解消について
-
VB6.0での小数点の扱いについて
-
コンピューターは指数関数をど...
-
2038年問題 日付算出
-
時刻の比較
-
2進数、16進数、10進数のことを...
-
浮動小数演算は実行環境の変化...
-
2進数の足し算(C言語)
おすすめ情報