ZenLib
|
00001 /* Copyright (c) MediaArea.net SARL. All Rights Reserved. 00002 * 00003 * Use of this source code is governed by a zlib-style license that can 00004 * be found in the License.txt file in the root of the source tree. 00005 */ 00006 00007 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00008 // 00009 // based on http://Tringi.Mx-3.cz 00010 // Only adapted for ZenLib: 00011 // - .hpp --> .h 00012 // - Namespace 00013 // - int128u alias 00014 // 00015 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00016 00017 #ifndef UINT128_HPP 00018 #define UINT128_HPP 00019 00020 /* 00021 Name: uint128.hpp 00022 Copyright: Copyright (C) 2005, Jan Ringos 00023 Author: Jan Ringos, http://Tringi.Mx-3.cz 00024 00025 Version: 1.1 00026 */ 00027 00028 00029 #include <exception> 00030 #include <cstdlib> 00031 #include <cstdio> 00032 #include "ZenLib/Conf.h" 00033 00034 // CLASS 00035 00036 namespace ZenLib 00037 { 00038 00039 class uint128 { 00040 public://private: 00041 // Binary correct representation of signed 128bit integer 00042 int64u lo; 00043 int64u hi; 00044 00045 protected: 00046 // Some global operator functions must be friends 00047 friend bool operator < (const uint128 &, const uint128 &) throw (); 00048 friend bool operator == (const uint128 &, const uint128 &) throw (); 00049 friend bool operator || (const uint128 &, const uint128 &) throw (); 00050 friend bool operator && (const uint128 &, const uint128 &) throw (); 00051 00052 public: 00053 // Constructors 00054 inline uint128 () throw () {}; 00055 inline uint128 (const uint128 & a) throw () : lo (a.lo), hi (a.hi) {}; 00056 00057 inline uint128 (const int & a) throw () : lo (a), hi (0ull) {}; 00058 inline uint128 (const unsigned int & a) throw () : lo (a), hi (0ull) {}; 00059 inline uint128 (const int64u & a) throw () : lo (a), hi (0ull) {}; 00060 00061 uint128 (const float a) throw (); 00062 uint128 (const double & a) throw (); 00063 uint128 (const long double & a) throw (); 00064 00065 uint128 (const char * sz) throw (); 00066 00067 // TODO: Consider creation of operator= to eliminate 00068 // the need of intermediate objects during assignments. 00069 00070 private: 00071 // Special internal constructors 00072 uint128 (const int64u & a, const int64u & b) throw () 00073 : lo (a), hi (b) {}; 00074 00075 public: 00076 // Operators 00077 bool operator ! () const throw (); 00078 00079 uint128 operator - () const throw (); 00080 uint128 operator ~ () const throw (); 00081 00082 uint128 & operator ++ (); 00083 uint128 & operator -- (); 00084 uint128 operator ++ (int); 00085 uint128 operator -- (int); 00086 00087 uint128 & operator += (const uint128 & b) throw (); 00088 uint128 & operator *= (const uint128 & b) throw (); 00089 00090 uint128 & operator >>= (unsigned int n) throw (); 00091 uint128 & operator <<= (unsigned int n) throw (); 00092 00093 uint128 & operator |= (const uint128 & b) throw (); 00094 uint128 & operator &= (const uint128 & b) throw (); 00095 uint128 & operator ^= (const uint128 & b) throw (); 00096 00097 // Inline simple operators 00098 inline const uint128 & operator + () const throw () { return *this; }; 00099 00100 // Rest of inline operators 00101 inline uint128 & operator -= (const uint128 & b) throw () { 00102 return *this += (-b); 00103 }; 00104 inline uint128 & operator /= (const uint128 & b) throw () { 00105 uint128 dummy; 00106 *this = this->div (b, dummy); 00107 return *this; 00108 }; 00109 inline uint128 & operator %= (const uint128 & b) throw () { 00110 this->div (b, *this); 00111 return *this; 00112 }; 00113 00114 // Common methods 00115 unsigned int toUint () const throw () { 00116 return (unsigned int) this->lo; }; 00117 int64u toUint64 () const throw () { 00118 return (int64u) this->lo; }; 00119 const char * toString (unsigned int radix = 10) const throw (); 00120 float toFloat () const throw (); 00121 double toDouble () const throw (); 00122 long double toLongDouble () const throw (); 00123 00124 // Arithmetic methods 00125 uint128 div (const uint128 &, uint128 &) const throw (); 00126 00127 // Bit operations 00128 bool bit (unsigned int n) const throw (); 00129 void bit (unsigned int n, bool val) throw (); 00130 } 00131 #ifdef __GNUC__ 00132 __attribute__ ((__aligned__ (16), __packed__)) 00133 #endif 00134 ; 00135 00136 00137 // GLOBAL OPERATORS 00138 00139 bool operator < (const uint128 & a, const uint128 & b) throw (); 00140 bool operator == (const uint128 & a, const uint128 & b) throw (); 00141 bool operator || (const uint128 & a, const uint128 & b) throw (); 00142 bool operator && (const uint128 & a, const uint128 & b) throw (); 00143 00144 // GLOBAL OPERATOR INLINES 00145 00146 inline uint128 operator + (const uint128 & a, const uint128 & b) throw () { 00147 return uint128 (a) += b; }; 00148 inline uint128 operator - (const uint128 & a, const uint128 & b) throw () { 00149 return uint128 (a) -= b; }; 00150 inline uint128 operator * (const uint128 & a, const uint128 & b) throw () { 00151 return uint128 (a) *= b; }; 00152 inline uint128 operator / (const uint128 & a, const uint128 & b) throw () { 00153 return uint128 (a) /= b; }; 00154 inline uint128 operator % (const uint128 & a, const uint128 & b) throw () { 00155 return uint128 (a) %= b; }; 00156 00157 inline uint128 operator >> (const uint128 & a, unsigned int n) throw () { 00158 return uint128 (a) >>= n; }; 00159 inline uint128 operator << (const uint128 & a, unsigned int n) throw () { 00160 return uint128 (a) <<= n; }; 00161 00162 inline uint128 operator & (const uint128 & a, const uint128 & b) throw () { 00163 return uint128 (a) &= b; }; 00164 inline uint128 operator | (const uint128 & a, const uint128 & b) throw () { 00165 return uint128 (a) |= b; }; 00166 inline uint128 operator ^ (const uint128 & a, const uint128 & b) throw () { 00167 return uint128 (a) ^= b; }; 00168 00169 inline bool operator > (const uint128 & a, const uint128 & b) throw () { 00170 return b < a; }; 00171 inline bool operator <= (const uint128 & a, const uint128 & b) throw () { 00172 return !(b < a); }; 00173 inline bool operator >= (const uint128 & a, const uint128 & b) throw () { 00174 return !(a < b); }; 00175 inline bool operator != (const uint128 & a, const uint128 & b) throw () { 00176 return !(a == b); }; 00177 00178 00179 // MISC 00180 00181 typedef uint128 __uint128; 00182 00183 typedef uint128 int128u; 00184 } //NameSpace 00185 00186 #endif