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

来源:互联网 发布:centos7 安装网络配置 编辑:程序博客网 时间:2024/05/01 17:27

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

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

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

//主程序int a[] = {0, 0, 0, 0, 0, 0, 21, 0};int b[] = {9999, 9999, 9999, 9999, 9999, 9999, 9999, 9901}; // -99的补码表示形式,且当作是机器中的表示形式int c1[N], c2[N], c3[N], c4[N] = {0};add(a, b, c1);       print(c1);subtract(a, b, c2);  print(c2);multiply(a, -3, c3); print(c3);divide(a, -3, 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* b, int* c) {    if(b[0] == 9999) {//判断b是不是负数        int comp[N] = {0};        toComp(b, comp);//求补数        add(a, comp, 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 b, int *c) {  // b 為除數    int op1[N] = {0}; absv(a, op1);    int op2 = abs(b);        int i, tmp, 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] = {'\0'};//字符数组        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");}






0 0
原创粉丝点击