民芸的プログラミング 〜ソフトウェア開発日記〜

アクセスカウンタ

zoom RSS 0.1 を 1 万回足すプログラム

<<   作成日時 : 2008/09/10 18:07   >>

ブログ気持玉 0 / トラックバック 0 / コメント 4

プログラミングの落とし穴。0.1 を 1 万回足してもなかなか 1,000 ちょうどにはなってくれない。コンピュータが 2 進数で動いていることの証拠なのだが、金融や会計のプログラムではちょっと困ったことになる。
と、よく言われるのだが、本当に 1,000 にならないのか、手近な環境で何パターンか試してみた

まず、JScript (WSH) の場合

var sum = 0;
for (var i = 0; i < 10000; ++i) {
sum += 0.1;
}
WScript.Echo(sum);

これで、答えは 1000.00000000016 となった。


続いて、Perl (AvtivePerl)

$sum = 0;
for ($i = 0; $i < 10000; ++$i) {
$sum += 0.1;
}
print $sum;

これでも答えは 1000.00000000016 となった。


続いて、VBScript (WSH)

Dim sum, i
sum = 0
for i = 0 to 10000
sum = sum + 0.1
next
WScript.Echo(s)

これで答えはなぜか 1000.10000000016


最後に、Excel を起動して、セルA1 から A10000まで、0.1 で埋めて、A10001 に =SUM(A1:A10000) と入力してみた。
すると、答えは 1000.00000000016


私の手元には、10進数の小数点を正確に扱える環境が無いようだ。
最後の Excel がちょっと意外だったかな。

テーマ

関連テーマ 一覧


月別リンク

ブログ気持玉

クリックして気持ちを伝えよう!
ログインしてクリックすれば、自分のブログへのリンクが付きます。
→ログインへ

トラックバック(0件)

タイトル (本文) ブログ名/日時

トラックバック用URL help


自分のブログにトラックバック記事作成(会員用) help

タイトル
本 文

コメント(4件)

内 容 ニックネーム/日時
だいぶ遅くなりますけど

use strict;
use warnings;
use bignum;

my $sum = 0;
for (my $i = 0; $i < 10000; ++$i) {
$sum += 0.1;
}
print $sum, "\n";
通りすがり
2008/09/10 22:03
MSX-BASICの場合ちゃんと1000になります。
これはBCD表現と呼ばれるもののおかげです。
厳密に言うとMSXのBIOS内部にあるMathPackがBCD表現を使っており、BCDを使わないで0.1を1万回足すプログラムでやると1000にはならないようです。最近のパソコンの特徴ですかね?大きい数値には強いが小さい数値表現に弱いのは?もし江戸時代の関孝和が現代でコンピュータの設計にかかわったらどんなのができたでしょうか?そんなつまらんこと想像しちゃいます。
偏屈斎
2008/09/10 23:06
通りすがりさん、今、手元のcygwin環境でそのスクリプトを試したところ、実行時間20倍になりましたが、正確に 1000 が出ました。ありがとうございます。

偏屈斎さん、BCD は COBOL でも使われているやつですよね。MSX の BIOS にそんなものが載っていたんですね。最終的には Z80 で演算するのでしょうから、速度面では不利だったのでは?

ところで、何の偶然か、私、つい先日、関孝和のお墓(東京都新宿区)の近くを通りかかったんですよ。こういう話になるのだったら、お参りしておけばよかったです。
kazuyoshikakihara
2008/09/10 23:47
一晩寝て落ち着いてから考えるに、BCD で精度を確保するのか、2進数のままでスピード確保とメモリの節約をするのか、という議論に行き着きそうですね。
最近の PC だと性能に余裕があるので、普段は 2 進数でも、ライブラリなどを使って、必要に応じて BCD あるいは他の方法で精度を確保できるようになっているというのが主流でしょうか。

うっかりさんが、肝心なときに精度を上げるのを忘れてプログラミングして、後で大騒ぎになったりしそうですが。
kazuyoshikakihara
2008/09/11 07:10

コメントする help

ニックネーム
本 文
0.1 を 1 万回足すプログラム 民芸的プログラミング 〜ソフトウェア開発日記〜/BIGLOBEウェブリブログ
文字サイズ:       閉じる