24 #ifndef PPL_checked_mpq_inlines_hh
25 #define PPL_checked_mpq_inlines_hh 1
35 template <
typename Policy>
38 if ((Policy::has_nan || Policy::has_infinity)
39 && ::
sgn(v.get_den()) == 0) {
40 int s =
::sgn(v.get_num());
41 if (Policy::has_nan && (nan || sign) && s == 0) {
47 if (Policy::has_infinity) {
57 return static_cast<Result>(sgn<Policy>(v));
64 template <typename Policy>
67 return Policy::has_nan
68 &&
::sgn(v.get_den()) == 0
69 && ::
sgn(v.get_num()) == 0;
74 template <typename Policy>
77 return Policy::has_infinity
78 &&
::sgn(v.get_den()) == 0
79 && ::
sgn(v.get_num()) < 0;
84 template <typename Policy>
87 return Policy::has_infinity
88 &&
::sgn(v.get_den()) == 0
89 && ::
sgn(v.get_num()) > 0;
94 template <typename Policy>
97 if ((Policy::has_infinity || Policy::has_nan)
98 && ::
sgn(v.get_den()) == 0) {
99 return !(Policy::has_nan &&
::sgn(v.get_num()) == 0);
102 return v.get_den() == 1;
108 template <typename Policy>
113 if (Policy::has_nan) {
120 if (Policy::has_infinity) {
127 if (Policy::has_infinity) {
143 template <typename To_Policy, typename From_Policy, typename
From>
146 new(&to) mpq_class(from);
161 template <typename To_Policy, typename From_Policy, typename
From>
164 if (is_nan<From_Policy>(from)) {
167 else if (is_minf<From_Policy>(from)) {
170 else if (is_pinf<From_Policy>(from)) {
173 new(&to) mpq_class(from);
192 template <typename To_Policy, typename From_Policy, typename
From>
195 if (is_nan<From_Policy>(from)) {
198 else if (is_minf<From_Policy>(from)) {
201 else if (is_pinf<From_Policy>(from)) {
212 template <typename To_Policy, typename From_Policy, typename
From>
215 if (
sizeof(
From) <=
sizeof(
signed long)) {
216 to =
static_cast<signed long>(from);
219 mpz_ptr m = to.get_num().get_mpz_t();
221 mpz_import(m, 1, 1,
sizeof(
From), 0, 0, &from);
225 mpz_import(m, 1, 1,
sizeof(
From), 0, 0, &n);
235 template <
typename To_Policy,
typename From_Policy,
typename From>
238 if (
sizeof(
From) <=
sizeof(
unsigned long)) {
239 to =
static_cast<unsigned long>(from);
242 mpz_import(to.get_num().get_mpz_t(), 1, 1,
sizeof(
From), 0, 0, &from);
250 template <
typename To_Policy,
typename From_Policy>
253 mpz_fdiv_q(to.get_num().get_mpz_t(),
254 from.get_num().get_mpz_t(), from.get_den().get_mpz_t());
261 template <typename To_Policy, typename From_Policy>
264 mpz_cdiv_q(to.get_num().get_mpz_t(),
265 from.get_num().get_mpz_t(), from.get_den().get_mpz_t());
272 template <typename To_Policy, typename From_Policy>
275 mpz_tdiv_q(to.get_num().get_mpz_t(),
276 from.get_num().get_mpz_t(), from.get_den().get_mpz_t());
283 template <typename To_Policy, typename From_Policy>
286 mpq_neg(to.get_mpq_t(), from.get_mpq_t());
292 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
301 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
310 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
319 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
322 if (
CHECK_P(To_Policy::check_div_zero,
sgn(y) == 0)) {
331 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
334 if (
CHECK_P(To_Policy::check_div_zero,
sgn(y) == 0)) {
338 return trunc<To_Policy, To_Policy>(to, to, dir);
343 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
346 if (
CHECK_P(To_Policy::check_div_zero,
sgn(y) == 0)) {
351 tmp.get_num() %= tmp.get_den();
358 template <typename To_Policy, typename From_Policy>
364 mpz_mul_2exp(v.get_mpz_t(), v.get_mpz_t(), exp);
371 template <typename To_Policy, typename From_Policy>
377 mpz_mul_2exp(v.get_mpz_t(), v.get_mpz_t(), exp);
384 template <typename To_Policy, typename From_Policy>
388 mpz_mul_2exp(to.get_num().get_mpz_t(), x.get_num().get_mpz_t(), exp);
389 to.get_den() = x.get_den();
396 template <typename To_Policy, typename From_Policy>
400 to.get_num() = x.get_num();
401 mpz_mul_2exp(to.get_den().get_mpz_t(), x.get_den().get_mpz_t(), exp);
408 template <typename To_Policy, typename From_Policy>
412 mpz_mul_2exp(to.get_den().get_mpz_t(), x.get_den().get_mpz_t(), exp);
413 mpz_fdiv_r(to.get_num().get_mpz_t(), x.get_num().get_mpz_t(), to.get_den().get_mpz_t());
414 mpz_fdiv_q_2exp(to.get_den().get_mpz_t(), to.get_den().get_mpz_t(), 1);
415 bool neg = to.get_num() >= to.get_den();
416 mpz_mul_2exp(to.get_den().get_mpz_t(), to.get_den().get_mpz_t(), 1);
418 to.get_num() -= to.get_den();
420 mpz_mul_2exp(to.get_num().get_mpz_t(), to.get_num().get_mpz_t(), exp);
427 template <typename To_Policy, typename From_Policy>
431 mpz_mul_2exp(to.get_den().get_mpz_t(), x.get_den().get_mpz_t(), exp);
432 mpz_fdiv_r(to.get_num().get_mpz_t(), x.get_num().get_mpz_t(), to.get_den().get_mpz_t());
433 mpz_mul_2exp(to.get_num().get_mpz_t(), to.get_num().get_mpz_t(), exp);
440 template <typename To_Policy, typename From_Policy>
449 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
459 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
471 template <typename To_Policy, typename From_Policy>
474 if (
CHECK_P(To_Policy::check_sqrt_neg, from < 0)) {
481 bool gt1 = from.get_num() > from.get_den();
482 const mpz_class& from_a = gt1 ? from.get_num() : from.get_den();
483 const mpz_class& from_b = gt1 ? from.get_den() : from.get_num();
484 mpz_class& to_a = gt1 ? to.get_num() : to.get_den();
485 mpz_class& to_b = gt1 ? to.get_den() : to.get_num();
487 mul_2exp<To_Policy, From_Policy>(to_a, from_a,
490 = div<To_Policy, To_Policy, To_Policy>(to_a, to_a, from_b, rdir);
491 Result r_sqrt = sqrt<To_Policy, To_Policy>(to_a, to_a, rdir);
493 mul_2exp<To_Policy, To_Policy>(to_b, to_b,
496 return (r_div !=
V_EQ) ? r_div : r_sqrt;
501 template <typename Policy>
509 return assign_special<Policy>(to,
c, dir);
511 return assign_nan<Policy>(to, r);
519 template <typename Policy>
522 const mpq_class& from,
554 throw std::invalid_argument(
"PPL::set_irrational_precision(p)"
555 " with p > INT_MAX");
561 #endif // !defined(PPL_checked_mpq_inlines_hh)
Result sqrt_mpq(mpq_class &to, const mpq_class &from, Rounding_Dir dir)
#define PPL_SPECIALIZE_NEG(func, To, From)
The computed result is exact.
Taking the square root of a negative number.
Result mul_2exp_mpq(mpq_class &to, const mpq_class &x, unsigned int exp, Rounding_Dir)
bool is_nan_mpq(const mpq_class &v)
bool is_minf_mpq(const mpq_class &v)
#define PPL_SPECIALIZE_ADD_MUL(func, To, From1, From2)
#define PPL_SPECIALIZE_IS_MINF(func, Type)
Result sub_mul_mpq(mpq_class &to, const mpq_class &x, const mpq_class &y, Rounding_Dir)
Result umod_2exp_mpq(mpq_class &to, const mpq_class &x, unsigned int exp, Rounding_Dir)
Rounding_Dir
Rounding directions for arithmetic computations.
#define PPL_SPECIALIZE_SQRT(func, To, From)
void assign_mpq_numeric_float(mpq_class &to, const From from)
Computing a remainder modulo zero.
#define PPL_SPECIALIZE_CLASSIFY(func, Type)
unsigned irrational_precision
Holds the precision parameter used for irrational calculations.
#define PPL_SPECIALIZE_ADD(func, To, From1, From2)
Result
Possible outcomes of a checked arithmetic computation.
Result assign_special_mpq(mpq_class &v, Result_Class c, Rounding_Dir)
The standard C++ namespace.
#define PPL_SPECIALIZE_REM(func, To, From1, From2)
Result trunc_mpq(mpq_class &to, const mpq_class &from, Rounding_Dir)
Negative infinity result class.
bool is_int_mpq(const mpq_class &v)
Not a number result class.
Result smod_2exp_mpq(mpq_class &to, const mpq_class &x, unsigned int exp, Rounding_Dir)
#define PPL_SPECIALIZE_ABS(func, To, From)
Result assign_mpq_unsigned_int(mpq_class &to, const From from, Rounding_Dir)
#define PPL_SPECIALIZE_UMOD_2EXP(func, To, From)
void set_irrational_precision(const unsigned p)
Sets the precision parameter used for irrational calculations.
bool is_pinf_mpq(const mpq_class &v)
The computed result is inexact and rounded down.
#define PPL_SPECIALIZE_TRUNC(func, To, From)
#define PPL_SPECIALIZE_CEIL(func, To, From)
#define PPL_SPECIALIZE_DIV(func, To, From1, From2)
Rounding_Dir inverse(Rounding_Dir dir)
Result ceil_mpq(mpq_class &to, const mpq_class &from, Rounding_Dir)
#define PPL_SPECIALIZE_IDIV(func, To, From1, From2)
Result add_2exp_mpq(mpq_class &to, const mpq_class &x, unsigned int exp, Rounding_Dir)
Result floor_mpq(mpq_class &to, const mpq_class &from, Rounding_Dir)
#define PPL_SPECIALIZE_MUL_2EXP(func, To, From)
Positive infinity result class.
Result rem_mpq(mpq_class &to, const mpq_class &x, const mpq_class &y, Rounding_Dir)
Result_Class result_class(Result r)
The computed result is not representable.
#define PPL_SPECIALIZE_SUB(func, To, From1, From2)
#define PPL_SPECIALIZE_ASSIGN_SPECIAL(func, Type)
Negative infinity result.
Result add_mul_mpq(mpq_class &to, const mpq_class &x, const mpq_class &y, Rounding_Dir)
#define PPL_SPECIALIZE_ADD_2EXP(func, To, From)
Result mul_mpq(mpq_class &to, const mpq_class &x, const mpq_class &y, Rounding_Dir)
Result div_2exp_mpq(mpq_class &to, const mpq_class &x, unsigned int exp, Rounding_Dir)
#define PPL_SPECIALIZE_SUB_MUL(func, To, From1, From2)
Result div_mpq(mpq_class &to, const mpq_class &x, const mpq_class &y, Rounding_Dir)
#define PPL_DIRTY_TEMP(T, id)
Result output_mpq(std::ostream &os, const mpq_class &from, const Numeric_Format &, Rounding_Dir)
Result construct_mpq_base(mpq_class &to, const From &from, Rounding_Dir)
#define PPL_SPECIALIZE_IS_INT(func, Type)
#define PPL_SPECIALIZE_FLOOR(func, To, From)
Result sub_2exp_mpq(mpq_class &to, const mpq_class &x, unsigned int exp, Rounding_Dir)
#define PPL_SPECIALIZE_CONSTRUCT(func, To, From)
Result assign_mpq_float(mpq_class &to, const From &from, Rounding_Dir dir)
Result neg_mpq(mpq_class &to, const mpq_class &from, Rounding_Dir)
Result assign_exact(To &to, const From &from, Rounding_Dir)
The entire library is confined to this namespace.
#define PPL_SPECIALIZE_DIV_2EXP(func, To, From)
Enable_If< Is_Same< To_Policy, From_Policy >::value, void >::type copy_generic(Type &to, const Type &from)
Result sub_mpq(mpq_class &to, const mpq_class &x, const mpq_class &y, Rounding_Dir)
unsigned irrational_precision()
Returns the precision parameter used for irrational calculations.
From bool Type Type Rounding_Dir From
Result input_mpq(mpq_class &to, std::istream &is)
#define PPL_SPECIALIZE_IS_NAN(func, Type)
Result abs_mpq(mpq_class &to, const mpq_class &from, Rounding_Dir)
int sgn(Boundary_Type type, const T &x, const Info &info)
Result idiv_mpq(mpq_class &to, const mpq_class &x, const mpq_class &y, Rounding_Dir dir)
#define PPL_SPECIALIZE_ASSIGN(func, To, From)
Positive infinity result.
Result assign_mpq_signed_int(mpq_class &to, const From from, Rounding_Dir)
#define PPL_SPECIALIZE_SUB_2EXP(func, To, From)
#define PPL_SPECIALIZE_COPY(func, Type)
Result construct_mpq_float(mpq_class &to, const From &from, Rounding_Dir dir)
#define CHECK_P(cond, check)
#define PPL_SPECIALIZE_OUTPUT(func, Type)
The computed result is inexact and rounded up.
The computed result may be inexact.
#define PPL_SPECIALIZE_INPUT(func, Type)
#define PPL_SPECIALIZE_SMOD_2EXP(func, To, From)
#define PPL_SPECIALIZE_MUL(func, To, From1, From2)
Result classify_mpq(const mpq_class &v, bool nan, bool inf, bool sign)
#define PPL_SPECIALIZE_IS_PINF(func, Type)
Result add_mpq(mpq_class &to, const mpq_class &x, const mpq_class &y, Rounding_Dir)