C言語版の移植

 投稿者:山中和義  投稿日:2009年 5月15日(金)10時58分0秒
  Tiny programs for constants computation
にπ、eなどの多桁を求めるC言語のショートプログラムがあります。

Q&Aのコーナー
 CやJavaで書かれた数値計算アルゴリズムの移植
を参考に、書き換えてみました。

これより、機械的に置き換えるパターンが見えてきます。


●サンプル1
!eの9000桁
!main(){int N=9009,n=N,a[9009],x;while(--n)a[n]=1+1/n;
!for(;N>9;printf("%d",x))
!for(n=N--;--n;a[n]=x%n,x=10*a[n-1]+x/n);}

!整形すると
!main(){
!  int N=9009,n=N,a[9009],x;
!  while(--n)
!    a[n]=1+1/n;
!  for( ;N>9; printf("%d",x) )
!    for( n=N--; --n; a[n]=x%n, x=10*a[n-1]+x/n );
!}

REM---> main(){
!nop

REM---> int N=9009,n=N,a[9009],x;
LET N=9009
LET n_=N !※C言語は大文字と小文字は区別される
DIM a(0 TO 9009-1) !※C言語は初期化しないため値は不定
LET x=0 !※

REM --> while(--n)
DO
   LET n_=n_-1
   IF n_=0 THEN EXIT DO

   REM --> a[n]=1+1/n;
   LET a(n_)=1+IP(1/n_)

LOOP

REM---> for(;N>9;printf("%d",x))
!nop !for(※; ; )部分

DO !for( ;※; )部分
   IF NOT N>9 THEN EXIT DO


   REM---> for(n=N--;--n;a[n]=x%n,x=10*a[n-1]+x/n)
   LET n_=N !for(※; ; )部分
   LET N=N-1

   DO !for( ;※; )部分
      LET n_=n_-1
      IF NOT n_<>0 THEN EXIT DO


      REM---> ;


      LET a(n_)=REMAINDER(x,n_) !for( ; ;※)部分
      LET x=10*a(n_-1)+IP(x/n_)

   LOOP


   PRINT x; !for( ; ;※)部分

LOOP

REM---> }

END


●サンプル2
!π
!main(){int a=1e4,c=3e3,b=c,d=0,e=0,f[3000],g=1,h=0;
!for(;b;!--b?printf("%04d",e+d/a),e=d%a,h=b=c-=15:f[b]=(d=d/g*b+a*(h?f[b]:2e3))%(g=b*2-1));}

!整形すると
!main(){
!  int a=1e4,
!      c=3e3,
!      b=c,
!      d=0,
!      e=0,
!      f[3000],
!      g=1,
!      h=0;
!  for(;
!      b;
!      !--b?
!        printf("%04d",e+d/a),
!        e=d%a,
!        h=b=c-=15
!      :
!        f[b]=(d=d/g*b+a*(h?
!                           f[b]
!                         :
!                           2e3
!                        )
!                         )%(g=b*2-1)
!     )
!    ;
!}

REM---> main(){
!nop

REM---> int a=1e4,c=3e3,b=c,d=0,e=0,f[3000],g=1,h=0;
LET a=1E4
LET c=3E3
LET b=c
LET d=0
LET e=0
DIM f(0 TO 3000-1) !※C言語は初期化しないため値は不定
LET g=1
LET h=0

REM---> for(;b;!--b?printf("%04d",e+d/a),e=d%a,h=b=c-=15:f[b]=(d=d/g*b+a*(h?f[b]:2e3))%(g=b*2-1))
!nop !for(※; ; )部分

DO !for( ;※; )部分
   IF NOT b<>0 THEN EXIT DO


   REM---> ;


   !for( ; ;※)部分
   LET b=b-1 ! !--b?~:~部分
   IF NOT b<>0 THEN
      PRINT USING "%%%%": e+IP(d/a); !printf("%04d",e+d/a),
      LET e=REMAINDER(d,a) !e=d%a,
      LET AX_=c-15 !h=b=c-=15
      LET h,b,c=AX_
   ELSE
      IF h<>0 THEN LET AX_=f(b) ELSE LET AX_=2E3 !h?~:~部分
      LET d=IP(d/g)*b+a*AX_ !d=d/g*b+a*(~)部分
      LET g=b*2-1 !g=b*2-1部分
      LET f(b)=REMAINDER(d,g) !f[b]=(~)%(~)
   END IF

LOOP

REM---> }

END
 

Re: C言語版の移植

 投稿者:山中和義  投稿日:2009年 5月16日(土)11時12分42秒
  > No.378[元記事へ]

●サンプル3
!2の平方根の2400桁
!main(){int a=1000,b=0,c=1413,d,f[1414],n=800,k;
!for(;b<c;f[b++]=14);
!for(;n--;d+=*f*a,printf("%.3d",d/a),*f=d%a)
!for(d=0,k=c;--k;d/=b,d*=2*k-1)f[k]=(d+=f[k]*a)%(b=100*k);}

!整形すると
!main(){
!  int a=1000,b=0,c=1413,d,f[1414],n=800,k;
!  for( ;b<c; f[b++]=14 );
!  for( ;n--; d+=*f*a,printf("%.3d",d/a),*f=d%a )
!    for( d=0,k=c; --k; d/=b,d*=2*k-1 )
!      f[k]=(d+=f[k]*a)%(b=100*k);
!  }

REM---> main(){
!nop

REM---> int a=1000,b=0,c=1413,d,f[1414],n=800,k;
LET a=1000
LET b=0
LET c=1413
DIM f(0 TO 1414-1) !※C言語は初期化しないため値は不定
LET n=800
LET k=0 !※C言語は初期化しないため値は不定

REM---> for( ;b<c; f[b++]=14 );
!nop !for(※; ; )部分

DO !for( ;※; )部分
   IF NOT b<c THEN EXIT DO


   REM--> ;


   LET f(b)=14 !for( ; ;※)部分
   LET b=b+1

LOOP


REM---> for( ;n--; d+=*f*a,printf("%.3d",d/a),*f=d%a )
!nop !for(※; ; )部分

DO !for( ;※; )部分
   IF NOT n<>0 THEN EXIT DO
   LET n=n-1


   REM---> for(d=0,k=c; --k; d/=b,d*=2*k-1 )
   LET d=0 !for(※; ; )部分
   LET k=c

   DO !for( ;※; )部分
      LET k=k-1
      IF NOT k<>0 THEN EXIT DO


      REM--> f[k]=(d+=f[k]*a)%(b=100*k);
      LET d=d+f(k)*a
      LET b=100*k
      LET f(k)=REMAINDER(d,b)


      LET d=IP(d/b) !for( ; ;※)部分
      LET d=d*(2*k-1)

   LOOP


   LET d=d+f(0)*a !for( ; ;※)部分
   PRINT USING "%%%": IP(d/a) !最小桁数3桁
   LET f(0)=REMAINDER(d,a)

LOOP


REM---> }

END
 

戻る