クリエイター手抜きプロジェクト[166]学習編 小数計算は正しくない
── 古籏一浩 ──

投稿:  著者:


コンピュータは計算機ですから、当然計算は得意で正しい計算結果を返すはずだ、と思っている人が多いのではないでしょうか。

ところが、コンピュータで計算を行なった場合に正しい結果にならないことがあります。正しい結果を返すのは、「整数値で計算した時で決められた範囲内に収まっているときだけ」です。逆に、これ以外の場合は正確な計算結果を返しません。


例えば、正しくない結果になる例としては、小数値を含む計算が有名です。実際に、以下のスクリプトをWebブラウザ(Safari、Firefoxなど)で実行してみてください。このスクリプトは0.1を10回足すだけのものです。0.1を10回足すわけですから

0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1

つまり

0.1×10

となり結果は「1」になるはずです。

< html >
< head >
< title >Sample< /title >
< /head >
< body >
< script >
n = 0;
for (i=0; i< 10; i++){
n= n + 0.1;
}
alert(n);
if (n == 1) alert("本当に1です"); else alert("1ではありません");
< /script >
< /body >
< /html >

実行してみると、計算結果は「1」ではなく「0.999999999」のようになってしまうはずです。これは、コンピュータが0と1で動作しているのが大きな原因です。コンピュータは小数値を内部で表すために0と1に変換しますが、この時に正しく表現できない数があります。

内部的には「1÷(2のn乗)」として表現されます。つまり

1は1
1/2は0.5
1/4は0.25
1/8は0.125
1/16は0.0625

のようになります。例えば、0.75であれば0.5+0.25で誤差なく表現できますが、そうでない場合には一番近い数値を返すようになっています。つまり、小数値で計算してしまうと、値によってはどうしても誤差が発生してしまうのです。

まだ、ブラウザのように0.9999999を返してくれる方が親切です。
Adobe IllustratorやPhotoshopなどは、もっと痛い目にあうことがあります。
以下のスクリプトを実行させてみてください。

n = 0;
for (i=0; i< 10; i++){
n= n + 0.1;
}
alert(n);
if (n == 1) alert("本当に1です"); else alert("1ではありません");

アラートダイアログには「1」と表示されるのに、1かどうか判別すると「1ではありません」となってしまいます。もし、コンピュータに詳しくない人であれば、頭を抱え込んでしまいそうです。

ご丁寧に四捨五入しているのかどうか分かりませんが、Adobe系のアプリケーションに騙されることがあるというのは覚えておいた方がいいでしょう。

でも、ここまで読んで「そんなに誤差が発生していたらまずいのでは?」と思う人もいるでしょう。上記で説明したものは一般的なもので、厳格に計算しなければいけないものに関しては、BCD演算など別の計算手法を利用して行ないます。計算速度は低下しますが、上記のような誤差は発生しません。また、FORTRANのように有効桁数を指定して計算できる言語もあります。

整数値の計算は有効範囲であれば誤差は出ませんから、小数計算は100倍して計算して最後に100で割るという方法も使われます。

計算を間違えると、せっかく打ち上げた衛星とかもどっか間違った方向に飛んでいってしまうことになります。また、計算結果の誤差を利用して金利計算による誤差の分を自分の通帳に入れるのも駄目です。

ということで、コンピュータの計算結果は正しくないことがあるというのを覚えておいてもらえば、思わぬ落とし穴にはまることも減るかと思います。


【古籏一浩】openspc@po.shiojiri.ne.jp
< http://www.openspc2.org/
>

「prototype.jsパーフェクトリファレンス」が発売になりました。でも、アマゾンだと名前が違うので、直接書籍名を入れないと出てきません。
< http://www.amazon.co.jp/exec/obidos/ASIN/4048700200/dgcrcom-22/
>

Photomatix Pro 3例文辞典を公開しました。一応、そこそこ日本語化するパッチも用意してあります。ただし、MacOS X版のみですが。
・Photomatix Pro 3例文辞
< http://www.openspc2.org/reibun/Photomatix_Pro3/
>

photo
prototype.jsパーフェクトリファレンス
古旗 一浩
角川グループパブリッシング 2008-04-18



photo
改訂第4版 JavaScript ポケットリファレンス
古籏 一浩
技術評論社 2006-10-18
おすすめ平均 star
starJavaScriptを使ったプロジェクトのお供に是非
starJavaScript仮免者以上の方へ
starバランスの良いバイブル
star中級者向けです。

[改訂版] PHP ポケットリファレンス (Pocket reference) 改訂新版 SQLポケットリファレンス (Pocket reference) 基礎 Ajax + JavaScript 改訂第5版 オールカラー  HTML ポケットリファレンス (POCKET REFERENCE) 標準DOMスクリプティング JavaScript+DOMによるWebアプリデザインの基礎



photo
ActionScript逆引きクイックリファレンス―5&MX&MX2004&8対応 for Windows & Macintosh
田中 康博 古籏 一浩 林 拓也
毎日コミュニケーションズ 2005-12
おすすめ平均 star
starFlash(ActionScript)の開発前の調査にも役立ちます
star良書です。

Flash逆引きクイックリファレンス 8&MX2004対応for Windows & Macintosh 速習Webテクニック FLASH8 ActionScript 実例サンプル47 (Quick master of web technique) Flash Hacks―プロが教えるテクニック&ツール100選 FLASH ActionScript スーパーサンプル集 1.0/2.0対応版[CD-ROM付き] Dreamweaver逆引きクイックリファレンス―8 & MX 2004対応for Windows & Macintosh

by G-Tools , 2008/04/21