$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r83401 - in sandbox/big_number/boost/multiprecision: . detail
From: e_float_at_[hidden]
Date: 2013-03-10 15:26:53
Author: christopher_kormanyos
Date: 2013-03-10 15:26:52 EDT (Sun, 10 Mar 2013)
New Revision: 83401
URL: http://svn.boost.org/trac/boost/changeset/83401
Log:
Progress with cpp_bin_float.
Text files modified: 
   sandbox/big_number/boost/multiprecision/cpp_bin_float.hpp       |    74 +++++++++++++++++++++------------------ 
   sandbox/big_number/boost/multiprecision/detail/utype_helper.hpp |    23 ++++++++++++                            
   2 files changed, 63 insertions(+), 34 deletions(-)
Modified: sandbox/big_number/boost/multiprecision/cpp_bin_float.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/cpp_bin_float.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/cpp_bin_float.hpp	2013-03-10 15:26:52 EDT (Sun, 10 Mar 2013)
@@ -83,6 +83,8 @@
     static const boost::uint32_t cpp_bin_float_elem_number =    boost::uint32_t(cpp_bin_float_bits_number / std::numeric_limits<short_limb_type>::digits)
                                                              + (boost::uint32_t(cpp_bin_float_bits_number % std::numeric_limits<short_limb_type>::digits) != boost::uint32_t(0U) ? 1U : 0U);
 
+    // TBD: Right-justify the data in the data array (seems to be standard established by GMP, etc.).
+
     typedef mpl::list<eval_ops_signed_type>   signed_types;
     typedef mpl::list<eval_ops_unsigned_type> unsigned_types;
     typedef mpl::list<eval_ops_float_type>    float_types;
@@ -116,7 +118,7 @@
                                                                                         my_fpclass          (cpp_bin_float_finite),
                                                                                         my_precision_in_bits(cpp_bin_float_bits_number)
     {
-      from_unsigned_integer_type(ui);
+      from_unsigned_integer_type<unsigned_integer_type>(ui);
       round_and_truncate();
     }
 
@@ -170,7 +172,7 @@
                                                                                   my_fpclass          (less_eq_other.my_fpclass),
                                                                                   my_precision_in_bits(less_eq_other.my_precision_in_bits)
     {
-      // TBD: Handle limb types larger and smaller the limb type of *this.
+      // TBD: Handle other limb types both larger and smaller than the limb type of *this.
       std::copy(less_eq_other.my_data.begin(),
                 less_eq_other.my_data.begin() + less_eq_other.cpp_bin_float_elem_number,
                 my_data.begin());
@@ -199,7 +201,7 @@
                                                                                             my_precision_in_bits(cpp_bin_float_bits_number)
     {
       // TBD: Do a proper rounding here.
-      // TBD: Handle limb types both larger and smaller the limb type of *this.
+      // TBD: Handle other limb types both larger and smaller than the limb type of *this.
       std::copy(larger_other.my_data.begin(),
                 larger_other.my_data.begin() + cpp_bin_float_elem_number,
                 my_data.begin());
@@ -219,7 +221,7 @@
       }
       else
       {
-        from_float_type(static_cast<float_type>(a));
+        from_float_type(a);
       }
 
       round_and_truncate();
@@ -281,16 +283,37 @@
       {
         boost::uint_least8_t i = boost::uint_least8_t(0U);
 
-        while(u != unsigned_integer_type(0U))
+        for(;;)
         {
           my_data[i] = short_limb_type(u);
+
           ++i;
+
           u >>= std::numeric_limits<short_limb_type>::digits;
-          my_exp += std::numeric_limits<short_limb_type>::digits;
+
+          if(u != unsigned_integer_type(0U))
+          {
+            my_exp += std::numeric_limits<short_limb_type>::digits;
+          }
+          else
+          {
+            break;
+          }
         }
 
         std::reverse(my_data.begin(), my_data.begin() + i);
       }
+
+      const int priority_bit = boost::multiprecision::detail::utype_prior(my_data[0U]);
+
+      if(priority_bit < (std::numeric_limits<short_limb_type>::digits - 1))
+      {
+        const int shift = std::numeric_limits<short_limb_type>::digits - (1 + priority_bit);
+
+        shift_data_to_the_left(shift);
+
+        my_exp -= shift;
+      }
     }
 
     template<class float_type>
@@ -303,37 +326,11 @@
 
       my_exp = static_cast<my_exponent_type>(e2);
 
-      int delta_exp = int(my_exp % std::numeric_limits<short_limb_type>::digits);
-
       int number_of_digits;
 
-      unsigned i = 0U;
-
-      if(delta_exp != 0)
-      {
-        if(delta_exp > 0)
-        {
-          y *= (short_limb_type(1U) << delta_exp);
-          number_of_digits = delta_exp;
-          my_exp -= delta_exp;
-        }
-        else
-        {
-          y *= (short_limb_type(1U) << (std::numeric_limits<short_limb_type>::digits + delta_exp));
-          number_of_digits = std::numeric_limits<short_limb_type>::digits + delta_exp;
-          my_exp -= (std::numeric_limits<short_limb_type>::digits + delta_exp);
-        }
-
-        my_data[i] = static_cast<short_limb_type>(y);
-        y -= my_data[i];
-        ++i;
-      }
-      else
-      {
-        number_of_digits = 0U;
-      }
+      typename array_type::size_type i(0U);
 
-      while(number_of_digits < boost::uint_least16_t(std::numeric_limits<float_type>::digits))
+      while(number_of_digits < std::numeric_limits<float_type>::digits)
       {
         if((std::numeric_limits<float_type>::digits - number_of_digits) >= std::numeric_limits<short_limb_type>::digits)
         {
@@ -399,6 +396,15 @@
     // TBD: Round and truncate the data.
   }
 
+  void shift_data_to_the_left(const int shift)
+  {
+    // TBD: Shift data to the left.
+  }
+
+  void shift_data_to_the_right(const int shift)
+  {
+    // TBD: Shift data to the right.
+  }
   } // namespace backends
 
   using boost::multiprecision::backends::cpp_bin_float;
Modified: sandbox/big_number/boost/multiprecision/detail/utype_helper.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/utype_helper.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/detail/utype_helper.hpp	2013-03-10 15:26:52 EDT (Sun, 10 Mar 2013)
@@ -8,6 +8,7 @@
 #ifndef BOOST_MP_UTYPE_HELPER_HPP
   #define BOOST_MP_UTYPE_HELPER_HPP
 
+  #include <limits>
   #include <boost/cstdint.hpp>
 
   namespace boost { namespace multiprecision {
@@ -82,6 +83,28 @@
   template<> struct utype_helper<62U> { typedef boost::uint64_t exact; };
   template<> struct utype_helper<63U> { typedef boost::uint64_t exact; };
   template<> struct utype_helper<64U> { typedef boost::uint64_t exact; };
+
+  template<class unsigned_type>
+  int utype_prior(unsigned_type ui)
+  {
+    // TBD: Implement a templated binary search for this.
+    int priority_bit;
+
+    unsigned_type priority_mask = unsigned_type(unsigned_type(1U) << (std::numeric_limits<unsigned_type>::digits - 1));
+
+    for(priority_bit = std::numeric_limits<unsigned_type>::digits - 1; priority_bit >= 0; --priority_bit)
+    {
+      if(unsigned_type(priority_mask & ui) != unsigned_type(0U))
+      {
+        break;
+      }
+
+      priority_mask >>= 1;
+    }
+
+    return priority_bit;
+  }
+
   } } }
 
 #endif // BOOST_MP_UTYPE_HELPER_HPP