Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77983 - in sandbox/big_number/boost/multiprecision: . detail/functions
From: e_float_at_[hidden]
Date: 2012-04-15 05:27:58


Author: christopher_kormanyos
Date: 2012-04-15 05:27:55 EDT (Sun, 15 Apr 2012)
New Revision: 77983
URL: http://svn.boost.org/trac/boost/changeset/77983

Log:
- Re-factor constants in cpp_dec_float.hpp.
- Tighten up tolerance on multiply, do trivial cleanup in cpp_dec_float.
- Change digit progression in iteration in sqrt and atan.
Text files modified:
   sandbox/big_number/boost/multiprecision/cpp_dec_float.hpp | 74 ++++++++++++++++++++--------------------
   sandbox/big_number/boost/multiprecision/detail/functions/trig.hpp | 4 +-
   2 files changed, 39 insertions(+), 39 deletions(-)

Modified: sandbox/big_number/boost/multiprecision/cpp_dec_float.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/cpp_dec_float.hpp (original)
+++ sandbox/big_number/boost/multiprecision/cpp_dec_float.hpp 2012-04-15 05:27:55 EDT (Sun, 15 Apr 2012)
@@ -36,27 +36,32 @@
    typedef long long exponent_type;
 
 
- static const boost::int32_t mp_radix = 10;
- static const boost::int32_t cpp_dec_float_digits = Digits10;
+ static const boost::int32_t mp_radix = 10;
 
    static const boost::int32_t cpp_dec_float_digits10_setting = Digits10;
    static const boost::int32_t cpp_dec_float_digits10_limit = boost::integer_traits<boost::int32_t>::const_max - 100;
- static const boost::int32_t cpp_dec_float_digits10 = ((cpp_dec_float_digits10_setting < static_cast<boost::int32_t>(30)) ? static_cast<boost::int32_t>(30) : ((cpp_dec_float_digits10_setting > cpp_dec_float_digits10_limit) ? cpp_dec_float_digits10_limit : cpp_dec_float_digits10_setting));
- static const boost::int32_t cpp_dec_float_digits10_extra = static_cast<boost::int32_t>(((static_cast<boost::int64_t>(cpp_dec_float_digits10) * 15LL) + 50LL) / 100LL);
- static const boost::int32_t cpp_dec_float_max_digits10 = static_cast<boost::int32_t>(cpp_dec_float_digits10 + ((cpp_dec_float_digits10_extra < static_cast<boost::int32_t>(5)) ? static_cast<boost::int32_t>(5) : ((cpp_dec_float_digits10_extra > static_cast<boost::int32_t>(30)) ? static_cast<boost::int32_t>(30) : cpp_dec_float_digits10_extra)));
- static const boost::int64_t cpp_dec_float_max_exp10 = 2776234983093287512;
+ static const boost::int32_t cpp_dec_float_digits10 = ((Digits10 < 30) ? 30 : ((Digits10 > cpp_dec_float_digits10_limit) ? cpp_dec_float_digits10_limit : Digits10));
+ static const boost::int64_t cpp_dec_float_max_exp10 = 2776234983093287512;
    static const boost::int64_t cpp_dec_float_min_exp10 = -2776234983093287512;
    static const boost::int64_t cpp_dec_float_max_exp = (cpp_dec_float_max_exp10 / 301LL) * 1000LL;
    static const boost::int64_t cpp_dec_float_min_exp = (cpp_dec_float_min_exp10 / 301LL) * 1000LL;
- static const boost::int32_t mp_elem_digits10 = static_cast<boost::int32_t>(8);
+
+ static const boost::int32_t mp_elem_digits10 = static_cast<boost::int32_t>(8);
 
    BOOST_STATIC_ASSERT(0 == cpp_dec_float_max_exp10 % mp_elem_digits10);
    BOOST_STATIC_ASSERT(cpp_dec_float_max_exp10 == -cpp_dec_float_min_exp10);
 
 private:
- static const boost::int32_t cpp_dec_float_digits10_num_base = static_cast<boost::int32_t>((cpp_dec_float_max_digits10 / mp_elem_digits10) + (((cpp_dec_float_max_digits10 % mp_elem_digits10) != 0) ? 1 : 0));
- static const boost::int32_t mp_elem_number = static_cast<boost::int32_t>(cpp_dec_float_digits10_num_base + 2);
- static const boost::int32_t mp_elem_mask = static_cast<boost::int32_t>(100000000);
+ static const boost::int32_t cpp_dec_float_digits10_num_base = static_cast<boost::int32_t>((cpp_dec_float_digits10 / mp_elem_digits10) + (((cpp_dec_float_digits10 % mp_elem_digits10) != 0) ? 1 : 0));
+
+ // There are three guard limbs.
+ // 1) The first limb has 'play' from 1...8 decimal digits.
+ // 2) The last limb also has 'play' from 1...8 decimal digits.
+ // 3) One limb can get lost when justifying after multiply,
+ // as only half of the triangle is multiplied and a carry
+ // from below is missing.
+ static const boost::int32_t mp_elem_number = static_cast<boost::int32_t>(cpp_dec_float_digits10_num_base + 3);
+ static const boost::int32_t mp_elem_mask = static_cast<boost::int32_t>(100000000);
 
 public:
    static const boost::int32_t cpp_dec_float_total_digits10 = mp_elem_number * mp_elem_digits10;
