总结了一下大整数的加、乘操作涉及的代码。
需要注意的点:
- 注意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;
}