|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r54348 - sandbox/mp_math/boost/mp_math/integer/detail
From: baraclese_at_[hidden]
Date: 2009-06-25 14:06:14
Author: baraclese
Date: 2009-06-25 14:06:12 EDT (Thu, 25 Jun 2009)
New Revision: 54348
URL: http://svn.boost.org/trac/boost/changeset/54348
Log:
* add missing files
Added:
sandbox/mp_math/boost/mp_math/integer/detail/adder.hpp (contents, props changed)
sandbox/mp_math/boost/mp_math/integer/detail/bitwise_ops.hpp (contents, props changed)
sandbox/mp_math/boost/mp_math/integer/detail/shifter.hpp (contents, props changed)
Added: sandbox/mp_math/boost/mp_math/integer/detail/adder.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/adder.hpp 2009-06-25 14:06:12 EDT (Thu, 25 Jun 2009)
@@ -0,0 +1,185 @@
+// Copyright Tom St Denis 2002 - 2007.
+// Copyright Kevin Sopp 2008 - 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_ADDER_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_ADDER_HPP
+
+#include <stdexcept>
+#include <boost/mp_math/integer/detail/base/adder.hpp>
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+
+
+template<class ApInt, bool IsSigned = ApInt::is_signed>
+struct adder;
+
+
+template<class ApInt>
+struct adder<ApInt, false>
+{
+ typedef ApInt int_type;
+ typedef base::adder<int_type> base_adder_type;
+
+ static void add (ApInt& z, const ApInt& x);
+ static void subtract(ApInt& z, const ApInt& x);
+};
+
+
+template<class ApInt>
+void adder<ApInt, false>::add(ApInt& z, const ApInt& x)
+{
+ const ApInt* a;
+ const ApInt* b;
+
+ // a will point to the number with the most digits
+ if (z.size() > x.size())
+ {
+ a = &z;
+ b = &x;
+ }
+ else
+ {
+ a = &x;
+ b = &z;
+ }
+
+ z.reserve(a->size() + 1);
+
+ base_adder_type::add_smaller_magnitude(z, *a, *b);
+}
+
+template<class ApInt>
+void adder<ApInt, false>::subtract(ApInt& z, const ApInt& x)
+{
+ if (!(z < x)) // means z >= rhs
+ base_adder_type::subtract_smaller_magnitude(z, x);
+ else
+ throw std::runtime_error("adder::subtract: negative result");
+}
+
+
+template<class ApInt>
+struct adder<ApInt, true>
+{
+ typedef ApInt int_type;
+ typedef base::adder<int_type> base_adder_type;
+ typedef typename int_type::magnitude_type magnitude_type;
+ typedef typename int_type::traits_type::ops_type ops_type;
+
+ static void add (ApInt& z, const ApInt& x);
+ static void add_magnitude(ApInt& z, const ApInt& x);
+ static void subtract (ApInt& z, const ApInt& x);
+};
+
+
+template<class ApInt>
+void adder<ApInt, true>::add(ApInt& z, const ApInt& x)
+{
+ if (z.sign_bit() == x.sign_bit())
+ add_magnitude(z, x);
+ else
+ {
+ // Subtract the one with the lesser magnitude from the one of the greater
+ // magnitude. The result gets the sign of the one with the greater
+ // magnitude.
+ const ApInt* a;
+ const ApInt* b;
+
+ // a will point to the number with the most digits
+ if (static_cast<const magnitude_type&>(z) >=
+ static_cast<const magnitude_type&>(x))
+ {
+ a = &z;
+ b = &x;
+ }
+ else
+ {
+ z.reserve(x.size());
+ z.set_sign_bit(x.sign_bit());
+ a = &x;
+ b = &z;
+ }
+
+ ops_type::sub_smaller_magnitude(z.digits(), a->digits(), a->size(),
+ b->digits(), b->size());
+ z.set_size(a->size());
+
+ z.clamp();
+
+ if (!z)
+ z.set_sign_bit(0);
+ }
+}
+
+template<class ApInt>
+void adder<ApInt, true>::add_magnitude(ApInt& z, const ApInt& x)
+{
+ const ApInt* a;
+ const ApInt* b;
+
+ // a will point to the number with the most digits
+ if (z.size() > x.size())
+ {
+ a = &z;
+ b = &x;
+ }
+ else
+ {
+ a = &x;
+ b = &z;
+ }
+
+ z.reserve(a->size() + 1);
+
+ base_adder_type::add_smaller_magnitude(z, *a, *b);
+}
+
+template<class ApInt>
+void adder<ApInt, true>::subtract(ApInt& z, const ApInt& x)
+{
+ if (z.sign_bit() != x.sign_bit())
+ // add magnitudes, and use the sign of z.
+ add_magnitude(z, x);
+ else
+ {
+ const ApInt* a;
+ const ApInt* b;
+ if (static_cast<const magnitude_type&>(z) >=
+ static_cast<const magnitude_type&>(x))
+ {
+ a = &z;
+ b = &x;
+ }
+ else
+ {
+ z.reserve(x.size());
+ // result has opposite sign from z
+ z.set_sign_bit(!z.sign_bit());
+ a = &x;
+ b = &z;
+ }
+
+ ops_type::sub_smaller_magnitude(z.digits(), a->digits(), a->size(),
+ b->digits(), b->size());
+ z.set_size(a->size());
+
+ z.clamp();
+
+ if (!z)
+ z.set_sign_bit(0);
+ }
+}
+
+
+
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Added: sandbox/mp_math/boost/mp_math/integer/detail/bitwise_ops.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/bitwise_ops.hpp 2009-06-25 14:06:12 EDT (Thu, 25 Jun 2009)
@@ -0,0 +1,45 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_BITWISE_OPS_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BITWISE_OPS_HPP
+
+#include <boost/mp_math/integer/detail/base/bitwise_ops.hpp>
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+
+
+template<class ApInt>
+struct bitwise_ops
+{
+ typedef base::bitwise_ops<ApInt> base_bitwise_ops_type;
+
+ static void or_bits (ApInt& z, const ApInt& x, const ApInt& y)
+ {
+ z.reserve(std::max(x.size(), y.size()));
+ base_bitwise_ops_type::or_bits(z, x, y);
+ }
+
+ static void and_bits(ApInt& z, const ApInt& x, const ApInt& y)
+ {
+ z.reserve(std::min(x.size(), y.size()));
+ base_bitwise_ops_type::and_bits(z, x, y);
+ }
+
+ static void xor_bits(ApInt& z, const ApInt& x, const ApInt& y)
+ {
+ z.reserve(std::max(x.size(), y.size()));
+ base_bitwise_ops_type::xor_bits(z, x, y);
+ }
+};
+
+
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
Added: sandbox/mp_math/boost/mp_math/integer/detail/shifter.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/shifter.hpp 2009-06-25 14:06:12 EDT (Thu, 25 Jun 2009)
@@ -0,0 +1,97 @@
+// Copyright Tom St Denis 2002 - 2007.
+// Copyright Kevin Sopp 2008 - 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_SHIFTER_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_SHIFTER_HPP
+
+#include <boost/mp_math/integer/detail/base/divider.hpp>
+#include <boost/mp_math/integer/detail/base/shifter.hpp>
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+
+template<class ApInt>
+struct shifter
+{
+ typedef ApInt int_type;
+ typedef base::shifter<int_type> base_shifter_type;
+ typedef typename int_type::traits_type traits_type;
+ typedef typename traits_type::ops_type ops_type;
+ typedef typename int_type::digit_type digit_type;
+ typedef typename int_type::size_type size_type;
+
+ static void shift_bits_left (ApInt& z, size_type n);
+ static void shift_bits_right(ApInt& z, size_type n)
+ {
+ base_shifter_type::shift_bits_right(z, n);
+ }
+
+ // stores remainder in r
+ static void shift_bits_right(ApInt& z, ApInt& r, size_type n);
+
+ static void shift_digits_left(ApInt& z, size_type n)
+ {
+ z.reserve(z.size() + n);
+ base_shifter_type::shift_digits_left(z, n);
+ }
+
+ static void shift_digits_right(ApInt& z, size_type n)
+ {
+ base_shifter_type::shift_digits_right(z, n);
+ }
+};
+
+
+template<class ApInt>
+void shifter<ApInt>::shift_bits_left(ApInt& z, size_type n)
+{
+ assert(z != digit_type(0));
+
+ if (n)
+ {
+ z.reserve(z.size() + n/traits_type::radix_bits + 1);
+
+ // shift by as many digits in the bit count
+ if (n >= traits_type::radix_bits)
+ base_shifter_type::shift_digits_left(z, n / traits_type::radix_bits);
+
+ // shift any bit count < radix_bits
+ const digit_type b = static_cast<digit_type>(n % traits_type::radix_bits);
+
+ if (b)
+ {
+ const digit_type carry =
+ ops_type::shift_bits_left(z.digits(), z.size(), b);
+
+ if (carry)
+ z.push(carry);
+ }
+ }
+}
+
+template<class ApInt>
+void shifter<ApInt>::shift_bits_right(ApInt& z, ApInt& remainder, size_type n)
+{
+ if (!n)
+ {
+ remainder = digit_type(0);
+ return;
+ }
+
+ remainder = z;
+ base::divider<ApInt>::modulo_pow2(remainder, n);
+
+ base_shifter_type::shift_bits_right(z, n);
+}
+
+
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
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