大整数类设计(C++)

简介

在平时的功能需求中,C/C++语言内置的整形变量表示范围已经足够大了,但是在一些特定的场合,例如解决数学问题的时候,可能需要表示极大的整数。这时候C/C++语言提供的类型就不能满足需求了,需要自己来实现超大整数的实现,当然仅仅是能够存储超大整数还不行,还要能够进行运算。

设计功能

  1. 能够表达正数与负数
  2. 能够由整形或字符串转化得到
  3. 能够使用 + - * / 等符号进行运算
  4. 可以与int 类型进行混合运算
  5. 可以使用输入输出流
  6. 当发生除数为零等错误时会抛出异常

源码分享

头文件:big_int.h

#ifndef BIGINT_H
#define BIGINT_H

#include <iostream>
#include <vector>
using std::istream;
using std::ostream;
using std::string;
using std::vector;
class BigInt {
   public:
    BigInt(long long num = 0);
    explicit BigInt(string str);
    virtual ~BigInt();
    
    int digit_at(size_t index) const;

     BigInt& operator=(const BigInt& number2);
     BigInt& operator+=(const BigInt& number2);
     BigInt& operator*=(const BigInt& number2);
     BigInt& operator-=(const BigInt& number2);
     BigInt& operator/=(const BigInt& number2);
     BigInt& operator%=(const BigInt& number2);
     BigInt& operator++();
     BigInt& operator--();
     BigInt operator++(int);
     BigInt operator--(int);

    friend bool operator==(const BigInt& number1, const BigInt& number2);
    friend bool operator!=(const BigInt& number1, const BigInt& number2);
    friend bool operator<(const BigInt& number1, const BigInt& number2);
    friend bool operator>(const BigInt& number1, const BigInt& number2);
    friend bool operator<=(const BigInt& number1, const BigInt& number2);
    friend bool operator>=(const BigInt& number1, const BigInt& number2);

    friend BigInt operator+(const BigInt& number1, const BigInt& number2);
    friend BigInt operator*(const BigInt& number1, const BigInt& number2);
    friend BigInt operator-(const BigInt& number1, const BigInt& number2);
    friend BigInt operator/(const BigInt& number1, const BigInt& number2);
    friend BigInt operator%(const BigInt& number1, const BigInt& number2);
    friend ostream& operator<<(ostream& output, const BigInt& num);
    friend istream& operator>>(istream& intput, BigInt& num);

   private:
    vector<char> number;
    bool negtive;
    static void simple_calc(vector<char>& number1, const vector<char>& number2,
                            bool plus);
    static void add_at(vector<char>& num, int i, unsigned char x);
    static bool greater(const vector<char>& number1, const vector<char>& number2);
};
#endif

源文件:big_int.cpp

#include "big_int.h"
using std::cin;
using std::cout;
using std::endl;

BigInt::BigInt(long long num) {
    negtive = false;
    if (num < 0) {
        num *= -1;
        negtive = true;
    }
    while (num) {
        number.emplace_back(num % 10);
        num /= 10;
    }
    if (number.empty()) {
        number.emplace_back(0);
    }
}

BigInt::BigInt(string str) {
    negtive = false;
    for (int i = str.length() - 1; i >= 0; i--) {
        if (str[i] >= '0' && str[i] <= '9') {
            number.emplace_back(str[i] - '0');
        } else if (i == 0 && str[0] == '-') {
            negtive = true;
        } else {
            break;
        }
    }
    while (number.back() == 0) {
        number.pop_back();
    }
    if (number.empty()) {
        number.emplace_back(0);
        negtive = false;
    }
}
BigInt::~BigInt() {}

int BigInt::digit_at(size_t index) const {
    if (index >= number.size()) {
        throw "Out of range";
    }
    return number[index];
}
void BigInt::add_at(vector<char>& number, int index, unsigned char x) {
    if (x == 0) {
        return;
    }
    int size = number.size();
    if (index >= size) {
        number.insert(number.end(), index - size + 1, 0);
        size = index + 1;
    }
    number[index] += x;
    while (index < size && number[index] >= 10) {
        if (index + 1 == size) {
            number.emplace_back(number[index] / 10);
            size++;
        } else {
            number[index + 1] += number[index] / 10;
        }
        number[index] %= 10;
        index++;
    }
}

