こんばんは!

仕事がうまくいかなさ過ぎて、世の中に絶望しているゆってぃです。

今日のテーマは桁落ちです。
大事なMy sweet sister(妹)に「桁落ちって何?」と聞かれたので、ここで説明することにしました。

桁落ちとは、浮動小数点演算で絶対値が非常に近い2つの値で減算を行ったときに、有効数字の桁数が極端に少なくなる現象を言います。
整数型での演算では発生しませんのでご安心(?)ください。

おい、その前に有効数字ってなんだよ?

これは、とりあえず信用できる桁数とお考え頂ければ結構です。

たとえば、体温計を想像してください。
「36.5度」と表示されたら、有効数字3桁です。

体温計くん「もっと細かい数字もあるのだろうけど、俺ちゃん、ちょっとそこまできちんと計れる自信ないから、有効数字3桁まで出すね。ここまでなら自信あるよ!!」
ってことですね(笑)

精度の良い高価な体温計なら、「36.52度」みたいに教えてくれるかもしれません。
この場合は、有効数字4桁です。

宇宙人がアンドロメダから持ち込んだ奇跡の体温計が
「36.52476度」
と表示してくれたら、それは有効数字7桁といえます。(体温計が正確であれば^^;)


桁落ちと言っても、それが最終的な演算結果を求めるときに発生するだけなら、(桁落ちしてる時点でダメですが)大きな問題にならない場合もあります。

問題なのは
桁落ちした数値を使い、さらに演算を続けること
にあります。
特に、桁落ちした数値に大きな値をかけるなんてしたら、もう最悪です。。。
駆け込んだトイレに紙がなかった挙句、なんかよく見たら女子トイレだったYO!
しかもどうやら自分の後に並んでる人(女性)がいて、出るに出られないZE!

ってくらい最悪です。
っていうか、本当にそんな状況になったらどうすればいいんだろう・・・。





さて


それでは、桁落ちのよくある例をご紹介します。

と、その前にひとつ、コンピュータを用いた演算における前提のお話を・・・

コンピュータで演算を行うときは、例えば√1001のような無理数は、適当に(後述しますが、有効数字7桁になるように)丸められてしまいます。
これを丸め誤差といいます。

みなさんもやりますよね?
飲み会でお会計が「15003円」だったとき、
「いくら?」
と聞かれて
「15000円」
と答えるでしょ?
3円は丸めこまれてしまったわけです。

通常、float型と呼ばれる浮動小数点型変数は、有効数字7桁です。
ですので、7桁では収まらない数字は、最後の桁で丸められて誤差が発生します。

では、次の式を見てください。

√1001 ≒ 31.63858404 ≒ 31.63858 = 0.3163858 × 10^2
√999 ≒ 31.60696126 ≒ 31.60696 = 0.3160696 × 10^2


ともに有効数字は7桁ですね。

ここで、この2つの値の減算を行うと

√1001 - √999 = 0.03162 ・・・(1)

となります。
・・・あれ?
有効数字が7桁から4桁まで落ちてる!!

ここで、コンピュータは(1)を
0.3162000 × 10^(-1)
のように、仮数部が7桁になるように勝手に0で埋めてしまいます!

「ん?何がいけないの?」

だって、ここって本当にですか?

丸め誤差のせいでうやむやになっていましたが、実際は

√1001 ≒ 31.63858404
√999 ≒ 31.60696126

ですから、もし有効数字が7桁のままなら
0.3162278 × 10^(-1)
のはずです。

つまり、一見正しい計算のように見えても、有効数字はすでに7桁では無くなっているのです。

なお、この現象は絶対値が離れた値どうしの減算では生じません。

例えば、

√2 ≒ 1.414214 = 0.1414214 × 10^1

より

√1001 - √2 = 0.3022437 × 10^2

となり、有効数字は維持されます。

「けどさ、理論値とズレてるとこって小数点以下6位とかすっごく小さい値の話だし、別にいいんじゃね?」

と思うかもしれません。
僕は冒頭で、「最終的な演算結果を求めるときに発生するだけ」なら、大きな問題にはならない場合もあると言いました。
そう、これが最終結果なら…。

でも、この数に1000000とかをかけちゃうと・・・
いままでは小さいと思っていた理論値との誤差が、一気に大きくなってしまいますね!
こんな計算をして出てくる答えなんて、誤差の塊でほとんどアテになりません。

対策は色々ありますが、、、
一番の対策は、計算方法を工夫して、桁落ちが発生しないようなプログラムを組むことです。
慣れるまでは大変ですが、頑張って書籍やネットなどで学習をしましょう。

(なお、double型を用いれば精度は上がりますが、根本解決にはなりません)

はい!

