5
5
#ifndef BIGINT_HH
6
6
#define BIGINT_HH
7
7
8
+ #include < utility>
9
+
8
10
// This one is pretty simple but has a fair divide implementation.
9
11
// Though I'm not ambitious enough to do that FFT-like stuff.
10
12
//
@@ -166,12 +168,11 @@ public:
166
168
BigInt (llong_t ) _fast;
167
169
BigInt (ullong_t ) _fast;
168
170
BigInt (BigInt const &) _fast;
171
+ BigInt (BigInt &&) _fast;
169
172
BigInt (char const *, onedig_t = 10 ) _fast;
170
173
171
- BigInt &operator = (llong_t ) _fast;
172
- BigInt &operator = (ullong_t ) _fast;
173
174
BigInt &operator = (BigInt const &) _fast;
174
- BigInt &operator = (char const * ) _fast;
175
+ BigInt &operator = (BigInt && ) _fast;
175
176
176
177
// Input conversion from text.
177
178
@@ -220,8 +221,9 @@ public:
220
221
221
222
// Eliminate need for explicit casts when comparing.
222
223
223
- int compare (int n) const { return compare (llong_t (n)); }
224
- int compare (unsigned n) const { return compare (ullong_t (n)); }
224
+ int compare (unsigned long n) const { return compare (static_cast <ullong_t >(n)); }
225
+ int compare (int n) const { return compare (static_cast <llong_t > (n)); }
226
+ int compare (unsigned n) const { return compare (static_cast <ullong_t >(n)); }
225
227
226
228
// Tests. These are faster than comparing with 0 or of course %2.
227
229
@@ -236,109 +238,51 @@ public:
236
238
BigInt &negate () { if (!is_zero ()) positive = !positive; return *this ; }
237
239
BigInt operator -() const { return BigInt (*this ).negate (); }
238
240
239
- BigInt &operator += (llong_t ) _fast;
240
- BigInt &operator -= (llong_t ) _fast;
241
- BigInt &operator *= (llong_t ) _fast;
242
- BigInt &operator /= (llong_t ) _fast;
243
- BigInt &operator %= (llong_t ) _fast;
244
-
245
- BigInt &operator = (unsigned long x) { return (*this )=(ullong_t )x; }
246
- BigInt &operator += (unsigned long x) { return (*this )+=(ullong_t )x; }
247
- BigInt &operator -= (unsigned long x) { return (*this )-=(ullong_t )x; }
248
- BigInt &operator *= (unsigned long x) { return (*this )*=(ullong_t )x; }
249
- BigInt &operator /= (unsigned long x) { return (*this )/=(ullong_t )x; }
250
- BigInt &operator %= (unsigned long x) { return (*this )%=(ullong_t )x; }
251
-
252
- BigInt &operator += (ullong_t ) _fast;
253
- BigInt &operator -= (ullong_t ) _fast;
254
- BigInt &operator *= (ullong_t ) _fast;
255
- BigInt &operator /= (ullong_t ) _fast;
256
- BigInt &operator %= (ullong_t ) _fast;
257
-
258
- BigInt &operator += (BigInt const &) _fast;
259
- BigInt &operator -= (BigInt const &) _fast;
260
- BigInt &operator *= (BigInt const &) _fast;
261
- BigInt &operator /= (BigInt const &) _fasta;
262
- BigInt &operator %= (BigInt const &) _fasta;
241
+ #define IN_PLACE_OPERATOR (TYPE ) \
242
+ BigInt &operator += (TYPE) _fast; \
243
+ BigInt &operator -= (TYPE) _fast; \
244
+ BigInt &operator *= (TYPE) _fast; \
245
+ BigInt &operator /= (TYPE) _fast; \
246
+ BigInt &operator %= (TYPE) _fast;
247
+
248
+ IN_PLACE_OPERATOR (const BigInt &)
249
+ IN_PLACE_OPERATOR (llong_t )
250
+ IN_PLACE_OPERATOR (ullong_t )
251
+ #undef IN_PLACE_OPERATOR
252
+
253
+ #define OVERLOAD_IN_PLACE_OPERATOR (FROM, TO ) \
254
+ BigInt &operator +=(FROM x) { return operator +=(static_cast <TO>(x)); } \
255
+ BigInt &operator -=(FROM x) { return operator -=(static_cast <TO>(x)); } \
256
+ BigInt &operator *=(FROM x) { return operator *=(static_cast <TO>(x)); } \
257
+ BigInt &operator /=(FROM x) { return operator /=(static_cast <TO>(x)); } \
258
+ BigInt &operator %=(FROM x) { return operator %=(static_cast <TO>(x)); }
259
+
260
+ OVERLOAD_IN_PLACE_OPERATOR (unsigned long , ullong_t )
261
+ OVERLOAD_IN_PLACE_OPERATOR (int , llong_t )
262
+ OVERLOAD_IN_PLACE_OPERATOR (unsigned , ullong_t )
263
+ #undef OVERLOAD_IN_PLACE_OPERATOR
263
264
264
265
BigInt &operator ++ () { return operator +=(1 ); } // preincrement
265
266
BigInt &operator -- () { return operator -=(1 ); } // predecrement
266
267
267
268
static void div (BigInt const &, BigInt const &,
268
269
BigInt ", BigInt &rem) _fasta;
269
270
270
- // Avoid the need for explicit casts to [u]llong_t.
271
-
272
- // disabled by DK
273
- // operator int() const { return int (operator llong_t()); }
274
- // operator unsigned() const { return unsigned (operator ullong_t()); }
275
-
276
- BigInt &operator = (int n) { return operator = (llong_t (n)); }
277
- BigInt &operator += (int n) { return operator += (llong_t (n)); }
278
- BigInt &operator -= (int n) { return operator -= (llong_t (n)); }
279
- BigInt &operator *= (int n) { return operator *= (llong_t (n)); }
280
- BigInt &operator /= (int n) { return operator /= (llong_t (n)); }
281
- BigInt &operator %= (int n) { return operator %= (llong_t (n)); }
282
-
283
- BigInt &operator = (unsigned n) { return operator = (ullong_t (n)); }
284
- BigInt &operator += (unsigned n) { return operator += (ullong_t (n)); }
285
- BigInt &operator -= (unsigned n) { return operator -= (ullong_t (n)); }
286
- BigInt &operator *= (unsigned n) { return operator *= (ullong_t (n)); }
287
- BigInt &operator /= (unsigned n) { return operator /= (ullong_t (n)); }
288
- BigInt &operator %= (unsigned n) { return operator %= (ullong_t (n)); }
289
-
290
- // Binary arithmetic operators. These are entirely syntactic sugar.
291
- // Though there's joy in repetition -- let the preprocessor enjoy.
292
-
293
- #define decl_binary (T ) \
294
- BigInt operator + (T b) const { return BigInt (*this ) += b; } \
295
- BigInt operator - (T b) const { return BigInt (*this ) -= b; } \
296
- BigInt operator * (T b) const { return BigInt (*this ) *= b; } \
297
- BigInt operator / (T b) const { return BigInt (*this ) /= b; } \
298
- BigInt operator % (T b) const { return BigInt (*this ) %= b; }
299
- decl_binary (int );
300
- decl_binary (unsigned );
301
- decl_binary (llong_t );
302
- decl_binary (ullong_t );
303
- decl_binary (BigInt const &);
304
- #undef decl_binary
305
-
306
- BigInt operator + (unsigned long b) const { return BigInt (*this ) += (ullong_t )b; } \
307
- BigInt operator - (unsigned long b) const { return BigInt (*this ) -= (ullong_t )b; } \
308
- BigInt operator * (unsigned long b) const { return BigInt (*this ) *= (ullong_t )b; } \
309
- BigInt operator / (unsigned long b) const { return BigInt (*this ) /= (ullong_t )b; } \
310
- BigInt operator % (unsigned long b) const { return BigInt (*this ) %= (ullong_t )b; }
311
-
312
- // Binary comparision operators.
313
-
314
- #define decl_binary (T ) \
315
- bool operator < (T b) const { return compare (b) < 0 ; } \
316
- bool operator > (T b) const { return compare (b) > 0 ; } \
317
- bool operator <= (T b) const { return compare (b) <= 0 ; } \
318
- bool operator >= (T b) const { return compare (b) >= 0 ; } \
319
- bool operator == (T b) const { return compare (b) == 0 ; } \
320
- bool operator != (T b) const { return compare (b) != 0 ; }
321
- decl_binary (int );
322
- decl_binary (unsigned );
323
- decl_binary (llong_t );
324
- decl_binary (ullong_t );
325
- decl_binary (BigInt const &);
326
- #undef decl_binary
327
-
328
- bool operator < (unsigned long b) const { return compare ((ullong_t )b) < 0 ; } \
329
- bool operator > (unsigned long b) const { return compare ((ullong_t )b) > 0 ; } \
330
- bool operator <= (unsigned long b) const { return compare ((ullong_t )b) <= 0 ; } \
331
- bool operator >= (unsigned long b) const { return compare ((ullong_t )b) >= 0 ; } \
332
- bool operator == (unsigned long b) const { return compare ((ullong_t )b) == 0 ; } \
333
- bool operator != (unsigned long b) const { return compare ((ullong_t )b) != 0 ; }
334
-
335
271
// Returns the largest x such that 2^x <= abs() or 0 if input is 0
336
272
// Not part of original BigInt.
337
273
unsigned floorPow2 () const _fast;
338
274
339
275
// Sets the number to the power of two given by the exponent
340
276
// Not part of original BigInt.
341
277
void setPower2 (unsigned exponent) _fast;
278
+
279
+ void swap (BigInt &other)
280
+ {
281
+ std::swap (other.size , size);
282
+ std::swap (other.length , length);
283
+ std::swap (other.digit , digit);
284
+ std::swap (other.positive , positive);
285
+ }
342
286
};
343
287
344
288
@@ -350,5 +294,65 @@ BigInt sqrt (BigInt const &) _fast;
350
294
BigInt gcd (const BigInt &, const BigInt &) _fast;
351
295
BigInt modinv (const BigInt &, const BigInt &) _fast;
352
296
297
+ // Binary arithmetic operators
298
+
299
+ inline BigInt operator + (const BigInt &lhs, const BigInt &rhs) { return BigInt (lhs) += rhs; }
300
+ inline BigInt operator - (const BigInt &lhs, const BigInt &rhs) { return BigInt (lhs) -= rhs; }
301
+ inline BigInt operator * (const BigInt &lhs, const BigInt &rhs) { return BigInt (lhs) *= rhs; }
302
+ inline BigInt operator / (const BigInt &lhs, const BigInt &rhs) { return BigInt (lhs) /= rhs; }
303
+ inline BigInt operator % (const BigInt &lhs, const BigInt &rhs) { return BigInt (lhs) %= rhs; }
304
+
305
+ // Because the operators `+` and `*` are associative, we can do fast math, no
306
+ // matter which side the BigInt is on. For the rest of the operators, which
307
+ // are non-associative, we can only get speedups if the primitive type is on
308
+ // the RHS.
309
+ #define BINARY_ARITHMETIC_OPERATORS (OTHER ) \
310
+ inline BigInt operator + (const BigInt &lhs, OTHER rhs) { return BigInt (lhs) += rhs; } \
311
+ inline BigInt operator + (OTHER lhs, const BigInt &rhs) { return BigInt (rhs) += lhs; } \
312
+ inline BigInt operator * (const BigInt &lhs, OTHER rhs) { return BigInt (lhs) *= rhs; } \
313
+ inline BigInt operator * (OTHER lhs, const BigInt &rhs) { return BigInt (rhs) *= lhs; } \
314
+ inline BigInt operator - (const BigInt &lhs, OTHER rhs) { return BigInt (lhs) -= rhs; } \
315
+ inline BigInt operator / (const BigInt &lhs, OTHER rhs) { return BigInt (lhs) /= rhs; } \
316
+ inline BigInt operator % (const BigInt &lhs, OTHER rhs) { return BigInt (lhs) %= rhs; }
317
+
318
+ BINARY_ARITHMETIC_OPERATORS (BigInt::llong_t )
319
+ BINARY_ARITHMETIC_OPERATORS(BigInt::ullong_t )
320
+ BINARY_ARITHMETIC_OPERATORS(unsigned long )
321
+ BINARY_ARITHMETIC_OPERATORS(int )
322
+ BINARY_ARITHMETIC_OPERATORS(unsigned )
323
+ #undef BINARY_ARITHMETIC_OPERATORS
324
+
325
+ // Binary comparison operators
326
+
327
+ inline bool operator < (const BigInt &lhs, const BigInt &rhs) { return lhs.compare (rhs) < 0 ; }
328
+ inline bool operator > (const BigInt &lhs, const BigInt &rhs) { return lhs.compare (rhs) > 0 ; }
329
+ inline bool operator <= (const BigInt &lhs, const BigInt &rhs) { return lhs.compare (rhs) <= 0 ; }
330
+ inline bool operator >= (const BigInt &lhs, const BigInt &rhs) { return lhs.compare (rhs) >= 0 ; }
331
+ inline bool operator == (const BigInt &lhs, const BigInt &rhs) { return lhs.compare (rhs) == 0 ; }
332
+ inline bool operator != (const BigInt &lhs, const BigInt &rhs) { return lhs.compare (rhs) != 0 ; }
333
+
334
+
335
+ // These operators are all associative, so we can define them all for
336
+ // primitives on the LHS and RHS.
337
+ #define COMPARISON_OPERATORS (OTHER ) \
338
+ inline bool operator < (const BigInt &lhs, OTHER rhs) { return lhs.compare (rhs) < 0 ; } \
339
+ inline bool operator > (const BigInt &lhs, OTHER rhs) { return lhs.compare (rhs) > 0 ; } \
340
+ inline bool operator <= (const BigInt &lhs, OTHER rhs) { return lhs.compare (rhs) <= 0 ; } \
341
+ inline bool operator >= (const BigInt &lhs, OTHER rhs) { return lhs.compare (rhs) >= 0 ; } \
342
+ inline bool operator == (const BigInt &lhs, OTHER rhs) { return lhs.compare (rhs) == 0 ; } \
343
+ inline bool operator != (const BigInt &lhs, OTHER rhs) { return lhs.compare (rhs) != 0 ; } \
344
+ inline bool operator < (OTHER lhs, const BigInt &rhs) { return -rhs.compare (lhs) < 0 ; } \
345
+ inline bool operator > (OTHER lhs, const BigInt &rhs) { return -rhs.compare (lhs) > 0 ; } \
346
+ inline bool operator <= (OTHER lhs, const BigInt &rhs) { return -rhs.compare (lhs) <= 0 ; } \
347
+ inline bool operator >= (OTHER lhs, const BigInt &rhs) { return -rhs.compare (lhs) >= 0 ; } \
348
+ inline bool operator == (OTHER lhs, const BigInt &rhs) { return -rhs.compare (lhs) == 0 ; } \
349
+ inline bool operator != (OTHER lhs, const BigInt &rhs) { return -rhs.compare (lhs) != 0 ; }
350
+
351
+ COMPARISON_OPERATORS (BigInt::llong_t )
352
+ COMPARISON_OPERATORS(BigInt::ullong_t )
353
+ COMPARISON_OPERATORS(unsigned long )
354
+ COMPARISON_OPERATORS(int )
355
+ COMPARISON_OPERATORS(unsigned )
356
+ #undef COMPARISON_OPERATORS
353
357
354
358
#endif // ndef BIGINT_HH
0 commit comments