C++大数操作

来源:互联网 发布:做注册单开淘宝店铺 编辑:程序博客网 时间:2024/06/16 20:53

今天想试着实现了一些C++大数的操作,忙活的时间不少,只不过就实现了加减法,乘除的方法只能有时间再来实现了。

说点心得,我下面大数的存储方式很蠢(起初没想着实现负数哭  后来写减法的时候就想着也把负数的实现了奋斗 实现起来的时候才发现自己给自己挖了一个大坑),下次实现大数的话,符号估计会单独存储,这样处理乘除法也比较方便。


#include<iostream>#include<cstdlib>#include<cstdio>#include<memory.h>#include<cstring>#include<cmath>#include<algorithm>#include<vector>#include<queue>#define mem(array)  memset((array),0,sizeof((array)))#define Qsort(array,len,cmp) qsort(array,len,sizeof(array[0]),cmp)#define inf 0x7fffffff#define MAXN 1000#define BigLen 1000#define BigCarry 1000using namespace std;int compareBig(int *a, int *b);int getTopDigits(int *a);int getBigLen(int *a);int* addBig(int *sum,int *a, int *b);int* addSmall(int *sum,int *big, int small);int* subtractBig(int *sub,int *a,int *b);int* subtractSmall(int *sub,int *big, int small);int outputBig(int *a);int compareBig(int *a, int *b) /*** if a > b then return 1 while return -1 when a < b ,other case(a = b) return 0 */{    int aTopDigits = getTopDigits(a);    int bTopDigits = getTopDigits(b);    if(aTopDigits < 0 && bTopDigits > 0) /*** a is a negative number while b is a positive number */        return -1;    else if(aTopDigits > 0 && bTopDigits < 0) /*** a is a positive number while b is a negative number */        return 1;    /*** both a and b are negative number or positive number */    int aLen = getBigLen(a);    int bLen = getBigLen(b);    int flag = (aTopDigits>0 ? 1 : -1);    if(aLen < bLen)        return -flag;    else if(aLen > bLen)        return flag;    else{        if(a[aLen] < b[aLen])            return -1;        else if(a[aLen] > b[aLen])            return 1;        for(int i = aLen-1; i >= 0; --i){            if(a[i] < b[i])                return -flag;            else if(a[i] > b[i])                return flag;        }    }    return 0;}int getTopDigits(int *a){    for(int i = BigLen-1; i >= 0; --i){        if(a[i])            return a[i];    }}int getBigLen(int *a){    int cnt;    for(cnt = BigLen-1; cnt >= 0; --cnt){        if(a[cnt])            return cnt+1;            //break;    }/***    int digits;    if(abs(a[cnt]) >= 100)        digits = 3;    else if(abs(a[cnt]) >= 10)        digits = 2;    else if(abs(a[cnt]) >= 0)        digits = 1;    else        return -1;    digits += cnt*(int)log10(BigLen);    return digits;    */}int* addBig(int *sum,int *a, int *b)  /*** sum = a + b */{    int aTopDigits = getTopDigits(a);    int bTopDigits = getTopDigits(b);    if(aTopDigits >= 0 && bTopDigits >= 0){ /*** a is a positive number while b is a positive number*/        int t;        int carry = 0;        for(int i = 0; i < BigLen; ++i){            t = a[i] + b[i] + carry;            sum[i] = t % BigCarry;            carry = t / BigCarry;        }        return sum;    }    else if(aTopDigits >= 0 && bTopDigits < 0){ /*** a is a positive number while b is a negative number*/        int *t = new int[BigLen];        for(int i = 0; i < BigLen; ++i)            t[i] = b[i];        int index = getBigLen(t)-1;        t[index] = -t[index];        subtractBig(sum,a,t);        delete t;        return sum;    }    else if(aTopDigits < 0 && bTopDigits >= 0){ /*** a is a negative number while b is a positive number*/        return addBig(sum,b,a);    }    else if(aTopDigits < 0 && bTopDigits < 0){ /*** a is a negative number while b is a negative number*/        int *t1 = new int[BigLen];        int *t2 = new int[BigLen];        for(int i = 0; i < BigLen; ++i){            t1[i] = a[i];            t2[i] = b[i];        }        int index_1 = getBigLen(t1)-1;        int index_2 = getBigLen(t2)-1;        t1[index_1] = -t1[index_1];        t2[index_2] = -t2[index_2];        addBig(sum,t1,t2);        delete t1,t2;        int index = getBigLen(sum) - 1;        sum[index] = -sum[index];        return sum;    }}int* addSmall(int *sum,int *big, int small) /**** sum = big + small , compute a big number and a small number , big number must be greater than 0 */{    if(small < 0)        return subtractSmall(sum,big,-small);    int t = small % BigCarry;    int carry = small / BigCarry;    int index;    for(index = 0; (t||carry) && index < BigLen; ++index){        t += big[index];        sum[index] = t % BigCarry;        carry += t / BigCarry;        t = carry % BigCarry;        carry /= BigCarry;    }    while(index < BigLen)        sum[index] = big[index++];    return sum;}int* subtractBig(int *sub,int *a,int *b) /*** sub = a - b */{    int aTopDigits = getTopDigits(a);    int bTopDigits = getTopDigits(b);    if(aTopDigits >= 0 && bTopDigits >= 0){ /*** a is a positive number while b is a positive number*/        int t;        int carry = 0;        for(int i = 0; i < BigLen; ++i){            t = a[i] - b[i] - carry;            t >= 0 ? carry = 0 : (carry = 1,t += BigCarry);            sub[i] = t;        }        if(carry){            for(int i = 0; i < BigLen; ++i)                sub[i] = BigLen - sub[i] - 1;            addSmall(sub,sub,1);            for(int i = BigLen-1; i >= 0; --i)                if(sub[i]){                    sub[i] = -sub[i];                    break;                }        }        return sub;    }    else if(aTopDigits >= 0 && bTopDigits < 0){ /*** a is a positive number while b is a negative number*/        int *t = new int[BigLen];        for(int i = 0; i < BigLen; ++i)            t[i] = b[i];        int index = getBigLen(t)-1;        t[index] = -t[index];        addBig(sub,a,t);        delete t;        return sub;    }    else if(aTopDigits < 0 && bTopDigits >= 0){ /*** a is a negative number while b is a positive number*/        int *t = new int[BigLen];        for(int i = 0; i < BigLen; ++i)            t[i] = a[i];        int index = getBigLen(t)-1;        t[index] = -t[index];        addBig(sub,t,b);        delete t;        index = getBigLen(sub) - 1;        sub[index] = -sub[index];        return sub;    }    else if(aTopDigits < 0 && bTopDigits < 0){ /*** a is a negative number while b is a negative number*/        int *t1 = new int[BigLen];        int *t2 = new int[BigLen];        for(int i = 0; i < BigLen; ++i){            t1[i] = a[i];            t2[i] = b[i];        }        int index_1 = getBigLen(t1) - 1;        int index_2 = getBigLen(t2) - 1;        t1[index_1] = -t1[index_1];        t2[index_2] = -t2[index_2];        subtractBig(sub,t2,t1);        delete t1,t2;        return sub;    }}int* subtractSmall(int *sub,int *big, int small) /**** sub = big - small , compute a big number and a small number , big number must be greater than 0 */{    if(small < 0)        return addSmall(sub,big,-small);    int t = small % BigCarry;    int carry = small / BigCarry;    int index;    for(index = 0; (t||carry) && index < BigLen; ++index){        sub[index] = big[index] - t;        /** sub[index] < 0 ? (sub[index] += BigCarry , ++carry) : ; */        if(sub[index] < 0){            sub[index] += BigCarry;            ++carry;        }        t = carry % BigCarry;        carry /= BigCarry;    }    while(index < BigLen)        sub[index] = big[index++];    return sub;}int outputBig(int *a){    int index = -1;    for(int i = BigLen-1; i >= 0; --i)        if(a[i] != 0){            index = i;            printf("%d",a[i]);            break;        }    for(int i = index-1; i >= 0; --i)        printf("%03d",a[i]);    if(index == -1)        cout<<0;    cout<<endl;}int a[MAXN];int b[MAXN];int c[MAXN];int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    mem(a);    mem(b);    mem(c);    for(int i = 0; i < 10; ++i){        a[i] = 555;        b[i] = 555;    }    b[0] = 556;    //b[10] = -1;    a[10] = -1;    //addBig(c,a,b);    subtractBig(c,a,b);    //cout<<compareBig(a,b)<<endl;    //cout<<getTopDigits(a)<<endl;    //cout<<getBigLen(a)<<endl;    //addSmall(c,a,-566);    //subtractSmall(c,a,0);    //outputBig(c);    //subtractBig(c,a,b);    //subtractSmall(b,a,9999);    //subtractSmall(a,a,999);    outputBig(a);    outputBig(b);    outputBig(c);    return 0;}


原创粉丝点击