ざっくりですが、以上が桁落ちに関する説明です。
コンピュータでの演算には色々な誤差がありますが、桁落ちはかなりわかりづらく、理解に苦しむ部分だと思います。
ただ、有益なサイトや参考書なども多々ありますので、頑張って消化して、自分のものにしてしまいましょう!

最後までお読みいただいて、ありがとうございました!(感謝)

--

<追記>
ネットで桁落ちに関して改めて調べてみると、(ちょっと語弊がありますが)サイトによって微妙にニュアンスが違うように感じました。
いや、結果的には同じことを言っているのですが、どこまでを「桁落ち」と定義するのかと言う部分ですね。

Wikipediaなどで調べると、一般的には正規化までを含めて桁落ちと定義しているようです。
つまり、浮動小数点演算で絶対値の近い値を減算→有効数字が減少→空いてしまったビットを0で埋める(正規化)という過程全体を、桁落ちと定義しています。


ただ、IT用語辞典の説明を読むと

浮動小数点演算で、計算結果が0に極端に近くなる加減算を行ったときに、有効数字の桁数が極端に少なくなる現象。
例えば、「1.23456789x10^2-1.23456780x10^2」のような計算を行うと、計算結果は「9x10^-6」となり、有効数字の桁数は9桁から一気に1桁に減少してしまう。
浮動小数点形式の値は内部的には常に有効数字の桁数を一定として扱っているため、桁落ちが発生すると、不足した桁数が自動的に0で埋められてしまい、真の値との間に誤差が発生する。そして、桁落ちした数値に大きな数を掛けるなどの計算を行うと、発生した誤差が上の桁に上がってくることによって、計算結果を無意味にするほどの大きな誤差を含んだ値が返されることになる。
桁落ち自体による問題はコンピュータとは無関係に発生するが、コンピュータ上での桁落ちは、計算途中の値が分からない・結果の桁数が常に一定なので気づきにくいという特徴がある。


と書かれているので、
「有効桁数が少なくなる現象」が桁落ちであり、「コンピュータとは無関係に発生」する
と読めます。
そして、
桁落ちが発生すると、不足した桁数が自動的に0で埋められてしまい、真の値との間に誤差が発生する。
桁落ちした数値に大きな数を掛けるなどの計算を行うと
計算結果を無意味にするほどの大きな誤差を含んだ値が返されることになる

と書かれていることから
有効数字が減少することを桁落ちと定義しているようです。
もっとも、冒頭に「浮動小数点演算で」と書かれているので、正規化まで含めて書かれているのかもしれませんが。。。
(私、国語がすごく苦手で…単に読解力が足りないだけかも(汗))

どちらも結果的には同じ事を言っているのですが、どこまでを桁落ちと呼ぶのかという部分では、少しニュアンスが異なるのかな、という印象を受けました。

(僕はWikipedidaと同じ解釈で、正規化されてしまう部分も含めて桁落ちだと理解していました)

もっとも、これらはあくまでも言葉の定義の問題であり、現象そのものは普遍的なものなので、実際にプログラムを組むときには
細心の注意を払わなければならないことに変わりはない
のですが、気になったので追記させていただきました。

いやぁ、理解したつもりでいたことも、改めて聞かれると
結構戸惑ってしまうものですね(笑)
僕自身も勉強になりました^^

--

この記事をお読みになられた方は、きっと工学系の学生さんか、若手エンジニアの方ではないでしょうか?

みなさん、本当に勉強家なのですね…。

だって

僕は学生のときはもちろん、入社してからもしばらくの間は

桁落ちという言葉すら知りませんでしたから(涙)

みなさんのそのモチベーションの高さ、本当に素晴らしいと思います!

僕も見習わなければなりませんね><

みなさん、せっかくこうして勉強をされているのですから、、その成果は是非、資格という形で残しておきましょう!^^

そこでオススメなのは、やはり情報処理技術者試験です。

情報処理技術者試験に合格すると、学内・社内で評価対象になることはもちろん、就職や転職でも非常に有利です。(給与に反映してくれる企業も少なくありません)

多くの情報はネット上で入手することが可能ですが、それらの情報が最新のものである保障はありません。

今年は最新といわれる技術も、来年には過去のものになるのがこの業界です。

資格の取得を目指すのであれば、1冊だけでも良いので、最新の参考書をお手元に置くことをオススメします。

一緒に頑張っていきましょうね!!

 

関連記事
スポンサーサイト
コメント
非常に参考になりました。
テキストを読んでも簡単な説明しか書いておらず
いまいち理解できなかったのですが
この説明を聞いて理解できました!

これからも頑張ってください
Re: 非常に参考になりました。
本ブログをご覧頂き、誠にありがとうございます!
また、こんなに有難いコメントまで頂いて…とても嬉しいです(T_T)

