在大部分oier看来,只要有高精度的题就是毒瘤题(雾),之前的我遇到高精度的题就直接弃疗了,但是如果考试考到,这些分就白丢了,所以说抽出时间整理了一下高精度模板,主要包括:高精加,高精减,高精乘,高精除单精
先说说如何定义:
struct bigint{
int s[10100];
int len;
bool zf;
bigint()
{
memset(s,0,sizeof(s));
len=0;
zf=0;
}
void init()
{
len=strlen(ch);
if (ch[1]=='-')
{
zf=1;
for (int i=2;i<=len;i++)
s[i]=ch[len-i]-'0';
}
else
{
for (int i=1;i<=len;i++)
s[i]=ch[len-i]-'0';
}
}
void reverse()
{
int t[10010];
for (int i=1;i<=len;i++)
t[i]=s[len-i+1];
for (int i=1;i<=len;i++)
s[i]=t[i];
}
void uni()
{
while (s[len]==0&&len>1)len--;
}
void pr()
{
for (int i=len;i>=1;i--) printf("%d",s[i]);
}
};
init是反着存数,uni是去掉前导零,reverse是翻转,pr是输出答案,为什么要翻转呢?因为除了除法其他操作都是从低到高,为了方便直观理解,我们可以再除法操作之前先reverse再除再reverse(其实是懒得处理下标问题)
加法:
bigint operator +(bigint x,bigint y)
{
bigint nw;
nw.len=max(x.len,y.len);
for (int i=1;i<=nw.len;i++)
{
nw.s[i]+=x.s[i]+y.s[i];
nw.s[i+1]+=nw.s[i]/10;
nw.s[i]%=10;
}
if (nw.s[nw.len+1]>0) nw.len++;
return nw;
}
减法:
bool operator >(bigint x,bigint y)
{
if (x.len>y.len) return 1;
else if (x.len<y.len) return 0;
int nw=x.len;
while (nw)
{
if (x.s[nw]>y.s[nw]) return 1;
else if (x.s[nw]<y.s[nw]) return 0;
nw--;
}
if (nw==0) return 1;
return 1;
}
bigint operator -(bigint x,bigint y)
{
bigint nw;
nw.len=max(x.len,y.len);
for (int i=1;i<=nw.len;i++)
{
nw.s[i]+=x.s[i]-y.s[i];
if (nw.s[i]<0) nw.s[i+1]--,nw.s[i]+=10;
}
while (nw.s[nw.len]==0&&nw.len>1)nw.len--;
return nw;
}
这里有个技巧:(这里只写了a,b都是正数的比较函数)
if (a>b)
{
a=a-b;
}
else a=b-a,printf("-");
a.pr();
这样可以避免减出负数
乘法:
bigint operator *(bigint x,bigint y)
{
bigint nw;
nw.len=x.len+y.len;
for (int i=1;i<=x.len;i++)
for (int j=1;j<=y.len;j++)
{
nw.s[i+j-1]+=x.s[i]*y.s[j];
nw.s[i+j]+=nw.s[i+j-1]/10;
nw.s[i+j-1]%=10;
}
while (nw.s[nw.len]==0&&nw.len>1)nw.len--;
return nw;
}
高精除单精:
bigint operator /(bigint x,int y)
{
bigint sh;
int nv=0;
for (int i=1;i<=x.len;i++)
{
nv=nv*10+x.s[i];
sh.s[++sh.len]=nv/y;
nv=nv%y;
}
return sh;
}
这种东西只要细心相信大家都可以写出来,这里的模板只是供大家参考,最好是自己写一下