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

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

新規登録して質問してみよう
ただいま回答率
85.35%
コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

2481閲覧

floatで100.001f -100 を計算したときに0.001にならない理由を教えてください

LazzyBerry

総合スコア1

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2021/07/22 15:44

前提・実現したいこと

C++の勉強をしています。
「独習C++」の本で練習問題1.5 2問目でなぜ誤差が発生するのか、
どうすれば解決できるのかわからなくて困っています。(出力が0.001になるのが理想です。)

アドバイス、回答いただけると嬉しいです。
よろしくお願いいたします。

該当のソースコード

c++

1#include <iostream> 2 3 4int main() 5{ 6 float f = 100.001f; 7 f -= 100; 8 std::cout << f << std::endl; 9 10 //予想;0.001 11 //実際;0.000999451 12 //丸め誤差が発生するため?。実数を浮動小数点数すなわち有限桁数の2進数によって計算するときに発生する誤差 13}

試したこと

コメントは自分の考えた回答ですが、自信がありません。

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

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

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

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

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

guest

回答2

0

ベストアンサー

10進数の0.001は2進数では無限小数なので、どうしても有限桁では表現できません。
float型の有効桁数は10進換算で約7桁なので、100.001の6桁はかなり誤差割合が大きいことになります。

解決方法としては、
案1:floatではなくdoubleを使う。doubleだと約15桁の有効桁数があるので、かなり大丈夫です。
案2:小数点以下3桁までだけ考えればいいのであれば、1000倍して小数部をなくし、表示の時に元に戻すと、計算途中でも小数部がゼロのままであれば、誤差発生は最後に1000で割る部分だけなので、これはほとんど大丈夫です。1000で割らずに1000倍の値を文字列化してから小数点を文字列処理で挿入すると誤差はありません。もちろん有効桁数の範囲を越えない場合ですが。(float型でなくint型を使うことも考えられます)
案3:何らかの10進数計算ライブラリーを使う。

案2の例:

C++

1#include <iostream> 2int main() 3{ 4 float f = 100001.0f; 5 f -= 100000; 6 std::cout << f/1000 << std::endl; 7}

投稿2021/07/22 23:23

編集2021/07/22 23:34
otn

総合スコア85901

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

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

LazzyBerry

2021/07/23 00:52

回答ありがとうございます。解決方法、とても参考になりました! doubleで試したところ、0.000999451になってしまいましたが、 案2の方法はうまくいきました。
otn

2021/07/23 02:20

> doubleで試したところ、0.000999451になってしまいましたが、 定数部分が、100.001f と単精度のままでは?
LazzyBerry

2021/07/23 05:11

その通りでした。 指摘の通り修正したら期待通りの結果になりました。 再度ありがとうございます。
guest

0

丸め誤差が発生するため?。実数を浮動小数点数すなわち有限桁数の2進数によって計算するときに発生する誤差

正解。100.001f(あるいは0.001f)を誤差無しに(有限桁の)二進数で表現できないからです。

投稿2021/07/22 15:52

編集2021/07/22 15:53
episteme

総合スコア16612

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

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

LazzyBerry

2021/07/22 16:07

回答ありがとうございます。誤差が出る理由がわかりました!
episteme

2021/07/22 22:54

解決したんなら close しといて。
LazzyBerry

2021/07/23 05:03

申し訳ありません。クローズします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問