[PPL-devel] [GIT] ppl/ppl(master): Documented rational sqrt precision and implemented a more precise variant for numbers < 1.

Abramo Bagnara abramo.bagnara at gmail.com
Sat Mar 28 15:26:05 CET 2009


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

Author: Abramo Bagnara <abramo.bagnara at gmail.com>
Date:   Sat Mar 28 13:59:39 2009 +0100

Documented rational sqrt precision and implemented a more precise variant for numbers < 1.

---

 TODO                       |    2 ++
 src/Init.cc                |    4 ++--
 src/checked_mpq.inlines.hh |   27 +++++++++++++++++----------
 3 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/TODO b/TODO
index 98df6e6..0cff626 100644
--- a/TODO
+++ b/TODO
@@ -12,6 +12,8 @@ Enhancements for PPL 0.10.1 or later versions
 Enhancements for PPL 0.11 or later versions
 ===========================================
 
+- Rename set_rational_sqrt_precision_parameter to
+  set_irrational_precision and make it available on all interfaces.
 - Intervals are best instantiated with checked numbers with
   particular policies: review all the interfaced boxes,
   augment the testsuite, and update the documentation.
diff --git a/src/Init.cc b/src/Init.cc
index 373ed36..dce7393 100644
--- a/src/Init.cc
+++ b/src/Init.cc
@@ -86,8 +86,8 @@ PPL::Init::Init() {
     old_rounding_direction = fpu_get_rounding_direction();
     fpu_set_rounding_direction(round_fpu_dir(ROUND_DIRECT));
 #endif
-    // FIXME(0.10.1): is 3200 a magic number?
-    set_rational_sqrt_precision_parameter(3200);
+    // FIXME(0.10.1): choose a better default
+    set_rational_sqrt_precision_parameter(128);
   }
 }
 
diff --git a/src/checked_mpq.inlines.hh b/src/checked_mpq.inlines.hh
index d613489..c4bfef2 100644
--- a/src/checked_mpq.inlines.hh
+++ b/src/checked_mpq.inlines.hh
@@ -386,16 +386,22 @@ inline Result
 sqrt_mpq(mpq_class& to, const mpq_class& from, Rounding_Dir dir) {
   if (CHECK_P(To_Policy::check_sqrt_neg, from < 0))
     return assign_special<To_Policy>(to, V_SQRT_NEG, ROUND_IGNORE);
-  const unsigned long k = rational_sqrt_precision_parameter;
-  mpz_class& to_num = to.get_num();
-  mul2exp<To_Policy, From_Policy>(to_num, from.get_num(), 2*k, dir);
+  if (from == 0) {
+    to = 0;
+    return V_EQ;
+  }
+  bool gt1 = from.get_num() > from.get_den();
+  const mpz_class& from_a = gt1 ? from.get_num() : from.get_den();
+  const mpz_class& from_b = gt1 ? from.get_den() : from.get_num();
+  mpz_class& to_a = gt1 ? to.get_num() : to.get_den();
+  mpz_class& to_b = gt1 ? to.get_den() : to.get_num();
+  Rounding_Dir rdir = gt1 ? dir : inverse(dir);
+  mul2exp<To_Policy, From_Policy>(to_a, from_a, 2*rational_sqrt_precision_parameter, ROUND_IGNORE);
   Result rdiv
-    = div<To_Policy, To_Policy, To_Policy>(to_num,
-					   to_num, from.get_den(), dir);
-  Result rsqrt = sqrt<To_Policy, To_Policy>(to_num, to_num, dir);
-  mpz_class& to_den = to.get_den();
-  to_den = 1;
-  mul2exp<To_Policy, To_Policy>(to_den, to_den, k, dir);
+    = div<To_Policy, To_Policy, To_Policy>(to_a, to_a, from_b, rdir);
+  Result rsqrt = sqrt<To_Policy, To_Policy>(to_a, to_a, rdir);
+  to_b = 1;
+  mul2exp<To_Policy, To_Policy>(to_b, to_b, rational_sqrt_precision_parameter, ROUND_IGNORE);
   to.canonicalize();
   return rdiv != V_EQ ? rdiv : rsqrt;
 }
@@ -456,7 +462,8 @@ rational_sqrt_precision_parameter() {
 }
 
 //! Sets the precision parameter used for rational square root calculations.
-/*!
+/*! The lesser between numerator and denominator is limited to 2**\p p.
+
   If \p p is less than or equal to <CODE>INT_MAX</CODE>, sets the
   precision parameter used for rational square root calculations to \p p.
 




More information about the PPL-devel mailing list