總結了一下大整數的加、乘操作涉及的代碼。
需要注意的點:
- 注意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;
}