[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