侮り難し 生成AI
ここのところ、暇を見つけては、CP/MエミュレータのBASICで記述した「πの1000桁」をc言語に移植する事を試みていた。書籍に書いてあったソースプログラムは、書籍に書いてある通り「インタープリタでの実行速度を少しでも高めるよう、ぎっしり詰めて記述してあり、読みづらい」。まずは、ソースを読みやすいように書換えることから始めた。書換えて気づいたことがあった。このプログラムは、遠い昔に見たものに似ている!「エンサイクロペディア・アスキー Vol2」p163の「πの千桁!」(元記事は月刊アスキー 78年6月号p65) に載っていたものだ。これに拠れば、マーチンの公式を利用して円周率を計算している。そうと分かれば、あとは力ずくと思い、c言語に移植する事を始めてみたものの・・・もう、すっかりc言語を忘れている。力尽き、試しに生成AIにc言語への移植を依頼してみた。利用した生成AIは、今メインで使っているクロームブックにあるグーグルのGemini。依頼したら即座に移植が次のように完了した。#include <stdio.h>#include <stdlib.h>#define SIZE 253 // 配列サイズを253に変更(A(1)~A(252)をCの配列の添え字0~251に対応させるため)void sub210(int A[], int B[], int M, int *R);void sub220(int B[], int C[]);void sub240(int B[], int C[]);void sub420(int F[]);void sub430(int Y, int D[], int F[]);void sub440(int D[]);int main() {int A[SIZE] = {0};int B[SIZE] = {0};int C[SIZE] = {0};int D[5] = {0}; // D(1)~D(4)をD[1]~D[4]で使う。Cの配列は0から始まるので、D[0]は未使用。int F[5] = {0}; // F(1)~F(4)をF[1]~F[4]で使う。Cの配列は0から始まるので、F[0]は未使用。int M, R, X, I, J, O, L, Y, Z;printf("\nProgram Start\n");sub420(F);A[1] = 80;for (O = 1; O <= 1494; O += 2) {M = 25;sub210(A, B, M, &R);for (I = 1; I < SIZE; I++) {A[I] = B[I];B[I] = 0;}M = O;sub210(A, B, M, &R);sub240(B, C);O += 2;M = 25;sub210(A, B, M, &R);for (I = 1; I < SIZE; I++) {A[I] = B[I];B[I] = 0;}M = O;sub210(A, B, M, &R);sub220(B, C);}for (J = 1; J < SIZE; J++) {A[J] = 0;B[J] = 0;}A[1] = 956;for (O = 1; O <= 421; O += 2) {M = 239;sub210(A, B, M, &R);for (I = 1; I < SIZE; I++) {A[I] = B[I];B[I] = 0;}M = 239;sub210(A, B, M, &R);for (I = 1; I < SIZE; I++) {A[I] = B[I];B[I] = 0;}M = O;sub210(A, B, M, &R);sub220(B, C);O += 2;M = 239;sub210(A, B, M, &R);for (I = 1; I < SIZE; I++) {A[I] = B[I];B[I] = 0;}M = 239;sub210(A, B, M, &R);for (I = 1; I < SIZE; I++) {A[I] = B[I];B[I] = 0;}M = O;sub210(A, B, M, &R);sub240(B, C);}printf("\nProgram Stop\n\nPI= 3.");I = 2;while (I < SIZE) {printf(" ");Y = C[I];sub430(Y, D, F);sub440(D);I++;if ((I - 2) % 10 == 0) {printf("\n\t");}}printf("\n\n");return 0;}void sub210(int A[], int B[], int M, int *R) {int I, X;*R = 0;for (I = 1; I < SIZE; I++) {X = A[I] + (*R) * 10000;B[I] = X / M;*R = X - B[I] * M;}}void sub220(int B[], int C[]) {int I, D = 0;for (I = SIZE - 1; I > 0; I--) {C[I] = C[I] - B[I] - D;D = 0;if (C[I] < 0) {C[I] = C[I] + 10000;D = 1;}}}あれ? 楽天ブログがインデントを無視している。実際はもっと読み易く出来ているのに。まあいいや。早速コンパイルしたらエラー無し、オブジェクトも問題なく動くし、結果は1000桁間違いなし。侮り難し、生成AI。ってか、拙者が苦労していた時間って、何だったんだろう???ついでに生成AIに、プログラムのスタート時刻とストップ時刻を打ち出すようにお願いした。これも難無く出来上がった。ちなみに円周率を1000桁計算する実行時間は、なんと1秒未満!1982年当時のPC-8001のMBASICで5時間以上、if800のCP/Mで4時間、拙者のポンコツPCのCP/Mエミュレータ上のMBASICで6分20秒、同じくMBASICコンパイラのオブジェクトで1分20秒掛かったものが、1秒未満で終わった。なんと速いことか!!ならば、πを10000桁計算したら、どのくらいの時間がかかるだろう?計算する桁を増やすには、上のソースプログラムの赤字の所をいじれば良さそうだ。それについては、また後日。