大数相乘是指由于计算机无法保存的两数进行的乘法运算,因此我们可以通过字符数组来存储大数然后利用乘法规则自己编写算法将数组中的每一位相乘放到另外一个数组中。首先我们定义两个字符数组A、B分别存储两位大数,并将结果放到C中。若A的有效长度为lenA(出去符号之后的长度),B的有效长度为lenB,那么C的长度为lenA+lenB-1(最高位不进位)或lenA+lenB(最高位进位)。因此我们C数组的长度申请为lenA+lenB+1(包含'\0'的长度)。然后我们考虑A、B中的符号问题,利用函数Sign跳过A,B中的符号并将相乘后的符号放到变量sign中。由于我们平时进行的乘法运算都是从右往左算,这样保存在C数组中时也必须从右往左为算法带来了一些麻烦,于是我们可以考虑用一个函数将字符串进行翻转进行计算,算完后再将字符串翻转回去。在两数相乘的核心算法中我们用addCarry存储加法进位,用mulCarry存储乘法进位。计算的时候每乘一个数都立刻存放到C数组中。
</pre><pre class="cpp" name="code">#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//将字符串的顺序翻转
void reverse(char *str,int p,int q)
{
char temp;
while(p<q)
{
temp=str[p];
str[p]=str[q];
str[q]=temp;
p++;
q--;
}
}
char *multiLargeNum(char *A, char *B)
{
int lenA = strlen(A);
int lenB = strlen(B);
int lenC = lenA+lenB;
char *C = new char[lenC+1];//最后一位存放'/0'
int mulCarry = 0;//乘法进位
int addCarry = 0;//加法进位
int temp1=0,temp2=0;
int i,j;
//翻转两串
reverse(A,0,lenA-1);
reverse(B,0,lenB-1);
//将该串字符全部变为'0'
for(i=0;i<lenC;i++)
{
C[i]='0';
}
C[i]='\0';
for(i=0;i<lenB;i++)
{
mulCarry = 0;
addCarry = 0;
for(j=0;j<lenA;j++)
{
//A[j]-48将字母转化为数字
temp1 = (A[j]-48)*(B[i]-48) + mulCarry;
mulCarry = temp1/10;
temp1=temp1%10;
temp2=(C[i+j] - 48) + temp1 + addCarry;
addCarry = temp2/10;
C[i+j] = temp2%10 + 48;
}
C[i+lenA] += addCarry + mulCarry;
}
reverse(C,0,lenC-1);
return C;
}
//用于判断大数的符号并对其进行调整
void Sign(char *a,char *b)
{
char sign;//符号
//当A、B同为负号
if((a[0]=='-')&&(b[0]=='-')){
//跳过第一个字符
a++;
b++;
sign='+';
}else if((a[0]=='-')&&(b[0]!='-')){
a++;
sign='-';
}else if((a[0]!='-')&&(b[0]=='-')){
b++;
sign='-';
}else{
sign='+';
}
char *C = multiLargeNum(a,b);
printf("C=");
if(sign=='-')
printf("%c",sign);//打印负号
if(C[0]==0)
puts(C+1);
puts(C);//打印结果部分
delete[] C;
}
int main()
{
char A[] = "973432463";
char B[] = "-24566";
Sign(A,B);
return 0;
}