C语言实现大整数加减乘除运算详解
首先需要定义一个结构体来表示大整数,包括符号(正负)、位数和每一位的值。然后可以定义四个函数来实现加减乘除运算。
- 大整数加法
大整数加法可以按照二进制加法的方式来实现,从低位到高位依次相加,如果有进位则在高一位加1。需要注意的是,两个大整数的位数可能不相等,需要在位数少的一方前面补0。
- 大整数减法
大整数减法可以按照二进制减法的方式来实现,从低位到高位依次相减,如果被减数小于减数则需要向高一位借1。同样需要注意位数不相等的情况。
- 大整数乘法
大整数乘法可以按照二进制乘法的方式来实现,先将两个大整数转化为二进制,然后从低位到高位依次相乘,如果相乘结果为1则将对应位的值加上该位的权值。
- 大整数除法
大整数除法可以按照二进制除法的方式来实现,先将被除数和除数转化为二进制,然后从高位到低位依次进行除法运算。需要注意的是,如果被除数小于除数则商为0,否则商为1,并将被除数减去除数的值。
以下是示例代码及注释:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAX_LEN 1000 // 定义大整数的最大位数
// 定义大整数结构体
typedef struct {
int sign; // 符号,1为正数,-1为负数
int len; // 位数
int val[MAX_LEN]; // 数值,每一位的值
} BigInt;
// 初始化大整数
void init(BigInt *num) {
num->sign = 1;
num->len = 0;
memset(num->val, 0, sizeof(num->val));
}
// 将字符串转化为大整数
void str2num(BigInt *num, char *str) {
int i, j, len;
init(num);
len = strlen(str);
if (str[0] == '-') {
num->sign = -1;
i = 1;
} else {
i = 0;
}
for (j = len - 1; j >= i; j--) {
num->val[num->len++] = str[j] - '0';
}
}
// 将大整数转化为字符串
void num2str(BigInt *num, char *str) {
int i;
if (num->len == 0) {
str[0] = '0';
str[1] = '\0';
return;
}
if (num->sign == -1) {
str[0] = '-';
i = 1;
} else {
i = 0;
}
for (; i < num->len; i++) {
str[i] = num->val[num->len - i - 1] + '0';
}
str[num->len] = '\0';
}
// 大整数相加
void add(BigInt *a, BigInt *b, BigInt *c) {
int i, carry = 0;
init(c);
c->sign = a->sign;
for (i = 0; i < a->len || i < b->len || carry != 0; i++) {
if (i < a->len) {
carry += a->val[i];
}
if (i < b->len) {
carry += b->val[i];
}
c->val[c->len++] = carry % 2;
carry /= 2;
}
}
// 大整数相减
void sub(BigInt *a, BigInt *b, BigInt *c) {
int i, borrow = 0;
init(c);
c->sign = a->sign;
for (i = 0; i < a->len || i < b->len || borrow != 0; i++) {
if (i < a->len) {
borrow += a->val[i];
}
if (i < b->len) {
borrow -= b->val[i];
}
if (borrow < 0) {
c->val[c->len++] = borrow + 2;
borrow = -1;
} else {
c->val[c->len++] = borrow;
borrow = 0;
}
}
// 去除前导0
while (c->len > 1 && c->val[c->len - 1] == 0) {
c->len--;
}
}
// 大整数相乘
void mul(BigInt *a, BigInt *b, BigInt *c) {
int i, j;
init(c);
c->sign = a->sign * b->sign;
for (i = 0; i < a->len; i++) {
for (j = 0; j < b->len; j++) {
c->val[i + j] += a->val[i] * b->val[j];
if (c->val[i + j] >= 2) {
c->val[i + j + 1] += c->val[i + j] / 2;
c->val[i + j] %= 2;
}
}
}
// 去除前导0
while (c->len > 1 && c->val[c->len - 1] == 0) {
c->len--;
}
}
// 大整数相除
void div(BigInt *a, BigInt *b, BigInt *c) {
int i, j, k;
BigInt tmp, tmp2;
init(c);
c->sign = a->sign * b->sign;
if (b->len == 1 && b->val[0] == 0) {
fprintf(stderr, "division by zero\n");
exit(1);
}
for (i = a->len - 1; i >= 0; i--) {
tmp2.len = 1;
tmp2.val[0] = a->val[i];
mul(&tmp, c, &tmp2);
k = 0;
for (j = tmp.len - 1; j >= 0; j--) {
k = k * 2 + tmp.val[j];
tmp.val[j] = k / b->val[0];
k %= b->val[0];
}
while (tmp.len > 1 && tmp.val[tmp.len - 1] == 0) {
tmp.len--;
}
c->val[i] = tmp.val[0];
c->len = i + 1;
}
// 去除前导0
while (c->len > 1 && c->val[c->len - 1] == 0) {
c->len--;
}
}
int main() {
char str1[MAX_LEN], str2[MAX_LEN];
BigInt num1, num2, res;
printf("请输入第一个大整数:");
scanf("%s", str1);
str2num(&num1, str1);
printf("请输入第二个大整数:");
scanf("%s", str2);
str2num(&num2, str2);
add(&num1, &num2, &res);
printf("加法结果为:%s\n", num2str(&res, str1));
sub(&num1, &num2, &res);
printf("减法结果为:%s\n", num2str(&res, str1));
mul(&num1, &num2, &res);
printf("乘法结果为:%s\n", num2str(&res, str1));
div(&num1, &num2, &res);
printf("除法结果为:%s\n", num2str(&res, str1));
return 0;
}
原文地址: https://www.cveoy.top/t/topic/nJvM 著作权归作者所有。请勿转载和采集!