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/p/11690769.html