#include <stdio.h>
int main()
{
float height,weight;
printf("身長と体重を入力してください。\n");
scanf("%f",&height);
scanf("%f",&weight);
printf("身長は%fセンチ:体重は%fキロです。\n",height,weight);
return 0;
}
上記のようなプログラムを作って、身長には175.1体重には56.1という入力を行なって実行したところ、
身長は175.100006センチ:体重は56.099998キロです。
という結果が返ってきました。
heightとweightをdouble型で宣言したところ(もちろんscanf文の変換仕様は%lfにしています。)、結果は
身長は175.100000センチ:体重は56.100000キロです。
と私が、期待していたものが返ってきました。なぜfloat型だと期待通りの結果が返ってこないのでしょうか?ご教授お願い致します。
No.3ベストアンサー
- 回答日時:
ご質問は,いわゆる2進数計算のまるめ誤差のことでしょうか.
問題は,2つあると思います.
・循環小数を有限ケタで切ること
と
・何桁まで表示するか?
という問題です.
・循環小数を有限ケタで切ること
コンピュータの内部は,一部を除き,
「2進数」で処理されています.
少数点以下の表し方の中には,10進数だときっちり表せるものが,2進数では,循環小数のようになって有限のケタでは正確に表せない場合が出てきます.
つまり,10進数だと
0.1 (10^-1)
0.01 (10^-2)
0.001 (10^-3)
として,区切りですが,
2進数だと,
0.5 (2^-1)
0.25 (2^-2)
0.125 (2^-3)
0.0625 (2^-4)
0.03125 (2^-5)
0.015625 (2^-6)
0.0078125 (2^-7)
0.00390625 (2^-8)
となり,たとえば,0.1は
0.1(10進数) = 0*0.5 + 0*0.25 + 0*0.125 + 1*0.0625 + 1*0.03125 + 0*0.015625 + 0*0.0078125 + 1*.00390625 + ...
= 0.00011001... (2進数)
となり,2進数の世界では循環小数となります.
これを有限のケタで切ると誤差ができます.
つまり,2進数の有限のケタであらわした
0.1(10進数)を10こ足しても,
1になりません.
・何桁まで表示するか?
そうはいっても,単精度でも,通常の使用には十分
耐える精度は持っています.
表示桁数を少なくして,四捨五入してしまえば
みためには正解にみえるものも表示できます.
多くの計算結果は,そのようにして表示されています.
たとえば,さきほどの
0.00011001... (2進数)
= 0*0.5 + 0*0.25 + 0*0.125 + 1*0.0625 + 1*0.03125 + 0*0.015625 + 0*0.0078125 + 1*.00390625
= 0.09765625 (10進数)
です.少数第3位で四捨五入すれば,
0.1 (10進数)
です.
ご質問では,倍精度ではただしいという結果が出ていますが,0.1は2進数では循環小数ですから,倍精度といえども内部表現は不正確です.
ここでの差は単なる表示桁数の差でしょう.
単精度は,10進数で7ケタ
倍精度は,10進数で14ケタ
の精度を持っています.ご質問では,9ケタ程度表示していますので,その差がでていると思います.
ご質問者は,「電卓だとちゃんと表示するじゃないか」と思われると思います.
実は,電卓などの会計にしようされるものには,上記のような不正確さは許されません.
よって,「10進補正」といいまして,
10進数で正確に表せるように内部計算を10進数で行っているのです.
このような補正をすれば,計算速度はかなり落ちますが,10進数であらわしたものは正確に計算できます.
事務用のマシンでこの機能をもったものが多いようです.
おおくのコンピュータは,処理速度が命ですから,
2進数で計算していますだから,このような誤差は認識した上で使用すべきでしょう.
この誤差を避ける方法として,「固定小数点方式」
といいまして,
0.1を1000000 * 0.0000001
としてあらわし,計算はすべて,整数でおこない表示だけを小数点をつけてあらわす方法です.この方法だと,整数で計算するので,上記の誤差はでません.
ただし,この方法では,極端に大きな数字
たとえば,6.02*10^24 を表すことが出来ません.
極端に小さな数字 8.854*10^-24などもあらわせません.
また,ちなみに,最近のCPUは,浮動小数計算専用のハードを実装していて,単精度も倍精度も計算時間は変わりません.ただし,メモリは倍必要になります.メモリさえゆるせば,私はすべて倍精度としています.
また,C言語では,言語の簡単化のためか,変数にfloatは存在していますが,計算時の内部処理はすべていったん倍精度に変換されてから行われます.
(単精度を倍精度に変換しても,精度はあがりませんが.)
ものすごく親切な回答をしていただきありがとうございます。電卓では補正をおこなっているのは知りませんでした。最近のパソコンではメモリーも大容量積まれているので、doubleでも問題ないようですね。勉強になりました。
No.2
- 回答日時:
doubleも
厳密に175.100000ジャストではありません。
そのことについては浮動小数点を理解してください。
http://www.jtw.zaq.ne.jp/kayakaya/new/kihon/text …
IEEE形式浮動小数点について
http://www.cc.nao.ac.jp/vppman/HTML/japan/langFo …
doubleで175.100000と表示されるのは
第7位が四捨五入されて175.100000になっているだけです。
floatの有効数字は7桁
10.000000 この場合9桁の有効数字がなければ
表示上誤差がでる可能性があります。
doubleも17桁以上表示させれば誤差を確認できます。
double h = 175.100000;
printf("h=%.17lf\n",h);
結果
h=175.09999999999999430
No.1
- 回答日時:
floatの方が精度が悪いみたいですよ。
http://www.kilab.tama.or.jp/~komai/unix/c/float_ …
参考URL:http://www.kilab.tama.or.jp/~komai/unix/c/float_ …
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
c languageで 簡単な質問があ...
-
”/”を使わずに割り算したいんで...
-
ExcelのINT関数の計算結果がお...
-
BCD・HEX・BINについて
-
三角比の俯角の計算
-
コンピューターは指数関数をど...
-
2の補数について
-
有効数字について 以前質問をし...
-
16進数 加算 減算 C言語
-
O(n log n)について2
-
2÷3などの余りについて
-
信頼区間の1.96や1.65ってどこ...
-
std::set<int> で、ある値が何...
-
「Aに対するBの割合」と「Aに対...
-
#define _CRT_SECURE_NO_WARNIN...
-
【gcc・cygwin】multiple defin...
-
ある商品のロス率を5%見込み、...
-
Enterキーを押されたら次の処理...
-
Aの値からBの値を除するとは??
-
関数f(x)= x³‐3ax²+3ax+2 が極...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
O(n log n)について2
-
VB.net Double と...
-
c languageで 簡単な質問があ...
-
ExcelのINT関数の計算結果がお...
-
有効数字について 以前質問をし...
-
ExcelでPC(パソコン)によって...
-
三菱シーケンサ(Aシリーズ)で...
-
除算を使わずに10で割りたい。
-
16進数 加算 減算 C言語
-
EXCELの関数"STDEV(標準偏差)"...
-
VB6.0での小数点の扱いについて
-
”/”を使わずに割り算したいんで...
-
距離から緯度経度を求める方法
-
VBAでミリ秒まで出力する方法
-
floatの有効桁数
-
コンピューターは指数関数をど...
-
時刻の比較
-
計算の丸め誤差の解消について
-
Double型について
-
powf を使わずにべき乗を計算
おすすめ情報