これからも、皆様のお役に立てる記事が書けるよう頑張ります^^
非常にわかりやすい
桁落ちで検索して、ひっかかったところを上から順番に見ていったが、有効数字が減ることの何がいけないのかわかりにくいものばかりだった。
ここはそういうことかって納得できた初めてのサイト。
すばらしいと思う。
Re: 非常にわかりやすい
本ブログをご覧頂き、誠にありがとうございます!
わかりづらい説明にも関わらず、お褒めの言葉まで戴いて・・・本当にありがとうございます><

最近ブログの更新が滞っていたのですが、とおりすがりさんのお陰でやる気が出てまいりました!
これからも頑張ります!
とても分かりすかったです(*^_^*)
とても分かりやすかったです。(*^_^*)
ありがとうございました
Re: とても分かりすかったです(*^_^*)
> まりこさん

お返事が遅くなって申し訳ありません><
また、当ブログをお読み下さった上、コメントまでつけて頂き、誠にありがとうございます!

これからもよろしくお願いします^ ^
>駆け込んだトイレに紙がなかった挙句、なんかよく見たら女子トイレだったYO!
>しかもどうやら自分の後に並んでる人(女性)がいて、出るに出られないZE!

昔、そういった状況で苦悩する男性が主人公のドラマを見た。恐らくは、世にも奇妙な物語。後味の悪さは一品でしたね。

数値表現むずすぎわろえません。。。
Re: タイトルなし
> リーダーさん

世にも奇妙な物語で一番恐かったのは、「雪山」という話でした(笑)
基本情報まであと1ヶ月ちょっと!
リーダーなら大丈夫だと思うけど、がんばってね!!^^
参考にさせて頂きました。
どうもありがとうございます。
Re: タイトルなし
> 105さん

コメントありがとうございます^^
頑張ってくださいね!
わかりやすい!
やっと理解出来ました。
読みやすい文章で、おもしろかったです!
ありがとうございます。
Re: わかりやすい!
> スマートぼっち さん
こんな太古の記事をお読み頂いた上、コメントまでして頂いて…こちらこそ、ありがとうございます!><

そもそも浮動小数は、どうしても誤差を含んでしまうものです。
それがわかっている熟練エンジニアでも、「うっかり」やっちゃうことがあるくらい闇が深いです(笑)
桁落ちだけではなく、色々な落とし穴を持っているので、もしご興味があれば色々調べてみて下さい^^
頑張って下さいね!!
他のサイトを見てもいまいち桁落ち誤差についてわからなかったのですが、ここを見て納得出来ました。ありがとうございます。
Re: タイトルなし
> 学生さん

コメントありがとうございます^ ^
お力になれたようで、僕も嬉しいです。
勉強、頑張ってくださいね!
質問です。
√1001 ≒ 31.63858404 ≒ 31.63858 = 0.3163858 × 10^2 について、
0.3163858 × 10^2を書く意味ってなんですか?
31.63858の時点で、「有効桁数が7桁なんだな」と
示す為に書いたと思うのですが、0.3163858 × 10^2 を書いた意味がわかりません。よろしくお願いします。

Re: 質問です。
ご指摘ありがとうございます^^

これは、浮動小数点を扱う上で仮数部と呼ばれている「有効数字を現す部分」を小数点以下にすることによって、桁を揃えてわかり易く書こうと思った…のだと思います(汗)

ちゃんと書くなら、浮動小数点の2進数での取り扱いまで言及して(IEEE 754に準拠した)書き方にすべきですね。
この記事ではそこまで深い話をするつもりがなかったので、割愛させて貰った次第です。
コメントの投稿
トラックバック URL
トラックバック
ご訪問者様
プロフィール

ゆってぃ

Author:ゆってぃ
経歴7年の組み込み系・制御系エンジニアです。
("ど素人"という文言は取りました…笑)
ソフトウェア開発経験ゼロの状態から、なんとか実務がこなせるようになってきた現在に至るまでの経験を、備忘録代わりに綴っていきたいと思います。
入門者の方、大歓迎!
(上級者の方、ごめんなさい…)

あと、ブログには全然関係ないですが、Bumpy Headというバンドのギターをやっています。
ライブ情報なんかも書いたりすることがあるので、その時に「行ってもいいよ~」といった感じのコメントを戴けると、泣いて喜びます(泣)
ブログ読んでくださってる方なら、チケット代サービスしちゃいます!

最後に…滅多に流用することは無いでしょうが、このブログに書かれているソースは、特に指定の無い限りMITライセンスとします。ただし、一部それ以外のものもございますのでご注意下さい。
※ブログのリンク先にあるコードに関しては、リンク先のポリシーに従ってください。

最新記事
最新コメント
カテゴリ
RSSリンクの表示
メールフォーム

名前:
メール:
件名:
本文:

twitter
リンク
ブロとも申請フォーム
スポンサードリンク