Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
fc::uint128 Class Reference

an implementation of 128 bit unsigned integer More...

#include <uint128.hpp>

Public Member Functions

 uint128 ()
 
 uint128 (uint32_t l)
 
 uint128 (int32_t l)
 
 uint128 (int64_t l)
 
 uint128 (uint64_t l)
 
 uint128 (const std::string &s)
 
 uint128 (uint64_t _h, uint64_t _l)
 
 uint128 (const fc::bigint &bi)
 
 uint128 (unsigned __int128 i)
 
 operator std::string () const
 
 operator fc::bigint () const
 
 operator unsigned __int128 () const
 
bool operator== (const uint128 &o) const
 
bool operator!= (const uint128 &o) const
 
bool operator< (const uint128 &o) const
 
bool operator< (const int64_t &o) const
 
bool operator! () const
 
uint128 operator- () const
 
uint128 operator~ () const
 
uint128operator++ ()
 
uint128operator-- ()
 
uint128 operator++ (int)
 
uint128 operator-- (int)
 
uint128operator|= (const uint128 &u)
 
uint128operator&= (const uint128 &u)
 
uint128operator^= (const uint128 &u)
 
uint128operator<<= (const uint128 &u)
 
uint128operator>>= (const uint128 &u)
 
uint128operator+= (const uint128 &u)
 
uint128operator-= (const uint128 &u)
 
uint128operator*= (const uint128 &u)
 
uint128operator/= (const uint128 &u)
 
uint128operator%= (const uint128 &u)
 
uint32_t to_integer () const
 
uint64_t to_uint64 () const
 
uint32_t low_32_bits () const
 
uint64_t low_bits () const
 
uint64_t high_bits () const
 
uint8_t popcount () const
 

Static Public Member Functions

static uint128 max_value ()
 
static void full_product (const uint128 &a, const uint128 &b, uint128 &result_hi, uint128 &result_lo)
 

Public Attributes

uint64_t hi
 
uint64_t lo
 

Friends

uint128 operator+ (const uint128 &l, const uint128 &r)
 
uint128 operator- (const uint128 &l, const uint128 &r)
 
uint128 operator* (const uint128 &l, const uint128 &r)
 
uint128 operator/ (const uint128 &l, const uint128 &r)
 
uint128 operator% (const uint128 &l, const uint128 &r)
 
uint128 operator| (const uint128 &l, const uint128 &r)
 
uint128 operator& (const uint128 &l, const uint128 &r)
 
uint128 operator^ (const uint128 &l, const uint128 &r)
 
uint128 operator<< (const uint128 &l, const uint128 &r)
 
uint128 operator>> (const uint128 &l, const uint128 &r)
 
bool operator> (const uint128 &l, const uint128 &r)
 
bool operator> (const uint128 &l, const int64_t &r)
 
bool operator> (const int64_t &l, const uint128 &r)
 
bool operator>= (const uint128 &l, const uint128 &r)
 
bool operator>= (const uint128 &l, const int64_t &r)
 
bool operator>= (const int64_t &l, const uint128 &r)
 
bool operator<= (const uint128 &l, const uint128 &r)
 
bool operator<= (const uint128 &l, const int64_t &r)
 
bool operator<= (const int64_t &l, const uint128 &r)
 
std::size_t hash_value (const uint128 &v)
 

Detailed Description

Definition at line 21 of file uint128.hpp.

Constructor & Destructor Documentation

◆ uint128() [1/9]

fc::uint128::uint128 ( )
inline

Definition at line 26 of file uint128.hpp.

26:hi(0),lo(0){}
uint64_t lo
Definition uint128.hpp:122
uint64_t hi
Definition uint128.hpp:121
Here is the caller graph for this function:

◆ uint128() [2/9]

fc::uint128::uint128 ( uint32_t l)
inline

Definition at line 27 of file uint128.hpp.

27:hi(0),lo(l){}
int l

◆ uint128() [3/9]

fc::uint128::uint128 ( int32_t l)
inline

Definition at line 28 of file uint128.hpp.

28:hi( -(l<0) ),lo(l){}

