Library to allo USB PTP device to be hosted by the mbed platform
Dependents: class_project_main
PIMA15740/uint128_t..h@11:3b072cf16df8, 2013-10-07 (annotated)
- Committer:
- jakowisp
- Date:
- Mon Oct 07 04:45:55 2013 +0000
- Revision:
- 11:3b072cf16df8
- Parent:
- 10:fc1cb68fc91e
Add code for Property description download.; Add code decoder logic.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jakowisp | 10:fc1cb68fc91e | 1 | /* |
jakowisp | 10:fc1cb68fc91e | 2 | uint128_t.h |
jakowisp | 10:fc1cb68fc91e | 3 | An unsigned 128 bit integer library for C++ |
jakowisp | 10:fc1cb68fc91e | 4 | By Jason Lee @ calccrypto@yahoo.com |
jakowisp | 10:fc1cb68fc91e | 5 | with much help from Auston Sterling |
jakowisp | 10:fc1cb68fc91e | 6 | |
jakowisp | 10:fc1cb68fc91e | 7 | And thanks to Stefan Deigmüller for finding |
jakowisp | 10:fc1cb68fc91e | 8 | a bug in operator*. |
jakowisp | 10:fc1cb68fc91e | 9 | */ |
jakowisp | 10:fc1cb68fc91e | 10 | |
jakowisp | 10:fc1cb68fc91e | 11 | #ifndef UINT128_T_H |
jakowisp | 10:fc1cb68fc91e | 12 | #define UINT128_T_H |
jakowisp | 10:fc1cb68fc91e | 13 | |
jakowisp | 10:fc1cb68fc91e | 14 | #include <cstdlib> |
jakowisp | 10:fc1cb68fc91e | 15 | #include <iostream> |
jakowisp | 10:fc1cb68fc91e | 16 | #include <stdint.h> |
jakowisp | 10:fc1cb68fc91e | 17 | |
jakowisp | 10:fc1cb68fc91e | 18 | class uint128_t{ |
jakowisp | 10:fc1cb68fc91e | 19 | private: |
jakowisp | 10:fc1cb68fc91e | 20 | uint64_t UPPER, LOWER; |
jakowisp | 10:fc1cb68fc91e | 21 | |
jakowisp | 10:fc1cb68fc91e | 22 | public: |
jakowisp | 10:fc1cb68fc91e | 23 | // Constructors |
jakowisp | 10:fc1cb68fc91e | 24 | uint128_t(){ |
jakowisp | 10:fc1cb68fc91e | 25 | UPPER = 0; |
jakowisp | 10:fc1cb68fc91e | 26 | LOWER = 0; |
jakowisp | 10:fc1cb68fc91e | 27 | } |
jakowisp | 10:fc1cb68fc91e | 28 | |
jakowisp | 10:fc1cb68fc91e | 29 | template <typename T> |
jakowisp | 10:fc1cb68fc91e | 30 | uint128_t(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 31 | UPPER = 0; |
jakowisp | 10:fc1cb68fc91e | 32 | LOWER = (uint64_t) rhs; |
jakowisp | 10:fc1cb68fc91e | 33 | } |
jakowisp | 10:fc1cb68fc91e | 34 | |
jakowisp | 10:fc1cb68fc91e | 35 | template <typename S, typename T> |
jakowisp | 10:fc1cb68fc91e | 36 | uint128_t(const S upper_rhs, const T lower_rhs){ |
jakowisp | 10:fc1cb68fc91e | 37 | UPPER = (uint64_t) upper_rhs; |
jakowisp | 10:fc1cb68fc91e | 38 | LOWER = (uint64_t) lower_rhs; |
jakowisp | 10:fc1cb68fc91e | 39 | } |
jakowisp | 10:fc1cb68fc91e | 40 | |
jakowisp | 10:fc1cb68fc91e | 41 | uint128_t(const uint128_t & rhs){ |
jakowisp | 10:fc1cb68fc91e | 42 | UPPER = rhs.UPPER; |
jakowisp | 10:fc1cb68fc91e | 43 | LOWER = rhs.LOWER; |
jakowisp | 10:fc1cb68fc91e | 44 | } |
jakowisp | 10:fc1cb68fc91e | 45 | |
jakowisp | 10:fc1cb68fc91e | 46 | // RHS input args only |
jakowisp | 10:fc1cb68fc91e | 47 | |
jakowisp | 10:fc1cb68fc91e | 48 | // Assignment Operator |
jakowisp | 10:fc1cb68fc91e | 49 | template <typename T> uint128_t operator=(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 50 | UPPER = 0; |
jakowisp | 10:fc1cb68fc91e | 51 | LOWER = (uint64_t) rhs; |
jakowisp | 10:fc1cb68fc91e | 52 | return *this; |
jakowisp | 10:fc1cb68fc91e | 53 | } |
jakowisp | 10:fc1cb68fc91e | 54 | |
jakowisp | 10:fc1cb68fc91e | 55 | uint128_t operator=(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 56 | UPPER = rhs.UPPER; |
jakowisp | 10:fc1cb68fc91e | 57 | LOWER = rhs.LOWER; |
jakowisp | 10:fc1cb68fc91e | 58 | return *this; |
jakowisp | 10:fc1cb68fc91e | 59 | } |
jakowisp | 10:fc1cb68fc91e | 60 | |
jakowisp | 10:fc1cb68fc91e | 61 | // Typecast Operators |
jakowisp | 10:fc1cb68fc91e | 62 | operator bool(){ |
jakowisp | 10:fc1cb68fc91e | 63 | return (bool) (UPPER | LOWER); |
jakowisp | 10:fc1cb68fc91e | 64 | } |
jakowisp | 10:fc1cb68fc91e | 65 | |
jakowisp | 10:fc1cb68fc91e | 66 | operator char(){ |
jakowisp | 10:fc1cb68fc91e | 67 | return (char) LOWER; |
jakowisp | 10:fc1cb68fc91e | 68 | } |
jakowisp | 10:fc1cb68fc91e | 69 | |
jakowisp | 10:fc1cb68fc91e | 70 | operator int(){ |
jakowisp | 10:fc1cb68fc91e | 71 | return (int) LOWER; |
jakowisp | 10:fc1cb68fc91e | 72 | } |
jakowisp | 10:fc1cb68fc91e | 73 | |
jakowisp | 10:fc1cb68fc91e | 74 | operator uint8_t(){ |
jakowisp | 10:fc1cb68fc91e | 75 | return (uint8_t) LOWER; |
jakowisp | 10:fc1cb68fc91e | 76 | } |
jakowisp | 10:fc1cb68fc91e | 77 | |
jakowisp | 10:fc1cb68fc91e | 78 | operator uint16_t(){ |
jakowisp | 10:fc1cb68fc91e | 79 | return (uint16_t) LOWER; |
jakowisp | 10:fc1cb68fc91e | 80 | } |
jakowisp | 10:fc1cb68fc91e | 81 | |
jakowisp | 10:fc1cb68fc91e | 82 | operator uint32_t(){ |
jakowisp | 10:fc1cb68fc91e | 83 | return (uint32_t) LOWER; |
jakowisp | 10:fc1cb68fc91e | 84 | } |
jakowisp | 10:fc1cb68fc91e | 85 | |
jakowisp | 10:fc1cb68fc91e | 86 | operator uint64_t(){ |
jakowisp | 10:fc1cb68fc91e | 87 | return LOWER; |
jakowisp | 10:fc1cb68fc91e | 88 | } |
jakowisp | 10:fc1cb68fc91e | 89 | |
jakowisp | 10:fc1cb68fc91e | 90 | // Bitwise Operators |
jakowisp | 10:fc1cb68fc91e | 91 | template <typename T> uint128_t operator&(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 92 | return uint128_t(0, LOWER & (uint64_t) rhs); |
jakowisp | 10:fc1cb68fc91e | 93 | } |
jakowisp | 10:fc1cb68fc91e | 94 | |
jakowisp | 10:fc1cb68fc91e | 95 | uint128_t operator&(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 96 | return uint128_t(UPPER & rhs.UPPER, LOWER & rhs.LOWER); |
jakowisp | 10:fc1cb68fc91e | 97 | } |
jakowisp | 10:fc1cb68fc91e | 98 | |
jakowisp | 10:fc1cb68fc91e | 99 | template <typename T> uint128_t operator|(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 100 | return uint128_t(UPPER, LOWER | (uint64_t) rhs); |
jakowisp | 10:fc1cb68fc91e | 101 | } |
jakowisp | 10:fc1cb68fc91e | 102 | |
jakowisp | 10:fc1cb68fc91e | 103 | uint128_t operator|(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 104 | return uint128_t(UPPER | rhs.UPPER, LOWER | rhs.LOWER); |
jakowisp | 10:fc1cb68fc91e | 105 | } |
jakowisp | 10:fc1cb68fc91e | 106 | |
jakowisp | 10:fc1cb68fc91e | 107 | template <typename T> uint128_t operator^(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 108 | return uint128_t(UPPER, LOWER ^ (uint64_t) rhs); |
jakowisp | 10:fc1cb68fc91e | 109 | } |
jakowisp | 10:fc1cb68fc91e | 110 | |
jakowisp | 10:fc1cb68fc91e | 111 | uint128_t operator^(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 112 | return uint128_t(UPPER ^ rhs.UPPER, LOWER ^ rhs.LOWER); |
jakowisp | 10:fc1cb68fc91e | 113 | } |
jakowisp | 10:fc1cb68fc91e | 114 | |
jakowisp | 10:fc1cb68fc91e | 115 | template <typename T> uint128_t operator&=(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 116 | UPPER = 0; |
jakowisp | 10:fc1cb68fc91e | 117 | LOWER &= rhs; |
jakowisp | 10:fc1cb68fc91e | 118 | return *this; |
jakowisp | 10:fc1cb68fc91e | 119 | } |
jakowisp | 10:fc1cb68fc91e | 120 | |
jakowisp | 10:fc1cb68fc91e | 121 | uint128_t operator&=(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 122 | UPPER &= rhs.UPPER; |
jakowisp | 10:fc1cb68fc91e | 123 | LOWER &= rhs.LOWER; |
jakowisp | 10:fc1cb68fc91e | 124 | return *this; |
jakowisp | 10:fc1cb68fc91e | 125 | } |
jakowisp | 10:fc1cb68fc91e | 126 | |
jakowisp | 10:fc1cb68fc91e | 127 | template <typename T> uint128_t operator|=(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 128 | LOWER |= (uint64_t) rhs; |
jakowisp | 10:fc1cb68fc91e | 129 | return *this; |
jakowisp | 10:fc1cb68fc91e | 130 | } |
jakowisp | 10:fc1cb68fc91e | 131 | |
jakowisp | 10:fc1cb68fc91e | 132 | uint128_t operator|=(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 133 | UPPER |= rhs.UPPER; |
jakowisp | 10:fc1cb68fc91e | 134 | LOWER |= rhs.LOWER; |
jakowisp | 10:fc1cb68fc91e | 135 | return *this; |
jakowisp | 10:fc1cb68fc91e | 136 | } |
jakowisp | 10:fc1cb68fc91e | 137 | |
jakowisp | 10:fc1cb68fc91e | 138 | template <typename T> uint128_t operator^=(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 139 | LOWER ^= (uint64_t) rhs; |
jakowisp | 10:fc1cb68fc91e | 140 | return *this; |
jakowisp | 10:fc1cb68fc91e | 141 | } |
jakowisp | 10:fc1cb68fc91e | 142 | |
jakowisp | 10:fc1cb68fc91e | 143 | uint128_t operator^=(const uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 144 | UPPER ^= rhs.UPPER; |
jakowisp | 10:fc1cb68fc91e | 145 | LOWER ^= rhs.LOWER; |
jakowisp | 10:fc1cb68fc91e | 146 | return *this; |
jakowisp | 10:fc1cb68fc91e | 147 | } |
jakowisp | 10:fc1cb68fc91e | 148 | |
jakowisp | 10:fc1cb68fc91e | 149 | uint128_t operator~(){ |
jakowisp | 10:fc1cb68fc91e | 150 | return uint128_t(~UPPER, ~LOWER); |
jakowisp | 10:fc1cb68fc91e | 151 | } |
jakowisp | 10:fc1cb68fc91e | 152 | |
jakowisp | 10:fc1cb68fc91e | 153 | // Bit Shift Operators |
jakowisp | 10:fc1cb68fc91e | 154 | template <typename T> |
jakowisp | 10:fc1cb68fc91e | 155 | uint128_t operator<<(const T shift){ |
jakowisp | 10:fc1cb68fc91e | 156 | if (shift >= 128) |
jakowisp | 10:fc1cb68fc91e | 157 | return uint128_t(0, 0); |
jakowisp | 10:fc1cb68fc91e | 158 | else if (shift == 64) |
jakowisp | 10:fc1cb68fc91e | 159 | return uint128_t(LOWER, 0); |
jakowisp | 10:fc1cb68fc91e | 160 | else if (shift == 0) |
jakowisp | 10:fc1cb68fc91e | 161 | return *this; |
jakowisp | 10:fc1cb68fc91e | 162 | else if (shift < 64) |
jakowisp | 10:fc1cb68fc91e | 163 | return uint128_t((UPPER << shift) + (LOWER >> (64 - shift)), LOWER << shift); |
jakowisp | 10:fc1cb68fc91e | 164 | else if ((128 > shift) && (shift > 64)) |
jakowisp | 10:fc1cb68fc91e | 165 | return uint128_t(LOWER << (shift - 64), 0); |
jakowisp | 10:fc1cb68fc91e | 166 | else |
jakowisp | 10:fc1cb68fc91e | 167 | return uint128_t(0); |
jakowisp | 10:fc1cb68fc91e | 168 | } |
jakowisp | 10:fc1cb68fc91e | 169 | |
jakowisp | 10:fc1cb68fc91e | 170 | template <typename T> |
jakowisp | 10:fc1cb68fc91e | 171 | uint128_t operator>>(const T shift){ |
jakowisp | 10:fc1cb68fc91e | 172 | if (shift >= 128) |
jakowisp | 10:fc1cb68fc91e | 173 | return uint128_t(0, 0); |
jakowisp | 10:fc1cb68fc91e | 174 | else if (shift == 64) |
jakowisp | 10:fc1cb68fc91e | 175 | return uint128_t(0, UPPER); |
jakowisp | 10:fc1cb68fc91e | 176 | else if (shift == 0) |
jakowisp | 10:fc1cb68fc91e | 177 | return *this; |
jakowisp | 10:fc1cb68fc91e | 178 | else if (shift < 64) |
jakowisp | 10:fc1cb68fc91e | 179 | return uint128_t(UPPER >> shift, (UPPER << (64 - shift)) + (LOWER >> shift)); |
jakowisp | 10:fc1cb68fc91e | 180 | else if ((128 > shift) && (shift > 64)) |
jakowisp | 10:fc1cb68fc91e | 181 | return uint128_t(0, (UPPER >> (shift - 64))); |
jakowisp | 10:fc1cb68fc91e | 182 | else |
jakowisp | 10:fc1cb68fc91e | 183 | return uint128_t(0); |
jakowisp | 10:fc1cb68fc91e | 184 | } |
jakowisp | 10:fc1cb68fc91e | 185 | |
jakowisp | 10:fc1cb68fc91e | 186 | uint128_t operator<<=(int shift){ |
jakowisp | 10:fc1cb68fc91e | 187 | *this = *this << shift; |
jakowisp | 10:fc1cb68fc91e | 188 | return *this; |
jakowisp | 10:fc1cb68fc91e | 189 | } |
jakowisp | 10:fc1cb68fc91e | 190 | |
jakowisp | 10:fc1cb68fc91e | 191 | uint128_t operator>>=(int shift){ |
jakowisp | 10:fc1cb68fc91e | 192 | *this = *this >> shift; |
jakowisp | 10:fc1cb68fc91e | 193 | return *this; |
jakowisp | 10:fc1cb68fc91e | 194 | } |
jakowisp | 10:fc1cb68fc91e | 195 | |
jakowisp | 10:fc1cb68fc91e | 196 | // Logical Operators |
jakowisp | 10:fc1cb68fc91e | 197 | bool operator!(){ |
jakowisp | 10:fc1cb68fc91e | 198 | return !(bool) (UPPER | LOWER); |
jakowisp | 10:fc1cb68fc91e | 199 | } |
jakowisp | 10:fc1cb68fc91e | 200 | |
jakowisp | 10:fc1cb68fc91e | 201 | template <typename T> bool operator&&(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 202 | return (bool) *this && rhs; |
jakowisp | 10:fc1cb68fc91e | 203 | } |
jakowisp | 10:fc1cb68fc91e | 204 | |
jakowisp | 10:fc1cb68fc91e | 205 | template <typename T> bool operator&&(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 206 | return (bool) *this && (bool) rhs; |
jakowisp | 10:fc1cb68fc91e | 207 | } |
jakowisp | 10:fc1cb68fc91e | 208 | |
jakowisp | 10:fc1cb68fc91e | 209 | template <typename T> bool operator||(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 210 | return ((bool) *this) || rhs; |
jakowisp | 10:fc1cb68fc91e | 211 | |
jakowisp | 10:fc1cb68fc91e | 212 | } |
jakowisp | 10:fc1cb68fc91e | 213 | |
jakowisp | 10:fc1cb68fc91e | 214 | template <typename T> bool operator||(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 215 | return ((bool) *this) || (bool) rhs; |
jakowisp | 10:fc1cb68fc91e | 216 | } |
jakowisp | 10:fc1cb68fc91e | 217 | |
jakowisp | 10:fc1cb68fc91e | 218 | // Comparison Operators |
jakowisp | 10:fc1cb68fc91e | 219 | template <typename T> bool operator==(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 220 | return (!UPPER && (LOWER == (uint64_t) rhs)); |
jakowisp | 10:fc1cb68fc91e | 221 | } |
jakowisp | 10:fc1cb68fc91e | 222 | |
jakowisp | 10:fc1cb68fc91e | 223 | bool operator==(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 224 | return ((UPPER == rhs.UPPER) && (LOWER == rhs.LOWER)); |
jakowisp | 10:fc1cb68fc91e | 225 | } |
jakowisp | 10:fc1cb68fc91e | 226 | |
jakowisp | 10:fc1cb68fc91e | 227 | template <typename T> bool operator!=(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 228 | return (UPPER | (LOWER != (uint64_t) rhs)); |
jakowisp | 10:fc1cb68fc91e | 229 | } |
jakowisp | 10:fc1cb68fc91e | 230 | |
jakowisp | 10:fc1cb68fc91e | 231 | bool operator!=(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 232 | return ((UPPER != rhs.UPPER) | (LOWER != rhs.LOWER)); |
jakowisp | 10:fc1cb68fc91e | 233 | } |
jakowisp | 10:fc1cb68fc91e | 234 | |
jakowisp | 10:fc1cb68fc91e | 235 | template <typename T> bool operator>(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 236 | if (UPPER) |
jakowisp | 10:fc1cb68fc91e | 237 | return true; |
jakowisp | 10:fc1cb68fc91e | 238 | return (LOWER > (uint64_t) rhs); |
jakowisp | 10:fc1cb68fc91e | 239 | } |
jakowisp | 10:fc1cb68fc91e | 240 | |
jakowisp | 10:fc1cb68fc91e | 241 | bool operator>(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 242 | if (UPPER == rhs.UPPER) |
jakowisp | 10:fc1cb68fc91e | 243 | return (LOWER > rhs.LOWER); |
jakowisp | 10:fc1cb68fc91e | 244 | if (UPPER > rhs.UPPER) |
jakowisp | 10:fc1cb68fc91e | 245 | return true; |
jakowisp | 10:fc1cb68fc91e | 246 | return false; |
jakowisp | 10:fc1cb68fc91e | 247 | } |
jakowisp | 10:fc1cb68fc91e | 248 | |
jakowisp | 10:fc1cb68fc91e | 249 | template <typename T> bool operator<(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 250 | if (!UPPER) |
jakowisp | 10:fc1cb68fc91e | 251 | return (LOWER < (uint64_t) rhs); |
jakowisp | 10:fc1cb68fc91e | 252 | return false; |
jakowisp | 10:fc1cb68fc91e | 253 | } |
jakowisp | 10:fc1cb68fc91e | 254 | |
jakowisp | 10:fc1cb68fc91e | 255 | bool operator<(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 256 | if (UPPER == rhs.UPPER) |
jakowisp | 10:fc1cb68fc91e | 257 | return (LOWER < rhs.LOWER); |
jakowisp | 10:fc1cb68fc91e | 258 | if (UPPER < rhs.UPPER) |
jakowisp | 10:fc1cb68fc91e | 259 | return true; |
jakowisp | 10:fc1cb68fc91e | 260 | return false; |
jakowisp | 10:fc1cb68fc91e | 261 | } |
jakowisp | 10:fc1cb68fc91e | 262 | |
jakowisp | 10:fc1cb68fc91e | 263 | template <typename T> bool operator>=(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 264 | return ((*this > rhs) | (*this == rhs)); |
jakowisp | 10:fc1cb68fc91e | 265 | } |
jakowisp | 10:fc1cb68fc91e | 266 | |
jakowisp | 10:fc1cb68fc91e | 267 | bool operator>=(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 268 | return ((*this > rhs) | (*this == rhs)); |
jakowisp | 10:fc1cb68fc91e | 269 | } |
jakowisp | 10:fc1cb68fc91e | 270 | |
jakowisp | 10:fc1cb68fc91e | 271 | template <typename T> bool operator<=(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 272 | return ((*this < rhs) | (*this == rhs)); |
jakowisp | 10:fc1cb68fc91e | 273 | } |
jakowisp | 10:fc1cb68fc91e | 274 | |
jakowisp | 10:fc1cb68fc91e | 275 | bool operator<=(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 276 | return ((*this < rhs) | (*this == rhs)); |
jakowisp | 10:fc1cb68fc91e | 277 | } |
jakowisp | 10:fc1cb68fc91e | 278 | |
jakowisp | 10:fc1cb68fc91e | 279 | // Arithmetic Operators |
jakowisp | 10:fc1cb68fc91e | 280 | template <typename T> uint128_t operator+(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 281 | return uint128_t(UPPER + ((LOWER + (uint64_t) rhs) < LOWER), LOWER + (uint64_t) rhs); |
jakowisp | 10:fc1cb68fc91e | 282 | } |
jakowisp | 10:fc1cb68fc91e | 283 | |
jakowisp | 10:fc1cb68fc91e | 284 | uint128_t operator+(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 285 | return uint128_t(rhs.UPPER + UPPER + ((LOWER + rhs.LOWER) < LOWER), LOWER + rhs.LOWER); |
jakowisp | 10:fc1cb68fc91e | 286 | } |
jakowisp | 10:fc1cb68fc91e | 287 | |
jakowisp | 10:fc1cb68fc91e | 288 | template <typename T> uint128_t operator+=(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 289 | UPPER = UPPER + ((LOWER + rhs) < LOWER); |
jakowisp | 10:fc1cb68fc91e | 290 | LOWER = LOWER + rhs; |
jakowisp | 10:fc1cb68fc91e | 291 | return *this; |
jakowisp | 10:fc1cb68fc91e | 292 | } |
jakowisp | 10:fc1cb68fc91e | 293 | |
jakowisp | 10:fc1cb68fc91e | 294 | uint128_t operator+=(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 295 | UPPER = rhs.UPPER + UPPER + ((LOWER + rhs.LOWER) < LOWER); |
jakowisp | 10:fc1cb68fc91e | 296 | LOWER = LOWER + rhs.LOWER; |
jakowisp | 10:fc1cb68fc91e | 297 | return *this; |
jakowisp | 10:fc1cb68fc91e | 298 | } |
jakowisp | 10:fc1cb68fc91e | 299 | |
jakowisp | 10:fc1cb68fc91e | 300 | template <typename T> uint128_t operator-(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 301 | return uint128_t((uint64_t) (UPPER - ((LOWER - rhs) > LOWER)), (uint64_t) (LOWER - rhs)); |
jakowisp | 10:fc1cb68fc91e | 302 | } |
jakowisp | 10:fc1cb68fc91e | 303 | |
jakowisp | 10:fc1cb68fc91e | 304 | uint128_t operator-(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 305 | return uint128_t(UPPER - rhs.UPPER - ((LOWER - rhs.LOWER) > LOWER), LOWER - rhs.LOWER); |
jakowisp | 10:fc1cb68fc91e | 306 | } |
jakowisp | 10:fc1cb68fc91e | 307 | |
jakowisp | 10:fc1cb68fc91e | 308 | template <typename T> uint128_t operator-=(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 309 | *this = *this - rhs; |
jakowisp | 10:fc1cb68fc91e | 310 | return *this; |
jakowisp | 10:fc1cb68fc91e | 311 | } |
jakowisp | 10:fc1cb68fc91e | 312 | |
jakowisp | 10:fc1cb68fc91e | 313 | uint128_t operator-=(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 314 | *this = *this - rhs; |
jakowisp | 10:fc1cb68fc91e | 315 | return *this; |
jakowisp | 10:fc1cb68fc91e | 316 | } |
jakowisp | 10:fc1cb68fc91e | 317 | |
jakowisp | 10:fc1cb68fc91e | 318 | template <typename T> uint128_t operator*(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 319 | return *this * uint128_t(rhs); |
jakowisp | 10:fc1cb68fc91e | 320 | } |
jakowisp | 10:fc1cb68fc91e | 321 | |
jakowisp | 10:fc1cb68fc91e | 322 | uint128_t operator*(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 323 | // split values into 4 32-bit parts |
jakowisp | 10:fc1cb68fc91e | 324 | uint64_t top[4] = {UPPER >> 32, UPPER % 0x100000000ULL, LOWER >> 32, LOWER % 0x100000000ULL}; |
jakowisp | 10:fc1cb68fc91e | 325 | uint64_t bottom[4] = {rhs.upper() >> 32, rhs.upper() % 0x100000000ULL, rhs.lower() >> 32, rhs.lower() % 0x100000000ULL}; |
jakowisp | 10:fc1cb68fc91e | 326 | uint64_t products[4][4]; |
jakowisp | 10:fc1cb68fc91e | 327 | |
jakowisp | 10:fc1cb68fc91e | 328 | for(int y = 3; y > -1; y--) |
jakowisp | 10:fc1cb68fc91e | 329 | for(int x = 3; x > -1; x--){ |
jakowisp | 10:fc1cb68fc91e | 330 | products[3 - x][y] = top[x] * bottom[y]; |
jakowisp | 10:fc1cb68fc91e | 331 | } |
jakowisp | 10:fc1cb68fc91e | 332 | |
jakowisp | 10:fc1cb68fc91e | 333 | // initial row |
jakowisp | 10:fc1cb68fc91e | 334 | uint64_t fourth32 = products[0][3] % 0x100000000ULL; |
jakowisp | 10:fc1cb68fc91e | 335 | uint64_t third32 = products[0][2] % 0x100000000ULL + (products[0][3] >> 32); |
jakowisp | 10:fc1cb68fc91e | 336 | uint64_t second32 = products[0][1] % 0x100000000ULL + (products[0][2] >> 32); |
jakowisp | 10:fc1cb68fc91e | 337 | uint64_t first32 = products[0][0] % 0x100000000ULL + (products[0][1] >> 32); |
jakowisp | 10:fc1cb68fc91e | 338 | |
jakowisp | 10:fc1cb68fc91e | 339 | // second row |
jakowisp | 10:fc1cb68fc91e | 340 | third32 += products[1][3] % 0x100000000ULL; |
jakowisp | 10:fc1cb68fc91e | 341 | second32 += (products[1][2] % 0x100000000ULL) + (products[1][3] >> 32); |
jakowisp | 10:fc1cb68fc91e | 342 | first32 += (products[1][1] % 0x100000000ULL) + (products[1][2] >> 32); |
jakowisp | 10:fc1cb68fc91e | 343 | |
jakowisp | 10:fc1cb68fc91e | 344 | // third row |
jakowisp | 10:fc1cb68fc91e | 345 | second32 += products[2][3] % 0x100000000ULL; |
jakowisp | 10:fc1cb68fc91e | 346 | first32 += (products[2][2] % 0x100000000ULL) + (products[2][3] >> 32); |
jakowisp | 10:fc1cb68fc91e | 347 | |
jakowisp | 10:fc1cb68fc91e | 348 | // fourth row |
jakowisp | 10:fc1cb68fc91e | 349 | first32 += products[3][3] % 0x100000000ULL; |
jakowisp | 10:fc1cb68fc91e | 350 | |
jakowisp | 10:fc1cb68fc91e | 351 | // combines the values, taking care of carry over |
jakowisp | 10:fc1cb68fc91e | 352 | return uint128_t(first32 << 32, 0) + uint128_t(third32 >> 32, third32 << 32) + uint128_t(second32, 0) + uint128_t(fourth32); |
jakowisp | 10:fc1cb68fc91e | 353 | } |
jakowisp | 10:fc1cb68fc91e | 354 | |
jakowisp | 10:fc1cb68fc91e | 355 | template <typename T> uint128_t operator*=(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 356 | *this = *this * uint128_t(rhs); |
jakowisp | 10:fc1cb68fc91e | 357 | return *this; |
jakowisp | 10:fc1cb68fc91e | 358 | } |
jakowisp | 10:fc1cb68fc91e | 359 | |
jakowisp | 10:fc1cb68fc91e | 360 | uint128_t operator*=(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 361 | *this = *this * rhs; |
jakowisp | 10:fc1cb68fc91e | 362 | return *this; |
jakowisp | 10:fc1cb68fc91e | 363 | } |
jakowisp | 10:fc1cb68fc91e | 364 | |
jakowisp | 10:fc1cb68fc91e | 365 | template <typename T> uint128_t operator/(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 366 | return *this / uint128_t(rhs); |
jakowisp | 10:fc1cb68fc91e | 367 | } |
jakowisp | 10:fc1cb68fc91e | 368 | |
jakowisp | 10:fc1cb68fc91e | 369 | uint128_t operator/(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 370 | // Save some calculations ///////////////////// |
jakowisp | 10:fc1cb68fc91e | 371 | if (rhs == 0){ |
jakowisp | 10:fc1cb68fc91e | 372 | std::cout << "Error: division or modulus by zero" << std::endl; |
jakowisp | 10:fc1cb68fc91e | 373 | exit(1); |
jakowisp | 10:fc1cb68fc91e | 374 | } |
jakowisp | 10:fc1cb68fc91e | 375 | if (rhs == 1) |
jakowisp | 10:fc1cb68fc91e | 376 | return *this; |
jakowisp | 10:fc1cb68fc91e | 377 | if (*this == rhs) |
jakowisp | 10:fc1cb68fc91e | 378 | return uint128_t(1); |
jakowisp | 10:fc1cb68fc91e | 379 | if ((*this == 0) | (*this < rhs)) |
jakowisp | 10:fc1cb68fc91e | 380 | return uint128_t(0); |
jakowisp | 10:fc1cb68fc91e | 381 | // Checks for divisors that are powers of two |
jakowisp | 10:fc1cb68fc91e | 382 | uint16_t s = 0; |
jakowisp | 10:fc1cb68fc91e | 383 | uint128_t copyd(rhs); |
jakowisp | 10:fc1cb68fc91e | 384 | while ((copyd.LOWER & 1) == 0){ |
jakowisp | 10:fc1cb68fc91e | 385 | copyd >>= 1; |
jakowisp | 10:fc1cb68fc91e | 386 | s++; |
jakowisp | 10:fc1cb68fc91e | 387 | } |
jakowisp | 10:fc1cb68fc91e | 388 | if (copyd == 1) |
jakowisp | 10:fc1cb68fc91e | 389 | return *this >> s; |
jakowisp | 10:fc1cb68fc91e | 390 | //////////////////////////////////////////////// |
jakowisp | 10:fc1cb68fc91e | 391 | uint128_t copyn(*this), quotient = 0; |
jakowisp | 10:fc1cb68fc91e | 392 | while (copyn >= rhs){ |
jakowisp | 10:fc1cb68fc91e | 393 | uint128_t copyd(rhs), temp(1); |
jakowisp | 10:fc1cb68fc91e | 394 | // shift the divsor to match the highest bit |
jakowisp | 10:fc1cb68fc91e | 395 | while ((copyn >> 1) > copyd){ |
jakowisp | 10:fc1cb68fc91e | 396 | copyd <<= 1; |
jakowisp | 10:fc1cb68fc91e | 397 | temp <<= 1; |
jakowisp | 10:fc1cb68fc91e | 398 | } |
jakowisp | 10:fc1cb68fc91e | 399 | copyn -= copyd; |
jakowisp | 10:fc1cb68fc91e | 400 | quotient += temp; |
jakowisp | 10:fc1cb68fc91e | 401 | } |
jakowisp | 10:fc1cb68fc91e | 402 | return quotient; |
jakowisp | 10:fc1cb68fc91e | 403 | } |
jakowisp | 10:fc1cb68fc91e | 404 | |
jakowisp | 10:fc1cb68fc91e | 405 | template <typename T> uint128_t operator/=(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 406 | *this = *this / uint128_t(rhs); |
jakowisp | 10:fc1cb68fc91e | 407 | return *this; |
jakowisp | 10:fc1cb68fc91e | 408 | } |
jakowisp | 10:fc1cb68fc91e | 409 | |
jakowisp | 10:fc1cb68fc91e | 410 | uint128_t operator/=(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 411 | *this = *this / rhs; |
jakowisp | 10:fc1cb68fc91e | 412 | return *this; |
jakowisp | 10:fc1cb68fc91e | 413 | } |
jakowisp | 10:fc1cb68fc91e | 414 | |
jakowisp | 10:fc1cb68fc91e | 415 | template <typename T> uint128_t operator%(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 416 | return *this - (rhs * (*this / rhs)); |
jakowisp | 10:fc1cb68fc91e | 417 | } |
jakowisp | 10:fc1cb68fc91e | 418 | |
jakowisp | 10:fc1cb68fc91e | 419 | uint128_t operator%(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 420 | return *this - (rhs * (*this / rhs)); |
jakowisp | 10:fc1cb68fc91e | 421 | } |
jakowisp | 10:fc1cb68fc91e | 422 | |
jakowisp | 10:fc1cb68fc91e | 423 | template <typename T> uint128_t operator%=(T rhs){ |
jakowisp | 10:fc1cb68fc91e | 424 | *this = *this % uint128_t(rhs); |
jakowisp | 10:fc1cb68fc91e | 425 | return *this; |
jakowisp | 10:fc1cb68fc91e | 426 | } |
jakowisp | 10:fc1cb68fc91e | 427 | |
jakowisp | 10:fc1cb68fc91e | 428 | uint128_t operator%=(uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 429 | *this = *this % rhs; |
jakowisp | 10:fc1cb68fc91e | 430 | return *this; |
jakowisp | 10:fc1cb68fc91e | 431 | } |
jakowisp | 10:fc1cb68fc91e | 432 | |
jakowisp | 10:fc1cb68fc91e | 433 | // Increment Operator |
jakowisp | 10:fc1cb68fc91e | 434 | uint128_t operator++(){ |
jakowisp | 10:fc1cb68fc91e | 435 | *this += 1; |
jakowisp | 10:fc1cb68fc91e | 436 | return *this; |
jakowisp | 10:fc1cb68fc91e | 437 | } |
jakowisp | 10:fc1cb68fc91e | 438 | |
jakowisp | 10:fc1cb68fc91e | 439 | uint128_t operator++(int){ |
jakowisp | 10:fc1cb68fc91e | 440 | uint128_t temp(*this); |
jakowisp | 10:fc1cb68fc91e | 441 | ++*this; |
jakowisp | 10:fc1cb68fc91e | 442 | return temp; |
jakowisp | 10:fc1cb68fc91e | 443 | } |
jakowisp | 10:fc1cb68fc91e | 444 | |
jakowisp | 10:fc1cb68fc91e | 445 | // Decrement Operator |
jakowisp | 10:fc1cb68fc91e | 446 | uint128_t operator--(){ |
jakowisp | 10:fc1cb68fc91e | 447 | *this -= 1; |
jakowisp | 10:fc1cb68fc91e | 448 | return *this; |
jakowisp | 10:fc1cb68fc91e | 449 | } |
jakowisp | 10:fc1cb68fc91e | 450 | |
jakowisp | 10:fc1cb68fc91e | 451 | uint128_t operator--(int){ |
jakowisp | 10:fc1cb68fc91e | 452 | uint128_t temp(*this); |
jakowisp | 10:fc1cb68fc91e | 453 | --*this; |
jakowisp | 10:fc1cb68fc91e | 454 | return temp; |
jakowisp | 10:fc1cb68fc91e | 455 | } |
jakowisp | 10:fc1cb68fc91e | 456 | |
jakowisp | 10:fc1cb68fc91e | 457 | // get private values |
jakowisp | 10:fc1cb68fc91e | 458 | uint64_t upper(){ |
jakowisp | 10:fc1cb68fc91e | 459 | return UPPER; |
jakowisp | 10:fc1cb68fc91e | 460 | } |
jakowisp | 10:fc1cb68fc91e | 461 | |
jakowisp | 10:fc1cb68fc91e | 462 | uint64_t lower(){ |
jakowisp | 10:fc1cb68fc91e | 463 | return LOWER; |
jakowisp | 10:fc1cb68fc91e | 464 | } |
jakowisp | 10:fc1cb68fc91e | 465 | }; |
jakowisp | 10:fc1cb68fc91e | 466 | // lhs type T as first arguemnt |
jakowisp | 10:fc1cb68fc91e | 467 | |
jakowisp | 10:fc1cb68fc91e | 468 | // Bitwise Operators |
jakowisp | 10:fc1cb68fc91e | 469 | template <typename T> T operator&(T lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 470 | T out = lhs & (T) rhs.lower(); |
jakowisp | 10:fc1cb68fc91e | 471 | return out; |
jakowisp | 10:fc1cb68fc91e | 472 | } |
jakowisp | 10:fc1cb68fc91e | 473 | |
jakowisp | 10:fc1cb68fc91e | 474 | template <typename T> T operator|(T lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 475 | T out = lhs | (T) rhs.lower(); |
jakowisp | 10:fc1cb68fc91e | 476 | return out; |
jakowisp | 10:fc1cb68fc91e | 477 | } |
jakowisp | 10:fc1cb68fc91e | 478 | |
jakowisp | 10:fc1cb68fc91e | 479 | template <typename T> T operator^(T lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 480 | T out = lhs ^ (T) rhs.lower(); |
jakowisp | 10:fc1cb68fc91e | 481 | return out; |
jakowisp | 10:fc1cb68fc91e | 482 | } |
jakowisp | 10:fc1cb68fc91e | 483 | |
jakowisp | 10:fc1cb68fc91e | 484 | template <typename T> T operator&=(T & lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 485 | lhs &= (T) rhs.lower(); |
jakowisp | 10:fc1cb68fc91e | 486 | return lhs; |
jakowisp | 10:fc1cb68fc91e | 487 | } |
jakowisp | 10:fc1cb68fc91e | 488 | |
jakowisp | 10:fc1cb68fc91e | 489 | template <typename T> T operator|=(T & lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 490 | lhs |= (T) rhs.lower(); |
jakowisp | 10:fc1cb68fc91e | 491 | return lhs; |
jakowisp | 10:fc1cb68fc91e | 492 | } |
jakowisp | 10:fc1cb68fc91e | 493 | |
jakowisp | 10:fc1cb68fc91e | 494 | template <typename T> T operator^=(T & lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 495 | lhs ^= (T) rhs.lower(); |
jakowisp | 10:fc1cb68fc91e | 496 | return lhs; |
jakowisp | 10:fc1cb68fc91e | 497 | } |
jakowisp | 10:fc1cb68fc91e | 498 | |
jakowisp | 10:fc1cb68fc91e | 499 | // Comparison Operators |
jakowisp | 10:fc1cb68fc91e | 500 | template <typename T> bool operator==(T lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 501 | return (!rhs.upper() && ((uint64_t) lhs == rhs.lower())); |
jakowisp | 10:fc1cb68fc91e | 502 | } |
jakowisp | 10:fc1cb68fc91e | 503 | |
jakowisp | 10:fc1cb68fc91e | 504 | template <typename T> bool operator!=(T lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 505 | return (rhs.upper() | ((uint64_t) lhs != rhs.lower())); |
jakowisp | 10:fc1cb68fc91e | 506 | } |
jakowisp | 10:fc1cb68fc91e | 507 | |
jakowisp | 10:fc1cb68fc91e | 508 | template <typename T> bool operator>(T lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 509 | if (rhs.upper()) |
jakowisp | 10:fc1cb68fc91e | 510 | return false; |
jakowisp | 10:fc1cb68fc91e | 511 | return ((uint64_t) lhs > rhs.lower()); |
jakowisp | 10:fc1cb68fc91e | 512 | } |
jakowisp | 10:fc1cb68fc91e | 513 | |
jakowisp | 10:fc1cb68fc91e | 514 | template <typename T> bool operator<(T lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 515 | if (rhs.upper()) |
jakowisp | 10:fc1cb68fc91e | 516 | return true; |
jakowisp | 10:fc1cb68fc91e | 517 | return ((uint64_t) lhs < rhs.lower()); |
jakowisp | 10:fc1cb68fc91e | 518 | } |
jakowisp | 10:fc1cb68fc91e | 519 | |
jakowisp | 10:fc1cb68fc91e | 520 | template <typename T> bool operator>=(T lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 521 | if (rhs.upper()) |
jakowisp | 10:fc1cb68fc91e | 522 | return false; |
jakowisp | 10:fc1cb68fc91e | 523 | return ((uint64_t) lhs >= rhs.lower()); |
jakowisp | 10:fc1cb68fc91e | 524 | } |
jakowisp | 10:fc1cb68fc91e | 525 | |
jakowisp | 10:fc1cb68fc91e | 526 | template <typename T> bool operator<=(T lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 527 | if (rhs.upper()) |
jakowisp | 10:fc1cb68fc91e | 528 | return true; |
jakowisp | 10:fc1cb68fc91e | 529 | return ((uint64_t) lhs <= rhs.lower()); |
jakowisp | 10:fc1cb68fc91e | 530 | } |
jakowisp | 10:fc1cb68fc91e | 531 | |
jakowisp | 10:fc1cb68fc91e | 532 | // Arithmetic Operators |
jakowisp | 10:fc1cb68fc91e | 533 | template <typename T> T operator+(T lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 534 | return (T) (rhs + lhs); |
jakowisp | 10:fc1cb68fc91e | 535 | } |
jakowisp | 10:fc1cb68fc91e | 536 | |
jakowisp | 10:fc1cb68fc91e | 537 | template <typename T> T & operator+=(T & lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 538 | lhs = (T) (rhs + lhs); |
jakowisp | 10:fc1cb68fc91e | 539 | return lhs; |
jakowisp | 10:fc1cb68fc91e | 540 | } |
jakowisp | 10:fc1cb68fc91e | 541 | |
jakowisp | 10:fc1cb68fc91e | 542 | template <typename T> T operator-(T lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 543 | return (T) (rhs - lhs); |
jakowisp | 10:fc1cb68fc91e | 544 | } |
jakowisp | 10:fc1cb68fc91e | 545 | |
jakowisp | 10:fc1cb68fc91e | 546 | template <typename T> T & operator-=(T & lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 547 | lhs = (T) (rhs - lhs); |
jakowisp | 10:fc1cb68fc91e | 548 | return lhs; |
jakowisp | 10:fc1cb68fc91e | 549 | } |
jakowisp | 10:fc1cb68fc91e | 550 | |
jakowisp | 10:fc1cb68fc91e | 551 | template <typename T> T operator*(T lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 552 | return lhs * rhs.lower(); |
jakowisp | 10:fc1cb68fc91e | 553 | } |
jakowisp | 10:fc1cb68fc91e | 554 | |
jakowisp | 10:fc1cb68fc91e | 555 | template <typename T> T & operator*=(T & lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 556 | lhs = (T) (rhs.lower() * lhs); |
jakowisp | 10:fc1cb68fc91e | 557 | return lhs; |
jakowisp | 10:fc1cb68fc91e | 558 | } |
jakowisp | 10:fc1cb68fc91e | 559 | |
jakowisp | 10:fc1cb68fc91e | 560 | template <typename T> T operator/(T lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 561 | return (T) (uint128_t(lhs) / rhs); |
jakowisp | 10:fc1cb68fc91e | 562 | } |
jakowisp | 10:fc1cb68fc91e | 563 | |
jakowisp | 10:fc1cb68fc91e | 564 | template <typename T> T & operator/=(T & lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 565 | lhs = (T) (uint128_t(lhs) / rhs); |
jakowisp | 10:fc1cb68fc91e | 566 | return lhs; |
jakowisp | 10:fc1cb68fc91e | 567 | } |
jakowisp | 10:fc1cb68fc91e | 568 | |
jakowisp | 10:fc1cb68fc91e | 569 | template <typename T> T operator%(T lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 570 | return (T) (uint128_t(lhs) % rhs); |
jakowisp | 10:fc1cb68fc91e | 571 | } |
jakowisp | 10:fc1cb68fc91e | 572 | |
jakowisp | 10:fc1cb68fc91e | 573 | template <typename T> T & operator%=(T & lhs, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 574 | lhs = (T) (uint128_t(lhs) % rhs); |
jakowisp | 10:fc1cb68fc91e | 575 | return lhs; |
jakowisp | 10:fc1cb68fc91e | 576 | } |
jakowisp | 10:fc1cb68fc91e | 577 | |
jakowisp | 10:fc1cb68fc91e | 578 | // IO Operator |
jakowisp | 10:fc1cb68fc91e | 579 | std::ostream & operator<<(std::ostream & stream, uint128_t rhs){ |
jakowisp | 10:fc1cb68fc91e | 580 | std::string out = ""; |
jakowisp | 10:fc1cb68fc91e | 581 | if (rhs == 0) |
jakowisp | 10:fc1cb68fc91e | 582 | out = "0"; |
jakowisp | 10:fc1cb68fc91e | 583 | else { |
jakowisp | 10:fc1cb68fc91e | 584 | int div = 10; |
jakowisp | 10:fc1cb68fc91e | 585 | if (stream.flags() & stream.oct) |
jakowisp | 10:fc1cb68fc91e | 586 | div = 8; |
jakowisp | 10:fc1cb68fc91e | 587 | if (stream.flags() & stream.dec) |
jakowisp | 10:fc1cb68fc91e | 588 | div = 10; |
jakowisp | 10:fc1cb68fc91e | 589 | if (stream.flags() & stream.hex) |
jakowisp | 10:fc1cb68fc91e | 590 | div = 16; |
jakowisp | 10:fc1cb68fc91e | 591 | while (rhs > 0){ |
jakowisp | 10:fc1cb68fc91e | 592 | out = "0123456789abcdef"[size_t(rhs % div)] + out; |
jakowisp | 10:fc1cb68fc91e | 593 | rhs /= div; |
jakowisp | 10:fc1cb68fc91e | 594 | } |
jakowisp | 10:fc1cb68fc91e | 595 | } |
jakowisp | 10:fc1cb68fc91e | 596 | stream << out; |
jakowisp | 10:fc1cb68fc91e | 597 | return stream; |
jakowisp | 10:fc1cb68fc91e | 598 | } |
jakowisp | 10:fc1cb68fc91e | 599 | |
jakowisp | 10:fc1cb68fc91e | 600 | #endif // UINT128_T_H |