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 00018 #ifndef BOOST_INCLUDED_XINT_INTEGER_HPP 00019 #define BOOST_INCLUDED_XINT_INTEGER_HPP 00020 00021 #include "detail/internals.hpp" 00022 #include "random.hpp" 00023 00024 namespace boost { 00025 namespace xint { 00026 00052 template<BOOST_XINT_INITIAL_APARAMS> 00053 class integer_t: virtual public detail::integer_t_data<BOOST_XINT_APARAMS>, 00054 public detail::nan_functions<detail::integer_t_data<BOOST_XINT_APARAMS>:: 00055 NothrowType::value, integer_t<BOOST_XINT_APARAMS>, BOOST_XINT_APARAMS>, 00056 public detail::fixed_functions<detail::integer_t_data<BOOST_XINT_APARAMS>:: 00057 BitsType::value, integer_t<BOOST_XINT_APARAMS>, BOOST_XINT_APARAMS>, public 00058 detail::unsigned_negative_functions<detail::integer_t_data< 00059 BOOST_XINT_APARAMS>::SignType::value, BOOST_XINT_APARAMS> 00060 { 00061 typedef typename detail::integer_t_data<BOOST_XINT_APARAMS>::BitsType 00062 BitsType; 00063 typedef typename detail::integer_t_data<BOOST_XINT_APARAMS>::SecureType 00064 SecureType; 00065 typedef typename detail::integer_t_data<BOOST_XINT_APARAMS>::SignType 00066 SignType; 00067 typedef typename detail::integer_t_data<BOOST_XINT_APARAMS>::Alloc Alloc; 00068 00069 public: 00070 #ifndef BOOST_XINT_DOXYGEN_IGNORE 00071 typedef integer_t<BOOST_XINT_APARAMS> type; 00072 typedef void (integer_t<BOOST_XINT_APARAMS>::*safe_bool_type)() const; 00073 void this_is_a_safe_bool_type() const { } 00074 00075 typedef typename detail::integer_t_data<BOOST_XINT_APARAMS>::datatype 00076 datatype; 00077 00078 using detail::integer_t_data<BOOST_XINT_APARAMS>::Threadsafe; 00079 using detail::integer_t_data<BOOST_XINT_APARAMS>::Nothrow; 00080 using detail::integer_t_data<BOOST_XINT_APARAMS>::Signed; 00081 00082 using detail::integer_t_data<BOOST_XINT_APARAMS>::data; 00083 using detail::integer_t_data<BOOST_XINT_APARAMS>::_data; 00084 00085 using typename detail::nan_functions<detail::integer_t_data< 00086 BOOST_XINT_APARAMS>::NothrowType::value, integer_t< 00087 BOOST_XINT_APARAMS>, BOOST_XINT_APARAMS>::is_nan; 00088 00089 using typename detail::unsigned_negative_functions<detail::integer_t_data< 00090 BOOST_XINT_APARAMS>::SignType::value, BOOST_XINT_APARAMS>:: 00091 _fix_negative_unsigned; 00092 #endif // BOOST_XINT_DOXYGEN_IGNORE 00093 00096 integer_t(); 00097 integer_t(const integer_t<BOOST_XINT_APARAMS>& b, bool force_thread_safety = 00098 false); 00099 integer_t(BOOST_XINT_RV_REF(type) b) { _swap(b); } 00100 template <typename charT> 00101 explicit integer_t(const charT *str, std::size_t base = 10); 00102 template <typename charT> 00103 integer_t(const charT *str, const charT*& endptr, std::size_t base = 10); 00104 template <typename charT, typename traitsT, typename allocT> 00105 explicit integer_t(const std::basic_string<charT, traitsT, allocT>& str, 00106 std::size_t base = 10); 00107 explicit integer_t(const xint::binary_t b, bitsize_t bits = 0); 00108 template <BOOST_XINT_CLASS_BPARAMS> explicit integer_t(const 00109 integer_t<BOOST_XINT_BPARAMS>& other, bool force_thread_safety = false); 00110 template <typename Type> integer_t(const Type n, typename 00111 boost::enable_if<boost::is_integral<Type> >::type* = 0); 00112 00113 #ifndef BOOST_XINT_DOXYGEN_IGNORE 00114 00115 explicit integer_t(const detail::raw_integer_t<BitsType::value, 00116 SecureType::value, Alloc> c): 00117 detail::integer_t_data<BOOST_XINT_APARAMS>(c) { if (Threadsafe == true) 00118 _data().make_unique(); } 00119 #endif // BOOST_XINT_DOXYGEN_IGNORE 00120 00121 00127 integer_t<BOOST_XINT_APARAMS>& operator=(BOOST_XINT_COPY_ASSIGN_REF(type) 00128 c); 00129 integer_t<BOOST_XINT_APARAMS>& operator=(BOOST_XINT_RV_REF(type) c) { 00130 _swap(c); return *this; } 00131 template <typename Type> integer_t<BOOST_XINT_APARAMS>& operator=(const Type 00132 n) { integer_t<BOOST_XINT_APARAMS> nn(n); _swap(nn); return *this; } 00133 00134 operator safe_bool_type() const { return (data.is_zero() ? 0 : 00135 &integer_t<BOOST_XINT_APARAMS>::this_is_a_safe_bool_type); } 00136 bool operator!() const { return data.is_zero(); } 00137 integer_t<BOOST_XINT_APARAMS> operator-() const; 00138 integer_t<BOOST_XINT_APARAMS>& operator+() { return *this; } 00139 const integer_t<BOOST_XINT_APARAMS>& operator+() const { return *this; } 00140 00141 #ifdef BOOST_XINT_DOXYGEN_IGNORE // inherited, only here for doxygen 00142 integer_t<BOOST_XINT_APARAMS> operator~() const; 00143 #endif 00144 00145 integer_t<BOOST_XINT_APARAMS>& operator+=(const 00146 integer_t<BOOST_XINT_APARAMS> b); 00147 integer_t<BOOST_XINT_APARAMS>& operator-=(const 00148 integer_t<BOOST_XINT_APARAMS> b); 00149 integer_t<BOOST_XINT_APARAMS>& operator*=(const 00150 integer_t<BOOST_XINT_APARAMS> b); 00151 integer_t<BOOST_XINT_APARAMS>& operator/=(const 00152 integer_t<BOOST_XINT_APARAMS> b); 00153 integer_t<BOOST_XINT_APARAMS>& operator%=(const 00154 integer_t<BOOST_XINT_APARAMS> b); 00155 00156 integer_t<BOOST_XINT_APARAMS>& operator++(); 00157 integer_t<BOOST_XINT_APARAMS>& operator--(); 00158 integer_t<BOOST_XINT_APARAMS> operator++(int); 00159 integer_t<BOOST_XINT_APARAMS> operator--(int); 00160 00161 integer_t<BOOST_XINT_APARAMS>& operator&=(const 00162 integer_t<BOOST_XINT_APARAMS> n); 00163 integer_t<BOOST_XINT_APARAMS>& operator|=(const 00164 integer_t<BOOST_XINT_APARAMS> n); 00165 integer_t<BOOST_XINT_APARAMS>& operator^=(const 00166 integer_t<BOOST_XINT_APARAMS> n); 00167 integer_t<BOOST_XINT_APARAMS> operator<<(bitsize_t shift) const; 00168 integer_t<BOOST_XINT_APARAMS> operator>>(bitsize_t shift) const; 00169 integer_t<BOOST_XINT_APARAMS>& operator<<=(bitsize_t shift); 00170 integer_t<BOOST_XINT_APARAMS>& operator>>=(bitsize_t shift); 00172 00175 bool is_odd() const; 00176 bool is_even() const; 00177 int sign(bool signed_zero = false) const; 00178 std::size_t hex_digits() const; 00179 00180 #ifdef BOOST_XINT_DOXYGEN_IGNORE // inherited, only here for doxygen 00181 bool is_nan() const; 00182 #endif 00183 00184 00185 typedef base_divide_t<integer_t<BOOST_XINT_APARAMS> > divide_t; 00186 00194 00195 static integer_t<BOOST_XINT_APARAMS> pow2(std::size_t exponent); 00196 static integer_t<BOOST_XINT_APARAMS> factorial(std::size_t n); 00197 00198 #ifdef BOOST_XINT_DOXYGEN_IGNORE // inherited, only here for doxygen 00199 static integer_t<BOOST_XINT_APARAMS> nan(); 00200 #endif 00201 00202 template <class Type> static integer_t<BOOST_XINT_APARAMS> 00203 random_by_size(Type& gen, bitsize_t size_in_bits, bool high_bit_on = 00204 false, bool low_bit_on = false, bool can_be_negative = false); 00205 template <class Type> static integer_t<BOOST_XINT_APARAMS> 00206 random_prime(Type& gen, bitsize_t size_in_bits, callback_t callback = 00207 no_callback); 00209 00210 #ifndef BOOST_XINT_DOXYGEN_IGNORE 00211 00212 00213 void _swap(integer_t<BOOST_XINT_APARAMS>& s) { using std::swap; 00214 swap(data, s.data); } 00216 #endif 00217 00218 private: 00219 BOOST_XINT_COPYABLE_AND_MOVABLE(type) 00220 }; 00221 00223 // Member function template definitions 00224 00226 template<BOOST_XINT_CLASS_APARAMS> 00227 integer_t<BOOST_XINT_APARAMS>::integer_t() { 00228 // Don't need to do anything, already preinitialized to zero. 00229 } 00230 00241 template<BOOST_XINT_CLASS_APARAMS> 00242 integer_t<BOOST_XINT_APARAMS>::integer_t(const integer_t<BOOST_XINT_APARAMS>& b, 00243 bool force_thread_safety) 00244 { 00245 if (Nothrow) { 00246 BOOST_XINT_TRY { 00247 data = b.data; 00248 if (!data.is_nan()) { 00249 if (force_thread_safety && Threadsafe == false) 00250 data.make_unique(); 00251 } 00252 } BOOST_XINT_CATCH { 00253 data.make_nan(); 00254 } 00255 } else { 00256 data = b.data; 00257 if (force_thread_safety && Threadsafe == false) data.make_unique(); 00258 } 00259 } 00260 00262 template<BOOST_XINT_CLASS_APARAMS> 00263 template <typename charT> 00264 integer_t<BOOST_XINT_APARAMS>::integer_t(const charT *str, std::size_t base) { 00265 if (Nothrow) { 00266 BOOST_XINT_TRY { 00267 const std::basic_string<charT>& tnan = detail::nan_text<charT>(); 00268 if (str[0] == tnan[0] && std::basic_string<charT>(str) == tnan) { 00269 data.make_nan(); 00270 } else { 00271 data.from_string(str, base); 00272 if (!Signed && data.negative) _fix_negative_unsigned(); 00273 } 00274 } BOOST_XINT_CATCH { 00275 data.make_nan(); 00276 } 00277 } else { 00278 data.from_string(str, base); 00279 if (!Signed && data.negative) _fix_negative_unsigned(); 00280 } 00281 } 00282 00311 template<BOOST_XINT_CLASS_APARAMS> 00312 template <typename charT> 00313 integer_t<BOOST_XINT_APARAMS>::integer_t(const charT *str, const charT*& endptr, 00314 std::size_t base) 00315 { 00316 if (Nothrow) { 00317 BOOST_XINT_TRY { 00318 const std::basic_string<charT>& tnan = detail::nan_text<charT>(); 00319 if (str[0] == tnan[0]) { 00320 std::basic_string<charT> s(str); 00321 if (s.substr(0, tnan.length()) == tnan) { 00322 data.make_nan(); 00323 endptr = str + tnan.length(); 00324 return; 00325 } 00326 } 00327 data.from_string(str, endptr, base); 00328 if (!Signed && data.negative) _fix_negative_unsigned(); 00329 } BOOST_XINT_CATCH { 00330 data.make_nan(); 00331 } 00332 } else { 00333 data.from_string(str, endptr, base); 00334 if (!Signed && data.negative) _fix_negative_unsigned(); 00335 } 00336 } 00337 00362 template<BOOST_XINT_CLASS_APARAMS> 00363 template <typename charT, typename traitsT, typename allocT> 00364 integer_t<BOOST_XINT_APARAMS>::integer_t(const std::basic_string<charT, traitsT, 00365 allocT>& str, std::size_t base) 00366 { 00367 if (Nothrow) { 00368 BOOST_XINT_TRY { 00369 if (str == detail::nan_text<charT>()) data.make_nan(); 00370 else { 00371 data.from_string(str, base); 00372 if (!Signed && data.negative) _fix_negative_unsigned(); 00373 } 00374 } BOOST_XINT_CATCH { 00375 data.make_nan(); 00376 } 00377 } else { 00378 data.from_string(str, base); 00379 if (!Signed && data.negative) _fix_negative_unsigned(); 00380 } 00381 } 00382 00404 template<BOOST_XINT_CLASS_APARAMS> 00405 integer_t<BOOST_XINT_APARAMS>::integer_t(const xint::binary_t b, bitsize_t bits) 00406 { 00407 if (Nothrow) { 00408 BOOST_XINT_TRY { 00409 data.from_binary(b, bits); 00410 } BOOST_XINT_CATCH { 00411 data.make_nan(); 00412 } 00413 } else { 00414 data.from_binary(b, bits); 00415 } 00416 } 00417 00430 template<BOOST_XINT_CLASS_APARAMS> 00431 template <BOOST_XINT_CLASS_BPARAMS> 00432 integer_t<BOOST_XINT_APARAMS>::integer_t(const integer_t<BOOST_XINT_BPARAMS>& b, 00433 bool force_thread_safety) 00434 { 00435 if (Nothrow) { 00436 BOOST_XINT_TRY { 00437 if (b.is_nan()) { 00438 data.make_nan(); 00439 } else { 00440 data = b._data(); 00441 if (!data.is_nan()) { 00442 if (force_thread_safety && Threadsafe == false) 00443 data.make_unique(); 00444 if (!Signed && data.negative) _fix_negative_unsigned(); 00445 } 00446 } 00447 } BOOST_XINT_CATCH { 00448 data.make_nan(); 00449 } 00450 } else { 00451 if (b._data().is_nan()) detail::exception_handler<>::call(__FILE__, 00452 __LINE__, exceptions::not_a_number()); 00453 data = b._data(); 00454 if (force_thread_safety && Threadsafe == false) data.make_unique(); 00455 if (!Signed && data.negative) _fix_negative_unsigned(); 00456 } 00457 } 00458 00471 template<BOOST_XINT_CLASS_APARAMS> 00472 template <typename Type> integer_t<BOOST_XINT_APARAMS>::integer_t(const Type n, 00473 typename boost::enable_if<boost::is_integral<Type> >::type*) 00474 { 00475 if (Nothrow) { 00476 BOOST_XINT_TRY { 00477 if (std::numeric_limits<Type>::is_signed) { 00478 data.set_signed(n); 00479 if (!Signed && data.negative) _fix_negative_unsigned(); 00480 } else data.set_unsigned(n); 00481 } BOOST_XINT_CATCH { 00482 data.make_nan(); 00483 } 00484 } else { 00485 if (std::numeric_limits<Type>::is_signed) { 00486 data.set_signed(n); 00487 if (!Signed && data.negative) _fix_negative_unsigned(); 00488 } else data.set_unsigned(n); 00489 } 00490 } 00491 00492 template<BOOST_XINT_CLASS_APARAMS> 00493 integer_t<BOOST_XINT_APARAMS>& integer_t<BOOST_XINT_APARAMS>:: 00494 operator=(BOOST_XINT_COPY_ASSIGN_REF(type) c) 00495 { 00496 if (Nothrow) { 00497 if (c._data().is_nan()) data.make_nan(); 00498 else { 00499 BOOST_XINT_TRY { 00500 data = c.data; 00501 if (Threadsafe == true) data.make_unique(); 00502 } BOOST_XINT_CATCH { 00503 data.make_nan(); 00504 } 00505 } 00506 } else { 00507 data = c.data; 00508 if (Threadsafe == true) data.make_unique(); 00509 } 00510 return *this; 00511 } 00512 00513 #ifdef BOOST_XINT_DOXYGEN_IGNORE // Doesn't really exist, this is here for docs 00514 00530 template<BOOST_XINT_CLASS_APARAMS> 00531 integer_t<BOOST_XINT_APARAMS> integer_t<BOOST_XINT_APARAMS>::operator~() const; 00532 #endif // BOOST_XINT_DOXYGEN_IGNORE 00533 00540 template<BOOST_XINT_CLASS_APARAMS> 00541 integer_t<BOOST_XINT_APARAMS> integer_t<BOOST_XINT_APARAMS>::operator-() const { 00542 if (Nothrow) { 00543 if (is_nan()) return *this; 00544 BOOST_XINT_TRY { 00545 integer_t<BOOST_XINT_APARAMS> r(*this); 00546 if (Threadsafe == true) r._make_unique(); 00547 r.data = -r.data; 00548 if (!Signed && r.data.negative) r._fix_negative_unsigned(); 00549 return BOOST_XINT_MOVE(r); 00550 } BOOST_XINT_CATCH { 00551 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 00552 } 00553 } else { 00554 integer_t<BOOST_XINT_APARAMS> r(*this); 00555 if (Threadsafe == true) r._make_unique(); 00556 r.data = -r.data; 00557 if (!Signed && r.data.negative) r._fix_negative_unsigned(); 00558 return BOOST_XINT_MOVE(r); 00559 } 00560 } 00561 00563 template<BOOST_XINT_CLASS_APARAMS> 00564 integer_t<BOOST_XINT_APARAMS>& integer_t<BOOST_XINT_APARAMS>::operator+=(const 00565 integer_t<BOOST_XINT_APARAMS> b) 00566 { 00567 if (Nothrow) { 00568 if (b.is_nan()) data.make_nan(); 00569 if (!is_nan()) { 00570 BOOST_XINT_TRY { 00571 data += b.data; 00572 if (Threadsafe == true) data.make_unique(); 00573 } BOOST_XINT_CATCH { 00574 data.make_nan(); 00575 } 00576 } 00577 } else { 00578 data += b.data; 00579 if (Threadsafe == true) data.make_unique(); 00580 } 00581 return *this; 00582 } 00583 00585 template<BOOST_XINT_CLASS_APARAMS> 00586 integer_t<BOOST_XINT_APARAMS>& integer_t<BOOST_XINT_APARAMS>::operator-=(const 00587 integer_t<BOOST_XINT_APARAMS> b) 00588 { 00589 if (Nothrow) { 00590 if (b.is_nan()) data.make_nan(); 00591 if (!is_nan()) { 00592 BOOST_XINT_TRY { 00593 data -= b.data; 00594 if (Threadsafe == true) data.make_unique(); 00595 if (!Signed && data.negative) _fix_negative_unsigned(); 00596 } BOOST_XINT_CATCH { 00597 data.make_nan(); 00598 } 00599 } 00600 } else { 00601 data -= b.data; 00602 if (Threadsafe == true) data.make_unique(); 00603 if (!Signed && data.negative) _fix_negative_unsigned(); 00604 } 00605 return *this; 00606 } 00607 00609 template<BOOST_XINT_CLASS_APARAMS> 00610 integer_t<BOOST_XINT_APARAMS>& integer_t<BOOST_XINT_APARAMS>::operator*=(const 00611 integer_t<BOOST_XINT_APARAMS> b) 00612 { 00613 if (Nothrow) { 00614 if (b.is_nan()) data.make_nan(); 00615 if (!is_nan()) { 00616 BOOST_XINT_TRY { 00617 data *= b.data; 00618 if (Threadsafe == true) data.make_unique(); 00619 } BOOST_XINT_CATCH { 00620 data.make_nan(); 00621 } 00622 } 00623 } else { 00624 data *= b.data; 00625 if (Threadsafe == true) data.make_unique(); 00626 } 00627 return *this; 00628 } 00629 00631 template<BOOST_XINT_CLASS_APARAMS> 00632 integer_t<BOOST_XINT_APARAMS>& integer_t<BOOST_XINT_APARAMS>::operator/=(const 00633 integer_t<BOOST_XINT_APARAMS> b) 00634 { 00635 if (Nothrow) { 00636 if (b.is_nan()) data.make_nan(); 00637 if (!is_nan()) { 00638 BOOST_XINT_TRY { 00639 data /= b.data; 00640 if (Threadsafe == true) data.make_unique(); 00641 } BOOST_XINT_CATCH { 00642 data.make_nan(); 00643 } 00644 } 00645 } else { 00646 data /= b.data; 00647 if (Threadsafe == true) data.make_unique(); 00648 } 00649 return *this; 00650 } 00651 00653 template<BOOST_XINT_CLASS_APARAMS> 00654 integer_t<BOOST_XINT_APARAMS>& integer_t<BOOST_XINT_APARAMS>::operator%=(const 00655 integer_t<BOOST_XINT_APARAMS> b) 00656 { 00657 if (Nothrow) { 00658 if (b.is_nan()) data.make_nan(); 00659 if (!is_nan()) { 00660 BOOST_XINT_TRY { 00661 data %= b.data; 00662 if (Threadsafe == true) data.make_unique(); 00663 } BOOST_XINT_CATCH { 00664 data.make_nan(); 00665 } 00666 } 00667 } else { 00668 data %= b.data; 00669 if (Threadsafe == true) data.make_unique(); 00670 } 00671 return *this; 00672 } 00673 00678 template<BOOST_XINT_CLASS_APARAMS> 00679 integer_t<BOOST_XINT_APARAMS>& integer_t<BOOST_XINT_APARAMS>::operator++() { 00680 if (Nothrow) { 00681 if (!is_nan()) { 00682 BOOST_XINT_TRY { 00683 ++data; 00684 if (Threadsafe == true) data.make_unique(); 00685 } BOOST_XINT_CATCH { 00686 data.make_nan(); 00687 } 00688 } 00689 } else { 00690 ++data; 00691 if (Threadsafe == true) data.make_unique(); 00692 } 00693 return *this; 00694 } 00695 00700 template<BOOST_XINT_CLASS_APARAMS> 00701 integer_t<BOOST_XINT_APARAMS>& integer_t<BOOST_XINT_APARAMS>::operator--() { 00702 if (Nothrow) { 00703 if (!is_nan()) { 00704 BOOST_XINT_TRY { 00705 --data; 00706 if (Threadsafe == true) data.make_unique(); 00707 if (!Signed && data.negative) _fix_negative_unsigned(); 00708 } BOOST_XINT_CATCH { 00709 data.make_nan(); 00710 } 00711 } 00712 } else { 00713 --data; 00714 if (Threadsafe == true) data.make_unique(); 00715 if (!Signed && data.negative) _fix_negative_unsigned(); 00716 } 00717 return *this; 00718 } 00719 00727 template<BOOST_XINT_CLASS_APARAMS> 00728 integer_t<BOOST_XINT_APARAMS> integer_t<BOOST_XINT_APARAMS>::operator++(int) { 00729 if (Nothrow) { 00730 if (is_nan()) return *this; 00731 BOOST_XINT_TRY { 00732 integer_t<BOOST_XINT_APARAMS> r(data++); 00733 if (Threadsafe == true) { r._make_unique(); data.make_unique(); } 00734 return BOOST_XINT_MOVE(r); 00735 } BOOST_XINT_CATCH { 00736 data.make_nan(); 00737 } 00738 } else { 00739 integer_t<BOOST_XINT_APARAMS> r(data++); 00740 if (Threadsafe == true) { r._make_unique(); data.make_unique(); } 00741 return BOOST_XINT_MOVE(r); 00742 } 00743 } 00744 00752 template<BOOST_XINT_CLASS_APARAMS> 00753 integer_t<BOOST_XINT_APARAMS> integer_t<BOOST_XINT_APARAMS>::operator--(int) { 00754 if (Nothrow) { 00755 if (is_nan()) return *this; 00756 BOOST_XINT_TRY { 00757 integer_t<BOOST_XINT_APARAMS> r(data--); 00758 if (Threadsafe == true) { r._make_unique(); data.make_unique(); } 00759 if (!Signed && data.negative) _fix_negative_unsigned(); 00760 return BOOST_XINT_MOVE(r); 00761 } BOOST_XINT_CATCH { 00762 data.make_nan(); 00763 } 00764 } else { 00765 integer_t<BOOST_XINT_APARAMS> r(data--); 00766 if (Threadsafe == true) { r._make_unique(); data.make_unique(); } 00767 if (!Signed && data.negative) _fix_negative_unsigned(); 00768 return BOOST_XINT_MOVE(r); 00769 } 00770 } 00771 00773 template<BOOST_XINT_CLASS_APARAMS> 00774 integer_t<BOOST_XINT_APARAMS>& integer_t<BOOST_XINT_APARAMS>::operator&=(const 00775 integer_t<BOOST_XINT_APARAMS> n) 00776 { 00777 if (Nothrow) { 00778 if (n.is_nan()) data.make_nan(); 00779 if (!is_nan()) { 00780 BOOST_XINT_TRY { 00781 data &= n.data; 00782 if (Threadsafe == true) data.make_unique(); 00783 } BOOST_XINT_CATCH { 00784 data.make_nan(); 00785 } 00786 } 00787 } else { 00788 data &= n.data; 00789 if (Threadsafe == true) data.make_unique(); 00790 } 00791 return *this; 00792 } 00793 00795 template<BOOST_XINT_CLASS_APARAMS> 00796 integer_t<BOOST_XINT_APARAMS>& integer_t<BOOST_XINT_APARAMS>::operator|=(const 00797 integer_t<BOOST_XINT_APARAMS> n) 00798 { 00799 if (Nothrow) { 00800 if (n.is_nan()) data.make_nan(); 00801 if (!is_nan()) { 00802 BOOST_XINT_TRY { 00803 data |= n.data; 00804 if (Threadsafe == true) data.make_unique(); 00805 } BOOST_XINT_CATCH { 00806 data.make_nan(); 00807 } 00808 } 00809 } else { 00810 data |= n.data; 00811 if (Threadsafe == true) data.make_unique(); 00812 } 00813 return *this; 00814 } 00815 00817 template<BOOST_XINT_CLASS_APARAMS> 00818 integer_t<BOOST_XINT_APARAMS>& integer_t<BOOST_XINT_APARAMS>::operator^=(const 00819 integer_t<BOOST_XINT_APARAMS> n) 00820 { 00821 if (Nothrow) { 00822 if (n.is_nan()) data.make_nan(); 00823 if (!is_nan()) { 00824 BOOST_XINT_TRY { 00825 data ^= n.data; 00826 if (Threadsafe == true) data.make_unique(); 00827 } BOOST_XINT_CATCH { 00828 data.make_nan(); 00829 } 00830 } 00831 } else { 00832 data ^= n.data; 00833 if (Threadsafe == true) data.make_unique(); 00834 } 00835 return *this; 00836 } 00837 00846 template<BOOST_XINT_CLASS_APARAMS> 00847 integer_t<BOOST_XINT_APARAMS> 00848 integer_t<BOOST_XINT_APARAMS>::operator<<(bitsize_t shift) const { 00849 if (Nothrow) { 00850 if (is_nan()) return *this; 00851 BOOST_XINT_TRY { 00852 integer_t<BOOST_XINT_APARAMS> r(data << shift); 00853 if (Threadsafe == true) r._make_unique(); 00854 return BOOST_XINT_MOVE(r); 00855 } BOOST_XINT_CATCH { 00856 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 00857 } 00858 } else { 00859 integer_t<BOOST_XINT_APARAMS> r(data << shift); 00860 if (Threadsafe == true) r._make_unique(); 00861 return BOOST_XINT_MOVE(r); 00862 } 00863 } 00864 00873 template<BOOST_XINT_CLASS_APARAMS> 00874 integer_t<BOOST_XINT_APARAMS> 00875 integer_t<BOOST_XINT_APARAMS>::operator>>(bitsize_t shift) const { 00876 if (Nothrow) { 00877 if (is_nan()) return *this; 00878 BOOST_XINT_TRY { 00879 integer_t<BOOST_XINT_APARAMS> r(data >> shift); 00880 if (Threadsafe == true) r._make_unique(); 00881 return BOOST_XINT_MOVE(r); 00882 } BOOST_XINT_CATCH { 00883 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 00884 } 00885 } else { 00886 integer_t<BOOST_XINT_APARAMS> r(data >> shift); 00887 if (Threadsafe == true) r._make_unique(); 00888 return BOOST_XINT_MOVE(r); 00889 } 00890 } 00891 00893 template<BOOST_XINT_CLASS_APARAMS> 00894 integer_t<BOOST_XINT_APARAMS>& 00895 integer_t<BOOST_XINT_APARAMS>::operator<<=(bitsize_t shift) { 00896 if (Nothrow) { 00897 if (!is_nan()) { 00898 BOOST_XINT_TRY { 00899 data <<= shift; 00900 if (Threadsafe == true) data.make_unique(); 00901 } BOOST_XINT_CATCH { 00902 data.make_nan(); 00903 } 00904 } 00905 } else { 00906 data <<= shift; 00907 if (Threadsafe == true) data.make_unique(); 00908 } 00909 return *this; 00910 } 00911 00913 template<BOOST_XINT_CLASS_APARAMS> 00914 integer_t<BOOST_XINT_APARAMS>& 00915 integer_t<BOOST_XINT_APARAMS>::operator>>=(bitsize_t shift) { 00916 if (Nothrow) { 00917 if (!is_nan()) { 00918 BOOST_XINT_TRY { 00919 data >>= shift; 00920 if (Threadsafe == true) data.make_unique(); 00921 } BOOST_XINT_CATCH { 00922 data.make_nan(); 00923 } 00924 } 00925 } else { 00926 data >>= shift; 00927 if (Threadsafe == true) data.make_unique(); 00928 } 00929 return *this; 00930 } 00931 00939 template<BOOST_XINT_CLASS_APARAMS> 00940 bool integer_t<BOOST_XINT_APARAMS>::is_odd() const { 00941 if (Nothrow) { 00942 if (is_nan()) return false; 00943 return data.is_odd(); 00944 } else { 00945 return data.is_odd(); 00946 } 00947 } 00948 00956 template<BOOST_XINT_CLASS_APARAMS> 00957 bool integer_t<BOOST_XINT_APARAMS>::is_even() const { 00958 if (Nothrow) { 00959 if (is_nan()) return false; 00960 return data.is_even(); 00961 } else { 00962 return data.is_even(); 00963 } 00964 } 00965 00966 #ifdef BOOST_XINT_DOXYGEN_IGNORE // Doesn't really exist, this is here for docs 00967 00978 template<BOOST_XINT_CLASS_APARAMS> 00979 bool integer_t<BOOST_XINT_APARAMS>::is_nan() const; 00980 #endif // BOOST_XINT_DOXYGEN_IGNORE 00981 00993 template<BOOST_XINT_CLASS_APARAMS> 00994 int integer_t<BOOST_XINT_APARAMS>::sign(bool signed_zero) const { 00995 if (Nothrow) { 00996 if (is_nan()) return 0; 00997 BOOST_XINT_TRY { 00998 return data.sign(signed_zero); 00999 } BOOST_XINT_CATCH { 01000 return 0; 01001 } 01002 } else { 01003 return data.sign(signed_zero); 01004 } 01005 } 01006 01014 template<BOOST_XINT_CLASS_APARAMS> 01015 size_t integer_t<BOOST_XINT_APARAMS>::hex_digits() const { 01016 if (Nothrow) { 01017 if (is_nan()) return 0; 01018 BOOST_XINT_TRY { 01019 return data.hex_digits(); 01020 } BOOST_XINT_CATCH { 01021 return 0; 01022 } 01023 } else { 01024 return data.hex_digits(); 01025 } 01026 } 01027 01041 template<BOOST_XINT_CLASS_APARAMS> 01042 integer_t<BOOST_XINT_APARAMS> integer_t<BOOST_XINT_APARAMS>::pow2(std::size_t 01043 exponent) 01044 { 01045 if (Nothrow) { 01046 BOOST_XINT_TRY { 01047 integer_t<BOOST_XINT_APARAMS> r; 01048 detail::pow2(r.data, exponent); 01049 if (Threadsafe == true) r._make_unique(); 01050 return BOOST_XINT_MOVE(r); 01051 } BOOST_XINT_CATCH { 01052 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01053 } 01054 } else { 01055 integer_t<BOOST_XINT_APARAMS> r; 01056 detail::pow2(r.data, exponent); 01057 if (Threadsafe == true) r._make_unique(); 01058 return BOOST_XINT_MOVE(r); 01059 } 01060 } 01061 01075 template<BOOST_XINT_CLASS_APARAMS> 01076 integer_t<BOOST_XINT_APARAMS> 01077 integer_t<BOOST_XINT_APARAMS>::factorial(std::size_t n) { 01078 if (Nothrow) { 01079 BOOST_XINT_TRY { 01080 integer_t<BOOST_XINT_APARAMS> r; 01081 detail::factorial(r.data, n); 01082 if (Threadsafe == true) r._make_unique(); 01083 return BOOST_XINT_MOVE(r); 01084 } BOOST_XINT_CATCH { 01085 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01086 } 01087 } else { 01088 integer_t<BOOST_XINT_APARAMS> r; 01089 detail::factorial(r.data, n); 01090 if (Threadsafe == true) r._make_unique(); 01091 return BOOST_XINT_MOVE(r); 01092 } 01093 } 01094 01095 #ifdef BOOST_XINT_DOXYGEN_IGNORE // Doesn't really exist, this is here for docs 01096 01107 template<BOOST_XINT_CLASS_APARAMS> 01108 integer_t<BOOST_XINT_APARAMS> integer_t<BOOST_XINT_APARAMS>::nan(); 01109 #endif // BOOST_XINT_DOXYGEN_IGNORE 01110 01135 template<BOOST_XINT_CLASS_APARAMS> 01136 template <class Type> 01137 integer_t<BOOST_XINT_APARAMS>integer_t<BOOST_XINT_APARAMS>::random_by_size(Type& 01138 gen, bitsize_t size_in_bits, bool high_bit_on, bool low_bit_on, bool 01139 can_be_negative) 01140 { 01141 if (!Signed) can_be_negative = false; 01142 if (Nothrow) { 01143 BOOST_XINT_TRY { 01144 return integer_t<BOOST_XINT_APARAMS>(datatype::random_by_size(gen, 01145 size_in_bits, high_bit_on, low_bit_on, can_be_negative)); 01146 } BOOST_XINT_CATCH { 01147 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01148 } 01149 } else { 01150 return integer_t<BOOST_XINT_APARAMS>(datatype::random_by_size(gen, 01151 size_in_bits, high_bit_on, low_bit_on, can_be_negative)); 01152 } 01153 } 01154 01182 template<BOOST_XINT_CLASS_APARAMS> 01183 template <class Type> 01184 integer_t<BOOST_XINT_APARAMS> integer_t<BOOST_XINT_APARAMS>::random_prime(Type& 01185 gen, bitsize_t size_in_bits, callback_t callback) 01186 { 01187 if (Nothrow) { 01188 BOOST_XINT_TRY { 01189 return integer_t<BOOST_XINT_APARAMS>(datatype::random_prime(gen, 01190 size_in_bits, callback)); 01191 } BOOST_XINT_CATCH { 01192 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01193 } 01194 } else { 01195 return integer_t<BOOST_XINT_APARAMS>(datatype::random_prime(gen, 01196 size_in_bits, callback)); 01197 } 01198 } 01199 01201 // Free function template definitions 01207 01208 01217 template<BOOST_XINT_CLASS_APARAMS> 01218 integer_t<BOOST_XINT_APARAMS> abs(const integer_t<BOOST_XINT_APARAMS> n) { 01219 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01220 if (n.is_nan()) 01221 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01222 BOOST_XINT_TRY { 01223 integer_t<BOOST_XINT_APARAMS> r(n._data().abs()); 01224 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) 01225 r._make_unique(); 01226 return BOOST_XINT_MOVE(r); 01227 } BOOST_XINT_CATCH { 01228 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01229 } 01230 } else { 01231 integer_t<BOOST_XINT_APARAMS> r(n._data().abs()); 01232 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) r._make_unique(); 01233 return BOOST_XINT_MOVE(r); 01234 } 01235 } 01236 01255 template<BOOST_XINT_CLASS_APARAMS> 01256 typename integer_t<BOOST_XINT_APARAMS>::divide_t divide(const 01257 integer_t<BOOST_XINT_APARAMS> dividend, const integer_t<BOOST_XINT_APARAMS> 01258 divisor) 01259 { 01260 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01261 if (dividend.is_nan() || divisor.is_nan()) return typename 01262 integer_t<BOOST_XINT_APARAMS>::divide_t(detail::get_nan< 01263 integer_t<BOOST_XINT_APARAMS> >(), detail::get_nan< 01264 integer_t<BOOST_XINT_APARAMS> >()); 01265 BOOST_XINT_TRY { 01266 typename integer_t<BOOST_XINT_APARAMS>::datatype::divide_t rr = 01267 detail::divide(dividend._data(), divisor._data()); 01268 typename integer_t<BOOST_XINT_APARAMS>::divide_t 01269 r(integer_t<BOOST_XINT_APARAMS>(rr.quotient), 01270 integer_t<BOOST_XINT_APARAMS>(rr.remainder)); 01271 return BOOST_XINT_MOVE(r); 01272 } BOOST_XINT_CATCH { 01273 return typename integer_t<BOOST_XINT_APARAMS>::divide_t( 01274 detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(), 01275 detail::get_nan<integer_t<BOOST_XINT_APARAMS> >()); 01276 } 01277 } else { 01278 typename integer_t<BOOST_XINT_APARAMS>::datatype::divide_t rr = 01279 detail::divide(dividend._data(), divisor._data()); 01280 typename integer_t<BOOST_XINT_APARAMS>::divide_t 01281 r(integer_t<BOOST_XINT_APARAMS>(rr.quotient), 01282 integer_t<BOOST_XINT_APARAMS>(rr.remainder)); 01283 return BOOST_XINT_MOVE(r); 01284 } 01285 } 01286 01299 template <BOOST_XINT_CLASS_APARAMS> 01300 integer_t<BOOST_XINT_APARAMS> difference(const integer_t<BOOST_XINT_APARAMS> n1, 01301 const integer_t<BOOST_XINT_APARAMS> n2) 01302 { 01303 typename integer_t<BOOST_XINT_APARAMS>::datatype rdata = n1._data() - 01304 n2._data(); 01305 rdata.negative = false; 01306 return integer_t<BOOST_XINT_APARAMS>(rdata); 01307 } 01309 01315 01316 01328 template<BOOST_XINT_CLASS_APARAMS> 01329 integer_t<BOOST_XINT_APARAMS> square(const integer_t<BOOST_XINT_APARAMS> n) { 01330 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01331 if (n.is_nan()) return n; 01332 BOOST_XINT_TRY { 01333 integer_t<BOOST_XINT_APARAMS> r(detail::square(n._data())); 01334 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) 01335 r._make_unique(); 01336 return BOOST_XINT_MOVE(r); 01337 } BOOST_XINT_CATCH { 01338 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01339 } 01340 } else { 01341 integer_t<BOOST_XINT_APARAMS> r(detail::square(n._data())); 01342 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) r._make_unique(); 01343 return BOOST_XINT_MOVE(r); 01344 } 01345 } 01346 01355 template<BOOST_XINT_CLASS_APARAMS> 01356 integer_t<BOOST_XINT_APARAMS> pow(const integer_t<BOOST_XINT_APARAMS> n, const 01357 integer_t<BOOST_XINT_APARAMS> e) 01358 { 01359 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01360 if (n.is_nan() || e.is_nan()) 01361 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01362 BOOST_XINT_TRY { 01363 integer_t<BOOST_XINT_APARAMS> r; 01364 pow(r._data(), n._data(), e._data()); 01365 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) 01366 r._make_unique(); 01367 return BOOST_XINT_MOVE(r); 01368 } BOOST_XINT_CATCH { 01369 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01370 } 01371 } else { 01372 integer_t<BOOST_XINT_APARAMS> r; 01373 pow(r._data(), n._data(), e._data()); 01374 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) r._make_unique(); 01375 return BOOST_XINT_MOVE(r); 01376 } 01377 } 01378 01391 template<BOOST_XINT_CLASS_APARAMS> 01392 integer_t<BOOST_XINT_APARAMS> square_root(const integer_t<BOOST_XINT_APARAMS> n) 01393 { 01394 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01395 if (n.is_nan()) return n; 01396 BOOST_XINT_TRY { 01397 integer_t<BOOST_XINT_APARAMS> r(square_root(n._data())); 01398 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) 01399 r._make_unique(); 01400 return BOOST_XINT_MOVE(r); 01401 } BOOST_XINT_CATCH { 01402 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01403 } 01404 } else { 01405 integer_t<BOOST_XINT_APARAMS> r(square_root(n._data())); 01406 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) r._make_unique(); 01407 return BOOST_XINT_MOVE(r); 01408 } 01409 } 01411 01417 01418 01431 template <typename T, BOOST_XINT_CLASS_APARAMS> 01432 T to(const integer_t<BOOST_XINT_APARAMS> n) { 01433 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01434 if (n.is_nan()) return T(0); 01435 BOOST_XINT_TRY { 01436 return to<T>(n._data()); 01437 } BOOST_XINT_CATCH { 01438 return T(0); 01439 } 01440 } else { 01441 return to<T>(n._data()); 01442 } 01443 } 01444 01467 template<typename charT, BOOST_XINT_CLASS_APARAMS> 01468 std::basic_string<charT> to_stringtype(const integer_t<BOOST_XINT_APARAMS> n, 01469 std::size_t base = 10, bool uppercase = false) 01470 { 01471 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01472 if (n.is_nan()) return detail::nan_text<charT>(); 01473 BOOST_XINT_TRY { 01474 return detail::to_string<charT>(n._data(), base, uppercase); 01475 } BOOST_XINT_CATCH { 01476 return std::basic_string<charT>(); 01477 } 01478 } else { 01479 return detail::to_string<charT>(n._data(), base, uppercase); 01480 } 01481 } 01482 01486 template<BOOST_XINT_CLASS_APARAMS> 01487 std::string to_string(const integer_t<BOOST_XINT_APARAMS> n, std::size_t base = 01488 10, bool uppercase = false) 01489 { 01490 return to_stringtype<char>(n, base, uppercase); 01491 } 01492 01496 template<BOOST_XINT_CLASS_APARAMS> 01497 std::wstring to_wstring(const integer_t<BOOST_XINT_APARAMS> n, std::size_t base 01498 = 10, bool uppercase = false) 01499 { 01500 return to_stringtype<wchar_t>(n, base, uppercase); 01501 } 01502 01530 template<BOOST_XINT_CLASS_APARAMS> 01531 xint::binary_t to_binary(const integer_t<BOOST_XINT_APARAMS> n, bitsize_t bits = 01532 0) 01533 { 01534 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01535 if (n.is_nan()) return xint::binary_t(); 01536 BOOST_XINT_TRY { 01537 return to_binary(n._data(), bits); 01538 } BOOST_XINT_CATCH { 01539 return xint::binary_t(); 01540 } 01541 } else { 01542 return to_binary(n._data(), bits); 01543 } 01544 } 01546 01549 01560 template<BOOST_XINT_CLASS_APARAMS> 01561 bool getbit(const integer_t<BOOST_XINT_APARAMS> n, bitsize_t bit) { 01562 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01563 if (n.is_nan()) return false; 01564 BOOST_XINT_TRY { 01565 return getbit(n._data(), bit); 01566 } BOOST_XINT_CATCH { 01567 return false; 01568 } 01569 } else { 01570 return getbit(n._data(), bit); 01571 } 01572 } 01573 01583 template<BOOST_XINT_CLASS_APARAMS> 01584 void setbit(integer_t<BOOST_XINT_APARAMS>& n, bitsize_t bit) { 01585 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01586 if (!n.is_nan()) { 01587 BOOST_XINT_TRY { 01588 setbit(n._data(), bit); 01589 } BOOST_XINT_CATCH { 01590 // Do nothing. 01591 } 01592 } 01593 } else { 01594 setbit(n._data(), bit); 01595 } 01596 } 01597 01607 template<BOOST_XINT_CLASS_APARAMS> 01608 void clearbit(integer_t<BOOST_XINT_APARAMS>& n, bitsize_t bit) { 01609 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01610 if (!n.is_nan()) { 01611 BOOST_XINT_TRY { 01612 clearbit(n._data(), bit); 01613 } BOOST_XINT_CATCH { 01614 // Do nothing. 01615 } 01616 } 01617 } else { 01618 clearbit(n._data(), bit); 01619 } 01620 } 01621 01635 template<BOOST_XINT_CLASS_APARAMS> 01636 bitsize_t lowestbit(const integer_t<BOOST_XINT_APARAMS> n, bitsize_t 01637 return_if_zero = 0) 01638 { 01639 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01640 if (n.is_nan()) return return_if_zero; 01641 BOOST_XINT_TRY { 01642 return lowestbit(n._data(), return_if_zero); 01643 } BOOST_XINT_CATCH { 01644 return return_if_zero; 01645 } 01646 } else { 01647 return lowestbit(n._data(), return_if_zero); 01648 } 01649 } 01650 01664 template<BOOST_XINT_CLASS_APARAMS> 01665 bitsize_t highestbit(const integer_t<BOOST_XINT_APARAMS> n, bitsize_t 01666 return_if_zero = 0) 01667 { 01668 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01669 if (n.is_nan()) return return_if_zero; 01670 BOOST_XINT_TRY { 01671 return highestbit(n._data(), return_if_zero); 01672 } BOOST_XINT_CATCH { 01673 return return_if_zero; 01674 } 01675 } else { 01676 return highestbit(n._data(), return_if_zero); 01677 } 01678 } 01680 01689 01690 01705 template<BOOST_XINT_CLASS_APARAMS> 01706 integer_t<BOOST_XINT_APARAMS> mulmod(const integer_t<BOOST_XINT_APARAMS> n, 01707 const integer_t<BOOST_XINT_APARAMS> by, const integer_t<BOOST_XINT_APARAMS> 01708 modulus) 01709 { 01710 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01711 if (n.is_nan() || by.is_nan() || modulus.is_nan()) return 01712 detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01713 BOOST_XINT_TRY { 01714 integer_t<BOOST_XINT_APARAMS> r(mulmod(n._data(), by._data(), 01715 modulus._data())); 01716 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) 01717 r._make_unique(); 01718 return BOOST_XINT_MOVE(r); 01719 } BOOST_XINT_CATCH { 01720 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01721 } 01722 } else { 01723 integer_t<BOOST_XINT_APARAMS> r(mulmod(n._data(), by._data(), 01724 modulus._data())); 01725 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) r._make_unique(); 01726 return BOOST_XINT_MOVE(r); 01727 } 01728 } 01729 01744 template<BOOST_XINT_CLASS_APARAMS> 01745 integer_t<BOOST_XINT_APARAMS> sqrmod(const integer_t<BOOST_XINT_APARAMS> n, 01746 const integer_t<BOOST_XINT_APARAMS> modulus) 01747 { 01748 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01749 if (n.is_nan()) return n; 01750 BOOST_XINT_TRY { 01751 integer_t<BOOST_XINT_APARAMS> r = sqrmod(n._data(), 01752 modulus._data()); 01753 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) 01754 r._make_unique(); 01755 return BOOST_XINT_MOVE(r); 01756 } BOOST_XINT_CATCH { 01757 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01758 } 01759 } else { 01760 integer_t<BOOST_XINT_APARAMS> r = sqrmod(n._data(), modulus._data()); 01761 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) r._make_unique(); 01762 return BOOST_XINT_MOVE(r); 01763 } 01764 } 01765 01789 template<BOOST_XINT_CLASS_APARAMS> 01790 integer_t<BOOST_XINT_APARAMS> powmod(const integer_t<BOOST_XINT_APARAMS> n, 01791 const integer_t<BOOST_XINT_APARAMS> exponent, const 01792 integer_t<BOOST_XINT_APARAMS> modulus, bool no_monty = false) 01793 { 01794 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01795 if (n.is_nan() || exponent.is_nan() || modulus.is_nan()) return 01796 detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01797 BOOST_XINT_TRY { 01798 integer_t<BOOST_XINT_APARAMS> r(powmod(n._data(), exponent._data(), 01799 modulus._data(), no_monty)); 01800 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) 01801 r._make_unique(); 01802 return BOOST_XINT_MOVE(r); 01803 } BOOST_XINT_CATCH { 01804 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01805 } 01806 } else { 01807 integer_t<BOOST_XINT_APARAMS> r(powmod(n._data(), exponent._data(), 01808 modulus._data(), no_monty)); 01809 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) r._make_unique(); 01810 return BOOST_XINT_MOVE(r); 01811 } 01812 } 01813 01826 template<BOOST_XINT_CLASS_APARAMS> 01827 integer_t<BOOST_XINT_APARAMS> invmod(const integer_t<BOOST_XINT_APARAMS> n, 01828 const integer_t<BOOST_XINT_APARAMS> modulus) 01829 { 01830 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01831 if (n.is_nan() || modulus.is_nan()) return 01832 detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01833 BOOST_XINT_TRY { 01834 integer_t<BOOST_XINT_APARAMS> r(invmod(n._data(), modulus._data())); 01835 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) 01836 r._make_unique(); 01837 return BOOST_XINT_MOVE(r); 01838 } BOOST_XINT_CATCH { 01839 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 01840 } 01841 } else { 01842 integer_t<BOOST_XINT_APARAMS> r(invmod(n._data(), modulus._data())); 01843 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) r._make_unique(); 01844 return BOOST_XINT_MOVE(r); 01845 } 01846 } 01848 01854 01855 01880 template<BOOST_XINT_CLASS_APARAMS> 01881 int is_prime(const integer_t<BOOST_XINT_APARAMS> n, callback_t callback = 01882 no_callback) 01883 { 01884 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01885 if (n.is_nan()) return -2; 01886 BOOST_XINT_TRY { 01887 return is_prime(n._data(), callback); 01888 } BOOST_XINT_CATCH { 01889 return -2; 01890 } 01891 } else { 01892 return is_prime(n._data(), callback); 01893 } 01894 } 01896 01903 01904 template<BOOST_XINT_CLASS_APARAMS> bool operator<(const 01905 integer_t<BOOST_XINT_APARAMS> n1, const integer_t<BOOST_XINT_APARAMS> n2) 01906 { 01907 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01908 if (n1.is_nan() || n2.is_nan()) return false; 01909 BOOST_XINT_TRY { 01910 return operator<(n1._data(), n2._data()); 01911 } BOOST_XINT_CATCH { 01912 return false; 01913 } 01914 } else { 01915 return operator<(n1._data(), n2._data()); 01916 } 01917 } 01918 01919 template<BOOST_XINT_CLASS_APARAMS> bool operator>(const 01920 integer_t<BOOST_XINT_APARAMS> n1, const integer_t<BOOST_XINT_APARAMS> n2) 01921 { 01922 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01923 if (n1.is_nan() || n2.is_nan()) return false; 01924 BOOST_XINT_TRY { 01925 return operator>(n1._data(), n2._data()); 01926 } BOOST_XINT_CATCH { 01927 return false; 01928 } 01929 } else { 01930 return operator>(n1._data(), n2._data()); 01931 } 01932 } 01933 01934 template<BOOST_XINT_CLASS_APARAMS> bool operator<=(const 01935 integer_t<BOOST_XINT_APARAMS> n1, const integer_t<BOOST_XINT_APARAMS> n2) 01936 { 01937 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01938 if (n1.is_nan() || n2.is_nan()) return false; 01939 BOOST_XINT_TRY { 01940 return operator<=(n1._data(), n2._data()); 01941 } BOOST_XINT_CATCH { 01942 return false; 01943 } 01944 } else { 01945 return operator<=(n1._data(), n2._data()); 01946 } 01947 } 01948 01949 template<BOOST_XINT_CLASS_APARAMS> bool operator>=(const 01950 integer_t<BOOST_XINT_APARAMS> n1, const integer_t<BOOST_XINT_APARAMS> n2) 01951 { 01952 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01953 if (n1.is_nan() || n2.is_nan()) return false; 01954 BOOST_XINT_TRY { 01955 return operator>=(n1._data(), n2._data()); 01956 } BOOST_XINT_CATCH { 01957 return false; 01958 } 01959 } else { 01960 return operator>=(n1._data(), n2._data()); 01961 } 01962 } 01963 01964 template<BOOST_XINT_CLASS_APARAMS> bool operator==(const 01965 integer_t<BOOST_XINT_APARAMS> n1, const integer_t<BOOST_XINT_APARAMS> n2) 01966 { 01967 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01968 if (n1.is_nan() || n2.is_nan()) return false; 01969 BOOST_XINT_TRY { 01970 return operator==(n1._data(), n2._data()); 01971 } BOOST_XINT_CATCH { 01972 return false; 01973 } 01974 } else { 01975 return operator==(n1._data(), n2._data()); 01976 } 01977 } 01978 01979 template<BOOST_XINT_CLASS_APARAMS> bool operator!=(const 01980 integer_t<BOOST_XINT_APARAMS> n1, const integer_t<BOOST_XINT_APARAMS> n2) 01981 { 01982 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 01983 if (n1.is_nan() || n2.is_nan()) return false; 01984 BOOST_XINT_TRY { 01985 return operator!=(n1._data(), n2._data()); 01986 } BOOST_XINT_CATCH { 01987 return false; 01988 } 01989 } else { 01990 return operator!=(n1._data(), n2._data()); 01991 } 01992 } 01994 01999 02000 02009 template<BOOST_XINT_CLASS_APARAMS> 02010 integer_t<BOOST_XINT_APARAMS> operator+(const integer_t<BOOST_XINT_APARAMS> n1, 02011 const integer_t<BOOST_XINT_APARAMS> n2) 02012 { 02013 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 02014 if (n1.is_nan() || n2.is_nan()) 02015 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02016 BOOST_XINT_TRY { 02017 integer_t<BOOST_XINT_APARAMS> r(n1._data() + n2._data()); 02018 return BOOST_XINT_MOVE(r); 02019 } BOOST_XINT_CATCH { 02020 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02021 } 02022 } else { 02023 integer_t<BOOST_XINT_APARAMS> r(n1._data() + n2._data()); 02024 return BOOST_XINT_MOVE(r); 02025 } 02026 } 02027 02036 template<BOOST_XINT_CLASS_APARAMS> 02037 integer_t<BOOST_XINT_APARAMS> operator-(const integer_t<BOOST_XINT_APARAMS> n1, 02038 const integer_t<BOOST_XINT_APARAMS> n2) 02039 { 02040 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 02041 if (n1.is_nan() || n2.is_nan()) 02042 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02043 BOOST_XINT_TRY { 02044 integer_t<BOOST_XINT_APARAMS> r(n1._data() - n2._data()); 02045 if (!integer_t<BOOST_XINT_APARAMS>::Signed && r._data().negative) 02046 r._fix_negative_unsigned(); 02047 return BOOST_XINT_MOVE(r); 02048 } BOOST_XINT_CATCH { 02049 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02050 } 02051 } else { 02052 integer_t<BOOST_XINT_APARAMS> r(n1._data() - n2._data()); 02053 if (!integer_t<BOOST_XINT_APARAMS>::Signed && r._data().negative) 02054 r._fix_negative_unsigned(); 02055 return BOOST_XINT_MOVE(r); 02056 } 02057 } 02058 02071 template<BOOST_XINT_CLASS_APARAMS> 02072 integer_t<BOOST_XINT_APARAMS> operator*(const integer_t<BOOST_XINT_APARAMS> n1, 02073 const integer_t<BOOST_XINT_APARAMS> n2) 02074 { 02075 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 02076 if (n1.is_nan() || n2.is_nan()) 02077 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02078 BOOST_XINT_TRY { 02079 integer_t<BOOST_XINT_APARAMS> r(n1._data() * n2._data()); 02080 return BOOST_XINT_MOVE(r); 02081 } BOOST_XINT_CATCH { 02082 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02083 } 02084 } else { 02085 integer_t<BOOST_XINT_APARAMS> r(n1._data() * n2._data()); 02086 return BOOST_XINT_MOVE(r); 02087 } 02088 } 02089 02100 template<BOOST_XINT_CLASS_APARAMS> 02101 integer_t<BOOST_XINT_APARAMS> operator/(const integer_t<BOOST_XINT_APARAMS> 02102 dividend, const integer_t<BOOST_XINT_APARAMS> divisor) 02103 { 02104 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 02105 if (dividend.is_nan() || divisor.is_nan()) return 02106 detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02107 BOOST_XINT_TRY { 02108 integer_t<BOOST_XINT_APARAMS> r(dividend._data() / divisor._data()); 02109 return BOOST_XINT_MOVE(r); 02110 } BOOST_XINT_CATCH { 02111 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02112 } 02113 } else { 02114 integer_t<BOOST_XINT_APARAMS> r(dividend._data() / divisor._data()); 02115 return BOOST_XINT_MOVE(r); 02116 } 02117 } 02118 02128 template<BOOST_XINT_CLASS_APARAMS> 02129 integer_t<BOOST_XINT_APARAMS> operator%(const integer_t<BOOST_XINT_APARAMS> n1, 02130 const integer_t<BOOST_XINT_APARAMS> n2) 02131 { 02132 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 02133 if (n1.is_nan() || n2.is_nan()) 02134 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02135 BOOST_XINT_TRY { 02136 integer_t<BOOST_XINT_APARAMS> r(n1._data() % n2._data()); 02137 return BOOST_XINT_MOVE(r); 02138 } BOOST_XINT_CATCH { 02139 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02140 } 02141 } else { 02142 integer_t<BOOST_XINT_APARAMS> r(n1._data() % n2._data()); 02143 return BOOST_XINT_MOVE(r); 02144 } 02145 } 02146 02156 template<BOOST_XINT_CLASS_APARAMS> 02157 integer_t<BOOST_XINT_APARAMS> operator&(const integer_t<BOOST_XINT_APARAMS> n1, 02158 const integer_t<BOOST_XINT_APARAMS> n2) 02159 { 02160 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 02161 if (n1.is_nan() || n2.is_nan()) 02162 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02163 BOOST_XINT_TRY { 02164 integer_t<BOOST_XINT_APARAMS> r(n1._data() & n2._data()); 02165 return BOOST_XINT_MOVE(r); 02166 } BOOST_XINT_CATCH { 02167 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02168 } 02169 } else { 02170 integer_t<BOOST_XINT_APARAMS> r(n1._data() & n2._data()); 02171 return BOOST_XINT_MOVE(r); 02172 } 02173 } 02174 02184 template<BOOST_XINT_CLASS_APARAMS> 02185 integer_t<BOOST_XINT_APARAMS> operator|(const integer_t<BOOST_XINT_APARAMS> n1, 02186 const integer_t<BOOST_XINT_APARAMS> n2) 02187 { 02188 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 02189 if (n1.is_nan() || n2.is_nan()) 02190 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02191 BOOST_XINT_TRY { 02192 integer_t<BOOST_XINT_APARAMS> r(n1._data() | n2._data()); 02193 return BOOST_XINT_MOVE(r); 02194 } BOOST_XINT_CATCH { 02195 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02196 } 02197 } else { 02198 integer_t<BOOST_XINT_APARAMS> r(n1._data() | n2._data()); 02199 return BOOST_XINT_MOVE(r); 02200 } 02201 } 02202 02212 template<BOOST_XINT_CLASS_APARAMS> 02213 integer_t<BOOST_XINT_APARAMS> operator^(const integer_t<BOOST_XINT_APARAMS> n1, 02214 const integer_t<BOOST_XINT_APARAMS> n2) 02215 { 02216 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 02217 if (n1.is_nan() || n2.is_nan()) 02218 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02219 BOOST_XINT_TRY { 02220 integer_t<BOOST_XINT_APARAMS> r(n1._data() ^ n2._data()); 02221 return BOOST_XINT_MOVE(r); 02222 } BOOST_XINT_CATCH { 02223 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02224 } 02225 } else { 02226 integer_t<BOOST_XINT_APARAMS> r(n1._data() ^ n2._data()); 02227 return BOOST_XINT_MOVE(r); 02228 } 02229 } 02231 02234 02244 template<BOOST_XINT_CLASS_APARAMS> 02245 integer_t<BOOST_XINT_APARAMS> gcd(const integer_t<BOOST_XINT_APARAMS> num1, 02246 const integer_t<BOOST_XINT_APARAMS> num2) 02247 { 02248 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 02249 if (num1.is_nan() || num2.is_nan()) return 02250 detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02251 BOOST_XINT_TRY { 02252 integer_t<BOOST_XINT_APARAMS> r; 02253 gcd(r._data(), num1._data(), num2._data()); 02254 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) 02255 r._make_unique(); 02256 return BOOST_XINT_MOVE(r); 02257 } BOOST_XINT_CATCH { 02258 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02259 } 02260 } else { 02261 integer_t<BOOST_XINT_APARAMS> r; 02262 gcd(r._data(), num1._data(), num2._data()); 02263 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) r._make_unique(); 02264 return BOOST_XINT_MOVE(r); 02265 } 02266 } 02267 02278 template<BOOST_XINT_CLASS_APARAMS> 02279 integer_t<BOOST_XINT_APARAMS> lcm(const integer_t<BOOST_XINT_APARAMS> num1, 02280 const integer_t<BOOST_XINT_APARAMS> num2) 02281 { 02282 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 02283 if (num1.is_nan() || num2.is_nan()) return 02284 detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02285 BOOST_XINT_TRY { 02286 integer_t<BOOST_XINT_APARAMS> r; 02287 lcm(r._data(), num1._data(), num2._data()); 02288 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) 02289 r._make_unique(); 02290 return BOOST_XINT_MOVE(r); 02291 } BOOST_XINT_CATCH { 02292 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02293 } 02294 } else { 02295 integer_t<BOOST_XINT_APARAMS> r; 02296 lcm(r._data(), num1._data(), num2._data()); 02297 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) r._make_unique(); 02298 return BOOST_XINT_MOVE(r); 02299 } 02300 } 02301 02314 template<BOOST_XINT_CLASS_APARAMS> 02315 int compare(const integer_t<BOOST_XINT_APARAMS> n1, const 02316 integer_t<BOOST_XINT_APARAMS> n2, bool ignoresign = false) 02317 { 02318 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 02319 if (n1.is_nan() || n2.is_nan()) return 2; 02320 BOOST_XINT_TRY { 02321 return compare(n1._data(), n2._data(), ignoresign); 02322 } BOOST_XINT_CATCH { 02323 return 2; 02324 } 02325 } else { 02326 return compare(n1._data(), n2._data(), ignoresign); 02327 } 02328 } 02329 02346 template<BOOST_XINT_CLASS_APARAMS> 02347 size_t log2(const integer_t<BOOST_XINT_APARAMS> n) { 02348 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 02349 if (n.is_nan()) return 0; 02350 BOOST_XINT_TRY { 02351 return log2(n._data()); 02352 } BOOST_XINT_CATCH { 02353 return 0; 02354 } 02355 } else { 02356 return log2(n._data()); 02357 } 02358 } 02360 02362 #define BOOST_XINT_ANY_COMPARE(rtype, op) \ 02363 template <BOOST_XINT_CLASS_APARAMS, typename N> \ 02364 rtype op(const integer_t<BOOST_XINT_APARAMS> n1, const N n2) { \ 02365 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { \ 02366 BOOST_XINT_TRY { \ 02367 return op(n1, integer_t<BOOST_XINT_APARAMS>(n2)); \ 02368 } BOOST_XINT_CATCH { \ 02369 return rtype(0); \ 02370 } \ 02371 } else { \ 02372 return op(n1, integer_t<BOOST_XINT_APARAMS>(n2)); \ 02373 } \ 02374 } \ 02375 \ 02376 template <typename N, BOOST_XINT_CLASS_APARAMS> \ 02377 rtype op(const N n1, const integer_t<BOOST_XINT_APARAMS> n2) { \ 02378 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { \ 02379 BOOST_XINT_TRY { \ 02380 return op(integer_t<BOOST_XINT_APARAMS>(n1), n2); \ 02381 } BOOST_XINT_CATCH { \ 02382 return rtype(0); \ 02383 } \ 02384 } else { \ 02385 return op(integer_t<BOOST_XINT_APARAMS>(n1), n2); \ 02386 } \ 02387 } 02388 02389 BOOST_XINT_ANY_COMPARE(bool, operator<) 02390 BOOST_XINT_ANY_COMPARE(bool, operator>) 02391 BOOST_XINT_ANY_COMPARE(bool, operator<=) 02392 BOOST_XINT_ANY_COMPARE(bool, operator>=) 02393 BOOST_XINT_ANY_COMPARE(bool, operator==) 02394 BOOST_XINT_ANY_COMPARE(bool, operator!=) 02395 BOOST_XINT_ANY_COMPARE(int, compare) 02396 02398 #define BOOST_XINT_ANY_MATH(op) \ 02399 template <BOOST_XINT_CLASS_APARAMS, typename N> \ 02400 integer_t<BOOST_XINT_APARAMS> op(const integer_t<BOOST_XINT_APARAMS> n1, \ 02401 const N n2) \ 02402 { \ 02403 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { \ 02404 BOOST_XINT_TRY { \ 02405 integer_t<BOOST_XINT_APARAMS> r(op(n1, \ 02406 integer_t<BOOST_XINT_APARAMS>(n2))); \ 02407 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) \ 02408 r._make_unique(); \ 02409 if (!integer_t<BOOST_XINT_APARAMS>::Signed && \ 02410 r._data().negative) r._fix_negative_unsigned(); \ 02411 return BOOST_XINT_MOVE(r); \ 02412 } BOOST_XINT_CATCH { \ 02413 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); \ 02414 } \ 02415 } else { \ 02416 integer_t<BOOST_XINT_APARAMS> r(op(n1, \ 02417 integer_t<BOOST_XINT_APARAMS>(n2))); \ 02418 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) \ 02419 r._make_unique(); \ 02420 if (!integer_t<BOOST_XINT_APARAMS>::Signed && r._data().negative) \ 02421 r._fix_negative_unsigned(); \ 02422 return BOOST_XINT_MOVE(r); \ 02423 } \ 02424 } \ 02425 \ 02426 template <typename N, BOOST_XINT_CLASS_APARAMS> \ 02427 integer_t<BOOST_XINT_APARAMS> op(const N n1, const \ 02428 integer_t<BOOST_XINT_APARAMS> n2) \ 02429 { \ 02430 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { \ 02431 BOOST_XINT_TRY { \ 02432 integer_t<BOOST_XINT_APARAMS> \ 02433 r(op(integer_t<BOOST_XINT_APARAMS>(n1), n2)); \ 02434 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) \ 02435 r._make_unique(); \ 02436 if (!integer_t<BOOST_XINT_APARAMS>::Signed && \ 02437 r._data().negative) r._fix_negative_unsigned(); \ 02438 return BOOST_XINT_MOVE(r); \ 02439 } BOOST_XINT_CATCH { \ 02440 return detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); \ 02441 } \ 02442 } else { \ 02443 integer_t<BOOST_XINT_APARAMS> \ 02444 r(op(integer_t<BOOST_XINT_APARAMS>(n1), n2)); \ 02445 if (integer_t<BOOST_XINT_APARAMS>::Threadsafe == true) \ 02446 r._make_unique(); \ 02447 if (!integer_t<BOOST_XINT_APARAMS>::Signed && r._data().negative) \ 02448 r._fix_negative_unsigned(); \ 02449 return BOOST_XINT_MOVE(r); \ 02450 } \ 02451 } 02452 02453 BOOST_XINT_ANY_MATH(pow) 02454 BOOST_XINT_ANY_MATH(mulmod) 02455 BOOST_XINT_ANY_MATH(sqrmod) 02456 BOOST_XINT_ANY_MATH(powmod) 02457 BOOST_XINT_ANY_MATH(invmod) 02458 BOOST_XINT_ANY_MATH(operator+) 02459 BOOST_XINT_ANY_MATH(operator-) 02460 BOOST_XINT_ANY_MATH(operator*) 02461 BOOST_XINT_ANY_MATH(operator/) 02462 BOOST_XINT_ANY_MATH(operator%) 02463 BOOST_XINT_ANY_MATH(operator&) 02464 BOOST_XINT_ANY_MATH(operator|) 02465 BOOST_XINT_ANY_MATH(operator^) 02466 BOOST_XINT_ANY_MATH(gcd) 02467 BOOST_XINT_ANY_MATH(lcm) 02468 02471 template <typename charT, typename traits, BOOST_XINT_CLASS_APARAMS> inline 02472 std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT, 02473 traits>& out, const integer_t<BOOST_XINT_APARAMS> n) 02474 { 02475 if (integer_t<BOOST_XINT_APARAMS>::Nothrow && n.is_nan()) return 02476 operator<<(out, detail::nan_text<charT>()); 02477 return operator<<(out, n._data()); 02478 } 02479 02480 template <typename charT, typename traits, BOOST_XINT_CLASS_APARAMS> inline 02481 std::basic_istream<charT,traits>& operator>>(std::basic_istream<charT, 02482 traits>& in, integer_t<BOOST_XINT_APARAMS>& n) 02483 { 02484 if (integer_t<BOOST_XINT_APARAMS>::Nothrow) { 02485 const std::basic_string<charT>& tnan = detail::nan_text<charT>(); 02486 charT nextchar = charT(in.peek()); 02487 if (nextchar == tnan[0]) { 02488 // Must be either #NaN# or an error 02489 std::vector<charT> buffer; 02490 02491 charT p = 0; 02492 for (std::size_t i = 0; i < tnan.length(); ++i) { 02493 in >> p; 02494 buffer.push_back(p); 02495 } 02496 buffer.push_back(0); 02497 02498 std::basic_string<charT> str(&buffer[0]); 02499 if (str == tnan) 02500 n = detail::get_nan<integer_t<BOOST_XINT_APARAMS> >(); 02501 else in.setstate(std::ios::failbit); 02502 return in; 02503 } 02504 } 02505 operator>>(in, n._data()); 02506 if (!integer_t<BOOST_XINT_APARAMS>::Signed && n._data().negative) 02507 n._fix_negative_unsigned(); 02508 return in; 02509 } 02511 02512 template<BOOST_XINT_CLASS_APARAMS> 02513 inline void swap(integer_t<BOOST_XINT_APARAMS>& left, 02514 integer_t<BOOST_XINT_APARAMS>& right) 02515 { 02516 left._swap(right); 02517 } 02518 02523 typedef integer_t<> integer; 02524 02530 typedef integer_t<options::nothrow> nothrow_integer; 02531 02532 } // namespace xint 02533 } // namespace boost 02534 02535 #ifndef BOOST_XINT_DOXYGEN_IGNORE 02536 namespace std { 02537 02538 template<BOOST_XINT_CLASS_APARAMS> 02539 class numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> > { 02540 public: 02541 static const bool is_specialized; 02542 02543 static boost::xint::integer_t<BOOST_XINT_APARAMS> min 02544 BOOST_PREVENT_MACRO_SUBSTITUTION() throw() 02545 { 02546 if (boost::xint::integer_t<BOOST_XINT_APARAMS>::Bits) 02547 return -~(boost::xint::integer_t<BOOST_XINT_APARAMS>()); 02548 else return 0; 02549 } 02550 static boost::xint::integer_t<BOOST_XINT_APARAMS> max 02551 BOOST_PREVENT_MACRO_SUBSTITUTION() throw() 02552 { 02553 if (boost::xint::integer_t<BOOST_XINT_APARAMS>::Bits) 02554 return ~(boost::xint::integer_t<BOOST_XINT_APARAMS>()); 02555 else return 0; 02556 } 02557 02558 static const int digits; 02559 static const int digits10; 02560 static const bool is_signed; 02561 static const bool is_integer; 02562 static const bool is_exact; 02563 static const int radix; 02564 static boost::xint::integer_t<BOOST_XINT_APARAMS> epsilon() throw() { return 02565 0; } 02566 static boost::xint::integer_t<BOOST_XINT_APARAMS> round_error() throw() { 02567 return 0; } 02568 02569 static const int min_exponent; // N/A 02570 static const int min_exponent10; // N/A 02571 static const int max_exponent; // N/A 02572 static const int max_exponent10; // N/A 02573 02574 static const bool has_infinity; // N/A 02575 static const bool has_quiet_NaN; 02576 static const bool has_signaling_NaN; // N/A 02577 static const float_denorm_style has_denorm; // N/A 02578 static const bool has_denorm_loss; // N/A 02579 02580 static boost::xint::integer_t<BOOST_XINT_APARAMS> infinity() throw() { 02581 return 0; } // N/A 02582 static boost::xint::integer_t<BOOST_XINT_APARAMS> quiet_NaN() throw() { 02583 if (boost::xint::integer_t<BOOST_XINT_APARAMS>::Nothrow) return boost:: 02584 xint::detail::get_nan<boost::xint::integer_t<BOOST_XINT_APARAMS> >(); 02585 else return 0; 02586 } 02587 static boost::xint::integer_t<BOOST_XINT_APARAMS> signaling_NaN() throw() { 02588 return 0; } // N/A 02589 static boost::xint::integer_t<BOOST_XINT_APARAMS> denorm_min() throw() { 02590 return 0; } // N/A 02591 02592 static const bool is_iec559; // N/A 02593 static const bool is_bounded; 02594 static const bool is_modulo; 02595 02596 static const bool traps; // I assume this means exceptions? 02597 static const bool tinyness_before; // N/A 02598 static const float_round_style round_style; // N/A 02599 }; 02600 02601 template<BOOST_XINT_CLASS_APARAMS> 02602 const bool numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02603 is_specialized = true; 02604 02605 template<BOOST_XINT_CLASS_APARAMS> 02606 const int numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >::digits = 02607 static_cast<int>(boost::xint::integer_t<BOOST_XINT_APARAMS>::Bits); 02608 02609 template<BOOST_XINT_CLASS_APARAMS> 02610 const int numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >::digits10 02611 = static_cast<int>(boost::xint::detail::log10_bits( 02612 boost::xint::integer_t<BOOST_XINT_APARAMS>::Bits)); 02613 02614 template<BOOST_XINT_CLASS_APARAMS> 02615 const bool numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02616 is_signed = (boost::xint::integer_t<BOOST_XINT_APARAMS>::Signed ? true : 02617 false); 02618 02619 template<BOOST_XINT_CLASS_APARAMS> 02620 const bool numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02621 is_integer = true; 02622 02623 template<BOOST_XINT_CLASS_APARAMS> 02624 const bool numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >::is_exact 02625 = true; 02626 02627 template<BOOST_XINT_CLASS_APARAMS> 02628 const int numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >::radix = 02629 2; 02630 02631 template<BOOST_XINT_CLASS_APARAMS> 02632 const int numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02633 min_exponent = 0; 02634 02635 template<BOOST_XINT_CLASS_APARAMS> 02636 const int numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02637 min_exponent10 = 0; 02638 02639 template<BOOST_XINT_CLASS_APARAMS> 02640 const int numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02641 max_exponent = 0; 02642 02643 template<BOOST_XINT_CLASS_APARAMS> 02644 const int numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02645 max_exponent10 = 0; 02646 02647 template<BOOST_XINT_CLASS_APARAMS> 02648 const bool numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02649 has_infinity = false; 02650 02651 template<BOOST_XINT_CLASS_APARAMS> 02652 const bool numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02653 has_quiet_NaN = (boost::xint::integer_t<BOOST_XINT_APARAMS>::Nothrow ? true 02654 : false); 02655 02656 template<BOOST_XINT_CLASS_APARAMS> 02657 const bool numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02658 has_signaling_NaN = false; 02659 02660 template<BOOST_XINT_CLASS_APARAMS> 02661 const float_denorm_style numeric_limits<boost::xint::integer_t< 02662 BOOST_XINT_APARAMS> >::has_denorm = denorm_absent; 02663 02664 template<BOOST_XINT_CLASS_APARAMS> 02665 const bool numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02666 has_denorm_loss = false; 02667 02668 template<BOOST_XINT_CLASS_APARAMS> 02669 const bool numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02670 is_iec559 = false; 02671 02672 template<BOOST_XINT_CLASS_APARAMS> 02673 const bool numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02674 is_bounded = (boost::xint::integer_t<BOOST_XINT_APARAMS>::Bits == 0 ? false 02675 : true); 02676 02677 template<BOOST_XINT_CLASS_APARAMS> 02678 const bool numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02679 is_modulo = (boost::xint::integer_t<BOOST_XINT_APARAMS>::Bits == 0 ? false : 02680 true); 02681 02682 template<BOOST_XINT_CLASS_APARAMS> 02683 const bool numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >::traps = 02684 (boost::xint::integer_t<BOOST_XINT_APARAMS>::Nothrow ? false : true); 02685 02686 template<BOOST_XINT_CLASS_APARAMS> 02687 const bool numeric_limits<boost::xint::integer_t<BOOST_XINT_APARAMS> >:: 02688 tinyness_before = false; 02689 02690 template<BOOST_XINT_CLASS_APARAMS> 02691 const float_round_style numeric_limits<boost::xint::integer_t< 02692 BOOST_XINT_APARAMS> >::round_style = round_indeterminate; 02693 02694 } // namespace std 02695 #endif // BOOST_XINT_DOXYGEN_IGNORE 02696 #endif // BOOST_INCLUDED_XINT_INTEGER_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)