読者です 読者をやめる 読者になる 読者になる

留年戦記

留年と工学と人間関係と毎日戦っている人のブログです. 今年は留年回避済み.プロマネのお勉強中.留学試みたりTOEICの得点向上を試みたり.普通に学校の勉強を頑張ったり工学(プログラミングも回路も)について学んでみたり.時々レーザーカッターのパラメータを記事にしてます.

【C言語】floatとdoubleで計算したら計算結果が異なる!誤差が…!<原因は解明済み>

もうそろそろ本腰入れて,ブログ頑張ろうと思ったあこさんです.

(ちょっと色々今リアルがあれで現実逃避なうっていうやつです(;´Д`))

 

さて,今回はfloatとdoubleの計算誤差の本題です.

ただしその1です.今回で全部説明は出来ません.

ので,ちょっと連番になっちゃいますが更新を楽しみにしてくださいね.

 

1,問題の誤差の有名な例

f:id:aconote:20161115223521p:plain

さて,皆様結果がどうなるか分かりますか?

(知ってる人は知らないふりするんですよ!!!私がかなしいから!)

 

f=yes

 

となると思った方…正解…

ではありません!

 

( ゚-゚)( ゚ロ゚)(( ロ゚)゚((( ロ)~゚ ゚ナント!!!

って感じですよね.

 

はい.証拠.

f:id:aconote:20161115224007p:plain

f==noです.

(ここでふと…「なんで=が二つあるんだ…?」ってなりました(笑))

さて,これが問題の誤差です.

と,問題提示も終わったことですし種明かししましょうか.

 

2,誤差の原因(floatとかdoubleについてはまた後日)

0.1を二進数に直すと…0.0001100110011001....と続きます.

floatの場合32bitなので,コンピュータの中には0.000110011001100110011001と入ります.

そしてこれを10進数に直すと…0.1にならず0.09999996423721313...となります.

ちょっと足りません!

そして,次0.2.

二進数にすると,0.001100110011001100110011.

そしてこれを10進数に戻すと,0.199999988079....となります.

こっちも足りない.

まぁ,この時点で自明ですよね…(;´Д`)

足りないんです.足しても,0.3にならないんです.

だから0.3とイコール関係でないと表示されたんです.

この進数が各進数毎に1対1に対応しないからいけないんです!

これが誤差の正体でした.

(ちなみに進数の話はこちらへ)

 

aconote.hatenablog.com

 

 

aconote.hatenablog.com

 

3,さてタイトル.計算結果が異なります.

f:id:aconote:20161115231934p:plain

さっきと似たコードですがちょっと違います.

まず,fがdoubleの型となっており,dがfloatの型となっています.

(dとfが逆じゃんと言われそうなので言い訳.ナチュラルに間違って書いてましたorz書いてスクショしたあとにショック受けたんですよ…?これでも)

そして,15E25という数字を代入.

(ここでEって何?と思われる方いらっしゃると思います.これは10の乗数という意味で,上の場合15*10^25という意味になります)

これ,普通に考えれば両方とも出力結果が

150000000000000000000000000となるはずなんですよ.

が,結果はこれです.

f:id:aconote:20161115232215p:plain

はい.

floatの答え,ずれてますね.

これ,この間の課題でどうしても結果がずれる~~~って悩んだんですよ.

floatの方が確保メモリ小さくて乗数作っていくと誤差が増えていくんですよね…(遠い目)

よって,25乗とかの桁数になると…下の方の誤差が見えてくる,と.

そんなわけで皆様,10の乗数の場合,デカい指数の場合にこそ「double」使ってくださいね!

 

4,次回予告

floatとdoubleという話を一切せずにいきなり結果から話してしまったので次回はfloatとdoubleの話について詳しく書こうと思います.

今回はとりあえず,「こんなエラーが発生するので皆様お気をつけて!」という意味の記事でした!

ではでは~