总结:大整数类加法、乘法

来源:互联网 发布:java手机 编辑:程序博客网 时间:2024/05/21 00:46

总结了一下大整数的加、乘操作涉及的代码。
需要注意的点:

  • 注意C++类的语法,尤其是构造函数、重载内访问另一个对象
  • 数字在数组中是逆序存放的,每一位都是十进制表示,用len来记录这个大整数的有效长度
  • 加法操作时,由于两个数的长度可能不一,因此不能漏掉多出来的那一段,以及最后的溢出位。
  • 乘法操作时,每一次外层循环(从最低位开始遍历第二个数)得到的乘法结果,要和前一次乘法结果错开一位相加。
  • 输出时,注意len=0即数字为0的情况。
#include <iostream>#include <cstdio>#include <cstdlib>#include <string>#include <cstring>using namespace std;class BigInt //自定义大整数类{public:    int num[105], len; //数字逆序存放    BigInt():len(0){} //初始化    BigInt(long long int n):len(0) //构造函数:long long int    {        while(n > 0)        {            num[len++] = n % 10;            n /= 10;        }    }    BigInt(string s):len(0) //构造函数:字符串    {        for (int i = s.length()-1; i >= 0; --i)            num[len++] = s[i]-'0';    }    BigInt operator + (const BigInt & b) //重载+    {        BigInt res;        int cnt, carry = 0; //carry存放将要加到这一位结果的值        for (cnt = 0; cnt < this->len || cnt < b.len || carry > 0; ++cnt) //不要漏掉最后carry>0的情况        {            if (cnt < this->len)                carry += this->num[cnt];            if (cnt < b.len)                carry += b.num[cnt];            res.num[cnt] = carry % 10;            carry /= 10;        }        res.len = cnt;        return res;    }    BigInt operator += (const BigInt & b) //重载+=    {        *this = *this + b;        return *this;    }    BigInt operator * (const BigInt & b) //重载*    {        BigInt res;        int mul[105] = {0}; //存放临时结果        for (int i = 0; i < b.len; ++i) //模拟乘法运算和错位相加,先不考虑进位        {            for (int j = 0; j < len; ++j)                mul[i+j] += b.num[i] * num[j];        }        int last = 100;        while (last >= 0 && mul[last] == 0) last--; //确定非0的最高位下标last        if (last >= 0)        {            int carry = 0;            for (int i = 0; i <= last; ++i)  //统一进位            {                mul[i] += carry;                carry = mul[i] / 10;                mul[i] %= 10;            }            if (carry) //最高位溢出                mul[last+1] = carry;            res.len = (carry == 0) ? last+1 : last+2; //结果的长度            memcpy(res.num, mul, sizeof(int)*105); //数值拷贝到结果中        }        return res;    }    BigInt operator *= (const BigInt &b) //重载*=    {        *this = *this * b;        return *this;    }    void print() //输出    {        printf("Length: %d\nValue: ", len);        if (len == 0) //注意值为0时长度为0        {            printf("0\n");            return;        }        for (int i = len-1; i >= 0; --i)            printf("%d", num[i]);        printf("\n");    }};const int maxn = 10005;BigInt a[maxn];void addTest() //POJ 1503---AC{    int i = 0;    string s;    BigInt ans(0);    while (cin >> s && s != "0")    {        a[i] = BigInt(s);        ans += a[i];        i++;    }    ans.print();}void mulTest() //测试:大数乘法{    string a,b;    BigInt x, y, z;    while(cin >> a >> b)    {        x = BigInt(a);        y = BigInt(b);        z = x * y;        z.print();    }}void FibonacciAdd() //测试:计算斐波那契数列{    a[0] = BigInt(0);    a[1] = BigInt(1);    int n;    while(cin >> n)    {        for (int i = 2; i <= n; ++i)        {            if (a[i].len == 0)                a[i] = a[i-1] + a[i-2];        }        a[n].print();    }}int main(){    //addTest();    //FibonacciAdd();    mulTest();    return 0;}
原创粉丝点击