00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PPL_math_utilities_inlines_hh
00025 #define PPL_math_utilities_inlines_hh 1
00026
00027 #include "Coefficient.defs.hh"
00028 #include <limits>
00029 #include "assert.hh"
00030
00031 namespace Parma_Polyhedra_Library {
00032
00033 inline void
00034 normalize2(Coefficient_traits::const_reference x,
00035 Coefficient_traits::const_reference y,
00036 Coefficient& nx, Coefficient& ny) {
00037 PPL_DIRTY_TEMP_COEFFICIENT(gcd);
00038 gcd_assign(gcd, x, y);
00039 exact_div_assign(nx, x, gcd);
00040 exact_div_assign(ny, y, gcd);
00041 }
00042
00043 template <typename T>
00044 inline T
00045 low_bits_mask(const unsigned n) {
00046 PPL_ASSERT(n < unsigned(std::numeric_limits<T>::digits));
00047 return n == 0 ? 0 : ~(~(T(0u)) << n);
00048 }
00049
00050 template <typename T>
00051 inline typename Enable_If<Is_Native_Or_Checked<T>::value, void>::type
00052 numer_denom(const T& from,
00053 Coefficient& num, Coefficient& den) {
00054 PPL_ASSERT(!is_not_a_number(from)
00055 && !is_minus_infinity(from)
00056 && !is_plus_infinity(from));
00057 PPL_DIRTY_TEMP0(mpq_class, q);
00058 assign_r(q, from, ROUND_NOT_NEEDED);
00059 num = q.get_num();
00060 den = q.get_den();
00061 }
00062
00063 template <typename T>
00064 inline typename Enable_If<Is_Native_Or_Checked<T>::value, void>::type
00065 div_round_up(T& to,
00066 Coefficient_traits::const_reference x,
00067 Coefficient_traits::const_reference y) {
00068 PPL_DIRTY_TEMP0(mpq_class, qx);
00069 PPL_DIRTY_TEMP0(mpq_class, qy);
00070
00071
00072 assign_r(qx, x, ROUND_NOT_NEEDED);
00073 assign_r(qy, y, ROUND_NOT_NEEDED);
00074 div_assign_r(qx, qx, qy, ROUND_NOT_NEEDED);
00075 assign_r(to, qx, ROUND_UP);
00076 }
00077
00078 template <typename N>
00079 inline void
00080 min_assign(N& x, const N& y) {
00081 if (x > y)
00082 x = y;
00083 }
00084
00085 template <typename N>
00086 inline void
00087 max_assign(N& x, const N& y) {
00088 if (x < y)
00089 x = y;
00090 }
00091
00092 template <typename T>
00093 inline typename Enable_If<Is_Native_Or_Checked<T>::value, bool>::type
00094 is_even(const T& x) {
00095 T mod;
00096 return umod_2exp_assign_r(mod, x, 1, ROUND_DIRECT | ROUND_STRICT_RELATION) == V_EQ
00097 && mod == 0;
00098 }
00099
00100 template <typename T>
00101 inline typename Enable_If<Is_Native_Or_Checked<T>::value, bool>::type
00102 is_additive_inverse(const T& x, const T& y) {
00103 T negated_x;
00104 return neg_assign_r(negated_x, x, ROUND_DIRECT | ROUND_STRICT_RELATION) == V_EQ
00105 && negated_x == y;
00106 }
00107
00108 inline bool
00109 is_canonical(const mpq_class& x) {
00110 if (x.get_den() <= 0)
00111 return false;
00112 PPL_DIRTY_TEMP0(mpq_class, temp);
00113 temp = x;
00114 temp.canonicalize();
00115 return temp.get_num() == x.get_num();
00116 }
00117
00118 }
00119
00120 #endif // !defined(PPL_math_utilities_inlines_hh)