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

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

  • 注意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;
}
发布了116 篇原创文章 · 获赞 27 · 访问量 5万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章