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_POWERS_HPP 00021 #define BOOST_INCLUDED_XINT_POWERS_HPP 00022 00023 namespace boost { 00024 namespace xint { 00025 namespace detail { 00027 00028 BOOST_XINT_RAWINT_TPL 00029 void pow(BOOST_XINT_RAWINT& target, const BOOST_XINT_RAWINT n, const 00030 BOOST_XINT_RAWINT e) 00031 { 00032 if (e.is_zero()) { 00033 // Anything to the zeroth power is one. 00034 target.set(1); 00035 return; 00036 } else if (e.negative) { 00037 // Anything to a negative power is a fractional value, which an integer 00038 // library can't represent. 00039 target.set(0); 00040 return; 00041 } 00042 00043 bool neg = (!n.is_zero() && n.negative && e.is_odd()); 00044 00045 std::size_t lastBitCount = 0; 00046 digit_t ee(e[e.length - 1]); 00047 while (ee != 0) { ee >>= 1; ++lastBitCount; } 00048 00049 BOOST_XINT_RAWINT p(n.abs()); 00050 target.set(1); 00051 for (std::size_t eIndex = 0; eIndex < e.length; ++eIndex) { 00052 digit_t eee(e[eIndex]); 00053 00054 int bitCount(int(eIndex == e.length - 1 ? lastBitCount : 00055 bits_per_digit)); 00056 while (bitCount-- > 0) { 00057 if (eee & 0x01) target *= p; 00058 p = square(p); 00059 eee >>= 1; 00060 } 00061 } 00062 target.negative = neg; 00063 target.trim(); 00064 } 00065 00066 BOOST_XINT_RAWINT_TPL void pow2(BOOST_XINT_RAWINT& target, std::size_t exponent) 00067 { 00068 target.set(0); 00069 setbit(target, exponent); 00070 target.trim(); 00071 } 00072 00073 BOOST_XINT_RAWINT_TPL void factorial(BOOST_XINT_RAWINT& target, std::size_t n) { 00074 target.set(1); 00075 00076 BOOST_XINT_RAWINT one(1), nn(n); 00077 while (nn > one) { 00078 target *= nn; 00079 --nn; 00080 } 00081 } 00082 00084 } // namespace detail 00085 } // namespace xint 00086 } // namespace boost 00087 00088 #endif // BOOST_INCLUDED_XINT_POWERS_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)