のび太算考

小学生の頃、算数の問題で「最大公約数を求めなさい」という問題がありました。「70と56の最大公約数は?」とか、「72と120の最大公約数は?」とかです。普通は、両方に共通な約数を見つけ、それで割り、さらに割り切れるものはないかと、繰り返します。

(70,56)の場合は、共通の約数7が見えるので、それで割って(10,8)。さらに2で割って(5,4)。これ以上はないので、7と2の積14が最大公約数と解ります。(72,120)の場合は、いきなり12が見えます。それで割ると(6,10)。さらに2で割って(3,5)で終わり。従って24が最大公約数です。

このようなことをドリルを使って繰り返しやっていると、「14って70-56だな」とか、「24って120-72=48の約数だよな」等に気づき、最大公約数を求める問題では、まず差を求め、その約数から考える裏技を手に入れました。差を取ると小さな数になるような問題が多く、スピード面で有利に働いたと思います。「経験則」みたいなもので、これによって得た答えが、正しいことはすぐに確認できる一方、これが常に正しい方法なのか、正しい場合、どうしてそれでいけるのか等はもやもやとした状態でした。

高校に入ってまもなくの頃、「ユークリッドの互除法」というものを習いました。小学校の頃体得していた裏技にお墨付きができたのと同時に、あの気づきは、「ユークリッドの互除法」の一部品で、これを繰り返し積み上げ、体系化すると「ユークリッドの互除法」ができあがると理解したのを覚えています。


最近これと似た感覚を覚えました。
のび太算は、連分数表現と強い関わりがあったのです。

$${ad-bc=-1}$$を満たす、非負整数$${a,b,c,d}$$を使って作る開区間$${(a/b,c/d)}$$の中で、最も分母が小さい有理数は$${(a+c)/(b+d)}$$です。
これに、連分数表現の性質を考えると、繋がりがあるは(今考えると)当然だったのですが、今回作ったプログラムでそれを知らされました。


プログラムの話に入る前に、のび太算のいくつかの性質について、整理したいと思います。

元祖・のび太算は、マンガ「ドラえもん」の中で、のび太の算数の答案にありそうな答え(分数の足し算を、分子は分子同士の和、分母は分母同士の和として計算)から、「愚かな間違い」的な意味でつかわれていたと思います。

分数の足し算としては、明らかに誤りです。が、この演算は、ある特殊なケースでは利用できます。

その典型例が濃度計算です。
3%の食塩水150グラムと5%の食塩水350グラムを混ぜると何%の食塩水ができるか?このような問題を考えてみましょう。

普通は、前者は食塩4.5グラムと水145.5グラムが混ざったもの。後者は食塩17.5グラムと水332.5グラムが混ざったもの。これらを混ぜると、食塩22グラムと水478グラムになり、22グラムを(478+22)グラムで割って、22/500=4.4%と計算すると思います。

しかし、のび太算を無理矢理利用するならば、前者の食塩水の「量と濃度」を表すものを (150/150)×(3/100)=450/15000 と表現し、後者のそれは、(350/350)×(5/100)=1750/35000と表現し、これらを、のび太算で、
450/15000  +$${_{_{のび太}}}$$ 1750/35000 = (450+1750)/(15000+35000) =2200/50000=(500/500)×(4.4/100)
と計算します。

このままでは、3%と5%を 150:350=3:7 に内分するところを探しただけとも言えますが、さて、どうでしょうか?

何をやったかというと、450/15000 等と書いたもの、これは、一見分数っぽいですが、分数として扱ってはいません。
1750/35000 も(食塩の質量の100倍)と(食塩水の質量の100倍)を / の上と下に書いたものです。(食塩の質量)同士は足すことが可能です。(食塩水の質量)も、全体の質量と考えれば、足すことに違和感はないでしょう。正々堂々とのび太算を行うことができるのです。
分子同士の和を分母同士の和で割ったものと認識するのではなく、食塩の質量の和と全体の質量の和を / の上下に書いたものと考えれば、のび太算が行っている計算に全く問題はありません。

そして、"/" という記号を、分数の横棒と読み替えた場合、その値は、「濃度」という情報に自動的に変換できる付加価値と考えます。

