Changeset 83394


Ignore:
Timestamp:
Mar 10, 2013, 11:02:41 AM (6 years ago)
Author:
christopher_kormanyos
Message:

Progress with cpp_bin_float.

Location:
sandbox/big_number/boost/multiprecision
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • sandbox/big_number/boost/multiprecision/cpp_bin_float.hpp

    r83336 r83394  
    1414  #include <boost/math/policies/policy.hpp>
    1515  #include <boost/multiprecision/detail/dynamic_array.hpp>
     16  #include <boost/multiprecision/detail/utype_helper.hpp>
    1617
    1718  namespace boost { namespace multiprecision {
     
    108109    }
    109110
    110     template<class integer_type>
    111     cpp_bin_float(integer_type i,
    112                   typename enable_if<is_unsigned<integer_type> >::type* = 0) : my_data             (),
    113                                                                                my_exp              (static_cast<my_exponent_type>(0)),
    114                                                                                my_neg              (false),
    115                                                                                my_fpclass          (cpp_bin_float_finite),
    116                                                                                my_precision_in_bits(cpp_bin_float_bits_number)
    117     {
    118       from_unsigned_type(i);
     111    template<class unsigned_integer_type>
     112    cpp_bin_float(unsigned_integer_type ui,
     113                  typename enable_if<is_unsigned<unsigned_integer_type> >::type* = 0) : my_data             (),
     114                                                                                        my_exp              (static_cast<my_exponent_type>(0)),
     115                                                                                        my_neg              (false),
     116                                                                                        my_fpclass          (cpp_bin_float_finite),
     117                                                                                        my_precision_in_bits(cpp_bin_float_bits_number)
     118    {
     119      from_unsigned_integer_type(ui);
    119120      round_and_truncate();
    120121    }
    121122
    122     template<class integer_type>
    123     cpp_bin_float(integer_type i,
    124                   typename enable_if<is_signed<integer_type> >::type* = 0) : my_data             (),
    125                                                                              my_exp              (static_cast<my_exponent_type>(0)),
    126                                                                              my_neg              (i < static_cast<integer_type>(0)),
    127                                                                              my_fpclass          (cpp_bin_float_finite),
    128                                                                              my_precision_in_bits(cpp_bin_float_bits_number)
    129     {
     123    template<class signed_integer_type>
     124    cpp_bin_float(signed_integer_type si,
     125                  typename enable_if<is_signed<signed_integer_type> >::type* = 0) : my_data             (),
     126                                                                                    my_exp              (static_cast<my_exponent_type>(0)),
     127                                                                                    my_neg              (si < static_cast<signed_integer_type>(0)),
     128                                                                                    my_fpclass          (cpp_bin_float_finite),
     129                                                                                    my_precision_in_bits(cpp_bin_float_bits_number)
     130    {
     131      typedef typename boost::multiprecision::detail::utype_helper<std::numeric_limits<signed_integer_type>::digits>::exact unsigned_integer_type;
     132
    130133      if(my_neg)
    131134      {
    132         from_unsigned_type(static_cast<eval_ops_unsigned_type>(-i));
     135        from_unsigned_integer_type<unsigned_integer_type>(-si);
    133136      }
    134137      else
    135138      {
    136         from_unsigned_type(static_cast<eval_ops_unsigned_type>(i));
     139        from_unsigned_integer_type<unsigned_integer_type>(si);
    137140      }
    138141
     
    213216      if(my_neg)
    214217      {
    215         from_float_type(static_cast<eval_ops_float_type>(-a));
     218        from_float_type(static_cast<float_type>(-a));
    216219      }
    217220      else
    218221      {
    219         from_float_type(static_cast<eval_ops_float_type>(a));
     222        from_float_type(static_cast<float_type>(a));
    220223      }
    221224
     
    268271                                           my_precision_in_bits(cpp_bin_float_bits_number) { }
    269272
    270     void from_unsigned_type(eval_ops_unsigned_type u)
    271     {
    272       boost::uint_least8_t i = boost::uint_least8_t(0U);
    273 
    274       while(u != eval_ops_unsigned_type(0U))
    275       {
    276         my_data[i] = short_limb_type(u);
    277         ++i;
    278         u >>= std::numeric_limits<short_limb_type>::digits;
    279         my_exp += std::numeric_limits<short_limb_type>::digits;
    280       }
    281 
    282       std::reverse(my_data.begin(), my_data.begin() + i);
    283     }
    284 
    285     void from_float_type(eval_ops_float_type a)
     273    template<class unsigned_integer_type>
     274    void from_unsigned_integer_type(unsigned_integer_type u)
     275    {
     276      if(u <= (std::numeric_limits<short_limb_type>::max)())
     277      {
     278        my_data[0U] = short_limb_type(u);
     279      }
     280      else
     281      {
     282        boost::uint_least8_t i = boost::uint_least8_t(0U);
     283
     284        while(u != unsigned_integer_type(0U))
     285        {
     286          my_data[i] = short_limb_type(u);
     287          ++i;
     288          u >>= std::numeric_limits<short_limb_type>::digits;
     289          my_exp += std::numeric_limits<short_limb_type>::digits;
     290        }
     291
     292        std::reverse(my_data.begin(), my_data.begin() + i);
     293      }
     294    }
     295
     296    template<class float_type>
     297    void from_float_type(float_type a)
    286298    {
    287299      BOOST_MATH_STD_USING // ADL of std names, needed for frexp.
    288300
    289301      int e2;
    290       eval_ops_float_type y = frexp(a, &e2);
     302      float_type y = frexp(a, &e2);
    291303
    292304      my_exp = static_cast<my_exponent_type>(e2);
    293305
    294       boost::uint_least8_t i = boost::uint_least8_t(0U);
    295 
    296       for( ; i < boost::uint_least8_t(std::numeric_limits<eval_ops_float_type>::digits / std::numeric_limits<short_limb_type>::digits); ++i)
    297       {
    298         y *= long_limb_type(long_limb_type(1U) << std::numeric_limits<short_limb_type>::digits);
     306      int delta_exp = int(my_exp % std::numeric_limits<short_limb_type>::digits);
     307
     308      int number_of_digits;
     309
     310      unsigned i = 0U;
     311
     312      if(delta_exp != 0)
     313      {
     314        if(delta_exp > 0)
     315        {
     316          y *= (short_limb_type(1U) << delta_exp);
     317          number_of_digits = delta_exp;
     318          my_exp -= delta_exp;
     319        }
     320        else
     321        {
     322          y *= (short_limb_type(1U) << (std::numeric_limits<short_limb_type>::digits + delta_exp));
     323          number_of_digits = std::numeric_limits<short_limb_type>::digits + delta_exp;
     324          my_exp -= (std::numeric_limits<short_limb_type>::digits + delta_exp);
     325        }
     326
    299327        my_data[i] = static_cast<short_limb_type>(y);
    300328        y -= my_data[i];
    301       }
    302 
    303       if((std::numeric_limits<eval_ops_float_type>::digits % std::numeric_limits<short_limb_type>::digits) != 0)
    304       {
    305         y *= long_limb_type(long_limb_type(1U) << (std::numeric_limits<eval_ops_float_type>::digits % std::numeric_limits<short_limb_type>::digits));
     329        ++i;
     330      }
     331      else
     332      {
     333        number_of_digits = 0U;
     334      }
     335
     336      while(number_of_digits < boost::uint_least16_t(std::numeric_limits<float_type>::digits))
     337      {
     338        if((std::numeric_limits<float_type>::digits - number_of_digits) >= std::numeric_limits<short_limb_type>::digits)
     339        {
     340          y *= long_limb_type(long_limb_type(1U) << std::numeric_limits<short_limb_type>::digits);
     341          number_of_digits += std::numeric_limits<short_limb_type>::digits;
     342        }
     343        else if((std::numeric_limits<float_type>::digits - number_of_digits) > 0)
     344        {
     345          y *= (short_limb_type(1U) << (std::numeric_limits<float_type>::digits - number_of_digits));
     346          number_of_digits += (std::numeric_limits<float_type>::digits - number_of_digits);
     347        }
     348
    306349        my_data[i] = static_cast<short_limb_type>(y);
    307350        y -= my_data[i];
     351        ++i;
    308352      }
    309353    }
  • sandbox/big_number/boost/multiprecision/detail/dynamic_array.hpp

    r83287 r83394  
    11///////////////////////////////////////////////////////////////////////////////
    2 //  Copyright Christopher Kormanyos 2013.
    3 //  Copyright 2012 John Maddock. Distributed under the Boost
     2//  Copyright 2012 John Maddock.
     3//  Copyright Christopher Kormanyos 2013. Distributed under the Boost
    44//  Software License, Version 1.0. (See accompanying file
    55//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  • sandbox/big_number/boost/multiprecision/detail/rebind.hpp

    r83287 r83394  
    11///////////////////////////////////////////////////////////////////////////////
    2 //  Copyright Christopher Kormanyos 2013.
    3 //  Copyright 2012 John Maddock. Distributed under the Boost
     2//  Copyright 2012 John Maddock.
     3//  Copyright Christopher Kormanyos 2013. Distributed under the Boost
    44//  Software License, Version 1.0. (See accompanying file
    55//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Note: See TracChangeset for help on using the changeset viewer.