Quantcast
Channel: 円周率近似値の日に生まれて理系じゃないわけないだろ! - knifeのblog
Viewing all articles
Browse latest Browse all 5376

連分数計算のプログラムを作る

$
0
0

午後のひとときに、連分数を計算するプログラムを作ってみる。

昨日の続きですね。

renbunsuukeisan.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>

int main(int argc, char *argv[])
{
    unsigned long long u,l,t,u2,u5,l2,l5;
    int i,j,k;

    if (argc == 1) return EXIT_SUCCESS;    

    u = atoll(argv[1]);
    l = 1;
    printf("%19llu / %19llu = %d\n",u,l,u);
    
    for (i=2; i<=argc-1; i++) {
        u = atoll(argv[i]);
        l = 1;
        for (j=i-1; j>0; j--) {
            t = l;
            l = u;
            u = t;
            u += l*atoll(argv[j]);
            if ( u > ULONG_LONG_MAX/10 ) return EXIT_SUCCESS;
        }
        printf("%19llu / %19llu = %d",u,l,u/l);

        if ( u == 0 ) {
            k = 1;
        } else {
            k = log10((double)u/l);
        }

        if ( u%l == 0 ) {
            printf("\n");
            continue;
        }

        printf(".");
        u %= l;

        u2 = u5 = u;
        l2 = l5 = l;
        while ( u2%2 == 0 && l2%2 == 0 ) {
            u2/=2;
            l2/=2;
        }
        while ( u5%5 == 0 && l5%5 == 0 ) {
            u5/=5;
            l5/=5;
        }
        while ( (l2%2)*(l5%5) == 0 && u != 0 && k < 50 ) {
            k++;
            if ( u*10 < u ) {
                printf(" break 1 u=%llu l=%llu\n",u,l);
                return EXIT_SUCCESS;
            }
            u *= 10;
            printf("%d",u/l);
            u %= l;
            if ( l2%2 == 0 ) l2 /= 2;
            if ( l5%5 == 0 ) l5 /= 5;
        }

        if ( u == 0 ) {
            printf("\n");
            continue;
        }

        do {
            k ++;
            if ( u*10 < u ) {
                return EXIT_SUCCESS;
            }
            u *= 10;
            printf("%d",u/l);
            u %= l;
        } while ( k < 50 );
        printf("\n");
    }

    return EXIT_SUCCESS;
}

パラメーターに数列を入れます。
但し、循環節には対応させていません。
沢山のパラメータを与えれば、それだけ精密に計算してくれますが、分子がオーバーフローする手前で計算をやめますので、それ以上パラメータを与えても計算しません。
最大で小数点以下50桁を表示しますが、そこまで精度は出ないかと思います。

円周率π
> renbunsuukeisan 3 7 15 1 292 1 1 1 2 1 3 1 14 2 1 1 2 2 2 2 1 84 2 1 1 15 3 13 1 4 2
                  3 /                   1 = 3
                 22 /                   7 = 3.14285714285714285714285714285714285714285714285714
                333 /                 106 = 3.14150943396226415094339622641509433962264150943396
                355 /                 113 = 3.14159292035398230088495575221238938053097345132743
             103993 /               33102 = 3.14159265301190260407226149477372968400700863996133
             104348 /               33215 = 3.14159265392142104470871594159265392142104470871594
             208341 /               66317 = 3.14159265346743670552045478534915632492422757362365
             312689 /               99532 = 3.14159265361893662339750030141060161556082465940602
             833719 /              265381 = 3.14159265358107777120441930658185778183065102626035
            1146408 /              364913 = 3.14159265359140397848254241421927966391989323482583
            4272943 /             1360120 = 3.14159265358938917154368732170690821398111931300179
            5419351 /             1725033 = 3.14159265358981538324194377730744861112801900021622
           80143857 /            25510582 = 3.14159265358979265937562694571217544154813872925360
          165707065 /            52746197 = 3.14159265358979340254615892023457160333284312421614
          245850922 /            78256779 = 3.14159265358979316028327718420406748404505633946421
          411557987 /           131002976 = 3.14159265358979325782644815641440084536705486751690
         1068966896 /           340262731 = 3.14159265358979323539256492948091926059336777614942
         2549491779 /           811528438 = 3.14159265358979323901400975919959073572231365230358
         6167950454 /          1963319607 = 3.14159265358979323838637750639037956696777388216650
        14885392687 /          4738167652 = 3.14159265358979323849387505801156062596832738665617
        21053343141 /          6701487259 = 3.14159265358979323846238174277486901359488207302730
      1783366216531 /        567663097408 = 3.14159265358979323846264461102927921823330023329103
      3587785776203 /       1142027682075 = 3.14159265358979323846264306850252143875993269670411
      5371151992734 /       1709690779483 = 3.14159265358979323846264358066268961876404956275251
      8958937768937 /       2851718461558 = 3.14159265358979323846264337555790890412119362139949
    139755218526789 /      44485467702853 = 3.14159265358979323846264338344061241435579945092592
    428224593349304 /     136308121570117 = 3.14159265358979323846264338327569743446914073265493
   5706674932067741 /    1816491048114374 = 3.14159265358979323846264338327973616618713083563102
   6134899525417045 /    1952799169684491 = 3.14159265358979323846264338327945425704739383578638
  30246273033735921 /    9627687726852338 = 3.14159265358979323846264338327950744587561949997933
  66627445592888887 /   21208174623389167 = 3.14159265358979323846264338327950254837258399500294

