高精除以低精

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("
");
43     return 0;
44 }
原文地址:https://www.cnblogs.com/mrclr/p/8535873.html