C でプログラムを書いて、除算の繰り返しに関する浮動小数点誤差の大きさを感じてみてください。
#include <stdio.h>
int main (int argc, char* argv[]) {
if (argc < 3) {
printf("Enter a decimal number as the first positional "
"argument\n");
printf("Enter the maximum number of digits to print as the "
"second positional argument\n");
return 0;
}
long double d;
sscanf(argv[1], "%Lf", &d);
int m;
sscanf(argv[2], "%d", &m);
int i;
char format[10];
for (i = 1; i <= m; ++i) {
printf("(%d digits)\n", i);
sprintf(format, "%%.%dLf\n\n", i);
printf(format, d);
}
long double p = d;
printf("\n");
for (i = 1; i <= m; ++i) {
printf("(%Lf/10e%d with %d digits)\n", d, i, m);
p = p/(long double)10.0;
printf(format, p);
}
return 0;
}
これは、次の引数を指定して実行した場合の出力の 1 行です。
$ fpe 0.1 700
.
.
.
(0.100000/10e180 with 700 digits)
0.0000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000999999999999999999969819570700939858153376
736698732853283605408116087882762948991724868957176649769045358705872354052
261113540314114885779914335315639806061208847920179776799404948795506248532
485303630811119507604985596684233990126219304092175565232198569923253737561
276484626462077772036038845251286782974821021132356946292172207615386395848
331484216638642723800290357587296443408362280895970909637712494349003491485
594533190659822910753768473307578901199121901299804449081420898437500000000
000000000000000000000000000
.
.
.
ここでは、485 桁の浮動小数点ノイズが観察されます。これは gcc 4.4.3 でコンパイルされたもので、80 ビットの拡張精度を使用していると思われます。ただし、10 進数で 485 桁というのは、80 ビットをはるかに超える情報量です。それで、私の質問は、この情報はどこから来ているのですか?