大整数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顺序混乱,如无必要,可以不关。

posted @ 2022-03-26 15:13  Conqueror712  阅读(51)  评论(0)    收藏  举报