寫程式有感

先前我寫了一篇文章 ( 圓周率的估計值,內裏我寫了一些程式顯示結果:

1. 隨著分母增加,一個迫近於圓周率的有理數數列。
程式碼

#!/usr/bin/env python
import math
from fractions import Fraction
 
# i=7, j=22,我把第一個數的分母設為7,分子設為22,以作為開始的項。
 
i=7 
j=22
counter=1
temp_denominator=1
temp_numerator=1
error_range=math.fabs(math.pi - j/i)
F=open('output','w') # 結果顯示在一個名為output 的文字檔。
F.write("||"+str(counter)+"||"+str(j)+"||"+str(i)+"||"+str(j/i)+"||"+str(error_range)+"||"+"\n")
i=i+1
counter=counter+1
while i <= 200000: # 測試所有分母小於或等於 200000 的情況
    temp_result=Fraction(math.pi).limit_denominator(i)
    temp_denominator=temp_result.denominator
    temp_numerator=temp_result.numerator
    if temp_denominator == i:
        i=temp_denominator
        j=temp_numerator
        error_range=math.fabs(math.pi - j/i)
        F=open('output','a')
        F.write("||"+str(counter)+"||"+str(j)+"||"+str(i)+"||"+str(j/i)+"||"+str(error_range)+"||"+"\n")
        counter=counter+1
 
    i=i+1
F.close()

此程式我在 Linux (32 bit) 上執行,而且是 python 3.2。
如在 windows 或其他 os 上執行,或用 python 2.x,請自行稍作修改。

分母去到78256779的結果:

次序 分子 分母 以小數表示 與 π 的絕對誤差
1 22 7 3.142857142857143 0.0012644892673496777
2 179 57 3.1403508771929824 0.0012417763968106676
3 201 64 3.140625 0.000967653589793116
4 223 71 3.140845070422535 0.0007475831672580924
5 245 78 3.141025641025641 0.0005670125641521473
6 267 85 3.1411764705882352 0.00041618300155787935
7 289 92 3.141304347826087 0.0002883057637061981
8 311 99 3.1414141414141414 0.00017851217565167943
9 333 106 3.141509433962264 8.32196275291075e-05
10 355 113 3.1415929203539825 2.667641894049666e-07
11 52163 16604 3.141592387376536 2.662132572162079e-07
12 52518 16717 3.1415923909792425 2.6261055063869776e-07
13 52873 16830 3.141592394533571 2.5905622225153024e-07
14 53228 16943 3.1415923980404887 2.555493043843171e-07
15 53583 17056 3.141592401500938 2.5208885512384427e-07
16 53938 17169 3.1415924049158366 2.4867395653771496e-07
17 54293 17282 3.141592408286078 2.4530371511843896e-07
18 54648 17395 3.141592411612532 2.419772608952542e-07
19 55003 17508 3.1415924148960475 2.386937456577698e-07
20 55358 17621 3.1415924181374497 2.354523434000555e-07
21 55713 17734 3.1415924213375437 2.3225224943246303e-07
22 56068 17847 3.1415924244971145 2.2909267860526938e-07
23 56423 17960 3.1415924276169265 2.259728666409444e-07
24 56778 18073 3.141592430697726 2.2289206702552633e-07
25 57133 18186 3.14159243374024 2.1984955322906785e-07
26 57488 18299 3.1415924367451775 2.1684461559701163e-07
27 57843 18412 3.1415924397132304 2.1387656268245792e-07
28 58198 18525 3.141592442645074 2.1094471902571854e-07
29 58553 18638 3.141592445541367 2.080484260424953e-07
30 58908 18751 3.141592448402752 2.0518704113570152e-07
31 59263 18864 3.141592451229856 2.023599372513729e-07
32 59618 18977 3.1415924540232916 1.9956650154639988e-07
33 59973 19090 3.1415924567836564 1.9680613672079517e-07
34 60328 19203 3.1415924595115348 1.9407825835315862e-07
35 60683 19316 3.1415924622074964 1.91382296677034e-07
36 61038 19429 3.1415924648720983 1.8871769480455214e-07
37 61393 19542 3.141592467505885 1.8608390828234178e-07
38 61748 19655 3.141592470109387 1.8348040597970794e-07
39 62103 19768 3.1415924726831244 1.809066687563643e-07
40 62458 19881 3.141592475227604 1.78362189018344e-07
41 62813 19994 3.141592477743323 1.7584647027391043e-07
42 63168 20107 3.1415924802307655 1.7335902757764643e-07
43 63523 20220 3.1415924826904056 1.708993875304543e-07
44 63878 20333 3.141592485122707 1.6846708605910976e-07
45 64233 20446 3.141592487528123 1.6606167019261875e-07
46 64588 20559 3.141592489907097 1.6368269628586063e-07
47 64943 20672 3.1415924922600618 1.613297313518558e-07
48 65298 20785 3.1415924945874427 1.5900235039723043e-07
49 65653 20898 3.1415924968896545 1.5670013864266252e-07
50 66008 21011 3.141592499167103 1.5442269019061428e-07
51 66363 21124 3.1415925014201855 1.5216960758124287e-07
52 66718 21237 3.1415925036492913 1.4994050179240048e-07
53 67073 21350 3.141592505854801 1.4773499223963427e-07
54 67428 21463 3.1415925080370872 1.4555270588800795e-07
55 67783 21576 3.1415925101965145 1.4339327858436945e-07
56 68138 21689 3.1415925123334407 1.4125635239281564e-07
57 68493 21802 3.1415925144482157 1.3914157737104915e-07
58 68848 21915 3.141592516541182 1.370486111262892e-07
59 69203 22028 3.1415925186126747 1.3497711837118231e-07
60 69558 22141 3.1415925206630235 1.3292676959153482e-07
61 69913 22254 3.14159252269255 1.3089724326675878e-07
62 70268 22367 3.1415925247015695 1.2888822364942598e-07
63 70623 22480 3.1415925266903915 1.2689940165344638e-07
64 70978 22593 3.141592528659319 1.2493047396588963e-07
65 71333 22706 3.1415925306086496 1.2298114349107436e-07
66 71688 22819 3.1415925325386738 1.2105111935056811e-07
67 72043 22932 3.141592534449677 1.1914011599500895e-07
68 72398 23045 3.1415925363419395 1.1724785364819468e-07
69 72753 23158 3.1415925382157353 1.153740578629936e-07
70 73108 23271 3.1415925400713336 1.1351845952134454e-07
71 73463 23384 3.1415925419089974 1.1168079572243528e-07
72 73818 23497 3.141592543728987 1.0986080622998884e-07
73 74173 23610 3.1415925455315543 1.0805823880133403e-07
74 74528 23723 3.1415925473169497 1.062728434142457e-07
75 74883 23836 3.141592549085417 1.0450437626374764e-07
76 75238 23949 3.1415925508371956 1.0275259754166655e-07
77 75593 24062 3.141592552572521 1.0101727232481039e-07
78 75948 24175 3.1415925542916234 9.929816968679006e-08
79 76303 24288 3.14159255599473 9.759506314210853e-08
80 76658 24401 3.141592557682062 9.590773109025008e-08
81 77013 24514 3.1415925593538385 9.423595459523426e-08
82 77368 24627 3.141592561010273 9.257952005015113e-08
83 77723 24740 3.1415925626515766 9.093821651262601e-08
84 78078 24853 3.1415925642779543 8.931183881344396e-08
85 78433 24966 3.14159256588961 8.770018311565764e-08
86 78788 25079 3.1415925674867418 8.610305135547947e-08
87 79143 25192 3.141592569069546 8.452024724547869e-08
88 79498 25305 3.1415925706382137 8.295157938320585e-08
89 79853 25418 3.141592572192934 8.139685903074678e-08
90 80208 25531 3.141592573733892 7.985590100290096e-08
91 80563 25644 3.14159257526127 7.832852322309236e-08
92 80918 25757 3.1415925767752455 7.681454761154782e-08
93 81273 25870 3.1415925782759953 7.531379786485104e-08
94 81628 25983 3.1415925797636914 7.382610167638859e-08
95 81983 26096 3.141592581238504 7.23512889599931e-08
96 82338 26209 3.141592582700599 7.08891940703893e-08
97 82693 26322 3.1415925841501404 6.943965269456953e-08
98 83048 26435 3.1415925855872895 6.800250362815063e-08
99 83403 26548 3.1415925870122043 6.65775887753739e-08
100 83758 26661 3.1415925884250404 6.516475270501587e-08
101 84113 26774 3.1415925898259505 6.376384265038837e-08
102 84468 26887 3.1415925912150855 6.237470762116004e-08
103 84823 27000 3.1415925925925925 6.099720062380243e-08
104 85178 27113 3.1415925939586176 5.963117555296549e-08
105 85533 27226 3.1415925953133033 5.827648985601286e-08
106 85888 27339 3.141592596656791 5.693300231257581e-08
107 86243 27452 3.1415925979892174 5.5600575699088495e-08
108 86598 27565 3.1415925993107203 5.427907279198507e-08
109 86953 27678 3.1415926006214323 5.29683608085918e-08
110 87308 27791 3.1415926019214853 5.166830785441334e-08
111 87663 27904 3.1415926032110093 5.037878381131122e-08
112 88018 28017 3.141592604490131 4.909966211386063e-08
113 88373 28130 3.141592605758976 4.783081708481518e-08
114 88728 28243 3.1415926070176683 4.657212482328532e-08
115 89083 28356 3.141592608266328 4.5323464981095185e-08
116 89438 28469 3.141592609505076 4.40847172100689e-08
117 89793 28582 3.1415926107340284 4.285576471474428e-08
118 90148 28695 3.141592611953302 4.1636491143748344e-08
119 90503 28808 3.1415926131630103 4.042678281024337e-08
120 90858 28921 3.1415926143632653 3.922652780374847e-08
121 91213 29034 3.141592615554178 3.8035615101961184e-08
122 91568 29147 3.1415926167358563 3.685393679120352e-08
123 91923 29260 3.1415926179084073 3.568138584597591e-08
124 92278 29373 3.141592619071937 3.451785612895719e-08
125 92633 29486 3.141592620226548 3.336324505553989e-08
126 92988 29599 3.1415926213723435 3.2217449597027326e-08
127 93343 29712 3.1415926225094237 3.108036938925807e-08
128 93698 29825 3.1415926236378877 2.995190540033832e-08
129 94053 29938 3.1415926247578327 2.8831960374731125e-08
130 94408 30051 3.1415926258693556 2.7720437500988737e-08
131 94763 30164 3.14159262697255 2.6617243076287878e-08
132 95118 30277 3.14159262806751 2.5522282953716058e-08
133 95473 30390 3.141592629154327 2.443546609498526e-08
134 95828 30503 3.1415926302330917 2.335670146180746e-08
135 96183 30616 3.1415926313038933 2.2285899792251485e-08
136 96538 30729 3.1415926323668195 2.122297360074299e-08
137 96893 30842 3.1415926334219573 2.0167835845796844e-08
138 97248 30955 3.141592634469391 1.9120402150463178e-08
139 97603 31068 3.1415926355092054 1.808058769370291e-08
140 97958 31181 3.1415926365414837 1.7048309430833797e-08
141 98313 31294 3.1415926375663066 1.6023486537619647e-08
142 98668 31407 3.1415926385837554 1.5006037745735057e-08
143 99023 31520 3.1415926395939087 1.3995884451389884e-08
144 99378 31633 3.141592640596845 1.2992948050793984e-08
145 99733 31746 3.1415926415926414 1.1997151716514054e-08
146 100088 31859 3.141592642581374 1.1008419065205999e-08
147 100443 31972 3.1415926435631176 1.0026675489882564e-08
148 100798 32085 3.1415926445379463 9.051846827645704e-09
149 101153 32198 3.141592645505932 8.083861136043424e-09
150 101508 32311 3.1415926464671475 7.1226455844453085e-09
151 101863 32424 3.141592647421663 6.168130006756201e-09
152 102218 32537 3.1415926483695484 5.220244680970154e-09
153 102573 32650 3.141592649310873 4.2789203291704325e-09
154 102928 32763 3.141592650245704 3.3440890057079287e-09
155 103283 32876 3.1415926511741086 2.415684541290375e-09
156 103638 32989 3.1415926520961532 1.493639878447084e-09
157 103993 33102 3.1415926530119025 5.778906242426274e-10
158 104348 33215 3.141592653921421 3.3162805834763276e-10
159 208341 66317 3.1415926534674368 1.2235634727630895e-10
160 312689 99532 3.1415926536189365 2.914335439641036e-11
161 833719 265381 3.141592653581078 8.715250743307479e-12
162 1146408 364913 3.141592653591404 1.6107115641261771e-12
163 3126535 995207 3.1415926535886505 1.1426415369442111e-12
164 4272943 1360120 3.141592653589389 4.04121180963557e-13
165 5419351 1725033 3.1415926535898153 2.220446049250313e-14
166 42208400 13435351 3.1415926535897722 2.0872192862952943e-14
167 47627751 15160384 3.141592653589777 1.5987211554602254e-14
168 53047102 16885417 3.141592653589781 1.199040866595169e-14
169 58466453 18610450 3.1415926535897842 8.881784197001252e-15
170 63885804 20335483 3.141592653589787 6.217248937900877e-15
171 69305155 22060516 3.141592653589789 3.9968028886505635e-15
172 74724506 23785549 3.141592653589791 2.220446049250313e-15
173 80143857 25510582 3.1415926535897927 4.440892098500626e-16
174 165707065 52746197 3.1415926535897936 4.440892098500626e-16
175 245850922 78256779 3.141592653589793 0.0

留意,我只是用 default 的 data type,π 也是取內置 math.pi 的值。準確度有限,所以表末的結果未必正確。你看去到最末一行,絕對誤差為0,這是沒有可能吧。
雖然如此,但也有一些參考價值。
曾經,我在網上搜尋過有沒有相關 data,直接引述算數,但找不到。可能這個數列沒甚麼意義。人們有興趣的,是收歛得快的數列,這個實在數歛得太慢了。留意第10項跳去11項,看分母是很大的一步!之後分母都是慢慢上升,直到第158項後開始才快些。

2. 把圓周率的連分數形式化為普通分數形式:

#!/usr/bin/env python
 
import math
PiConFrac=[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,6,6,99,1,2,2,6,3,5,1,1,6,8,1,7,1,2,3,7,1,2,1,1,12,1,1,1,3,1,1,
8,1,1,2,1,6,1,1,5,2,2,3,1,2,4,4,16,1,161,45,1,22,1,2,2,1,4,1,2,24,1,2,
1,3,1,2,1]
num_list=[1,3] #儲存分子
den_list=[0,1] #儲存分母
# 第1個分子是1,第2個分母是0,未下定義?這不是真正的分子分母,只是我用這兩數為初始值,對於以下 algorithm 的運算會很方便。
num=1
den=1
counter=1
terms=len(PiConFrac)
i=2
F=open('output','w') # 結果顯示在一個名為 output 的文字檔
while i <=terms:
    den=den_list[i-1]*PiConFrac[i-1]+den_list[i-2]
    den_list.append(den)
    num=num_list[i-1]*PiConFrac[i-1]+num_list[i-2]
    num_list.append(num)
    F=open('output','a')
    F.write("||"+str(counter)+"||"+str(num)+"||"+str(den)+"||"+"\n")
    i=i+1
    counter=counter+1
F.close()

與第一個程式一樣,是 Linux (32 bit)下的 python 3.2。

結果:

次序 分子 分母
1 22 7
2 333 106
3 355 113
4 103993 33102
5 104348 33215
6 208341 66317
7 312689 99532
8 833719 265381
9 1146408 364913
10 4272943 1360120
11 5419351 1725033
12 80143857 25510582
13 165707065 52746197
14 245850922 78256779
15 411557987 131002976
16 1068966896 340262731
17 2549491779 811528438
18 6167950454 1963319607
19 14885392687 4738167652
20 21053343141 6701487259
21 1783366216531 567663097408
22 3587785776203 1142027682075
23 5371151992734 1709690779483
24 8958937768937 2851718461558
25 139755218526789 44485467702853
26 428224593349304 136308121570117
27 5706674932067741 1816491048114374
28 6134899525417045 1952799169684491
29 30246273033735921 9627687726852338
30 66627445592888887 21208174623389167
31 430010946591069243 136876735467187340
32 2646693125139304345 842468587426513207
33 262452630335382199398 83541266890691994833
34 265099323460521503743 84383735478118508040
35 792651277256425206884 252308737846929010913
36 1850401877973371917511 589001211171976529866
37 11895062545096656711950 3786316004878788190109
38 37535589513263342053361 11947949225808341100193
39 199573010111413366978755 63526062133920493691074
40 237108599624676709032116 75474011359728834791267
41 436681609736090076010871 139000073493649328482341
42 2857198258041217165097342 909474452321624805685313
43 23294267674065827396789607 7414795692066647773964845
44 26151465932107044561886949 8324270144388272579650158
45 206354529198815139329998250 65684686702784555831515951
46 232505995130922183891885199 74008956847172828411166109
47 671366519460659507113768648 213702600397130212653848169
48 2246605553512900705233191143 715116758038563466372710616
49 16397605394050964443746106649 5219519906667074477262822481
50 18644210947563865148979297792 5934636664705637943635533097
51 53686027289178694741704702233 17088793236078350364533888675
52 72330238236742559890684000025 23023429900783988308169421772
53 126016265525921254632388702258 40112223136862338672703310447
54 1584525424547797615479348427121 504370107543132052380609147136
55 1710541690073718870111737129379 544482330679994391053312457583
56 3295067114621516485591085556500 1048852438223126443433921604719
57 5005608804695235355702822685879 1593334768903120834487234062302
58 18311893528707222552699553614137 5828856744932488946895623791625
59 23317502333402457908402376300016 7422191513835609781382857853927
60 41629395862109680461101929914153 13251048258768098728278481645552
61 356352669230279901597217815613240 113430577583980399607610711018343
62 397982065092389582058319745527393 126681625842748498335889192663895
63 754334734322669483655537561140633 240112203426728897943499903682238
64 1906651533737728549369394867808659 606906032696206294222889000028371
65 2660986268060398033024932428949292 847018236122935192166388903710609
66 17872569142100116747518989441504411 5689015449433817447221222422292025
67 20533555410160514780543921870453703 6536033685556752639387611326002634
68 38406124552260631528062911311958114 12225049134990570086608833748294659
69 212564178171463672420858478430244273 67661279360509603072431780067475929
70 463534480895187976369779868172446660 147547607856009776231472393883246517
71 1139633139961839625160418214775137593 362756495072529155535376567833968963
72 3882433900780706851851034512497859439 1235817093073597242837602097385153406
73 5022067040742546477011452727272997032 1598573588146126398372978665219122369
74 13926567982265799805873939967043853503 4432964269365850039583559427823398144
75 60728338969805745700507212595448411044 19330430665609526556707216376512714945
76 256839923861488782607902790348837497679 81754686931803956266412424933874257924
77 4170167120753626267426951858176848373908 1327405421574472826819306015318500841729
78 4427007044615115050034854648525685871587 1409160108506276783085718440252375099653
79 716918301303787149323038550270812273699415 228202182891085034903619974895950891885862
80 32265750565715036834586769616835078002345262 10270507390207332847445984588758042509963443
81 32982668867018823983909808167105890276044677 10498709573098417882349604563653993401849305
82 757884465640129164480602549293164664075328156 241242117998372526259137284989145897350648153
83 790867134507147988464512357460270554351372833 251740827571470944141486889552799890752497458
84 2339618734654425141409627264213705772778073822 744723773141314414542111064094745678855643069
85 5470104603815998271283766885887682099907520477 1741188373854099773225709017742291248463783596
86 7809723338470423412693394150101387872685594299 2485912146995414187767820081837036927319426665
87 36708997957697691922057343486293233590649897673 11684836961835756524296989345090438957741490256
88 44518721296168115334750737636394621463335491972 14170749108831170712064809426927475885060916921
89 125746440550033922591558818759082476517320881617 40026335179498097948426608198945390727863324098
90 3062433294496982257532162387854374057879036650780 974802793416785521474303406201616853353780695273
91 3188179735047016180123721206613456534396357532397 1014829128596283619422730014400562244081644019371
92 9438792764591014617779604801081287126671751715574 3004461050609352760319763435002741341517068734015
93 12626972499638030797903326007694743661068109247971 4019290179205636379742493449403303585598712753386
94 47319710263505107011489582824165518109876079459487 15062331588226261899547243783212652098313206994173
95 59946682763143137809392908831860261770944188707458 19081621767431898279289737232615955683911919747559
96 167213075789791382630275400487886041651764456874403 53225575123090058458126718248444563466137046489291
97 227159758552934520439668309319746303422708645581861 72307196890521956737416455481060519150048966236850

我寫程式的功力其實很差,算是 BB 班。一直以來,我都學得不太用心。

中四中五時有讀電腦,學過一下寫 PASCAL。其實我不太鍾意,覺得很悶,功課的問題一來提不起興趣,二來覺得白痴得很。如此簡單的問題,在腦海,或用紙筆,也能完成。為何要花時間去寫程式?我寫程式時很多 syntax error,對我很困擾。覺得既然不用寫程式也能解決,為何我還要花一大堆時間去寫?花一大堆時間去跟進那些 syntax error?

後來,其實已出來工作了。覺得寫程式很重要,與工作沒有甚麼關係,只是覺得心入面有些東西、想法,都可以靠寫程式來做到。試想想,若你要創造一件東西,一件實物,例如一架車,普通人根本沒有資源去做。但如果你想去創造的能在電腦程式上實現,你只須一台電腦,其他的就是自己的時間和心力。相對地可行性高得多。

但我一直也學不好。一來,也是中五時的問題。覺得書中的問題很無聊,看那些寫程式的書籍實在很悶。但要做一些複雜的問題,我又沒有這個功力。二來,上班工作、加班,嚴重影響學習的進度和決心。是我的個人毅力不夠。

這次,是一個很美好的經驗。
首先想到一個自己感興趣的問題,而這個問題也能用程式來實現。更重要,是我有能力去完成。

第一個程式,雛型不是這樣的。起初,我心想了一個 algorithm,寫了幾個 loops,去完成了,但效率其低。最初我產生了一個分母小於20000的數列,電腦運算花了五個小時。我知道一部分原因是我設計的 algorithm 太爛,後來想番起,有些 testing 是不必要的。loop一兩次無乜所謂,但loop 上萬次,就大大影響。

第二,python 的問題。很多資料建議人可以用到 standard library 就用,無謂自己去砌。因為 python 是一種 script,interpret 較慢。但 standard library 是用C來implement,會較你自己用python 去實現來效率好得多。但我不熟識 library,起初也沒有為意有現成的可用。後來想想下,發現Fraction這功能,加些少改變化,便可做到我想做的結果。一試之後,快得多。分母小於20000的情況,數秒完成。第一個表中,分母小於八千萬,在我家中的電腦運算了七小時。若用我先前的,真是要等到天荒地老。

這樣努力去看資料,去思考,去嘗試,全因有一個感興趣的題目。

你們有沒有嘗試過去把連分數化為普通分數?由最底開始做運算,一路做呀做,通分母真的很煩!於是我又嘗試去寫程式來解決。過程中,我竟然發現了一個連分數的性質,把問題化簡不少,原來只須一個簡單的遞歸序列便可由連分數的各項描述普通分數分子的各項,分母也有相應的遞歸序列來描述。這個連分數的性質,自己從未想過,實在神奇。因此,全靠這性質,第二個程式比我當初想像的簡短得多。

寫程式、學數學,或者很多很多課題也一樣,問題,是引發人們去思考、去探究的動力。

我希望也能慢慢學好寫程式,做到一個心入面的計劃。


Add a New Comment
or Sign in as Wikidot user
(will not be published)
- +