uint128_t 添加 c++ 重载类型强制转换
类型声明:
1 class uint128 2 { 3 public: 4 uint128() :hi(0), lo(0){} 5 uint128(uint32_t l) :hi(0), lo(l){} 6 uint128(int32_t l) :hi(-(l < 0)), lo(l){} 7 uint128(int64_t l) :hi(-(l < 0)), lo(l){} 8 uint128(uint64_t l) :hi(0), lo(l){} 9 uint128(const std::string& s); 10 uint128(uint64_t _h, uint64_t _l) 11 :hi(_h), lo(_l){} 12 13 14 bool operator == (const uint128& o)const{ return hi == o.hi && lo == o.lo; } 15 bool operator != (const uint128& o)const{ return hi != o.hi || lo != o.lo; } 16 bool operator < (const uint128& o)const { return (hi == o.hi) ? lo < o.lo : hi < o.hi; } 17 bool operator < (const int64_t& o)const { return *this < uint128(o); } 18 bool operator !()const { return !(hi != 0 || lo != 0); } 19 uint128 operator -()const { return ++uint128(~hi, ~lo); } 20 uint128 operator ~()const { return uint128(~hi, ~lo); } 21 22 uint128& operator++() { hi += (++lo == 0); return *this; } 23 uint128& operator--() { hi -= (lo-- == 0); return *this; } 24 uint128 operator++(int) { auto tmp = *this; ++(*this); return tmp; } 25 uint128 operator--(int) { auto tmp = *this; --(*this); return tmp; } 26 27 uint128& operator |= (const uint128& u) { hi |= u.hi; lo |= u.lo; return *this; } 28 uint128& operator &= (const uint128& u) { hi &= u.hi; lo &= u.lo; return *this; } 29 uint128& operator ^= (const uint128& u) { hi ^= u.hi; lo ^= u.lo; return *this; } 30 uint128& operator <<= (const uint128& u); 31 uint128& operator >>= (const uint128& u); 32 33 uint128& operator += (const uint128& u) { const uint64_t old = lo; lo += u.lo; hi += u.hi + (lo < old); return *this; } 34 uint128& operator -= (const uint128& u) { return *this += -u; } 35 uint128& operator *= (const uint128& u); 36 37 38 friend uint128 operator + (const uint128& l, const uint128& r) { return uint128(l) += r; } 39 friend uint128 operator + (const uint128& l, const uint64_t& r) { return uint128(l) += uint128(r); } 40 friend uint128 operator + (const uint128& l, const uint32_t& r) { return uint128(l) += uint128(r); } 41 friend uint128 operator + (const uint128& l, const int32_t& r) { return uint128(l) += uint128(r); } 42 friend uint128 operator + (const uint64_t& l, const uint128& r) { return uint128(l) += r; } 43 friend uint128 operator - (const uint128& l, const uint128& r) { return uint128(l) -= r; } 44 friend uint128 operator * (const uint128& l, const uint128& r) { return uint128(l) *= r; } 45 friend uint128 operator * (const uint128& l, const uint64_t& r) { return uint128(l) *= uint128(r); } 46 friend uint128 operator * (const uint128& l, const uint32_t& r) { return uint128(l) *= uint128(r); } 47 friend uint128 operator | (const uint128& l, const uint128& r) { return uint128(l) = (r); } 48 friend uint128 operator & (const uint128& l, const uint128& r) { return uint128(l) &= r; } 49 friend uint128 operator & (const uint128& l, const uint64_t& r) { return uint128(l) &= uint128(r); } 50 friend uint128 operator ^ (const uint128& l, const uint128& r) { return uint128(l) ^= r; } 51 friend uint128 operator << (const uint128& l, const uint128& r) { return uint128(l) <<= r; } 52 friend uint128 operator >> (const uint128& l, const uint128& r) { return uint128(l) >>= r; } 53 friend uint128 operator >> (const uint128& l, const int32_t& r) { return uint128(l) >>= uint128(r); } 54 friend bool operator > (const uint128& l, const uint128& r) { return r < l; } 55 friend bool operator >(const uint128& l, const int64_t& r) { return uint128(r) < l; } 56 friend bool operator > (const int64_t& l, const uint128& r) { return r < uint128(l); } 57 58 friend bool operator >= (const uint128& l, const uint128& r) { return l == r || l > r; } 59 friend bool operator >= (const uint128& l, const int64_t& r) { return l >= uint128(r); } 60 friend bool operator >= (const int64_t& l, const uint128& r) { return uint128(l) >= r; } 61 friend bool operator <= (const uint128& l, const uint128& r) { return l == r || l < r; } 62 friend bool operator <= (const uint128& l, const int64_t& r) { return l <= uint128(r); } 63 friend bool operator <= (const int64_t& l, const uint128& r) { return uint128(l) <= r; } 64 65 operator uint64_t() { return lo; } //强制转换为uint64_t 66 operator uint32_t() { return (uint32_t)lo; } //强制转换为uint32_t 67 operator int32_t() { return (int32_t)lo; } //强制转换为int32_t 68 69 70 uint32_t low_32_bits()const { return (uint32_t)lo; } 71 uint64_t low_bits()const { return lo; } 72 uint64_t high_bits()const { return hi; } 73 74 uint64_t hi; 75 uint64_t lo; 76 };
实现函数:
1 uint128::uint128(const std::string &sz) 2 :hi(0), lo(0) 3 { 4 // do we have at least one character? 5 if (!sz.empty()) { 6 // make some reasonable assumptions 7 int radix = 10; 8 bool minus = false; 9 10 std::string::const_iterator i = sz.begin(); 11 12 // check for minus sign, i suppose technically this should only apply 13 // to base 10, but who says that -0x1 should be invalid? 14 if (*i == '-') { 15 ++i; 16 minus = true; 17 } 18 19 // check if there is radix changing prefix (0 or 0x) 20 if (i != sz.end()) { 21 if (*i == '0') { 22 radix = 8; 23 ++i; 24 if (i != sz.end()) { 25 if (*i == 'x') { 26 radix = 16; 27 ++i; 28 } 29 } 30 } 31 32 while (i != sz.end()) { 33 unsigned int n = 0; 34 const char ch = *i; 35 36 if (ch >= 'A' && ch <= 'Z') { 37 if (((ch - 'A') + 10) < radix) { 38 n = (ch - 'A') + 10; 39 } 40 else { 41 break; 42 } 43 } 44 else if (ch >= 'a' && ch <= 'z') { 45 if (((ch - 'a') + 10) < radix) { 46 n = (ch - 'a') + 10; 47 } 48 else { 49 break; 50 } 51 } 52 else if (ch >= '0' && ch <= '9') { 53 if ((ch - '0') < radix) { 54 n = (ch - '0'); 55 } 56 else { 57 break; 58 } 59 } 60 else { 61 /* completely invalid character */ 62 break; 63 } 64 65 (*this) *= radix; 66 (*this) += n; 67 68 ++i; 69 } 70 } 71 72 if (minus) { 73 *this = -*this; 74 } 75 } 76 } 77 78 uint128& uint128::operator<<=(const uint128& rhs) 79 { 80 if (rhs >= 128) 81 { 82 hi = 0; 83 lo = 0; 84 } 85 else 86 { 87 unsigned int n = rhs.to_integer(); 88 const unsigned int halfsize = 128 / 2; 89 90 if (n >= halfsize){ 91 n -= halfsize; 92 hi = lo; 93 lo = 0; 94 } 95 96 if (n != 0) { 97 // shift high half 98 hi <<= n; 99 100 const uint64_t mask(~(uint64_t(-1) >> n)); 101 102 // and add them to high half 103 hi |= (lo & mask) >> (halfsize - n); 104 105 // and finally shift also low half 106 lo <<= n; 107 } 108 } 109 110 return *this; 111 } 112 113 uint128 & uint128::operator>>=(const uint128& rhs) 114 { 115 if (rhs >= 128) 116 { 117 hi = 0; 118 lo = 0; 119 } 120 else 121 { 122 unsigned int n = rhs.to_integer(); 123 const unsigned int halfsize = 128 / 2; 124 125 if (n >= halfsize) { 126 n -= halfsize; 127 lo = hi; 128 hi = 0; 129 } 130 131 if (n != 0) { 132 // shift low half 133 lo >>= n; 134 135 // get lower N bits of high half 136 const uint64_t mask(~(uint64_t(-1) << n)); 137 138 // and add them to low qword 139 lo |= (hi & mask) << (halfsize - n); 140 141 // and finally shift also high half 142 hi >>= n; 143 } 144 } 145 return *this; 146 } 147 148 uint128& uint128::operator*=(const uint128 &b) 149 { 150 uint64_t a0 = (uint32_t)(this->lo); 151 uint64_t a1 = (uint32_t)(this->lo >> 0x20); 152 uint64_t a2 = (uint32_t)(this->hi); 153 uint64_t a3 = (uint32_t)(this->hi >> 0x20); 154 155 uint64_t b0 = (uint32_t)(b.lo); 156 uint64_t b1 = (uint32_t)(b.lo >> 0x20); 157 uint64_t b2 = (uint32_t)(b.hi); 158 uint64_t b3 = (uint32_t)(b.hi >> 0x20); 159 160 161 this->hi = 0; 162 this->lo = a3*b0; 163 (*this) += a2*b1; 164 (*this) += a1*b2; 165 (*this) += a0*b3; 166 (*this) <<= 0x20; 167 (*this) += a2*b0; 168 (*this) += a1*b1; 169 (*this) += a0*b2; 170 (*this) <<= 0x20; 171 (*this) += a1*b0; 172 (*this) += a0*b1; 173 (*this) <<= 0x20; 174 (*this) += a0*b0; 175 176 return *this; 177 }
----------------陌上阡头,草长莺飞-----------------
https://www.cnblogs.com/tyche116/