つまり、のび太算の両脇に現れた 450/15000 や 1750/35000 等のオペランドは、食塩の質量と全体の質量を併記したもの。その区切りに "/” を用いていただけで、いざとなれば、分数と認識してもよい、ということです。 

実にくだらない屁理屈ですが、のび太算の性質の一端を見ることができます。のび太算のオペランドは濃度にアナロジーできるものであり、濃度の異なるものを混ぜると、その中間(真ん中という意味ではなく、一定の範囲の中のという意味)の濃度のものができあがるのです。極自然な帰結です。
のび太算がこの性質を有しているのは、

$${(\dfrac{a}{b}-\dfrac{a+c}{b+d}) (\dfrac{a+c}{b+d}-\dfrac{c}{d}) = \dfrac{(ad-bc)^2}{bd(b+d)^2}  ≧  0}$$

から示されます。


ここからは、非負整数$${a,b,c,d}$$が、$${|ad-bc|=1}$$を満たすものとします。対称性から$${ad-bc=-1}$$と固定し、$${a/b < c/d}$$を満たすものとします。なお、この二つの分数の差(=区間$${(\dfrac{a}{b},\dfrac{c}{d})}$$の幅)は、$${c/d-a/b=\frac{bc-ad}{bd}=1/bd}$$であることは気にとめておいて下さい。

四つの格子点$${O(0,0),P(a,b),Q(c,d),R(a+c,b+d)}$$を考えます。区間$${(\dfrac{a}{b},\dfrac{c}{d})}$$の下限$${\dfrac{a}{b}}$$は、直線$${OP}$$の傾き、上限$${\dfrac{c}{d}}$$は、直線$${OQ}$$の傾きに相当します。

この四点は平行四辺形をなし、面積は$${1}$$で、この内部に格子点はありません。内部に格子点を持たない平行四辺形、これを実現する条件が、$${|ad-bc|=1}$$と言えます。

半直線$${OP}$$と半直線$${OQ}$$に挟まれた領域にある全ての格子点は、先ほどの平行四辺形を縦方向、横方向に連ねた結果としてのみ存在します。従ってその領域の格子点は、自然数$${m,n}$$を使って、$${m \vec{P}+n \vec{Q}}$$ と表せます。

区間$${(\dfrac{a}{b},\dfrac{c}{d})}$$にある有理数は、半直線$${OP}$$と半直線$${OQ}$$に挟まれた領域にあるいずれかの格子点と原点を結ぶ直線の傾きに対応できます。この領域の全ての格子点の中で、最も$${x}$$座標が小さいのは、$${m=n=1}$$の時の$${R}$$で、これは、区間$${(\dfrac{a}{b},\dfrac{c}{d})}$$の中の有理数の中で、最も分母が小さいのは、$${\dfrac{a+c}{b+d}}$$であると言うことを意味します。


実数$${x}$$が与えられ、これを有理数で近似する事を考えてみましょう。

ガウス記号$${ [ ] }$$を使って、$${ [ x ] ≦ x  < [ x ]+1 }$$ が成立します。
ここでの目標は、$${ x }$$を有理数で近似することなので、$${ x }$$が整数であることを除外し、$${ [ x ] <   x  <  [ x ]+1 }$$ が成立するとします。

$${a=[ x ],b=1,c=[ x ]+1,d=1}$$として、$${x}$$ は区間$${(\dfrac{a}{b},\dfrac{c}{d})}$$内にあります。この時、$${ad-bc=[x]×1-([x]+1)×1=-1}$$であることを確かめておきます。区間の幅は、$${1/bd}$$で与えられ、スタート時点では当然$${1}$$です。

もし、$${x}$$ が、$${\dfrac{a+c}{b+d}}$$に等しければ、ここで終了。
$${x}$$ が、区間$${(\dfrac{a}{b},\dfrac{a+c}{b+d})}$$と、区間$${(\dfrac{a+c}{b+d},\dfrac{c}{d})}$$のどちらにあるかを判断し、もし下位範囲にあるなら、上限値に関わる値を$${c←a+c,d←b+d}$$と変更、もし上位範囲にあるなら下限値に関わる値を$${a←a+c,b←b+d}$$と変更、以降同じ事を繰り返します。

