C语言大整数加减乘除运算:二进制实现详解
C语言实现大整数加减乘除运算:二进制存储详解
大整数加减乘除运算的实现涉及到较多的细节问题,需要使用复杂的算法和数据结构。以下是C语言中实现大整数加减乘除运算的基本思路:
- 将大整数转化为二进制:将每一位数字转化为二进制,存放在字符数组中。
- 将二进制数转化为十进制数:从字符数组中读取每一位二进制数,计算对应的十进制数。
- 实现加法:逐位相加,处理进位。
- 实现减法:逐位相减,处理借位。
- 实现乘法:将一个数的每一位与另一个数的每一位相乘,将结果相加。
- 实现除法:使用长除法算法,逐步计算商和余数。
以下是C语言中实现大整数加减乘除运算的示例代码:
#include <stdio.h>
#include <string.h>
#define MAX_LEN 1000 // 定义最大字符数组长度
char a[MAX_LEN], b[MAX_LEN], res[MAX_LEN]; // 定义输入和输出的字符数组
// 将十进制数转化为二进制数
void dec2bin(char *num, char *bin) {
int i, j = 0;
for (i = strlen(num) - 1; i >= 0; i--) { // 从最高位开始转化
int n = num[i] - '0'; // 将数字字符转化为数字
while (n > 0) { // 不断除以2,得到二进制数
bin[j++] = n % 2 + '0'; // 将二进制数以字符形式存放在数组中
n /= 2;
}
}
bin[j] = '\0'; // 字符数组以'\0'结尾
}
// 将二进制数转化为十进制数
void bin2dec(char *bin, char *num) {
int i, j, k, len = strlen(bin);
num[0] = '0'; // 数字初始化为0
num[1] = '\0';
for (i = len - 1; i >= 0; i--) { // 从最高位开始转化
if (bin[i] == '1') { // 如果是1,加上对应的2的幂
for (j = 0, k = 1; j < len - 1 - i; j++, k *= 2) {
if (num[j] == '\0') num[j] = '0'; // 数字不足时,前面补0
int n = num[j] - '0';
n += k;
num[j] = n % 10 + '0';
if (n >= 10 && num[j + 1] == '\0') num[j + 1] = '0'; // 进位时,数字增加一位
while (n >= 10) {
n /= 10;
int m = num[j + 1] - '0';
m += n;
num[j + 1] = m % 10 + '0';
if (m >= 10 && num[j + 2] == '\0') num[j + 2] = '0';
j++;
}
}
}
}
if (num[strlen(num) - 1] == '0') num[strlen(num) - 1] = '\0'; // 去除数字末尾的0
}
// 实现加法
void add(char *a, char *b, char *res) {
int i, j, k, len_a = strlen(a), len_b = strlen(b), len_res = 0, carry = 0;
for (i = len_a - 1, j = len_b - 1; i >= 0 || j >= 0; i--, j--) { // 从最低位开始相加
k = 0;
if (i >= 0) k += a[i] - '0';
if (j >= 0) k += b[j] - '0';
k += carry; // 加上进位
res[len_res++] = k % 2 + '0'; // 计算当前位的值
carry = k / 2; // 计算进位
}
if (carry > 0) res[len_res++] = carry + '0'; // 最高位有进位时,增加一位
res[len_res] = '\0'; // 字符数组以'\0'结尾
strrev(res); // 反转字符数组
}
// 实现减法
void sub(char *a, char *b, char *res) {
int i, j, k, len_a = strlen(a), len_b = strlen(b), len_res = 0, borrow = 0;
for (i = len_a - 1, j = len_b - 1; i >= 0 || j >= 0; i--, j--) { // 从最低位开始相减
k = 0;
if (i >= 0) k += a[i] - '0';
if (j >= 0) k -= b[j] - '0';
k -= borrow; // 减去借位
if (k < 0) { // 需要借位
res[len_res++] = k + 2 + '0'; // 借位后的值
borrow = 1; // 设置借位
} else {
res[len_res++] = k + '0'; // 不需要借位
borrow = 0;
}
}
while (len_res > 1 && res[len_res - 1] == '0') len_res--; // 去除高位的0
res[len_res] = '\0'; // 字符数组以'\0'结尾
strrev(res); // 反转字符数组
}
// 实现乘法
void mul(char *a, char *b, char *res) {
int i, j, k, len_a = strlen(a), len_b = strlen(b), len_res = 0, carry = 0;
for (i = len_a - 1; i >= 0; i--) { // 从最低位开始相乘
char temp[MAX_LEN] = {0}; // 临时结果
k = 0;
for (j = len_b - 1; j >= 0; j--) { // 逐位相乘
k += (a[i] - '0') * (b[j] - '0'); // 计算当前位的乘积
temp[j + 1] = k % 2 + '0'; // 记录当前位的值
k /= 2; // 计算进位
}
if (k > 0) temp[0] = k + '0'; // 最高位有进位时,增加一位
for (j = 0; j < len_a - 1 - i; j++) temp[len_b + j + 1] = '0'; // 补0
add(res, temp, res); // 将临时结果加入总结果中
}
}
// 实现除法
void div(char *a, char *b, char *res) {
int i, j, len_a = strlen(a), len_b = strlen(b), len_res = 0;
char temp[MAX_LEN] = {0}; // 临时被除数
for (i = 0; i < len_a; i++) { // 从最高位开始逐步计算商和余数
temp[i] = a[len_a - 1 - i]; // 取出一位被除数
temp[i + 1] = '\0';
if (strcmp(temp, b) < 0) { // 被除数小于除数时,商为0
res[i] = '0';
continue;
}
for (j = 0; j <= 1; j++) { // 从最高位开始逐步计算商和余数
char temp2[MAX_LEN] = {0}; // 临时除数
temp2[0] = j + '0'; // 取出一位除数
mul(b, temp2, temp2); // 计算当前位的乘积
if (strcmp(temp, temp2) >= 0) { // 被除数大于等于除数时,减去除数
sub(temp, temp2, temp); // 计算当前位的余数
res[i] = j + '0'; // 记录当前位的商
break;
}
}
}
res[len_a] = '\0'; // 字符数组以'\0'结尾
strrev(res); // 反转字符数组
}
int main() {
printf("请输入两个大整数:\n");
scanf("%s %s", a, b);
char bin_a[MAX_LEN * 4] = {0}, bin_b[MAX_LEN * 4] = {0};
dec2bin(a, bin_a);
dec2bin(b, bin_b);
printf("二进制表示为:%s %s\n", bin_a, bin_b);
char num_a[MAX_LEN] = {0}, num_b[MAX_LEN] = {0};
bin2dec(bin_a, num_a);
bin2dec(bin_b, num_b);
printf("十进制表示为:%s %s\n", num_a, num_b);
add(bin_a, bin_b, res);
printf("相加的结果为:%s\n", res);
sub(bin_a, bin_b, res);
printf("相减的结果为:%s\n", res);
mul(bin_a, bin_b, res);
printf("相乘的结果为:%s\n", res);
div(bin_a, bin_b, res);
printf("相除的结果为:%s\n", res);
return 0;
}
以上代码仅为示例代码,实际应用中需要根据具体情况进行修改和优化。
原文地址: https://www.cveoy.top/t/topic/nJvU 著作权归作者所有。请勿转载和采集!