c语言编程实现大整数的除法运算
时间: 2023-09-10 14:15:03 浏览: 172
c语言实现的大整数数运算程序
4星 · 用户满意度95%
大整数的除法运算可以通过模拟手算的方式实现。具体步骤如下:
1. 将被除数和除数转化为字符串形式,用数组存储每一位的数字。
2. 确定商的位数,即被除数的位数减去除数的位数再加1。
3. 从高位开始,依次将被除数的当前位及后面的若干位(位数等于除数的位数)与除数进行比较,确定商的当前位。
4. 将除数乘以商的当前位,得到一个临时的余数,用被除数减去这个余数得到新的被除数。
5. 将新的被除数的下一位补全,继续执行第3步至第4步,直到商的所有位都确定。
6. 对商进行去前导零操作,输出结果。
下面是一个基于字符串的大整数除法函数的实现:
```c
#include <stdio.h>
#include <string.h>
#define MAX_LEN 1000 // 数组最大长度
void div_bigint(char *a, char *b, char *q, char *r) {
int la = strlen(a), lb = strlen(b), lq = la - lb + 1, lr = lb; // 计算长度
int ia = 0, ib = 0, iq = 0, ir = 0; // 指针初始化
char ta[MAX_LEN], tb[MAX_LEN]; // 临时数组
strcpy(ta, a);
strcpy(tb, b);
while (lr <= la) { // 从高位到低位依次确定商的每一位
while (ib < lb) { // 模拟手算过程,从高位到低位依次比较
if (ta[ia] < tb[ib]) { // 被除数不够除
q[iq++] = '0'; // 商的当前位为0
lr++; // 被除数向右移动一位
ta[ia + lr - 1] = a[ia + lr - 1]; // 将新的被除数的下一位补全
break;
} else {
ia++;
ib++;
}
}
if (ib == lb) { // 被除数够除
int qq = 0; // 当前商的值
while (qq < 10 && strcmp(tb, "0") != 0) { // 尝试商的当前位为1~9
char tq[MAX_LEN]; // 临时数组
memset(tq, 0, MAX_LEN);
sprintf(tq, "%d", qq + 1); // 将数字转化为字符串
char tr[MAX_LEN]; // 临时数组
memset(tr, 0, MAX_LEN);
strcpy(tr, tb);
mul_bigint(tb, tq, tb); // 将除数乘以当前的商的值
if (strcmp(tb, ta + ia) <= 0) { // 如果乘积不大于被除数
qq++; // 商的值加1
strcpy(tb, tr); // 还原除数
} else {
break;
}
}
char tq[MAX_LEN]; // 临时数组
memset(tq, 0, MAX_LEN);
sprintf(tq, "%d", qq); // 将商的值转化为字符串
q[iq++] = tq[0]; // 保存商的当前位
char tr[MAX_LEN]; // 临时数组
memset(tr, 0, MAX_LEN);
mul_bigint(tb, tq, tb); // 将除数乘以当前的商的值
char tt[MAX_LEN]; // 临时数组
memset(tt, 0, MAX_LEN);
memcpy(tt, ta + ia, lr); // 取出被除数的若干位
sub_bigint(tt, tb, tr); // 用被除数减去除数的乘积
memcpy(ta + ia, tr, lr); // 将新的被除数保存
if (strcmp(ta + ia, "0") == 0) { // 如果被除数为0,结束运算
break;
}
ia += lr; // 被除数向右移动一位
ib = 0;
lr = 1;
}
}
while (iq > 1 && q[iq - 1] == '0') { // 去掉前导零
iq--;
}
q[iq] = '\0';
if (strcmp(ta + ia, "0") == 0) { // 如果被除数为0,余数为0
strcpy(r, "0");
} else {
strcpy(r, ta + ia);
}
}
void mul_bigint(char *a, char *b, char *c) { // 大整数乘法函数
int la = strlen(a), lb = strlen(b), lc = la + lb; // 计算长度
int ia, ib, ic; // 指针初始化
int *ta = new int[la], *tb = new int[lb], *tc = new int[lc]; // 动态分配内存
memset(tc, 0, lc * sizeof(int)); // 初始化数组
for (ia = 0; ia < la; ia++) {
ta[ia] = a[la - ia - 1] - '0'; // 将字符串转化为整数数组
}
for (ib = 0; ib < lb; ib++) {
tb[ib] = b[lb - ib - 1] - '0'; // 将字符串转化为整数数组
}
for (ia = 0; ia < la; ia++) { // 计算乘积
for (ib = 0; ib < lb; ib++) {
tc[ia + ib] += ta[ia] * tb[ib];
}
}
for (ic = 0; ic < lc - 1; ic++) { // 进位
tc[ic + 1] += tc[ic] / 10;
tc[ic] %= 10;
}
while (lc > 1 && tc[lc - 1] == 0) { // 去掉前导零
lc--;
}
for (ic = 0; ic < lc; ic++) { // 将整数数组转化为字符串
c[ic] = tc[lc - ic - 1] + '0';
}
c[ic] = '\0';
delete[] ta; // 释放内存
delete[] tb;
delete[] tc;
}
void sub_bigint(char *a, char *b, char *c) { // 大整数减法函数
int la = strlen(a), lb = strlen(b), lc = la; // 计算长度
int ia, ib, ic; // 指针初始化
int *ta = new int[la], *tb = new int[lb], *tc = new int[lc]; // 动态分配内存
memset(tc, 0, lc * sizeof(int)); // 初始化数组
for (ia = 0; ia < la; ia++) {
ta[ia] = a[la - ia - 1] - '0'; // 将字符串转化为整数数组
}
for (ib = 0; ib < lb; ib++) {
tb[ib] = b[lb - ib - 1] - '0'; // 将字符串转化为整数数组
}
for (ia = 0; ia < la; ia++) { // 计算差
if (ia < lb) {
ta[ia] -= tb[ia];
}
if (ta[ia] < 0) {
ta[ia] += 10;
ta[ia + 1]--;
}
tc[ia] = ta[ia];
}
while (lc > 1 && tc[lc - 1] == 0) { // 去掉前导零
lc--;
}
for (ic = 0; ic < lc; ic++) { // 将整数数组转化为字符串
c[ic] = tc[lc - ic - 1] + '0';
}
c[ic] = '\0';
delete[] ta; // 释放内存
delete[] tb;
delete[] tc;
}
int main() {
char a[MAX_LEN], b[MAX_LEN], q[MAX_LEN], r[MAX_LEN]; // 定义变量
scanf("%s%s", a, b); // 输入被除数和除数
div_bigint(a, b, q, r); // 计算商和余数
printf("%s/%s=%s...%s\n", a, b, q, r); // 输出结果
return 0;
}
```
上述代码中,我们使用了三个函数:大整数乘法函数 `mul_bigint()`、大整数减法函数 `sub_bigint()` 和大整数除法函数 `div_bigint()`。其中,大整数乘法函数和大整数减法函数都是比较基础的函数,这里不再赘述,我们主要关注大整数除法函数的实现。
在大整数除法函数中,我们首先计算了被除数和除数的长度,然后从高位到低位依次确定商的每一位。对于每一位,我们通过模拟手算的方式从高位到低位依次比较被除数的当前位及后面的若干位(位数等于除数的位数),确定商的当前位。如果被除数不够除,则商的当前位为0,并将被除数向右移动一位。如果被除数够除,则尝试商的当前位为1~9,计算除数乘以当前的商的值,如果乘积不大于被除数,则商的值加1,并将新的被除数保存。最后,我们对商进行去前导零操作,输出结果。
需要注意的是,在大整数除法函数中,我们调用了大整数乘法函数 `mul_bigint()` 和大整数减法函数 `sub_bigint()` 进行计算。这两个函数的实现也非常重要,因为它们是大整数运算的基础。如果你对这两个函数的实现不熟悉,可以参考其他资料进行学习。
另外,需要注意的是,在进行大整数运算时,需要使用字符串来存储大整数,这样才能处理任意长度的大整数。在本文中,我们将大整数存储为字符串形式,并使用字符数组来存储每一位的数字。这样做的好处是可以方便地进行数组操作,例如截取若干位、补全若干位等。不过,需要注意的是,在进行大整数运算时,需要特别小心数组下标越界的问题,否则会导致程序崩溃或计算错误。
阅读全文