23 #ifndef PRECISION_H_INCLUDED 24 #define PRECISION_H_INCLUDED 33 extern size_t PRECISION;
35 extern bool WARN_OVERFLOW;
37 void fillDigits(
const std::vector<short>& digits,
38 std::vector<short>& receiver);
40 template<const
size_t base>
41 long double log(
long double x)
44 return log(x)/log((
long double)base);
47 char convertDigit(
short digit);
49 template<
size_t base = 10>
52 template<
size_t base = 10>
55 template<
size_t t_base>
60 bool minusSign =
false;
62 std::vector<short> digits;
69 int_ap(
long long int value);
72 int_ap(
const std::vector<short>& t_digits);
76 const std::vector<short>& t_digits);
86 template<
size_t targetBase>
97 X.setMinusSign(
false);
101 divide(X, target_ap, divisor, rest);
104 targetBasePower.shiftLeft();
106 res.setMinusSign(sign);
115 short operator[](
size_t i)
const;
117 bool getMinusSign()
const;
119 void setMinusSign(
bool t_minusSign);
129 void shiftLeft(
size_t n = 1);
131 void shiftRight(
size_t n = 1);
137 long long int toCInteger()
const;
140 std::ostream& operator<<(std::ostream& fout, const int_ap<base>& integer)
142 if (integer.minusSign)
146 for (
auto digit = integer.digits.rbegin();
147 digit != integer.digits.rend();
149 fout << convertDigit(*digit);
176 if (a.minusSign xor b.minusSign) {
181 a.setMinusSign(
false);
188 a.setMinusSign(
false);
193 if (a.size() < b.size()) {
200 const int n = b.digits.size();
202 for (
int i = 0; i < n; ++i) {
203 short sum = retenue + a.digits[i] + b.digits[i];
204 if (sum > (
int)base-1) {
212 for (
int i = n; i < (int)a.digits.size(); ++i) {
213 short sum = retenue + a.digits[i];
214 if (sum > (
int)base-1) {
223 a.digits.push_back(retenue);
256 if (a.minusSign xor b.minusSign) {
258 a.setMinusSign(
false);
268 a.setMinusSign(
false);
286 for (
size_t i = 0; i != b.size(); ++i) {
287 short res = base + a[i] - (b[i] + retenue);
288 a.digits[i] = res % base;
289 retenue = res < (int)base;
291 if (a.size() > b.size()) {
292 for (
size_t j = b.size(); j != a.size(); ++j) {
295 a.digits[j] = base - 1;
297 a.digits[j] = a[j] - 1;
379 std::vector<short> newDigits(0);
381 for (
size_t i = 0; i != a.digits.size(); ++i) {
382 std::vector<short> intermediateDigits(i,0);
384 for (
size_t j = 0; j != b.digits.size(); ++j) {
385 int product = retenue + a.digits[i]*b.digits[j];
386 if (product > (
int)base-1) {
387 retenue = product / base;
388 product = product % base;
392 intermediateDigits.push_back(product);
395 intermediateDigits.push_back(retenue);
399 a.digits = res.digits;
400 a.setMinusSign(a.minusSign xor b.minusSign);
409 divide(a, b, res, rest);
419 if (abs(a) < abs(b)) {
425 std::cout <<
"Division by 0 encountered in int_ap<" 429 bool sign = a.minusSign xor b.minusSign;
430 bool signA = a.minusSign;
434 std::vector<short> a_digits;
438 a_digits.push_back(a.digits[0]);
446 for (
size_t i = 0; i != base; ++i) {
455 rest.shiftLeft(nDigits);
456 divisor.shiftLeft(nDigits);
458 if (a_digits.empty()) {
463 divide(rest, b, result, rest);
466 result.setMinusSign(sign);
467 rest .setMinusSign(signA);
479 divide(a, b, result, rest);
481 while (rest != 0 and result.digits.size()+1 < PRECISION) {
486 divide(rest, b, intermediate, rest);
487 result += intermediate;
519 divide(a, b, divisor, rest);
564 if (a != 0 and b == 0)
573 if (totalPow*2 <= b) {
577 else if (totalPow == b)
580 return res *= pow(a, b-totalPow);
608 if (a.minusSign != b.minusSign)
610 if (a.digits.size() != b.digits.size())
613 for (
size_t i = 0; i != a.digits.size(); ++i)
614 if (a.digits[i] != b.digits[i])
638 bool operator<(long long int a, const int_ap<base>& b)
644 bool operator<(const int_ap<base>& a,
long long int b)
646 return a<int_ap<base>(b);
650 bool operator<(const int_ap<base>& a,
const int_ap<base>& b)
652 if (a.minusSign != b.minusSign)
656 if (a.digits.size() < b.digits.size())
658 if (b.digits.size() < a.digits.size())
660 for (
size_t i = a.size(); i --> 0 ;) {
661 if (a.digits[i] < b.digits[i])
663 else if (b.digits[i] != a.digits[i])
670 bool operator<=(long long int a, const int_ap<base>& b)
672 return (a<b or a==b);
676 bool operator<=(const int_ap<base>& a,
long long int b)
678 return (a<b or a==b);
682 bool operator<=(const int_ap<base>& a,
const int_ap<base>& b)
684 return (a<b or a==b);
708 return (a>b or a==b);
714 return (a>b or a==b);
720 return (a>b or a==b);
725 template<
size_t base>
728 template<
size_t base>
729 int_ap<base>::int_ap(
long long int value)
735 template<
size_t base>
736 int_ap<base>::int_ap(
const std::vector<short>& t_digits)
738 fillDigits(t_digits, digits);
742 template<
size_t base>
743 int_ap<base>::int_ap(
bool t_minusSign,
744 const std::vector<short>& t_digits)
746 fillDigits(t_digits, digits);
748 setMinusSign(t_minusSign);
751 template<
size_t base>
754 return digits.size();
757 template<
size_t base>
760 return digits.empty();
763 template<
size_t base>
769 template<
size_t base>
775 template<
size_t base>
778 minusSign = t_minusSign;
779 if (minusSign and digits.size() == 1 and digits[0] == 0)
784 template<
size_t base>
787 setMinusSign(not minusSign);
790 template<
size_t base>
793 digits[i] = base - digits[i];
796 template<
size_t base>
799 std::vector<short> newDigits(digits.size());
800 for (
size_t i = 0; i != digits.size(); ++i)
801 newDigits[i] = base - digits[i];
805 template<
size_t base>
808 return int_ap<base>(minusSign, std::vector<short>(digits.size(), base-1));
811 template<
size_t base>
814 for (
size_t i = digits.size(); i --> 0 ;)
815 if (digits[i] != 0) {
816 if (i+1 <= digits.size()-1)
817 digits.erase(digits.begin()+i+1,digits.end());
820 digits = std::vector<short>(1, 0);
823 template<
size_t base>
826 for (
size_t i = 0; i != digits.size(); ++i)
827 if (digits[i] != 0) {
829 digits.erase(digits.begin(), digits.begin()+i);
832 digits = std::vector<short>(1, 0);
835 template<
size_t base>
840 std::vector<short> newDigits = std::vector<short>(n ,0);
841 digits.insert(digits.begin(), newDigits.begin(), newDigits.end());
844 template<
size_t base>
847 if (n > digits.size())
849 digits.erase(digits.begin(), digits.begin()+n);
852 template<
size_t base>
861 if (value < (
int)base)
862 digits = std::vector<short>(1);
864 digits = std::vector<short>(1 + floor(log<base>((value))));
865 for (
size_t i = 0; i != digits.size(); ++i) {
866 int digit = value % base;
875 template<
size_t base>
878 minusSign = value.minusSign;
879 digits = value.digits;
883 template<
size_t base>
893 template<
size_t base>
897 std::cout <<
"Error: getting C++ integer for a number bigger than" 901 long long int res = 0;
902 for (
auto iter = digits.rbegin(); iter != digits.rend(); ++iter)
903 res = base * res + *iter;
Namespace for csl library.
Definition: abreviation.h:34
Definition: precision_int.h:53
Expr operator+(const Expr &a, const Expr &b)
Shortcut function that allows to use arithmetic operator + with Expr (== shared_ptr<Abstract>).
Definition: abstract.cpp:1298
Definition: precision_int.h:915
bool operator>(const Expr &a, const Expr &b)
see Abstract::operator>()
Definition: abstract.cpp:1419
bool operator>=(const Expr &a, const Expr &b)
see Abstract::operator>=()
Definition: abstract.cpp:1413
Definition: precision_int.h:909
Definition: precision_float.h:63
Expr operator/(const Expr &a, const Expr &b)
Shortcut function that allows to use arithmetic operator / with Expr (== shared_ptr<Abstract>).
Definition: abstract.cpp:1372
Expr operator*(const Expr &a, const Expr &b)
Shortcut function that allows to use arithmetic operator * with Expr (== shared_ptr<Abstract>).
Definition: abstract.cpp:1351
bool operator==(const Expr &a, const Expr &b)
see Abstract::operator==()
Definition: abstract.cpp:1398
bool operator!=(const Expr &a, const Expr &b)
see Abstract::operator!=()
Definition: abstract.cpp:1404