|
@@ -53,11 +53,11 @@ biginteger & operator+=(biginteger & rhs, biginteger const & lhs) {
|
|
|
return rhs;
|
|
return rhs;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-//biginteger & operator-=(biginteger & rhs, biginteger const & lhs) {
|
|
|
|
|
-// swap(rhs, rhs - lhs);
|
|
|
|
|
-// return rhs;
|
|
|
|
|
-//}
|
|
|
|
|
-//
|
|
|
|
|
|
|
+biginteger & operator-=(biginteger & rhs, biginteger const & lhs) {
|
|
|
|
|
+ swap(rhs, rhs - lhs);
|
|
|
|
|
+ return rhs;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
//biginteger & operator*=(biginteger & rhs, biginteger const & lhs) {
|
|
//biginteger & operator*=(biginteger & rhs, biginteger const & lhs) {
|
|
|
// swap(rhs, rhs * lhs);
|
|
// swap(rhs, rhs * lhs);
|
|
|
// return rhs;
|
|
// return rhs;
|
|
@@ -75,6 +75,8 @@ biginteger biginteger::operator-() const {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
biginteger math::operator+(biginteger const & rhs, biginteger const & lhs) {
|
|
biginteger math::operator+(biginteger const & rhs, biginteger const & lhs) {
|
|
|
|
|
+ if (lhs == biginteger::ZERO) { return rhs; }
|
|
|
|
|
+ else if (rhs == biginteger::ZERO) { return lhs; }
|
|
|
if (rhs.is_negative == lhs.is_negative) {
|
|
if (rhs.is_negative == lhs.is_negative) {
|
|
|
return {rhs.is_negative, detail::add(rhs.data, lhs.data)};
|
|
return {rhs.is_negative, detail::add(rhs.data, lhs.data)};
|
|
|
} else {
|
|
} else {
|
|
@@ -89,6 +91,23 @@ biginteger math::operator+(biginteger const & rhs, biginteger const & lhs) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+biginteger math::operator-(biginteger const & rhs, biginteger const & lhs) {
|
|
|
|
|
+ if (lhs == biginteger::ZERO) { return rhs; }
|
|
|
|
|
+ else if (rhs == biginteger::ZERO) { return -lhs; }
|
|
|
|
|
+ if (rhs.is_negative != lhs.is_negative) {
|
|
|
|
|
+ return {rhs.is_negative, detail::add(rhs.data, lhs.data)};
|
|
|
|
|
+ } else {
|
|
|
|
|
+ auto cmp = detail::compare(rhs.data, lhs.data);
|
|
|
|
|
+ if (cmp == 0) {
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ } else if (cmp > 0) {
|
|
|
|
|
+ return {rhs.is_negative, detail::subtract_nounderflow(rhs.data, lhs.data)};
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return {!lhs.is_negative, detail::subtract_nounderflow(lhs.data, rhs.data)};
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
namespace detail {
|
|
namespace detail {
|
|
|
#define IMPL_COMPARE(expr) \
|
|
#define IMPL_COMPARE(expr) \
|
|
|
if (rhs expr < lhs expr) return -1; \
|
|
if (rhs expr < lhs expr) return -1; \
|
|
@@ -106,7 +125,7 @@ namespace detail {
|
|
|
data_type add(data_type const & rhs, data_type const & lhs) {
|
|
data_type add(data_type const & rhs, data_type const & lhs) {
|
|
|
data_type::size_type const rbnd = rhs.size(), lbnd = lhs.size();
|
|
data_type::size_type const rbnd = rhs.size(), lbnd = lhs.size();
|
|
|
data_type::size_type const ubnd = std::max(rbnd, lbnd);
|
|
data_type::size_type const ubnd = std::max(rbnd, lbnd);
|
|
|
- data_type rval(ubnd);
|
|
|
|
|
|
|
+ data_type rval(ubnd+1);
|
|
|
// Add
|
|
// Add
|
|
|
for (data_type::size_type i = 0; i < rbnd; ++i) {
|
|
for (data_type::size_type i = 0; i < rbnd; ++i) {
|
|
|
rval[i] += rhs[i];
|
|
rval[i] += rhs[i];
|
|
@@ -115,16 +134,13 @@ namespace detail {
|
|
|
rval[i] += lhs[i];
|
|
rval[i] += lhs[i];
|
|
|
}
|
|
}
|
|
|
// Carry
|
|
// Carry
|
|
|
- for (data_type::size_type i = 0; i < ubnd-1; ++i) {
|
|
|
|
|
|
|
+ for (data_type::size_type i = 0; i < ubnd; ++i) {
|
|
|
if (rval[i] > biginteger::MAX_SEG) {
|
|
if (rval[i] > biginteger::MAX_SEG) {
|
|
|
rval[i] -= biginteger::OVER_SEG;
|
|
rval[i] -= biginteger::OVER_SEG;
|
|
|
rval[i+1] += 1;
|
|
rval[i+1] += 1;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if (rval[ubnd-1] > biginteger::MAX_SEG) {
|
|
|
|
|
- rval[ubnd-1] -= biginteger::OVER_SEG;
|
|
|
|
|
- rval.push_back(1);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (rval[ubnd] == 0) { rval.pop_back(); }
|
|
|
return rval;
|
|
return rval;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -147,6 +163,12 @@ namespace detail {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+bool math::operator==(biginteger const & rhs, biginteger const & lhs) {
|
|
|
|
|
+ return rhs.is_negative == lhs.is_negative && detail::compare(rhs.data, lhs.data) == 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+biginteger const biginteger::ZERO{0}, biginteger::ONE{1}, biginteger::NEGATIVE_ONE{-1};
|
|
|
|
|
+
|
|
|
#include <iomanip>
|
|
#include <iomanip>
|
|
|
#include <sstream>
|
|
#include <sstream>
|
|
|
|
|
|