◆ uint128() [4/9]

fc::uint128::uint128 ( int64_t l)
inline

Definition at line 29 of file uint128.hpp.

29:hi( -(l<0) ),lo(l){}

◆ uint128() [5/9]

fc::uint128::uint128 ( uint64_t l)
inline

Definition at line 30 of file uint128.hpp.

30:hi(0),lo(l){}

◆ uint128() [6/9]

fc::uint128::uint128 ( const std::string & s)

Definition at line 47 of file uint128.cpp.

48 :hi(0), lo(0)
49 {
50 // do we have at least one character?
51 if(!sz.empty()) {
52 // make some reasonable assumptions
53 int radix = 10;
54 bool minus = false;
55
56 std::string::const_iterator i = sz.begin();
57
58 // check for minus sign, i suppose technically this should only apply
59 // to base 10, but who says that -0x1 should be invalid?
60 if(*i == '-') {
61 ++i;
62 minus = true;
63 }
64
65 // check if there is radix changing prefix (0 or 0x)
66 if(i != sz.end()) {
67 if(*i == '0') {
68 radix = 8;
69 ++i;
70 if(i != sz.end()) {
71 if(*i == 'x') {
72 radix = 16;
73 ++i;
74 }
75 }
76 }
77
78 while(i != sz.end()) {
79 unsigned int n = 0;
80 const char ch = *i;
81
82 if(ch >= 'A' && ch <= 'Z') {
83 if(((ch - 'A') + 10) < radix) {
84 n = (ch - 'A') + 10;
85 } else {
86 break;
87 }
88 } else if(ch >= 'a' && ch <= 'z') {
89 if(((ch - 'a') + 10) < radix) {
90 n = (ch - 'a') + 10;
91 } else {
92 break;
93 }
94 } else if(ch >= '0' && ch <= '9') {
95 if((ch - '0') < radix) {
96 n = (ch - '0');
97 } else {
98 break;
99 }
100 } else {
101 /* completely invalid character */
102 break;
103 }
104
105 (*this) *= radix;
106 (*this) += n;
107
108 ++i;
109 }
110 }
111
112 // if this was a negative number, do that two's compliment madness :-P
113 if(minus) {
114 *this = -*this;
115 }
116 }
117 }
static const Reg8 ch(Operand::CH)

◆ uint128() [7/9]

fc::uint128::uint128 ( uint64_t _h,
uint64_t _l )
inline

Definition at line 32 of file uint128.hpp.

33 :hi(_h),lo(_l){}

◆ uint128() [8/9]

fc::uint128::uint128 ( const fc::bigint & bi)

Definition at line 126 of file uint128.cpp.

127 {
128 *this = uint128( std::string(bi) ); // TODO: optimize this...
129 }

◆ uint128() [9/9]

fc::uint128::uint128 ( unsigned __int128 i)
inlineexplicit

Definition at line 35 of file uint128.hpp.

35:hi( i >> 64 ), lo(i){ }

Member Function Documentation

◆ full_product()

void fc::uint128::full_product ( const uint128 & a,
const uint128 & b,
uint128 & result_hi,
uint128 & result_lo )
static

Definition at line 297 of file uint128.cpp.

