对于一个很懒且计算能力不强的人来说,计算器是一个不错的东西,两个数字的计算更是再简单不过了:为了填充我的博客,下面是简单的计算:
个人觉得高精加就十分够用了,毕竟关键时刻还可以写成函数循环转乘法(如果你真的不会的话);
减法比较简单,自行理解
阶乘和(对照noi题库1.6 15题看)
#include<cstdio>
int main()
{
int a,b;
char c;
scanf("%d %c %d",&a,&c,&b);
if(c=='+') printf("%d",a+b);
if(c=='-') printf("%d",a-b);
if(c=='*') printf("%d",a*b);
if(c=='/') printf("%d",a/b);
if(c=='%') printf("%d",a%b);
return 0;
}
相信这个东西就算是刚学的初学者也能看懂,所以就没必要解释了;
but 当我们信心满满输入一大串数进行运算的时候,尴尬的一幕产生了:
因为int(甚至long long)类型已经存不下
这时:就产生了我们牛逼的高精度运算:
高精度运算的原理特别简单,就是用计算机分步把竖式运算的方法表示出来,在对进位退位的细节进行处理,就形成的简单的高精度运算;
我要讲的主要是高精度的加、减、乘,因为这些运算比较简单(再说除法我也不怎么会):
直接上代码,大家自行理解;
高精加:
#include<cstdio>
#include<cstring>
int a[205],b[205],c[205];//输入的a,b;c是辅助
char a1[205],b1[205];
int main()
{
int lena,lenb,lenc,i,x,t;
fgets(a1,205,stdin);
fgets(b1,205,stdin);//用字符串的形式输入a,b数组(既需要计算的数字a,b)
lena=strlen(a1)-1;
lenb=strlen(b1)-1;//a,b的长度(类比竖式运算)
for(i=0;i<=lena-1;i++)
a[lena-i]=a1[i]-48;
for(i=0;i<=lenb-1;i++)
b[lenb-i]=b1[i]-48;//转数字(进行运算)
lenc=1;
x=0;
while(lenc<=lena||lenc<=lenb)
{
c[lenc]=a[lenc]+b[lenc]+x;
x=c[lenc]/10;
c[lenc]%=10;
lenc++;
}//相加,进位
c[lenc]=x;//单独做最低位
t=lenc;
for(i=1;i<=t;i++)
{
if(c[lenc]==0)
lenc--;
if(lenc==0)
printf("0");
}//消除前导0
for(i=lenc;i>=1;i--)
printf("%d",c[i]);//输出运算结果
printf("\n");
return 0;
}
个人觉得高精加就十分够用了,毕竟关键时刻还可以写成函数循环转乘法(如果你真的不会的话);
高精减:
#include<cstdio>
#include<cstring>
int a[205],b[205],c[205];
char a1[205],b1[205],c1[205];
int main()
{
int lena,lenb,lenc,i;
gets(a1);
gets(b1);
if((strlen(a1)<strlen(b1))||(strlen(a1)==strlen(b1)&&strcmp(a1,b1)<0))
{strcpy(c1,a1);strcpy(a1,b1);strcpy(b1,c1);printf("-");}//a比b小,结果为负,交换a,b
lena=strlen(a1);
lenb=strlen(b1);//同样是关键的长度
for(i=0;i<=lena-1;i++)
a[lena-i]=a1[i]-48;
for(i=0;i<=lenb-1;i++)
b[lenb-i]=b1[i]-48;//转数字
lenc=1;
while(lenc<=lena||lenc<=lenb)
{
if(a[lenc]<b[lenc])
{
a[lenc]+=10;
a[lenc+1]--;
}//借位
c[lenc]=a[lenc]-b[lenc];
lenc++;//相减
}
while(lenc>1&&c[lenc]==0)
lenc--;//前导0
for(i=lenc;i>=1;i--)
printf("%d",c[i]);//输出结果
printf("\n");
return 0;
}
减法比较简单,自行理解
高精乘
#include<cstdio>
#include<cstring>
int main()
{
char z[200],yy[200];
int w[200]={},a[200]={},n[400]={},lena,lenb,lenc,i,j,x;
gets(z);
gets(yy);
lena=strlen(z);
lenb=strlen(yy);//同理
for(i=0;i<=lena-1;i++) w[lena-i]=z[i]-48;
for(i=0;i<=lenb-1;i++) a[lenb-i]=yy[i]-48;//转换
for(i=1;i<=lena;i++)
{
x=0;
for(j=1;j<=lenb;j++)
{
n[i+j-1]=w[i]*a[j]+x+n[i+j-1];
x=n[i+j-1]/10;
n[i+j-1]=n[i+j-1]%10;
}
n[i+lenb]=x;
}//计算,进位
lenc=lena+lenb;
while(n[lenc]==0&&lenc>1)
lenc--;//前导0
for(i=lenc;i>=1;i--)
printf("%d",n[i]);//输出
}
高精除法比较困难(for me)所以就不在此讲解了;
再为大家补充几个比较常用的高精运算(不作讲解)
阶乘(对照noi题库1.6 14 题看)
#include<cstdio>
const int N=10005;
const int M=100000;
int s[N]={1,1},i,j,x,len=1;
int main()
{
scanf("%d",&x);
for(i=2;i<=x;i++)
{
for(j=1;j<=len;j++)
s[j]*=i;
for(int j=1;j<=len;j++)
{
s[j+1]+=s[j]/M;
s[j]%=M;
}
len++;
while(s[len])
{
s[len+1]=s[len]/M;
s[len]%=M;
len++;
}
}
while(s[len]==0&&len>1)
len--;
printf("%d",s[len]);
for(i=len-1;i>=1;i--)
printf("%05d",s[i]);
}
分解因子(对照noi题库1.6 13题看)
#include<cstdio>
#include<cstring>
int main()
{
char a[35];
scanf("%s",a);
int x, y=1;
for (int k = 2; k <= 9; k++)
{
x= 0;
for (int i = 0; a[i] != 0; i++)
{
x= x* 10 + (a[i] - '0');
x %= k;
}
if (x== 0)
{
if (y)
{
printf("%d ",k);
y = 0;
}
else
printf("%d ",k);
}
}
if (y)
printf("none");
printf("\n");
return 0;
}
阶乘和(对照noi题库1.6 15题看)
#include<cstdio>
#include<climits>
const int MX=100000;
int s[100005]={1},sum[100005]={1};
int i,j,k,n,t=0,tt=0,c=0,tmp;
void mul()
{
c=0;
for(j=0;j<=t;j++)
{
tmp=s[j]*i+c;
if(tmp>=MX)
{
s[j]=tmp%MX;
c=tmp/MX;
if(j+1>t)
{
s[j+1]=c;
t++;
break;
}
}
else
{
s[j]=tmp;
c=0;
}
}
}
void add()
{
c=0;
if(tt<t) tt=t;
for(j=0;j<=tt;j++)
{
tmp=sum[j]+s[j]+c;
if(tmp>=MX)
{
sum[j]=tmp%MX;
c=tmp/MX;
if(j+1>tt)
{
sum[j+1]=c;
tt++;
break;
}
}
else
{
sum[j]=tmp;
c=0;
}
}
}
void pri()
{
printf("%d",sum[tt]);
for(k=tt-1;k>=0;k--)
printf("%05d",sum[k]);
printf("\n");
}
int main()
{
scanf("%d",&n);
for(i=2;i<=n;i++)
{
mul();
add();
}
pri();
}
这就是我掌握的一些基础的高精度运算,希望有帮助(如果不够,调数组大小),当然,这些模板都是要非常熟练的基础知识......好好记吧.....
the end