高精度算法详解

本人GitHub:codecode2929 (张贺翔) (github.com)

1.高精度加法

算法核心:

c[i]+=a[i]+b[i];
c[i+1]=c[i]/10;
c[i]%=10;

代码: 

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
	char s1[10010],s2[10010];
	int la,lb,lc,a[10010],b[10010],c[10010];
	cin>>s1>>s2; 
	la=strlen(s1),lb=strlen(s2),lc=max(la,lb)+1;
	for(int i=0;i<la;i++)a[la-i]=s1[i]-'0';//转换
	for(int i=0;i<lb;i++)b[lb-i]=s2[i]-'0';//转换
	for(int i=0;i<lc;i++)c[i]+=a[i]+b[i],c[i+1]=c[i]/10,c[i]%=10;//加起来 
	if(c[lc]==0&&lc>0)lc--;//del前导0 
	for(int i=lc;i>0;i--)printf("%d",c[i]);//输出 
	return 0;
}

2.高精度减法

普通(大减小):

特殊:(小减大):

要点 :
1.如果a<b则需要交换a与b
2.如果a[i]<b[i],需要高位借一当十使用

算法核心:

1.减:

if(a[i]-b[i]<0)//向高位进一 
	a[i]+=10,a[i+1]--;
c[i]=a[i]-b[i];

2.调换:

if(strlen(s1)<strlen(s2)||strlen(s1)==strlen(s2)&&strcmp(s1,s2)<0)
    //如果结果是负数,调换后输出负号 
	{
        char tem[11000];
        strcpy(tem,s1);
        strcpy(s1,s2);
        strcpy(s2,tem);
        printf("-");
    }

代码:

#include<stdio.h>
#include<string.h>
int main()
{
	char s1[11000],s2[11000];
	int a[11000]={0},b[11000]={0};
	scanf("%s %s",s1,s2);
	if(strlen(s1)<strlen(s2)||strlen(s1)==strlen(s2)&&strcmp(s1,s2)<0)
    //如果结果是负数,调换后输出负号 
		{char tem[11000];strcpy(tem,s1);strcpy(s1,s2);strcpy(s2,tem);printf("-");}
	for(int i=1;i<=strlen(s1);i++)a[i]=s1[strlen(s1)-i]-'0';//转换
	for(int i=1;i<=strlen(s2);i++)b[i]=s2[strlen(s2)-i]-'0';//转换
	int c[11000]={0};
	for(int i=1;i<=strlen(s1);i++)
	{
		if(a[i]-b[i]<0)//向高位进一 
			a[i]+=10,a[i+1]--;
		c[i]=a[i]-b[i];
	}
	int flag=0;
	for(int i=strlen(s1);i>0;i--)
		if(c[i]!=0)flag=1,printf("%d",c[i]);
		else if(c[i]==0&&flag) printf("%d",c[i]);
	if(flag==0) printf("0");
	return 0;
}

3.高精度乘法

算法核心:

c[i+j-1]+=a[i]*b[j];//累加 
c[i+j]+=c[i+j-1]/10;//进位 
c[i+j-1]%=10;//取余 

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int main()
{
    int la,lb,lc;
	char s1[10010],s2[10010];
	int a[10010],b[10010],c[10010];
	cin>>s1>>s2;
	la=strlen(s1),lb=strlen(s2),lc=la+lb;
	for(int i=0;i<la;i++)a[la-i]=s1[i]-'0';//转化 
	for(int i=0;i<lb;i++)b[lb-i]=s2[i]-'0';//转化
	for(int i=1;i<=la;i++)
		for(int j=1;j<=lb;j++)
		{
			c[i+j-1]+=a[i]*b[j];//累加 
			c[i+j]+=c[i+j-1]/10;//进位 
			c[i+j-1]%=10;//取余 
		} 
	if(c[lc]==0&&lc>0)lc--;
	for(int i=lc;i>0;i--)cout<<c[i]; 
    return 0;
}

4.高精度除法(高精除以低精)

算法核心:

c[i]=(x*10+a[i])/b;	//求商 
x=(x*10+a[i])%b;	//求余 

代码:

#include<iostream>
#include<cstring>
using namespace std;
char s1[50005];
long long b,c[50005],x,a[50005],la,lc;
int main()
{
	cin>>s1>>b;//被除数与除数 
	la=strlen(s1);
	for(int i=1;i<=la;i++)a[i]=s1[i-1]-'0';///转化 
	for(int i=1;i<=la;++i)
	{
		c[i]=(x*10+a[i])/b;	//求商 
		x=(x*10+a[i])%b;	//求余 
	}lc=1;
	while(c[lc]==0&&lc<la)lc++;//删除前导0 
	for(int i=lc;i<=la;++i)cout<<c[i];//输出结果 
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值