「2のn乗の数」の先頭の数字列:無限の恐ろしさ。:その2・プログラムの「バグ」にぶつかる。
「その1」で見通しを立てたその方針でプログラムを書きました。(仮称10進BASICで)
INPUT PROMPT "a = ":a
LET L2 = LOG10(2)
LET L = FP(LOG10(a))
LET R = FP(LOG10(a+1))LET n = 1
DO
LET w = FP(n * L2)
IF(L <= w) AND (w < R) THEN
EXIT DO
END IF
LET n = n + 1
LOOP
LET tmp = n * L2
PRINT "2 ^";n;"=";10^FP(tmp);"* 10 ^";IP(tmp)END
{プログラム中「FP」というのは小数部を求める関数、「IP」は整数部を求める関数です。}
★そうしたら、まず7でしくじった。
先頭の数として「7」を指定すると、答えとして「2^3 = 8」が出てきてしまうんです!
このBASICの内部の演算精度のせいで、普通に実行したとき
プログラムの冒頭で、R = log(7+1) を求めると「 .903089986991944」となります。これが不等式の右。
ところが、演算時、n=3のときに「3 * L2」の小数部を計算すると「 .903089986991943 」こうなるんです。
そうすると、不等式が成立しまして、答えとして「2^3=8」が提示されるのですね。
変数の値を追跡してわかりました。
このBASICのオプションには「1000桁モード、超越関数使用」というのがあります。対数での1000桁は無理ですが、内部演算精度が上がります。これで「7問題」はクリアできました。
a = 7
2 ^ 46 = 7.0368744177664036 * 10 ^ 13
「2の46乗は7で始まります。」
{ヨカッタ}
★次に9でしくじった。
a=9 なら a+1=10 です。log(10)=1 ですので、小数部が0です。
そうすると
log(a) の小数部分 ≦ log(X) の小数部分 < log(a+1) の小数部分
この不等式の左は正の小数なのに、右が0ですから、この不等式が成立することは永遠にあり得ない。
で、「恐怖の無限ループ」に落っこちた、はまった。
仕方なくブレイクをかける。マイッタナ。
解決法:9とか、99とか、1を足して対数を取った時に小数部が0になる場合は、不等式の右を「1」にすればいいのです。
そうすると「1未満」となるので無限ループの罠は解消するはず。
そのようにして実行すると
a = 9
2 ^ 53 = 9.0071992547409972 * 10 ^ 15
「2の53乗は9で始まります」
{ヨカッタ、ヨカッタ}
★本の著者の数学者、根上さんはこの出来事を見落としてないか?と再度ちゃんと読んだら
・・・aが999…99である場合を除き・・・
その唯一の例外の場合は、a+1=1000…00となって、log(a+1)は半端がなくなり
log(a+1)-s=1
となります。・・・
ちゃんと指摘してありました。読者=私が見落としていただけでした。
「唯一の例外」ではあるのですが、この例外は無限個あるんですよ。おそろしいなぁ。
« 「2のn乗の数」の先頭の数字列:無限の恐ろしさ。:その1・話の概要 | トップページ | 「2のn乗の数」の先頭の数字列:無限の恐ろしさ。:その3・プログラム完成・実行結果 »
「理科おじさん」カテゴリの記事
- 化学の日(2022.10.26)
- 秒速→時速(2022.09.01)
- 風速75メートル(2022.08.31)
- 「ウクライナで生まれた科学者たち」(2022.05.31)
- 反射光(2022.05.09)
« 「2のn乗の数」の先頭の数字列:無限の恐ろしさ。:その1・話の概要 | トップページ | 「2のn乗の数」の先頭の数字列:無限の恐ろしさ。:その3・プログラム完成・実行結果 »
コメント