多倍長計算

多倍長表現を利用した計算例です。今回は、差分の計算を行っています。

多倍長表現による差分計算例list_41.c)
/*----------------------------------------------------------------------
  多倍長表現を利用した差分
  ----------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#define DLENG 20
//-----------------------------------------------------------------
void disp_data(char* str,int a[DLENG],int pm_flg);
void input_data(char* str,int a[DLENG]);
int  sub_data(int a[DLENG],int b[DLENG],int c[DLENG]);
//-----------------------------------------------------------------

int main(void)
{
    int i,j,pm_flg;
    int A[DLENG],B[DLENG],C[DLENG];
    memset(A,0,sizeof(int)*DLENG);
    memset(B,0,sizeof(int)*DLENG);
    
    input_data("a",A);
    input_data("b",B);
    pm_flg = sub_data(A,B,C);
    disp_data("A-B = ",C,pm_flg);
    return 0;
}
// 引算
int sub_data(int a[DLENG],int b[DLENG],int c[DLENG])
{
    int i,ii,iii,pm_flg=0;
    int* aa=(int*)calloc(DLENG,sizeof(int));
    int* bb=(int*)calloc(DLENG,sizeof(int));
    int *ap,*bp;
    memcpy(aa,a,sizeof(int)*DLENG);
    memcpy(bb,b,sizeof(int)*DLENG);
    // 正負の判定
    for(i=DLENG-1; i>=0; i--){
        if(aa[i]>bb[i])     { break; }
        else if(aa[i]<bb[i]){ pm_flg=1; break; }
    }
    // ポインタにより正負の計算の入換え
    if(pm_flg){ap=bb; bp=aa;}
    else      {ap=aa; bp=bb;}
    // 計算
    for(i=0;i<DLENG;i++){
        if((ap[i])<bp[i]){
            if(ap[i+1]){
                c[i]=(ap[i]+10-bp[i]);
                ap[i+1]--;
            } else {
                for(ii=i+2;ii<DLENG;ii++){
                    if(ap[ii]){
                        ap[ii]--;
                        for(iii=ii-1;iii>i;iii--) ap[iii] += 9;
                        break;
                    }
                }
                c[i]=(ap[i]+10-bp[i]);
            }
        } else {
            c[i]=(ap[i]-bp[i]);
        }
    }
    free(aa); free(bb);
    return pm_flg;
}
// 多倍長表現のデータ表示
void disp_data(char* str,int a[DLENG],int pm_flg)
{
    int i;
    printf("%s",str);
    if(pm_flg) printf("-");
    for(i=DLENG-1;i>=0;i--){
        printf("%d", a[i]);
        if(i==0){putchar('\n');}
    }
}
// 多倍長表現のデータ入力
void input_data(char* str,int a[DLENG])
{
    int i,len;
    char c[2],buf[BUFSIZ];
    memset(buf,0,sizeof(char)*BUFSIZ);
    printf("input data[%s]: ",str);
    scanf("%s",buf);
    //-------------------------------------------------------
    // データの入力
    // 桁数より多い場合は切捨て
    //-------------------------------------------------------
    len = strlen(buf);
    for(i=0;i<DLENG;i++){
        c[0] = buf[len-i-1];
        a[i] = atoi(&c);
    }
}
実行結果
Gami[59]% ./list_41.exe
input data[a]: 192922112
input data[b]: 22112822
A-B = 00000000000170809290
Gami[60]%
inserted by FC2 system