
程序代码:
#ifndef __BIG_INT_H__
#define __BIG_INT_H__
// include section
#include <cassert>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <iomanip>
#include <utility>
#include <climits>
#include <algorithm>
#include <stdexcept>
#include <limits>
// ========================================
// BOOST
// --------------------------
// #define BIG_INT_USES_BOOST
// --------------------------
#ifdef BIG_INT_USES_BOOST
#include <boost/static_assert.hpp>
#endif
// ========================================
// ========== FUNCTION_NAME MACROS (BEGIN) =========
#ifdef FUNCTION_NAME
#undef FUNCTION_NAME
#endif
#ifdef UNDECORATED_FUNCTION_NAME
#undef UNDECORATED_FUNCTION_NAME
#endif
// --------------------------------------
// --------------------------------------
#if defined _MSC_VER // Windows
// #define FUNCTION_NAME __FUNCSIG__ // too long and not friendly representation
#define FUNCTION_NAME __FUNCTION__
#define UNDECORATED_FUNCTION_NAME __FUNCTION__
#elif defined __GNUC__ // g++ GNU C++
#define FUNCTION_NAME __PRETTY_FUNCTION__
#define UNDECORATED_FUNCTION_NAME __FUNCTION__
#elif defined __HP_aCC // aCC on HP-UX
#define FUNCTION_NAME __PRETTY_FUNCTION__
#define UNDECORATED_FUNCTION_NAME __FUNCTION__
#elif defined __xlC__ // xlC on IBM AIX
#define FUNCTION_NAME __FUNCTION__
#define UNDECORATED_FUNCTION_NAME __func__
#elif defined __SUNPRO_CC // SUN CC
#define FUNCTION_NAME BOOST_CURRENT_FUNCTION // Must be compiled with option -features=extensions
#define UNDECORATED_FUNCTION_NAME __func__ // Must be compiled with option -features=extensions
#elif defined __INTEL_COMPILER // Intel C/C++
#define FUNCTION_NAME __PRETTY_FUNCTION__
#define UNDECORATED_FUNCTION_NAME __FUNCTION__
#else
#define FUNCTION_NAME "Unable to detect FUNCTION_NAME"
#define UNDECORATED_FUNCTION_NAME "Unable to detect UNDECORATED_FUNCTION_NAME"
#endif
// ========== FUNCTION_NAME MACROS (END) ===========
// =================================================
// ===========================================
// ========== DISPLAY MACROS (BEGIN) =========
#define PRE_MSG(s, p) s << p << "[" << __FILE__ << ", #" << std::dec << std::setw(3) << __LINE__ << "; " << UNDECORATED_FUNCTION_NAME << "] " << std::flush
#define SCREEN_MSG(s,p,x,t) { std::ostringstream oo_ss_ss; PRE_MSG(oo_ss_ss,p) << x << t << std::endl; s << std::flush << oo_ss_ss.str() << std::flush; }
#define FATAL_MSG(s, t) SCREEN_MSG (s, "FATAL ", "", t)
#define ERR_MSG(s, t) SCREEN_MSG (s, "ERROR ", "", t)
#define WARN_MSG(s, t) SCREEN_MSG (s, "WARNING ", "", t)
#define INFO_MSG(s, t) SCREEN_MSG (s, "INFO ", "", t)
#define SUCCESS_MSG(s, t) SCREEN_MSG (s, "SUCCESS ", "", t)
// ===========================================
// ========= ASSERTION MACROS (BEGIN) ========
#define ASSERTION(x) assert(x); \
if (!(x)) \
{ \
std::cerr << "[" \
<< __FILE__ \
<< ", " \
<< __LINE__ \
<< "] assert(" \
<< #x \
<< ") not working" \
<< std::endl \
<< std::flush; \
abort(); \
}
// ========== ASSERTION MACROS (END) =========
// ===========================================
struct BigInt
{
// -------------------
// FORWARD DECLARATION
// -------------------
class Rossi;
// --------
// TYPEDEFS
// --------
typedef unsigned long Ulong;
// ----------------
// STATIC CONSTANTS
// ----------------
static const std::size_t BIG_INT_MAJOR_VERSION = 4;
static const std::size_t BIG_INT_MINOR_VERSION = 0;
static const std::size_t DEC_DIGIT = 10;
static const std::size_t HEX_DIGIT = 16;
static const std::size_t NIBBLE_BIT = 4;
static const std::size_t ULONG_HEX_DIGITS = ((sizeof (Ulong) * CHAR_BIT)/NIBBLE_BIT);
static const Ulong MAX_UNIT_VALUE = (ULONG_MAX >> 2);
static const Ulong ULONG_MSB = static_cast<Ulong>(1) << (sizeof(Ulong) * CHAR_BIT - 1);
static const Ulong BASE1 = 10;
static const Ulong BASE2 = 1000000000; // // BASE1 ** (BASE1 - 1)
static const Ulong SUB_BASE2 = BASE2 - 1; // 999999999
static const Ulong OVER_BASE2 = 0xc0000000; // OVER_BASE2 > SUB_BASE2
// -----------------------------------------
#ifdef BIG_INT_USES_BOOST
BOOST_STATIC_ASSERT (SUB_BASE2 == 999999999);
BOOST_STATIC_ASSERT (!(BASE2 >= MAX_UNIT_VALUE));
BOOST_STATIC_ASSERT (BASE1 * (BASE2/BASE1 + 1) < MAX_UNIT_VALUE);
BOOST_STATIC_ASSERT (!(BASE2 != (SUB_BASE2 + 1)));
BOOST_STATIC_ASSERT (OVER_BASE2 > SUB_BASE2);
BOOST_STATIC_ASSERT(
(sizeof(Ulong) == 4) && ((ULONG_MSB == static_cast<Ulong>(0x80000000)))
||
(sizeof(Ulong) == 8) && ((ULONG_MSB == ((static_cast<Ulong>(0x80000000) << 31) << 1)))
);
#endif
// -----------------------------------------
// Public Methods
static void assertCheck();
static void showVersion(std::ostream& o_stream);
// -----------------------------------
template <typename T>
static std::string toString(const T& t)
{
std::ostringstream oss;
oss << t;
return oss.str();
}
// -------------------------------
template<typename T, std::size_t N>
static std::size_t getArrayElems(const T(&)[N])
{
return N;
}
// -------------------------------
template<typename T, std::size_t N>
static std::size_t getArrayElems(T(&)[N])
{
return N;
}
// -------------------------------
template<typename T, std::size_t N>
static std::size_t getArraySizeInBytes(const T(&a)[N])
{
return getArrayElems(a) * sizeof (T);
}
// -------------------------------
template<typename T, std::size_t N>
static std::size_t getArraySizeInBytes(T(&a)[N])
{
return getArrayElems(a) * sizeof (T);
}
// -------------------------------
template<typename T, std::size_t N>
static std::vector<T> array2vector(const T(&a)[N])
{
return std::vector<T> (a, a + getArrayElems (a));
}
// --------------------------------
template<typename T, std::size_t N>
static std::vector<T> array2vector(T(&a)[N])
{
return std::vector<T> (a, a + getArrayElems (a));
}
// ------------------------------------
template<typename T>
static std::vector<T> elem2vector(const T& e)
{
return std::vector<T> (&e, &e + 1);
}
// ------------------------------------
template<typename T>
static std::vector<T> elem2vector(T& e)
{
return std::vector<T> (&e, &e + 1);
}
// ---------------------------------------------------------
template<typename K, typename T, std::size_t N>
static std::map<K, T> array2map(const std::pair<K,T>(&a)[N])
{
return std::map<K, T> (a, a + getArrayElems (a));
}
// ---------------------------------------------------------
template<typename K, typename T, std::size_t N>
static std::map<K, T> array2map(std::pair<K,T>(&a)[N])
{
return std::map<K, T> (a, a + getArrayElems (a));
}
// ------------------------------------
template<typename K, typename T>
static std::map<K, T> pair2map(const std::pair<K,T>& e)
{
return std::map<K, T> (&e, &e + 1);
}
// ==============
class BaseBigInt
// ==============
{
public:
// --- Public Methods
std::size_t getUnitsSize () const;
void maximize ();
protected :
// --- Protected Data Members ---
std::vector<Ulong> m_units;
static std::map<char, std::size_t> ms_hex2dec;
// --- Protected Methods
void showUnits (std::ostream& o_stream) const;
virtual ~BaseBigInt () = 0;
public :
// --- Public Methods ---
bool isEmpty () const;
};
// ==============
class Vin : public BaseBigInt
// ==============
{
private :
// -------
// FRIENDS
// -------
friend std::ostream& operator<< (std::ostream& o_os, const Vin& i_ins);
private :
// --- Private Data Members ---
static Ulong s_carry;
// --- Private Methods ---
static Ulong addUnits(Ulong n1, Ulong n2);
bool initViaString (const std::string& i_arg, std::size_t i_digitBase);
public :
// ----------------------
// --- Public Methods ---
// ----------------------
// --- Constructors ---
explicit Vin ();
explicit Vin (Ulong i_unit);
explicit Vin (const std::string& i_arg, std::size_t i_digitBase);
explicit Vin (const Rossi& i_arg);
// --- Aux methods ---
Ulong toUlong () const;
// operator Ulong () const;
// --- Show functions ---
std::string toStrHex (const std::string& i_prefix = "") const;
std::string toStr0xHex () const;
std::string toStrDec (const std::string& i_prefix = "") const;
// --- General purpose mathematical methods ---
Vin operator+ (const Vin& i_arg) const;
Vin operator* (Ulong i_arg) const;
// --- Comparison operators ---
bool operator== (const Vin& i_arg) const;
bool operator!= (const Vin& i_arg) const;
bool operator< (const Vin& i_arg) const;
bool operator> (const Vin& i_arg) const;
bool operator<= (const Vin& i_arg) const;
bool operator>= (const Vin& i_arg) const;
// ---- Service methods ---
void showUnits(std::ostream& o_stream) const;
};
// ============================
class Rossi : public BaseBigInt
// ============================
{
private :
// -------
// FRIENDS
// -------
friend std::ostream& operator<< (std::ostream& o_os, const Rossi& i_ins);
private :
// --- Private Methods ---
void resizeUnits (std::size_t i_size);
void truncateUnits ();
void smartTruncateUnits ();
bool backUnitIsNull () const;
bool initViaString (const std::string& i_arg, std::size_t i_digitBase);
public :
// ----------------------
// --- Public Methods ---
// ----------------------
// --- Constructors ---
explicit Rossi ();
explicit Rossi (Ulong i_unit);
explicit Rossi (const std::string& i_arg, std::size_t i_digitBase);
explicit Rossi (const Vin& i_arg);
explicit Rossi (const std::size_t i_noOfUnits, Ulong i_internalUnits, Ulong i_backUnit);
// --- Aux methods ---
Ulong toUlong () const;
// operator Ulong () const;
// --- General purpose mathematical methods ---
// Rossi& operator= (Ulong i_arg);
Rossi operator+ (const Rossi& i_arg);
Rossi operator+ (Ulong i_arg);
Rossi operator* (Rossi i_arg) const;
Rossi operator* (Ulong i_arg) const;
// Rossi& Rossi::operator*= (Rossi i_arg);
Rossi operator/ (const Rossi& i_arg) const;
Rossi operator% (const Rossi& i_arg) const;
Rossi divide(const Rossi& i_dividend, const Rossi& i_divisor, Rossi* o_remainder) const;
Rossi& operator+= (const Rossi& i_arg);
Rossi operator++ (int); // Post increment operator
Rossi& operator++ (); // Pre increment operator
Rossi operator- (const Rossi& i_arg);
Rossi operator- ();
Rossi operator-- (int); // Post decrement operator
Rossi& operator-- (); // Pre decrement operator
Rossi& operator-= (const Rossi& i_arg);
Rossi sqrt();
// --- Bitwise boolean operators ---
Rossi operator& (const Rossi& i_arg);
Rossi operator| (const Rossi& i_arg);
Rossi operator^ (const Rossi& i_arg);
Rossi& operator&= (const Rossi& i_arg);
Rossi& operator|= (const Rossi& i_arg);
Rossi& operator^= (const Rossi& i_arg);
Rossi operator~ ();
Rossi operator>> (std::size_t i_shift);
Rossi operator<< (std::size_t i_shift);
Rossi& operator>>= (std::size_t i_shift);
Rossi& operator<<= (std::size_t i_shift);
// --- Comparison operators ---
bool operator== (const Rossi& i_arg) const;
bool operator!= (const Rossi& i_arg) const;
bool operator< (const Rossi& i_arg) const;
bool operator> (const Rossi& i_arg) const;
bool operator<= (const Rossi& i_arg) const;
bool operator>= (const Rossi& i_arg) const;
// --- Show functions ---
std::string toStrHex (const std::string& i_prefix = "") const;
std::string toStr0xHex () const;
std::string toStrDec (const std::string& i_prefix = "") const;
// ---- Service methods ---
void showUnits(std::ostream& o_stream) const;
};
}; // class BigInt
#endif // __BIG_INT_H__