#C08L03P01. C08.L03.高精度除法.概述
C08.L03.高精度除法.概述
在读小学时,我们做除法都采用竖式方法计算。被除数从高位开始,和除数对齐,逐位“试商”,“试商”后除数减去“试商”的数的乘积,如下图所示。
采用计算机做高精度除法时,模拟日常除法的步骤。但计算机不可能做“试商”,这时,我们可以采用减法来模拟。
试商过程
-
将除数移动和被除数对齐,位数不够时,补 0。
-
利用被除数减去除数,一直减到被除数小于除数,减的次数,就是“试商”的结果,每移动一次。
-
重复上述步骤,一直到被除数和除数的位数相等为止。
举例说明
举一个例子,比如 524134 除以 123,结果是 4261 ,余数为 31。
-
第一位 4 的来源是我们把 524 和 123 对齐,然后进行循环减法,循环了 4 次,余 32;
-
将 32134 的前三位 321 继续和 123 对齐,循环减法 2 次,余 75;
-
把 7534 的前三位 753 和 123 对齐,循环减法 6 次,余 15;
-
将 154 和 123 对齐,只能减 1 次,余 31。
所以 524134 除以 123,结果是 4261,余数为 31。
计算过程
高精度除法实现
设计思路:
-
定义存储数组。
-
读入数据处理。
-
试商过程。
-
删除前导 0 。所谓前导零,就是出现类似这样数据 01234,这个 0 实际是不需要的。
-
输出结果。倒序输出减法的结果数组 C,因为我们的个位是存储在下标为 0 的地方。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 300+4; //根据题目的最大值。+4为了防止A+B出现进位
string s1;//存储字符串
string s2;//存储字符串
int tmp[MAXN] = {};//交换用字符串
int a[MAXN] = {};//存储加数A
int b[MAXN] = {};//存储加数B
int c[MAXN] = {};//存储和B
int compare(int a[], int b[]) {
//索引为0的数据为数组长度
if (a[0]>b[0])
return 1;
else if (a[0]<b[0])
return -1;
//逐位比较
for (int i=a[0]; i>0; i--) {
if (a[i]>b[i])
return 1;
else if (a[i]<b[i])
return -1;
}
return 0;
}
void numcpy(int a[],int b[],int dest) {
//将数组右移,使两个数组右端对齐,形参q数组储存右移后的结果
for (int i=1;i<=a[0];i++) {
b[i+dest-1] =a[i];
}
b[0] = a[0]+dest-1;
}
int main() {
cin>>s1>>s2;//读入字符串
//处理负数
bool flaga = false;//乘数a的符号
if ('-'==s1[0]) {
flaga = true;
s1.erase(s1.begin());;//删除负号
}
bool flagb = false;//乘数b的符号
if ('-'==s2[0]) {
flagb = true;
s2.erase(s2.begin());;//删除负号
}
//处理输出的负号
if (flaga!=flagb)
printf("-");//商为负数
//处理乘数1
int len = s1.size();
a[0] = len;
for (int i=0; i<len; i++)
a[len-i]=s1[i]-'0';
//处理乘数2
len = s2.size();
b[0] = len;
for (int i=0; i<len; i++)
b[len-i]=s2[i]-'0';
if (0==compare(a,b)) {
//两数相等
printf("1\n0\n");
return 0;
}
else if (compare(a,b)==-1){
//被除数小,除数大
printf("0\n");//输出除数
if (true==flaga) {
printf("-");
}
cout<<s1<<endl;
return 0;
}
else {
c[0] = a[0]-b[0]+1;
for (int i=c[0]; i>0; i--) {
memset(tmp, 0, sizeof(tmp));
//高位对齐
numcpy(b,tmp,i);
while (compare(a, tmp)>=0) {
c[i]++;
//减法
for (int j=1; j<=a[0]; j++) {
if (a[j]<tmp[j]) {
a[j+1]--;
a[j]+=10;
}
a[j]-=tmp[j];
}
int k=a[0];
while (a[k]==0)
k--;
a[0]=k;
}
}
//控制最高位的0
while (c[0]>0 && c[c[0]]==0)
c[0]--;
}
//逆序打印输出商和余数
for (int i=c[0]; i>0; i--)
printf("%d", c[i]);
printf("\n");
if (0==a[0])
printf("0\n");
else
{
if (true==flaga)
printf("-");
for (int i=a[0]; i>0; i--)
printf("%d", a[i]);
printf("\n");
}
return 0;
}
相关
在以下作业中: