@@ -157,7 +157,11 @@ namespace BigInt {
157157
158158 bigint operator +=(const bigint &rhs)
159159 {
160- *this = add (*this , rhs);
160+ if (*this == 0 && rhs == 0 ) return *this ;
161+ if (*this == 0 ) {*this = rhs; return *this ;}
162+ if (rhs != 0 ) {
163+ *this = add (*this , rhs);
164+ }
161165 return *this ;
162166 }
163167
@@ -246,6 +250,21 @@ namespace BigInt {
246250 return tmp;
247251 }
248252
253+ bigint operator -() const &
254+ {
255+ bigint temp = *this ;
256+ if (temp == 0 ) return temp;
257+ temp.is_neg = !this ->is_neg ;
258+ return temp;
259+ }
260+
261+ bigint operator -() &&
262+ {
263+ if (*this == 0 ) return *this ;
264+ this ->is_neg = !this ->is_neg ;
265+ return *this ;
266+ }
267+
249268 friend bool operator ==(const bigint &l, const bigint &r)
250269 {
251270 if (l.is_neg != r.is_neg )
@@ -300,14 +319,17 @@ namespace BigInt {
300319
301320 static bigint abs (const bigint &s)
302321 {
303- if (is_negative (s))
304- {
305- bigint temp = s;
306- temp.is_neg = false ;
322+ if (!is_negative (s)) return s;
307323
308- return temp;
309- }
324+ bigint temp = s;
325+ temp.is_neg = false ;
326+
327+ return temp;
328+ }
310329
330+ static bigint abs (bigint&& s)
331+ {
332+ s.is_neg = false ;
311333 return s;
312334 }
313335
@@ -355,20 +377,32 @@ namespace BigInt {
355377 return sum;
356378 }
357379
380+ /* *
381+ * @brief Generates a random positive bigint of a specified length.
382+ *
383+ * This method ensures the resulting bigint is valid by using a random device
384+ * and engine for non-deterministic seeding.
385+ *
386+ * @param length The number of digits the generated bigint should have.
387+ * @return A bigint object representing the randomly generated number.
388+ */
358389 static bigint random (size_t length);
359390
360391 private:
361392 std::vector<long long > vec{};
362- bool is_neg{};
393+ bool is_neg{false };
363394
364395 // Function Definitions for Internal Uses
365396
366- static bigint trim (const bigint& input) {
367- auto temp = input;
368- while (temp.vec .front () == 0 ){
369- temp.vec .erase (temp.vec .begin ());
397+ static bigint trim (bigint input) {
398+ while (input.vec .size () > 1 && input.vec .front () == 0 ) {
399+ input.vec .erase (input.vec .begin ());
370400 }
371- return temp;
401+ if (input.vec .empty ()) {
402+ input.vec .push_back (0 );
403+ input.is_neg = false ;
404+ }
405+ return input;
372406 }
373407
374408 static std::vector<long long > string_to_vector (std::string input);
@@ -418,10 +452,16 @@ namespace BigInt {
418452 static bigint negate (const bigint& input)
419453 {
420454 bigint temp = input;
421- temp.is_neg = true ;
455+ temp.is_neg = !temp. is_neg ;
422456 return temp;
423457 }
424458
459+ static bigint negate (bigint&& input)
460+ {
461+ input.is_neg = !input.is_neg ;
462+ return input;
463+ }
464+
425465 static bool less_than (const bigint& lhs, const bigint& rhs)
426466 {
427467 if (is_negative (lhs) && is_negative (rhs))
@@ -455,61 +495,50 @@ namespace BigInt {
455495 return s.find_first_not_of (" 0123456789" , 0 ) == std::string::npos;
456496 }
457497
458- inline std::pair< int , long long > add_with_carry (const long long lhs, const long long rhs)
498+ inline bigint bigint::add (const bigint & lhs, const bigint & rhs)
459499 {
460- auto sum = lhs + rhs;
500+ bool negate_answer = false ;
501+ // Ensure both are positive
502+ if (is_negative (lhs) && is_negative (rhs)) negate_answer = true ;
503+ else if (is_negative (lhs)) return subtract (rhs, abs (lhs));
504+ else if (is_negative (rhs)) return subtract (lhs, abs (rhs));
461505
462- if (sum >= bigint::MAX_SIZE)
463- {
464- // Carry needs to happen
465- auto carry = sum / bigint::MAX_SIZE;
466- auto result = sum % bigint::MAX_SIZE;
467- return {carry, result};
468- }
506+ // Ensure LHS is larger than RHS
507+ if (lhs.vec .size () < rhs.vec .size ()) return add (rhs, lhs);
469508
470- return {0 , sum};
471- }
509+ // Prepare result vector with enough space (max size + 1 for potential carry)
510+ std::vector<long long > result;
511+ result.reserve (lhs.vec .size () + 1 );
472512
473- inline bigint bigint::add (const bigint &lhs, const bigint &rhs)
474- {
475- // Ensure LHS is larger than RHS, and both are positive
476- if (lhs == 0 ) return rhs;
477- if (rhs == 0 ) return lhs;
478- if (is_negative (lhs) && is_negative (rhs))
479- {
480- return negate (add (abs (lhs) ,abs (rhs)));
481- }
482- if (is_negative (lhs))
483- {
484- return rhs - abs (lhs);
485- }
486- if (is_negative (rhs))
487- {
488- return lhs - abs (rhs);
489- }
490- if (lhs < rhs)
491- {
492- return add (rhs, lhs);
493- }
513+ long long carry = 0 ;
514+ auto it_l = lhs.vec .rbegin ();
515+ auto it_r = rhs.vec .rbegin ();
494516
495- bigint full_rhs = rhs;
496- std::vector<std::pair<int , long long >> carry_result (lhs.vec .size () + 1 );
517+ while (it_l != lhs.vec .rend ()) {
518+ long long sum = *it_l + carry;
519+ if (it_r != rhs.vec .rend ()) {
520+ sum += *it_r;
521+ ++it_r;
522+ }
497523
498- // Fill the smaller to match the larger size
499- while (lhs.vec .size () > full_rhs.vec .size ())
500- {
501- full_rhs.vec .insert (full_rhs.vec .begin (), 0 );
502- }
524+ if (sum >= MAX_SIZE) {
525+ sum -= MAX_SIZE;
526+ carry = 1 ;
527+ } else {
528+ carry = 0 ;
529+ }
503530
504- std::transform (lhs.vec .rbegin (), lhs.vec .rend (), full_rhs.vec .rbegin (), carry_result.rbegin (), add_with_carry);
531+ result.push_back (sum);
532+ ++it_l;
533+ }
505534
506- std::vector<long long > final (lhs.vec .size () + 1 );
507- for (int i = carry_result.size () - 1 ; i > 0 ; --i) {
508- final [i] += carry_result[i].second ;
509- final [i - 1 ] += carry_result[i].first ;
535+ if (carry > 0 ) {
536+ result.push_back (carry);
510537 }
511538
512- return trim (bigint (final ));
539+ std::reverse (result.begin (), result.end ());
540+ bigint result_bigint {std::move (result)};
541+ return negate_answer ? negate (result_bigint) : result_bigint;
513542 }
514543
515544 inline std::pair<int , long long > subtract_with_borrow (const long long lhs, const long long rhs)
@@ -843,8 +872,8 @@ namespace BigInt {
843872 return true ;
844873 }
845874
846- inline bigint bigint::random (size_t length) {
847- const char charset[] = " 0123456789" ;
875+ inline bigint bigint::random (const size_t length) {
876+ constexpr char charset[] = " 0123456789" ;
848877 std::default_random_engine rng (std::random_device{}());
849878
850879 // Distribution for the first digit (1-9)
0 commit comments