42 #ifndef TEUCHOS_BIG_UINT_HPP
43 #define TEUCHOS_BIG_UINT_HPP
55 BigUInt<n>::BigUInt() {}
58 BigUInt<n>::BigUInt(std::uint64_t v) {
59 for (
int i = 2; i < n; ++i) x[i] = 0;
60 if (n > 1) x[1] = std::uint32_t(v >> 32);
61 x[0] = std::uint32_t(v);
65 BigUInt<n>::BigUInt(std::string
const& s) : BigUInt(std::uint32_t(0)) {
73 BigUInt<n>::operator bool() const noexcept {
74 for (
int i = 0; i < n; ++i)
if (x[i])
return true;
79 std::uint32_t& BigUInt<n>::operator[](
int i) {
return x[i]; }
82 std::uint32_t
const& BigUInt<n>::operator[](
int i)
const {
return x[i]; }
85 BigUInt<n>& BigUInt<n>::operator+=(std::uint32_t b) {
86 std::uint32_t carry = b;
87 for (
int i = 0; i < n; ++i) {
88 std::uint64_t ax = x[i];
89 auto cx = ax + std::uint64_t(carry);
90 carry = std::uint32_t(cx >> 32);
91 x[i] = std::uint32_t(cx);
97 BigUInt<n>& BigUInt<n>::operator+=(BigUInt<n>
const& b) {
98 std::uint32_t carry = 0;
99 for (
int i = 0; i < n; ++i) {
100 std::uint64_t ax = x[i];
101 std::uint64_t bx = b[i];
102 auto cx = ax + bx + std::uint64_t(carry);
103 carry = std::uint32_t(cx >> 32);
104 x[i] = std::uint32_t(cx);
110 BigUInt<n>& BigUInt<n>::operator-=(std::uint32_t b) {
111 std::int64_t carry = b;
112 for (
int i = 0; i < n; ++i) {
113 std::int64_t ax = x[i];
114 auto cx = ax - carry;
117 cx += std::int64_t(1) << 32;
121 x[i] = std::uint32_t(cx);
127 BigUInt<n>& BigUInt<n>::operator-=(BigUInt<n>
const& b) {
128 std::int64_t carry = 0;
129 for (
int i = 0; i < n; ++i) {
130 std::int64_t ax = x[i];
131 std::int64_t bx = b[i];
132 auto cx = ax - bx - carry;
135 cx += std::int64_t(1) << 32;
139 x[i] = std::uint32_t(cx);
145 BigUInt<n>& BigUInt<n>::operator*=(std::uint32_t b) {
146 std::uint32_t carry = 0;
147 for (
int i = 0; i < n; ++i) {
148 std::uint64_t ax = x[i];
149 auto cx = (ax * std::uint64_t(b)) + std::uint64_t(carry);
150 carry = std::uint32_t(cx >> 32);
151 x[i] = std::uint32_t(cx);
157 BigUInt<n>& BigUInt<n>::operator<<=(std::uint32_t b) {
158 auto ndigits = b / 32;
159 auto nbits = b - (ndigits * 32);
160 for (
int i = n - 1; i >= 0; --i) {
161 std::uint32_t xi = 0;
162 if (i >=
int(ndigits)) {
163 xi = x[i - ndigits] << nbits;
166 if (nbits && (i >
int(ndigits))) {
167 xi |= x[i - ndigits - 1] >> (32 - nbits);
175 BigUInt<n>& BigUInt<n>::operator>>=(std::uint32_t b) {
176 auto ndigits = b / 32;
177 auto nbits = b - (ndigits * 32);
178 for (
int i = 0; i < n; ++i) {
179 std::uint32_t xi = 0;
180 if (i + ndigits < n) xi = x[i + ndigits] >> nbits;
181 if (nbits && i + ndigits + 1 < n) xi |= x[i + ndigits + 1] << (32 - nbits);
188 std::ostream& operator<<(std::ostream& os, BigUInt<n> a) {
193 divmod(quotient, a, 10);
194 auto remainder = a[0];
196 buf[i++] = char(remainder) +
'0';
198 for (
int j = 0; j < i / 2; ++j) {
199 auto tmp = buf[i - j - 1];
200 buf[i - j - 1] = buf[j];
203 if (i == 0) buf[i++] =
'0';
210 BigUInt<n> operator+(BigUInt<n>
const& a, BigUInt<n>
const& b) {
217 BigUInt<n> operator-(BigUInt<n>
const& a, BigUInt<n>
const& b) {
224 BigUInt<n> operator*(BigUInt<n>
const& a, BigUInt<n>
const& b) {
225 BigUInt<n> a_times_b_i;
227 for (
int i = n - 1; i >= 0; --i) {
237 BigUInt<n> operator/(BigUInt<n>
const& a, std::uint32_t
const& b) {
240 divmod(quotient, x, b);
245 BigUInt<n> operator/(BigUInt<n>
const& a, BigUInt<n>
const& b) {
246 if (b > a)
return BigUInt<n>(0);
247 BigUInt<n> quotient(1);
253 auto factor = quotient;
275 int comp(BigUInt<n>
const& a, BigUInt<n>
const& b) {
276 for (
int i = n - 1; i >= 0; --i) {
278 if (a[i] > b[i])
return 1;
286 bool operator>=(BigUInt<n>
const& a, BigUInt<n>
const& b) {
287 return comp(a, b) > -1;
291 bool operator<=(BigUInt<n>
const& a, BigUInt<n>
const& b) {
292 return comp(a, b) < 1;
296 bool operator<(BigUInt<n>
const& a, BigUInt<n>
const& b) {
297 return comp(a, b) == -1;
301 bool operator>(BigUInt<n>
const& a, BigUInt<n>
const& b) {
302 return comp(a, b) == 1;
306 bool operator==(BigUInt<n>
const& a, BigUInt<n>
const& b) {
307 for (
int i = 0; i < n; ++i)
if (a[i] != b[i])
return false;
312 void divmod(BigUInt<n>& quotient, BigUInt<n>& x, std::uint32_t
const& b) {
313 quotient = BigUInt<n>(std::uint32_t(0));
314 for (
int i = n - 1; i >= 0;) {
317 auto dividend = x[i];
318 auto quotient2 = dividend / b;
319 auto remainder = dividend - (quotient2 * b);
320 quotient[i] = quotient2;
323 auto dividend = std::uint64_t(x[i]);
325 dividend |= x[i - 1];
326 auto quotient2 = dividend / std::uint64_t(b);
327 auto remainder = dividend - (quotient2 * std::uint64_t(b));
328 quotient[i - 1] = std::uint32_t(quotient2);
330 x[i - 1] = std::uint32_t(remainder);
Arbitrary-precision unsigned integer declaration.