円周率の計算 (10)
アセンブリ言語による arctan 公式による円周率の計算プログラムを、8 ビット縛りで STM8S-Discovery 用に、16 ビット縛りで PC (x86 プロセッサ) 用に作成しました。
ソース・プログラムは、両者とも 500 行を超えるので、この blog 上には置かず、web サイト上に置くことにしました。(→こちらとこちら)
8 ビット縛りの STM8S 用では有効桁数 610 桁、16 ビット縛りの x86 用では有効桁数 157,717 桁です。
まず、STM8S 用の「pi_600.asm」ですが、ソースは(→こちら) におきました。
アセンブル結果の S フォーマット・ファイルを下に示します。
ソースからアセンブルしなくても、このファイルを STVP (ST Visual Programmer) で STM8S-Discovery に書き込んでも実行できます。
pi_600.s19
S00600004844521B S1138080AE07FF94AE00007F5CA300FF23F9AE01AE S1138090007F5CA305FF23F9AE06007F5CA307FF06 S10B80A023F9CD80A820FE8025 S11380A8350050C6CD812A721050117210500FAE8F S11380B88296CD828A7211500FAE01004FCD815540 S11380C890AE8105CD80EB72A90006907D26F5AEB1 S11380D80100A604CD81887210500F90AE0200CD25 S11380E8821E819089AE0200CD81DC160190E605DE S11380F890AE0200AE0100CD8161908581E3FF005E S113810800FF0064161F00DDFF2C382500BF003374 S11381181B6D00B5001B072B2B99FF58100D4F97AB S1138128000035015243351A524235005244350C89 S113813852458172A900FF1C00FFA6FF81CD813B37 S113814888905A5A90F6F70A0126F6848188CD81D8 S11381583F5A7F4A26FB84F78188CD813B880702F2 S11381685A905A90F61802F9F70A0126F384848182 S1138178CD813F88985A4FF2F70A0126F87C84810A S1138188908952046B040F020F03CD813F6B015A8F S1138198F690977B04904272F902909FF7909E6B39 S11381A8030A0126EA5B049085814D272688908975 S11381B852026B02905FA6FF6B01F690977B0290C8 S11381C8629095909FF75C0A0126EF5B0290858484 S11381D81D00FF81A601CD815590E604887B01A08E S11381E802CD8188AD1EAD1C7B01CD81B2CD8178D5 S11381F87B01A0026B01A10126E390E600CD8188F2 S1138208AD02848190E601CD81B290E602CD81B2BF S113821890E603CC81B289908951CD8145905F90D5 S1138228BF009089F6AB30CD826C7FA60ACD8188D9 S11382381601A60A9062A1002616A62E614D612792 S113824802A620CD826CA60590624D2603CD827FBE S11382581601905C170190A3026526C89085908545 S113826885AD148189BE00D703005CBF0085720FF9 S11382785240FBC752418188A60DADF2A60AADEE65 S1138288848188F65C4D2704ADE420F784810D0AC7 S10982987069203D200086 S113800082008080820080A7820080A7820080A7EF S1138010820080A7820080A7820080A7820080A7B8 S1138020820080A7820080A7820080A7820080A7A8 S1138030820080A7820080A7820080A7820080A798 S1138040820080A7820080A7820080A7820080A788 S1138050820080A7820080A7820080A7820080A778 S1138060820080A7820080A7820080A7820080A768 S1138070820080A7820080A7820080A7820080A758 S9030000FC
実行結果を下に示します。
pi = 3. 1415926535 8979323846 2643383279 5028841971 6939937510 5820974944 5923078164 0628620899 8628034825 3421170679 8214808651 3282306647 0938446095 5058223172 5359408128 4811174502 8410270193 8521105559 6446229489 5493038196 4428810975 6659334461 2847564823 3786783165 2712019091 4564856692 3460348610 4543266482 1339360726 0249141273 7245870066 0631558817 4881520920 9628292540 9171536436 7892590360 0113305305 4882046652 1384146951 9415116094 3305727036 5759591953 0921861173 8193261179 3105118548 0744623799 6274956735 1885752724 8912279381 8301194912 9833673362 4406566430 8602139494 6395224737 1907021798 6094370277 0539217176 2931767523 8467481846 7669405132 0005681271 31
C 言語版のプログラムとは、計算方法を一部変えたために、有効桁数が 608 桁から 610 桁に増えました。
最後の行の「0005681271 31」の「0005681271」まで (610 桁) が正しく、「31」(以降) からは正しくありません。
次に、16 ビット縛りの「pi86atan.asm」ですが、ソースは (→こちら) に置きました。
「16 ビット縛り」、つまり、
- 16 ビット x 16 ビット = 32 ビットの乗算
- 32 ビット / 16 ビット = 16 ビット商、16 ビット余りの除算
- 配列のサイズは 2 バイト・オフセットでアクセス可能な 65536 バイト以下
という制限の中で計算しており、理論上の最大桁数は約 157,717 桁で、理論値通りの結果が得られています。
実行時間 (メモリ上の配列に 2 進表現の数値が求まるまで) は Celeron M430 (1.73 GHz, 65 nm Yonah-1M コア, FSB 533 MHz) の PC 上で約 4 分です。
64 K バイト x 2 個の配列領域を、正式な手続きによらず簡易的な方法で割り付けているので、プログラムをロード/実行可能なコンベンショナル・メモリが 192 K バイト以上ないと正常な動作をしません。
もし空きが足りない場合には、システムの TSR (Terminate and Stay Resident) プログラムなどの、すでにメモリ上にあるプログラムを何の考慮もせずに破壊する可能性があります。
アセンブル結果の COM ファイルを intel HEX フォーマット・ファイルに変換したもの下に示します。
pi86atan.hex
:100100008CD80500108EC00500108EE0E82E00B4DB :100110004CCD2160B42CCD21BF5D03BE04008AC547 :100120008AE98ACE8AF2D40A05303086C4890583EA :10013000C7034E75E9BA5D03E8150261C3B8000054 :10014000E8F900BB9001803F00742CE8C5FFBA6954 :1001500003E8FC01E8E601FE066E03E84601E85C00 :1001600000E84001807F01007405E8E800EB03E847 :10017000D50083C306EBCFE899FFE8C001BAB5010B :10018000E8CD01E82501E8B401E887FFE8AE01C346 :10019000E300FF00FFFF64FFAA0267D92C001808E4 :1001A000C5B933007F0B61B51BFF8F3263965800D2 :1001B00030402392000D0A7069203D2024B80100D0 :1001C000E879008B4F048BC183E802E8BE00E88623 :1001D000018B47023D00017304F7E0EB03E89B004D :1001E000E8740150F7E183FA005A740992E88B0031 :1001F000E864018BC1E88300E85C01E8680083E9FA :100200000283F90273C08A07B400C1E002E87C00EF :100210008B4702E86500C333F68B0E580333FFFCAF :10022000C3E8F5FF8BF94FD1E7FDC3E8F3FF8BF788 :10023000C360E8E2FF64ADABE2FB61C360E8D9FFF5 :10024000AB33C0E2FB61C360E8E0FF64AD26130599 :10025000ABE2F861C360E8D2FF268B05641B044E55 :100260004EABE2F561C360E8B7FFB80000261B059E :10027000ABE2F783C70226FF0561C360E89AFF334C :10028000D293268B05F7F3ABE2F861C360E891FFE8 :1002900033F693268B05F7E303C6AB83D2008BF2CC :1002A000E2F161C3060FA0070FA1C360E8F5FFE804 :1002B0007FFF26A10000E8400026C70600000000DE :1002C000B81027E8C6FF26A10000E81400813E5AB6 :1002D00003207775E4803E5C030F75DDE8C5FF61A0 :1002E000C350B364F6F3E8040086C4EB0150D40AAB :1002F00086C4E8040086C4EB01500430E84800A13D :100300005A0304012786C414002786C4A35A037322 :1003100006FE065C037408A80F7520B320EB04FEEC :10032000C4B32E93E82000933C50740C3C00750B32 :10033000F6C40F7503E80500E8020058C360B00D6D :10034000E80400B00AEB01608AD0B402CD2161C399 :1003500060B409CD2161C3C300809999FF30303A60 :1003600030303A30302E303024207465726D3124B4 :0400000300000100F8 :00000001FF
COM ファイルのファイル・サイズは 624 バイトです。
途中を省略した実行結果を下に示します。
結果が出るまで数分かかるので、途中経過が分かるように、全部で 6 項ある arctan の各項の計算を開始する時点、出力開始時点、および出力終了時点の時刻を表示しています。
ctrl-C による実行の中断は、すぐには有効となりませんが、 第 1 項目が表示されている時に ctrl-C を押したとすると、3 項目の表示が出るあたりで中断されます。
19:00:01.24 term1 19:00:43.70 term2 19:01:32.52 term3 19:02:14.10 term4 19:02:54.64 term5 19:03:28.36 term6 19:04:00.99 pi = 3. 1415926535 8979323846 2643383279 5028841971 6939937510 5820974944 5923078164 0628620899 8628034825 3421170679 8214808651 3282306647 0938446095 5058223172 5359408128 4811174502 8410270193 8521105559 6446229489 5493038196 4428810975 6659334461 2847564823 3786783165 2712019091 4564856692 3460348610 4543266482 1339360726 0249141273 7245870066 0631558817 4881520920 9628292540 9171536436 7892590360 0113305305 4882046652 1384146951 9415116094 3305727036 5759591953 0921861173 8193261179 3105118548 0744623799 6274956735 1885752724 8912279381 8301194912 9833673362 4406566430 8602139494 6395224737 1907021798 6094370277 0539217176 2931767523 8467481846 7669405132 0005681271 4526356082 7785771342 7577896091 7363717872 1468440901 2249534301 4654958537 1050792279 6892589235 4201995611 2129021960 8640344181 5981362977 4771309960 5187072113 4999999837 2978049951 0597317328 1609631859 5024459455 3469083026 4252230825 3344685035 2619311881 7101000313 7838752886 5875332083 8142061717 7669147303 5982534904 2875546873 1159562863 8823537875 9375195778 1857780532 1712268066 1300192787 6611195909 2164201989 <<<<<< 以下 1001 桁から 157,000 桁まで省略 >>>>>> <<<<<< 157,001 桁から 157,720 桁まで >>>>>> 4774315429 3290326295 3211497882 6203515987 4125464228 8439527779 5499289564 7543471058 9858515900 5508490056 9690369399 4638054127 4407827207 9588120610 9501826667 5052829100 4286440115 9690915602 6024587211 7456045510 9407684697 9736827481 4597904045 5219048418 0115456634 7833534380 8815341403 7239817881 9077576306 4723383684 8076617187 8875254440 7318658305 0118647563 2030171398 3390078987 5424411026 2777492594 5578726315 1608748702 5048062038 1626062841 5675429971 1008457236 0794368388 3177569711 6071774760 1977362998 6084709225 6124190334 4303868060 7516077836 5027891666 2836093176 7596955301 4936812797 9354666523 9389865492 2082126132 7763789820 2946799581 6243987059 3623917051 1750705049 3924429371 2287520721 0047900369 5203530541 7470268810 0313142753 1174456246 4073545194 19:04:11.15
最後から 2 行目の「4073545194」は、「4073545」までが正しく、「194」からは正しくありません。