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函数中,我们首先将两个字符数组翻转,然后分别求出它们的长度lenalenb,取它们中的较大值作为长度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函数中,我们首先将两个字符数组翻转,然后分别求出它们的长度lenalenb,取它们中的较大值作为长度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函数中,我们首先将两个字符数组翻转,然后分别求出它们的长度lenalenb。我们需要用一个大小为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函数中,我们首先将两个字符数组翻转,然后分别求出它们的长度lenalenb。我们需要用一个字符数组temp来存放被除数,另一个字符数组quotient来存放商,然后将其初始化为空。我们从被除数的最高位开始,依次减去除数,如果减完后仍然大于除数,则继续减,直到小于除数为止。每次减完后,将得到的商存放在商数组中。最后,如果商数组中有前导0,则需要将其去掉,即将结果数组的长度减小到最小值。

注意: 上面的代码仅提供了大整数加减乘除运算的基本实现,实际应用中可能还需要考虑一些其他因素,例如溢出处理、负数处理等。读者可以根据需要进行改进和完善。

希望本文能够帮助你理解如何使用C语言实现大整数的加减乘除运算。如果你有任何问题或建议,请随时在评论区留言。


原文地址: https://www.cveoy.top/t/topic/nJv8 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录