高精度除法(高精除以高精)模板

(若想查看高精除以单精,请点击链接)链接
嗯,这个还有点儿难度(虽然不常用),其实也不难,稍微讲讲吧!

在用竖式计算除法的时候,用减法模拟每次的相除,从高位到低位,每次减到不能再减为止,然后向后移一位。嗯,就这样。

Code

#include<bits/stdc++.h>
using namespace std;

int c[300];
char ch1[300],ch2[300],ans[300];

bool cmp(int p,char ch1[],char ch2[])//对前p位的被除数字符串ch1和整个除数字符串ch2比较大小
{
	int l=1;
	while(ch1[l]=='0'&&l<=p-1) l++;//删除被除数的第p位之前已经被减为0的位
	char tch[300];
	int cnt=0;
	for(int i=l;i<=p;i++)
	{
		tch[++cnt]=ch1[i];//把被除数删完之后的部分存储在tch里
	}
	tch[cnt+1]='\0';
	if(strlen(tch+1)>strlen(ch2+1)||(strlen(tch+1)==strlen(ch2+1)&&strcmp(tch+1,ch2+1)>=0)) return true;
	//如果被除数位数比除数位数多,被除数大
	//如果两者位数相等,根据字母序比较两个字符串大小即可
	else return false;
}

void subtraction(int p,char ch1[],char ch2[])
{
	int l=1;
	while(ch1[l]=='0'&&l<=p-1) l++;//删除被除数的第p位之前已经被减为0的位
	char tch[300];
	int cnt=-1;
	for(int i=l;i<=p;i++)
	{
		tch[++cnt]=ch1[i];//把被除数删完之后的部分存储在tch里
	}
	int ta[300],tb[300];
	memset(ta,0,sizeof(ta));
	memset(tb,0,sizeof(tb));
	int len2=strlen(ch2+1);
	for(int i=1;i<=cnt+1;i++) ta[i]=tch[cnt+1-i]-'0';//把被除数要相减的部分转化为整数数组
	for(int i=1;i<=len2;i++) tb[i]=ch2[len2+1-i]-'0';//把除数转化为整数数组
	int tc[300];
	memset(tc,0,sizeof(tc));
	for(int i=1;i<=cnt+1;i++)//高精度减法模板
	{
		if(ta[i]-tb[i]<0)
		{
			ta[i+1]--;
			ta[i]+=10;
		}
		tc[i]=ta[i]-tb[i];
	}
	for(int i=1;i<=cnt+1;i++)
	{
		ch1[l-1+i]=tc[cnt+2-i]+'0';//将相减的结果又转化成字符串,并更新被除数
	}
}

void add_ans(int p)
{
	ans[p]++;
}

int main()
{
	cin>>ch1+1>>ch2+1;//不用转化为整数数组,每次直接对字符串进行操作
	int len1=strlen(ch1+1);
	int len2=strlen(ch2+1);
	for(int i=len2;i<=len1;i++)//从可能产生答案的最高位len2减到最后一位len1
	{
		while(cmp(i,ch1,ch2)==true)//每位减到不能再减为止,因此这儿需要做个比较
		{
			subtraction(i,ch1,ch2);//用减法模拟每次相除
			add_ans(i);//答案数组的i位上+1
		}
	}
	int l1=1,l2=1;
	while(ans[l1]==0&&l1<=len1-1) l1++;//删除存储商的数组中的多余的前导0
	for(int i=l1;i<=len1;i++) printf("%d",ans[i]);//ans即为存储商的数组
	cout<<endl;
	while(ch1[l2]=='0'&&l2<=len1-1) l2++;//删除余数中多余的前导0
	for(int i=l2;i<=len1;i++) printf("%c",ch1[i]);//ch1(被除数数组)剩余的即为相除余数
	return 0;
}

嗯,还是比较有难度,结合竖式相除的过程再理解一下,应该不会有太大问题。(记住:用高精度减法模拟每位相除的过程)

学习厌倦了?点我有更多精彩哦!

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值