298 {
299 // (ah * 2**64 + al) * (bh * 2**64 + bl)
300 // = (ah * bh * 2**128 + al * bh * 2**64 + ah * bl * 2**64 + al * bl
301 // = P * 2**128 + (Q + R) * 2**64 + S
302 // = Ph * 2**192 + Pl * 2**128
303 // + Qh * 2**128 + Ql * 2**64
304 // + Rh * 2**128 + Rl * 2**64
305 // + Sh * 2**64 + Sl
306 //
307
308 uint64_t ah = a.hi;
309 uint64_t al = a.lo;
310 uint64_t bh = b.hi;
311 uint64_t bl = b.lo;
312
313 uint128 s = al;
314 s *= bl;
315 uint128 r = ah;
316 r *= bl;
317 uint128 q = al;
318 q *= bh;
319 uint128 p = ah;
320 p *= bh;
321
322 uint64_t sl = s.lo;
323 uint64_t sh = s.hi;
324 uint64_t rl = r.lo;
325 uint64_t rh = r.hi;
326 uint64_t ql = q.lo;
327 uint64_t qh = q.hi;
328 uint64_t pl = p.lo;
329 uint64_t ph = p.hi;
330
331 uint64_t y[4]; // final result
332 y[0] = sl;
333
334 uint128 acc = sh;
335 acc += ql;
336 acc += rl;
337 y[1] = acc.lo;
338 acc = acc.hi;
339 acc += qh;
340 acc += rh;
341 acc += pl;
342 y[2] = acc.lo;
343 y[3] = acc.hi + ph;
344
345 result_hi = uint128( y[3], y[2] );
346 result_lo = uint128( y[1], y[0] );
347
348 return;
349 }
const mie::Vuint & p
Definition bn.cpp:27
const mie::Vuint & r
Definition bn.cpp:28
static const Reg8 ah(Operand::AH)
static const Reg8 bh(Operand::BH)
static const Reg8 bl(Operand::BL)
uint64_t y
Definition sha3.cpp:34
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
unsigned __int64 uint64_t
Definition stdint.h:136
char * s

◆ high_bits()

uint64_t fc::uint128::high_bits ( ) const
inline

Definition at line 109 of file uint128.hpp.

109{ return hi; }
Here is the caller graph for this function:

◆ low_32_bits()

uint32_t fc::uint128::low_32_bits ( ) const
inline

Definition at line 107 of file uint128.hpp.

107{ return (uint32_t) lo; }
unsigned int uint32_t
Definition stdint.h:126

◆ low_bits()

uint64_t fc::uint128::low_bits ( ) const
inline

Definition at line 108 of file uint128.hpp.

108{ return lo; }
Here is the caller graph for this function:

◆ max_value()

static uint128 fc::uint128::max_value ( )
inlinestatic

Definition at line 111 of file uint128.hpp.

111 {
112 const uint64_t max64 = std::numeric_limits<uint64_t>::max();
113 return uint128( max64, max64 );
114 }
Here is the call graph for this function:

◆ operator fc::bigint()

fc::uint128::operator fc::bigint ( ) const

◆ operator std::string()

fc::uint128::operator std::string ( ) const

Definition at line 131 of file uint128.cpp.

132 {
133 if(*this == 0) { return "0"; }
134
135 // at worst it will be size digits (base 2) so make our buffer
136 // that plus room for null terminator
137 static char sz [128 + 1];
138 sz[sizeof(sz) - 1] = '\0';
139
140 uint128 ii(*this);
141 int i = 128 - 1;
142
143 while (ii != 0 && i) {
144
145 uint128 remainder;
146 divide(ii, uint128(10), ii, remainder);
147 sz [--i] = "0123456789abcdefghijklmnopqrstuvwxyz"[remainder.to_integer()];
148 }
149
150 return &sz[i];
151 }
Here is the call graph for this function:

◆ operator unsigned __int128()

fc::uint128::operator unsigned __int128 ( ) const
inlineexplicit

Definition at line 40 of file uint128.hpp.

40 {
41 unsigned __int128 result(hi);
42 result <<= 64;
43 return result | lo;
44 }

◆ operator!()

bool fc::uint128::operator! ( ) const
inline

Definition at line 50 of file uint128.hpp.

50{ return !(hi !=0 || lo != 0); }

◆ operator!=()

bool fc::uint128::operator!= ( const uint128 & o) const
inline

Definition at line 47 of file uint128.hpp.

47{ return hi != o.hi || lo != o.lo; }

◆ operator%=()

uint128 & fc::uint128::operator%= ( const uint128 & u)

Definition at line 250 of file uint128.cpp.

251 {
252 uint128 quotient;
253 divide(*this, b, quotient, *this);
254 return *this;
255 }

◆ operator&=()

uint128 & fc::uint128::operator&= ( const uint128 & u)
inline

Definition at line 60 of file uint128.hpp.

60{ hi &= u.hi; lo &= u.lo; return *this; }

◆ operator*=()

uint128 & fc::uint128::operator*= ( const uint128 & u)

Definition at line 257 of file uint128.cpp.

258 {
259 uint64_t a0 = (uint32_t) (this->lo );
260 uint64_t a1 = (uint32_t) (this->lo >> 0x20);
261 uint64_t a2 = (uint32_t) (this->hi );
262 uint64_t a3 = (uint32_t) (this->hi >> 0x20);
263
264 uint64_t b0 = (uint32_t) (b.lo );
265 uint64_t b1 = (uint32_t) (b.lo >> 0x20);
266 uint64_t b2 = (uint32_t) (b.hi );
267 uint64_t b3 = (uint32_t) (b.hi >> 0x20);
268
269 // (a0 + (a1 << 0x20) + (a2 << 0x40) + (a3 << 0x60)) *
270 // (b0 + (b1 << 0x20) + (b2 << 0x40) + (b3 << 0x60)) =
271 // a0 * b0
272 //
273 // (a1 * b0 + a0 * b1) << 0x20
274 // (a2 * b0 + a1 * b1 + a0 * b2) << 0x40
275 // (a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3) << 0x60
276 //
277 // all other cross terms are << 0x80 or higher, thus do not appear in result
278
279 this->hi = 0;
280 this->lo = a3*b0;
281 (*this) += a2*b1;
282 (*this) += a1*b2;
283 (*this) += a0*b3;
284 (*this) <<= 0x20;
285 (*this) += a2*b0;
286 (*this) += a1*b1;
287 (*this) += a0*b2;
288 (*this) <<= 0x20;
289 (*this) += a1*b0;
290 (*this) += a0*b1;
291 (*this) <<= 0x20;
292 (*this) += a0*b0;
293
294 return *this;
295 }

◆ operator++() [1/2]

uint128 & fc::uint128::operator++ ( )
inline

Definition at line 54 of file uint128.hpp.

54{ hi += (++lo == 0); return *this; }

◆ operator++() [2/2]

uint128 fc::uint128::operator++ ( int )
inline

Definition at line 56 of file uint128.hpp.

56{ auto tmp = *this; ++(*this); return tmp; }

◆ operator+=()

uint128 & fc::uint128::operator+= ( const uint128 & u)
inline

Definition at line 65 of file uint128.hpp.

65{ const uint64_t old = lo; lo += u.lo; hi += u.hi + (lo < old); return *this; }

◆ operator-()

uint128 fc::uint128::operator- ( ) const
inline

Definition at line 51 of file uint128.hpp.

51{ return ++uint128( ~hi, ~lo ); }
Here is the call graph for this function:

◆ operator--() [1/2]

uint128 & fc::uint128::operator-- ( )
inline

Definition at line 55 of file uint128.hpp.

55{ hi -= (lo-- == 0); return *this; }

◆ operator--() [2/2]

uint128 fc::uint128::operator-- ( int )
inline

Definition at line 57 of file uint128.hpp.

57{ auto tmp = *this; --(*this); return tmp; }

◆ operator-=()

uint128 & fc::uint128::operator-= ( const uint128 & u)
inline

Definition at line 66 of file uint128.hpp.

66{ return *this += -u; }

◆ operator/=()

uint128 & fc::uint128::operator/= ( const uint128 & u)

Definition at line 224 of file uint128.cpp.

225 {
226 auto self = (m128(hi) << 64) + m128(lo);
227 auto other = (m128(b.hi) << 64) + m128(b.lo);
228 self /= other;
229 hi = static_cast<uint64_t>(self >> 64);
230 lo = static_cast<uint64_t>((self << 64 ) >> 64);
231
232 /*
233 uint128 remainder;
234 divide(*this, b, *this, remainder ); //, *this);
235 if( tmp.hi != hi || tmp.lo != lo ) {
236 std::cerr << tmp.hi << " " << hi <<"\n";
237 std::cerr << tmp.lo << " " << lo << "\n";
238 exit(1);
239 }
240 */
241
242 /*
243 const auto& b128 = std::reinterpret_cast<const m128&>(b);
244 auto& this128 = std::reinterpret_cast<m128&>(*this);
245 this128 /= b128;
246 */
247 return *this;
248 }
boost::multiprecision::uint128_t m128
Definition uint128.cpp:11
@ self
the connection is to itself
Definition protocol.hpp:48

