概述
当计算的数值非常大或是对于计算的精度要求非常高时,用已知的数据类型无法精确地表示数值。可以采用数组来模拟大数运算的过程。
高精度加法
两个大数进行相加计算时,要解决三个问题
- 如何存储
- 如何计算
- 如何输出答案
先解决第一个问题,数据地存储,由于数据过于庞大,已知的数据类型无法精确地表示数值,会发生数据溢出问题。此时可考虑将数据拆分,将大数分割成若干个0~9数字组成的整体。这样的结构能让我们联想到数组。但是,若是整数数组,在输入时较难将数字存储在各个元素空间内,此时可考虑使用字符串形式进行输入,在存储后再进行转换。
const int maxn=1e10+5;
char s1[maxn]={0},s2[maxn]={0};
cin>>s1>>s2;
输入完成后,再去考虑计算问题。首先,字符类型直接相加的结果并不正确,需要将其转化为整数数字。可利用ASCII码差值来进行处理。且在进行计算时,模拟竖式加法计算过程,需要从低位开始向高位相加计算且注意过程中的进位。在相加时,加数和被加数位数可能不同,需要低位对齐。实现低位对齐可在转换时进行倒序存放。
// 转换过程
int num[maxn]={0};
int len=strlen(s);
for(int i=0;i<len;i++)
{
num[i]=s[len-1-i]-'0';
}
倒序转换好之后,在模拟竖式计算进行处理。注意过程中的进位。
int ans[maxn]={0};
for(int i=0;i<maxLen;i++)
{
ans[i]+=num1[i]+num2[i];
ans[i+1]=ans[i]/10;//进位
ans[i]%=10;//保留余数
}
计算完成之后可以进行输出,这时候需要注意答案是倒着存放的,需要倒序进行输出并去除前导0;
int flag=0;
for(int i=maxLen+1;i>=0;i--)
{
if(ans[i]!=0||i==0) flag=1;
if(falg) cout<<ans[i];
}
高精度减法
高精度减法和高精度加法过程类似,字符串输入后模拟竖式进行计算。
前面数据输入和倒置存放的过程相同就不再重复。再计算过程中需要注意的问题就是可能相减会出现负数,两数相减需要考虑绝对值大小问题。
计算a-b,若a>=b,ans=a-b;若a<b,ans=-(b-a);故需要判断大小,可根据长度来判断大小,长度相同则使用字符串比较函数,从字符串内容上进行判断。
int len1=strlen(s1);
int len2=strlen(s2);
if((len1>len2) || (len2==len1&&strcmp(s1,s2)>=0 )
{
//ans=a-b;
for(int i=0;i<len1;i++)
{
if(num1[i]<num2[i]){
num1[i]+=10;
num1[i+1]--;
}
ans[i]=num1[i]-num2[i];
}
}else
{
//ans=-(b-a);
for(int i=0;i<len2;i++)
{
if(num2[i]<num1[i]){
num2[i]+=10;
num2[i+1]--;
}
ans[i]=num2[i]-num1[i];
}
cout<<"-";
}
算完后,再和前面一样进行倒序输出答案,注意删除前导0即可。