[GIT] ppl/ppl(master): Renamed and commented ROUND_STRICT_RELATION. Added some use of it. Added some optimizations when ROUND_NOT_NEEDED is specified.
Module: ppl/ppl Branch: master Commit: 3ec4eb24ac151c9904f29eeafd583741240650b6 URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=3ec4eb24ac151... Author: Abramo Bagnara <abramo.bagnara@gmail.com> Date: Fri May 15 16:15:47 2009 +0200 Renamed and commented ROUND_STRICT_RELATION. Added some use of it. Added some optimizations when ROUND_NOT_NEEDED is specified. --- src/Boundary.defs.hh | 2 +- src/Rounding_Dir.defs.hh | 10 +++++++--- src/Rounding_Dir.inlines.hh | 4 ++-- src/checked.inlines.hh | 2 +- src/checked_float.inlines.hh | 6 ++++-- src/checked_mpz.inlines.hh | 30 +++++++++++++++++++++++------- src/intervals.defs.hh | 8 ++++---- 7 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/Boundary.defs.hh b/src/Boundary.defs.hh index 6557099..93a113e 100644 --- a/src/Boundary.defs.hh +++ b/src/Boundary.defs.hh @@ -56,7 +56,7 @@ enum Boundary_Type { inline Rounding_Dir round_dir_check(Boundary_Type t, bool check = false) { if (check) - return static_cast<Rounding_Dir>(t | ROUND_FPU_CHECK_INEXACT); + return static_cast<Rounding_Dir>(t | ROUND_STRICT_RELATION); else return static_cast<Rounding_Dir>(t); } diff --git a/src/Rounding_Dir.defs.hh b/src/Rounding_Dir.defs.hh index 68cb245..540a29e 100644 --- a/src/Rounding_Dir.defs.hh +++ b/src/Rounding_Dir.defs.hh @@ -59,9 +59,13 @@ enum Rounding_Dir { ROUND_DIR_MASK = 7, - ROUND_FPU_CHECK_INEXACT = 8, + /*! \hideinitializer + The client code is willing to pay an extra price to know the exact + relation beetwen the exact result and the computed one. + */ + ROUND_STRICT_RELATION = 8, - ROUND_CHECK = ROUND_DIRECT | ROUND_FPU_CHECK_INEXACT + ROUND_CHECK = ROUND_DIRECT | ROUND_STRICT_RELATION }; /*! \brief @@ -79,7 +83,7 @@ bool round_not_requested(Rounding_Dir dir); bool round_direct(Rounding_Dir dir); bool round_inverse(Rounding_Dir dir); -bool round_fpu_check_inexact(Rounding_Dir dir); +bool round_strict_relation(Rounding_Dir dir); fpu_rounding_direction_type round_fpu_dir(Rounding_Dir dir); diff --git a/src/Rounding_Dir.inlines.hh b/src/Rounding_Dir.inlines.hh index 686f674..45546ae 100644 --- a/src/Rounding_Dir.inlines.hh +++ b/src/Rounding_Dir.inlines.hh @@ -68,8 +68,8 @@ round_inverse(Rounding_Dir dir) { } inline bool -round_fpu_check_inexact(Rounding_Dir dir) { - return dir & ROUND_FPU_CHECK_INEXACT; +round_strict_relation(Rounding_Dir dir) { + return dir & ROUND_STRICT_RELATION; } #if PPL_CAN_CONTROL_FPU diff --git a/src/checked.inlines.hh b/src/checked.inlines.hh index 7e2e664..6627ba7 100644 --- a/src/checked.inlines.hh +++ b/src/checked.inlines.hh @@ -539,7 +539,7 @@ le(const T1& x, const T2& y) { Result r = assign_r(tmp, y, - static_cast<Rounding_Dir>(ROUND_UP | ROUND_FPU_CHECK_INEXACT)); + static_cast<Rounding_Dir>(ROUND_UP | ROUND_STRICT_RELATION)); if (!result_representable(r)) return true; switch (result_relation(r)) { diff --git a/src/checked_float.inlines.hh b/src/checked_float.inlines.hh index f7dc1c2..a245829 100644 --- a/src/checked_float.inlines.hh +++ b/src/checked_float.inlines.hh @@ -281,14 +281,16 @@ round_gt_float(To& to, Rounding_Dir dir) { template <typename Policy> inline void prepare_inexact(Rounding_Dir dir) { - if (Policy::fpu_check_inexact && round_fpu_check_inexact(dir)) + if (Policy::fpu_check_inexact && + !round_not_needed(dir) && round_strict_relation(dir)) fpu_reset_inexact(); } template <typename Policy> inline Result result_relation(Rounding_Dir dir) { - if (Policy::fpu_check_inexact && round_fpu_check_inexact(dir)) { + if (Policy::fpu_check_inexact && + !round_not_needed(dir) && round_strict_relation(dir)) switch (fpu_check_inexact()) { case 0: return V_EQ; diff --git a/src/checked_mpz.inlines.hh b/src/checked_mpz.inlines.hh index 765a848..5ba5433 100644 --- a/src/checked_mpz.inlines.hh +++ b/src/checked_mpz.inlines.hh @@ -311,7 +311,11 @@ PPL_SPECIALIZE_ASSIGN(assign_mpz_long_double, mpz_class, long double) template <typename To_Policy, typename From_Policy> inline Result assign_mpz_mpq(mpz_class& to, const mpq_class& from, Rounding_Dir dir) { - if (round_not_requested(dir)) { + if (round_not_needed(dir)) { + to = from.get_num(); + return V_LGE; + } + if (round_ignore(dir)) { to = from; return V_LGE; } @@ -319,12 +323,16 @@ assign_mpz_mpq(mpz_class& to, const mpq_class& from, Rounding_Dir dir) { mpz_srcptr d = from.get_den().get_mpz_t(); if (round_down(dir)) { mpz_fdiv_q(to.get_mpz_t(), n, d); - return mpz_divisible_p(n, d) ? V_EQ : V_GT; + if (round_strict_relation(dir)) + return mpz_divisible_p(n, d) ? V_EQ : V_GT; + return V_GE; } else { assert(round_up(dir)); mpz_cdiv_q(to.get_mpz_t(), n, d); - return mpz_divisible_p(n, d) ? V_EQ : V_LT; + if (round_strict_relation(dir)) + return mpz_divisible_p(n, d) ? V_EQ : V_LT; + return V_LE; } } @@ -389,12 +397,16 @@ div_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y, } if (round_down(dir)) { mpz_fdiv_q(to.get_mpz_t(), n, d); - return mpz_divisible_p(n, d) ? V_EQ : V_GT; + if (round_strict_relation(dir)) + return mpz_divisible_p(n, d) ? V_EQ : V_GT; + return V_GE; } else { assert(round_up(dir)); mpz_cdiv_q(to.get_mpz_t(), n, d); - return mpz_divisible_p(n, d) ? V_EQ : V_LT; + if (round_strict_relation(dir)) + return mpz_divisible_p(n, d) ? V_EQ : V_LT; + return V_LE; } } @@ -474,12 +486,16 @@ div_2exp_mpz(mpz_class& to, const mpz_class& x, unsigned int exp, } if (round_down(dir)) { mpz_fdiv_q_2exp(to.get_mpz_t(), n, exp); - return mpz_divisible_2exp_p(n, exp) ? V_EQ : V_GT; + if (round_strict_relation(dir)) + return mpz_divisible_2exp_p(n, exp) ? V_EQ : V_GT; + return V_GE; } else { assert(round_up(dir)); mpz_cdiv_q_2exp(to.get_mpz_t(), n, exp); - return mpz_divisible_2exp_p(n, exp) ? V_EQ : V_LT; + if (round_strict_relation(dir)) + return mpz_divisible_2exp_p(n, exp) ? V_EQ : V_LT; + return V_LE; } } diff --git a/src/intervals.defs.hh b/src/intervals.defs.hh index 2cc2dfd..92be62f 100644 --- a/src/intervals.defs.hh +++ b/src/intervals.defs.hh @@ -172,7 +172,7 @@ public: case V_LGE: return r; case V_LE: - r = assign_r(to, c.value(), static_cast<Rounding_Dir>(ROUND_UP | ROUND_FPU_CHECK_INEXACT)); + r = assign_r(to, c.value(), static_cast<Rounding_Dir>(ROUND_UP | ROUND_STRICT_RELATION)); r = result_relation_class(r); if (r == V_EQ) return V_LE; @@ -195,7 +195,7 @@ public: } break; case V_GE: - r = assign_r(to, c.value(), static_cast<Rounding_Dir>(ROUND_DOWN | ROUND_FPU_CHECK_INEXACT)); + r = assign_r(to, c.value(), static_cast<Rounding_Dir>(ROUND_DOWN | ROUND_STRICT_RELATION)); r = result_relation_class(r); if (r == V_EQ) return V_GE; @@ -295,7 +295,7 @@ public: case V_LT: if (is_integer(to)) { rel = sub_assign_r(to, to, T(1), - static_cast<Rounding_Dir>(ROUND_UP | ROUND_FPU_CHECK_INEXACT)); + static_cast<Rounding_Dir>(ROUND_UP | ROUND_STRICT_RELATION)); rel = result_relation_class(rel); return rel == V_EQ ? V_LE : rel; } @@ -308,7 +308,7 @@ public: case V_GT: if (is_integer(to)) { rel = add_assign_r(to, to, T(1), - static_cast<Rounding_Dir>(ROUND_DOWN | ROUND_FPU_CHECK_INEXACT)); + static_cast<Rounding_Dir>(ROUND_DOWN | ROUND_STRICT_RELATION)); rel = result_relation_class(rel); return rel == V_EQ ? V_GE : rel; }
participants (1)
-
Abramo Bagnara