44 mpfr_const_pi(result.
value, MPFR_RNDN);
51 mpfr_set_ui(result.
value, 1, MPFR_RNDN);
52 mpfr_exp(result.
value, result.
value, MPFR_RNDN);
63 mpfr_div_ui(result.
value, result.
value, 2, MPFR_RNDN);
69 mpfr_const_log2(result.
value, MPFR_RNDN);
83 mpfr_const_log2(result.
value, MPFR_RNDN);
84 mpfr_ui_div(result.
value, 1, result.
value, MPFR_RNDN);
93 mpfr_ui_div(result.
value, 1, result.
value, MPFR_RNDN);
99 mpfr_const_euler(result.
value, MPFR_RNDN);
105 mpfr_const_catalan(result.
value, MPFR_RNDN);
110 mpfr_t one, next, eps;
111 mpfr_init2(one, precision);
112 mpfr_init2(next, precision);
113 mpfr_init2(eps, precision);
115 mpfr_set_ui(one, 1, MPFR_RNDN);
116 mpfr_set(next, one, MPFR_RNDN);
117 mpfr_nextabove(next);
118 mpfr_sub(eps, next, one, MPFR_RNDN);
124 mpfr_init2(
value, precision);
125 mpfr_set_zero(
value, 1);
129 mpfr_init2(
value, precision);
130 mpfr_set_si(
value, i, MPFR_RNDN);
134 mpfr_init2(
value, precision);
135 mpfr_set_z(
value, i.
getMPZ().get_mpz_t(), MPFR_RNDN);
139 mpfr_init2(
value, precision);
140 mpfr_set_d(
value, d, MPFR_RNDN);
144 mpfr_init2(
value, precision);
145 mpfr_set_flt(
value, f, MPFR_RNDN);
149 mpfr_prec_t precision) {
150 mpfr_init2(
value, precision);
152 if (mpfr_set_str(
value, s.c_str(), 10, MPFR_RNDN) != 0) {
154 throw std::invalid_argument(
155 "Cannot convert string to high precision real number");
160 mpfr_init2(
value, precision);
162 if (mpfr_set_str(
value, s, 10, MPFR_RNDN) != 0) {
164 throw std::invalid_argument(
165 "Cannot convert string to high precision real number");
170 mpfr_init2(
value, precision);
171 mpfr_set(
value, t, MPFR_RNDN);
175 mpfr_init2(
value, mpfr_get_prec(other.
value));
182 if (
this != &other) {
184 if (mpfr_get_prec(
value) != mpfr_get_prec(other.
value)) {
186 mpfr_init2(
value, mpfr_get_prec(other.
value));
200 std::max(mpfr_get_prec(
value), mpfr_get_prec(other.
value)));
208 std::max(mpfr_get_prec(
value), mpfr_get_prec(other.
value)));
222 std::max(mpfr_get_prec(
value), mpfr_get_prec(other.
value)));
230 std::max(mpfr_get_prec(
value), mpfr_get_prec(other.
value)));
265 return !(*
this == other);
273 return mpfr_lessequal_p(
value, other.
value) != 0;
277 return mpfr_greater_p(
value, other.
value) != 0;
281 return mpfr_greaterequal_p(
value, other.
value) != 0;
293 throw std::domain_error(
"Cannot compute square root of a negative number");
342 throw std::domain_error(
343 "Cannot compute logarithm of a non-positive number");
352 throw std::domain_error(
353 "Cannot compute logarithm of a non-positive number");
362 throw std::domain_error(
363 "Cannot compute logarithm of a non-positive number");
373 throw std::domain_error(
"Invalid arguments for logarithm");
420 throw std::domain_error(
"Argument for asin must be in range [-1, 1]");
429 throw std::domain_error(
"Argument for acos must be in range [-1, 1]");
454 throw std::domain_error(
"Argument for asec cannot be 0");
457 mpfr_ui_div(reciprocal.
value, 1,
value, MPFR_RNDN);
458 return reciprocal.
acos();
464 throw std::domain_error(
"Argument for acsc cannot be 0");
467 mpfr_ui_div(reciprocal.
value, 1,
value, MPFR_RNDN);
468 return reciprocal.
asin();
473 mpfr_prec_t precision =
474 std::max(mpfr_get_prec(y.
value), mpfr_get_prec(x.
value));
525 throw std::domain_error(
"Argument for acosh must be >= 1");
534 throw std::domain_error(
"Argument for atanh must be in range (-1, 1)");
544 throw std::domain_error(
"Argument for acoth must be outside range [-1, 1]");
547 mpfr_ui_div(reciprocal.
value, 1,
value, MPFR_RNDN);
548 return reciprocal.
atanh();
553 throw std::domain_error(
"Argument for asech must be in range (0, 1]");
557 mpfr_ui_div(reciprocal.
value, 1,
value, MPFR_RNDN);
558 return reciprocal.
acosh();
563 throw std::domain_error(
"Argument for acsch cannot be 0");
567 mpfr_ui_div(reciprocal.
value, 1,
value, MPFR_RNDN);
568 return reciprocal.
asinh();
580 if (mpfr_nan_p(
value))
582 if (mpfr_inf_p(
value))
583 return mpfr_sgn(
value) < 0 ?
"-inf" :
"inf";
587 if (mpfr_integer_p(
value)) {
588 mpfr_asprintf(&buf,
"%.0Rf",
value);
594 mpfr_get_str(
nullptr, &exp10, 10, 0,
value, MPFR_RNDN);
595 if (exp10 >= -6 && exp10 <= 6) {
597 mpfr_asprintf(&buf,
"%.17Rf",
value);
599 std::string tmp(buf);
602 while (tmp.size() > 1 && tmp.back() ==
'0')
604 if (!tmp.empty() && tmp.back() ==
'.')
621 return std::stod(str);
626 return std::stof(str);
634 mpfr_get_z(z,
value, MPFR_RNDN);
645 mpfr_get_z(z,
value, MPFR_RNDN);
649 if (mpz_fits_slong_p(z)) {
650 result = mpz_get_si(z);
654 if (mpz_sgn(z) >= 0) {
668 mpfr_prec_round(
value, precision, MPFR_RNDN);
672 return mpfr_get_prec(
value);
685 mpfr_nextbelow(result.
value);
692 mpfr_nextabove(result.
value);
699 return mpfr_inf_p(
value) != 0 && mpfr_sgn(
value) < 0;
703 return mpfr_inf_p(
value) != 0 && mpfr_sgn(
value) > 0;
708 mpz_set(
value.get_mpz_t(), z);
712 return (
const mpz_t *)
value.get_mpz_t();
718 for (
unsigned long i = 2; i <= n; ++i) {
730 for (
unsigned long i = 2; i <= n; ++i) {
741 mpz_gcd(result.
value.get_mpz_t(), a.
value.get_mpz_t(), b.
value.get_mpz_t());
748 mpz_lcm(result.
value.get_mpz_t(), a.
value.get_mpz_t(), b.
value.get_mpz_t());
762 : value(
std::to_string(i)) {}
768 value = mpz_class(s, base);
770 catch (
const std::exception &e) {
771 throw std::invalid_argument(
772 "Cannot convert string to high precision integer");
778 value = mpz_class(s, base);
780 catch (
const std::exception &e) {
781 throw std::invalid_argument(
782 "Cannot convert string to high precision integer");
787 : value(other.value) {}
792 if (
this != &other) {
828 if (other.
value == 0) {
829 throw std::domain_error(
"Division by zero");
838 if (other.
value == 0) {
839 throw std::domain_error(
"Modulo by zero");
866 if (other.
value == 0) {
867 throw std::domain_error(
"Division by zero");
875 if (other.
value == 0) {
876 throw std::domain_error(
"Modulo by zero");
934 mpz_and(result.
value.get_mpz_t(),
value.get_mpz_t(), other.
value.get_mpz_t());
941 mpz_ior(result.
value.get_mpz_t(),
value.get_mpz_t(), other.
value.get_mpz_t());
948 mpz_xor(result.
value.get_mpz_t(),
value.get_mpz_t(), other.
value.get_mpz_t());
954 mpz_com(result.
value.get_mpz_t(),
value.get_mpz_t());
961 mpz_mul_2exp(result.
value.get_mpz_t(),
value.get_mpz_t(), bits);
968 mpz_fdiv_q_2exp(result.
value.get_mpz_t(),
value.get_mpz_t(), bits);
975 mpz_abs(result.
value.get_mpz_t(),
value.get_mpz_t());
981 mpz_pow_ui(result.
value.get_mpz_t(),
value.get_mpz_t(), exp);
987 throw std::domain_error(
"Cannot compute square root of a negative number");
990 mpz_sqrt(result.
value.get_mpz_t(),
value.get_mpz_t());
999 mpz_sqrt(result.
value.get_mpz_t(),
value.get_mpz_t());
1004 throw std::domain_error(
"Cannot compute zeroth root");
1007 throw std::domain_error(
"Cannot compute even root of a negative number");
1010 mpz_root(result.
value.get_mpz_t(),
value.get_mpz_t(), n);
1015 return mpz_probab_prime_p(
value.get_mpz_t(), reps) > 0;
1020 throw std::domain_error(
"Cannot check divisibility by zero");
1022 return mpz_divisible_p(
value.get_mpz_t(), d.
value.get_mpz_t()) != 0;
1027 if (base < 2 || base > 62) {
1028 throw std::invalid_argument(
"Base must be between 2 and 62");
1030 char *str = mpz_get_str(
nullptr, base,
value.get_mpz_t());
1031 std::string result(str);
1038 throw std::overflow_error(
"Value does not fit in int");
1040 return value.get_si();
1044 if (!mpz_fits_slong_p(
value.get_mpz_t())) {
1045 throw std::overflow_error(
"Value does not fit in long");
1047 return value.get_si();
1051 if (
value < 0 || !mpz_fits_ulong_p(
value.get_mpz_t())) {
1052 throw std::overflow_error(
"Value does not fit in unsigned long");
1054 return value.get_ui();
1060 if (mpz_fits_slong_p(
value.get_mpz_t())) {
1061 return value.get_si();
1067 catch (
const std::exception &e) {
1068 throw std::overflow_error(
"Value does not fit in long long");
1135 if (
this != &other) {
1156 throw std::runtime_error(
"Number is not an integer");
1163 throw std::runtime_error(
"Number is not a real");
1306 "Cannot compute modulo of non-integer numbers");
1352 "Cannot compute modulo of non-integer numbers");
1477 catch (
const std::overflow_error &) {
#define condAssert(cond, msg)
HighPrecisionInteger operator+(const HighPrecisionInteger &other) const
HighPrecisionInteger & operator++()
HighPrecisionInteger sqrt() const
HighPrecisionInteger operator|(const HighPrecisionInteger &other) const
bool operator>(const HighPrecisionInteger &other) const
HighPrecisionInteger operator~() const
static HighPrecisionInteger gcd(const HighPrecisionInteger &a, const HighPrecisionInteger &b)
HighPrecisionInteger operator%(const HighPrecisionInteger &other) const
HighPrecisionInteger root(unsigned long n) const
const mpz_class & getMPZ() const
HighPrecisionInteger & operator*=(const HighPrecisionInteger &other)
bool isDivisibleBy(const HighPrecisionInteger &d) const
HighPrecisionInteger & operator+=(const HighPrecisionInteger &other)
HighPrecisionInteger operator&(const HighPrecisionInteger &other) const
bool isProbablePrime(int reps=25) const
HighPrecisionInteger operator^(const HighPrecisionInteger &other) const
HighPrecisionInteger abs() const
HighPrecisionInteger nextBelow() const
bool operator<=(const HighPrecisionInteger &other) const
HighPrecisionInteger operator>>(unsigned long bits) const
HighPrecisionInteger operator<<(unsigned long bits) const
HighPrecisionInteger operator*(const HighPrecisionInteger &other) const
HighPrecisionInteger safeSqrt() const
const mpz_t * get_mpz_t() const
bool operator<(const HighPrecisionInteger &other) const
HighPrecisionInteger & operator%=(const HighPrecisionInteger &other)
unsigned long toULong() const
static HighPrecisionInteger factorial(unsigned long n)
std::string toString(int base=10) const
bool operator==(const HighPrecisionInteger &other) const
HighPrecisionInteger pow(unsigned long exp) const
HighPrecisionInteger & operator--()
HighPrecisionInteger operator-() const
long long toLongLong() const
static HighPrecisionInteger lcm(const HighPrecisionInteger &a, const HighPrecisionInteger &b)
bool operator>=(const HighPrecisionInteger &other) const
HighPrecisionInteger nextAbove() const
HighPrecisionInteger & operator=(const HighPrecisionInteger &other)
static HighPrecisionInteger fibonacci(unsigned long n)
HighPrecisionInteger operator/(const HighPrecisionInteger &other) const
bool operator!=(const HighPrecisionInteger &other) const
HighPrecisionInteger & operator/=(const HighPrecisionInteger &other)
HighPrecisionInteger & operator-=(const HighPrecisionInteger &other)
std::string toString() const
HighPrecisionReal atanh() const
static HighPrecisionReal ln10(mpfr_prec_t precision=128)
HighPrecisionReal safeSqrt() const
HighPrecisionReal ln() const
HighPrecisionReal asinh() const
void setPrecision(mpfr_prec_t precision)
HighPrecisionReal tanh() const
static HighPrecisionReal atan2(const HighPrecisionReal &y, const HighPrecisionReal &x)
HighPrecisionReal acsc() const
HighPrecisionReal sech() const
HighPrecisionReal cot() const
HighPrecisionReal abs() const
HighPrecisionReal acosh() const
HighPrecisionReal & operator+=(const HighPrecisionReal &other)
HighPrecisionReal & operator/=(const HighPrecisionReal &other)
bool operator!=(const HighPrecisionReal &other) const
HighPrecisionReal asech() const
HighPrecisionReal asec() const
HighPrecisionReal & operator=(const HighPrecisionReal &other)
bool operator<(const HighPrecisionReal &other) const
static HighPrecisionReal euler(mpfr_prec_t precision=128)
HighPrecisionReal operator*(const HighPrecisionReal &other) const
static HighPrecisionReal epsilon(mpfr_prec_t precision=128)
HighPrecisionReal acsch() const
HighPrecisionReal acot() const
HighPrecisionReal sqrt() const
bool operator>=(const HighPrecisionReal &other) const
HighPrecisionReal nextAbove() const
long long toLongLong() const
HighPrecisionReal operator+(const HighPrecisionReal &other) const
HighPrecisionReal sec() const
HighPrecisionReal exp() const
static HighPrecisionReal pi(mpfr_prec_t precision=128)
bool operator==(const HighPrecisionReal &other) const
HighPrecisionReal tan() const
bool operator>(const HighPrecisionReal &other) const
bool operator<=(const HighPrecisionReal &other) const
HighPrecisionReal sin() const
static HighPrecisionReal log2_e(mpfr_prec_t precision=128)
HighPrecisionReal & operator-=(const HighPrecisionReal &other)
HighPrecisionReal(mpfr_prec_t precision=128)
HighPrecisionReal ceil() const
HighPrecisionReal acos() const
HighPrecisionReal cos() const
HighPrecisionReal nextBelow() const
HighPrecisionReal floor() const
Integer toInteger() const
bool isPositiveInfinity() const
HighPrecisionReal operator/(const HighPrecisionReal &other) const
HighPrecisionReal csch() const
bool isNegativeInfinity() const
HighPrecisionReal asin() const
static HighPrecisionReal log10_e(mpfr_prec_t precision=128)
HighPrecisionReal atan() const
HighPrecisionReal lg() const
HighPrecisionReal lb() const
HighPrecisionReal & operator*=(const HighPrecisionReal &other)
static HighPrecisionReal phi(mpfr_prec_t precision=128)
HighPrecisionReal pow(const HighPrecisionReal &exp) const
HighPrecisionReal operator-() const
static HighPrecisionReal e(mpfr_prec_t precision=128)
HighPrecisionReal sinh() const
static HighPrecisionReal catalan(mpfr_prec_t precision=128)
HighPrecisionReal csc() const
HighPrecisionReal log(const HighPrecisionReal &base) const
HighPrecisionReal round() const
mpfr_prec_t getPrecision() const
static HighPrecisionReal ln2(mpfr_prec_t precision=128)
HighPrecisionReal coth() const
HighPrecisionReal acoth() const
HighPrecisionReal cosh() const
Number operator%(const Number &other) const
const HighPrecisionInteger & getInteger() const
Number pow(const Number &exp) const
bool operator!=(const Number &other) const
Number & operator%=(const Number &other)
Number & operator+=(const Number &other)
static Number ln10(size_t precision=128)
HighPrecisionInteger intValue
std::string toString() const
Number & operator/=(const Number &other)
HighPrecisionInteger toInteger() const
bool operator>=(const Number &other) const
HighPrecisionReal toReal(mpfr_prec_t precision=128) const
HighPrecisionReal realValue
static Number atan2(const Number &y, const Number &x)
static Number phi(size_t precision=128)
static Number log2_e(size_t precision=128)
bool isPositiveInfinity() const
bool operator<(const Number &other) const
bool operator==(const Number &other) const
bool operator>(const Number &other) const
static Number pi(size_t precision=128)
Number & operator=(const Number &other)
const HighPrecisionReal & getReal() const
Number & operator*=(const Number &other)
Number log(const Number &base) const
bool isNegativeInfinity() const
bool operator<=(const Number &other) const
Number operator+(const Number &other) const
static Number epsilon(size_t precision=128)
Number operator*(const Number &other) const
static Number e(size_t precision=128)
Number & operator-=(const Number &other)
static Number log10_e(size_t precision=128)
static Number ln2(size_t precision=128)
Number operator/(const Number &other) const
static Number positiveInfinity()
static Number negativeInfinity()