@@ -181,8 +186,8 @@
       prec_elem(mp_elem_number)
    {
       // TODO: this doesn't round!
- std::copy(f.data.begin(), f.data.begin() + std::min(f.prec_elem, prec_elem), data.begin());
- precision(std::min(f.prec_elem, prec_elem));
+ std::copy(f.data.begin(), f.data.begin() + (std::min)(f.prec_elem, prec_elem), data.begin());
+ precision((std::min)(f.prec_elem, prec_elem));
    }
 
    template <class F>
@@ -215,7 +220,7 @@
    {
       init.do_nothing();
       static bool init = false;
- static const std::string str_max = std::string("9." + std::string(static_cast<std::size_t>(cpp_dec_float_max_digits10), static_cast<char>('9')))
+ static const std::string str_max = std::string("9." + std::string(static_cast<std::size_t>(cpp_dec_float_total_digits10), static_cast<char>('9')))
          + std::string("e+" + boost::lexical_cast<std::string>(cpp_dec_float_max_exp10));
       static cpp_dec_float val_max;
       if(!init)
@@ -327,8 +332,8 @@
       exp = f.exp;
       neg = f.neg;
       fpclass = static_cast<enum_fpclass>(static_cast<int>(f.fpclass));
- std::copy(f.data.begin(), f.data.begin() + std::min(f.prec_elem, prec_elem), data.begin());
- precision(std::min(f.prec_elem, prec_elem));
+ std::copy(f.data.begin(), f.data.begin() + (std::min)(f.prec_elem, prec_elem), data.begin());
+ precision((std::min)(f.prec_elem, prec_elem));
       return *this;
    }
    cpp_dec_float& operator= (long long v)
@@ -431,10 +436,10 @@
    signed long long extract_signed_long_long (void) const;
    unsigned long long extract_unsigned_long_long(void) const;
    void extract_parts (double& mantissa, boost::int64_t& exponent) const;