◆ operator<() [1/2]

bool fc::uint128::operator< ( const int64_t & o) const
inline

Definition at line 49 of file uint128.hpp.

49{ return *this < uint128(o); }
Here is the call graph for this function:

◆ operator<() [2/2]

bool fc::uint128::operator< ( const uint128 & o) const
inline

Definition at line 48 of file uint128.hpp.

48{ return (hi == o.hi) ? lo < o.lo : hi < o.hi; }

◆ operator<<=()

uint128 & fc::uint128::operator<<= ( const uint128 & u)

Definition at line 154 of file uint128.cpp.

155 {
156 if(rhs >= 128)
157 {
158 hi = 0;
159 lo = 0;
160 }
161 else
162 {
163 unsigned int n = rhs.to_integer();
164 const unsigned int halfsize = 128 / 2;
165
166 if(n >= halfsize){
167 n -= halfsize;
168 hi = lo;
169 lo = 0;
170 }
171
172 if(n != 0) {
173 // shift high half
174 hi <<= n;
175
176 const uint64_t mask(~(uint64_t(-1) >> n));
177
178 // and add them to high half
179 hi |= (lo & mask) >> (halfsize - n);
180
181 // and finally shift also low half
182 lo <<= n;
183 }
184 }
185
186 return *this;
187 }
Here is the call graph for this function:

◆ operator==()

bool fc::uint128::operator== ( const uint128 & o) const
inline

Definition at line 46 of file uint128.hpp.

46{ return hi == o.hi && lo == o.lo; }

◆ operator>>=()

uint128 & fc::uint128::operator>>= ( const uint128 & u)

Definition at line 189 of file uint128.cpp.

190 {
191 if(rhs >= 128)
192 {
193 hi = 0;
194 lo = 0;
195 }
196 else
197 {
198 unsigned int n = rhs.to_integer();
199 const unsigned int halfsize = 128 / 2;
200
201 if(n >= halfsize) {
202 n -= halfsize;
203 lo = hi;
204 hi = 0;
205 }
206
207 if(n != 0) {
208 // shift low half
209 lo >>= n;
210
211 // get lower N bits of high half
212 const uint64_t mask(~(uint64_t(-1) << n));
213
214 // and add them to low qword
215 lo |= (hi & mask) << (halfsize - n);
216
217 // and finally shift also high half
218 hi >>= n;
219 }
220 }
221 return *this;
222 }
Here is the call graph for this function:

◆ operator^=()

uint128 & fc::uint128::operator^= ( const uint128 & u)
inline

Definition at line 61 of file uint128.hpp.

61{ hi ^= u.hi; lo ^= u.lo; return *this; }

◆ operator|=()

uint128 & fc::uint128::operator|= ( const uint128 & u)
inline

Definition at line 59 of file uint128.hpp.

59{ hi |= u.hi; lo |= u.lo; return *this; }

◆ operator~()

uint128 fc::uint128::operator~ ( ) const
inline

Definition at line 52 of file uint128.hpp.

52{ return uint128( ~hi, ~lo ); }
Here is the call graph for this function:

◆ popcount()

uint8_t fc::uint128::popcount ( ) const

Definition at line 372 of file uint128.cpp.

373 {
374 return _popcount_64( lo ) + _popcount_64( hi );
375 }

◆ to_integer()

uint32_t fc::uint128::to_integer ( ) const
inline

Definition at line 95 of file uint128.hpp.

96 {
97 FC_ASSERT( hi == 0 );
98 uint32_t lo32 = (uint32_t) lo;
99 FC_ASSERT( lo == lo32 );
100 return lo32;
101 }
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Here is the caller graph for this function:

◆ to_uint64()

uint64_t fc::uint128::to_uint64 ( ) const
inline

Definition at line 102 of file uint128.hpp.

103 {
104 FC_ASSERT( hi == 0 );
105 return lo;
106 }

Friends And Related Symbol Documentation

