View difference between Paste ID: MxQdP5s9 and XtAab7Vz
SHOW: | | - or go back to the newest paste.
1
#include <vector>
2
#include <string>
3
#include <ostream>
4
#include <iomanip>
5
#include <sstream>
6
7
class big_integer {
8
	// основание системы счисления (1 000 000 000)
9
	static const int BASE = 1000000000;
10
11
	// внутреннее хранилище числа
12
	std::vector<int> _digits;
13
14
	// знак числа
15
	bool _is_negative;
16
17
	void _remove_leading_zeros();
18
	void _shift_right();
19
20
public:
21
	// класс-исключение, бросаемое при делении на ноль
22
	class divide_by_zero: public std::exception {  };
23
24
	big_integer();
25
	big_integer(std::string);
26
	big_integer(signed char);
27
	big_integer(unsigned char);
28
	big_integer(signed short);
29
	big_integer(unsigned short);
30
	big_integer(signed int);
31
	big_integer(unsigned int);
32
	big_integer(signed long);
33
	big_integer(unsigned long);
34
	big_integer(signed long long);
35
	big_integer(unsigned long long);
36
37
	friend std::ostream& operator <<(std::ostream&, const big_integer&);
38
	operator std::string() const;
39
	const big_integer operator +() const;
40
	const big_integer operator -() const;
41
	const big_integer operator ++();
42
	const big_integer operator ++(int);
43
	const big_integer operator --();
44
	const big_integer operator --(int);
45
	friend bool operator ==(const big_integer&, const big_integer&);
46
	friend bool operator <(const big_integer&, const big_integer&);
47
	friend bool operator !=(const big_integer&, const big_integer&);
48
	friend bool operator <=(const big_integer&, const big_integer&);
49
	friend bool operator >(const big_integer&, const big_integer&);
50
	friend bool operator >=(const big_integer&, const big_integer&);
51
	friend const big_integer operator +(big_integer, const big_integer&);
52
	big_integer& operator +=(const big_integer&);
53
	friend const big_integer operator -(big_integer, const big_integer&);
54
	big_integer& operator -=(const big_integer&);
55
	friend const big_integer operator *(const big_integer&, const big_integer&);
56
	big_integer& operator *=(const big_integer&);
57
	friend const big_integer operator /(const big_integer&, const big_integer&);
58
	big_integer& operator /=(const big_integer&);
59
	friend const big_integer operator %(const big_integer&, const big_integer&);
60
	big_integer& operator %=(const big_integer&);
61
62
	bool odd() const;
63
	bool even() const;
64
	const big_integer pow(big_integer) const;
65
};
66
67
// создает длинное целое число со значением 0
68
big_integer::big_integer() {
69
	this->_is_negative = false;
70
}
71
72
// создает длинное целое число из C++-строки
73
big_integer::big_integer(std::string str) {
74
	if (str.length() == 0) {
75
		this->_is_negative = false;
76
	}
77
	else {
78
		if (str[0] == '-') {
79
			str = str.substr(1);
80
			this->_is_negative = true;
81
		}
82
		else {
83
			this->_is_negative = false;
84
		}
85
86
		for (long long i = str.length(); i > 0; i -= 9) {
87
			if (i < 9)
88
				this->_digits.push_back(atoi(str.substr(0, i).c_str()));
89
			else
90
				this->_digits.push_back(atoi(str.substr(i - 9, 9).c_str()));
91
		}
92
93
		this->_remove_leading_zeros();
94
	}
95
}
96
97
// удаляет ведущие нули
98
void big_integer::_remove_leading_zeros() {
99
	while (this->_digits.size() > 1 && this->_digits.back() == 0) {
100
		this->_digits.pop_back();
101
	}
102
103
	if (this->_digits.size() == 1 && this->_digits[0] == 0) this->_is_negative = false;
104
}
105
106
// печатает число в поток вывода
107
std::ostream& operator <<(std::ostream& os, const big_integer& bi) {
108
	if (bi._digits.empty()) os << 0;
109
	else {
110
		if (bi._is_negative) os << '-';
111
		os << bi._digits.back();
112
		char old_fill = os.fill('0');
113
		for (long long i = static_cast<long long>(bi._digits.size()) - 2; i >= 0; --i) os << std::setw(9) << bi._digits[i];
114
		os.fill(old_fill);
115
	}
116
117
	return os;
118
}
119
120
// сравнивает два числа на равенство
121
bool operator ==(const big_integer& left, const big_integer& right) {
122
	if (left._is_negative != right._is_negative) return false;
123
	if (left._digits.empty()) {
124
		if (right._digits.empty() || (right._digits.size() == 1 && right._digits[0] == 0)) return true;
125
		else return false;
126
	}
127
	
128
	if (right._digits.empty()) {
129
		if (left._digits.size() == 1 && left._digits[0] == 0) return true;
130
		else return false;
131
	}
132
133
	if (left._digits.size() != right._digits.size()) return false;
134
	for (size_t i = 0; i < left._digits.size(); ++i) if (left._digits[i] != right._digits[i]) return false;
135
136
	return true;
137
}
138
139
// возвращает копию переданного числа
140
const big_integer big_integer::operator +() const {
141
	return big_integer(*this);
142
}
143
144
// возвращает переданное число с другим знаком
145
const big_integer big_integer::operator -() const {
146
	big_integer copy(*this);
147
	copy._is_negative = !copy._is_negative;
148
	return copy;
149
}
150
151
// проверяет, является ли левый операнд меньше правого
152
bool operator <(const big_integer& left, const big_integer& right) {
153
	if (left == right) return false;
154
	if (left._is_negative) {
155
		if (right._is_negative) return ((-right) < (-left));
156
		else return true;
157
	}
158
	else if (right._is_negative) return false;
159
	else {
160
		if (left._digits.size() != right._digits.size()) {
161
			return left._digits.size() < right._digits.size();
162
		}
163
		else {
164
			for (long long i = left._digits.size() - 1; i >= 0; --i) {
165
				if (left._digits[i] != right._digits[i]) return left._digits[i] < right._digits[i];
166
			}
167
			
168
			return false;
169
		}
170
	}
171
}
172
173
// сравнивает два числа на неравенство
174
bool operator !=(const big_integer& left, const big_integer& right) {
175
	return !(left == right);
176
}
177
178
// проверяет, является ли левый операнд меньше либо равен правого
179
bool operator <=(const big_integer& left, const big_integer& right) {
180
	return (left < right || left == right);
181
}
182
183
// проверяет, является ли левый операнд больше правого
184
bool operator >(const big_integer& left, const big_integer& right) {
185
	return !(left <= right);
186
}
187
188
// проверяет, является ли левый операнд больше либо равен правого
189
bool operator >=(const big_integer& left, const big_integer& right) {
190
	return !(left < right);
191
}
192
193
// складывает два числа
194
const big_integer operator +(big_integer left, const big_integer& right) {
195
	if (left._is_negative) {
196
		if (right._is_negative) return -(-left + (-right));
197
		else return right - (-left);
198
	}
199
	else if (right._is_negative) return left - (-right);
200
	int carry = 0;
201
	for (size_t i = 0; i < std::max(left._digits.size(), right._digits.size()) || carry != 0; ++i) {
202
		if (i == left._digits.size()) left._digits.push_back(0);
203
		left._digits[i] += carry + (i < right._digits.size() ? right._digits[i] : 0);
204
		carry = left._digits[i] >= big_integer::BASE;
205
		if (carry != 0) left._digits[i] -= big_integer::BASE;
206
	}
207
208
	return left;
209
}
210
211
// прибавляет к текущему числу новое
212
big_integer& big_integer::operator +=(const big_integer& value) {
213
	return *this = (*this + value);
214
}
215
216
// префиксный инкремент
217
const big_integer big_integer::operator++() {
218
	return (*this += 1);
219
}
220
221
// преобразует число к строке
222
big_integer::operator std::string() const {
223
	std::stringstream ss;
224
	ss << *this;
225
	return ss.str();
226
}
227
228
// преобразует signed char к big_integer
229
big_integer::big_integer(signed char c) {
230
	if (c < 0) this->_is_negative = true;
231
	else this->_is_negative = false;
232
	this->_digits.push_back(std::abs(c));
233
}
234
235
// преобразует unsigned char к big_integer
236
big_integer::big_integer(unsigned char c) {
237
	this->_is_negative = false;
238
	this->_digits.push_back(c);
239
}
240
241
// преобразует signed short к big_integer
242
big_integer::big_integer(signed short s) {
243
	if (s < 0) this->_is_negative = true;
244
	else this->_is_negative = false;
245
	this->_digits.push_back(std::abs(s));
246
}
247
248
// преобразует unsigned short к big_integer
249
big_integer::big_integer(unsigned short s) {
250
	this->_is_negative = false;
251
	this->_digits.push_back(s);
252
}
253
254
// преобразует signed int к big_integer
255
big_integer::big_integer(signed int i) {
256
	if (i < 0) this->_is_negative = true;
257
	else this->_is_negative = false;
258
	this->_digits.push_back(std::abs(i) % big_integer::BASE);
259
	i /= big_integer::BASE;
260
	if (i != 0) this->_digits.push_back(std::abs(i));
261
}
262
263
// преобразует unsigned int к big_integer
264
big_integer::big_integer(unsigned int i) {
265
	this->_digits.push_back(i % big_integer::BASE);
266
	i /= big_integer::BASE;
267
	if (i != 0) this->_digits.push_back(i);
268
}
269
270
// преобразует signed long к big_integer
271
big_integer::big_integer(signed long l) {
272
	if (l < 0) this->_is_negative = true;
273
	else this->_is_negative = false;
274
	this->_digits.push_back(std::abs(l) % big_integer::BASE);
275
	l /= big_integer::BASE;
276
	if (l != 0) this->_digits.push_back(std::abs(l));
277
}
278
279
// преобразует unsigned long к big_integer
280
big_integer::big_integer(unsigned long l) {
281
	this->_digits.push_back(l % big_integer::BASE);
282
	l /= big_integer::BASE;
283
	if (l != 0) this->_digits.push_back(l);
284
}
285
286
// преобразует signed long long к big_integer
287
big_integer::big_integer(signed long long l) {
288
	if (l < 0) { this->_is_negative = true; l = -l; }
289
	else this->_is_negative = false;
290
	do {
291
		this->_digits.push_back(l % big_integer::BASE);
292
		l /= big_integer::BASE;
293
	} while (l != 0);
294
}
295
296
// преобразует unsigned long long к big_integer
297
big_integer::big_integer(unsigned long long l) {
298
	this->_is_negative = false;
299
	do {
300
		this->_digits.push_back(l % big_integer::BASE);
301
		l /= big_integer::BASE;
302
	} while (l != 0);
303
}
304
305
// постфиксный инкремент
306
const big_integer big_integer::operator ++(int) {
307-
	big_integer bi(*this);
307+
308
	return *this - 1;
309-
	return bi;
309+
310
311
// префиксный декремент
312
const big_integer big_integer::operator --() {
313
	return *this -= 1;
314
}
315
316
// постфиксный декремент
317
const big_integer big_integer::operator --(int) {
318
	*this -= 1;
319-
	big_integer bi(*this);
319+
	return *this + 1;
320
}
321-
	return bi;
321+
322
// вычитает два числа
323
const big_integer operator -(big_integer left, const big_integer& right) {
324
	if (right._is_negative) return left + (-right);
325
	else if (left._is_negative) return -(-left + right);
326
	else if (left < right) return -(right - left);
327
	int carry = 0;
328
	for (size_t i = 0; i < right._digits.size() || carry != 0; ++i) {
329
		left._digits[i] -= carry + (i < right._digits.size() ? right._digits[i] : 0);
330
		carry = left._digits[i] < 0;
331
		if (carry != 0) left._digits[i] += big_integer::BASE;
332
	}
333
334
	left._remove_leading_zeros();
335
	return left;
336
}
337
338
// вычитает из текущего числа новое
339
big_integer& big_integer::operator -=(const big_integer& value) {
340
	return *this = (*this - value);
341
}
342
343
// перемножает два числа
344
const big_integer operator *(const big_integer& left, const big_integer& right) {
345
	big_integer result;
346
	result._digits.resize(left._digits.size() + right._digits.size());
347
	for (size_t i = 0; i < left._digits.size(); ++i) {
348
		int carry = 0;
349
		for (size_t j = 0; j < right._digits.size() || carry != 0; ++j) {
350
			long long cur = result._digits[i + j] + 
351
				left._digits[i] * 1LL * (j < right._digits.size() ? right._digits[j] : 0) + carry;
352
			result._digits[i + j] = static_cast<int>(cur % big_integer::BASE);
353
			carry = static_cast<int>(cur / big_integer::BASE);
354
		}
355
	}
356
357
	result._is_negative = left._is_negative != right._is_negative;
358
	result._remove_leading_zeros();
359
	return result;
360
}
361
362
// домножает текущее число на указанное
363
big_integer& big_integer::operator *=(const big_integer& value) {
364
	return *this = (*this * value);
365
}
366
367
// сдвигает все разряды на 1 вправо (домножает на BASE)
368
void big_integer::_shift_right() {
369
	if (this->_digits.size() == 0) {
370
		this->_digits.push_back(0);
371
		return;
372
	}
373
	this->_digits.push_back(this->_digits[this->_digits.size() - 1]);
374
	for (size_t i = this->_digits.size() - 2; i > 0; --i) this->_digits[i] = this->_digits[i - 1];
375
	this->_digits[0] = 0;
376
}
377
378
// делит два числа
379
const big_integer operator /(const big_integer& left, const big_integer& right) {
380
	if (right == 0) throw big_integer::divide_by_zero();
381
	big_integer b = right;
382
	b._is_negative = false;
383
	big_integer result, current;
384
	result._digits.resize(left._digits.size());
385
	for (long long i = static_cast<long long>(left._digits.size()) - 1; i >= 0; --i) {
386
		current._shift_right();
387
		current._digits[0] = left._digits[i];
388
		current._remove_leading_zeros();
389
		int x = 0, l = 0, r = big_integer::BASE;
390
		while (l <= r) {
391
			int m = (l + r) / 2;
392
			big_integer t = b * m;
393
			if (t <= current) {
394
				x = m;
395
				l = m + 1;
396
			}
397
			else r = m - 1;
398
		}
399
400
		result._digits[i] = x;
401
		current = current - b * x;
402
	}
403
404
	result._is_negative = left._is_negative != right._is_negative;
405
	result._remove_leading_zeros();
406
	return result;
407
}
408
409
// делит текущее число на указанное
410
big_integer& big_integer::operator /=(const big_integer& value) {
411
	return *this = (*this / value);
412
}
413
414
// возвращает остаток от деления двух чисел
415
const big_integer operator %(const big_integer& left, const big_integer& right) {
416
	big_integer result = left - (left / right) * right;
417
	if (result._is_negative) result += right;
418
	return result;
419
}
420
421
// присваивает текущему числу остаток от деления на другое число
422
big_integer& big_integer::operator %=(const big_integer& value) {
423
	return *this = (*this % value);
424
}
425
426
// проверяет, является ли текущее число нечетным
427
bool big_integer::odd() const {
428
	if (this->_digits.size() == 0) return false;
429
	return this->_digits[0] & 1;
430
}
431
432
// проверяет, является ли текущее число четным
433
bool big_integer::even() const {
434
	return !this->odd();
435
}
436
437
// возводит текущее число в указанную степень
438
const big_integer big_integer::pow(big_integer n) const {
439
	big_integer a(*this), result(1);
440
	while (n != 0) {
441
		if (n.odd()) result *= a;
442
		a *= a;
443
		n /= 2;
444
	}
445
446
	return result;
447
}