1128: 高精度高精度除法
题目描述
计算n/m的值,设n,m为整数,n的长度小于等于1000,m的长度小于等于15位,要求精确到小数点后500位。如果整数位为零,则省略小数点前的零
输入
两行,每行一个整数
输出
一行,保留500位小数的实数。
样例输入
355
113
样例输出
3.14159292035398230088495575221238938053097345132743362831858407079646017699115044247787610619469026548672566371681415929203539823008849557522123893805309734513274336283185840707964601769911504424778761061946902654867256637168141592920353982300884955752212389380530973451327433628318584070796460176991150442477876106194690265486725663716814159292035398230088495575221238938053097345132743362831858407079646017699115044247787610619469026548672566371681415929203539823008849557522123893805309734513274336
m 的长度小于等于15位,用 long long 就能存的下。这是一道高精除以低精的题目。
所谓的高精除以低精,也是竖式模拟。模拟的时候就是不断截取高精的数,并将其转化成低精的数,直到够除。
一下代码还会具体讲一下怎么控制输出小数点后500位
1 #include<cstdio>
2 #include<iostream>
3 #include<cmath>
4 #include<algorithm>
5 #include<cstring>
6 using namespace std;
7 typedef long long ll;
8 ll m, beichu, jianshu;
9 const int maxn = 1e4 + 5;
10 char a1[maxn];
11 int a[maxn], c[maxn];
12 int num = 0, weishu = 500;
13 int main()
14 {
15 scanf("%s%lld", a1, &m);
16 int la = strlen(a1);
17 for(int i = 0 ; i < la; ++i) a[i] = a1[i] - '0'; //正着存入就可以了
18 weishu += la + 1; //假设最终的位数是这个
19 for(int i = 0; ; ++i)
20 {
21 beichu = beichu * 10 + a[i];
22 if(beichu >= m) //说明取出的数已经够除了
23 {
24 c[++num] = beichu / m; //将这一次的商存入
25 if(num >= weishu) break; //已经到小数点后500位了
26 jianshu = c[num] * m;
27 beichu -= jianshu; //这一次除法结束,余数进行下一次操作(想一想竖式)
28 }
29 else //说明即使被除数的下一位也取出来了,还不够除,那么商就上0
30 {
31 c[++num] = 0;
32 if(num >= weishu) break;
33 }
34 if(i == la - 1) c[++num] = 233333; //标记小数点,虽然方法有点暴力……
35 }
36 int x = 1;
37 while(x < weishu && c[x] == 0) x++; //去除前导0
38 /*现在就可以解释 weishu 刚开始为什么会预处理成 weishu += la + 1了,虽然余数的整数和小数
39 的位数之和一定小于这个值,但是因为我们每一次循环都把商存了进去,所以一定也会存0,那么去
40 除前导0的时候就会把多了的位数去除了,剩下的小数部分的位数一定是500位*/
41 for(int i = x; i <= num; ++i) c[i] == 233333 ? printf(".") : printf("%d", c[i]);
42 printf("\n");
43 return 0;
44 }
来源:oschina
链接:https://my.oschina.net/u/4266471/blog/4053764