C语言实现大整数加减乘除运算:基于二进制字符数组
C语言实现大整数加减乘除运算:基于二进制字符数组
首先,我们需要明确一下什么是大整数。在计算机中,一个整数一般是32位或64位的,但是有时候我们需要处理的整数可能会超过这个范围,此时就需要使用大整数来处理。大整数是指位数非常大的整数,它们的位数可以达到上百位、上千位、甚至更多。
在C语言中,我们可以使用字符数组来表示大整数。我们将大整数转换为二进制后,每一位以字符形式表示,存放在字符数组中,这样可以方便地进行加减乘除运算。
下面我们来看一下如何实现大整数的加法、减法、乘法和除法运算。
1. 大整数加法
大整数加法的思路很简单,就是将两个大整数的每一位相加,如果有进位,则将进位加到下一位的运算中。具体实现如下:
#include <stdio.h>
#include <string.h>
#define MAX_LEN 1000
void reverse(char s[])
{
int len = strlen(s);
for (int i = 0; i < len/2; i++) {
char temp = s[i];
s[i] = s[len-i-1];
s[len-i-1] = temp;
}
}
void add(char a[], char b[], char res[])
{
reverse(a);
reverse(b);
int lena = strlen(a);
int lenb = strlen(b);
int len = lena > lenb ? lena : lenb;
int carry = 0;
for (int i = 0; i < len; i++) {
int x = i < lena ? a[i]-'0' : 0;
int y = i < lenb ? b[i]-'0' : 0;
int sum = x + y + carry;
res[i] = sum%10 + '0';
carry = sum/10;
}
if (carry > 0) {
res[len] = carry + '0';
len++;
}
res[len] = '\0';
reverse(res);
}
int main()
{
char a[MAX_LEN], b[MAX_LEN], res[MAX_LEN];
scanf('%s%s', a, b);
add(a, b, res);
printf('%s\n', res);
return 0;
}
在上面的代码中,我们定义了一个reverse函数,用来将字符数组翻转。这是因为我们在进行加法运算时,是从低位到高位依次相加的,但是最终的结果是从高位到低位的,因此需要将结果翻转一下才能输出正确的结果。
在add函数中,我们首先将两个字符数组翻转,然后分别求出它们的长度lena和lenb,取它们中的较大值作为长度len。然后从低位到高位依次相加,将结果存放在结果数组res中。如果有进位,则将进位加到下一位的运算中。最后,如果最高位有进位,则将进位加到结果数组的最后一位。
2. 大整数减法
大整数减法的思路也很简单,就是将两个大整数的每一位相减,如果需要借位,则从高位借位。具体实现如下:
#include <stdio.h>
#include <string.h>
#define MAX_LEN 1000
void reverse(char s[])
{
int len = strlen(s);
for (int i = 0; i < len/2; i++) {
char temp = s[i];
s[i] = s[len-i-1];
s[len-i-1] = temp;
}
}
void sub(char a[], char b[], char res[])
{
reverse(a);
reverse(b);
int lena = strlen(a);
int lenb = strlen(b);
int len = lena > lenb ? lena : lenb;
int borrow = 0;
for (int i = 0; i < len; i++) {
int x = i < lena ? a[i]-'0' : 0;
int y = i < lenb ? b[i]-'0' : 0;
int diff = x - y - borrow;
if (diff < 0) {
diff += 10;
borrow = 1;
} else {
borrow = 0;
}
res[i] = diff + '0';
}
while (len > 1 && res[len-1] == '0') len--;
res[len] = '\0';
reverse(res);
}
int main()
{
char a[MAX_LEN], b[MAX_LEN], res[MAX_LEN];
scanf('%s%s', a, b);
sub(a, b, res);
printf('%s\n', res);
return 0;
}
在上面的代码中,我们也定义了一个reverse函数,用来将字符数组翻转。在sub函数中,我们首先将两个字符数组翻转,然后分别求出它们的长度lena和lenb,取它们中的较大值作为长度len。然后从低位到高位依次相减,如果需要借位,则从高位借位。最后,如果结果中有前导0,则需要将其去掉,即将结果数组的长度减小到最小值。
3. 大整数乘法
大整数乘法的思路也很简单,就是将一个大整数的每一位与另一个大整数相乘,然后将结果相加。具体实现如下:
#include <stdio.h>
#include <string.h>
#define MAX_LEN 1000
void reverse(char s[])
{
int len = strlen(s);
for (int i = 0; i < len/2; i++) {
char temp = s[i];
s[i] = s[len-i-1];
s[len-i-1] = temp;
}
}
void mul(char a[], char b[], char res[])
{
reverse(a);
reverse(b);
int lena = strlen(a);
int lenb = strlen(b);
for (int i = 0; i < lena+lenb; i++) {
res[i] = '0';
}
for (int i = 0; i < lena; i++) {
int carry = 0;
int x = a[i] - '0';
for (int j = 0; j < lenb; j++) {
int y = b[j] - '0';
int sum = (res[i+j] - '0') + x * y + carry;
res[i+j] = sum % 10 + '0';
carry = sum / 10;
}
if (carry > 0) {
res[i+lenb] += carry;
}
}
while (strlen(res) > 1 && res[strlen(res)-1] == '0') {
res[strlen(res)-1] = '\0';
}
reverse(res);
}
int main()
{
char a[MAX_LEN], b[MAX_LEN], res[MAX_LEN];
scanf('%s%s', a, b);
mul(a, b, res);
printf('%s\n', res);
return 0;
}
在上面的代码中,我们也定义了一个reverse函数,用来将字符数组翻转。在mul函数中,我们首先将两个字符数组翻转,然后分别求出它们的长度lena和lenb。我们需要用一个大小为lena+lenb的数组来存放结果,然后将其初始化为0。然后从低位到高位依次相乘,将结果存放在结果数组中。最后,如果结果中有前导0,则需要将其去掉,即将结果数组的长度减小到最小值。
4. 大整数除法
大整数除法的思路也很简单,就是将一个大整数不断减去另一个大整数,直到被除数小于除数为止。具体实现如下:
#include <stdio.h>
#include <string.h>
#define MAX_LEN 1000
void reverse(char s[])
{
int len = strlen(s);
for (int i = 0; i < len/2; i++) {
char temp = s[i];
s[i] = s[len-i-1];
s[len-i-1] = temp;
}
}
int compare(char a[], char b[])
{
int lena = strlen(a);
int lenb = strlen(b);
if (lena > lenb) return 1;
if (lena < lenb) return -1;
for (int i = lena-1; i >= 0; i--) {
if (a[i] > b[i]) return 1;
if (a[i] < b[i]) return -1;
}
return 0;
}
void div(char a[], char b[], char res[])
{
reverse(a);
reverse(b);
int lena = strlen(a);
int lenb = strlen(b);
char temp[MAX_LEN];
char quotient[MAX_LEN];
int pos = 0;
for (int i = lena-1; i >= 0; i--) {
temp[pos++] = a[i];
temp[pos] = '\0';
int cmp = compare(temp, b);
if (cmp < 0) {
quotient[i] = '0';
continue;
}
int k = 0;
while (cmp >= 0) {
cmp = compare(temp, b);
if (cmp < 0) break;
for (int j = lenb-1; j >= 0; j--) {
int x = temp[j] - '0';
int y = b[j] - '0';
if (x < y) {
temp[j] += 10 - y + x;
temp[j-1]--;
} else {
temp[j] = x - y + '0';
}
}
k++;
}
quotient[i] = k + '0';
}
quotient[lena] = '\0';
while (strlen(quotient) > 1 && quotient[strlen(quotient)-1] == '0') {
quotient[strlen(quotient)-1] = '\0';
}
reverse(quotient);
strcpy(res, quotient);
}
int main()
{
char a[MAX_LEN], b[MAX_LEN], res[MAX_LEN];
scanf('%s%s', a, b);
div(a, b, res);
printf('%s\n', res);
return 0;
}
在上面的代码中,我们也定义了一个reverse函数,用来将字符数组翻转。在compare函数中,我们比较两个字符数组的大小,如果第一个数组大于第二个数组,则返回1;如果第一个数组小于第二个数组,则返回-1;如果两个数组相等,则返回0。在div函数中,我们首先将两个字符数组翻转,然后分别求出它们的长度lena和lenb。我们需要用一个字符数组temp来存放被除数,另一个字符数组quotient来存放商,然后将其初始化为空。我们从被除数的最高位开始,依次减去除数,如果减完后仍然大于除数,则继续减,直到小于除数为止。每次减完后,将得到的商存放在商数组中。最后,如果商数组中有前导0,则需要将其去掉,即将结果数组的长度减小到最小值。
注意: 上面的代码仅提供了大整数加减乘除运算的基本实现,实际应用中可能还需要考虑一些其他因素,例如溢出处理、负数处理等。读者可以根据需要进行改进和完善。
希望本文能够帮助你理解如何使用C语言实现大整数的加减乘除运算。如果你有任何问题或建议,请随时在评论区留言。
原文地址: https://www.cveoy.top/t/topic/nJv8 著作权归作者所有。请勿转载和采集!