区間の幅は、$${\dfrac{1}{bd}}$$だったものが、$${\dfrac{1}{b(b+d)}}$$または$${\dfrac{1}{(b+d)d}}$$に変更されるので、狭まることが確認できます。

これを繰り返していくと、$${x}$$ が有理数なら、必ずどこかで終了します。無理数なら無限に続きます。この方法は、$${ad-bc=-1}$$を満たす非負整数によって定まる区間$${(\dfrac{a}{b},\dfrac{c}{d})}$$を、上限と下限ののび太算$${(\dfrac{a+c}{b+d})}$$で分断し、下位側にあるか、上位側にあるか、二分法によって範囲をどんどん狭め、$${x}$$に迫っていく方法です。

これを具体的に行ったのが次のプログラムですが、下位側を何度連続して選択されたか、上位側を何度連続して選択されたか、それを確認できるようにしてあります。

実数→のび太範囲 プログラム


#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int x2nobita(long double x,unsigned long long *p){
    long double xn,err= x*1.0e-18f,dif;
//    long double xn,err= x*1.0e-16f,dif;
    unsigned long long a=p[0],b=p[1],c=p[2],d=p[3],m=a+c,n=b+d;
    int r=0;
    xn=(long double)m/(long double)n;
    dif=x-xn;

    if(dif > err){
        do{
            r++;
            p[0]+=p[2];p[1]+=p[3];
            dif=x-((long double)(p[0]+p[2]))/((long double)(p[1]+p[3]));
        }while(dif > err);
    }else if(dif < -err){
        do{
            r--;
            p[2]+=p[0];p[3]+=p[1];
            dif=x-((long double)(p[0]+p[2]))/((long double)(p[1]+p[3]));
        }while(dif < -err);
    }
    printf("%11llu/%-11llu = %21.19Lf  [%11llu/%-11llu,%11llu/%-11llu]  -- (  % 4d  ) -->\n",m,n,(long double)m/(long double)n,a,b,c,d,r);
    if(p[0]<a || p[1]<b || p[2]<c || p[3]<d)r=0;
    return r;
}

int main(int argc,char *argv[]){
    char buff[300];
    unsigned long long p[4];
    long double x;

    LOOP:
    do{
        x=0.0L;
        printf("\ninput x  (0.1 < x < 10.0) or  return\n");
        if(fgets(buff,256,stdin) == NULL){printf("err\n");goto END;}
        if((sscanf(buff,"%Lf",&x))==-1){printf("return end\n");goto END;}
        printf("%21.19Lf\n",x);       
    }while(x<=0.1L || x>=10.0L);

    p[0]=(unsigned long long)x;p[1]=1L;p[2]=p[0]+1L;p[3]=1L;

    while(x2nobita(x,p)!=0);

    goto LOOP;

    END:
    printf("\n実行時間=%f\nend\n",(double)(clock()/ CLOCKS_PER_SEC));
    return 0;
}

次のような入力をしてみました。3番目は、1234567890を繰り返しています。4番目は$${\sqrt{2}}$$、5番目は円周率、6番目は黄金比です。

1.6666666666666666666666666666
0.625
1.2345678901234567890123456789
1.4142135623730950488016887242
3.1415926535897932384626433832
1.6180339887498948482045868343


input x  (0.1 < x < 10.0) or  return
1.6666666666666666666
          3/2           = 1.5000000000000000000  [          1/1          ,          2/1          ]  -- (     1  ) -->
          5/3           = 1.6666666666666666666  [          3/2          ,          2/1          ]  -- (     0  ) -->

input x  (0.1 < x < 10.0) or  return
0.6250000000000000000
          1/2           = 0.5000000000000000000  [          0/1          ,          1/1          ]  -- (     1  ) -->
          2/3           = 0.6666666666666666667  [          1/2          ,          1/1          ]  -- (    -1  ) -->
          3/5           = 0.6000000000000000000  [          1/2          ,          2/3          ]  -- (     1  ) -->
          5/8           = 0.6250000000000000000  [          3/5          ,          2/3          ]  -- (     0  ) -->

