[PPL-devel] [GIT] ppl/ppl(master): Renamed and commented ROUND_STRICT_RELATION. Added some use of it. Added some optimizations when ROUND_NOT_NEEDED is specified.

Abramo Bagnara abramo.bagnara at gmail.com
Fri May 15 16:17:02 CEST 2009


Module: ppl/ppl
Branch: master
Commit: 3ec4eb24ac151c9904f29eeafd583741240650b6
URL:    http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=3ec4eb24ac151c9904f29eeafd583741240650b6

Author: Abramo Bagnara <abramo.bagnara at 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;
       }




More information about the PPL-devel mailing list