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.