input x  (0.1 < x < 10.0) or  return
1.2345678901234567890
          3/2           = 1.5000000000000000000  [          1/1          ,          2/1          ]  -- (    -3  ) -->
          6/5           = 1.2000000000000000000  [          1/1          ,          5/4          ]  -- (     3  ) -->
         21/17          = 1.2352941176470588235  [         16/13         ,          5/4          ]  -- (    -1  ) -->
         37/30          = 1.2333333333333333333  [         16/13         ,         21/17         ]  -- (     3  ) -->
        100/81          = 1.2345679012345679012  [         79/64         ,         21/17         ]  -- (    -1  ) -->
        179/145         = 1.2344827586206896552  [         79/64         ,        100/81         ]  -- (   13716  ) -->
    1371779/1111141     = 1.2345678901237556710  [    1371679/1111060    ,        100/81         ]  -- (    -1  ) -->
    2743458/2222201     = 1.2345678901233506780  [    1371679/1111060    ,    1371779/1111141    ]  -- (     1  ) -->
    4115237/3333342     = 1.2345678901234856790  [    2743458/2222201    ,    1371779/1111141    ]  -- (    -1  ) -->
    6858695/5555543     = 1.2345678901234316790  [    2743458/2222201    ,    4115237/3333342    ]  -- (     2  ) -->
   15089169/12222227    = 1.2345678901234611336  [   10973932/8888885    ,    4115237/3333342    ]  -- (    -2  ) -->
   37037033/29999997    = 1.2345678901234556790  [   10973932/8888885    ,   26063101/21111112   ]  -- (     4  ) -->
  141289437/114444445   = 1.2345678901234568441  [  115226336/93333333   ,   26063101/21111112   ]  -- (    -2  ) -->
  371742109/301111111   = 1.2345678901234567861  [  115226336/93333333   ,  256515773/207777778  ]  -- (     1  ) -->
  628257882/508888889   = 1.2345678901234567926  [  371742109/301111111  ,  256515773/207777778  ]  -- (    -1  ) -->
  999999991/810000000   = 1.2345678901234567901  [  371742109/301111111  ,  628257882/508888889  ]  -- (     0  ) -->

input x  (0.1 < x < 10.0) or  return
1.4142135623730950488
          3/2           = 1.5000000000000000000  [          1/1          ,          2/1          ]  -- (    -1  ) -->
          4/3           = 1.3333333333333333334  [          1/1          ,          3/2          ]  -- (     2  ) -->
         10/7           = 1.4285714285714285714  [          7/5          ,          3/2          ]  -- (    -2  ) -->
         24/17          = 1.4117647058823529412  [          7/5          ,         17/12         ]  -- (     2  ) -->
         58/41          = 1.4146341463414634146  [         41/29         ,         17/12         ]  -- (    -2  ) -->
        140/99          = 1.4141414141414141414  [         41/29         ,         99/70         ]  -- (     2  ) -->
        338/239         = 1.4142259414225941423  [        239/169        ,         99/70         ]  -- (    -2  ) -->
        816/577         = 1.4142114384748700174  [        239/169        ,        577/408        ]  -- (     2  ) -->
       1970/1393        = 1.4142139267767408471  [       1393/985        ,        577/408        ]  -- (    -2  ) -->
       4756/3363        = 1.4142134998513232234  [       1393/985        ,       3363/2378       ]  -- (     2  ) -->
      11482/8119        = 1.4142135731001354847  [       8119/5741       ,       3363/2378       ]  -- (    -2  ) -->
      27720/19601       = 1.4142135605326258864  [       8119/5741       ,      19601/13860      ]  -- (     2  ) -->
      66922/47321       = 1.4142135626888696350  [      47321/33461      ,      19601/13860      ]  -- (    -2  ) -->
     161564/114243      = 1.4142135623189166951  [      47321/33461      ,     114243/80782      ]  -- (     2  ) -->
     390050/275807      = 1.4142135623823905847  [     275807/195025     ,     114243/80782      ]  -- (    -2  ) -->
     941664/665857      = 1.4142135623715001869  [     275807/195025     ,     665857/470832     ]  -- (     2  ) -->
    2273378/1607521     = 1.4142135623733686838  [    1607521/1136689    ,     665857/470832     ]  -- (    -2  ) -->
    5488420/3880899     = 1.4142135623730481004  [    1607521/1136689    ,    3880899/2744210    ]  -- (     2  ) -->
   13250218/9369319     = 1.4142135623731031038  [    9369319/6625109    ,    3880899/2744210    ]  -- (    -2  ) -->
   31988856/22619537    = 1.4142135623730936667  [    9369319/6625109    ,   22619537/15994428   ]  -- (     2  ) -->
   77227930/54608393    = 1.4142135623730952859  [   54608393/38613965   ,   22619537/15994428   ]  -- (    -2  ) -->
  186444716/131836323   = 1.4142135623730950081  [   54608393/38613965   ,  131836323/93222358   ]  -- (     2  ) -->
  450117362/318281039   = 1.4142135623730950558  [  318281039/225058681  ,  131836323/93222358   ]  -- (    -1  ) -->
  768398401/543339720   = 1.4142135623730950500  [  318281039/225058681  ,  450117362/318281039  ]  -- (     0  ) -->

