整数大数据进行运算的时候并不能简单使用一个变量去存储结果,因为运算结果可能超出该变量能存储的最大字节数。因此可以使用一个SeqList或者STL中的vector对数据进行存储。
在进行乘法运算时,根据乘法的运算规则,每次对一列求和即可,求和完成要求的进位。最后每一列求和完的结果和即为乘法结果。
1. 求出列数与被乘数个数相同各列的和。
(1) 被乘数从i位置开始,乘数从j位置开始,i位置与j位置的数相乘,此时就算乘出的数大于10不着急进位,会在求和的时候进位。i–-, j++,直到i走到被乘数个位数的下一个。此时得到相同一列的数据。
(2) 同一列相加求和,再加上上一列的进位,对和sum进行取余操作存入SeqList中,sum / 10 得到进位值。
(3) 以此类推,得到第一个乘数与被乘数最后一位相乘所得到的结果数据。而且得到是个位数与被乘数所有位相乘的结果即每一行,十位数与被乘数除最后一位相乘的结果,以此类推,最后一位只于被乘数的个位相乘。
for (j = 1; i == 1 && j < size; ++j) {
sum = 0;
for (k = j, l = 1; k >= 1 && l <= j; --k, ++l) {
value = big1.big[k] * big2.big[l];
sum += value;
}
big.big[count++] = (sum + carry) % 10;
carry = (sum + carry) / 10;
}
2. 求出剩下的所有列数的各列之和
(1) i从被乘数的最后一位出发,j从十位开始。i位置的数和j位置的数相乘,i++, j--,继续相乘,直到j走到最后一位的下一位。然后调整i到被乘数的最后一位,j从百位出发,重复上述过程,直到调整j位乘数最后一位的下一位。
(2) 这样可得出乘数各位与被乘数各位相乘的结果。当乘数最后一位与被乘数最后一位相乘,余数已经存储在SeqList中,但如果有进位,需要最后对进位进行相应的处理。
3. 完整代码如下:
voidBigInt::Mul(BigInt &big, const BigInt &big1, const BigInt &big2) {
unsigned long value, sum = 0;
unsigned long i = 1;
unsigned long j, k, l, cnt;
unsigned int carry = 0; // 进位值
unsigned int count = 1;
for (i = 1; i < big2.size(); ++i) {
// sum = 0;
// 求出求出列数与被乘数个数相同各列的和
for (j = 1; i == 1 && j <size; ++j) {
sum = 0;
for (k = j, l = 1; k >= 1&& l <= j; --k, ++l) {
value = big1.big[k] *big2.big[l];
sum += value;
}
big.big[count++] = (sum + carry) %10;
carry = (sum + carry) / 10;
}
// 求出剩余列数的各列之和
for (k = size - 1, l = i; i != 1 && l< big2.size(); --k, ++l) {
value = big1.big[k] * big2.big[l];
sum += value;
}
if (i != 1) {
big.big[count++] = (sum + carry) %10;
carry = (sum + carry) / 10;
}
sum = 0;
}
// 处理最高位的进位
for ( ; carry; ) {
big.big[count++] = carry % 10;
carry /= 10;
}
for (i = count - 1; i >= 1; --i) {
cout << big.big[i];
}
cout << endl;
}
如果SeqList的类型位char,那么是否每次只存入一个数据,也就是一个字节,浪费空间,因此可以采用每次256进制的方法进行进位,以便节省大量的数据空间。其他数据类型也可以采用这样的方式。