BigInt& BigInt::operator=(const BigInt& number2) {
    number = number2.number;
    negtive = number2.negtive;
    return *this;
}
BigInt& BigInt::operator+=(const BigInt& number2) {
    if (negtive != number2.negtive && BigInt::greater(number2.number, number)) {
        BigInt ans = number2;
        BigInt::simple_calc(ans.number, number, false);
        *this = ans;
        return *this;
    }
    BigInt::simple_calc(number, number2.number, negtive == number2.negtive);
    if (number.size() == 1 && number[0] == 0) {
        negtive = false;
    }
    return *this;
}
BigInt& BigInt::operator*=(const BigInt& number2) {
    *this = (*this) * number2;
    return *this;
}
BigInt& BigInt::operator-=(const BigInt& number2) {
    *this = (*this) - number2;
    return *this;
}
BigInt& BigInt::operator/=(const BigInt& number2) {
    *this = (*this) / number2;
    return *this;
}
BigInt& BigInt::operator%=(const BigInt& number2) {
    if (number2 == 0){
        throw "Divide by zero";
    }
    if (BigInt::greater(number2.number, number)) {
        return *this;
    }
    int index = number.size() - number2.number.size();
    while (index >= 0) {
        vector<char> temp(index, 0);
        temp.insert(temp.end(), number2.number.begin(), number2.number.end());
        while (!BigInt::greater(temp, number)) {
            BigInt::simple_calc(number, temp, false);
        }
        index--;
    }
    if (number.size() == 1 && number[0] == 0){
        negtive = false;
    }
    return *this;
}

BigInt& BigInt::operator++() {
    (*this) += 1;
    return *this;
}
BigInt& BigInt::operator--() {
    (*this) -= 1;
    return *this;
}
BigInt BigInt::operator++(int) {
    BigInt temp = (*this);
    (*this) += 1;
    return temp;
}
BigInt BigInt::operator--(int) {
    BigInt temp = (*this);
    (*this) -= 1;
    return temp;
}

bool operator==(const BigInt& number1, const BigInt& number2) {
    if (number1.negtive != number2.negtive) {
        return false;
    }
    return number1.number == number2.number;
}
bool operator!=(const BigInt& number1, const BigInt& number2) {
    return !(number1 == number2);
}
bool operator<(const BigInt& number1, const BigInt& number2) {
    return number2 > number1;
}
bool operator>(const BigInt& number1, const BigInt& number2) {
    if (number1.negtive == false) {
        if (number2.negtive == true) {
            return true;
        } else {
            return BigInt::greater(number1.number, number2.number);  //全为正数
        }
    } else {
        if (number2.negtive == false) {
            return false;
        } else {
            return BigInt::greater(number2.number, number1.number);  //全为负数
        }
    }
}
bool operator<=(const BigInt& number1, const BigInt& number2) {
    return !(number1 > number2);
}
bool operator>=(const BigInt& number1, const BigInt& number2) {
    return !(number1 < number2);
}

BigInt operator+(const BigInt& number1, const BigInt& number2) {
    BigInt ans = number1;
    ans += number2;
    return ans;
}
BigInt operator*(const BigInt& number1, const BigInt& number2) {
    BigInt ans = 0;
    if (number1 == 0 || number2 == 0) {
        return ans;
    }
    ans.negtive = (number1.negtive != number2.negtive);  //同号得正,异号得负
    for (size_t i = 0; i < number1.number.size(); i++) {
        for (size_t j = 0; j < number2.number.size(); j++) {
            BigInt::add_at(ans.number, i + j,
                           number1.number[i] * number2.number[j]);
        }
    }
    return ans;
}

