本题是高精度运算题,现实生活中有时候所要处理的数字范围很大,而计算机受自身硬件限制无法处理。这个时候就要依靠高精度算法。
思想步骤:1、数字按字符串输入。
2、把字符串转换int数组。
3、对int数组进行竖式运算。
回顾下本类题基本题型 加法 减法 乘法 除法
加法: 求两个200位非负整数的和。
input: 2222222222222222222222
3333333333333333333333
output: 5555555555555555555555
#include<stdio.h>
#include<string.h>
#define Max 100
int a1[Max+10];
int a2[Max+10];
char s1[Max];
char s2[Max];
int main()
{
int i,j,len1,len2;
memset(a1,0,sizeof(a1));\\ 数组置空
memset(a2,0,sizeof(a2));
scanf("%s",s1);
scanf("%s",s2);
len1=strlen(s1);
len2=strlen(s2);
for(i=0,j=len1-1;j>=0;j--)\\字符串转换为数组
a1[i++]=s1[j]-'0';
for(i=0,j=len2-1;j>=0;j--)
a2[i++]=s2[j]-'0';
for(i=0;i<Max;i++)
{
a1[i]+=a2[i];
if(a1[i]>=10)
{
a1[i+1]++;\\ 判定是否进位
a1[i]-=10;
}
}
for(i=Max;(i>0)&&(a1[i]==0);i--) ;
for(;i>=0;i--)
printf("%d",a1[i]);
return 0;
}
乘法:不超过200位的非负整数的积,输出前导没有多余的0.
input: 1234567890
98765432100
output 121932636311126352690000
#include<stdio.h>
#include<string.h>
#define Max 200
int a1[Max+10];
int a2[Max+10];
int a[Max*2+10];
char s1[Max+10];
char s2[Max+10];
int main()
{
int i,j,len1,len2;
memset(a1,0,sizeof(a1));
memset(a2,0,sizeof(a2));
memset(a,0,sizeof(a));
scanf("%s",s1);
scanf("%s",s2);
len1=strlen(s1);
len2=strlen(s2);
for(i=0,j=len1-1;j>=0;j--)
a1[i++]=s1[j]-'0';
for(i=0,j=len2-1;j>=0;j--)
a2[i++]=s2[j]-'0';
for(i=0;i<len1;i++)
{
for(j=0;j<len2;j++)
a[i+j]=a1[i]*a2[j];\\ 这里i + j表示和所在位数,万进制。
}
for(i=0;i<Max*2;i++)
{
if(a[i]>=10)
{
a[i+1]+=a[i]/10;\\处理进位
a[i]%=10;
}
}
for(i=Max*2;(i>=0)&&(a[i]==0);i--);
for(;i>=0;i--)
printf("%d",a[i]);
return 0;
}
除法 : l两个大的正整数相除,输入第一个被除数,
input: 100000000000000000000000
100000000
output: 1000000000000000
除法思想:被除数循环减去除数
#include<stdio.h>
#include<string.h>
#define Max 200
int a1[Max+10];
int a2[Max+10];
int a[Max+10];
char s1[Max+10];
char s2[Max+10];
int submit(int * p1,int *p2, int len1,int len2 )// 知道*p1 *p2 用法 实参数组的首地址
{
int i;
if(len1<len2)
return -1;
if(len1==len2)
{
for(i=len1-1;i>=0;i--)
{
if(p1[i]>p2[i]) break;
else
if(p1[i]<p2[i]) return -1;
}
}
for(i=0;i<len1;i++)
{
p1[i]-=p2[i];
if(p1[i]<0)
{
p1[i+1]--;
p1[i]+=10;
}
}
for(i=len1-1;i>=0;i--)
if(p1[i])
return i+1;
return 0;
}
int main()
{
int i,j,times,len1,len2,re;
scanf("%s",s1);
scanf("%s",s2);
memset(a1,0,sizeof(a1));
memset(a2,0,sizeof(a2));
memset(a,0,sizeof(a));
len1=strlen(s1);
len2=strlen(s2);
for(i=0,j=len1-1;j>=0;j--)
a1[i++]=s1[j]-'0';
for(i=0,j=len2-1;j>=0;j--)
a2[i++]=s2[j]-'0';
if(len1<len2)
printf("0\n");
times=len1-len2;
if(times>0)
{
for(i=len1-1;i>=times;i--)\\ 除数补位 等于被除数相等的位数
a2[i]=a2[i-times];
for(;i>=0;i--)
a2[i]=0;
len2=len1;
}
for(i=0;i<=times;i++)
{
while( (re=submit(a1,a2+i,len1,len2-i))>=0)// 注意a2+i的含义:首地址向后移动一位,与len2-i相对应
{
len1=re;
a[times-i]++;
}
}
for(i=Max;(i>=0)&&(a[i]==0);i--);
for(;i>=0;i--)
printf("%d",a[i]);
return 0;
}
现在要你解决的问题是:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(R n),其中n 是整数并且 0 < n <= 25。
Input
Output
Sample Input
95.123 12 0.4321 20 5.1234 15 6.7592 9 98.999 10 1.0100 12
Sample Output
548815620517731830194541.899025343415715973535967221869852721 .00000005148554641076956121994511276767154838481760200726351203835429763013462401 43992025569.928573701266488041146654993318703707511666295476720493953024 29448126.764121021618164430206909037173276672 90429072743629540498.107596019456651774561044010001 1.126825030131969720661201其实这题幂就是乘法的变换。首先,把输入转换为整数,poi记录小数点的位置 例如 95.123 12 95123 poi=4 其次利用循环相乘计算幂。最后输出插入小数点。
#include<stdio.h>
#include<string.h>
int main()
{
char str[20];
int n;
while(scanf("%s %d",str,&n)!=EOF)
{
int a[500],b[500],c[500],len,i,j,k,poi=0;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
len=strlen(str);
for(i=0,j=len-1;j>=0;j--)
{
if(str[j]=='.') poi=i;\\记录小数点位置
else
a[i++]=str[j]-'0';
}
for(j=0;j<500;j++)
b[j]=a[j]; \\b[]作为乘积基底数组
if(!n) \\n=0 输出1
printf("1\n");
else
{
for(i=2;i<=n;i++)
{
for(j=0;j<500;j++)
c[j]=a[j]; //每次把a[] 赋值给c[] ,c[]作为中间变量
memset(a,0,sizeof(a)); //a[]一定要置0
for(k=0;k<6;k++)
{
for(j=0;j<500;j++)
a[k+j]+=b[k]*c[j];
}
for(j=0;j<500;j++)
{
if(a[j]>=10)
{
a[j+1]+=a[j]/10;
a[j]%=10;
}
}
}
poi*=n;
for(i=0;(i<poi)&&(a[i]==0);i++);
for(j=499;(j>=poi)&&(a[j]==0);j--); //掐头去尾。 把首段 末端 多余的0去除。注意尾端0去除时,poi减去去除的个数
for(;j>=poi;j--)
printf("%d",a[j]);
poi-=i; //注意这里 测试数据 10.000 3 1000 不能输出.
if(poi)printf(".");
for(;j>=i;j--)
printf("%d",a[j]);
printf("\n");
}
}
return 0;
}