Algorithms_in_C++  1.0.0
Set of algorithms implemented in C++.
uint128_t.hpp
Go to the documentation of this file.
1 /**
2  * @file
3  *
4  * @details Implementation of 128-bit unsigned integers.
5  * @note The implementation can be flagged as not completed. This header is used
6  * with enough operations as a part of bigger integer types 256-bit integer.
7  * @author [Ashish Daulatabad](https://github.com/AshishYUO)
8  */
9 
10 #include <algorithm> /// for `std::reverse` and other operations
11 #include <ostream> /// for `std::cout` overload
12 #include <string> /// for `std::string`
13 #include <utility> /// for `std::pair` library
14 
15 #ifdef _MSC_VER
16 #include <intrin.h> /// for _BitScanForward64 and __BitScanReverse64 operation
17 #endif
18 
19 #ifndef CIPHERS_UINT128_T_HPP_
20 #define CIPHERS_UINT128_T_HPP_
21 class uint128_t;
22 
23 template <>
25 template <>
27 template <>
29 
30 /**
31  * @brief Adding two string
32  * @details Adds two long integer, only used for printing numbers
33  * @param first First integer string
34  * @param second Second integer string
35  * @returns string denoting the addition of both the strings
36  */
37 std::string add(const std::string &first, const std::string &second) {
38  std::string third;
39  int16_t sum = 0, carry = 0;
40  for (int32_t i = static_cast<int32_t>(first.size()) - 1,
41  j = static_cast<int32_t>(second.size()) - 1;
42  i >= 0 || j >= 0; --i, --j) {
43  sum = ((i >= 0 ? first[i] - '0' : 0) + (j >= 0 ? second[j] - '0' : 0) +
44  carry);
45  carry = sum / 10;
46  sum %= 10;
47  third.push_back(sum + '0');
48  }
49  if (carry) {
50  third.push_back('1');
51  }
52  std::reverse(third.begin(), third.end());
53  return third;
54 }
55 /**
56  * @class uint128_t
57  * @brief class for 128-bit unsigned integer
58  */
59 class uint128_t {
60  uint64_t f{}, s{}; /// First and second half of 128 bit number
61 
62  /**
63  * @brief Get integer from given string.
64  * @details Create an integer from a given string
65  * @param str integer string, can be hexadecimal (starting on 0x... or
66  * number)
67  * @returns void
68  */
70  this->f = this->s = 0;
71  if (str.size() > 1 && str[1] == 'x') { // if hexadecimal
72  for (auto i = 2; i < str.size(); ++i) {
73  *this *= 16LL;
74  if (str[i] >= '0' && str[i] <= '9') {
75  *this += (str[i] - '0');
76  } else if (str[i] >= 'A' && str[i] <= 'F') {
77  *this += (str[i] - 'A' + 10);
78  } else if (str[i] >= 'a' && str[i] <= 'f') {
79  *this += (str[i] - 'a' + 10);
80  }
81  }
82  } else { // if decimal
83  for (auto &x : str) {
84  *this *= 10LL;
85  *this += (x - '0');
86  }
87  }
88  }
89 
90  public:
91  uint128_t() = default;
92 
93  /**
94  * @brief Parameterized constructor
95  * @tparam T integral type
96  * @param low lower part 8-bit unisgned integer
97  */
98  template <typename T, typename = typename std::enable_if<
100  explicit uint128_t(T low) : s(low) {}
101 
102  /**
103  * @brief Parameterized constructor
104  * @param str Integer string (hexadecimal starting with 0x.. or decimal)
105  */
106  explicit uint128_t(const std::string &str) {
108  }
109 
110  /**
111  * @brief Parameterized constructor
112  * @param high higher part 64-bit unsigned integer
113  * @param low lower part 64-bit unsigned integer
114  */
115  uint128_t(const uint64_t high, const uint64_t low) : f(high), s(low) {}
116 
117  /**
118  * @brief Copy constructor
119  * @param num 128-bit unsigned integer
120  */
121  uint128_t(const uint128_t &num) = default;
122 
123  /**
124  * @brief Move constructor
125  * @param num 128-bit unsigned integer
126  */
127  uint128_t(uint128_t &&num) noexcept : f(num.f), s(num.s) {}
128 
129  /**
130  * @brief Destructor for uint128_t
131  */
132  ~uint128_t() = default;
133 
134  /**
135  * @brief Leading zeroes in binary
136  * @details Calculates leading zeros in 128-bit integer
137  * @returns Integer denoting leading zeroes
138  */
139  inline uint32_t _lez() {
140 #ifndef _MSC_VER
141  if (f) {
142  return __builtin_clzll(f);
143  }
144  return 64 + __builtin_clzll(s);
145 #else
146  unsigned long r = 0;
147  _BitScanForward64(&r, f);
148  if (r == 64) {
149  unsigned long l = 0;
150  _BitScanForward64(&l, s);
151  return 64 + l;
152  }
153  return r;
154 #endif
155  }
156 
157  /**
158  * @brief Trailing zeroes in binary
159  * @details Calculates leading zeros in 128-bit integer
160  * @returns Integer denoting Trailing zeroes
161  */
162  inline uint32_t _trz() {
163 #ifndef _MSC_VER
164  if (f) {
165  return __builtin_ctzll(f);
166  }
167  return 64 + __builtin_ctzll(s);
168 #else
169  unsigned long r = 0;
170  _BitScanReverse64(&r, s);
171  if (r == 64) {
172  unsigned long l = 0;
173  _BitScanReverse64(&l, f);
174  return 64 + l;
175  }
176  return r;
177 #endif
178  }
179 
180  /**
181  * @brief casting operator to boolean value
182  * @returns true if value of this is non-zero, else false
183  */
184  inline explicit operator bool() const { return (f || s); }
185 
186  /**
187  * @brief casting operator to any integer valu
188  * @tparam T any integer type
189  * @returns integer value casted to mentioned type
190  */
191  template <typename T, typename = typename std::enable_if<
192  std::is_integral<T>::value, T>::type>
193  inline explicit operator T() const {
194  return static_cast<T>(s);
195  }
196 
197  /**
198  * @brief returns lower 64-bit integer part
199  * @returns returns lower 64-bit integer part
200  */
201  inline uint64_t lower() const { return s; }
202 
203  /**
204  * @brief returns upper 64-bit integer part
205  * @returns returns upper 64-bit integer part
206  */
207  inline uint64_t upper() const { return f; }
208 
209  /**
210  * @brief operator = for other types
211  * @tparam T denoting any integer type
212  * @param p an integer to assign it's value
213  * @returns this pointer with it's value equal to `p`
214  */
215  template <typename T, typename = typename std::enable_if<
216  std::is_integral<T>::value, T>::type>
217  inline uint128_t &operator=(const T &p) {
218  this->s = p;
219  return *this;
220  }
221 
222  /**
223  * @brief operator = for type string
224  * @param p a string to assign it's value to equivalent integer
225  * @returns this pointer with it's value equal to `p`
226  */
227  inline uint128_t &operator=(const std::string &p) {
228  this->__get_integer_from_string(p);
229  return *this;
230  }
231 
232  /**
233  * @brief operator = for uint128_t
234  * @param p an 128-bit integer to assign it's value
235  * @returns this pointer with it's value equal to `p`
236  */
237  inline uint128_t &operator=(const uint128_t &p) = default;
238 
239  /**
240  * @brief Move assignment operator
241  */
242  inline uint128_t &operator=(uint128_t &&p) = default;
243 
244  /**
245  * @brief operator + for uint128_t and other integer types.
246  * @tparam T denoting integral type
247  * @param p a type of integer variable
248  * @returns addition of this and p, returning uint128_t integer
249  */
250  template <typename T, typename = typename std::enable_if<
251  std::is_integral<T>::value, T>::type>
252  inline uint128_t operator+(const T p) {
253  return uint128_t(f + (p + s < s), p + s);
254  }
255 
256  /**
257  * @brief operator + for uint128_t and other integer types.
258  * @param p 128-bit unsigned integer
259  * @returns addition of this and p, returning uint128_t integer
260  */
261  inline uint128_t operator+(const uint128_t &p) {
262  return uint128_t(f + (p.s + s < s) + p.f, p.s + s);
263  }
264 
265  /**
266  * @brief operator += for uint128_t and other integer types.
267  * @tparam T denoting integral type
268  * @param p a type of integer variable
269  * @returns addition of this and p, returning this
270  */
271  template <typename T, typename = typename std::enable_if<
272  std::is_integral<T>::value, T>::type>
273  inline uint128_t &operator+=(const T p) {
274  bool app = p + s < s;
275  this->f += app;
276  this->s += p;
277  return *this;
278  }
279 
280  /**
281  * @brief operator += for uint128_t
282  * @param p 128-bit unsigned integer
283  * @returns addition of this and p, returning this
284  */
286  bool app = p.s + s < s;
287  f = f + app + p.f;
288  s = p.s + s;
289  return *this;
290  }
291 
292  /**
293  * @brief pre-increment operator
294  * @returns incremented value of this.
295  */
296  inline uint128_t &operator++() {
297  *this += 1;
298  return *this;
299  }
300 
301  /**
302  * @brief post-increment operator
303  * @returns incremented value of this.
304  */
305  inline uint128_t operator++(int) {
306  ++*this;
307  return *this;
308  }
309 
310  /**
311  * @brief operator - for uint128_t and other integer types.
312  * @tparam T denoting integral type
313  * @param p a type of integer variable
314  * @returns subtraction of this and p, returning uint128_t integer
315  */
316  template <typename T, typename = typename std::enable_if<
317  std::is_integral<T>::value, T>::type>
318  inline uint128_t operator-(const T &p) {
319  bool app = p > s;
320  return uint128_t(f - app, s - p);
321  }
322 
323  /**
324  * @brief operator - for uint128_t
325  * @param p a type of integer variable
326  * @returns subtraction of this and p, returning uint128_t integer
327  */
328  inline uint128_t operator-(const uint128_t &p) {
329  bool app = p.s > s;
330  return uint128_t(f - p.f - app, s - p.s);
331  }
332 
333  /**
334  * @brief operator - using twos complement
335  * @returns 2's complement of this.
336  */
337  inline uint128_t operator-() { return ~*this + uint128_t(1); }
338 
339  /**
340  * @brief operator -- (pre-decrement)
341  * @returns decremented value of this
342  */
343  inline uint128_t &operator--() {
344  *this -= 1;
345  return *this;
346  }
347 
348  /**
349  * @brief operator -- (post-decrement)
350  * @returns decremented value of this
351  */
352  inline uint128_t operator--(int p) {
353  --*this;
354  return *this;
355  }
356 
357  /**
358  * @brief operator -= for uint128_t and other integer types.
359  * @tparam T denoting integral type
360  * @param p a type of integer variable
361  * @returns subtraction of this and p, returning this
362  */
363  template <typename T, typename = typename std::enable_if<
364  std::is_integral<T>::value, T>::type>
365  uint128_t &operator-=(const T &p) {
366  bool app = p > s;
367  f -= app;
368  s -= p;
369  return *this;
370  }
371 
372  /**
373  * @brief operator -= for uint128_t
374  * @param p 128-bit unsigned integer
375  * @returns subtraction of this and p, returning this
376  */
378  bool app = p.s > s;
379  f = f - p.f - app;
380  s = s - p.s;
381  return *this;
382  }
383 
384  /**
385  * @brief operator * for uint128_t and other integer types.
386  * @tparam T denoting integral type
387  * @param p a type of integer variable
388  * @returns multiplication of this and p, returning uint128_t integer
389  */
390  template <typename T, typename = typename std::enable_if<
391  std::is_integral<T>::value, T>::type>
392  inline uint128_t operator*(const T p) {
393  return *this * uint128_t(p);
394  }
395 
396  /**
397  * @brief operator * for uint128_t and other integer types.
398  * @param p 128-bit unsigned integer
399  * @returns multiplication of this and p, returning uint128_t integer
400  */
402  uint64_t f_first = s >> 32, f_second = s & 0xFFFFFFFF,
403  s_first = p.s >> 32, s_second = p.s & 0xFFFFFFFF;
404  uint64_t fi = f_first * s_first, se = f_first * s_second,
405  th = s_first * f_second, fo = s_second * f_second;
406  uint64_t tmp = ((se & 0xFFFFFFFF) << 32), tmp2 = (th & 0xFFFFFFFF)
407  << 32;
408  int cc = (tmp + tmp2 < tmp);
409  tmp += tmp2;
410  cc += (tmp + fo < tmp);
411  uint64_t carry = fi + (se >> 32) + (th >> 32);
412  return uint128_t(this->f * p.s + this->s * p.f + carry + cc, tmp + fo);
413  }
414 
415  /**
416  * @brief operator *= for uint128_t and other integer types.
417  * @tparam T denoting integral type
418  * @param p a type of integer variable
419  * @returns multiplication of this and p, returning this
420  */
421  template <typename T, typename = typename std::enable_if<
422  std::is_integral<T>::value, T>::type>
423  inline uint128_t &operator*=(const T p) {
424  *this *= uint128_t(p);
425  return *this;
426  }
427 
428  /**
429  * @brief operator *= for uint128_t and other integer types.
430  * @param p 128-bit unsigned integer
431  * @returns multiplication of this and p, returning this
432  */
434  uint64_t f_first = s >> 32, f_second = s & 0xFFFFFFFF,
435  s_first = p.s >> 32, s_second = p.s & 0xFFFFFFFF;
436  uint64_t fi = f_first * s_first, se = f_first * s_second,
437  th = s_first * f_second, fo = s_second * f_second;
438  uint64_t tmp = (se << 32), tmp2 = (th << 32);
439  int cc = (tmp + tmp2 < tmp);
440  tmp += tmp2;
441  cc += (tmp + fo < tmp);
442  uint64_t carry = fi + (se >> 32) + (th >> 32);
443  f = this->f * p.s + this->s * p.f + carry + cc;
444  s = tmp + fo;
445  return *this;
446  }
447 
448  /**
449  * @brief divide function for uint128_t and other integer types.
450  * @details divide this value and
451  * @param p 128-bit unsigned integer
452  * @returns pair denoting quotient and remainder.
453  */
455  if (*this < p) { // if this is less than divisor
456  return {uint128_t(0), *this};
457  } else if (*this == p) { // if this is equal to divisor
458  return {uint128_t(1), uint128_t(0)};
459  }
460  uint128_t tmp = p, tmp2 = *this;
461  uint16_t left = tmp._lez() - _lez();
462  tmp <<= left;
463  uint128_t quotient(0);
464  uint128_t zero(0);
465  while (left >= 0 && tmp2 >= p) {
466  uint16_t shf = tmp2._lez() - tmp._lez();
467  if (shf) {
468  tmp >>= shf;
469  quotient <<= shf;
470  left -= shf;
471  }
472  if (tmp2 < tmp) {
473  tmp >>= 1;
474  quotient <<= 1;
475  --left;
476  }
477  tmp2 -= tmp;
478  ++quotient;
479  }
480  return {quotient << left, tmp2};
481  }
482 
483  /**
484  * @brief operator / for uint128_t and other integer types.
485  * @param p 128-bit unsigned integer
486  * @returns unsigned 128-bit quotient.
487  */
488  inline uint128_t operator/(const uint128_t &p) { return divide(p).first; }
489 
490  /**
491  * @brief operator / for uint128_t and other integer types.
492  * @tparam T denoting integral type
493  * @param p a type of integer variable
494  * @returns unsigned 128-bit quotient.
495  */
496  template <typename T, typename = typename std::enable_if<
497  std::is_integral<T>::value, T>::type>
498  inline uint128_t operator/(const T p) {
499  uint128_t tmp = *this;
500  tmp /= uint128_t(0, p);
501  return tmp;
502  }
503 
504  /**
505  * @brief operator /= for uint128_t
506  * @param p 128-bit unsigned integer
507  * @returns this set as unsigned 128-bit quotient.
508  */
509  inline uint128_t &operator/=(const uint128_t &p) {
510  *this = divide(p).first;
511  return *this;
512  }
513 
514  /**
515  * @brief operator /= for uint128_t and other integer types.
516  * @tparam T denoting integral type
517  * @param p a type of integer variable
518  * @returns this set as unsigned 128-bit quotient.
519  */
520  template <typename T, typename = typename std::enable_if<
521  std::is_integral<T>::value, T>::type>
522  inline uint128_t &operator/=(const T p) {
523  *this /= uint128_t(0, p);
524  return *this;
525  }
526 
527  /**
528  * @brief operator % for uint128_t
529  * @param p 128-bit unsigned integer
530  * @returns unsigned 128-bit remainder.
531  */
532  inline uint128_t operator%(const uint128_t &p) { return divide(p).second; }
533 
534  /**
535  * @brief operator % for uint128_t and other integer types.
536  * @tparam T denoting integral type
537  * @param p a type of integer variable
538  * @returns unsigned 128-bit remainder.
539  */
540  template <typename T, typename = typename std::enable_if<
541  std::is_integral<T>::value, T>::type>
542  inline uint128_t operator%(const T &p) {
543  return *this % uint128_t(p);
544  }
545 
546  /**
547  * @brief operator %= for uint128_t
548  * @param p 128-bit unsigned integer
549  * @returns this set as unsigned 128-bit remainder.
550  */
551  inline uint128_t &operator%=(const uint128_t &p) {
552  *this = divide(p).second;
553  return *this;
554  }
555 
556  /**
557  * @brief operator %= for uint128_t
558  * @tparam T denoting integral type
559  * @param p a type of integer variable
560  * @returns this set as unsigned 128-bit remainder.
561  */
562  template <typename T, typename = typename std::enable_if<
563  std::is_integral<T>::value, T>::type>
564  inline uint128_t &operator%=(const T &p) {
565  *this %= uint128_t(p);
566  return *this;
567  }
568 
569  /**
570  * @brief operator < for uint128_t
571  * @param other number to be compared with this
572  * @returns true if this is less than other, else false
573  */
574  inline bool operator<(const uint128_t &other) {
575  return f < other.f || (f == other.f && s < other.s);
576  }
577 
578  /**
579  * @brief operator <= for uint128_t
580  * @param other number to be compared with this
581  * @returns true if this is less than or equal to other, else false
582  */
583  inline bool operator<=(const uint128_t &other) {
584  return f < other.f || (f == other.f && s <= other.s);
585  }
586 
587  /**
588  * @brief operator > for uint128_t
589  * @param other number to be compared with this
590  * @returns true if this is greater than other, else false
591  */
592  inline bool operator>(const uint128_t &other) {
593  return f > other.f || (f == other.f && s > other.s);
594  }
595 
596  /**
597  * @brief operator >= for uint128_t
598  * @param other number to be compared with this
599  * @returns true if this is greater than or equal than other, else false
600  */
601  inline bool operator>=(const uint128_t &other) {
602  return (f > other.f) || (f == other.f && s >= other.s);
603  }
604 
605  /**
606  * @brief operator == for uint128_t
607  * @param other number to be compared with this
608  * @returns true if this is equal than other, else false
609  */
610  inline bool operator==(const uint128_t &other) {
611  return f == other.f && s == other.s;
612  }
613 
614  /**
615  * @brief operator != for uint128_t
616  * @param other number to be compared with this
617  * @returns true if this is not equal than other, else false
618  */
619  inline bool operator!=(const uint128_t &other) {
620  return f != other.f || s != other.s;
621  }
622 
623  /**
624  * @brief operator ! for uint128_t
625  * @returns true if this has zero value, else false
626  */
627  inline bool operator!() { return !f && !s; }
628 
629  /**
630  * @brief operator && for uint128_t
631  * @param b number to be compared with this
632  * @returns true if both of the values are not zero, else false
633  */
634  inline bool operator&&(const uint128_t &b) {
635  return (s || f) && (b.s || b.f);
636  }
637 
638  /**
639  * @brief operator || for uint128_t
640  * @param b number to be compared with this
641  * @returns true if one of the values are not zero, else false
642  */
643  inline bool operator||(const uint128_t &b) {
644  return (s || f) || (b.s || b.f);
645  }
646 
647  /**
648  * @brief operator () for uint128_t
649  * @returns true if this value is non-zero, else false
650  */
651  inline bool operator()() { return s || f; }
652 
653  /**
654  * @brief operator < for other types
655  * @tparam T integral type
656  * @param other number to be compared with this
657  * @returns true if this is less than other, else false
658  */
659  template <typename T, typename = typename std::enable_if<
660  std::is_integral<T>::value, T>::type>
661  inline bool operator<(const T other) {
662  return *this < uint128_t(other);
663  }
664 
665  /**
666  * @brief operator <= for other types
667  * @tparam T integral type
668  * @param other number to be compared with this
669  * @returns true if this is less than or equal to other, else false
670  */
671  template <typename T, typename = typename std::enable_if<
672  std::is_integral<T>::value, T>::type>
673  inline bool operator<=(const T other) {
674  return *this <= uint128_t(other);
675  }
676 
677  /**
678  * @brief operator > for other types
679  * @tparam T integral type
680  * @param other number to be compared with this
681  * @returns true if this is greater than other, else false
682  */
683  template <typename T, typename = typename std::enable_if<
684  std::is_integral<T>::value, T>::type>
685  inline bool operator>(const T other) {
686  return *this > uint128_t(other);
687  }
688 
689  /**
690  * @brief operator >= for other types
691  * @tparam T integral type
692  * @param other number to be compared with this
693  * @returns true if this is greater than or equal other, else false
694  */
695  template <typename T, typename = typename std::enable_if<
696  std::is_integral<T>::value, T>::type>
697  inline bool operator>=(const T other) {
698  return *this >= uint128_t(other);
699  }
700 
701  /**
702  * @brief operator == for other types
703  * @tparam T integral type
704  * @param other number to be compared with this
705  * @returns true if this is equal to other, else false
706  */
707  template <typename T, typename = typename std::enable_if<
708  std::is_integral<T>::value, T>::type>
709  inline bool operator==(const T other) {
710  return *this == uint128_t(other);
711  }
712 
713  /**
714  * @brief operator != for other types
715  * @tparam T integral type
716  * @param other number to be compared with this
717  * @returns true if this is not equal to other, else false
718  */
719  template <typename T, typename = typename std::enable_if<
720  std::is_integral<T>::value, T>::type>
721  inline bool operator!=(const T other) {
722  return *this != uint128_t(other);
723  }
724 
725  /**
726  * @brief operator && for other types
727  * @tparam T integral type
728  * @param other number to be compared with this
729  * @returns true if this is both values are non-zero, else false
730  */
731  template <typename T, typename = typename std::enable_if<
732  std::is_integral<T>::value, T>::type>
733  inline bool operator&&(const T b) {
734  return (f || s) && b;
735  }
736 
737  /**
738  * @brief operator || for other types
739  * @tparam T integral type
740  * @param other number to be compared with this
741  * @returns true if this is either one of the values are non-zero, else
742  * false
743  */
744  template <typename T, typename = typename std::enable_if<
745  std::is_integral<T>::value, T>::type>
746  inline bool operator||(const T b) {
747  return (f || s) || b;
748  }
749 
750  /**
751  * @brief operator ~ for uint128_t
752  * @returns 1's complement of this number
753  */
754  uint128_t operator~() { return uint128_t(~this->f, ~this->s); }
755 
756  /**
757  * @brief operator << for uint128_t
758  * @tparam T integral type
759  * @param p number denoting number of shifts
760  * @returns value of this shifted by p to left
761  */
762  template <typename T, typename = typename std::enable_if<
763  std::is_integral<T>::value, T>::type>
764  uint128_t operator<<(const T p) {
765  if (!p) {
766  return uint128_t(f, s);
767  } else if (p >= 64 && p <= 128) {
768  return uint128_t((this->s << (p - 64)), 0);
769  } else if (p < 64 && p > 0) {
770  return uint128_t((this->f << p) + ((this->s >> (64 - p))),
771  this->s << p);
772  }
773  return uint128_t(0);
774  }
775 
776  /**
777  * @brief operator <<= for uint128_t
778  * @tparam T integral type
779  * @param p number denoting number of shifts
780  * @returns this shifted by p to left
781  */
782  template <typename T, typename = typename std::enable_if<
783  std::is_integral<T>::value, T>::type>
784  uint128_t &operator<<=(const T p) {
785  if (p) {
786  if (p >= 64 && p <= 128) {
787  this->f = (this->s << (p - 64));
788  this->s = 0;
789  } else {
790  f = ((this->f << p) + (this->s >> (64 - p)));
791  s = (this->s << p);
792  }
793  }
794  return *this;
795  }
796 
797  /**
798  * @brief operator >> for uint128_t
799  * @tparam T integral type
800  * @param p number denoting number of shifts
801  * @returns value of this shifted by p to right
802  */
803  template <typename T, typename = typename std::enable_if<
804  std::is_integral<T>::value, T>::type>
805  uint128_t operator>>(const T p) {
806  if (!p) {
807  return uint128_t(this->f, this->s);
808  } else if (p >= 64 && p <= 128) {
809  return uint128_t(0, (this->f >> (p - 64)));
810  } else if (p < 64 && p > 0) {
811  return uint128_t((this->f >> p),
812  (this->s >> p) + (this->f << (64 - p)));
813  }
814  return uint128_t(0);
815  }
816 
817  /**
818  * @brief operator >>= for uint128_t
819  * @tparam T integral type
820  * @param p number denoting number of shifts
821  * @returns this shifted by p to right
822  */
823  template <typename T, typename = typename std::enable_if<
824  std::is_integral<T>::value, T>::type>
825  uint128_t &operator>>=(const T p) {
826  if (p) {
827  if (p >= 64) {
828  f = 0;
829  s = (this->f >> (p - 64));
830  } else {
831  s = (this->s >> p) + (this->f << (64 - p));
832  f = (this->f >> p);
833  }
834  }
835  return *this;
836  }
837 
838  /**
839  * @brief operator & for uint128_t (bitwise operator)
840  * @param p number to be operated
841  * @returns value of this & p (& is bit-wise operator)
842  */
843  inline uint128_t operator&(const uint128_t &p) {
844  return uint128_t(this->f & p.f, this->s & p.s);
845  }
846 
847  /**
848  * @brief operator & for other types (bitwise operator)
849  * @tparam T integral type
850  * @param p number to be operated
851  * @returns value of this & p (& is bit-wise operator)
852  */
853  template <typename T, typename = typename std::enable_if<
854  std::is_integral<T>::value, T>::type>
855  uint128_t operator&(const T p) {
856  uint128_t tmp = *this;
857  return tmp & uint128_t(p);
858  }
859 
860  /**
861  * @brief operator &= for uint128_t (bitwise operator)
862  * @param p number to be operated
863  * @returns this = this & p (& is bit-wise operator)
864  */
866  this->f &= p.f;
867  this->s &= p.s;
868  return *this;
869  }
870 
871  /**
872  * @brief operator &= for other types (bitwise operator)
873  * @tparam T integral type
874  * @param p number to be operated
875  * @returns this = this & p (& is bit-wise operator)
876  */
877  template <typename T, typename = typename std::enable_if<
878  std::is_integral<T>::value, T>::type>
879  uint128_t &operator&=(const T p) {
880  *this &= uint128_t(p);
881  return *this;
882  }
883 
884  /**
885  * @brief operator | for other types (bitwise operator)
886  * @tparam T integral type
887  * @param p number to be operated
888  * @returns value of this | p (| is bit-wise operator)
889  */
890  template <typename T, typename = typename std::enable_if<
891  std::is_integral<T>::value, T>::type>
892  inline uint128_t operator|(const T p) {
893  return uint128_t(p | s);
894  }
895 
896  /**
897  * @brief operator | for uint128_t (bitwise operator)
898  * @param p number to be operated
899  * @returns value of this | p (| is bit-wise OR operator)
900  */
901  inline uint128_t operator|(const uint128_t &p) {
902  return uint128_t(this->f | p.f, this->s | p.s);
903  }
904 
905  /**
906  * @brief operator |= for uint128_t (bitwise operator)
907  * @param p number to be operated
908  * @returns this = this | p (| is bit-wise OR operator)
909  */
911  f |= p.f;
912  s |= p.s;
913  return *this;
914  }
915 
916  /**
917  * @brief operator |= for other types (bitwise operator)
918  * @tparam T integral type
919  * @param p number to be operated
920  * @returns this = this | p (| is bit-wise OR operator)
921  */
922  template <typename T, typename = typename std::enable_if<
923  std::is_integral<T>::value, T>::type>
924  inline uint128_t &operator|=(const T p) {
925  s |= p.s;
926  return *this;
927  }
928 
929  /**
930  * @brief operator ^ for other types (bitwise operator)
931  * @tparam T integral type
932  * @param p number to be operated
933  * @returns value of this ^ p (^ is bit-wise XOR operator)
934  */
935  template <typename T, typename = typename std::enable_if<
936  std::is_integral<T>::value, T>::type>
937  inline uint128_t operator^(const T p) {
938  return uint128_t(this->f, this->s ^ p);
939  }
940 
941  /**
942  * @brief operator ^ for uint128_t (bitwise operator)
943  * @param p number to be operated
944  * @returns value of this ^ p (^ is bit-wise XOR operator)
945  */
946  inline uint128_t operator^(const uint128_t &p) {
947  return uint128_t(this->f ^ p.f, this->s ^ p.s);
948  }
949 
950  /**
951  * @brief operator ^= for uint128_t (bitwise operator)
952  * @param p number to be operated
953  * @returns this = this ^ p (^ is bit-wise XOR operator)
954  */
956  f ^= p.f;
957  s ^= p.s;
958  return *this;
959  }
960 
961  /**
962  * @brief operator ^= for other types (bitwise operator)
963  * @tparam T integral type
964  * @param p number to be operated
965  * @returns this = this ^ p (^ is bit-wise XOR operator)
966  */
967  template <typename T, typename = typename std::enable_if<
968  std::is_integral<T>::value, T>::type>
969  inline uint128_t &operator^=(const T &p) {
970  s ^= p;
971  return *this;
972  }
973 
974  /**
975  * @brief operator << for printing uint128_t integer
976  * @details Prints the uint128_t integer in decimal form
977  * @note Note that this operator is costly since it uses strings to print
978  * the value
979  * @param op ostream object
980  * @param p 128-bit integer
981  * @returns op, ostream object.
982  */
984  if (!p.f) {
985  op << p.s;
986  } else {
987  std::string out = "0", p_2 = "1";
988  for (int i = 0; i < 64; ++i) {
989  if (p.s & (1LL << i)) {
990  out = add(out, p_2);
991  }
992  p_2 = add(p_2, p_2);
993  }
994  for (int i = 0; i < 64; ++i) {
995  if (p.f & (1LL << i)) {
996  out = add(out, p_2);
997  }
998  p_2 = add(p_2, p_2);
999  }
1000  op << out;
1001  }
1002  return op;
1003  }
1004 };
1005 
1006 // Arithmetic operators
1007 template <typename T, typename = typename std::enable_if<
1008  std::is_integral<T>::value, T>::type>
1009 inline uint128_t operator+(const T &p, const uint128_t &q) {
1010  return uint128_t(p) + q;
1011 }
1012 
1013 template <typename T, typename = typename std::enable_if<
1014  std::is_integral<T>::value, T>::type>
1015 inline uint128_t operator-(const T p, const uint128_t &q) {
1016  return uint128_t(p) - q;
1017 }
1018 
1019 template <typename T, typename = typename std::enable_if<
1020  std::is_integral<T>::value, T>::type>
1021 inline uint128_t operator*(const T p, const uint128_t &q) {
1022  return uint128_t(p) * q;
1023 }
1024 
1025 template <typename T, typename = typename std::enable_if<
1026  std::is_integral<T>::value, T>::type>
1027 inline uint128_t operator/(const T p, const uint128_t &q) {
1028  return uint128_t(p) / q;
1029 }
1030 
1031 template <typename T, typename = typename std::enable_if<
1032  std::is_integral<T>::value, T>::type>
1033 inline uint128_t operator%(const T p, const uint128_t &q) {
1034  return uint128_t(p) % q;
1035 }
1036 
1037 // Bitwise operators
1038 template <typename T, typename = typename std::enable_if<
1039  std::is_integral<T>::value, T>::type>
1040 inline uint128_t operator&(const T &p, const uint128_t &q) {
1041  return uint128_t(p) & q;
1042 }
1043 
1044 template <typename T, typename = typename std::enable_if<
1045  std::is_integral<T>::value, T>::type>
1046 inline uint128_t operator|(const T p, const uint128_t &q) {
1047  return uint128_t(p) | q;
1048 }
1049 
1050 template <typename T, typename = typename std::enable_if<
1051  std::is_integral<T>::value, T>::type>
1052 inline uint128_t operator^(const T p, const uint128_t &q) {
1053  return uint128_t(p) ^ q;
1054 }
1055 
1056 // Boolean operators
1057 template <typename T, typename = typename std::enable_if<
1058  std::is_integral<T>::value, T>::type>
1059 inline bool operator&&(const T p, const uint128_t &q) {
1060  return uint128_t(p) && q;
1061 }
1062 
1063 template <typename T, typename = typename std::enable_if<
1064  std::is_integral<T>::value, T>::type>
1065 inline bool operator||(const T p, const uint128_t &q) {
1066  return uint128_t(p) || q;
1067 }
1068 
1069 // Comparison operators
1070 template <typename T, typename = typename std::enable_if<
1071  std::is_integral<T>::value, T>::type>
1072 inline bool operator==(const T p, const uint128_t &q) {
1073  return uint128_t(p) == q;
1074 }
1075 
1076 template <typename T, typename = typename std::enable_if<
1077  std::is_integral<T>::value, T>::type>
1078 inline bool operator!=(const T p, const uint128_t &q) {
1079  return uint128_t(p) != q;
1080 }
1081 
1082 template <typename T, typename = typename std::enable_if<
1083  std::is_integral<T>::value, T>::type>
1084 inline bool operator<(const T p, const uint128_t &q) {
1085  return uint128_t(p) < q;
1086 }
1087 
1088 template <typename T, typename = typename std::enable_if<
1089  std::is_integral<T>::value, T>::type>
1090 inline bool operator<=(const T p, const uint128_t &q) {
1091  return uint128_t(p) <= q;
1092 }
1093 
1094 template <typename T, typename = typename std::enable_if<
1095  std::is_integral<T>::value, T>::type>
1096 inline bool operator>(const T p, const uint128_t &q) {
1097  return uint128_t(p) > q;
1098 }
1099 
1100 template <typename T, typename = typename std::enable_if<
1101  std::is_integral<T>::value, T>::type>
1102 inline bool operator>=(const T p, const uint128_t &q) {
1103  return uint128_t(p) >= q;
1104 }
1105 
1106 #endif // CIPHERS_UINT128_T_HPP_
T begin(T... args)
class for 128-bit unsigned integer
Definition: uint128_t.hpp:59
uint128_t operator-()
operator - using twos complement
Definition: uint128_t.hpp:337
bool operator&&(const T b)
operator && for other types
Definition: uint128_t.hpp:733
uint128_t(const std::string &str)
Parameterized constructor.
Definition: uint128_t.hpp:106
uint128_t operator+(const uint128_t &p)
operator + for uint128_t and other integer types.
Definition: uint128_t.hpp:261
uint128_t & operator+=(const uint128_t &p)
operator += for uint128_t
Definition: uint128_t.hpp:285
uint128_t operator<<(const T p)
operator << for uint128_t
Definition: uint128_t.hpp:764
bool operator<=(const uint128_t &other)
operator <= for uint128_t
Definition: uint128_t.hpp:583
uint128_t & operator|=(const T p)
operator |= for other types (bitwise operator)
Definition: uint128_t.hpp:924
uint64_t upper() const
returns upper 64-bit integer part
Definition: uint128_t.hpp:207
uint128_t & operator%=(const T &p)
operator %= for uint128_t
Definition: uint128_t.hpp:564
uint128_t & operator<<=(const T p)
operator <<= for uint128_t
Definition: uint128_t.hpp:784
uint128_t & operator&=(const T p)
operator &= for other types (bitwise operator)
Definition: uint128_t.hpp:879
bool operator>(const uint128_t &other)
operator > for uint128_t
Definition: uint128_t.hpp:592
uint128_t operator--(int p)
operator – (post-decrement)
Definition: uint128_t.hpp:352
uint128_t operator|(const uint128_t &p)
operator | for uint128_t (bitwise operator)
Definition: uint128_t.hpp:901
uint128_t operator/(const uint128_t &p)
operator / for uint128_t and other integer types.
Definition: uint128_t.hpp:488
bool operator||(const uint128_t &b)
operator || for uint128_t
Definition: uint128_t.hpp:643
bool operator>=(const T other)
operator >= for other types
Definition: uint128_t.hpp:697
uint128_t & operator++()
pre-increment operator
Definition: uint128_t.hpp:296
uint128_t operator|(const T p)
operator | for other types (bitwise operator)
Definition: uint128_t.hpp:892
~uint128_t()=default
Destructor for uint128_t.
uint128_t operator~()
operator ~ for uint128_t
Definition: uint128_t.hpp:754
uint128_t operator*(const uint128_t &p)
operator * for uint128_t and other integer types.
Definition: uint128_t.hpp:401
bool operator<=(const T other)
operator <= for other types
Definition: uint128_t.hpp:673
uint128_t operator*(const T p)
operator * for uint128_t and other integer types.
Definition: uint128_t.hpp:392
uint128_t & operator|=(const uint128_t &p)
operator |= for uint128_t (bitwise operator)
Definition: uint128_t.hpp:910
friend std::ostream & operator<<(std::ostream &op, const uint128_t &p)
operator << for printing uint128_t integer
Definition: uint128_t.hpp:983
uint128_t operator+(const T p)
operator + for uint128_t and other integer types.
Definition: uint128_t.hpp:252
bool operator<(const T other)
operator < for other types
Definition: uint128_t.hpp:661
uint128_t & operator&=(const uint128_t &p)
operator &= for uint128_t (bitwise operator)
Definition: uint128_t.hpp:865
uint128_t & operator%=(const uint128_t &p)
operator %= for uint128_t
Definition: uint128_t.hpp:551
uint128_t & operator/=(const uint128_t &p)
operator /= for uint128_t
Definition: uint128_t.hpp:509
uint128_t(const uint128_t &num)=default
Copy constructor.
uint128_t & operator^=(const T &p)
operator ^= for other types (bitwise operator)
Definition: uint128_t.hpp:969
uint128_t operator-(const T &p)
operator - for uint128_t and other integer types.
Definition: uint128_t.hpp:318
uint128_t operator>>(const T p)
operator >> for uint128_t
Definition: uint128_t.hpp:805
bool operator!=(const T other)
operator != for other types
Definition: uint128_t.hpp:721
bool operator==(const T other)
operator == for other types
Definition: uint128_t.hpp:709
bool operator==(const uint128_t &other)
operator == for uint128_t
Definition: uint128_t.hpp:610
uint32_t _trz()
Trailing zeroes in binary.
Definition: uint128_t.hpp:162
uint128_t(uint128_t &&num) noexcept
Move constructor.
Definition: uint128_t.hpp:127
bool operator||(const T b)
operator || for other types
Definition: uint128_t.hpp:746
uint128_t operator-(const uint128_t &p)
operator - for uint128_t
Definition: uint128_t.hpp:328
bool operator>(const T other)
operator > for other types
Definition: uint128_t.hpp:685
void __get_integer_from_string(const std::string &str)
First and second half of 128 bit number.
Definition: uint128_t.hpp:69
uint128_t & operator-=(const T &p)
operator -= for uint128_t and other integer types.
Definition: uint128_t.hpp:365
uint128_t operator^(const uint128_t &p)
operator ^ for uint128_t (bitwise operator)
Definition: uint128_t.hpp:946
uint128_t(const uint64_t high, const uint64_t low)
Parameterized constructor.
Definition: uint128_t.hpp:115
uint128_t & operator^=(const uint128_t &p)
operator ^= for uint128_t (bitwise operator)
Definition: uint128_t.hpp:955
uint128_t operator&(const T p)
operator & for other types (bitwise operator)
Definition: uint128_t.hpp:855
uint64_t lower() const
returns lower 64-bit integer part
Definition: uint128_t.hpp:201
uint128_t operator^(const T p)
operator ^ for other types (bitwise operator)
Definition: uint128_t.hpp:937
std::pair< uint128_t, uint128_t > divide(const uint128_t &p)
divide function for uint128_t and other integer types.
Definition: uint128_t.hpp:454
bool operator&&(const uint128_t &b)
operator && for uint128_t
Definition: uint128_t.hpp:634
bool operator!=(const uint128_t &other)
operator != for uint128_t
Definition: uint128_t.hpp:619
uint128_t & operator-=(const uint128_t &p)
operator -= for uint128_t
Definition: uint128_t.hpp:377
uint128_t operator%(const uint128_t &p)
operator % for uint128_t
Definition: uint128_t.hpp:532
bool operator<(const uint128_t &other)
operator < for uint128_t
Definition: uint128_t.hpp:574
uint128_t operator&(const uint128_t &p)
operator & for uint128_t (bitwise operator)
Definition: uint128_t.hpp:843
bool operator!()
operator ! for uint128_t
Definition: uint128_t.hpp:627
uint128_t & operator>>=(const T p)
operator >>= for uint128_t
Definition: uint128_t.hpp:825
uint128_t(T low)
Parameterized constructor.
Definition: uint128_t.hpp:100
uint128_t operator%(const T &p)
operator % for uint128_t and other integer types.
Definition: uint128_t.hpp:542
uint128_t & operator*=(const uint128_t &p)
operator *= for uint128_t and other integer types.
Definition: uint128_t.hpp:433
uint128_t & operator+=(const T p)
operator += for uint128_t and other integer types.
Definition: uint128_t.hpp:273
bool operator>=(const uint128_t &other)
operator >= for uint128_t
Definition: uint128_t.hpp:601
uint128_t & operator--()
operator – (pre-decrement)
Definition: uint128_t.hpp:343
uint128_t operator/(const T p)
operator / for uint128_t and other integer types.
Definition: uint128_t.hpp:498
uint32_t _lez()
Leading zeroes in binary.
Definition: uint128_t.hpp:139
uint128_t & operator*=(const T p)
operator *= for uint128_t and other integer types.
Definition: uint128_t.hpp:423
bool operator()()
operator () for uint128_t
Definition: uint128_t.hpp:651
uint128_t & operator=(const std::string &p)
operator = for type string
Definition: uint128_t.hpp:227
uint128_t operator++(int)
post-increment operator
Definition: uint128_t.hpp:305
uint128_t & operator=(uint128_t &&p)=default
Move assignment operator.
uint128_t & operator=(const uint128_t &p)=default
operator = for uint128_t
uint128_t & operator=(const T &p)
operator = for other types
Definition: uint128_t.hpp:217
uint128_t & operator/=(const T p)
operator /= for uint128_t and other integer types.
Definition: uint128_t.hpp:522
bool operator==(const Complex &a, const Complex &b)
Operator overload of '==' on Complex class. Logical Equal overload for our Complex class.
Definition: complex_numbers.cpp:175
T end(T... args)
T sum(const std::vector< std::valarray< T >> &A)
Definition: vector_ops.hpp:232
T operator!=(T... args)
std::vector< float > operator/(std::vector< T > const &A, float const scalar)
Definition: ordinary_least_squares_regressor.cpp:174
std::vector< T > operator-(std::vector< T > const &A, std::vector< T > const &B)
Definition: ordinary_least_squares_regressor.cpp:183
std::vector< T > operator+(std::vector< T > const &A, std::vector< T > const &B)
Definition: ordinary_least_squares_regressor.cpp:204
T push_back(T... args)
T reverse(T... args)
T size(T... args)
std::string add(const std::string &first, const std::string &second)
Adding two string.
Definition: uint128_t.hpp:37