input x  (0.1 < x < 10.0) or  return
3.1415926535897932385
          7/2           = 3.5000000000000000000  [          3/1          ,          4/1          ]  -- (    -6  ) -->
         25/8           = 3.1250000000000000000  [          3/1          ,         22/7          ]  -- (    15  ) -->
        355/113         = 3.1415929203539823009  [        333/106        ,         22/7          ]  -- (    -1  ) -->
        688/219         = 3.1415525114155251141  [        333/106        ,        355/113        ]  -- (   292  ) -->
     104348/33215       = 3.1415926539214210447  [     103993/33102      ,        355/113        ]  -- (    -1  ) -->
     208341/66317       = 3.1415926534674367056  [     103993/33102      ,     104348/33215      ]  -- (     1  ) -->
     312689/99532       = 3.1415926536189366235  [     208341/66317      ,     104348/33215      ]  -- (    -1  ) -->
     521030/165849      = 3.1415926535583573009  [     208341/66317      ,     312689/99532      ]  -- (     2  ) -->
    1146408/364913      = 3.1415926535914039785  [     833719/265381     ,     312689/99532      ]  -- (    -1  ) -->
    1980127/630294      = 3.1415926535870561992  [     833719/265381     ,    1146408/364913     ]  -- (     3  ) -->
    5419351/1725033     = 3.1415926535898153833  [    4272943/1360120    ,    1146408/364913     ]  -- (    -1  ) -->
    9692294/3085153     = 3.1415926535896274837  [    4272943/1360120    ,    5419351/1725033    ]  -- (    14  ) -->
   85563208/27235615    = 3.1415926535897940987  [   80143857/25510582   ,    5419351/1725033    ]  -- (    -2  ) -->
  245850922/78256779    = 3.1415926535897931602  [   80143857/25510582   ,  165707065/52746197   ]  -- (     1  ) -->
  411557987/131002976   = 3.1415926535897932578  [  245850922/78256779   ,  165707065/52746197   ]  -- (    -1  ) -->
  657408909/209259755   = 3.1415926535897932214  [  245850922/78256779   ,  411557987/131002976  ]  -- (     1  ) -->
 1068966896/340262731   = 3.1415926535897932355  [  657408909/209259755  ,  411557987/131002976  ]  -- (     0  ) -->

