C++语言使用字符数组实现大数加减乘除运算

**要计算1000的阶乘,刚一听以为超级简单的递归,再一想发现不对,这个普通实现肯定会溢出,最后想到了可以用字符串实现这种大数的运算。
然后就直接写代码实现,还真不是那么容易,实现了加法和乘法,最后用乘法实现1000的递归,我去这么大的数,足足占了2000多位。
然后想到可以封装一个大数类,然后实现减法和除法,由于有别的事情除法就简单的用递减被除数实现了,那叫一个慢啊(其实可以从被除数最高位与除数最高位对齐开始拿被除数和除数相等的位数开始减除数,然后得到余数,再照此方法依次向后递推相减,最后得到结果)唉!有时间在优化吧。**

头文件
#include<iostream>
using namespace std;

#define MAX_SIZE 10000

class BigNum
{
private:
    char data[MAX_SIZE];
    char* pDataEnd;
    int size;

public:
    //构造函数
    BigNum(const char* pData);
    BigNum(int intValue);
    //拷贝构造函数
    BigNum(const BigNum& other);

    BigNum& operator=(BigNum& other);

    //初始化(数据置零)
    void init(int type);
    //获取大数的位数
    int getSize();

public:
    //比较大小
    int cmp(BigNum& otherNum);
    bool operator >(BigNum& otherNum);

    //相加
    void add(BigNum& otherNum);
    BigNum operator++();
    //相减
    void sub(BigNum& otherNum);
    BigNum operator--();
    //相乘
    void mul(BigNum& otherNum);
    void mulBase(char*  pData, char* pStartPos, char* currChar);

    //相除
    void div(BigNum& otherNum);

    //阶乘
    static BigNum factorial(BigNum startNum, Big
源文件
#include "BigNum.h"
#include<string>

//构造函数
BigNum::BigNum(const char* pData) :pDataEnd(nullptr), size(0)
{
    //init(0);

    if ((*pData) == '\0')
    {
        return;
    }
    const char* pOtherDataEnd = pData;
    while (*(pOtherDataEnd + 1) != '\0')
    {
        pOtherDataEnd++;
    }

    int index = 0;
    for (; index < MAX_SIZE - 1; index++)
    {
        if (pOtherDataEnd == pData - 1)
        {
            break;
        }
        else if ((*pOtherDataEnd)<'0' || (*pOtherDataEnd)>'9')
        {
            break;
        }
        else
        {
            data[index] = (*pOtherDataEnd);
        }
        pOtherDataEnd--;
    }
    this->pDataEnd = data + index - 1;
    this->size = index;
}

BigNum::BigNum(int intValue) :pDataEnd(nullptr), size(0)
{
    if (intValue == 0)
    {
        init(1);
        return;
    }
    init(0);
    while (intValue>0 && this->size<MAX_SIZE)
    {
        data[this->size] = intValue % 10 + '0';
        intValue /= 10;
        (this->size)++;
    }
    this->pDataEnd = this->data + size - 1;
}
//拷贝构造函数
BigNum::BigNum(const BigNum& other)
{
    for (size_t i = 0; i < MAX_SIZE; i++)
    {
        this->data[i] = other.data[i];
    }
    this->size = other.size;
    this->pDataEnd = this->data + size - 1;
}   

BigNum& BigNum::operator=(BigNum& other)
{
    for (size_t i = 0; i < MAX_SIZE; i++)
    {
        this->data[i] = other.data[i];
    }
    this->size = other.size;
    this->pDataEnd = this->data + size - 1;
    return *this;
}   

//初始化(数据置零)
void BigNum::init(int type)
{   
    for (size_t i = 0; i < MAX_SIZE; i++)
    {
        data[i] = '\0';
    }
    if (type == 0)
    {
        data[0] = '\0';
        this->size = 0;
        this->pDataEnd = this->data;
    }
    else
    {
        data[0] = '0';
        this->size = 1;
        this->pDataEnd = this->data;
    }
}   
//获取大数的位数
int BigNum::getSize()
{   
    return this->size;
}   

//比较大小
int BigNum::cmp(BigNum& otherNum)
{
    if (this->size>otherNum.size)
    {
        return 1;
    }
    else if (this->size<otherNum.size)
    {
        return -1;
    }
    else
    {
        char* myCurrPtr = this->pDataEnd;
        char* otherCurrPtr = otherNum.pDataEnd;

        while ((myCurrPtr + 1) != this->data && (otherCurrPtr + 1) != otherNum.data)
        {
            if ((*myCurrPtr) > (*otherCurrPtr))
            {
                return 1;
            }
            else if ((*myCurrPtr) < (*otherCurrPtr))
            {
                return -1;
            }
            else
            {
                myCurrPtr--;
                otherCurrPtr--;
            }
        }
        return 0;
    }
}   
bool BigNum::operator >(BigNum& otherNum)
{
    if (this->cmp(otherNum) > 0)
    {
        return true;
    }
    return false;
}   

//相加
void BigNum::add(BigNum& otherNum)
{
    char* pOtherDataEnd = otherNum.data;
    this->pDataEnd = this->data;

    int jinwei = 0;
    this->size = 1;
    while ((*pOtherDataEnd) != '\0' || (*(this->pDataEnd)) != '\0')
    {
        int tempValue = 0;
        if ((*pOtherDataEnd) != '\0')
        {
            tempValue += *pOtherDataEnd - '0';
        }
        if ((*(this->pDataEnd)) != '\0')
        {
            tempValue += *(this->pDataEnd) - '0';
        }
        tempValue += jinwei;
        jinwei = tempValue / 10;
        *(this->pDataEnd) = tempValue % 10 + '0';

        pOtherDataEnd++;
        (this->pDataEnd)++;
        this->size++;
    }
    if (this->size < MAX_SIZE && jinwei != 0)
    {
        *(this->pDataEnd) = jinwei + '0';
    }
    else
    {
        --(this->pDataEnd);
        this->size--;
    }
}   
BigNum BigNum::operator++()
{
    BigNum tempNum(1);
    this->add(tempNum);
    return *this;
}   
//相减
void BigNum::sub(BigNum& otherNum)
{
    if (this->cmp(otherNum) <= 0)
    {
        this->init(1);
    }
    else
    {
        int jiewei = 0;     //借位
        char* pMyCurrPtr = this->data;
        char* pOtherCurrPtr = otherNum.data;
        while (pMyCurrPtr != this->pDataEnd + 1)
        {
            if (*pOtherCurrPtr != '\0')
            {
                jiewei += *pOtherCurrPtr;
            }
            else
            {
                jiewei += '0';
            }

            if ((*pMyCurrPtr) >= jiewei)
            {
                *pMyCurrPtr = *pMyCurrPtr - jiewei + '0';
                jiewei = 0;
            }
            else
            {
                *pMyCurrPtr = 10 + *pMyCurrPtr - jiewei + '0';
            jiewei = 1;
        }

        pMyCurrPtr++;
        pOtherCurrPtr++;
    }
    while (*this->pDataEnd == '0' && this->pDataEnd>this->data)
        {
            *(this->pDataEnd) = '\0';
            this->pDataEnd--;
            this->size--;
        }
    }
}   
BigNum BigNum::operator--()
{
    BigNum tempNum(1);
    this->sub(tempNum);
    return *this;
}   
//相乘
void BigNum::mul(BigNum& otherNum)
{
    BigNum tempNum(0);
    if (otherNum > tempNum)
    {
        char* pCurrChar = otherNum.data;
        char tempData[MAX_SIZE + MAX_SIZE] = { 0 };
        char* pTempData = tempData;

        while (*pCurrChar != '\0')
        {
            mulBase(this->data, pTempData++, pCurrChar++);
        }
        //memset(this->data, 0, sizeof(this->data));
        strncpy(this->data, tempData, MAX_SIZE - 1);
        this->size = 0;
        while (this->data[this->size] != '\0')
        {
            this->size++;
        }
        this->pDataEnd = this->data + size - 1;
    }
    else
    {
        init(1);
    }
}   
void BigNum::mulBase(char*  pData, char* pStartPos, char* currChar)
{
    int currValue = *currChar - '0';

    int jinwei = 0;
    while (*pData != '\0')
    {
        int tempValue = currValue*(*pData - '0') + jinwei;
        if (*pStartPos != '\0')
        {
            tempValue += *pStartPos - '0';
        }
        jinwei = tempValue / 10;
        *pStartPos++ = tempValue % 10 + '0';
        pData++;
    }
    while (jinwei != 0)
    {
        if (*pStartPos != '\0')
        {
            int tempValue = *pStartPos - '0' + jinwei;
            jinwei = tempValue / 10;
            *pStartPos = tempValue % 10;
        }
        else
        {
            *pStartPos = jinwei + '0';
            jinwei = 0;
        }
    }

}

//相除
void BigNum::div(BigNum& otherNum)
{   
    if (this->cmp(otherNum)<0)
    {
        *this = BigNum(0);
    }
    else if (this->cmp(otherNum) == 0)
    {
        *this = BigNum(1);
    }
    else
    {
        BigNum resultNum(1);
        this->sub(otherNum);
        while (this->cmp(otherNum) >= 0)
        {
            this->sub(otherNum);
            ++resultNum;
        }
        *this = resultNum;
    }

}   

//阶乘
BigNum BigNum::factorial(BigNum startNum, BigNum countNum)
    {
        BigNum tempNum(0);
        BigNum tempMulNum(1);
        while (countNum>tempNum)
        {
            tempMulNum.mul(startNum);
            --startNum;
            --countNum;
            //temp.print();
        }
        //bigNum1.print();
        return tempMulNum;
    }

void BigNum::print()
{
    char* pCurrPtr = this->pDataEnd;
    while (pCurrPtr != this->data - 1)
    {
        cout << *pCurrPtr--;
    }
    cout << endl;
}   



void main()
{
    char mod = 0;

    while (mod != '0')
    {
        cout << "请选择模式======<<  加:+、减:-、乘:*、除:/、阶乘:!、退出:0 >>======\n\n";
        cin >> mod;
        if (mod == '0')
        {
            break;
        }
        cout << endl;

        string value1;
        string value2;
        cout << "输入第一个数:";
        cin >> value1;
        cout << "输入第二个数:";
        cin >> value2;

        BigNum bigNum1(value1.c_str());
        BigNum bigNum2(value2.c_str());

        if (mod == '+')
        {
            bigNum1.add(bigNum2);
            cout << "相加";
        }
        else if (mod == '-')
        {
            bigNum1.sub(bigNum2);
            cout << "相减";
        }
        else if (mod == '*')
        {
            bigNum1.mul(bigNum2);
            cout << "相乘";
        }
        else if (mod == '/')
        {
            bigNum1.div(bigNum2);
            cout << "相除";
        }
        else if (mod == '!')
        {
            bigNum1 = BigNum::factorial(bigNum1, bigNum2);
            cout << "阶乘";
        }
        else
        {
            continue;
        }

        cout << "结果是:" << endl;
        bigNum1.print();
        cout << "位数是:";
        cout << bigNum1.getSize();
        cout << endl;
    }

    system("pause");
}   

猜你喜欢

转载自blog.csdn.net/zhanghedong526/article/details/47045317