3.141592653589793238462643383279502
まで正しい値を示しています。

ネイピア数e
> renbunsuukeisan 2 1 2 1 1 4 1 1 6 1 1 8 1 1 10 1 1 12 1 1 14 1 1 16 1 1 18 1 1 20 1 1 22 1 1 24 1 1
                  2 /                   1 = 2
                  3 /                   1 = 3
                  8 /                   3 = 2.66666666666666666666666666666666666666666666666666
                 11 /                   4 = 2.75
                 19 /                   7 = 2.71428571428571428571428571428571428571428571428571
                 87 /                  32 = 2.71875
                106 /                  39 = 2.71794871794871794871794871794871794871794871794871
                193 /                  71 = 2.71830985915492957746478873239436619718309859154929
               1264 /                 465 = 2.71827956989247311827956989247311827956989247311827
               1457 /                 536 = 2.71828358208955223880597014925373134328358208955223
               2721 /                1001 = 2.71828171828171828171828171828171828171828171828171
              23225 /                8544 = 2.71828183520599250936329588014981273408239700374531
              25946 /                9545 = 2.71828182294394971189104243059193294918805657412257
              49171 /               18089 = 2.71828182873569572668472552379899386367405605616673
             517656 /              190435 = 2.71828182844540131803502507417228975766009399532648
             566827 /              208524 = 2.71828182847058372177782893096238322687076787324240
            1084483 /              398959 = 2.71828182845856341127785060620264237678558448361861
           13580623 /             4996032 = 2.71828182845906511407452954664822002741375555640956
           14665106 /             5394991 = 2.71828182845902801320706559102693591147788754420535
           28245729 /            10391023 = 2.71828182845904585140462108494996113472176897308378
          410105312 /           150869313 = 2.71828182845904521352198375822126266326936876818680
          438351041 /           161260336 = 2.71828182845904525462479502709209287521266233750126
          848456353 /           312129649 = 2.71828182845904523475756063147977332970377319073587
        14013652689 /          5155334720 = 2.71828182845904523537901337277281580661361984270926
        14862109042 /          5467464369 = 2.71828182845904523534353553278730109635580507612083
        28875761731 /         10622799089 = 2.71828182845904523536075323018848069263338394670075
       534625820200 /        196677847971 = 2.71828182845904523536027459394129614039857497358603
       563501581931 /        207300647060 = 2.71828182845904523536029912091100252448965993111743
      1098127402131 /        403978495031 = 2.71828182845904523536028717990008625935174427034809
     22526049624551 /       8286870547680 = 2.71828182845904523536028747861107435187070618550208
     23624177026682 /       8690849042711 = 2.71828182845904523536028746472603103495256774869070
     46150226651233 /      16977719590391 = 2.71828182845904523536028747150335798417095820512306
   1038929163353808 /     382200680031313 = 2.71828182845904523536028747134924856337158002893962
   1085079390005041 /     399178399621704 = 2.71828182845904523536028747135580309271246862746269
   2124008553358849 /     781379079653017 = 2.71828182845904523536028747135259703609205685078531
  52061284670617417 /   19152276311294112 = 2.71828182845904523536028747135266385783846606741049
  54185293223976266 /   19933655390947129 = 2.71828182845904523536028747135266123849376054222268
 106246577894593683 /   39085931702241241 = 2.71828182845904523536028747135266252198404387265932

