上一篇讲解的是两个高精度数字相除
接下来这篇是高精度算法的最后一篇内容,它涉及高精度除法的第二种——高精度数字除以常规数字。我们知道,常规数字是可以直接进行除法的,因此,我们不一定都要转换为高精度的整数数组形式。从高精度数字乘以常规数字时,我们就提到过,常规数字转换为高精度的整数数组形式需要使用循环语句,这是非常浪费时间的。特别在复杂的计算中,多一次循环将花费大量的时间。因此我们企图寻找其他方案解决高精度数字与常规数字之间除法的问题。
在前面几篇文章里,我们总是使用举例的方式描述所讲的算法。当然,这次也不例外。我想,这一章节图片更能说明问题。
图中列的是小学数学的知识——列竖式求解除法。这是除法最原始的样子。我们能看到,除法是从最高位开始的。最高为的1
被用来除以234
,这是不自量力的。我们只能给到0
。接着,1
作为余数与下一位2
结合,抱团形成12
,但在234
面前,他们还是显得有点力不从心。下一位3
也加入了阵营,它将12
变为了自己的高位,成为123
,这个数字在234
面前还是有些不足的。只好和4
合作,成为1234
,终于比234
大了。商填写5
。余数是64
,与下一位的0
结合,组成640
。同样的,使用640
在进行这样的运算。
经过这样的分析,思路就很清晰了。使用高位的数字除以常规数字,得到的商作为高位,余数将与下一位结合,继续做除法运算。
我们尝试将这种方法使用程序描述出来。
//描述高精度数字除以常规数字
#include <iostream>
using namespace std;
int main()
{
string s; //存放高精度数字
int num = 0; //常规数字
cin >> s >> num;
int result[100] = {}; //存放结果,假设结果不超过100
long long tmp = 0; //保存余数
for(int i = 0;i < s.size(); ++i) //从高位向低位访问
{
tmp = tmp * 10 + s[i] - '0'; //余数成为高位,与低一位结合形成新数字
result[i] = tmp / num; //获得商
tmp %= num; //获得余数
}//商保留在result中,余数保留在tmp中
//去前导0
int k = 0; //高位在下标为0的位置,因此从0号位置开始
while(result[k] == 0 && k < s.size() - 1)
++k;
for(int i = k; i < s.size(); ++i)
cout << result[i];
cout << endl;
cout << tmp << endl;
}
关于高精度数字除以常规数字的程序描述是比较简单的,我们也没有在使用函数进行实现。但需要注意的是高位保存在左侧,并没有逆向存放。这是非常关键的。同样的,在去前导0
的操作中,我们也要保持这样的状态——从左侧向右寻找。
经过这几篇的描述,高精度数字的相关知识我们暂告一段落了。下一篇,我们将介绍排序的内容。