天天看点

C++ 大整数类(支持上亿个位的整数 '+'、'-'、'*'、'/'、'%'、'^' 计算实现)

C++ 大整数类(支持上亿个位的整数 '+'、'-'、'*'、'/'、'%'、'^' 计算实现)

设计这个类的初衷,来自一次面试,第一个加数是1后面接一千个0,第二个加数是2后面接一千个0,描述这两个数相加的过程,而 int 类型的范围是-2147483648~2147483647,只能接9个0,unsigned long long int 类型也只能保存最大 18446744073709551615,1后面接19个0,远远无法满足需求,于是需要设计一个类来保存大整数的每一位。

LagerData类,包含两个成员变量,bool类型变量保存整数的正负号,char*类型变量指向一个字符串,字符串中保存每一位数字。

此类运用了大量C++的基础语法,无参构造、数值构造,数字字符串构造、拷贝构造、各种操作符重载、友元函数重载、使 string 类型变量可以像 stringstream 类型一样级联式输出,将数据级联式输出到 LagerData 类中

LagerData类的头文件声明如下:

class LagerData
{

private:

    bool	m_sign;
    char*	m_point;
    
public:
    
    // 默认构造函数
    LagerData(int num = 0, size_t length = 0);

    // 字符串形式构造
    LagerData(char const* pNum, size_t len);

    // 拷贝构造函数
    LagerData(LagerData const& that);

    // 析构函数
    virtual ~LagerData();

    // 非负数判断,非负数返回true,负数返回false
    bool nonnegative() const;

    // 负数判断,负数返回true,非负数返回false
    bool negative() const;

    // 返回该数据的长度(从数字首位开始计数,首位是0也会计数)
    size_t size() const;

    // 第一位有效数字(不为0的数)的索引号
    size_t const firstvalid() const;

    // 有效数字的个数
    size_t const validnum() const;

    // 将数字规格化,将数字前面的0去除,不是常对象的返回自身引用
    LagerData& regularization();

    // 将数字规格化,将数字前面的0去除,常对象的返回一个规格化后的常对象
    LagerData const regularization() const;

    // 打印每一位数字信息
    void print();

    // 方括号重载,返回下表位置的数值,不是常对象的返回该位置引用,可修改
    char& operator[](int index);

    // 方括号重载,返回下表位置的数值,常对象的返回常量字符,不可修改数据对象本身
    char const operator[](int index) const;

    // ==号操作符重载,判断两个大数据是否相等
    bool operator==(LagerData const& that) const;

    //  !=号操作符重载,判断两个大数据是否不相等
    bool operator!=(LagerData const& that) const;

    // 大于等于操作符重载,判断左操作数是否大于等于右操作数
    bool operator>=(LagerData const& that) const;

    // 小于等于操作符重载,判断左操作数是否小于等于右操作数
    bool operator<=(LagerData const& that) const;

    // 大于操作符重载,判断左操作数是否大于右操作数
    bool operator>(LagerData const& that) const;

    //  小于操作符重载,判断左操作数是否小于右操作数
    bool operator<(LagerData const& that) const;

    // 赋值操作符重载,将右操作数拷贝到左操作数,此为深拷贝
    LagerData& operator=(LagerData const& that);

    // 负号操作符重载,将操作数取反
    LagerData const operator-() const;

    // 加号操作符重载
    LagerData const operator+(LagerData const& that) const;

    // 减号操作符重载
    LagerData const operator-(LagerData const& that) const;

    // 乘法操作符重载
    LagerData const operator*(LagerData const& that) const;

    // 除法操作符重载
    LagerData const operator/(LagerData const& that) const;

    // %(取余)操作符重载
    LagerData const operator%(LagerData const& that) const;

    // 乘方操作符重载
    LagerData const operator^(LagerData const& that) const;

    // 前++
    LagerData& operator++();

    // 前--
    LagerData& operator--();

    // 后++
    LagerData const operator++(int);

    // 后--
    LagerData const operator--(int);

    // +=操作符重载
    LagerData& operator+=(LagerData const& that);

    // -=操作符重载
    LagerData& operator-=(LagerData const& that);

    // *=操作符重载
    LagerData& operator*=(LagerData const& that);

    // /=操作符重载
    LagerData& operator/=(LagerData const& that);

    // %=操作符重载
    LagerData& operator%=(LagerData const& that);