input x  (0.1 < x < 10.0) or  return
1.6180339887498948482
          3/2           = 1.5000000000000000000  [          1/1          ,          2/1          ]  -- (     1  ) -->
          5/3           = 1.6666666666666666666  [          3/2          ,          2/1          ]  -- (    -1  ) -->
          8/5           = 1.6000000000000000000  [          3/2          ,          5/3          ]  -- (     1  ) -->
         13/8           = 1.6250000000000000000  [          8/5          ,          5/3          ]  -- (    -1  ) -->
         21/13          = 1.6153846153846153846  [          8/5          ,         13/8          ]  -- (     1  ) -->
         34/21          = 1.6190476190476190476  [         21/13         ,         13/8          ]  -- (    -1  ) -->
         55/34          = 1.6176470588235294118  [         21/13         ,         34/21         ]  -- (     1  ) -->
         89/55          = 1.6181818181818181818  [         55/34         ,         34/21         ]  -- (    -1  ) -->
        144/89          = 1.6179775280898876404  [         55/34         ,         89/55         ]  -- (     1  ) -->
        233/144         = 1.6180555555555555555  [        144/89         ,         89/55         ]  -- (    -1  ) -->
        377/233         = 1.6180257510729613734  [        144/89         ,        233/144        ]  -- (     1  ) -->
        610/377         = 1.6180371352785145888  [        377/233        ,        233/144        ]  -- (    -1  ) -->
        987/610         = 1.6180327868852459016  [        377/233        ,        610/377        ]  -- (     1  ) -->
       1597/987         = 1.6180344478216818643  [        987/610        ,        610/377        ]  -- (    -1  ) -->
       2584/1597        = 1.6180338134001252348  [        987/610        ,       1597/987        ]  -- (     1  ) -->
       4181/2584        = 1.6180340557275541796  [       2584/1597       ,       1597/987        ]  -- (    -1  ) -->
       6765/4181        = 1.6180339631667065295  [       2584/1597       ,       4181/2584       ]  -- (     1  ) -->
      10946/6765        = 1.6180339985218033999  [       6765/4181       ,       4181/2584       ]  -- (    -1  ) -->
      17711/10946       = 1.6180339850173579390  [       6765/4181       ,      10946/6765       ]  -- (     1  ) -->
      28657/17711       = 1.6180339901755970865  [      17711/10946      ,      10946/6765       ]  -- (    -1  ) -->
      46368/28657       = 1.6180339882053250515  [      17711/10946      ,      28657/17711      ]  -- (     1  ) -->
      75025/46368       = 1.6180339889579020014  [      46368/28657      ,      28657/17711      ]  -- (    -1  ) -->
     121393/75025       = 1.6180339886704431856  [      46368/28657      ,      75025/46368      ]  -- (     1  ) -->
     196418/121393      = 1.6180339887802426828  [     121393/75025      ,      75025/46368      ]  -- (    -1  ) -->
     317811/196418      = 1.6180339887383030069  [     121393/75025      ,     196418/121393     ]  -- (     1  ) -->
     514229/317811      = 1.6180339887543225377  [     317811/196418     ,     196418/121393     ]  -- (    -1  ) -->
     832040/514229      = 1.6180339887482036213  [     317811/196418     ,     514229/317811     ]  -- (     1  ) -->
    1346269/832040      = 1.6180339887505408394  [     832040/514229     ,     514229/317811     ]  -- (    -1  ) -->
    2178309/1346269     = 1.6180339887496481016  [     832040/514229     ,    1346269/832040     ]  -- (     1  ) -->
    3524578/2178309     = 1.6180339887499890970  [    2178309/1346269    ,    1346269/832040     ]  -- (    -1  ) -->
    5702887/3524578     = 1.6180339887498588484  [    2178309/1346269    ,    3524578/2178309    ]  -- (     1  ) -->
    9227465/5702887     = 1.6180339887499085989  [    5702887/3524578    ,    3524578/2178309    ]  -- (    -1  ) -->
   14930352/9227465     = 1.6180339887498895959  [    5702887/3524578    ,    9227465/5702887    ]  -- (     1  ) -->
   24157817/14930352    = 1.6180339887498968544  [   14930352/9227465    ,    9227465/5702887    ]  -- (    -1  ) -->
   39088169/24157817    = 1.6180339887498940819  [   14930352/9227465    ,   24157817/14930352   ]  -- (     1  ) -->
   63245986/39088169    = 1.6180339887498951409  [   39088169/24157817   ,   24157817/14930352   ]  -- (    -1  ) -->
  102334155/63245986    = 1.6180339887498947364  [   39088169/24157817   ,   63245986/39088169   ]  -- (     1  ) -->
  165580141/102334155   = 1.6180339887498948909  [  102334155/63245986   ,   63245986/39088169   ]  -- (    -1  ) -->
  267914296/165580141   = 1.6180339887498948319  [  102334155/63245986   ,  165580141/102334155  ]  -- (     1  ) -->
  433494437/267914296   = 1.6180339887498948544  [  267914296/165580141  ,  165580141/102334155  ]  -- (    -1  ) -->
  701408733/433494437   = 1.6180339887498948458  [  267914296/165580141  ,  433494437/267914296  ]  -- (     1  ) -->
 1134903170/701408733   = 1.6180339887498948491  [  701408733/433494437  ,  433494437/267914296  ]  -- (     0  ) -->

