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_COMPARE_HPP 00021 #define BOOST_INCLUDED_XINT_COMPARE_HPP 00022 00024 namespace boost { 00025 namespace xint { 00026 namespace detail { 00027 00029 inline int compare(const digit_t *b1, const digit_t *b2, std::size_t len, bool 00030 equal_only) 00031 { 00032 const detail::digit_t *b1i = b1 + len, *b2i = b2 + len; 00033 if (equal_only) { 00034 // If we only care whether it's equal or not, we'll start from the 00035 // lowest digit instead of the highest, on the assumption that it's more 00036 // likely to be different. 00037 while (b1 < b1i) if (*b1++ != *b2++) return 1; 00038 } else { 00039 while (b1i > b1) 00040 if (*(--b1i) != *(--b2i)) 00041 return ((*b1i < *b2i) ? -1 : 1); 00042 } 00043 return 0; // They're identical. 00044 } 00045 00047 BOOST_XINT_RAWINT_TPL 00048 int compare(const BOOST_XINT_RAWINT b1, const BOOST_XINT_RAWINT b2, bool 00049 ignoresign = false) 00050 { 00051 bool invert_answer=false; 00052 if (!ignoresign) { 00053 if (b1.is_zero()) { 00054 if (b2.is_zero()) return 0; 00055 return (b2.negative ? 1 : -1); 00056 } else if (b2.is_zero()) { 00057 return (b1.negative ? -1 : 1); 00058 } else { 00059 if (b1.negative != b2.negative) return (b1.negative ? -1 : 1); 00060 if (b1.negative) invert_answer=true; 00061 } 00062 } 00063 00064 int answer = 0; 00065 if (b1.length != b2.length) { 00066 answer = ((b1.length < b2.length) ? -1 : 1); 00067 } else { 00068 answer = compare(b1.digits(), b2.digits(), b1.length, false); 00069 } 00070 return (invert_answer ? -answer : answer); 00071 } 00072 00074 BOOST_XINT_RAWINT_TPL 00075 int compare_eq(const BOOST_XINT_RAWINT b1, const BOOST_XINT_RAWINT b2) { 00076 if (b1.negative != b2.negative) { 00077 // Have to test for is_zero here, because in some rare cases, negative 00078 // zero is allowed, and negative zero is equal to zero. 00079 return (!b1.is_zero() || !b2.is_zero() ? 1 : 0); 00080 } 00081 if (b1.length != b2.length) return 1; 00082 return compare(b1.digits(), b2.digits(), b1.length, true); 00083 } 00084 00085 BOOST_XINT_RAWINT_TPL 00086 bool operator==(const BOOST_XINT_RAWINT num1, const BOOST_XINT_RAWINT num2) { 00087 return compare_eq(num1, num2)==0; } 00088 BOOST_XINT_RAWINT_TPL 00089 bool operator!=(const BOOST_XINT_RAWINT num1, const BOOST_XINT_RAWINT num2) { 00090 return compare_eq(num1, num2)!=0; } 00091 BOOST_XINT_RAWINT_TPL 00092 bool operator<(const BOOST_XINT_RAWINT num1, const BOOST_XINT_RAWINT num2) { 00093 return compare(num1, num2)<0; } 00094 BOOST_XINT_RAWINT_TPL 00095 bool operator>(const BOOST_XINT_RAWINT num1, const BOOST_XINT_RAWINT num2) { 00096 return compare(num1, num2)>0; } 00097 BOOST_XINT_RAWINT_TPL 00098 bool operator<=(const BOOST_XINT_RAWINT num1, const BOOST_XINT_RAWINT num2) { 00099 return compare(num1, num2)<=0; } 00100 BOOST_XINT_RAWINT_TPL 00101 bool operator>=(const BOOST_XINT_RAWINT num1, const BOOST_XINT_RAWINT num2) { 00102 return compare(num1, num2)>=0; } 00103 00104 } // namespace detail 00105 } // namespace xint 00106 } // namespace boost 00108 00109 #endif // BOOST_INCLUDED_XINT_COMPARE_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)