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_RANDOM_BY_SIZE_HPP 00021 #define BOOST_INCLUDED_XINT_RANDOM_BY_SIZE_HPP 00022 00023 namespace boost { 00024 namespace xint { 00025 namespace detail { 00027 00028 BOOST_XINT_RAWINT_TPL 00029 template <typename GenType> 00030 BOOST_XINT_RAWINT BOOST_XINT_RAWINT::random_by_size(GenType& _gen, bitsize_t 00031 bits, bool high_bit_on, bool low_bit_on, bool can_be_negative) 00032 { 00033 if (bits == 0) return 0; 00034 00035 // Grab a bunch of bits 00036 random_generator<GenType> gen(_gen); 00037 bitqueue_t bitqueue; 00038 while (bitqueue.size() < bits) bitqueue.push(gen(), 00039 std::numeric_limits<base_random_generator::result_type>::digits); 00040 00041 // Stick them into an integer 00042 BOOST_XINT_RAWINT target; 00043 std::size_t d = bits_to_digits(bits); 00044 digit_t *tdigits = target.digits(d, realloc::ignore); 00045 target.length = (std::min)(d + 1, target.max_length()); 00046 digit_t *pp = tdigits, *ppe = pp + target.length; 00047 while (pp < ppe) *pp++ = static_cast<digit_t>(bitqueue.pop(bits_per_digit)); 00048 00049 // Trim it to the proper length 00050 std::size_t index = (bits / bits_per_digit); 00051 digit_t mask = (digit_t(1) << (bits % bits_per_digit)) - 1; 00052 if (mask == 0) { mask = digit_mask; --index; } 00053 target.length = index + 1; 00054 tdigits[index] &= mask; 00055 for (digit_t *i = tdigits + index + 1, *ie = tdigits + target.length; i < 00056 ie; ++i) *i = 0; 00057 00058 if (high_bit_on) setbit(target, bits - 1); 00059 if (low_bit_on) setbit(target, 0); 00060 target.negative = (can_be_negative && (gen() & 0x01)); 00061 target.trim(); 00062 return target; 00063 } 00064 00066 } // namespace detail 00067 } // namespace xint 00068 } // namespace boost 00069 00070 #endif // BOOST_INCLUDED_XINT_RANDOM_BY_SIZE_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)