00001 00002 /* 00003 The Extended Integer (XInt) Library 00004 A fast, portable C++ library for multi-precision integer math 00005 Copyright 2010 by Chad Nelson 00006 00007 Distributed under the Boost Software License, Version 1.0. 00008 See accompanying file LICENSE_1_0.txt or copy at 00009 http://www.boost.org/LICENSE_1_0.txt 00010 00011 See http://www.boost.org/libs/xint for library home page. 00012 */ 00013 00020 #ifndef BOOST_INCLUDED_XINT_BITFUNCTIONS_HPP 00021 #define BOOST_INCLUDED_XINT_BITFUNCTIONS_HPP 00022 00024 namespace boost { 00025 namespace xint { 00026 namespace detail { 00027 00028 BOOST_XINT_RAWINT_TPL 00029 bool getbit(const BOOST_XINT_RAWINT n, std::size_t bit_index) { 00030 std::size_t index = bit_index / bits_per_digit; 00031 if (index < n.length) { 00032 digit_t mask = (digit_t(1) << (bit_index % bits_per_digit)); 00033 return ((n[index] & mask) != 0); 00034 } else return false; 00035 } 00036 00037 BOOST_XINT_RAWINT_TPL 00038 void setbit(BOOST_XINT_RAWINT& n, std::size_t bit_index) { 00039 if (Bits != 0 && bit_index >= (n.max_length() * bits_per_digit)) return; 00040 std::size_t index = (bit_index / bits_per_digit); 00041 digit_t mask = (digit_t(1) << (bit_index % bits_per_digit)); 00042 n.digits(index + 1, realloc::extend)[index] |= mask; 00043 if (n.length < index + 1) n.length = index + 1; 00044 n.trim(); 00045 } 00046 00047 BOOST_XINT_RAWINT_TPL 00048 void clearbit(BOOST_XINT_RAWINT& n, std::size_t bit_index) { 00049 std::size_t index = (bit_index / bits_per_digit); 00050 if (index >= n.length) return; // Bit can't be set, no need to clear it. 00051 digit_t mask = (digit_t(1) << (bit_index % bits_per_digit)); 00052 n.digits(0)[index] &= ~mask; 00053 n.trim(); 00054 } 00055 00056 BOOST_XINT_RAWINT_TPL 00057 size_t lowestbit(const BOOST_XINT_RAWINT n, std::size_t valueIfZero) { 00058 if (n.is_zero()) return valueIfZero; 00059 00060 const digit_t *d = n.digits(), *p = d, *pe = p + n.length; 00061 while (p != pe && *p == 0) ++p; 00062 std::size_t r = (bits_per_digit * (p - d)); 00063 00064 digit_t digit = *p; 00065 while ((digit & 0x01)==0) { digit >>= 1; ++r; } 00066 00067 return r; 00068 } 00069 00070 BOOST_XINT_RAWINT_TPL 00071 size_t highestbit(const BOOST_XINT_RAWINT n, std::size_t valueIfZero) { 00072 if (n.is_zero()) return valueIfZero; 00073 return ((n.length - 1) * bits_per_digit) + log2(n[n.length - 1]); 00074 } 00075 00076 BOOST_XINT_RAWINT_TPL 00077 BOOST_XINT_RAWINT BOOST_XINT_RAWINT::operator~() const { 00078 if (Bits == 0) { 00079 exception_handler<>::call(__FILE__, __LINE__, 00080 exceptions::too_big("operator~ on unlimited integers results in " 00081 "an infinitely long number.")); 00082 } else { 00083 BOOST_XINT_RAWINT r; 00084 const digit_t *s = digits(), *se = s + length; 00085 digit_t *t = r.digits(r.max_length(), realloc::extend), *te = t + 00086 r.max_length(); 00087 while (s != se) *t++ = ~(*s++); 00088 while (t != te) *t++ = ~digit_t(0); 00089 r.trim(); 00090 return r; 00091 } 00092 } 00093 00094 } // namespace detail 00095 } // namespace xint 00096 } // namespace boost 00098 00099 #endif // BOOST_INCLUDED_XINT_BITFUNCTIONS_HPP
© Copyright Chad Nelson, 2010-2011. 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)