20#ifndef CIPHERS_UINT128_T_HPP_
21#define CIPHERS_UINT128_T_HPP_
31std::string
add(
const std::string &first,
const std::string &second) {
33 int16_t sum = 0, carry = 0;
34 for (int32_t i =
static_cast<int32_t
>(first.size()) - 1,
35 j =
static_cast<int32_t
>(second.size()) - 1;
36 i >= 0 || j >= 0; --i, --j) {
37 sum = ((i >= 0 ? first[i] -
'0' : 0) + (j >= 0 ? second[j] -
'0' : 0) +
41 third.push_back(sum +
'0');
46 std::reverse(third.begin(), third.end());
64 this->f = this->s = 0;
65 if (str.size() > 1 && str[1] ==
'x') {
66 for (
auto i = 2; i < str.size(); ++i) {
68 if (str[i] >=
'0' && str[i] <=
'9') {
69 *
this += (str[i] -
'0');
70 }
else if (str[i] >=
'A' && str[i] <=
'F') {
71 *
this += (str[i] -
'A' + 10);
72 }
else if (str[i] >=
'a' && str[i] <=
'f') {
73 *
this += (str[i] -
'a' + 10);
92 template <
typename T,
typename =
typename std::enable_if<
93 std::is_integral<T>::value, T>::type>
109 uint128_t(
const uint64_t high,
const uint64_t low) : f(high), s(low) {}
121 uint128_t(uint128_t &&num) noexcept : f(num.f), s(num.s) {}
136 return __builtin_clzll(f);
138 return 64 + __builtin_clzll(s);
141 _BitScanForward64(&r, f);
144 _BitScanForward64(&l, s);
159 return __builtin_ctzll(f);
161 return 64 + __builtin_ctzll(s);
164 _BitScanReverse64(&r, s);
167 _BitScanReverse64(&l, f);
178 inline explicit operator bool()
const {
return (f || s); }
185 template <
typename T,
typename =
typename std::enable_if<
186 std::is_integral<T>::value, T>::type>
187 inline explicit operator T()
const {
188 return static_cast<T
>(s);
195 inline uint64_t
lower()
const {
return s; }
201 inline uint64_t
upper()
const {
return f; }
209 template <
typename T,
typename =
typename std::enable_if<
210 std::is_integral<T>::value, T>::type>
231 inline uint128_t &
operator=(
const uint128_t &p) =
default;
244 template <
typename T,
typename =
typename std::enable_if<
245 std::is_integral<T>::value, T>::type>
247 return uint128_t(f + (p + s < s), p + s);
256 return uint128_t(f + (p.s + s < s) + p.f, p.s + s);
265 template <
typename T,
typename =
typename std::enable_if<
266 std::is_integral<T>::value, T>::type>
268 bool app = p + s < s;
280 bool app = p.s + s < s;
310 template <
typename T,
typename =
typename std::enable_if<
311 std::is_integral<T>::value, T>::type>
314 return uint128_t(f - app, s - p);
324 return uint128_t(f - p.f - app, s - p.s);
331 inline uint128_t
operator-() {
return ~*
this + uint128_t(1); }
357 template <
typename T,
typename =
typename std::enable_if<
358 std::is_integral<T>::value, T>::type>
384 template <
typename T,
typename =
typename std::enable_if<
385 std::is_integral<T>::value, T>::type>
387 return *
this * uint128_t(p);
396 uint64_t f_first = s >> 32, f_second = s & 0xFFFFFFFF,
397 s_first = p.s >> 32, s_second = p.s & 0xFFFFFFFF;
398 uint64_t fi = f_first * s_first, se = f_first * s_second,
399 th = s_first * f_second, fo = s_second * f_second;
400 uint64_t tmp = ((se & 0xFFFFFFFF) << 32), tmp2 = (th & 0xFFFFFFFF)
402 int cc = (tmp + tmp2 < tmp);
404 cc += (tmp + fo < tmp);
405 uint64_t carry = fi + (se >> 32) + (th >> 32);
406 return uint128_t(this->f * p.s + this->s * p.f + carry + cc, tmp + fo);
415 template <
typename T,
typename =
typename std::enable_if<
416 std::is_integral<T>::value, T>::type>
418 *
this *= uint128_t(p);
428 uint64_t f_first = s >> 32, f_second = s & 0xFFFFFFFF,
429 s_first = p.s >> 32, s_second = p.s & 0xFFFFFFFF;
430 uint64_t fi = f_first * s_first, se = f_first * s_second,
431 th = s_first * f_second, fo = s_second * f_second;
432 uint64_t tmp = (se << 32), tmp2 = (th << 32);
433 int cc = (tmp + tmp2 < tmp);
435 cc += (tmp + fo < tmp);
436 uint64_t carry = fi + (se >> 32) + (th >> 32);
437 f = this->f * p.s + this->s * p.f + carry + cc;
448 std::pair<uint128_t, uint128_t>
divide(
const uint128_t &p) {
450 return {uint128_t(0), *
this};
451 }
else if (*
this == p) {
452 return {uint128_t(1), uint128_t(0)};
454 uint128_t tmp = p, tmp2 = *
this;
455 uint16_t left = tmp.
_lez() -
_lez();
457 uint128_t quotient(0);
460 uint16_t shf = tmp2._lez() - tmp.
_lez();
474 return {quotient << left, tmp2};
490 template <
typename T,
typename =
typename std::enable_if<
491 std::is_integral<T>::value, T>::type>
493 uint128_t tmp = *
this;
494 tmp /= uint128_t(0, p);
514 template <
typename T,
typename =
typename std::enable_if<
515 std::is_integral<T>::value, T>::type>
517 *
this /= uint128_t(0, p);
534 template <
typename T,
typename =
typename std::enable_if<
535 std::is_integral<T>::value, T>::type>
537 return *
this % uint128_t(p);
556 template <
typename T,
typename =
typename std::enable_if<
557 std::is_integral<T>::value, T>::type>
559 *
this %= uint128_t(p);
569 return f < other.f || (f == other.f && s < other.s);
578 return f < other.f || (f == other.f && s <= other.s);
587 return f > other.f || (f == other.f && s > other.s);
596 return (f > other.f) || (f == other.f && s >= other.s);
605 return f == other.f && s == other.s;
614 return f != other.f || s != other.s;
629 return (s || f) && (b.s || b.f);
638 return (s || f) || (b.s || b.f);
653 template <
typename T,
typename =
typename std::enable_if<
654 std::is_integral<T>::value, T>::type>
656 return *
this < uint128_t(other);
665 template <
typename T,
typename =
typename std::enable_if<
666 std::is_integral<T>::value, T>::type>
668 return *
this <= uint128_t(other);
677 template <
typename T,
typename =
typename std::enable_if<
678 std::is_integral<T>::value, T>::type>
680 return *
this > uint128_t(other);
689 template <
typename T,
typename =
typename std::enable_if<
690 std::is_integral<T>::value, T>::type>
692 return *
this >= uint128_t(other);
701 template <
typename T,
typename =
typename std::enable_if<
702 std::is_integral<T>::value, T>::type>
704 return *
this == uint128_t(other);
713 template <
typename T,
typename =
typename std::enable_if<
714 std::is_integral<T>::value, T>::type>
716 return *
this != uint128_t(other);
725 template <
typename T,
typename =
typename std::enable_if<
726 std::is_integral<T>::value, T>::type>
728 return (f || s) && b;
738 template <
typename T,
typename =
typename std::enable_if<
739 std::is_integral<T>::value, T>::type>
741 return (f || s) || b;
748 uint128_t
operator~() {
return uint128_t(~this->f, ~this->s); }
756 template <
typename T,
typename =
typename std::enable_if<
757 std::is_integral<T>::value, T>::type>
760 return uint128_t(f, s);
761 }
else if (p >= 64 && p <= 128) {
762 return uint128_t((this->s << (p - 64)), 0);
763 }
else if (p < 64 && p > 0) {
764 return uint128_t((this->f << p) + ((this->s >> (64 - p))),
776 template <
typename T,
typename =
typename std::enable_if<
777 std::is_integral<T>::value, T>::type>
780 if (p >= 64 && p <= 128) {
781 this->f = (this->s << (p - 64));
784 f = ((this->f << p) + (this->s >> (64 - p)));
797 template <
typename T,
typename =
typename std::enable_if<
798 std::is_integral<T>::value, T>::type>
801 return uint128_t(this->f, this->s);
802 }
else if (p >= 64 && p <= 128) {
803 return uint128_t(0, (this->f >> (p - 64)));
804 }
else if (p < 64 && p > 0) {
805 return uint128_t((this->f >> p),
806 (this->s >> p) + (this->f << (64 - p)));
817 template <
typename T,
typename =
typename std::enable_if<
818 std::is_integral<T>::value, T>::type>
823 s = (this->f >> (p - 64));
825 s = (this->s >> p) + (this->f << (64 - p));
838 return uint128_t(this->f & p.f, this->s & p.s);
847 template <
typename T,
typename =
typename std::enable_if<
848 std::is_integral<T>::value, T>::type>
850 uint128_t tmp = *
this;
851 return tmp & uint128_t(p);
871 template <
typename T,
typename =
typename std::enable_if<
872 std::is_integral<T>::value, T>::type>
874 *
this &= uint128_t(p);
884 template <
typename T,
typename =
typename std::enable_if<
885 std::is_integral<T>::value, T>::type>
887 return uint128_t(p | s);
896 return uint128_t(this->f | p.f, this->s | p.s);
916 template <
typename T,
typename =
typename std::enable_if<
917 std::is_integral<T>::value, T>::type>
929 template <
typename T,
typename =
typename std::enable_if<
930 std::is_integral<T>::value, T>::type>
932 return uint128_t(this->f, this->s ^ p);
941 return uint128_t(this->f ^ p.f, this->s ^ p.s);
961 template <
typename T,
typename =
typename std::enable_if<
962 std::is_integral<T>::value, T>::type>
977 friend std::ostream &
operator<<(std::ostream &op,
const uint128_t &p) {
981 std::string out =
"0", p_2 =
"1";
982 for (
int i = 0; i < 64; ++i) {
983 if (p.s & (1LL << i)) {
988 for (
int i = 0; i < 64; ++i) {
989 if (p.f & (1LL << i)) {
1001template <
typename T,
typename =
typename std::enable_if<
1002 std::is_integral<T>::value, T>::type>
1007template <
typename T,
typename =
typename std::enable_if<
1008 std::is_integral<T>::value, T>::type>
1013template <
typename T,
typename =
typename std::enable_if<
1014 std::is_integral<T>::value, T>::type>
1019template <
typename T,
typename =
typename std::enable_if<
1020 std::is_integral<T>::value, T>::type>
1025template <
typename T,
typename =
typename std::enable_if<
1026 std::is_integral<T>::value, T>::type>
1032template <
typename T,
typename =
typename std::enable_if<
1033 std::is_integral<T>::value, T>::type>
1038template <
typename T,
typename =
typename std::enable_if<
1039 std::is_integral<T>::value, T>::type>
1044template <
typename T,
typename =
typename std::enable_if<
1045 std::is_integral<T>::value, T>::type>
1051template <
typename T,
typename =
typename std::enable_if<
1052 std::is_integral<T>::value, T>::type>
1053inline bool operator&&(
const T p,
const uint128_t &q) {
1057template <
typename T,
typename =
typename std::enable_if<
1058 std::is_integral<T>::value, T>::type>
1059inline bool operator||(
const T p,
const uint128_t &q) {
1064template <
typename T,
typename =
typename std::enable_if<
1065 std::is_integral<T>::value, T>::type>
1066inline bool operator==(
const T p,
const uint128_t &q) {
1070template <
typename T,
typename =
typename std::enable_if<
1071 std::is_integral<T>::value, T>::type>
1072inline bool operator!=(
const T p,
const uint128_t &q) {
1076template <
typename T,
typename =
typename std::enable_if<
1077 std::is_integral<T>::value, T>::type>
1078inline bool operator<(
const T p,
const uint128_t &q) {
1082template <
typename T,
typename =
typename std::enable_if<
1083 std::is_integral<T>::value, T>::type>
1084inline bool operator<=(
const T p,
const uint128_t &q) {
1088template <
typename T,
typename =
typename std::enable_if<
1089 std::is_integral<T>::value, T>::type>
1090inline bool operator>(
const T p,
const uint128_t &q) {
1094template <
typename T,
typename =
typename std::enable_if<
1095 std::is_integral<T>::value, T>::type>
1096inline bool operator>=(
const T p,
const uint128_t &q) {
class for 128-bit unsigned integer
uint128_t & operator%=(const T &p)
operator %= for uint128_t
uint128_t operator-()
operator - using twos complement
uint128_t & operator-=(const T &p)
operator -= for uint128_t and other integer types.
bool operator&&(const T b)
operator && for other types
uint128_t & operator>>=(const T p)
operator >>= for uint128_t
uint128_t(const std::string &str)
Parameterized constructor.
uint128_t operator+(const uint128_t &p)
operator + for uint128_t and other integer types.
uint128_t operator<<(const T p)
operator << for uint128_t
bool operator<=(const uint128_t &other)
operator <= for uint128_t
uint128_t & operator--()
operator – (pre-decrement)
uint64_t upper() const
returns upper 64-bit integer part
uint128_t & operator&=(const T p)
operator &= for other types (bitwise operator)
uint128_t & operator%=(const uint128_t &p)
operator %= for uint128_t
bool operator>(const uint128_t &other)
operator > for uint128_t
uint128_t operator|(const uint128_t &p)
operator | for uint128_t (bitwise operator)
uint128_t & operator/=(const uint128_t &p)
operator /= for uint128_t
uint128_t & operator*=(const T p)
operator *= for uint128_t and other integer types.
uint128_t operator/(const uint128_t &p)
operator / for uint128_t and other integer types.
bool operator||(const uint128_t &b)
operator || for uint128_t
bool operator>=(const T other)
operator >= for other types
uint128_t & operator=(uint128_t &&p)=default
Move assignment operator.
uint128_t operator|(const T p)
operator | for other types (bitwise operator)
~uint128_t()=default
Destructor for uint128_t.
uint128_t operator~()
operator ~ for uint128_t
uint128_t operator*(const uint128_t &p)
operator * for uint128_t and other integer types.
uint128_t & operator^=(const T &p)
operator ^= for other types (bitwise operator)
bool operator<=(const T other)
operator <= for other types
uint128_t operator*(const T p)
operator * for uint128_t and other integer types.
uint128_t operator+(const T p)
operator + for uint128_t and other integer types.
uint128_t & operator+=(const T p)
operator += for uint128_t and other integer types.
bool operator<(const T other)
operator < for other types
friend std::ostream & operator<<(std::ostream &op, const uint128_t &p)
operator << for printing uint128_t integer
uint128_t(const uint128_t &num)=default
Copy constructor.
uint128_t & operator|=(const T p)
operator |= for other types (bitwise operator)
uint128_t operator-(const T &p)
operator - for uint128_t and other integer types.
uint128_t operator>>(const T p)
operator >> for uint128_t
uint128_t operator--(int)
operator – (post-decrement)
bool operator!=(const T other)
operator != for other types
bool operator==(const T other)
operator == for other types
bool operator==(const uint128_t &other)
operator == for uint128_t
uint32_t _trz()
Trailing zeroes in binary.
uint128_t(uint128_t &&num) noexcept
Move constructor.
bool operator||(const T b)
operator || for other types
uint128_t operator-(const uint128_t &p)
operator - for uint128_t
bool operator>(const T other)
operator > for other types
void __get_integer_from_string(const std::string &str)
First and second half of 128 bit number.
std::pair< uint128_t, uint128_t > divide(const uint128_t &p)
divide function for uint128_t and other integer types.
uint128_t operator^(const uint128_t &p)
operator ^ for uint128_t (bitwise operator)
uint128_t(const uint64_t high, const uint64_t low)
Parameterized constructor.
uint128_t & operator*=(const uint128_t &p)
operator *= for uint128_t and other integer types.
uint128_t & operator+=(const uint128_t &p)
operator += for uint128_t
uint128_t operator&(const T p)
operator & for other types (bitwise operator)
uint128_t & operator<<=(const T p)
operator <<= for uint128_t
uint64_t lower() const
returns lower 64-bit integer part
uint128_t & operator/=(const T p)
operator /= for uint128_t and other integer types.
uint128_t operator^(const T p)
operator ^ for other types (bitwise operator)
bool operator&&(const uint128_t &b)
operator && for uint128_t
bool operator!=(const uint128_t &other)
operator != for uint128_t
uint128_t & operator=(const uint128_t &p)=default
operator = for uint128_t
uint128_t & operator|=(const uint128_t &p)
operator |= for uint128_t (bitwise operator)
uint128_t & operator=(const std::string &p)
operator = for type string
uint128_t & operator-=(const uint128_t &p)
operator -= for uint128_t
uint128_t operator%(const uint128_t &p)
operator % for uint128_t
uint128_t & operator&=(const uint128_t &p)
operator &= for uint128_t (bitwise operator)
uint128_t & operator++()
pre-increment operator
uint128_t & operator=(const T &p)
operator = for other types
bool operator<(const uint128_t &other)
operator < for uint128_t
uint128_t operator&(const uint128_t &p)
operator & for uint128_t (bitwise operator)
bool operator!()
operator ! for uint128_t
uint128_t(T low)
Parameterized constructor.
uint128_t operator%(const T &p)
operator % for uint128_t and other integer types.
uint128_t & operator^=(const uint128_t &p)
operator ^= for uint128_t (bitwise operator)
bool operator>=(const uint128_t &other)
operator >= for uint128_t
uint128_t operator/(const T p)
operator / for uint128_t and other integer types.
uint32_t _lez()
Leading zeroes in binary.
bool operator()()
operator () for uint128_t
uint128_t operator++(int)
post-increment operator
std::string add(const std::string &first, const std::string &second)
Adding two string.