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 }