BigInt operator-(const BigInt& number1, const BigInt& number2) {
    BigInt temp = number2;
    temp.negtive = !number2.negtive;  // temp 是number2的相反数
    return operator+(number1, temp);  // n1 - n2 = n1 + (-1 * n2)
}
BigInt operator/(const BigInt& number1, const BigInt& number2) {
    BigInt ans = 0;
    if (number2 == 0){
        throw "Divide by zero";
    }
    if (BigInt::greater(number2.number, number1.number)) {
        return ans;
    }
    ans.negtive = (number1.negtive != number2.negtive);
    vector<char> left = number1.number;
    int index = left.size() - number2.number.size();
    while (index >= 0) {
        vector<char> temp(index, 0);
        temp.insert(temp.end(), number2.number.begin(), number2.number.end());
        while (!BigInt::greater(temp, left)) {
            BigInt::simple_calc(left, temp, false);
            BigInt::add_at(ans.number, index, 1);
        }
        index--;
    }
    return ans;
}
BigInt operator%(const BigInt& number1, const BigInt& number2) {
    BigInt ans = number1;
    ans %= number2;
    return ans;
}
istream& operator>>(istream& in, BigInt& num) {
    string str;
    in >> str;
    num = BigInt(str);
    return in;
}
ostream& operator<<(ostream& out, const BigInt& num) {
    if (num.negtive) {
        out << '-';
    }
    for (int i = num.number.size() - 1; i >= 0; --i) {
        out << (char)(num.number[i] + '0');
    }
    return out;
}

void BigInt::simple_calc(vector<char>& num1, const vector<char>& num2,
                         bool plus) {
    int size1 = num1.size();
    int size2 = num2.size();
    if (plus) {
        for (int i = 0; i < size2; i++) {
            add_at(num1, i, num2[i]);
        }
        return;
    } else {
        for (int i = 0; i < size2; i++) {
            num1[i] -= num2[i];
        }
        for (int i = 0; i < size1; i++) {
            if (num1[i] >= 0) {
                continue;
            }
            char temp = (9 - num1[i]) / 10;
            num1[i + 1] -= temp;
            num1[i] += temp * 10;
        }
        while (size1 > 1 && num1.back() == 0) {
            num1.pop_back();
            size1--;
        }
        return;
    }
}

bool BigInt::greater(const vector<char>& number1, const vector<char>& number2) {
    if (number1.size() != number2.size()) {
        return number1.size() > number2.size();
    }
    for (int i = number1.size() - 1; i >= 0; i--) {
        if (number1[i] != number2[i]) {
            return number1[i] > number2[i];
        }
    }
    return false;
}


int main() {
    BigInt num1, num2;
    while (1) {
        cout << "please enter two long number:" << endl;
        cin >> num1 >> num2;
        cout << "num1 = " << num1 << endl;
        cout << "num2 = " << num2 << endl;

        if (num1 == num2) {
            cout << "num1 == num2" << endl;
        } else if (num1 < num2) {
            cout << "num1 < num2" << endl;
        } else {
            cout << "num1 > num2" << endl;
        }
        cout << "num1 + num2 = " << num1 + num2 << endl;
        cout << "num1 - num2 = " << num1 - num2 << endl;
        cout << "num1 * num2 = " << num1 * num2 << endl;
        cout << "num1 / num2 = " << num1 / num2 << endl;
        cout << "num1 % num2 = " << num1 % num2 << endl;
    }
    
    return 0;
}

试验结果

please enter two long number:
666666   
233
num1 = 666666
num2 = 233
num1 > num2
num1 + num2 = 666899
num1 - num2 = 666433
num1 * num2 = 155333178      
num1 / num2 = 2861
num1 % num2 = 53
please enter two long number:
999999999
-111111111
num1 = 999999999 
num2 = -111111111
num1 > num2      
num1 + num2 = 888888888
num1 - num2 = 1111111110
num1 * num2 = -111111110888888889
num1 / num2 = -9
num1 % num2 = 0
please enter two long number:
0
-5
num1 = 0
num2 = -5
num1 > num2
num1 + num2 = -5
num1 - num2 = 5
num1 * num2 = 0
num1 / num2 = 0
num1 % num2 = 0
please enter two long number:
-4545454545454545
154423
num1 = -4545454545454545
num2 = 154423
num1 < num2
num1 + num2 = -4545454545300122
num1 - num2 = -4545454545608968
num1 * num2 = -701922727272727202535
num1 / num2 = -29435087684
num1 % num2 = -28213
  • 7
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值