input x  (0.1 < x < 10.0) or  return
return end

実行時間=0.000000
end


注目して欲しいのは、画面右端の方。
$${r}$$回連続して下位区間が選ばれたら$${-r}$$、$${r}$$回連続して上位区間が選ばれたら$${r}$$を記しています。

この$${r}$$の値が、$${\sqrt{2}}$$では、2と-2の繰り返し、黄金比では1と-1の繰り返し、円周率では符号を除くと、6,15,1,292,1,1,1,2,1,3,1,14,2,1となっています。円周率の最初の6以外は、それぞれの、連分数表示に一致します。(円周率の場合は7)


図らず、この結果を目の当たりにし、考えてみれば、そりゃそうだよなと、納得に至りました。$${ad-bc=-1}$$を満たすのび太算では、その範囲内で最も分母の小さい分数が現れます。その後、上位側の範囲が選択されるか、下位側の範囲が選択されるかで、次ののび太算の結果が変化していきますが、分母は、着実に大きくなっていきます。連分数表示も、結局はそれを意図した表現方法で、最短で近づいていく方法です。

これは、$${a}$$と$${b}$$の最大公約数は、$${a-b}$$の公約数でもあるという小学校の頃の気づきと、大きい方を小さい方で割った時の剰余の公約数でもあるというユークリッドの互除法の教えの関係に似ていて、高校入学まもなくの頃の感覚を思い起こしたわけです。



$${ad-bc=-1}$$を満たす$${a/b}$$と$${c/d}$$に対し、

$${\dfrac{k}{k} \dfrac{a}{b}  +{_{_{のび太}}}  \dfrac{c}{d} = \dfrac{ka+c}{kb+d}}$$

あるいは

$${\dfrac{a}{b}  +{_{_{のび太}}}   \dfrac{k}{k} \dfrac{c}{d} = \dfrac{a+kc}{b+kd}}$$

等を、「$${a/b}$$(あるいは$${c/d}$$)に$${k}$$の重みを持たせたのび太算」、あるいは単に「重み付きのび太算」と呼ぶことにすると、連分数表記の深さを一つ増やすことは、重み付きのび太算を行うことに相当します。

連分数表記では、カウントアップする毎に、正または、負の方向から、真の値に値に近づき、真の値を超えてしまった時、そこで終了し、一つ深い段階に移ります。そして先ほどとは逆方向から、真の値に近づくべく、新たなカウントアップが始まります。

黄金比を求める際の、のび太範囲の変遷は、
(1/1,2/1)→(3/2,2/1)→(3/2,5/3)→(8/5,5/3)→(8/5,13/8)→(21/13,13/8)→…
のように、上範囲、下範囲を交互に繰り返します。

円周率では、
(3/1,4/1)
→(下位6回):(3/1,(6*3+4)/(6*1+1))=(3/1,22/7)
→(上位15回):((15*22+3)/(15*7+1),22/7)=(333/106,22/7)
→(下位1回):(333/106,(1*22+333)/(1*7+106))=(333/106,355/113)
→(上位292回):(292*333+355)/(292*106+113),355/113)=(103993/33102,355/113)
のようになり、同じ方向に連続する偏った動きをしていることが解ります。
連続する動きが続くと言うことは、直前の値が目的の値に近かったことを意味します。改めて、22/7や355/113は円周率の近似値として優秀であることを確認できます。



#のび太算 #連分数 #連分数表示 #円周率 #黄金比 #格子点 #面積 #ピックの定理 #ユークリッドの互除法 #数学がすき


この記事が参加している募集

数学がすき

この記事が気に入ったらサポートをしてみませんか?