- cpp_dec_float extract_integer_part (void) const;
+ cpp_dec_float extract_integer_part (void) const;
    void precision(const boost::int32_t prec_digits)
    {
- if(prec_digits >= cpp_dec_float_digits10)
+ if(prec_digits >= cpp_dec_float_total_digits10)
       {
          prec_elem = mp_elem_number;
       }
@@ -525,18 +530,12 @@
 template <unsigned Digits10>
 const boost::int32_t cpp_dec_float<Digits10>::mp_radix;
 template <unsigned Digits10>
-const boost::int32_t cpp_dec_float<Digits10>::cpp_dec_float_digits;
-template <unsigned Digits10>
 const boost::int32_t cpp_dec_float<Digits10>::cpp_dec_float_digits10_setting;
 template <unsigned Digits10>
 const boost::int32_t cpp_dec_float<Digits10>::cpp_dec_float_digits10_limit;
 template <unsigned Digits10>
 const boost::int32_t cpp_dec_float<Digits10>::cpp_dec_float_digits10;
 template <unsigned Digits10>
-const boost::int32_t cpp_dec_float<Digits10>::cpp_dec_float_digits10_extra;
-template <unsigned Digits10>
-const boost::int32_t cpp_dec_float<Digits10>::cpp_dec_float_max_digits10;
-template <unsigned Digits10>
 const boost::int64_t cpp_dec_float<Digits10>::cpp_dec_float_max_exp;
 template <unsigned Digits10>
 const boost::int64_t cpp_dec_float<Digits10>::cpp_dec_float_min_exp;
@@ -855,7 +854,8 @@
 
    boost::array<boost::uint32_t, static_cast<std::size_t>(mp_elem_number + static_cast<boost::int32_t>(1))> w = {{ 0u }};
 
- mul_loop_uv(data.data(), v.data.data(), w.data(), (std::min)(prec_elem, v.prec_elem));
+ const boost::int32_t prec_mul = (std::min)(prec_elem, v.prec_elem);
+ mul_loop_uv(data.data(), v.data.data(), w.data(), prec_mul);
 
    // Copy the multiplication data into the result.
    // Shift the result and adjust the exponent if necessary.
@@ -863,11 +863,11 @@
    {
       exp += static_cast<boost::int64_t>(mp_elem_digits10);
 
- std::copy(w.begin(), w.end() - 1u, data.begin());
+ std::copy(w.begin(), w.begin() + prec_mul, data.begin());
    }
    else
    {
- std::copy(w.begin() + 1u, w.end(), data.begin());
+ std::copy(w.begin() + 1u, w.begin() + (prec_mul + 1), data.begin());
    }
 
    // Set the sign of the result.
@@ -1146,13 +1146,13 @@
    // is used. During the iterative steps, the precision of the calculation is limited
    // to the minimum required in order to minimize the run-time.
 
- static const boost::int32_t double_digits10_minus_one = std::numeric_limits<double>::digits10 - 1;
+ static const boost::int32_t double_digits10_minus_a_few = std::numeric_limits<double>::digits10 - 3;
 
- for(boost::int32_t digits = double_digits10_minus_one; digits <= cpp_dec_float_max_digits10; digits *= static_cast<boost::int32_t>(2))
+ for(boost::int32_t digits = double_digits10_minus_a_few; digits <= cpp_dec_float_total_digits10; digits *= static_cast<boost::int32_t>(2))
    {
       // Adjust precision of the terms.
- precision(static_cast<boost::int32_t>(digits * static_cast<boost::int32_t>(2)));
- x.precision(static_cast<boost::int32_t>(digits * static_cast<boost::int32_t>(2)));
+ precision(static_cast<boost::int32_t>((digits + 10) * static_cast<boost::int32_t>(2)));
+ x.precision(static_cast<boost::int32_t>((digits + 10) * static_cast<boost::int32_t>(2)));
 
       // Next iteration.
       cpp_dec_float t(*this);
@@ -1221,13 +1221,13 @@
    // http://www.jjj.de/pibook/pibook.html
    // http://www.amazon.com/exec/obidos/tg/detail/-/3540665722/qid=1035535482/sr=8-7/ref=sr_8_7/104-3357872-6059916?v=glance&n=507846
 
- static const boost::uint32_t double_digits10_minus_one = std::numeric_limits<double>::digits10 - 1;
+ static const boost::uint32_t double_digits10_minus_a_few = std::numeric_limits<double>::digits10 - 3;
 
- for(boost::int32_t digits = double_digits10_minus_one; digits <= cpp_dec_float_max_digits10; digits *= 2u)
+ for(boost::int32_t digits = double_digits10_minus_a_few; digits <= cpp_dec_float_total_digits10; digits *= 2u)
    {
       // Adjust precision of the terms.
- precision(digits * 2);
- vi.precision(digits * 2);
+ precision((digits + 10) * 2);
+ vi.precision((digits + 10) * 2);
 
       // Next iteration of vi
       cpp_dec_float t(*this);
@@ -1669,7 +1669,7 @@
    boost::intmax_t org_digits(number_of_digits);
    boost::int64_t my_exp = order();
    if(number_of_digits == 0)
- number_of_digits = cpp_dec_float_max_digits10;
+ number_of_digits = cpp_dec_float_total_digits10;
    if(f & std::ios_base::fixed)
    {
       number_of_digits += my_exp + 1;
@@ -2785,7 +2785,7 @@
       long long e2;
       cpp_dec_float<Digits10> r2;
       eval_frexp(r2, result, &e2);
- // overflow prtection:
+ // overflow protection:
       if((t > 0) && (e2 > 0) && (t > (std::numeric_limits<long long>::max)() - e2))
          BOOST_THROW_EXCEPTION(std::runtime_error("Exponent is too large to be represented as a power of 2."));
       if((t < 0) && (e2 < 0) && (t < (std::numeric_limits<long long>::min)() - e2))
@@ -2855,7 +2855,7 @@
       static const bool is_iec559 = false;
       static const int digits = Digits10;
       static const int digits10 = boost::multiprecision::cpp_dec_float<Digits10>::cpp_dec_float_digits10;
- static const int max_digits10 = boost::multiprecision::cpp_dec_float<Digits10>::cpp_dec_float_max_digits10;
+ static const int max_digits10 = boost::multiprecision::cpp_dec_float<Digits10>::cpp_dec_float_digits10 + 1;
       static const boost::int64_t min_exponent = boost::multiprecision::cpp_dec_float<Digits10>::cpp_dec_float_min_exp; // Type differs from int.
       static const boost::int64_t min_exponent10 = boost::multiprecision::cpp_dec_float<Digits10>::cpp_dec_float_min_exp10; // Type differs from int.
       static const boost::int64_t max_exponent = boost::multiprecision::cpp_dec_float<Digits10>::cpp_dec_float_max_exp; // Type differs from int.

Modified: sandbox/big_number/boost/multiprecision/detail/functions/trig.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/functions/trig.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/functions/trig.hpp 2012-04-15 05:27:55 EDT (Sun, 15 Apr 2012)
@@ -653,10 +653,10 @@
    result = fp_type(std::atan(d));
 
    // Newton-Raphson iteration
- static const boost::int32_t double_digits10_minus_one = std::numeric_limits<double>::digits10 - 1;
+ static const boost::int32_t double_digits10_minus_a_few = std::numeric_limits<double>::digits10 - 3;
 
    T s, c, t;
- for(boost::int32_t digits = double_digits10_minus_one; digits <= std::numeric_limits<mp_number<T> >::digits10; digits *= 2)
+ for(boost::int32_t digits = double_digits10_minus_a_few; digits <= std::numeric_limits<mp_number<T> >::digits10; digits *= 2)
    {
       eval_sin(s, result);
       eval_cos(c, result);


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk