【大整数乘法】

  1. 问题

 

2.伪代码

  • 理想情况下,XY位数相同
Mul(long long x,long long y,int num){
	Fh<--(x*y>0)?1:-1;
	x<--|x|; y<--|y|;
	if(num == 0)then return 0;
	else if(num==1) then return fh*x*y;
	else{
        x_high<--x/10^(num/2);
        x_low<--x mod 10^(num/2);
        y_high<--y/10^(num/2);
        y_low<--y_mod 10^(num/2);
		High<--mul(x_high,y_high, num/2);
        Low<--mul(x_low,y_low,num/2);
		Mid<--mul((x_high-x_low),(y_low-y_high),num/2)+High+Low;
		return fh* High*10^num +Mid*10^(num/2)+Low;
		}
}
Main(){
	Input:A,B;
	Temp<--A;
	While(temp) do{
		n++;
		temp<--temp/10;
}
	Return mul(a,b,n);
}

       

  • 非理想情况下,XY位数不同
Mul(long long x, int numx, long long y, int numy){
	Fh<--(x*y>0)?1:-1;
	x<--|x|; y<--|y|;
	if(numx == 0 || numy == 0) then return 0;
	else if((numx == 1 && numy == 1) || numx == 1 || numy == 1) then return fh*x*y;
	else{
		 x_low <-- numx / 2;
		 x_high<-- numx - x_low;
		 y_low <-- numy / 2;
		 y_high<-- numy - y_low;
		//记录XY分的高低位的位数。

		A <-- x / 10^x_low;
		B <-- x % 10^x_low;
		C <-- y / 10^y_low;
		D <-- y % 10^y_low;
		//获取XY的高低位的数值。

		AC<--mul(A, x_high, C, y_high);
		BD<-- mul(B, x_low, D, y_low);
		ABCD<--mul(( (A *10^x_low) - B), x_high, (D - (C * 10^y_low)), y_high);
		return fh * (2 * AC * 10^(x_low+y_low) + ABCD + 2 * BD);
	}
} 
Main(){
	Input:A,B;
	Temp<--A;
While(temp) do{
		n1++;
		temp<--temp/10;
}
Temp<--B;
While(temp) do{
		n2++;
		temp<--temp/10;
}
	Return mul(a,n1,b,n2);
}

  1. 源代码及结果
  • 理想情况下,XY位数相同
#include<bits/stdc++.h>
using namespace std;
#define sign(x) ((x>0)? 1:-1)

long long mul(long long x,long long y,int num){
		int fh=sign(x)*sign(y);
		x=x>0?x:-x;
		y=y>0?y:-y;
		if(num==0)
			return 0;
		else if(num==1)		
			return fh*x*y;
		else
		{
				long long x_high=x/(int)pow(10,(int)(num/2));
				long long x_low=x%(int)pow(10,(int)(num/2));
				long long y_high=y/(int)pow(10,(int)(num/2));
				long long y_low=y%(int)pow(10,(int)(num/2));
			
			    long long High=mul(x_high,y_high,(int)(num/2));
			    long long Low=mul(x_low,y_low,(int)(num/2));
			    long long Mid=mul((x_high-x_low),(y_low-y_high),(int)(num/2))+High+Low;
			    return fh*(long long)(High*pow(10,(int)(num/2)+(int)(num/2))+Mid*pow(10,(int)(num/2))+Low);
		}
}
int main(){
	long long a,b,c,temp;
	int n=0;
	while(cin>>a>>b){
		temp=a;
		while(temp){
			n++;
			temp=temp/10;
		}
		c=mul(a,b,n);
		cout<<c<<endl;
	}
	return 0;
}

运行结果:

 

  • 非理想情况下,XY位数不同
#include <bits/stdc++.h>
using namespace std;
#define sign(x) ((x>0)? 1:-1)


long long  mul(long long x, int numx, long long y, int numy) {
	int fh = sign(x) * sign(y);
	x = x > 0 ? x : -x;
	y = y > 0 ? y : -y;
	if (numx == 0 || numy == 0)
		return 0;
	else if ((numx == 1 && numy == 1) || numx == 1 || numy == 1) {
		return fh * x * y;
	} else {
		int x_low = numx / 2;
		int x_high = numx - x_low;
		int y_low = numy / 2;
		int y_high = numy - y_low;

		long long A = x / (int)pow(10, x_low);
		long long B = x % (int)pow(10, x_low);
		long long C = y / (int)pow(10, y_low);
		long long D = y % (int)pow(10, y_low);

		long long AC = mul(A, x_high, C, y_high);
		long long BD = mul(B, x_low, D, y_low);
		long long ABCD = mul(((long long)(A * pow(10, x_low)) - B), x_high, (D - (long long)(C * pow(10, y_low))), y_high);
		return fh * (long long)(2 * AC * pow(10, (x_low + y_low)) + ABCD + 2 * BD);
	}
}

int main() {
	long long a, b, c, temp;
	int n1 = 0, n2 = 0;

	while (cin >> a >> b) {
		temp = a;
		while (temp) {
			n1++;
			temp = temp / 10;
		}
		temp = b;
		while (temp) {
			n2++;
			temp = temp / 10;
		}
		c = mul(a, n1, b, n2);
		cout << c << endl;
		n1 = 0;
		n2 = 0;
	}
	return 0;
}

运行结果:

 

4.分析

①理想情况下,XY位数相同时:

 

如图所示,即X=A*10^(n/2)+B ,Y=C*10^*(n/2)+D;

 本来可以直接算(AD+BC),但是这样效率变低了,所以对(AD+BC)进行分解优化后得:

②非理想情况下,XY位数不同时:

 当XY位数不相同时,我们采用分治法将它拆分为A与B、C与D,因为位数不相同,所以此时我们就要先获取分完之后XY高低位的位数与高低位的值,此时:

XY=(A*10^x_low+B)*(C*10^y_low+D)

    =AC*10^(x_low+y_low)+(AD*10^x_low+BC*10^y_low)+BD

中间那部分进行分解优化后得:

ABCD=(A*10^x_low-B)(D-C*10^y_low)

=AD*10^x_low-AC*10^(x_low+y_low)-BD+BC*10^y_low;

则AD*10^x_low+BC*10^y_low

=ABCD+ AC*10^(x_low+y_low)+BD;

所以

XY= 2*AC*10^(x_low+y_low)+ABCD+2*BD

所以最后的返回值为:

fh * (2 * AC * pow(10, (x_low + y_low)) + ABCD + 2 * BD);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值