如何实现大数相乘?

2025-01-03 17:13:55
推荐回答(3个)
回答1:

网上搜的,评分较高的。
/*--------------------------------------------------------------------------
*函数名称: 大数乘法
*函数过程:1 输入两个大数作为字符串
* 2 作一个双向链表
* 3 两个指针分别指向数字字符串的最低位
* 4 以第一个数的最低的一个位乘以第二个数的所有项存于链表中
* 5 链表首指针移
* 6 重复4,5依次从最低位乘到最高位
* 7 乘完后因为最低位是链表首,最后一位是链表尾。所以在逆顺输出链表。
* 4 直到循环结束
*入口参数:numa,numb,result字符串
*出口参数:无
*--------------------------------------------------------------------------*/
void multiply(char *numa, char *numb ,char *result)//用来储结果的)//计算乘积
{
char *pna = findend(numa);//指向numa的一个指针。point numa pna 指向乘数的最低位,
char *pnb = findend(numb);//指向numb的一个指针 //pnb 指向被乘数的最低位,
int along=(int)strlen(numa);//标记数字a的长度;
int blong=(int)strlen(numb);//标记数字b的长度;
int carry=0,temp_result;//存贮进位 和临时结果的
Node *head, // 用于存贮头指针
*pstart, // 用于存贮计算时的首指针
*pnew, //作于申请新结点
*pgo; //作为每计算完一行时,回到下一行起始节点用,移位标致来用
head = pstart =new Node;//初始化首结点和头结点。
pstart -> data = 0;
pstart -> next = NULL;
pstart -> ahead = NULL;
while (along--)
{
pgo = pstart;//保存进位点
blong = (int)strlen(numb);//初始化长度
pnb = findend(numb); //初始化指针
while ((blong-- && (blong>=0))|| carry != 0)
{
if(!pstart->next)//如果当前为空结点,则申请新结点
{
pnew = new Node;
pnew -> data = 0;
pnew -> next = NULL;
pnew -> ahead = pstart;
pstart -> next = pnew;
}
if(blong<0)temp_result = carry ;//处理只有进位的情况
else temp_result =(pstart->data+(*pna-48)*(*pnb-48)+carry);//自身值+新值+进位作为新值
pstart -> data = temp_result%10; //存贮个位
carry = temp_result/10; //存贮进位
pstart = pstart -> next; //结点移动
pnb--; //指针移向被乘数高位
}
pstart = pgo->next; //前进一个位置;
pna--; //指针移向乘数高位
}
pstart =head;//寻找链表的结尾点
while(pstart->next != 0)
{
pstart->data += 48;//!!<<<因为我们的输出是字符。所以再此加上48>>>> 逆顺输出
pstart = pstart->next ;
}
int tip = 0;//转为字符串用
pstart = pstart->ahead ;//找有效字
while(pstart != 0)//输出正序的结果;
{
result[tip++] = pstart->data;
pstart = pstart->ahead ;
}
result[tip] = '\0';
pstart =head; //释放空间
while(pstart->next != 0)
{
pnew = pstart->next ;delete pstart;
pstart =pnew;
}
return ;
}

回答2:

求M和N的乘积,输入是十进制整数。
当计算机可计算的最大整数是2^32时,2^16 * 2^16 = 2^32; 2^16 = 65536 > 10000 = 10^4。
M,N可以用如下表达式表示

M = M0*10^(4*0) + M1*10^(4*1) + M2 *10^(4*2) + M3 *10^(4*3) + .... + Mi*10^(4*i)
N = N0*10^(4*0) + N1*10^(4*1) + N2 *10^(4*2) + N3 *10^(4*3) + .... + Nj*10^(4*j)
其中 Mi>=0 && Mi <10000, Ni >=0 && Ni <65536, Mi, Ni可用一无符号16位整数表示。
M, N分别可用一32位无符号数 数组表示。
Mi*10(4*i) * Nj*10(4*j) = Mi * Nj *10(4(i + j))
假如R = M *N;
R = R0*10^(4*0) +R1*10^(4*1) + R2 *10^(4*2) + R3 *10^(4*3) + .... + Rk*10^(4*k);
R'k 为所有i+j = k的 Mi * Nj的和。R' >= 0 && R' <10^8 < 2^32;
R0 = R'0%10^4, R'1 = R'1 + R0 / 10^4;
. .
. .
. .
Rk-1 = R'k-1%10^4, R'k = R'k + R'k-1/10^4
Rk = R'k%10^4

比如M,N分别为32K字节的数组,即8k的32位整数数组,
M[8*1024] * N[8*1024] < 10^(4*(8*1024 + 8*1024)) = 10^(2^16) = 10^65536,
即可计算乘积为65536位10进制数以内的两个大整数乘法,提高M,N数组大小,可以得到更大乘积。该算法用乘法次数最小!

回答3:

你的数有多大?
typedef long long int Int64;
够用吗
不行就用字符串自己实现乘法