大数据除法(Large data division)

时间:2023-03-08 17:51:42
题目描述 Description
除法是计算中的基础运算,虽然规则简单,但是位数太多了,也难免会出错。现在的问题是:给定任意位数(足够大就可以啦O(∩_∩)O)的一个被除数,再给定一个long long类型的除数,求它的余数,并保留小数点后s位。
 输入输出格式 Input/output
输入格式:
三行:
第一行:被除数
第二行:除数
第三行:一个数s,表示保留小数点后s位
输出格式:
第一行:表示计算的结果(不可以有前导0,保留小数点后s位)
第二行:余数
 输入输出样例 Sample input/output
样例测试点#1
输入样例#1:
123456789
123
30
输出样例#1:
1003713.731707317073170731707317073170
90
样例测试点#2
输入样例#2:

2456465461515648654411465465465413231256456445621
15
30

输出样例#2:

163764364101043243627431031031027548750430429708.066666666666666666666666666666
1

思路:这题的数据量很大,大数据类型的,如果直接计算是不可取的,必须用高精度算法。
这里可以分为几个函数来计算:
①高精度除以单精度法函数:专题里面会细细地讲的
倒序输出函数:专题里面会细细地讲的
③手算模拟了一下除法的过程,余数*10再除以除数,就得了第一位小数点后的数,保存到k里面,输出再把余数赋值为余数-除数*K(想不通的,可以手动模拟一下过程,其实很简单的)然后一位一位输出即可
代码如下:
 #include <stdio.h>
#include <string.h>
#define MaxLength 99999
int x,q;//q是备份余数用的
void output(int c[])//倒序输出函数
{
int i;
for(i=c[];i>=;i--)
printf("%d",c[i]);
}
/*============================================================================*/
void div(char strA[],int b,int c[])//高精度数a除以整数b,结果保存在c。
{
int a[MaxLength],i,lena,lenc,j,t;
memset(a,,sizeof(a));
memset(c,,sizeof(c));
if(b==)
{
c[]=;
c[]=;
return ;
}
lena=strlen(strA);
for(i=;i<lena;i++) //把串strA正序存储到数组a
a[i+]=strA[i]-'';
x=;
for(i=;i<=lena;i++) //按位相除
{
c[i]=(x*+a[i])/b;
x=(x*+a[i])%b;
}
lenc=;
while(c[lenc]==&&lenc<lena) //高位可能会有一些无意义的0,需要把lenc定好位
lenc++;
c[]=lena-lenc+;
for(j=;j<=c[];j++) //把数组c整体左移,也就是把前缀0给覆盖掉
{
c[j]=c[lenc];
lenc++;
}
for(i=,j=c[];i<j;i++,j--)
{
t=c[i];c[i]=c[j];c[j]=t;
}
q=x;//备份一下余数
output(c);//传入输出函数
}
/*============================================================================*/
int main()
{
char a[MaxLength];
int b[MaxLength];
int i,k;
long long s,n;
gets(a);
scanf("%I64d",&n);
scanf("%d",&s);
div(a,n,b);
printf(".");
for(i=;i<s;i++)//小数点后s位
{
x=x*;
k=x/n;
printf("%d",k);
x=x-n*k;
}
printf("\n%d\n",q);
return ;
}