我们今天来聊聊高精度。
顾名思义,高精度就指精度很高
那么精度很高又指什么呢?
我们知道
int
(整型)的表示范围是
−231
~
231−1
longlong
(长整型)的范围是
−263
~
263−1
那么我们就可以认为长整型精度较高,也可以说是表示范围更大
那么高精度有什么用处呢?
我们接下来看一道例题。
A+B Problem
Description
读入两个整数a,b,输出a+b
Input
两个整数a,b( 0≤a,b≤10500 )
Output
一个整数a+b
Sample Input
1 2
Sample Output
3
分析
大致地看一下这题,可能发现这题其实并没有什么不对,只要读入输出即可
如果你抱着这样的心态交代码,那么迎接你的将会是WA,甚至爆零
这是为什么呢?且听下回分解
请看数据范围!
没错,不论你用长整型,或者是无符号长整形,甚至是int128,那都是存不下的
这就是为什么我们需要高精度
接下来我们讲高精度的原理。
高精度加法
我们先分析一下数的构成
仔细一看,数是由个位、十位、百位等构成的
那么我们就可以说一个数是由多个数位构成的
我们不妨将每个数位都分开来存在一个数组里,以此加大数的表示范围
问题就好解决了
数组开多大,数的表示范围就有几位(比如上面那题我们可以开
a[505]
)
我个人习惯使用如下的结构体:
struct hugeint
{
int l,n[505];//l代表数的长度,n用来存储数的每一位
}a;
注意,这里的
a[1]
代表个位,
a[2]
代表十位,以此类推
接下来我们只要模仿竖式的过程,就可以轻松地进行高精度加法了
还记得竖式么?
5 6
3 3
——————————
8 9
于是乎,代码呼之欲出
非压位优化高精度加法模板.cpp
hugeint Plus(hugeint a,hugeint b)//作为加数的a,b
{
hugeint ans;
memset(ans.n,0,sizeof(ans.n));
ans.l=0;
for(int i=1;i<=max(a.l,b.l);i++)//从第一位开始循环
{
ans.n[i]+=a.n[i]+b.n[i];//加上
if(ans.n[i]>=10)//进位处理
{
ans.n[i+1]+=ans.n[i]/10;
ans.n[i]%=10;
if(i==max(a.l,b.l)) ans.l++;//如果最后一位要进位,长度+1
}
ans.l++;//每一位长度+1
}
return ans;
}
输出模板:
void Print(hugeint a)
{
for(int i=a.l;i>=1;i--) printf("%d",a.n[i]);
}
小结
高精度是OI中非常重要的元素,本人在这里只列出了加法,大家可以自行研究一下减法、乘法和除法,实在理解不了背下来也是可行的方法。
原创 By Venus
写的不好大佬轻喷