◆ hash_value

std::size_t hash_value ( const uint128 & v)
friend

Definition at line 93 of file uint128.hpp.

93{ return city_hash_size_t((const char*)&v, sizeof(v)); }
size_t city_hash_size_t(const char *buf, size_t len)
Definition city.hpp:62

◆ operator%

uint128 operator% ( const uint128 & l,
const uint128 & r )
friend

Definition at line 76 of file uint128.hpp.

76{ return uint128(l)%=r; }

◆ operator&

uint128 operator& ( const uint128 & l,
const uint128 & r )
friend

Definition at line 78 of file uint128.hpp.

78{ return uint128(l)&=r; }

◆ operator*

uint128 operator* ( const uint128 & l,
const uint128 & r )
friend

Definition at line 74 of file uint128.hpp.

74{ return uint128(l)*=r; }

◆ operator+

uint128 operator+ ( const uint128 & l,
const uint128 & r )
friend

Definition at line 72 of file uint128.hpp.

72{ return uint128(l)+=r; }

◆ operator-

uint128 operator- ( const uint128 & l,
const uint128 & r )
friend

Definition at line 73 of file uint128.hpp.

73{ return uint128(l)-=r; }

◆ operator/

uint128 operator/ ( const uint128 & l,
const uint128 & r )
friend

Definition at line 75 of file uint128.hpp.

75{ return uint128(l)/=r; }

◆ operator<<

uint128 operator<< ( const uint128 & l,
const uint128 & r )
friend

Definition at line 80 of file uint128.hpp.

80{ return uint128(l)<<=r; }

◆ operator<= [1/3]

bool operator<= ( const int64_t & l,
const uint128 & r )
friend

Definition at line 91 of file uint128.hpp.

91{ return uint128(l) <= r; }

◆ operator<= [2/3]

bool operator<= ( const uint128 & l,
const int64_t & r )
friend

Definition at line 90 of file uint128.hpp.

90{ return l <= uint128(r); }

◆ operator<= [3/3]

bool operator<= ( const uint128 & l,
const uint128 & r )
friend

Definition at line 89 of file uint128.hpp.

89{ return l == r || l < r; }

◆ operator> [1/3]

bool operator> ( const int64_t & l,
const uint128 & r )
friend

Definition at line 84 of file uint128.hpp.

84{ return r < uint128(l); }

◆ operator> [2/3]

bool operator> ( const uint128 & l,
const int64_t & r )
friend

Definition at line 83 of file uint128.hpp.

83{ return uint128(r) < l; }

◆ operator> [3/3]

bool operator> ( const uint128 & l,
const uint128 & r )
friend

Definition at line 82 of file uint128.hpp.

82{ return r < l; }

◆ operator>= [1/3]

bool operator>= ( const int64_t & l,
const uint128 & r )
friend

Definition at line 88 of file uint128.hpp.

88{ return uint128(l) >= r; }

◆ operator>= [2/3]

bool operator>= ( const uint128 & l,
const int64_t & r )
friend

Definition at line 87 of file uint128.hpp.

87{ return l >= uint128(r); }

◆ operator>= [3/3]

bool operator>= ( const uint128 & l,
const uint128 & r )
friend

Definition at line 86 of file uint128.hpp.

86{ return l == r || l > r; }

◆ operator>>

uint128 operator>> ( const uint128 & l,
const uint128 & r )
friend

Definition at line 81 of file uint128.hpp.

81{ return uint128(l)>>=r; }

◆ operator^

uint128 operator^ ( const uint128 & l,
const uint128 & r )
friend

Definition at line 79 of file uint128.hpp.

79{ return uint128(l)^=r; }

◆ operator|

uint128 operator| ( const uint128 & l,
const uint128 & r )
friend

Definition at line 77 of file uint128.hpp.

77{ return uint128(l)|=(r); }

Member Data Documentation

◆ hi

uint64_t fc::uint128::hi

Definition at line 121 of file uint128.hpp.

◆ lo

uint64_t fc::uint128::lo

Definition at line 122 of file uint128.hpp.


The documentation for this class was generated from the following files: