1 /*  Copyright (c) MediaArea.net SARL. All Rights Reserved.
2  *
3  *  Use of this source code is governed by a zlib-style license that can
4  *  be found in the License.txt file in the root of the source tree.
5  */
6 
7 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 //
9 // based on http://Tringi.Mx-3.cz
10 // Only adapted for ZenLib:
11 // - .hpp --> .h
12 // - Namespace
13 // - int128s alias
14 //
15 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
16 
17 #ifndef INT128_HPP
18 #define INT128_HPP
19 
20 /*
21   Name: int128.hpp
22   Copyright: Copyright (C) 2005, Jan Ringos
23   Author: Jan Ringos, http://Tringi.Mx-3.cz
24 
25   Version: 1.1
26 */
27 
28 #include <exception>
29 #include <cstdlib>
30 #include <cstdio>
31 #ifdef __cplusplus
32     #include <new> //for size_t
33 #else /* __cplusplus */
34     #include <stddef.h> //for size_t
35 #endif /* __cplusplus */
36 #include "ZenLib/Conf.h"
37 
38 namespace ZenLib
39 {
40 
41 // CLASS
42 
43 class int128 {
44     private:
45         // Binary correct representation of signed 128bit integer
46         int64u lo;
47         int64s hi;
48 
49     protected:
50         // Some global operator functions must be friends
51         friend bool operator <  (const int128 &, const int128 &) throw ();
52         friend bool operator == (const int128 &, const int128 &) throw ();
53         friend bool operator || (const int128 &, const int128 &) throw ();
54         friend bool operator && (const int128 &, const int128 &) throw ();
55 
56     public:
57         // Constructors
int128()58         inline int128 () throw () : lo(0), hi(0) {};
throw()59         inline int128 (const int128 & a) throw () : lo (a.lo), hi (a.hi) {};
60 
throw()61         inline int128 (const unsigned int & a) throw () : lo (a), hi (0ll) {};
throw()62         inline int128 (const signed int & a) throw () : lo (a), hi (0ll) {
63             if (a < 0) this->hi = -1ll;
64         };
65 
throw()66         inline int128 (const int64u & a) throw () : lo (a), hi (0ll) {};
throw()67         inline int128 (const int64s & a) throw () : lo (a), hi (0ll) {
68             if (a < 0) this->hi = -1ll;
69         };
70 
71         int128 (const float a) throw ();
72         int128 (const double & a) throw ();
73         int128 (const long double & a) throw ();
74 
75         int128 (const char * sz) throw ();
76 
77         // TODO: Consider creation of operator= to eliminate
78         //       the need of intermediate objects during assignments.
79 
80     private:
81         // Special internal constructors
int128(const int64u & a,const int64s & b)82         int128 (const int64u & a, const int64s & b) throw ()
83             : lo (a), hi (b) {};
84 
85     public:
86         // Operators
87         bool operator ! () const throw ();
88 
89         int128 operator - () const throw ();
90         int128 operator ~ () const throw ();
91 
92         int128 & operator ++ ();
93         int128 & operator -- ();
94         int128 operator ++ (int);
95         int128 operator -- (int);
96 
97         int128 & operator += (const int128 & b) throw ();
98         int128 & operator *= (const int128 & b) throw ();
99 
100         int128 & operator >>= (unsigned int n) throw ();
101         int128 & operator <<= (unsigned int n) throw ();
102 
103         int128 & operator |= (const int128 & b) throw ();
104         int128 & operator &= (const int128 & b) throw ();
105         int128 & operator ^= (const int128 & b) throw ();
106 
107         // Inline simple operators
108         inline const int128 & operator + () const throw () { return *this; };
109 
110         // Rest of inline operators
111         inline int128 & operator -= (const int128 & b) throw () {
112             return *this += (-b);
113         };
114         inline int128 & operator /= (const int128 & b) throw () {
115             int128 dummy;
116             *this = this->div (b, dummy);
117             return *this;
118         };
119         inline int128 & operator %= (const int128 & b) throw () {
120             this->div (b, *this);
121             return *this;
122         };
123 
124         // Common methods
toInt()125         int toInt () const throw () {  return (int) this->lo; };
toInt64()126         int64s toInt64 () const throw () {  return (int64s) this->lo; };
127 
128         const char * toString (unsigned int radix = 10) const throw ();
129         float toFloat () const throw ();
130         double toDouble () const throw ();
131         long double toLongDouble () const throw ();
132 
133         // Arithmetic methods
134         int128  div (const int128 &, int128 &) const throw ();
135 
136         // Bit operations
137         bool    bit (unsigned int n) const throw ();
138         void    bit (unsigned int n, bool val) throw ();
139 }
140 #if defined(__GNUC__)  && !defined(__ANDROID_API__)
141     __attribute__ ((__aligned__ (16), __packed__))
142 #endif
143 ;
144 
145 
146 // GLOBAL OPERATORS
147 
148 bool operator <  (const int128 & a, const int128 & b) throw ();
149 bool operator == (const int128 & a, const int128 & b) throw ();
150 bool operator || (const int128 & a, const int128 & b) throw ();
151 bool operator && (const int128 & a, const int128 & b) throw ();
152 
153 // GLOBAL OPERATOR INLINES
154 
155 inline int128 operator + (const int128 & a, const int128 & b) throw () {
156     return int128 (a) += b; }
157 inline int128 operator - (const int128 & a, const int128 & b) throw () {
158     return int128 (a) -= b; }
throw()159 inline int128 operator * (const int128 & a, const int128 & b) throw () {
160     return int128 (a) *= b; }
161 inline int128 operator / (const int128 & a, const int128 & b) throw () {
162     return int128 (a) /= b; }
163 inline int128 operator % (const int128 & a, const int128 & b) throw () {
164     return int128 (a) %= b; }
165 
throw()166 inline int128 operator >> (const int128 & a, unsigned int n) throw () {
167     return int128 (a) >>= n; }
168 inline int128 operator << (const int128 & a, unsigned int n) throw () {
169     return int128 (a) <<= n; }
170 
throw()171 inline int128 operator & (const int128 & a, const int128 & b) throw () {
172     return int128 (a) &= b; }
173 inline int128 operator | (const int128 & a, const int128 & b) throw () {
174     return int128 (a) |= b; }
175 inline int128 operator ^ (const int128 & a, const int128 & b) throw () {
176     return int128 (a) ^= b; }
177 
throw()178 inline bool operator >  (const int128 & a, const int128 & b) throw () {
179     return   b < a; }
180 inline bool operator <= (const int128 & a, const int128 & b) throw () {
181     return !(b < a); }
throw()182 inline bool operator >= (const int128 & a, const int128 & b) throw () {
183     return !(a < b); }
184 inline bool operator != (const int128 & a, const int128 & b) throw () {
185     return !(a == b); }
186 
187 
188 // MISC
189 
190 //typedef int128 __int128;
191 
192 typedef int128 int128s;
193 } //NameSpace
194 
195 #endif
196