C++大数操作Plus

来源:互联网 发布:php超链接 编辑:程序博客网 时间:2024/06/05 10:56

按照上次的思路,最近又重新实现了加减法以及大数的乘法,除法的话,实现起来难度还有点大,有比较好的思路再来续写吧。


#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 BigLen 10000     // length of the big number's array is BigLen#define BigCarry 1000   // carry of the big number's array is BigCarry/***Assumption bigNum is a big number,then the bigNum[0] is the lowest order digit while bigNum[BigLen-2] is the highest order digit and bigNum[BigLen-1] is sign bit.bigNum[BigLen-1] is -1 means bigNum is a negative number while bigNum[BigLen-1] is 1 means bigNum is a positive number or zero.We could define big number like this:int bigNum[BigLen];PS:I'm so sorry for my pool English. */using namespace std;bool add(int *sum, int *bigNum, int num);bool add(int *sum, int *bigNumA, int *bigNumB);int compare(int *bigNum,int num);int compare(int *bigNumA,int *bigNumB);int getTopPos(int *bigNum);bool input(int *bigNum, char *str);bool isBigNum(int *bigNum);bool multiply(int *product, int *bigNum, int num);bool multiply(int *product, int *bigNumA, int *bigNumB);bool output(int *bigNum);bool subtract(int *sub, int *bigNum, int num);bool subtract(int *sub, int *bigNumA, int *bigNumB);bool transBig2Num(int *bigNum, int &num);bool transNum2Big(int *bigNum, int num);bool isBigNum(int *bigNum){    /***    return true if the bigNum is legal big number while return false if not    */    for(int i = 0; i < BigLen-1; ++i)        if(bigNum[i] < 0 || bigNum[i] >= BigCarry)        return false;    if(bigNum[BigLen-1] != 1 && bigNum[BigLen-1] != -1)        return false;    return true;}bool input(int *bigNum, char *str){    /***    giving a integer string and a pointer of array which length equal to BigLen    the integer string have to be made up of integer figure from 0 to 9 and character '-' which means negative number    the function will return true if the string is legal while return false if not    */    int len = strlen(str);    if(len > (BigLen-1)*log10(BigCarry))        // the input string is too long so that the bigNum cannot save this number        return false;    int start = (str[0] == '-') ? 1 : 0;    bool isdigit = true;    for(int i = start; i < len; ++i){        if(str[i] < '0' || str[i] > '9'){            isdigit = false;            break;        }    }    if(!isdigit)        return false;   // the input string have some non numerical character except '-'    int index = 0;    int num = 0;    int power = 1;    for(int i = len-1; i >= start; --i){        num += (str[i]-'0') * power;        power *= 10;        if(power == BigCarry){            bigNum[index++] = num;            num = 0;            power = 1;        }    }    if(num)        bigNum[index++] = num;    for(int i = index; i < BigLen-1; ++i)        bigNum[i] = 0;    bigNum[BigLen-1] = start ? -1 : 1;    if(bigNum[0] == 0 && getTopPos(bigNum) == 0)    // this will be work if input the string like "-00000"        bigNum[BigLen-1] = 1;    return true;}bool multiply(int *product, int *bigNumA, int *bigNumB){    /***    computing the product of both bigNumA and bigNumB    */    if(product != bigNumA && product != bigNumB){        int topPosB = getTopPos(bigNumB);        int productTemp[BigLen];        int carry;        mem(product);        product[BigLen-1] = 1;        for(int i = 0; i <= topPosB; ++i){            int num = bigNumB[i];            carry = 0;            mem(productTemp);            productTemp[BigLen-1] = 1;            for(int j = 0; j < BigLen-1; ++j){                carry += bigNumA[j] * num;                productTemp[j] = carry % BigCarry;                carry /= BigCarry;           }            if(carry)       // return false if overflow                return false;            int topPosProductTemp = getTopPos(productTemp);            if(topPosProductTemp + i >= BigLen-1)   // overflow                return false;            for(int j = BigLen-2; j >= i; --j)                productTemp[j] = productTemp[j-i];            for(int j = 0; j < i; ++j)                productTemp[j] = 0;            if(!add(product,product,productTemp))                return false;        }        delete productTemp;        product[BigLen-1] = bigNumA[BigLen-1] * bigNumB[BigLen-1];        return true;    }    else{        int productTemp[BigLen];        mem(productTemp);        if(!multiply(productTemp,bigNumA,bigNumB))            return false;        for(int i = 0; i < BigLen; ++i)            product[i] = productTemp[i];        delete productTemp;        return true;    }}bool multiply(int *product, int *bigNum, int num){    /***    computing the product of both bigNum and num    */    int numSign;    num = (num >= 0) ? (numSign = 1 , num) : (numSign = -1 , -num);    if(num * BigCarry > inf){        int small[BigLen];        mem(small);        transNum2Big(small,num);        bool ans = multiply(product,bigNum,small);        delete small;        return ans;    }    else{        int carry = 0;        for(int i = 0; i < BigLen-1; ++i){            carry += bigNum[i] * num;            product[i] = carry % BigCarry;            carry /= BigCarry;        }        product[BigLen-1] = bigNum[BigLen-1] * numSign;        return carry ? false : true;    // return false if overflow    }}bool subtract(int *sub, int *bigNum, int num){    /***    computing the different of both bigNum and num    */    // 这个好麻烦啊→_→ 不想写了,简单调用一下吧。。。(using English cannot express my feelings)    // ignoring the above sentence, please    int small[BigLen];    mem(small);    transNum2Big(small,num);    bool ans = subtract(sub,bigNum,small);    delete small;    return ans;}bool add(int *sum, int *bigNum, int num){    /***    computing the sum of both bigNum and num    */    if(bigNum[BigLen-1] == 1){        if(num >= 0){       // bigNum >= 0 && num >= 0            int carry = num / BigCarry;            int t = num % BigCarry + bigNum[0];            carry += t / BigCarry;            sum[0] = t % BigCarry;            for(int i = 1; i < BigLen-1; ++i){                t = carry + bigNum[i];                sum[i] = t % BigCarry;                carry = t / BigCarry;            }            sum[BigLen-1] = bigNum[BigLen-1];            return carry ? false : true; // return false if overflow        }        else{       // bigNum >= 0 && num < 0            return subtract(sum,bigNum,-num);        }    }    else{        if(num >= 0){       // bigNum < 0 && num >= 0            bigNum[BigLen-1] = 1;            bool ans = subtract(sum,bigNum,num);            if(bigNum != sum)                bigNum[BigLen-1] = -1;            sum[BigLen-1] *= -1;            return ans;        }        else{       // bigNum < 0 && num < 0            bigNum[BigLen-1] = 1;            bool ans = add(sum,bigNum,-num);            bigNum[BigLen-1] = -1;            sum[BigLen-1] = -1;            return ans;        }    }}bool subtract(int *sub, int *bigNumA, int *bigNumB){    /***    computing the difference of both bigNumA and bigNumB    */    if(bigNumA[BigLen-1] == 1){        if(bigNumB[BigLen-1] == 1){     // bigNumA >= 0 && bigNumB >= 0            if(compare(bigNumA,bigNumB) >= 0){                int carry = 0;                for(int i = 0; i < BigLen-1; ++i){                    carry += bigNumA[i] - bigNumB[i] + BigCarry;                    sub[i] = carry % BigCarry;                    carry = carry / BigCarry - 1;                }                sub[BigLen-1] = 1;                return carry ? false : true;       // return false if overflow            }            else{                bool ans = subtract(sub,bigNumB,bigNumA);                sub[BigLen-1] = -1;                return ans;            }        }        else{       // bigNumA >=0 && bigNumB < 0            bigNumB[BigLen-1] = 1;            bool ans = add(sub,bigNumA,bigNumB);            if(bigNumB != sub)                bigNumB[BigLen-1] = -1;            return ans;        }    }    else{        if(bigNumB[BigLen-1] == 1){     // bigNumA < 0 && bigNumB >=0            bigNumA[BigLen-1] = 1;            bool ans = add(sub,bigNumA,bigNumB);            bigNumA[BigLen-1] = -1;            sub[BigLen-1] = -1;            return ans;        }        else{       // bigNumA < 0 && bigNumB < 0            bigNumA[BigLen-1] = 1;            bigNumB[BigLen-1] = 1;            bool ans = subtract(sub,bigNumB,bigNumA);            if(bigNumB != sub)                bigNumB[BigLen-1] = -1;            if(bigNumA != sub)                bigNumA[BigLen-1] = -1;            return ans;        }    }}bool add(int* sum, int *bigNumA, int *bigNumB){    /***    computing the sum of both bigNumA and bigNumB    */    if(bigNumA[BigLen-1] == bigNumB[BigLen-1]){     // both bigNumA and bigNumB are negative or positive numbers        int carry = 0;        for(int i = 0; i < BigLen-1; ++i){            carry += bigNumA[i] + bigNumB[i];            sum[i] = carry % BigCarry;            carry /= BigCarry;        }        sum[BigLen-1] = bigNumA[BigLen-1];        return carry ? false : true;       // return false if overflow    }    else{        if(bigNumA[BigLen-1] == -1){            bigNumA[BigLen-1] = 1;            bool ans = subtract(sum,bigNumB,bigNumA);            if(bigNumA != sum)                bigNumA[BigLen-1] = -1;            return ans;        }        else{            bigNumB[BigLen-1] = 1;            bool ans = subtract(sum,bigNumA,bigNumB);            if(bigNumB != sum)                bigNumB[BigLen-1] = -1;            return ans;        }    }}bool transNum2Big(int *bigNum, int num){    /***    transferring a integer number to bigNum    */    bigNum[BigLen-1] = (num >= 0 ? 1 : -1);    num = (num >= 0 ? num : -num);    int index = 0;    while(num > 0){        bigNum[index++] = num % BigCarry;        num /= BigCarry;    }    return true;}bool transBig2Num(int *bigNum, int &num){    /***    transferring a bigNum to a integer number    */    int topPos = getTopPos(bigNum);    if(int(topPos*log10(BigCarry) + log10(bigNum[topPos])) >= int(log10(inf)))        return false;       // return false if this num is not less than 1,000,000,000, but actually the biggest integer is 2,147,483,647(that is inf)    num = bigNum[BigLen-1];    num = num*bigNum[topPos];    for(int i = topPos-1; i >= 0; --i)        num = num*BigCarry + bigNum[i];    return true;}int compare(int *bigNum, int num){    /***    if bigNum > num, then return 1    if bigNum = num, then return 0    if bigNum < num, then return -1    */    int bigSign = bigNum[BigLen-1];    if(bigSign * num >= 0){        int topPos = getTopPos(bigNum);        int bigDigits = topPos*log10(BigCarry) + log10(bigNum[topPos]);        int numDigits = log10(num);        if(bigDigits != numDigits)            return bigDigits > numDigits ? bigSign : -bigSign;        int big;        if(transBig2Num(bigNum,big)){            if(big != num)                return big > num ? 1 : -1;            else                return 0;        }        else{            int small[BigLen];            mem(small);            transNum2Big(small,num);            int ans = compare(bigNum,small);            delete small;            return ans;        }    }    else{        return num > 0 ? -1 : 1;    }}int compare(int *bigNumA,int *bigNumB){    /***    if bigNumA > bigNumB, then return 1    if bigNumA = bigNumB, then return 0    if bigNumA < bigNumB, then return -1    */    if(bigNumA[BigLen-1] != bigNumB[BigLen-1])        return bigNumA[BigLen-1] > bigNumB[BigLen-1] ? 1 : -1;    // both bigNumA and bigNumB are positive numbers or negative numbers    int sign = bigNumA[BigLen-1];    int topPosA = getTopPos(bigNumA);    int topPosB = getTopPos(bigNumB);    if(topPosA != topPosB)        return topPosA > topPosB ? sign : -sign ;    for(int i = topPosA; i >= 0; --i)        if(bigNumA[i] != bigNumB[i])            return bigNumA[i] > bigNumB[i] ? sign : -sign ;    return 0;}int getTopPos(int *bigNum){    /***    return the array index of bigNum's highest digits    return 0 if the bigNum is zero    */    for(int topPos = BigLen-2; topPos >= 0; --topPos)        if(bigNum[topPos])            return topPos;    return 0;}bool output(int *bigNum){    /***    output big number bigNum and carriage return is followed    */    if(!isBigNum(bigNum))        return false;    int topPos = getTopPos(bigNum);    if(bigNum[BigLen-1] == -1 && (topPos || bigNum[topPos]))        printf("-");    printf("%d",bigNum[topPos]);    char formatLen[2] = {char(log10(BigCarry)) + '0'};    char format[6] = "%0";    strcat(format,formatLen);    strcat(format,"d");    for(int i = topPos-1; i >= 0; --i)        printf(format,bigNum[i]);    printf("\n");    return true;}

欢迎各界大佬指出bug,非常感谢!

原创粉丝点击