全整数域的高精度类

来源:互联网 发布:邓老师c语言视频教程 编辑:程序博客网 时间:2024/06/06 05:03

 

包含以下内容:输入,输出,加法,减法,乘法,整除(除数为高精度),幂运算,模运算,运算带等号,由int、string赋值,六种大小比较
时间复杂度:
加法——O(n)
减法——O(n)
乘法——O(n^2)
除法——O(n^3)
取模——O(n^3)

若有各种优化建议或者发现了bug,欢迎随时评论留言~

// BigNum.h#ifndef _BigNum_h#define _BigNum_h#include <iostream>#include <vector>#include <string>using namespace std;class BigNum{friend BigNum operator+(const BigNum a, const BigNum b);friend BigNum operator+=(BigNum &a, const BigNum b);friend BigNum operator-(BigNum a);friend BigNum operator-(BigNum a, BigNum b);friend BigNum operator-=(BigNum &a, const BigNum b);friend BigNum operator*(const BigNum a, const BigNum b);friend BigNum operator*=(BigNum &a, const BigNum b);friend BigNum operator/(const BigNum a, BigNum b);friend BigNum operator/=(BigNum &a, const BigNum b);friend BigNum operator%(const BigNum a, BigNum b);friend BigNum operator%=(BigNum &a, const BigNum b);friend BigNum operator^(const BigNum a, BigNum b);friend BigNum operator++(BigNum a);friend BigNum operator++(BigNum &a, int n);friend BigNum operator--(BigNum a);friend BigNum operator--(BigNum &a, int n);friend bool operator<(const BigNum a, const BigNum b);friend bool operator>(const BigNum a, const BigNum b);friend bool operator==(const BigNum a, const BigNum b);friend bool operator<=(const BigNum a, const BigNum b);friend bool operator>=(const BigNum a, const BigNum b);friend bool operator!=(const BigNum a, const BigNum b);friend ostream &operator<<(ostream &os, const BigNum &n);friend istream &operator>>(istream &is, BigNum &n);protected:bool symbol; // 表示正负号,false为正,true为负vector <int> num;public:// 运用赋值号初始化BigNum(const int n = 0) { *this = n; }BigNum(const string n) { *this = n; }BigNum &operator=(const int &n);BigNum &operator=(const string &n);BigNum &operator=(const BigNum &n);};BigNum &BigNum::operator=(const int &n){int temp;num.erase(num.begin(), num.end()); // 数据清空// 确定符号,并将数变为正if (n < 0){symbol = true;temp = -n;}else{symbol = false;temp = n;}// 开始填入数值while (temp >= 10){num.push_back(temp % 10);temp /= 10;}num.push_back(temp);// int没有前置0,所以不用去除return *this;}BigNum &BigNum::operator=(const string &n){num.erase(num.begin(), num.end()); // 数据清空// 填入除首位以外的数for (string::size_type i(n.size() - 1); i>0; i--)num.push_back(n[i] - '0');// 判断符号if (n[0] == '-') symbol = true;else{symbol = false;num.push_back(n[0] - '0');}// 去除前置0并确保至少留一位for (vector <int>::size_type i(num.size() - 1); num[i] == 0 && i>0; i--)num.pop_back();return *this;}BigNum &BigNum::operator=(const BigNum &n){num.erase(num.begin(), num.end()); // 数据清空symbol = n.symbol;for (vector <int>::size_type i(0); i<n.num.size(); i++)num.push_back(n.num[i]);return *this;}ostream &operator<<(ostream &os, const BigNum &n){if (n.symbol == true) os << '-';for (vector <int>::size_type i(n.num.size() - 1); i>0; i--)os << n.num[i];os << n.num[0]; // 为防止出错,最后一位单独输出return os;}istream &operator>>(istream &is, BigNum &n){string temp;is >> temp;n = temp;return is;}BigNum operator+(const BigNum a, const BigNum b){BigNum c;// 先确定符号,同号相加,异号相减if (a.symbol == b.symbol) c.symbol = a.symbol;else if (a.symbol)return b - (-a);elsereturn a - (-b);vector <int>::size_type lenA(a.num.size()), lenB(b.num.size()), lenC;lenC = (lenA > lenB ? lenA : lenB);for (vector <int>::size_type i(0); i<lenC; i++){int temp(c.num[c.num.size() - 1]); // 取出末尾的数if (i < lenA) temp += a.num[i];if (i < lenB) temp += b.num[i];c.num[c.num.size() - 1] = temp % 10;c.num.push_back(temp / 10); // 进位}if (c.num[lenC] == 0) c.num.pop_back(); // 若最后没有进位,则舍弃前置0return c;}BigNum operator+=(BigNum &a, const BigNum b){a = a + b;return a;}BigNum operator-(BigNum a){if (a != 0) a.symbol = !a.symbol; // 变为负数,注意0的符号return a;}BigNum operator-(BigNum a, BigNum b){BigNum c, big, small;// 先确定符号if (a < b) c.symbol = true;else c.symbol = false;if (a.symbol == b.symbol) // 同号绝对值相减{a.symbol = b.symbol = false;if (a < b){small = a; big = b;}else{small = b; big = a;}vector <int>::size_type lon(big.num.size()), sho(small.num.size()), len;for (vector <int>::size_type i(0); i<lon; i++){int temp(c.num[c.num.size() - 1] + 10);if (i < sho) temp += (big.num[i] - small.num[i]);else temp += big.num[i];c.num[c.num.size() - 1] = temp % 10;c.num.push_back(temp / 10 - 1);}// 去除前置0len = c.num.size();while (len--){if (c.num[len] == 0) c.num.pop_back();else break;}if (c.num.empty()) c.num.push_back(0); // 确保至少留一位}else // 异号绝对值相加{a.symbol = b.symbol = false;c.num = (a + b).num;}return c;}BigNum operator-=(BigNum &a, const BigNum b){a = a - b;return a;}BigNum operator*(const BigNum a, const BigNum b){BigNum c;vector <int>::size_type lenA(a.num.size()), lenB(b.num.size()), len(lenA + lenB - 1);c.num.insert(c.num.begin(), len, 0); // 初始化0for (vector <int>::size_type i(0); i<lenA; i++){for (vector <int>::size_type j(0); j<lenB; j++){c.num[i + j] += a.num[i] * b.num[j];c.num[i + j + 1] += c.num[i + j] / 10;c.num[i +j] %= 10;}}if (c.num[len] == 0) c.num.pop_back();if (c != 0) c.symbol = a.symbol ^ b.symbol; // 同假异真return c;}BigNum operator*=(BigNum &a, const BigNum b){a = a * b;return a;}BigNum operator/(const BigNum a, BigNum b){if (b == 0 || a == 0) return 0; // 除数为0的情况BigNum temp1, temp2;bool flag = a.symbol ^ b.symbol; // 暂存符号b.symbol = false;string s(a.num.size(), '0'); // 存放商vector <int>::size_type i(a.num.size());string::size_type j(0);while (i--){if (temp1 == 0) temp1.num.pop_back();temp1.num.insert(temp1.num.begin(), a.num[i]); // 往后取一位int k(10); // 试商while (k--){temp2 = temp1 - b * k;if (temp2 >= 0){s[j] += k;temp1 = temp2; // 保留余数break;}}j++;}BigNum c(s); // 构造函数自动去除前置0c.symbol = flag; // 归还符号return c;}BigNum operator/=(BigNum &a, const BigNum b){a = a / b;return a;}BigNum operator%(const BigNum a, BigNum b){if (b == 0 || a == 0) return 0;BigNum c, temp;b.symbol = false;vector <int>::size_type i(a.num.size());while (i--){if (c == 0) c.num.pop_back();c.num.insert(c.num.begin(), a.num[i]);int k(10);while (k--){temp = c - b * k;if (temp >= 0){c = temp; // c就是余数break;}}}c.symbol = a.symbol;return c;}BigNum operator%=(BigNum &a, const BigNum b){a = a % b;return a;}BigNum operator^(const BigNum a, BigNum b) // 快速幂运算{BigNum c = 1, base = a;while (b != 0){if (b.num[0] % 2) c *= base;base *= base; b /= 2;}return c;}BigNum operator++(BigNum a){a = a + 1;return a;}BigNum operator++(BigNum &a, int n){BigNum b = a;a = a + 1;return b;}BigNum operator--(BigNum a){a = a - 1;return a;}BigNum operator--(BigNum &a, int n){BigNum b = a;a = a - 1;return b;}bool operator<(const BigNum a, const BigNum b){vector <int>::size_type lenA(a.num.size()), lenB(b.num.size());if (a.symbol && !b.symbol) return true; // a负b正if (!a.symbol && b.symbol) return false; // a正b负if (lenA != lenB) // 长度不相等{if (!a.symbol) return lenA < lenB;else return lenA > lenB;}for (vector <int>::size_type i(lenA - 1); i>0; i--){if (a.num[i] != b.num[i]){if (!a.symbol) return a.num[i] < b.num[i];else return a.num[i] > b.num[i];}}if (!a.symbol) return a.num[0] < b.num[0];else return a.num[0] > b.num[0];}bool operator>(const BigNum a, const BigNum b){return b < a;}bool operator==(const BigNum a, const BigNum b){return !(a != b);}bool operator<=(const BigNum a, const BigNum b){return !(a > b);}bool operator>=(const BigNum a, const BigNum b){return !(a < b);}bool operator!=(const BigNum a, const BigNum b){return (a < b || a > b);}#endif

 

原创粉丝点击