天天看點

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

繼續閱讀