高精度乘高精度

C=A * B (A、B均是高精度数)
比如A=156,B=3,求A * B
在这里插入图片描述
很容易知道答案是468,怎样算的呢?
① 首先让3 * 6 = 18,然后向进一位,并且这位只保留8
② 让3 * 5 + 进位1 = 16,然后向前进一位,并且这位只保留6
③ 让3 * 1 + 进位1 = 4,此时不向前进位,保留4
所以最终答案是468

通过这个例子我们再来分析发现,C0 = A0 * B0,C1 = A1 * B0,C2 = A2 * B0,可以看出C的下标是和A、B下标相关的,0=0+0,1=1+0,2=2+0。

由此我们可以得出C[i+j] += A[i] * B[j]

那么核心代码就出来了

        c[i+j]+=a[i]*b[j]; 
	  	c[i+j+1]+=c[i+j]/10; // 进位 
	  	c[i+j]%=10;          //实际保留的值 

完整代码:

#include<iostream>
#include<cstring>
using namespace std;
int a[10000],b[10000],c[10000];
int main()
{
	string a1,b1;
	cin>>a1>>b1;
	
	int lena=a1.size();
	int lenb=b1.size();
	
	for(int i=lena-1,j=0; i>=0; i--,j++) a[j]=a1[i]-'0';
	for(int i=lenb-1,j=0; i>=0; i--,j++) b[j]=b1[i]-'0';
	
	for(int i=0; i<lena; i++)
	  for(int j=0; j<lenb; j++)
	  {
	  	c[i+j]+=a[i]*b[j]; 
	  	c[i+j+1]+=c[i+j]/10; // 进位 
	  	c[i+j]%=10;          //实际保留的值 
	  }
	
	int lenc=lena+lenb-1; // 两位数相乘最大位数是lena+lenb ,-1是因为下标从0开始
	while(c[lenc]==0 && lenc>0) lenc--; // 去前导0
	
	for(int i=lenc; i>=0; i--)
	{
		cout<<c[i];
	}
}

至于为什么是c[i+j]+=a[i]*b[j],而不是c[i+j]=a[i]*b[j],因为刚才上面的例子 B 是个一位数的,而实际中 B 是有很多位数字组成的,你要把那些都累加起来才能构成一个Ci的。

举个例子:
在这里插入图片描述
借鉴:高精度运算(大数运算)

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以使用string类来实现高精度运算,包括高精度乘法和支持负数的高精度运算。下面是一个基本的实现示例: ```cpp #include <iostream> #include <string> #include <algorithm> using namespace std; string add(string s1, string s2) { string res = ""; int carry = 0, i = s1.size() - 1, j = s2.size() - 1; while (i >= 0 || j >= 0 || carry != 0) { int x = i >= 0 ? s1[i--] - '0' : 0; int y = j >= 0 ? s2[j--] - '0' : 0; int sum = x + y + carry; res += sum % 10 + '0'; carry = sum / 10; } reverse(res.begin(), res.end()); return res; } string sub(string s1, string s2) { string res = ""; int borrow = 0, i = s1.size() - 1, j = s2.size() - 1; while (i >= 0 || j >= 0) { int x = i >= 0 ? s1[i--] - '0' : 0; int y = j >= 0 ? s2[j--] - '0' : 0; int diff = x - y - borrow; if (diff < 0) { diff += 10; borrow = 1; } else { borrow = 0; } res += diff + '0'; } reverse(res.begin(), res.end()); while (res.size() > 1 && res[0] == '0') res.erase(res.begin()); return res; } string mul(string s1, string s2) { string res(s1.size() + s2.size(), '0'); for (int i = s1.size() - 1; i >= 0; i--) { int carry = 0; for (int j = s2.size() - 1; j >= 0; j--) { int sum = (res[i + j + 1] - '0') + (s1[i] - '0') * (s2[j] - '0') + carry; res[i + j + 1] = sum % 10 + '0'; carry = sum / 10; } res[i] += carry; } while (res.size() > 1 && res[0] == '0') res.erase(res.begin()); return res; } int main() { string s1 = "-123456789"; string s2 = "987654321"; string res_add = add(s1, s2); string res_sub = sub(s1, s2); string res_mul = mul(s1, s2); cout << "s1 + s2 = " << res_add << endl; cout << "s1 - s2 = " << res_sub << endl; cout << "s1 * s2 = " << res_mul << endl; return 0; } ``` 在这个实现中,我们定义了三个函数:add、sub和mul。其中add和sub函数分别实现了高精度的加法和减法,mul函数实现了高精度乘法。在实现加法和减法时,我们可以通过比较两个字符串的长度来判断哪个数是负数,并对其进行特殊处理。在实现乘法时,我们使用了竖式乘法的思想,先一位一位地相乘,然后再将结果相加。 需要注意的是,在实现减法和乘法时,我们需要保证被减数和减数、被乘数和乘数的顺序,以便得到正确的结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值