![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
float型変数の値代入と表示について質問があります。
#include <stdio.h>
int main(void)
{
float flVal = 50.456;
printf("float型変数:%f", flVal);
return 0;
}
上記を実行すると、「float型変数:50.456001」と表示されました。
また、float flVal = 50.1; と変えて実行すると、「float型変数:50.099998」と表示されました。
それぞれ期待していた結果は、
「float型変数:50.456000」、「float型変数:50.100000」だったのですが
代入した値と結果が微妙に異なる理由は何でしょうか。よろしくお願いします。
No.1ベストアンサー
- 回答日時:
IBMのページから
http://www-06.ibm.com/jp/domino04/lotus/support/ …
基本的に小数点以下の数値を含むものは(0.5,0.25、0.125などを除き)、誤差が生じるため。
実際の浮動小数点演算プログラムでは、許容できる範囲であれば一致しているとみなして処理を行うことが多い。
irb(rubyの対話型インタプリタ)やpythonのプロンプトで
irb> 0.1 +0.2 == 0.3 (Enter) とすると
falseが返る。
金額計算などでは単位未満(日本での銭単位とか)を扱う場合はこれでは困るので、小数点以下でも有効桁数内では誤差が生じない固定小数点型が用いられる。
COBOLが何のかんのと言われながら、勘定系取引でシェアが高かったのも基本が固定小数点型を採用していた事が大きい
SQLでも整数型、浮動小数点型、固定小数点型みんなあります。
(Oracleは長いこと、固定小数点型で全部こなしてましたが)
JavaではBigDecimalクラスが固定小数点です。ただ、Java演算子のオーバーロードが出来ないので、いちいちadd、sub、multiply、divideメソッドを使わなければならないのがちょっと面倒。
.Net Framwork( VB.NET、C# )のdecimalクラスの方が直感的かもしれない。
ちなみにrubyにもあります。
http://www.ruby-lang.org/ja/man/html/BigDecimal. …
詳しい解説ありがとうございます。
float型が内部的に2進数でどのように保存されているか、
2進数から10進数にどのように変換される過程で誤差が発生するのか、勉強したいと思います。
また、データ型として固定小数点型という考え方があること、
C言語以外では固定小数点型をどのように扱うかの情報まで教えていただき、
ありがとうございました。参考にさせていただきます。
No.4
- 回答日時:
あとは、printfのような可変引数の場合、floatはdoubleに変換されます。
%fもdoubleを対象にしています。
例えば、
doubleでは50.456+誤差0.0000000000001
floatでは 50.456+誤差0.000001
だったとします。
%fではdoubleの分の誤差はまるめこんで 50.456と表示します。
floatでは誤差まで含めた50.456001がdouble型として変換されて、%fで処理されます。0.000001はdoubleでは有効桁内なので%fでは表示まるめこまないで表示します。(正確には、doubleの有効桁のところでのまるめこみが行われます)
特に理由が無い場合はdoubleを使うようにしましょう。
回答いただき、ありがとうございます。
double型で試したところ、
50.1は「50.100000」、50.456は「50.456000」と結果表示されることを確認しました。
floatとdoubleで有効桁が異なるため丸め込みの桁数が変わり、
結果も異なることが理解できました。
ありがとうございます。
No.3
- 回答日時:
簡単に言うと誤差です。
float flVal = 50.1;
とすると、float 型の値として 50.1 に最も近い 50.456001 が代入されたのだと思います。
↓を読むと納得できると思います。
http://pc.nikkeibp.co.jp/pc21/special/gosa/eg4.s …
あと、参考までに
http://ja.wikipedia.org/wiki/%E6%B5%AE%E5%8B%95% …
回答いただき、ありがとございます。
紹介していただいた日経のページに、
丁寧に解説が載っていましたのでじっくり読ませていただき、理解できました。
ありがとうございました。
No.2
- 回答日時:
特殊なものを除くと、floatは二進数です。
なので、10進数ではきれいに表せる数字であってもきれいに表現できない場合があります。
少なくとも有限の桁数なら誤差が発生します。
それが困る場合は内部的に10進数の計算を使えるするものもありますが、一般的ではありません。
とりあえず、コンピュータで実数を使う場合はそのようなことが発生するというのは覚えておく必要があります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語: ポインタ 5 2022/06/01 08:33
- C言語・C++・C# C言語について コマンドラインで >変数 12.00 (char型) と、小数点付きの値を共用体に渡 1 2022/04/22 16:56
- C言語・C++・C# C言語 共用体について コマンドライン引数で値を2つ入力したときに、argv[2]の値をUNI u1 4 2022/04/25 20:34
- PDF C#でfloatを整数部、小数部とも桁数固定で文字表示したい 2 2022/07/28 09:37
- C言語・C++・C# C++言語の16進数の表現についておしえてください 1 2022/11/14 17:46
- C言語・C++・C# C++ と、 1 2022/11/07 23:45
- PHP アップロード画像数でCSSを分けることに成功したのですが、画像の横に文字を並べることが出来ません。 3 2023/07/28 17:16
- C言語・C++・C# キャスト演算について。 1 2023/07/15 15:28
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# 至急お願いします。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分母 3 2022/07/19 17:09
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
O(n log n)について2
-
2進数の足し算(C言語)
-
”/”を使わずに割り算したいんで...
-
VBAのINT関数について
-
8進数と16進数表現について
-
VB6.0での小数点の扱いについて
-
大きすぎる数値になるとE+にな...
-
時刻の比較
-
c languageで 簡単な質問があ...
-
有効数字について 以前質問をし...
-
VBAでミリ秒まで出力する方法
-
floatの有効桁数
-
EXCELの関数"STDEV(標準偏差)"...
-
100桁の計算ができなくて困って...
-
乱数 なぜ剰余を使うのか
-
10進数での「25」が2進数では「...
-
16進数 加算 減算 C言語
-
「Aに対するBの割合」と「Aに対...
-
2÷3などの余りについて
-
マイナスからプラスへ転じた時...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
O(n log n)について2
-
16進数 加算 減算 C言語
-
c languageで 簡単な質問があ...
-
VB.net Double と...
-
”/”を使わずに割り算したいんで...
-
三菱シーケンサ(Aシリーズ)で...
-
ExcelのINT関数の計算結果がお...
-
有効数字について 以前質問をし...
-
ExcelでPC(パソコン)によって...
-
除算を使わずに10で割りたい。
-
EXCELの関数"STDEV(標準偏差)"...
-
floatの有効桁数
-
VBAでミリ秒まで出力する方法
-
100桁の計算ができなくて困って...
-
2進数の足し算(C言語)
-
VB6.0での小数点の扱いについて
-
VBAでの割り算の余りの求め方
-
コンピューターは指数関数をど...
-
距離から緯度経度を求める方法
-
BCD・HEX・BINについて
おすすめ情報