大整数BigInteger
这里用结构体实现大整数类。
主要功能有:输入 输出 四则运算 幂运算 比较运算。
代码如下:
1 #include<bits/stdc++.h> 2 #define ios ios::sync_with_stdio(false);cin.tie(0),cout.tie(0) 3 typedef long long ll; 4 //const ll mod = 1e9+7; 5 //const ll mod = 1000003; 6 #define endl "\n" 7 using namespace std; 8 9 struct BigInteger{ 10 #define SIZE(x) ((int)x.size()) 11 std::vector<int> x; // 低→高 12 bool sign; //零正一负 13 //initialization 14 BigInteger(std::vector<int> y) { this->x = y; } 15 BigInteger(const BigInteger& y) { *this = y; } 16 BigInteger(const BigInteger* y) { *this = *y; } 17 BigInteger(const std::string& y) { *this = y; } 18 BigInteger(long long y = 0) { *this = y; } 19 20 void squeeze(){ 21 while (SIZE(x) && x[SIZE(x) - 1] == 0) { 22 x.pop_back(); 23 } 24 if (SIZE(x) == 0) sign = 0; 25 } 26 27 BigInteger abs() const{ 28 BigInteger ret(this); 29 ret.sign = 0; 30 return ret; 31 } 32 33 BigInteger& operator = (const BigInteger& y){ 34 this->x = y.x; 35 this->sign = y.sign; 36 squeeze(); 37 return *this; 38 } 39 BigInteger& operator = (const std::string& y){ 40 x.clear(); 41 sign = (y[0] == '-'); 42 for (int i = SIZE(y) - 1; i >= sign; i--) { 43 x.push_back(y[i] - '0'); 44 } 45 squeeze(); 46 return *this; 47 } 48 BigInteger& operator = (long long y) 49 { 50 x.clear(); 51 sign = y < 0; 52 y = std::abs(y); 53 while (y){ 54 x.push_back(y % 10); 55 y /= 10; 56 } 57 squeeze(); 58 return *this; 59 } 60 61 BigInteger operator - () const{ 62 BigInteger ret(this); 63 ret.sign = sign ^ 1; 64 return ret; 65 } 66 67 BigInteger operator + (const BigInteger& y) const{ 68 if (y.sign == 1) { return *this - (-y); } 69 if (sign == 1) { return y - (-*this); } 70 BigInteger ret; 71 int i = 0, j = 0; 72 while (i < SIZE(x) && j < SIZE(y.x)) ret.x.push_back(x[i++] + y.x[j++]); 73 while (i < SIZE(x)) ret.x.push_back(x[i++]); 74 while (j < SIZE(y.x)) ret.x.push_back(y.x[j++]); 75 ret.x.push_back(0); 76 for (i = 0; i + 1 < SIZE(ret.x); i++) { 77 ret.x[i + 1] += ret.x[i] / 10, ret.x[i] %= 10; 78 } 79 ret.squeeze(); 80 return ret; 81 } 82 BigInteger operator - (const BigInteger& y) const{ 83 if (y.sign == 1) { return *this + (-y); } 84 if (sign == 1) { return -((-*this) + y); } 85 if (*this < y) { return -(y - *this); } 86 BigInteger ret; 87 int i = 0, j = 0; 88 while (j < SIZE(y.x)) { 89 ret.x.push_back(x[i++] - y.x[j++]); 90 } 91 while (i < SIZE(x)) { 92 ret.x.push_back(x[i++]); 93 } 94 for (int i = 0; i + 1 < SIZE(ret.x); i++) { 95 if (ret.x[i] < 0) { 96 ret.x[i] += 10, ret.x[i + 1]--; 97 } 98 } 99 ret.squeeze(); 100 return ret; 101 } 102 BigInteger operator * (const BigInteger& y) const { 103 BigInteger ret; 104 ret.sign = sign ^ y.sign; 105 for (int i = 0; i < (SIZE(x) + SIZE(y.x)) * 2; i++) { 106 ret.x.push_back(0); 107 } 108 for (int i = 0; i < SIZE(x); i++) { 109 for (int j = 0; j < SIZE(y.x); j++) { 110 ret.x[i + j] += x[i] * y.x[j]; 111 } 112 } 113 for (int i = 0; i < SIZE(ret.x) && (ret.x[i] > 9 || ret.x[i + 1] > 0); i++) { 114 ret.x[i + 1] += ret.x[i] / 10, ret.x[i] %= 10; 115 } 116 ret.squeeze(); 117 return ret; 118 } 119 BigInteger operator / (const BigInteger& y) const{ 120 std::stack<int> st; 121 BigInteger tmp(0ll), ten(10ll); 122 assert(y != tmp); 123 BigInteger t1 = this->abs(), t2 = y.abs(); 124 for (int i = SIZE(t1.x) - 1; i >= 0; i--){ 125 tmp = tmp * ten + t1.x[i]; 126 int s = 0; 127 while (tmp >= t2) 128 { 129 tmp = tmp - t2; 130 s++; 131 } 132 st.push(s); 133 } 134 tmp.x.clear(); 135 while (!st.empty()) { 136 tmp.x.push_back(st.top()), st.pop(); 137 } 138 delete& st; delete& t1; delete& t2; 139 tmp.sign = sign ^ y.sign; 140 tmp.squeeze(); 141 return tmp; 142 } 143 BigInteger operator % (const BigInteger& y) const{ 144 return *this - *this / y * y; 145 } 146 147 BigInteger operator += (const BigInteger& y) { *this = *this + y; return *this; } 148 BigInteger operator -= (const BigInteger& y) { *this = *this - y; return *this; } 149 BigInteger operator *= (const BigInteger& y) { *this = *this * y; return *this; } 150 BigInteger operator /= (const BigInteger& y) { *this = *this / y; return *this; } 151 BigInteger operator %= (const BigInteger& y) { *this = *this % y; return *this; } 152 BigInteger operator ++ () { *this = *this + 1; return *this; } 153 BigInteger operator -- () { *this = *this - 1; return *this; } 154 155 BigInteger operator ^ (const BigInteger& y) const{ 156 BigInteger ret(1ll), k(y), a(this), zero(0ll); 157 while (k > zero){ 158 if (k % 2 == 1) ret *= a; 159 a *= a; 160 k /= 2; 161 } 162 return ret; 163 } 164 bool operator < (const BigInteger& y) const{ 165 if (sign == 0 && y.sign == 1) return 0; 166 if (sign == 1 && y.sign == 0) return 1; 167 if (sign == 1 && y.sign == 1) { return (-y) < (-*this); } 168 if (SIZE(x) < SIZE(y.x)) return 1; 169 else if (SIZE(x) > SIZE(y.x)) return 0; 170 for (int i = SIZE(x) - 1; i >= 0; i--){ 171 if (x[i] < y.x[i]) return 1; 172 else if (x[i] > y.x[i]) return 0; 173 } 174 return 0; 175 } 176 bool operator > (const BigInteger& y) const { return y < *this; } 177 bool operator <= (const BigInteger& y) const { return !(y < *this); } 178 bool operator >= (const BigInteger& y) const { return !(*this < y); } 179 bool operator == (const BigInteger& y) const { return *this <= y && *this >= y; } 180 bool operator != (const BigInteger& y) const { return !(*this == y); } 181 182 friend std::ostream& operator << (std::ostream& out, const BigInteger& y){ 183 if (y.sign) out << '-'; 184 for (int i = SIZE(y.x) - 1; i >= 0; i--) { 185 out << y.x[i]; 186 } 187 if (SIZE(y.x) == 0) out << '0'; 188 return out; 189 } 190 friend std::istream& operator >> (std::istream& in, BigInteger& y){ 191 std::string s; 192 in >> s; 193 y = s; 194 return in; 195 } 196 }; 197 198 int main() { 199 ios; 200 cout << "This is a test." << endl; 201 BigInteger a,b,c; 202 cout << "请输入a = "; 203 cin >> a; //输入测试 204 cout << "请输入b = "; 205 cin >> b; 206 c = a - b; //赋值测试 207 cout << "a + b = " << a + b << endl; //输出测试 && 加法测试 208 cout << "a - b = " << c << endl; //减法测试 209 cout << "a * b = " << a * b << endl; //乘法测试 210 //除此之外 还有除法运算 比较运算 幂运算 不过在这里没有给出测试 211 return 0; 212 }
值得一提的是,这里是否要关闭流同步,个人认为不同编译器效果不同,有可能会造成cout cin顺序混乱,如无必要,可以不关。