大整数的四则运算

之前写过一套“大实数”的算法,但那一套采用的是C++、只有加法与乘法、注释残缺不全(Δεν ξέρω καν τι γράφω)。还是以一种负责的态度将源码重置一下吧。

前作:用线性顺序表(数组)计算大实数加法与大实数乘法

/**
 * @(#) BigInteger.h
 * 作者:Legend_1949
 * 编写日期:2019年1月9日
 * 语言:C
 **/
#pragma once
#include <string.h>
#include <stdlib.h>

 // 设置大整数精度
#define PRECISION (25)

// 自定义类型
typedef struct
{
    int valueArray[PRECISION];
} BigInteger;
typedef const char * String;

// 输入数值
BigInteger setValue(String _string)
{
    // 初始化大整数结构体实例,所有位被初始化为0
    BigInteger temp = { {0} };
    // 获取大整数字符串的长度
    int length = strlen(_string);
    for (int i = length - 1, j = PRECISION - 1; i >= 0; i--, j--)
    {
        // 从右向左提取字符串的每一位数字,存入大整数数组中
        temp.valueArray[j] = (int)(_string[i] - '0');
    }
    return temp;
}

// 读取数值
String getValue(BigInteger _bigInteger)
{
    char *string = (char *)calloc(PRECISION + 1, sizeof(char));
    string[PRECISION] = '\0';
    for (int i = 0; i < PRECISION; i++)
    {
        // 从左到右将大整数数组的每一位转化为字符
        string[i] = (char)(_bigInteger.valueArray[i] + '0');
    }
    // 不是所有位都有效(开头可能存在无意义的0),所以通过重设指针去除无效位
    char *temp = string;
    // 持续移指针到有效位上
    while (*temp == '0')
    {
        temp++;
    }
    // 由于C中的字符串是通过字符数组实现的,所以返回指向字符串开头的指针
    return temp;
}

// 大整数加法
BigInteger add(BigInteger _param1, BigInteger _param2)
{
    // 新建空结果
    BigInteger result = { {0} };
    // 进位标记
    int extra = 0;
    // 加法运算从低位(右)向高位(左)进行
    for (int i = PRECISION - 1; i >= 0; i--)
    {
        int sum = _param1.valueArray[i] + _param2.valueArray[i] + extra;
        result.valueArray[i] = sum % 10;
        extra = sum / 10;
    }
    return result;
}

// 大整数减法
BigInteger minus(BigInteger _param1, BigInteger _param2)
{
    // 新建空结果
    BigInteger result = { {0} };
    // 借位标记
    int borrow = 0;
    // 减法运算从低位(右)向高位(左)进行
    for (int i = PRECISION - 1; i >= 0; i--)
    {
        // 若被减数小于减数,则需要借位
        if (_param1.valueArray[i] < _param2.valueArray[i])
        {
            result.valueArray[i] = 10 + _param1.valueArray[i] - _param2.valueArray[i] - borrow;
            borrow = 1;
        }
        // 否则直接相减
        else
        {
            result.valueArray[i] = _param1.valueArray[i] - _param2.valueArray[i] - borrow;
            borrow = 0;
        }
    }
    return result;
}

// 大整数乘法
BigInteger multipy(BigInteger _param1, BigInteger _param2)
{
    // 新建空结果
    // 由于乘法会导致数位快速增长,所以另外新建结果数组,清算后再截取
    int temp[2 * PRECISION] = { {0} };
    // 笛卡尔乘法,模拟竖式运算
    // 第1步,乘数按位进行分配,得到各位的结果
    for (int i = PRECISION - 1; i >= 0; i--)
    {
        for (int j = PRECISION - 1; j >= 0; j--)
        {
            // ★难点:此处需要通过下标对结果进行数位对齐
            temp[i + j + 1] = temp[i + j + 1] + _param1.valueArray[j] * _param2.valueArray[i];
        }
    }
    // 第2步,清算分配结果和进位
    int extra = 0;
    for (int i = PRECISION - 1; i >= 0; i--)
    {
        int sum = temp[i] + extra;
        temp[i] = sum % 10;
        extra = sum / 10;
    }
    // 新建空白结果
    BigInteger result = { {0} };
    // 忽略真实结果左侧超出精度的值
    for (int i = 0; i < PRECISION; i++)
    {
        result.valueArray[PRECISION - i - 1] = temp[2 * PRECISION - i - 1];
    }
    return result;
}

// 大整数比较
int compare(BigInteger _param1, BigInteger _param2)
{
    // 从高位(左)向低位(右),逐位比对
    for (int i = 0; i < 25; i++)
    {
        // 小于为-1
        if (_param1.valueArray[i] < _param2.valueArray[2])
        {
            return -1;
        }
        // 大于为1
        else if (_param1.valueArray[1] > _param2.valueArray[2])
        {
            return 1;
        }
    }
    // 完全相同则为0
    return 0;
}

// 大整数除法
BigInteger divide(BigInteger _param1, BigInteger _param2)
{
    // 说实话,我也不知道除法要怎么写
}
发布了11 篇原创文章 · 获赞 8 · 访问量 4764

猜你喜欢

转载自blog.csdn.net/u011367208/article/details/86623511