高精度计算

高精度计算

计算机数据范围的表示有一定限制,如整型int、实数型double只能提供十几位的有效数字,如果计算位数超过100位,甚至1000位怎么办?这类问题通常采用高精度计算的方法解决。

高精度计算可以是整数间的计算,也可以是实数间的计算,其中实数间的高精度计算较为复杂。

初次写高精度计算多试错、调试几次应该都能写出来,但我们应该最终熟悉、掌握一种思路清晰、简洁正确的高精度计算写法。下面介绍一种较好的整数高精度计算写法。

读入高精度数

一般借助字符串读入高精度数,再将每位数字分别储存在数组中。高精度的第一位存储个位,而字符串的第一位存储最高位,所以需要进行逆序存储。通常情况下,会在数组的0号下标存储高精度数的位数以便输出。

void read(int a[])
{
	memset(a,0,sizeof(a));//清0
	string s;
	cin>>s;
	int l=s.length();
	for(int i=1;i<=l;i++)
		a[i]=s[l-i]-'0';
	a[0]=l;
}

高精度加法

void add(int a[],int b[],int c[])
{
	memset(c,0,sizeof(c));
	int w=max(a[0],b[0])+1;
	int z=0;				//z是进位
	for(int i=1;i<=w;i++)
	{
		c[i]=a[i]+b[i]+z;
		z=c[i]/10;
		c[i]%=10;
	}
	while(a[w]==0)w--;
	c[0]=w;
	for(int i=c[0];i>0;i--)cout<<c[i];//输出结果,根据实际可忽略
}

高精度减法

int compare(int a[],int b[])
{
	int w=max(a[0],b[0]);
	while(a[w]==b[w]&&w>0)w--;
	if(w==0)return 0;
	if(a[w]>b[w])return 1;
	else return -1;
}
void sub(int a[],int b[],int c[])
{
	memset(c,0,sizeof(c));
	int w=a[0];
	int z=0;				//z为退位
	for(int i=1;i<=w;i++)
	{
		c[i]=a[i]-b[i]-z;
		if(c[i]<0)
		{
			c[i]+=10;
			z=1;
		}
		else
			z=0;
	}
	while(a[w]==0&&w>1)w--;
	c[0]=w;
	for(int i=c[0];i>0;i--)cout<<c[i];//输出结果,根据实际可忽略
}
int main()
{
	...
	int x=compare(a,b);//保证大数减小数
	if(x==0)cout<<0;
	else if(x==1)sub(a,b,c);
	else 
	{
		cout<<'-';
		sub(b,a,c);
	}
	...
}

高精度乘法

void mul(int a[],int b[],int c[])
{
	memset(c,0,sizeof(c));
	for(int i=1;i<=a[0];i++)
		for(int j=1;j<=b[0];j++)
		{
			c[i+j-1]=a[i]*b[j];
			c[i+j]+=c[i+j-1]/10;	//进位
			c[i+j-1]%=10;
		}	
	int w=a[0]+b[0];
	while(c[w]==0&&w>1)w--;
	c[0]=w;
	for(int i=c[0];i>0;i--)cout<<c[i];//输出结果,根据实际可忽略
}

高精度数除法

这里主要讨论高精度数除以低精度数

void div(int a[],int b,int c[])
{
	memset(c,0,sizeof(c));
	int w=a[0];
	int z=0;				//余数
	for(int i=w;i>0;i--)
	{
		c[i]=(a[i]+z*10)/b;
		z=(a[i]+z*10)%b;
	}
	while(c[w]==0&&w>1)w--;
	c[0]=w;
	for(int i=c[0];i>0;i--)cout<<c[i];//输出结果,根据实际可忽略
}

看两道题
在这里插入图片描述

这道题直接套用上面高精度加法解决。
在这里插入图片描述
稍微综合了一下几种高精度计算,注意运用求和公式。

#include <bits/stdc++.h>
using namespace std;
int a[105],b[105],c[300],d[300];
void read(int a[])
{
	int len,i;
	string s;
	cin>>s;
	len=s.length();
	memset(a,0,sizeof(a));
	for(int i=1;i<=len;i++)
		a[i]=s[len-i]-'0';
	a[0]=len;
} 
void add(int a[],int b[])
{
	memset(b,0,sizeof(b));
	int x=1;
	int w=a[0]+1;
	for(int i=1;i<=w;i++)
	{
		b[i]=a[i]+x;
		x=b[i]/10;
		b[i]%=10;
	}
	int i=104;
	while(b[i]==0) i--;
	b[0]=i;
}
void mul(int a[],int b[],int c[])
{
	memset(c,0,sizeof(c));
	for(int i=1;i<=a[0];i++)
	{
		for(int j=1;j<=b[0];j++)
		{
			c[i+j-1]+=a[i]*b[j];
			int x=c[i+j-1]/10;
			c[i+j-1]%=10;
			c[i+j]+=x;
		}
	}
	int i=a[0]+b[0];
	while(c[i]==0&&i>0) i--;
	c[0]=max(1,i);
}
void div(int c[],int d[])
{
	int x=0;
	memset(d,0,sizeof(d));
	for(int i=c[0];i>0;i--)
	{
		x=x*10+c[i];
		d[i]=x/2;
		x%=2;
	}
	int i=c[0];
	while(d[i]==0&&i>0) i--;
	d[0]=max(i,1);
	for(int i=d[0];i>0;i--) cout<<d[i];
}
int main()
{
	read(a);
	add(a,b);
	mul(a,b,c);
	div(c,d);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值