2.718281828459045235360287471352662
まで正しい値を示しています。

黄金比φ
> renbunsuukeisan 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
                  1 /                   1 = 1
                  2 /                   1 = 2
                  3 /                   2 = 1.5
                  5 /                   3 = 1.66666666666666666666666666666666666666666666666666
                  8 /                   5 = 1.6
                 13 /                   8 = 1.625
                 21 /                  13 = 1.61538461538461538461538461538461538461538461538461
                 34 /                  21 = 1.61904761904761904761904761904761904761904761904761
                 55 /                  34 = 1.61764705882352941176470588235294117647058823529411
                 89 /                  55 = 1.61818181818181818181818181818181818181818181818181
                144 /                  89 = 1.61797752808988764044943820224719101123595505617977
                233 /                 144 = 1.61805555555555555555555555555555555555555555555555
                377 /                 233 = 1.61802575107296137339055793991416309012875536480686
                610 /                 377 = 1.61803713527851458885941644562334217506631299734748
                987 /                 610 = 1.61803278688524590163934426229508196721311475409836
               1597 /                 987 = 1.61803444782168186423505572441742654508611955420466
               2584 /                1597 = 1.61803381340012523481527864746399499060738885410144
               4181 /                2584 = 1.61803405572755417956656346749226006191950464396284
               6765 /                4181 = 1.61803396316670652953838794546759148529060033484812
              10946 /                6765 = 1.61803399852180339985218033998521803399852180339985
              17711 /               10946 = 1.61803398501735793897314087337840306961447103964918
              28657 /               17711 = 1.61803399017559708655637739258088193777878154819039
              46368 /               28657 = 1.61803398820532505147084481976480441078968489374323
              75025 /               46368 = 1.61803398895790200138026224982746721877156659765355
             121393 /               75025 = 1.61803398867044318560479840053315561479506831056314
             196418 /              121393 = 1.61803398878024268285650737686687041262675772079114
             317811 /              196418 = 1.61803398873830300685273243796393405899662963679499
             514229 /              317811 = 1.61803398875432253760883040549257262964466302299165
             832040 /              514229 = 1.61803398874820362134379819107829391185639082976650
            1346269 /              832040 = 1.61803398875054083938272198451997500120186529493774
            2178309 /             1346269 = 1.61803398874964810153097189343288748385352407282645
            3524578 /             2178309 = 1.61803398874998909704729677929072505324083956867460
            5702887 /             3524578 = 1.61803398874985884835007198024841555499693864059754
            9227465 /             5702887 = 1.61803398874990859892542145758806022283099770344388
           14930352 /             9227465 = 1.61803398874988959589659781966119622236443053427999
           24157817 /            14930352 = 1.61803398874989685440771925537991334698605900249371
           39088169 /            24157817 = 1.61803398874989408190317858604525400618772797227497
           63245986 /            39088169 = 1.61803398874989514090567915831514134110502848061263
          102334155 /            63245986 = 1.61803398874989473640271811083789570455902134247697
          165580141 /           102334155 = 1.61803398874989489090910068099941803398874989489090
          267914296 /           165580141 = 1.61803398874989483189291401799204893780106154155286
          433494437 /           267914296 = 1.61803398874989485443509143685262693111382156329574
          701408733 /           433494437 = 1.61803398874989484582474584327826103106370428462960
         1134903170 /           701408733 = 1.61803398874989484911360520514078058962519361731414
         1836311903 /          1134903170 = 1.61803398874989484785737271312758779235765109370520
         2971215073 /          1836311903 = 1.61803398874989484833721082730464662244254918386813
         4807526976 /          2971215073 = 1.61803398874989484815392897678666292899490820535427
         7778742049 /          4807526976 = 1.61803398874989484822393641416355517918574857727433
        12586269025 /          7778742049 = 1.61803398874989484819719595255086212205106635745185
        20365011074 /         12586269025 = 1.61803398874989484820740990001204904326284254042472
        32951280099 /         20365011074 = 1.61803398874989484820350851924118133676198756188312
        53316291173 /         32951280099 = 1.61803398874989484820499871409259753505274587299122
        86267571272 /         53316291173 = 1.61803398874989484820442951030921664668132147684713
       139583862445 /         86267571272 = 1.61803398874989484820464692680794311350483570618540
       225851433717 /        139583862445 = 1.61803398874989484820456388109514460140571731977480
       365435296162 /        225851433717 = 1.61803398874989484820459560173481367087955823587515
       591286729879 /        365435296162 = 1.61803398874989484820458348552860497455715387197229
       956722026041 /        591286729879 = 1.61803398874989484820458811350756199405052604728692
      1548008755920 /        956722026041 = 1.61803398874989484820458634577689963189281388520305
      2504730781961 /       1548008755920 = 1.61803398874989484820458702098992969887257819613379
      4052739537881 /       2504730781961 = 1.61803398874989484820458676308150186009099742542452
      6557470319842 /       4052739537881 = 1.61803398874989484820458686159375530945597542662147
     10610209857723 /       6557470319842 = 1.61803398874989484820458682396542280014262219373987
     17167680177565 /      10610209857723 = 1.61803398874989484820458683833816687871770389118771
     27777890035288 /      17167680177565 = 1.61803398874989484820458683284826715230581203172580
     44945570212853 /      27777890035288 = 1.61803398874989484820458683494522225296640591266368
     72723460248141 /      44945570212853 = 1.61803398874989484820458683414425667739651612931195
    117669030460994 /      72723460248141 = 1.61803398874989484820458683445019830344559159842927
    190392490709135 /     117669030460994 = 1.61803398874989484820458683433333900086825497442903
    308061521170129 /     190392490709135 = 1.61803398874989484820458683437797528255118937731242
    498454011879264 /     308061521170129 = 1.61803398874989484820458683436092574007972279266249
    806515533049393 /     498454011879264 = 1.61803398874989484820458683436743808581118814372889
   1304969544928657 /     806515533049393 = 1.61803398874989484820458683436495059108825867517963
   2111485077978050 /    1304969544928657 = 1.61803398874989484820458683436590072952558172976101
   3416454622906707 /    2111485077978050 = 1.61803398874989484820458683436553780893654203456613
   5527939700884757 /    3416454622906707 = 1.61803398874989484820458683436567643226633806556939
   8944394323791464 /    5527939700884757 = 1.61803398874989484820458683436562348286598966775450
  14472334024676221 /    8944394323791464 = 1.61803398874989484820458683436564370773723883019590
  23416728348467685 /   14472334024676221 = 1.61803398874989484820458683436563598252383974068658
  37889062373143906 /   23416728348467685 = 1.61803398874989484820458683436563893329278784677316
  61305790721611591 /   37889062373143906 = 1.61803398874989484820458683436563780619934261802274
  99194853094755497 /   61305790721611591 = 1.61803398874989484820458683436563823671073019818740
 160500643816367088 /   99194853094755497 = 1.61803398874989484820458683436563807227001268644385
 259695496911122585 /  160500643816367088 = 1.61803398874989484820458683436563813508077764150985
 420196140727489673 /  259695496911122585 = 1.61803398874989484820458683436563811108920028805540
 679891637638612258 /  420196140727489673 = 1.61803398874989484820458683436563812025316739335275
1100087778366101931 /  679891637638612258 = 1.61803398874989484820458683436563811675284343091515
1779979416004714189 / 1100087778366101931 = 1.61803398874989484820458683436563811808984821293060

1.61803398874989484820458683436563811
まで正しい値を示しています。


分子を10倍して、分母で割って、分母の剰余を取って、1桁ずつ求めているんだけど、循環節もちゃんと考えているから、ちょっとプログラム的に長くなっているけど、long doubleの精度が十分に出るなら、こんな面倒な計算をさせないんだけれどもね。

どのみち、オーバーフローする手前までやらすだけなので、連分数の循環節には対応させなかったけれども、これで十分かな。


ではでは

 


Viewing all articles
Browse latest Browse all 5376

Trending Articles