Library to allo USB PTP device to be hosted by the mbed platform

Dependents:   class_project_main

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?

UserRevisionLine numberNew 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