・アルゴリズム                       moonlight 氏

 自然数の平方根の値を1桁ずつ「数える」アルゴリズムというのを、たまたま別件で探して
いて見つけました。こんなん記憶にない!とか思ったのですが、皆さんご存知でしょうか?

 とても不思議なアルゴリズムに見えますが、何故これでうまくいくのでしょうか?あまりに面
白かったので、自分でもこれから少し考えてみますが...。


 MDAさんから参考文献をご紹介頂きました。(平成26年10月1日付け)


 GAI さんからのコメントです。(平成26年10月1日付け)

 Mahematica のプログラムを用いて、を出してみました。全部200
回繰り返していますが、ものによって手に入る桁数が微妙に異なることが面白いです。

In[123]:= n=2;M=List[];P=List[];
A=5*n;B=5;s=0;
For[i=0,i<201,i++;
If[A>=B,A=A-B;B=B+10;s++,A=100A;B=FromDigits[Insert[IntegerDigits[B],0,-2]];s=0]
;M=Append[M,s]];For[k=0,k<Length[M],k++;If[M[[k]]==0,P=Append[P,M[[k-1]]]]];P
N[Sqrt[n],38]
Out[125]= {1,4,1,4,2,1,3,5,6,2,3,7,3,0,9,5,0,4,8,8,0,1,6,8,8,7,2,4,2,0,9,6,9,8,0,7,8}
Out[126]= 1.4142135623730950488016887242096980786

In[127]:= n=3;
・・・・・・・・・・・・・
N[Sqrt[n],37]
Out[129]= {1,7,3,2,0,5,0,8,0,7,5,6,8,8,7,7,2,9,3,5,2,7,4,4,6,3,4,1,5,0,5,8,7,2,3,6}
Out[130]= 1.732050807568877293527446341505872367

In[131]:= n=5;
・・・・・・・・・・・・・
N[Sqrt[n],31]
Out[133]= {2,2,3,6,0,6,7,9,7,7,4,9,9,7,8,9,6,9,6,4,0,9,1,7,3,6,6,8,7,3}
Out[134]= 2.236067977499789696409173668731

In[135]:= n=6;
・・・・・・・・・・・・
N[Sqrt[n],33]
Out[137]= {2,4,4,9,4,8,9,7,4,2,7,8,3,1,7,8,0,9,8,1,9,7,2,8,4,0,7,4,7,0,5,8}
Out[138]= 2.44948974278317809819728407470589

In[139]:= n=7;
・・・・・・・・・・・・
N[Sqrt[n],43]
Out[141]= {2,6,4,5,7,5,1,3,1,1,0,6,4,5,9,0,5,9,0,5,0,1,6,1,5,7,5,3,6,3,9,2,6,0,4,2,5,7,1,0,2,5}
Out[142]= 2.645751311064590590501615753639260425710259


 MDAさんからのコメントです。(平成26年10月1日付け)

 回数が桁数になる仕組みなので、「7, 8, 9 」が多ければ桁数が少なく、「0, 1, 2 」が多けれ
ば桁数が多いみたいですね。


 DD++さんからのコメントです。(平成26年10月2日付け)

 なるほど、これは面白い方法ですね。について、このアルゴリズムを少し変えた以下を
4 桁くらい実行し、開平法と書き並べてみればその関連が見えると思います。

 (n,1) から出発する。
 左が大きければ操作A:左から右を引き、右に2を足す
 右が大きければ操作B:左は100倍し、右は1を引いて10倍して1を足す

 開平法で次の桁の数を探す作業を、逐次の掛け算ではなく、Σk=0〜n (2k+1)=(n+1)2 とい
う級数公式を用いて逐次の引き算で探しているわけですね。操作Bを行うタイミングの右の
数と開平法の左の数と1ズレるのはこの 2k "+1" のためで、毎回2を足すのは公差2の等
差数列を作るため。

 これを算数的に工夫したのがこの記事の方法で、あらかじめ 5 倍してから計算すること
に 2 つメリットがあります。

 1 つは、右側の数(平方根の 2 倍 +1)がさらに 5 倍することで平方根の 10 倍 +5 となるた
め、計算回数を数えなくても右側の最後の桁以外の部分に求める数字の列が直接現れるこ
と。

 もう 1 つは右で5を引いて10倍して5を足す作業(5倍してあるので)が、級数の公差を2か
ら10にしたことで、0を挟み込むだけの作業で代用できるようになった点。これも掛け算を回
避しています。

 ここからは私の推測ですが、この方法は日本人には実用的価値はありません。開平法の
方が圧倒的に速いですから。しかし、それは日本人(およびアジア圏の人)限定の話。日本
流掛け算割り算の筆算もそうですが、この類の計算手法は3桁×1桁とか4桁×1桁の掛け
算をさらさらっとできることが前提なので、それができない人には日本流は逆に時間がかか
ります。

 欧米は「掛け算するくらいならこの表見ながら足し算した方が速い」といって対数表を作る
ようなところですから、あやふやな九九(という概念もたぶんない)を使って掛け算だらけの開
平法に挑むよりも、足し算引き算0付加だけで済むこっちの方が圧倒的に速いのだろうと思
います。

 多分これを紹介したのは欧米の方だったということなのでしょう。このアルゴリズムの価値
を日本人が体感するには、こんな問題に挑めばいいですね。

【問題】 を八進法で小数第五位まで手計算せよ。

 九九が覚束ない状況で頑張って開平法をするよりは、(4n,4)から八進法の足し算引き算繰
り返す方がきっと速く正確でしょう。

 八進法でやる場合、操作AとBはそれぞれこうなるはずです。

  左が大きければ操作A:左から右を引き、右に10(8)を足す
  右が大きければ操作B:左は100(8)倍し、右は最後の4の前に0を入れる

 ぜひ試してみてください。

                                             投稿一覧に戻る