加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

大数运算(超长整数运算)算法的简单分析

发布时间:2020-12-14 03:53:55 所属栏目:大数据 来源:网络整理
导读:大数运算(超长整数运算),这里以大数(超长整数)的四则运算为例。 别的也不说了,直接上代码吧, 重点是注释 ,有不对的还请多多指正!O(∩_∩)O~ #define N 8//最大位数void add(int*,int*,int*);//加法void subtract(int*,int*);//减法void multiply(in

大数运算(超长整数运算),这里以大数(超长整数)的四则运算为例。

别的也不说了,直接上代码吧,重点是注释,有不对的还请多多指正!O(∩_∩)O~

#define N 8//最大位数

void add(int*,int*,int*);//加法
void subtract(int*,int*);//减法
void multiply(int*,int,int*);//乘法
void divide(int*,int*);//除法
void toComp(int*,int*);  // 转补数
void absv(int*,int*);    // 转绝对值
void print(int*);         // 展示大整数

//主程序
int a[] = {0,21,0};
int b[] = {9999,9999,9901}; // -99的补码表示形式,且当作是机器中的表示形式
int c1[N],c2[N],c3[N],c4[N] = {0};

add(a,b,c1);       print(c1);
subtract(a,c2);  print(c2);
multiply(a,-3,c3); print(c3);
divide(a,c4);   print(c4);

//核心方法
void add(int* a,int* b,int* c) {//加法运算
    if(b[0] == 9999) {//最高位是9999,表示负数
        int comp[N] = {0};
        toComp(b,comp);//求b的补数
        subtract(a,comp,c);//用减法算
    } else {
        int i,carry = 0;
        for(i = N - 1; i >= 0; i--) {
            c[i] = a[i] + b[i] + carry;//数组的每个元素进行相加,顺便把进位也加上
            if(c[i] < 10000) {
                carry = 0;
            } else { 
                c[i] = c[i] - 10000;
                carry = 1;//产生进位,加法的进位最多为1
            }
        }
    }
}

void subtract(int* a,int* c) {
    if(b[0] == 9999) {//判断b是不是负数
        int comp[N] = {0};
        toComp(b,comp);//求补数
        add(a,c);//进行加法运算
    } else {
        int i,borrow = 0;
        for(i = N - 1; i >= 0; i--) {//从低位开始
            c[i] = a[i] - b[i] - borrow;
            if(c[i] >= 0) {
                borrow = 0;
            } else { // 不够减,借1位
                c[i] = c[i] + 10000;
                borrow = 1;
            }
        }
    }
}

void multiply(int* a,int b,int* c) { //乘法
    int op1[N] = {0}; absv(a,op1);
    int op2 = abs(b);
    
    int i,tmp,carry = 0;
    for(i = N - 1; i >= 0; i--) {
        tmp = op1[i] * op2 + carry;//将被乘数拆成一位一位的计算,产生的进位加到高位的结果里,
        c[i] = tmp % 10000;
        carry = tmp / 10000;
    }
    
    if((a[0] == 9999 && b > 0) || (a[0] == 0 && b < 0)) {//如果一正一负,求补数
        toComp(c,c);
    }
}

void divide(int* a,int *c) {  // b 為除數
    int op1[N] = {0}; absv(a,remain = 0;
    for(i = 1; i < N; i++) {//从最高位算起
        tmp = op1[i] + remain;
        c[i] = tmp / op2;
        remain = (tmp % op2) * 10000;//余下的数,用到低位,所以要乘以10000
    }
    
    if((a[0] == 9999 && b > 0) || (a[0] == 0 && b < 0)) {//如果一正一负,求补数
        toComp(c,c);
    }
}

void toComp(int* src,int* comp) {//负数求补数,取反+1
    int j;
    for(j = 0; j < N; j++) {
        comp[j] = 9999 - src[j];
    }
    comp[N - 1] += 1;
    
}

void absv(int* src,int* op) {//求补数,不用提前判断是不是负数
    if(src[0] == 9999) {
        toComp(src,op);
    } else {
        int i;
        for(i = 0; i < N; i++) {
            op[i] = src[i];
        }
    }
}

void print(int* c) {
    int v[N] = {0}; absv(c,v);
    if(c[0] == 9999) {//如果结果为负数
        printf("-");
    }
    
    int isDropZero = 1;//是否去掉0,没有作用的当然去掉
    int i;
    for(i = 0; i < N; i++) {
        char s[5] = {''};//字符数组
        sprintf(s,"%04d",v[i]);
        if(isDropZero) {//主要处理高位无用的0
            int j;
            for(j = 0; s[j] == '0' && j < 4; j++);//找到s中开始不为0时所对应的j,接下来会用到这个j
            if(j < 4) {
                isDropZero = 0;//已经去掉了前面的0
                for(; j < 4; j++) {
                    printf("%c",s[j]);
                }
            } else if(i == N - 1) {
                printf("0");
            }
        }else {//首位不为0的数字已经打印,剩下的直接打印就可以了
            printf(s);
        }
    }
    printf("n");
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读