    // ^=操作符重载
    LagerData& operator^=(LagerData const& that);

    // 友元函数,<<操作符重载,左操作数是标准输出流对象,右操作数是长数据类型
    friend std::ostream& operator<<(std::ostream& os, LagerData const& that);
    
    // 友元函数,>>操作符重载,左操作数是字符串对象,右操作数是长数据类型
    friend std::string& operator>>(std::string& str, LagerData& that);
};

           

测试代码:

int main()
{
    cout << "欢迎使用大整数型计算器!" << endl;
    while (true) {
        cout << "请输入算式:(输入q退出)" << endl;
        string strBuffer;
        getline(cin, strBuffer);
        if (strBuffer == "q") {
            break;
        } else if (strBuffer == "") {
            continue;
        } else  if (strBuffer.find_first_not_of("0123456789+-*/%^ ") != string::npos) {
            cout << "有无法识别的字符,请重新键入只包含空白符、数字以及'+'、'-'、'*'、'/'、'%'、'^'的输入"
                << endl << "算式输入格式为(数字 运算符号 数字),如:1 + 2" << endl << endl;
            continue;
        }
        try {
            LagerData LagerLeft, LagerRight;
            MyChar chOperator;      // 自定义计算符号类,用于下一行级联式输入,不得已重写一个符号类
            strBuffer >> LagerLeft >> chOperator >> LagerRight;
            switch (*chOperator) {
                case '+':
                    cout << LagerLeft << ' ' << chOperator << ' ' << LagerRight << " = " << (LagerLeft + LagerRight) << endl;
                    break;
                case '-':
                    cout << LagerLeft << ' ' << chOperator << ' ' << LagerRight << " = " << (LagerLeft - LagerRight) << endl;
                    break;
                case '*':
                    cout << LagerLeft << ' ' << chOperator << ' ' << LagerRight << " = " << (LagerLeft * LagerRight) << endl;
                    break;
                case '/':
                    // 如果除数为0,将会抛出异常,此处需异常捕捉
                    cout << LagerLeft << ' ' << chOperator << ' ' << LagerRight << " = " << (LagerLeft / LagerRight) << endl;
                    break;
                case '%':
                    // 如果除数为0,将会抛出异常,此处需异常捕捉
                    cout << LagerLeft << ' ' << chOperator << ' ' << LagerRight << " = " << (LagerLeft % LagerRight) << endl;
                    break;
                case '^':
                    // 整数型计算器,不能计算负指数,如果有输入负指数的算式,将抛出异常
                    cout << LagerLeft << ' ' << chOperator << ' ' << LagerRight << " = " << (LagerLeft ^ LagerRight) << endl;
                    break;
                default:
                    cout << "对不起,无法识别您输入的运算,请输入格式为(数字 运算符号 数字)的算式,如:1 + 2" << endl;
                    break;
            }
        } catch (const std::exception& except) {
            cout << except.what() << endl;
        }
    }

    return 0;
}

           

测试代码中用到的自定义 MyChar 类头文件声明为:

class MyChar
{

private:

    char m_character;
    
public:

    // 解引用操作符重载,
    char operator*();
    
    // 友元函数,<<操作符重载,左操作数是标准输出流对象,右操作数是自定义字符类型
    friend std::ostream& operator<<(std::ostream& os, MyChar const& that);
    
    // 友元函数,>>操作符重载,左操作数是字符串对象,右操作数是自定义字符类型,接收计算符号
    friend std::string& operator>>(std::string& str, MyChar& that);
};
           

测试结果:

正常测试结果:

C++ 大整数类(支持上亿个位的整数 '+'、'-'、'*'、'/'、'%'、'^' 计算实现)

超长输入测试结果:

C++ 大整数类(支持上亿个位的整数 '+'、'-'、'*'、'/'、'%'、'^' 计算实现)

超长输出测试结果:

C++ 大整数类(支持上亿个位的整数 '+'、'-'、'*'、'/'、'%'、'^' 计算实现)

错误处理结果:

C++ 大整数类(支持上亿个位的整数 '+'、'-'、'*'、'/'、'%'、'^' 计算实现)

源文件代码比较多,超过600行,所以就不贴在这里了,有需要的同学,请点击下方链接下载吧

https://download.csdn.net/download/weixin_42438777/11125348

继续阅读