2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
49#define LONG_LONG_MIN LLONG_MIN
53#define LONG_LONG_MAX LLONG_MAX
57#define ULONG_LONG_MAX ULLONG_MAX
60#define INFINT_USE_EXCEPTIONS
71static const int powersOfTen[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
78 const char*
what()
const throw();
85 :
std::exception(), txt(txt) {}
92inline static div_t
my_div(
int num,
int denom) {
94 result.quot = num / denom;
95 result.rem = num - denom * result.quot;
99inline static ldiv_t
my_ldiv(
long num,
long denom) {
101 result.quot = num / denom;
102 result.rem = num - denom * result.quot;
106inline static lldiv_t
my_lldiv(
long long num,
long long denom) {
108 result.quot = num / denom;
109 result.rem = num - denom * result.quot;
114 friend std::ostream& operator<<(
std::ostream& s,
const InfInt& n);
127 InfInt(
unsigned long long l);
195 static void multiplyByDigit(
ELEM_TYPE factor, std::vector<ELEM_TYPE>& val);
197 void correct(
bool justCheckLeadingZeros =
false,
bool hasValidSign =
false);
198 void fromString(
const std::string& s);
199 void optimizeSqrtSearchBounds(
InfInt& lo,
InfInt& hi)
const;
200 void truncateToBase();
201 bool equalizeSigns();
202 void removeLeadingZeros();
204 std::vector<ELEM_TYPE> val;
210 val.push_back((ELEM_TYPE)0);
225 bool subtractOne =
false;
236 val.push_back((ELEM_TYPE)dt.rem);
247 bool subtractOne =
false;
258 val.push_back((ELEM_TYPE)dt.rem);
269 bool subtractOne =
false;
280 val.push_back((ELEM_TYPE)dt.rem);
292 val.push_back((ELEM_TYPE)(l % BASE));
300 val.push_back((ELEM_TYPE)(l % BASE));
308 val.push_back((ELEM_TYPE)(l % BASE));
331 bool subtractOne =
false;
344 val.push_back((ELEM_TYPE)dt.rem);
348 return subtractOne ?
--*
this : *
this;
353 bool subtractOne =
false;
366 val.push_back((ELEM_TYPE)dt.rem);
370 return subtractOne ?
--*
this : *
this;
375 bool subtractOne =
false;
388 val.push_back((ELEM_TYPE)dt.rem);
392 return subtractOne ?
--*
this : *
this;
400 val.push_back((ELEM_TYPE)(l % BASE));
411 val.push_back((ELEM_TYPE)(l % BASE));
422 val.push_back((ELEM_TYPE)(l % BASE));
430 if (
this == &l)
return *
this;
438 val[0] += (pos ? 1 : -1);
439 this->correct(
false,
true);
445 val[0] -= (pos ? 1 : -1);
446 this->correct(
false,
true);
453 val[0] += (pos ? 1 : -1);
454 this->correct(
false,
true);
461 val[0] -= (pos ? 1 : -1);
462 this->correct(
false,
true);
468 if (rhs.val.size() > val.size()) {
469 val.resize(rhs.val.size(), 0);
471 for (size_t i = 0; i < val.size(); ++i) {
472 val[i] = (pos ? val[i] : -val[i]) +
473 (i < rhs.val.size() ? (rhs.pos ? rhs.val[i] : -rhs.val[i]) : 0);
481 if (rhs.val.size() > val.size()) {
482 val.resize(rhs.val.size(), 0);
484 for (size_t i = 0; i < val.size(); ++i) {
485 val[i] = (pos ? val[i] : -val[i]) -
486 (i < rhs.val.size() ? (rhs.pos ? rhs.val[i] : -rhs.val[i]) : 0);
503 throw InfIntException(
"division by zero");
505 std::cerr <<
"Division by zero!" << std::endl;
510 InfInt D = (rhs.pos ? rhs :
-rhs);
511 InfInt N = (pos ? *
this :
-*
this);
513 std::fill(val.begin(), val.end(), 0);
514 for (
int i = (
int)N.val.size() - 1; i >= 0; --i) {
515 R.val.insert(R.val.begin(), N.val[i]);
522 pos = (val.size() == 1 && val[0] == 0) ?
true : (oldpos == rhs.pos);
558 multiplyByDigit(factor, val);
560 pos = (val.size() == 1 && val[0] == 0) ?
true : (oldpos == (rhs >= 0));
574 result.val.resize(val.size() > rhs.val.size() ? val.size() : rhs.val.size(), 0);
575 for (size_t i = 0; i < val.size() || i < rhs.val.size(); ++i) {
576 result.val[i] = (i < val.size() ? (pos ? val[i] : -val[i]) : 0) +
577 (i < rhs.val.size() ? (rhs.pos ? rhs.val[i] : -rhs.val[i]) : 0);
586 result.val.resize(val.size() > rhs.val.size() ? val.size() : rhs.val.size(), 0);
587 for (size_t i = 0; i < val.size() || i < rhs.val.size(); ++i) {
588 result.val[i] = (i < val.size() ? (pos ? val[i] : -val[i]) : 0) -
589 (i < rhs.val.size() ? (rhs.pos ? rhs.val[i] : -rhs.val[i]) : 0);
598 result.val.resize(val.size() + rhs.val.size(), 0);
607 for (size_t i = digit < rhs.val.size() ? 0 : digit - rhs.val.size() + 1;
608 i < val.size() && i <= digit; ++i) {
609 PRODUCT_TYPE pval = result.val[digit] + val[i] * (PRODUCT_TYPE)rhs.val[digit - i];
610 if (pval >= BASE || pval <= -BASE) {
611 lldiv_t dt = my_lldiv(pval, BASE);
615 result.val[digit] = (ELEM_TYPE)pval;
622 for (; carry > 0; ++digit) {
628 result.pos = (result.val.size() == 1 && result.val[0] == 0) ?
true : (pos == rhs.pos);
636 throw InfIntException(
"division by zero");
638 std::cerr <<
"Division by zero!" << std::endl;
644 InfInt D = (rhs.pos ? rhs :
-rhs);
645 InfInt N = (pos ? *
this :
-*
this);
646 Q.val.resize(N.val.size(), 0);
647 for (
int i = (
int)N.val.size() - 1; i >= 0; --i) {
648 R.val.insert(R.val.begin(), N.val[i]);
655 Q.pos = (Q.val.size() == 1 && Q.val[0] == 0) ?
true : (pos == rhs.pos);
663 throw InfIntException(
"division by zero");
665 std::cerr <<
"Division by zero!" << std::endl;
670 InfInt D = (rhs.pos ? rhs :
-rhs);
671 InfInt N = (pos ? *
this :
-*
this);
672 for (
int i = (
int)N.val.size() - 1; i >= 0; --i) {
673 R.val.insert(R.val.begin(), N.val[i]);
678 R.pos = (R.val.size() == 1 && R.val[0] == 0) ?
true : pos;
686 multiplyByDigit(factor, result.val);
688 result.pos = (result.val.size() == 1 && result.val[0] == 0) ?
true : (pos == (rhs >= 0));
694 if (pos != rhs.pos || val.size() != rhs.val.size()) {
697 for (
int i = (
int)val.size() - 1; i >= 0; --i) {
698 if (val[i] != rhs.val[i]) {
707 if (pos != rhs.pos || val.size() != rhs.val.size()) {
710 for (
int i = (
int)val.size() - 1; i >= 0; --i) {
711 if (val[i] != rhs.val[i]) {
720 if (pos && !rhs.pos) {
723 if (!pos && rhs.pos) {
726 if (val.size() > rhs.val.size()) {
727 return pos ?
false :
true;
729 if (val.size() < rhs.val.size()) {
730 return pos ?
true :
false;
732 for (
int i = (
int)val.size() - 1; i >= 0; --i) {
733 if (val[i] < rhs.val[i]) {
734 return pos ?
true :
false;
736 if (val[i] > rhs.val[i]) {
737 return pos ?
false :
true;
745 if (pos && !rhs.pos) {
748 if (!pos && rhs.pos) {
751 if (val.size() > rhs.val.size()) {
752 return pos ?
false :
true;
754 if (val.size() < rhs.val.size()) {
755 return pos ?
true :
false;
757 for (
int i = (
int)val.size() - 1; i >= 0; --i) {
758 if (val[i] < rhs.val[i]) {
759 return pos ?
true :
false;
761 if (val[i] > rhs.val[i]) {
762 return pos ?
false :
true;
770 if (pos && !rhs.pos) {
773 if (!pos && rhs.pos) {
776 if (val.size() > rhs.val.size()) {
777 return pos ?
true :
false;
779 if (val.size() < rhs.val.size()) {
780 return pos ?
false :
true;
782 for (
int i = (
int)val.size() - 1; i >= 0; --i) {
783 if (val[i] < rhs.val[i]) {
784 return pos ?
false :
true;
786 if (val[i] > rhs.val[i]) {
787 return pos ?
true :
false;
795 if (pos && !rhs.pos) {
798 if (!pos && rhs.pos) {
801 if (val.size() > rhs.val.size()) {
802 return pos ?
true :
false;
804 if (val.size() < rhs.val.size()) {
805 return pos ?
false :
true;
807 for (
int i = (
int)val.size() - 1; i >= 0; --i) {
808 if (val[i] < rhs.val[i]) {
809 return pos ?
false :
true;
811 if (val[i] > rhs.val[i]) {
812 return pos ?
true :
false;
821 for (
int i = (
int)
this->numberOfDigits() / 2; i >= 2; --i) {
837 throw InfIntException(
"intSqrt called for non-positive integer");
839 std::cerr <<
"intSqrt called for non-positive integer: " << *
this << std::endl;
843 InfInt hi = *
this / 2 + 1;
847 optimizeSqrtSearchBounds(lo, hi);
860 }
while (lo < hi - 1 && mid2
!= *
this);
866 if (numberOfDigits() <= i) {
868 throw InfIntException(
"invalid digit index");
870 std::cerr <<
"Invalid digit index: " << i << std::endl;
874 return (val[i / DIGIT_COUNT] / powersOfTen[i % DIGIT_COUNT]) % 10;
879 return (val.size() - 1) * DIGIT_COUNT +
880 (val.back() > 99999999
882 : (val.back() > 9999999
884 : (val.back() > 999999
886 : (val.back() > 99999
894 : (val.back() > 9 ? 2 : 1))))))));
899 std::ostringstream oss;
906 return val.size() *
sizeof(ELEM_TYPE) +
sizeof(
bool);
911 if (*
this > INT_MAX || *
this < INT_MIN) {
913 throw InfIntException(
"out of bounds");
915 std::cerr <<
"Out of INT bounds: " << *
this << std::endl;
919 for (
int i = (
int)val.size() - 1; i >= 0; --i) {
920 result = result * BASE + val[i];
922 return pos ? result : -result;
927 if (*
this > LONG_MAX || *
this < LONG_MIN) {
929 throw InfIntException(
"out of bounds");
931 std::cerr <<
"Out of LONG bounds: " << *
this << std::endl;
935 for (
int i = (
int)val.size() - 1; i >= 0; --i) {
936 result = result * BASE + val[i];
938 return pos ? result : -result;
945 throw InfIntException(
"out of bounds");
947 std::cerr <<
"Out of LLONG bounds: " << *
this << std::endl;
950 long long result = 0;
951 for (
int i = (
int)val.size() - 1; i >= 0; --i) {
952 result = result * BASE + val[i];
954 return pos ? result : -result;
959 if (!pos || *
this > UINT_MAX) {
961 throw InfIntException(
"out of bounds");
963 std::cerr <<
"Out of UINT bounds: " << *
this << std::endl;
966 unsigned int result = 0;
967 for (
int i = (
int)val.size() - 1; i >= 0; --i) {
968 result = result * BASE + val[i];
975 if (!pos || *
this > ULONG_MAX) {
977 throw InfIntException(
"out of bounds");
979 std::cerr <<
"Out of ULONG bounds: " << *
this << std::endl;
982 unsigned long result = 0;
983 for (
int i = (
int)val.size() - 1; i >= 0; --i) {
984 result = result * BASE + val[i];
993 throw InfIntException(
"out of bounds");
995 std::cerr <<
"Out of ULLONG bounds: " << *
this << std::endl;
998 unsigned long long result = 0;
999 for (
int i = (
int)val.size() - 1; i >= 0; --i) {
1000 result = result * BASE + val[i];
1005inline void InfInt::truncateToBase() {
1007 for (size_t i = 0; i < val.size(); ++i)
1009 if (val[i] >= BASE || val[i] <= -BASE) {
1010 div_t dt = my_div(val[i], BASE);
1012 if (i + 1 >= val.size()) {
1013 val.push_back(dt.quot);
1015 val[i + 1] += dt.quot;
1021inline bool InfInt::equalizeSigns() {
1023 bool isPositive =
true;
1024 int i = (
int)((val.size())) - 1;
1025 for (; i >= 0; --i) {
1027 isPositive = val[i--] > 0;
1033 for (; i >= 0; --i) {
1037 for (; (size_t)(index) < val.size() && val[index] == 0; ++k, ++index)
1043 for (; k > 0; --k) {
1044 val[i + k] = UPPER_BOUND;
1050 for (; i >= 0; --i) {
1054 for (; (size_t)(index) < val.size() && val[index] == 0; ++k, ++index)
1060 for (; k > 0; --k) {
1061 val[i + k] = -UPPER_BOUND;
1071inline void InfInt::removeLeadingZeros() {
1073 for (
int i = (
int)(val.size()) - 1; i > 0; --i)
1079 val.erase(val.begin() + i);
1083inline void InfInt::correct(
bool justCheckLeadingZeros,
bool hasValidSign) {
1085 if (!justCheckLeadingZeros) {
1088 if (equalizeSigns()) {
1089 pos = ((val.size() == 1 && val[0] == 0) || !hasValidSign) ?
true : pos;
1091 pos = hasValidSign ? !pos :
false;
1092 for (size_t i = 0; i < val.size(); ++i) {
1093 val[i] = abs(val[i]);
1098 removeLeadingZeros();
1101inline void InfInt::fromString(
const std::string& s) {
1105 val.reserve(s.size() / DIGIT_COUNT + 1);
1108 val.push_back(atoi(s.substr(i, DIGIT_COUNT).c_str()));
1112 if (ss.size() == 1 && ss[0] ==
'-') {
1115 val.push_back(atoi(ss.c_str()));
1118 if (val.back() < 0) {
1119 val.back() = -val.back();
1132 avg = dt.rem ? (dt.quot + 1) : dt.quot;
1146inline void InfInt::multiplyByDigit(
ELEM_TYPE factor, std::vector<ELEM_TYPE>& val) {
1149 for (size_t i = 0; i < val.size(); ++i) {
1151 if (pval >=
BASE || pval <= -
BASE) {
1161 val.push_back(carry);
1183 for (
int i = (
int)n.val.size() - 1; i >= 0; --i) {
1191 s <<
std::setfill(
' ');
static const int powersOfTen[]
static div_t my_div(int num, int denom)
static const ELEM_TYPE DIGIT_COUNT
#define INFINT_USE_EXCEPTIONS
static const ELEM_TYPE BASE
static ldiv_t my_ldiv(long num, long denom)
static lldiv_t my_lldiv(long long num, long long denom)
static const ELEM_TYPE UPPER_BOUND
InfIntException(const std::string &txt)
const char * what() const
bool operator!=(const InfInt &rhs) const
const InfInt & operator=(long l)
const InfInt & operator+=(const InfInt &rhs)
const InfInt & operator=(const std::string &s)
char digitAt(size_t i) const
bool operator<(const InfInt &rhs) const
InfInt operator*(const InfInt &rhs) const
bool operator<=(const InfInt &rhs) const
const InfInt & operator%=(const InfInt &rhs)
bool operator>(const InfInt &rhs) const
std::string to_string() const
friend std::istream & operator>>(std::istream &s, InfInt &val)
const InfInt & operator=(unsigned long long l)
unsigned int toUnsignedInt() const
const InfInt & operator=(int l)
const InfInt & operator--()
const InfInt & operator*=(const InfInt &rhs)
const InfInt & operator=(const char *c)
const InfInt & operator=(unsigned long l)
bool operator>=(const InfInt &rhs) const
const InfInt & operator=(const InfInt &l)
long long toLongLong() const
const InfInt & operator-=(const InfInt &rhs)
unsigned long long toUnsignedLongLong() const
size_t numberOfDigits() const
const InfInt & operator++()
InfInt(const std::string &s)
InfInt operator*(ELEM_TYPE rhs) const
const InfInt & operator/=(const InfInt &rhs)
InfInt operator-(const InfInt &rhs) const
const InfInt & operator=(unsigned int l)
const InfInt & operator=(long long l)
InfInt operator+(const InfInt &rhs) const
InfInt operator%(const InfInt &rhs) const
const InfInt & operator*=(ELEM_TYPE rhs)
unsigned long toUnsignedLong() const
InfInt operator/(const InfInt &rhs) const
InfInt(unsigned long long l)
bool operator==(const InfInt &rhs) const
std::string to_string(const InfInt &val)
size_t operator()(const InfInt &e) const noexcept