C语言实现大整数加减乘运算:基于二进制字符数组表示

为了解决大整数的表示与运算溢出问题,我们可以将大整数先转换成二进制,再把二进制中的每一位,0 或 1,以'0'或'1'字符的形式,从低到高位依次存放到一个字符数组中,称为大数的二进制字符数组表示。

以下是一个示例代码,支持大整数的加、减、乘运算,同时含有注释和符号判断:

#include <stdio.h>
#include <string.h>

#define MAX_LEN 1000 // 数组最大长度

// 将大整数转换为二进制字符数组表示
void toBinary(char* num, int len, char* bin) {
    for (int i = 0; i < len; i++) {
        int n = num[i] - '0'; // 将字符转换为数字
        for (int j = 0; j < 4; j++) {
            bin[i * 4 + j] = (n & (1 << j)) ? '1' : '0'; // 将数字转换为二进制字符
        }
    }
    bin[len * 4] = '\0'; // 末尾加上结束符
}

// 将二进制字符数组表示转换为大整数
void toNumber(char* bin, char* num) {
    int len = strlen(bin) / 4;
    for (int i = 0; i < len; i++) {
        int n = 0;
        for (int j = 0; j < 4; j++) {
            n |= ((bin[i * 4 + j] - '0') << j); // 将二进制字符转换为数字
        }
        num[i] = n + '0'; // 将数字转换为字符
    }
    num[len] = '\0'; // 末尾加上结束符
}

// 对二进制字符数组表示进行补位,使其长度为len
void pad(char* bin, int len) {
    int cur_len = strlen(bin);
    if (cur_len < len) {
        for (int i = 0; i < len - cur_len; i++) {
            bin[cur_len + i] = '0';
        }
        bin[len] = '\0'; // 末尾加上结束符
    }
}

// 对二进制字符数组表示进行去零,使其最高位不为0
void trim(char* bin) {
    int len = strlen(bin);
    while (len > 1 && bin[len - 1] == '0') {
        bin[len - 1] = '\0';
        len--;
    }
}

// 二进制字符数组表示的加法
void addBinary(char* bin1, char* bin2, char* res) {
    int len1 = strlen(bin1);
    int len2 = strlen(bin2);
    int len = (len1 > len2) ? len1 : len2; // 结果长度为两数长度的较大值
    pad(bin1, len);
    pad(bin2, len);
    int carry = 0;
    for (int i = 0; i < len; i++) {
        int sum = (bin1[i] - '0') + (bin2[i] - '0') + carry;
        res[i] = (sum % 2) ? '1' : '0';
        carry = sum / 2;
    }
    if (carry) {
        res[len] = '1';
        len++;
    }
    else {
        res[len] = '\0';
    }
    trim(res);
}

// 二进制字符数组表示的减法
void subBinary(char* bin1, char* bin2, char* res) {
    int len1 = strlen(bin1);
    int len2 = strlen(bin2);
    int len = (len1 > len2) ? len1 : len2; // 结果长度为两数长度的较大值
    pad(bin1, len);
    pad(bin2, len);
    int borrow = 0;
    for (int i = 0; i < len; i++) {
        int diff = (bin1[i] - '0') - (bin2[i] - '0') - borrow;
        if (diff < 0) {
            diff += 2;
            borrow = 1;
        }
        else {
            borrow = 0;
        }
        res[i] = (diff == 1) ? '1' : '0';
    }
    trim(res);
}

// 二进制字符数组表示的乘法
void mulBinary(char* bin1, char* bin2, char* res) {
    int len1 = strlen(bin1);
    int len2 = strlen(bin2);
    int len = len1 + len2; // 结果长度为两数长度之和
    char tmp[MAX_LEN] = { 0 };
    for (int i = 0; i < len1; i++) {
        int carry = 0;
        for (int j = 0; j < len2; j++) {
            int prod = (bin1[i] - '0') * (bin2[j] - '0') + carry;
            tmp[i + j] = (prod % 2) ? '1' : '0';
            carry = prod / 2;
        }
        if (carry) {
            tmp[i + len2] = '1';
        }
    }
    pad(tmp, len);
    strcpy(res, tmp);
    trim(res);
}

int main() {
    char num1[MAX_LEN], num2[MAX_LEN], op;
    scanf('%s %c %s', num1, &op, num2);

    int len1 = strlen(num1);
    int len2 = strlen(num2);
    char bin1[MAX_LEN * 4 + 1], bin2[MAX_LEN * 4 + 1], res[MAX_LEN * 8 + 1];
    toBinary(num1, len1, bin1);
    toBinary(num2, len2, bin2);

    switch (op) {
    case '+':
        addBinary(bin1, bin2, res);
        break;
    case '-':
        subBinary(bin1, bin2, res);
        break;
    case '*':
        mulBinary(bin1, bin2, res);
        break;
    default:
        printf('Invalid operator\n');
        return 1;
    }

    int sign1 = (num1[0] == '-') ? -1 : 1;
    int sign2 = (num2[0] == '-') ? -1 : 1;
    int sign = 1;
    if (op == '-' && sign1 * sign2 == -1) {
        sign = -1;
    }
    if (sign == -1) {
        printf('-');
    }
    toNumber(res, num1);
    printf('%s\n', num1);

    return 0;
}

需要注意的是,对于减法,我们需要判断被减数和减数的符号,如果它们不同,就相当于做加法,结果的符号为被减数的符号;否则,做减法,结果的符号为被减数和减数的符号相同。在代码中,我们通过sign1sign2分别记录被减数和减数的符号,通过sign来记录结果的符号。如果sign为-1,则在输出结果前先输出负号。

C语言实现大整数加减乘运算:基于二进制字符数组表示

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

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