1308:【例1.5】高精除
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 9100 通过数: 4302
【题目描述】
高精除以高精,求它们的商和余数。
【输入】
输入两个低于300位的正整数。
【输出】
输出商和余数。
【输入样例】
1231312318457577687897987642324567864324567876543245671425346756786867867867
1231312318767141738178325678412414124141425346756786867867867
【输出样例】
999999999748590
179780909068307566598992807564736854549985603543237528310337
【分析】
在读小学时,我们做除法都采用竖式方法计算。被除数从高位开始,和除数对齐,逐位“试商”,“试商”后除数减去“试商”的数的乘积,如下图所示。
采用计算机做高精度除法时,计算机不可能做“试商”,这时,我们可以采用减法来模拟。
试商过程:
1)将除数移动和被除数对齐,位数不够时,补 0。
2)利用被除数减去除数,一直减到被除数小于除数,减的次数,就是“试商”的结果。
3)重复上述步骤,一直到被除数和除数的位数相等为止。
【参考代码】
C代码:
#include <stdio.h>
#include <string.h>
#define MAXN 310
char s1[MAXN],s2[MAXN];
int tmp[MAXN],a[MAXN],b[MAXN],c[MAXN];
int compare(int a[], int b[])
{
int i;
if(a[0]>b[0])
return 1;
else if(a[0]<b[0])
return -1;
//逐位比较
for(i=a[0];i>0;i--)
{
if (a[i]>b[i])
return 1;
else if(a[i]<b[i])
return -1;
}
return 0;
}
void numcpy(int a[],int b[],int dest)
{
int i;
for(i=1;i<=a[0];i++)
b[i+dest-1]=a[i];
b[0]=a[0]+dest-1;
}
int main()
{
int i,j,k,flaga=0,flagb=0;
int len;
scanf("%s %s", s1, s2);//读入字符串
//处理负数
if(s1[0]=='-')
{
flaga=1;
strcpy(s1,&s1[1]); //删除负号
}
if(s2[0]=='-')
{
flagb=1;
strcpy(s2,&s2[1]);//删除负号
}
//处理输出的负号
if(flaga==1 && flagb==0)
{
//商为负数
printf("-");
}
//处理乘数1
len=strlen(s1);
a[0]=len;
for(i=0;i<len;i++)
a[len-i]=s1[i]-'0';
//处理乘数2
len=strlen(s2);
b[0]=len;
for(i=0;i<len;i++)
b[len-i]=s2[i]-'0';
if(compare(a,b)==0)
{
//两数相等
printf("1\n0\n");
return 0;
}
else if(compare(a,b)==-1)
{
//被除数小,除数大
printf("0\n");//输出除数
if(flaga==1)
printf("-");
printf("%s\n",s1);
return 0;
}
else
{
c[0]=a[0]-b[0]+1;
for(i=c[0];i>0;i--)
{
memset(tmp,0,sizeof(tmp));
//高位对齐
numcpy(b,tmp,i);
while(compare(a,tmp)>=0)
{
c[i]++;
//减法
for(j=1;j<=a[0];j++)
{
if(a[j]<tmp[j])
{
a[j+1]--;
a[j]+=10;
}
a[j]-=tmp[j];
}
k=a[0];
while(a[k]==0)
k--;
a[0]=k;
}
}
//控制最高位的0
while (c[0]>0 && c[c[0]]==0) {
c[0]--;
}
}
//逆序打印输出商和余数
for(i=c[0];i>0;i--)
printf("%d", c[i]);
printf("\n");
if(a[0]==0)
{
printf("0\n");
}
else
{
if(flaga==1)
{
printf("-");
}
for(i=a[0];i>0;i--)
{
printf("%d", a[i]);
}
printf("\n");
}
return 0;
}
http://ybt.ssoier.cn:8088/problem_show.php?pid=1308