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_LOG2_HPP 00021 #define BOOST_INCLUDED_XINT_LOG2_HPP 00022 00023 namespace boost { 00024 namespace xint { 00025 namespace detail { 00027 00028 inline std::size_t log2_base(boost::uintmax_t n, std::size_t maxbits) { 00029 boost::uintmax_t lo = 0, hi = maxbits; 00030 while (lo < hi) { 00031 boost::uintmax_t s = lo + ((hi - lo) >> 1); 00032 if (n >= (boost::uintmax_t(1) << s)) lo = s + 1; 00033 else hi = s; 00034 } 00035 return std::size_t(lo); 00036 } 00037 00038 template <typename T> 00039 size_t log2_helper(const T n, 00040 typename boost::enable_if<boost::is_unsigned<T> >::type* = 0) 00041 { 00042 return log2_base(n, std::numeric_limits<T>::digits); 00043 } 00044 00045 template <typename T> 00046 size_t log2_helper(const T n, 00047 typename boost::enable_if<boost::is_signed<T> >::type* = 0) 00048 { 00049 typedef typename boost::make_unsigned<T>::type uT; 00050 T nn = (n < 0 ? -n : n); 00051 return log2_base(static_cast<uT>(nn), std::numeric_limits<T>::digits); 00052 } 00053 00054 template <typename T> 00055 size_t log2(const T n, 00056 typename boost::enable_if<boost::is_integral<T> >::type* = 0) 00057 { 00058 return log2_helper(n); 00059 } 00060 00061 BOOST_XINT_RAWINT_TPL 00062 size_t log2(const BOOST_XINT_RAWINT n) { 00063 std::size_t r = bits_per_digit * (n.length - 1); 00064 return r + log2(n[n.length - 1]); 00065 } 00066 00068 } // namespace detail 00069 } // namespace xint 00070 } // namespace boost 00071 00072 #endif // BOOST_INCLUDED_XINT_LOG2_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)