初识高精度
高精度算法就是模拟手工计算,通过字符串来存储范围超过int数据范围的数字。
优点 | 可实现超级计算 | 易理解 |
---|---|---|
缺点 | 遇多次运算,易超时 | 细节繁多(个人感觉有点费手) |
那话不多说,步入正题吧。
高精加
我们先看图:
1 2 3 4 5 6 7 8 9 0
+ 9 9 9 9 9 9 9 9 9 9
---------------------------------------------------
首先,我们加法的手工计算是从右往左,用字符串就是从size()-1到0;
然后,我们就可以开始加了:
1 2 3 4 5 6 7 8 9 0
+ 9 9 9 9 9 9 9 9 9 9
---------------------------------------------------
9
第size()-1位相加,我们可以得到如下代码:
string jia(string s1,string s2)
{
int i=s1.size()-1,j=s2.size()-1;
char c;
string ans="";
c=(s1[i]-'0')+(s2[j]-'0')+'0';
ans+=c;
}
因为是字符相加,所以要减去字符0,最后也不要忘了加上字符0;这里定义了一个字符c来储存每一位的结果,字符串ans来储存整个的结果。
从第size()-1一直加到0,我们就可以添加一个while循环:
string jia(string s1,string s2)
{
int i=s1.size()-1,j=s2.size()-1;
char c;
string ans="";
while(i>=0&&j>=0)
{
c=(s1[i]-'0')+(s2[j]-'0')+'0';
ans+=c;
i--;
j--;
}
}
如上,我们就完成了没有进位且两个数字位数相同的高精加。如果需要进位,又该怎么办呢?
没关系,我们继续看图:
1 2 3 4 5 6 7 8 9 0
+ 9 9 9 9 9 9 9 9 9 9
---------------------------------------1--1----------
8 8 9
不难发现,进位其实就是相加的结果+进位mod10。而进多少,则是相加的结果+进位/10。
因此,我们就可以加上进位了:
string jia(string s1,string s2)
{
int i=s1.size()-1,j=s2.size()-1;
int jinwei=0;
char c;
string ans="";
while(i>=0&&j>=0)
{
c=((s1[i]-'0')+(s2[j]-'0')+jinwei)%10+'0';
jinwei=((s1[i]-'0')+(s2[j]-'0')+jinwei)/10;
ans+=c;
i--;
j--;
}
}
这时候,就差一个问题了。便是实现不同位数数字相加。
我们便可以在后面加上两个循环:
string jia(string s1,string s2)
{
int i=s1.size()-1,j=s2.size()-1;
int jinwei=0;
char c;
string ans="";
while(i>=0&&j>=0)
{
c=((s1[i]-'0')+(s2[j]-'0')+jinwei)%10+'0';
jinwei=((s1[i]-'0')+(s2[j]-'0')+jinwei)/10;
ans+=c;
i--;
j--;
}
while(i>=0)
{
c=((s1[i]-'0')+jinwei)%10+'0';
jinwei=((s1[i]-'0')+jinwei)/10;
ans+=c;
i--;
}
while(j>=0)
{
c=((s2[j]-'0')+jinwei)%10+'0';
jinwei=((s2[j]-'0')+jinwei)/10;
ans+=c;
j--;
}
}
你以为结束了?NO!看图:
9 9 9
+ 8 8 8
--------------1----1---1---------------------
1 8 8 7
加到最后一位时,如果还需进位,则还要加上一个字符1;别忘了,我们是倒着加的,最后还要翻转过来,去掉多余的前导0。
完整代码
string jia(string s1,string s2)
{
int i=s1.size()-1,j=s2.size()-1;
int jinwei=0;
string s="",ans="";
char c;
while(i>=0&&j>=0)
{
c=(s1[i]-'0'+s2[j]-'0'+jinwei)%10+'0';
jinwei=(s1[i]-'0'+s2[j]-'0'+jinwei)/10;
s+=c;
i--;
j--;
}
while(i>=0)
{
c=(s1[i]-'0'+jinwei)%10+'0';
jinwei=(s1[i]-'0'+jinwei)/10;
s+=c;
i--;
}
while(j>=0)
{
c=(s2[j]-'0'+jinwei)%10+'0';
jinwei=(s2[j]-'0'+jinwei)/10;
s+=c;
j--;
}
if(jinwei==1)
{
s+=1+'0';
}
int tag=0;
for(i=s.size()-1;i>=0;i--)
{
if(tag==0&&s[i]=='0')
{
continue;
}
ans+=s[i];
tag=1;
}
return ans;
}
好了,本文章到这里就结束了,再见。
(如以上代码有错误,请指出,万分感谢!)