uint128_t.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. #include <uint128_t.h>
  2. const uint128_t uint128_0(0);
  3. const uint128_t uint128_1(1);
  4. uint128_t::uint128_t()
  5. : UPPER(0), LOWER(0)
  6. {}
  7. uint128_t::uint128_t(const uint128_t & rhs)
  8. : UPPER(rhs.UPPER), LOWER(rhs.LOWER)
  9. {}
  10. uint128_t::uint128_t(uint128_t && rhs)
  11. : UPPER(std::move(rhs.UPPER)), LOWER(std::move(rhs.LOWER))
  12. {
  13. if (this != &rhs){
  14. rhs.UPPER = 0;
  15. rhs.LOWER = 0;
  16. }
  17. }
  18. uint128_t & uint128_t::operator=(const uint128_t & rhs){
  19. UPPER = rhs.UPPER;
  20. LOWER = rhs.LOWER;
  21. return *this;
  22. }
  23. uint128_t & uint128_t::operator=(uint128_t && rhs){
  24. if (this != &rhs){
  25. UPPER = std::move(rhs.UPPER);
  26. LOWER = std::move(rhs.LOWER);
  27. rhs.UPPER = 0;
  28. rhs.LOWER = 0;
  29. }
  30. return *this;
  31. }
  32. uint128_t::operator bool() const{
  33. return (bool) (UPPER | LOWER);
  34. }
  35. uint128_t::operator uint8_t() const{
  36. return (uint8_t) LOWER;
  37. }
  38. uint128_t::operator uint16_t() const{
  39. return (uint16_t) LOWER;
  40. }
  41. uint128_t::operator uint32_t() const{
  42. return (uint32_t) LOWER;
  43. }
  44. uint128_t::operator uint64_t() const{
  45. return (uint64_t) LOWER;
  46. }
  47. uint128_t uint128_t::operator&(const uint128_t & rhs) const{
  48. return uint128_t(UPPER & rhs.UPPER, LOWER & rhs.LOWER);
  49. }
  50. uint128_t & uint128_t::operator&=(const uint128_t & rhs){
  51. UPPER &= rhs.UPPER;
  52. LOWER &= rhs.LOWER;
  53. return *this;
  54. }
  55. uint128_t uint128_t::operator|(const uint128_t & rhs) const{
  56. return uint128_t(UPPER | rhs.UPPER, LOWER | rhs.LOWER);
  57. }
  58. uint128_t & uint128_t::operator|=(const uint128_t & rhs){
  59. UPPER |= rhs.UPPER;
  60. LOWER |= rhs.LOWER;
  61. return *this;
  62. }
  63. uint128_t uint128_t::operator^(const uint128_t & rhs) const{
  64. return uint128_t(UPPER ^ rhs.UPPER, LOWER ^ rhs.LOWER);
  65. }
  66. uint128_t & uint128_t::operator^=(const uint128_t & rhs){
  67. UPPER ^= rhs.UPPER;
  68. LOWER ^= rhs.LOWER;
  69. return *this;
  70. }
  71. uint128_t uint128_t::operator~() const{
  72. return uint128_t(~UPPER, ~LOWER);
  73. }
  74. uint128_t uint128_t::operator<<(const uint128_t & rhs) const{
  75. const uint64_t shift = rhs.LOWER;
  76. if (((bool) rhs.UPPER) || (shift >= 128)){
  77. return uint128_0;
  78. }
  79. else if (shift == 64){
  80. return uint128_t(LOWER, 0);
  81. }
  82. else if (shift == 0){
  83. return *this;
  84. }
  85. else if (shift < 64){
  86. return uint128_t((UPPER << shift) + (LOWER >> (64 - shift)), LOWER << shift);
  87. }
  88. else if ((128 > shift) && (shift > 64)){
  89. return uint128_t(LOWER << (shift - 64), 0);
  90. }
  91. else{
  92. return uint128_0;
  93. }
  94. }
  95. uint128_t & uint128_t::operator<<=(const uint128_t & rhs){
  96. *this = *this << rhs;
  97. return *this;
  98. }
  99. uint128_t uint128_t::operator>>(const uint128_t & rhs) const{
  100. const uint64_t shift = rhs.LOWER;
  101. if (((bool) rhs.UPPER) || (shift >= 128)){
  102. return uint128_0;
  103. }
  104. else if (shift == 64){
  105. return uint128_t(0, UPPER);
  106. }
  107. else if (shift == 0){
  108. return *this;
  109. }
  110. else if (shift < 64){
  111. return uint128_t(UPPER >> shift, (UPPER << (64 - shift)) + (LOWER >> shift));
  112. }
  113. else if ((128 > shift) && (shift > 64)){
  114. return uint128_t(0, (UPPER >> (shift - 64)));
  115. }
  116. else{
  117. return uint128_0;
  118. }
  119. }
  120. uint128_t & uint128_t::operator>>=(const uint128_t & rhs){
  121. *this = *this >> rhs;
  122. return *this;
  123. }
  124. bool uint128_t::operator!() const{
  125. return !(bool) (UPPER | LOWER);
  126. }
  127. bool uint128_t::operator&&(const uint128_t & rhs) const{
  128. return ((bool) *this && rhs);
  129. }
  130. bool uint128_t::operator||(const uint128_t & rhs) const{
  131. return ((bool) *this || rhs);
  132. }
  133. bool uint128_t::operator==(const uint128_t & rhs) const{
  134. return ((UPPER == rhs.UPPER) && (LOWER == rhs.LOWER));
  135. }
  136. bool uint128_t::operator!=(const uint128_t & rhs) const{
  137. return ((UPPER != rhs.UPPER) | (LOWER != rhs.LOWER));
  138. }
  139. bool uint128_t::operator>(const uint128_t & rhs) const{
  140. if (UPPER == rhs.UPPER){
  141. return (LOWER > rhs.LOWER);
  142. }
  143. return (UPPER > rhs.UPPER);
  144. }
  145. bool uint128_t::operator<(const uint128_t & rhs) const{
  146. if (UPPER == rhs.UPPER){
  147. return (LOWER < rhs.LOWER);
  148. }
  149. return (UPPER < rhs.UPPER);
  150. }
  151. bool uint128_t::operator>=(const uint128_t & rhs) const{
  152. return ((*this > rhs) | (*this == rhs));
  153. }
  154. bool uint128_t::operator<=(const uint128_t & rhs) const{
  155. return ((*this < rhs) | (*this == rhs));
  156. }
  157. uint128_t uint128_t::operator+(const uint128_t & rhs) const{
  158. return uint128_t(UPPER + rhs.UPPER + ((LOWER + rhs.LOWER) < LOWER), LOWER + rhs.LOWER);
  159. }
  160. uint128_t & uint128_t::operator+=(const uint128_t & rhs){
  161. UPPER += rhs.UPPER + ((LOWER + rhs.LOWER) < LOWER);
  162. LOWER += rhs.LOWER;
  163. return *this;
  164. }
  165. uint128_t uint128_t::operator-(const uint128_t & rhs) const{
  166. return uint128_t(UPPER - rhs.UPPER - ((LOWER - rhs.LOWER) > LOWER), LOWER - rhs.LOWER);
  167. }
  168. uint128_t & uint128_t::operator-=(const uint128_t & rhs){
  169. *this = *this - rhs;
  170. return *this;
  171. }
  172. uint128_t uint128_t::operator*(const uint128_t & rhs) const{
  173. // split values into 4 32-bit parts
  174. uint64_t top[4] = {UPPER >> 32, UPPER & 0xffffffff, LOWER >> 32, LOWER & 0xffffffff};
  175. uint64_t bottom[4] = {rhs.UPPER >> 32, rhs.UPPER & 0xffffffff, rhs.LOWER >> 32, rhs.LOWER & 0xffffffff};
  176. uint64_t products[4][4];
  177. // multiply each component of the values
  178. for(int y = 3; y > -1; y--){
  179. for(int x = 3; x > -1; x--){
  180. products[3 - x][y] = top[x] * bottom[y];
  181. }
  182. }
  183. // first row
  184. uint64_t fourth32 = (products[0][3] & 0xffffffff);
  185. uint64_t third32 = (products[0][2] & 0xffffffff) + (products[0][3] >> 32);
  186. uint64_t second32 = (products[0][1] & 0xffffffff) + (products[0][2] >> 32);
  187. uint64_t first32 = (products[0][0] & 0xffffffff) + (products[0][1] >> 32);
  188. // second row
  189. third32 += (products[1][3] & 0xffffffff);
  190. second32 += (products[1][2] & 0xffffffff) + (products[1][3] >> 32);
  191. first32 += (products[1][1] & 0xffffffff) + (products[1][2] >> 32);
  192. // third row
  193. second32 += (products[2][3] & 0xffffffff);
  194. first32 += (products[2][2] & 0xffffffff) + (products[2][3] >> 32);
  195. // fourth row
  196. first32 += (products[3][3] & 0xffffffff);
  197. // move carry to next digit
  198. third32 += fourth32 >> 32;
  199. second32 += third32 >> 32;
  200. first32 += second32 >> 32;
  201. // remove carry from current digit
  202. fourth32 &= 0xffffffff;
  203. third32 &= 0xffffffff;
  204. second32 &= 0xffffffff;
  205. first32 &= 0xffffffff;
  206. // combine components
  207. return uint128_t((first32 << 32) | second32, (third32 << 32) | fourth32);
  208. }
  209. uint128_t & uint128_t::operator*=(const uint128_t & rhs){
  210. *this = *this * rhs;
  211. return *this;
  212. }
  213. std::pair <uint128_t, uint128_t> uint128_t::divmod(const uint128_t & lhs, const uint128_t & rhs) const{
  214. // Save some calculations /////////////////////
  215. if (rhs == uint128_0){
  216. throw std::domain_error("Error: division or modulus by 0");
  217. }
  218. else if (rhs == uint128_1){
  219. return std::pair <uint128_t, uint128_t> (lhs, uint128_0);
  220. }
  221. else if (lhs == rhs){
  222. return std::pair <uint128_t, uint128_t> (uint128_1, uint128_0);
  223. }
  224. else if ((lhs == uint128_0) || (lhs < rhs)){
  225. return std::pair <uint128_t, uint128_t> (uint128_0, lhs);
  226. }
  227. std::pair <uint128_t, uint128_t> qr (uint128_0, uint128_0);
  228. for(uint8_t x = lhs.bits(); x > 0; x--){
  229. qr.first <<= uint128_1;
  230. qr.second <<= uint128_1;
  231. if ((lhs >> (x - 1U)) & 1){
  232. ++qr.second;
  233. }
  234. if (qr.second >= rhs){
  235. qr.second -= rhs;
  236. ++qr.first;
  237. }
  238. }
  239. return qr;
  240. }
  241. uint128_t uint128_t::operator/(const uint128_t & rhs) const{
  242. return divmod(*this, rhs).first;
  243. }
  244. uint128_t & uint128_t::operator/=(const uint128_t & rhs){
  245. *this = *this / rhs;
  246. return *this;
  247. }
  248. uint128_t uint128_t::operator%(const uint128_t & rhs) const{
  249. return divmod(*this, rhs).second;
  250. }
  251. uint128_t & uint128_t::operator%=(const uint128_t & rhs){
  252. *this = *this % rhs;
  253. return *this;
  254. }
  255. uint128_t & uint128_t::operator++(){
  256. return *this += uint128_1;
  257. }
  258. uint128_t uint128_t::operator++(int){
  259. uint128_t temp(*this);
  260. ++*this;
  261. return temp;
  262. }
  263. uint128_t & uint128_t::operator--(){
  264. return *this -= uint128_1;
  265. }
  266. uint128_t uint128_t::operator--(int){
  267. uint128_t temp(*this);
  268. --*this;
  269. return temp;
  270. }
  271. uint128_t uint128_t::operator+() const{
  272. return *this;
  273. }
  274. uint128_t uint128_t::operator-() const{
  275. return ~*this + uint128_1;
  276. }
  277. const uint64_t & uint128_t::upper() const{
  278. return UPPER;
  279. }
  280. const uint64_t & uint128_t::lower() const{
  281. return LOWER;
  282. }
  283. uint8_t uint128_t::bits() const{
  284. uint8_t out = 0;
  285. if (UPPER){
  286. out = 64;
  287. uint64_t up = UPPER;
  288. while (up){
  289. up >>= 1;
  290. out++;
  291. }
  292. }
  293. else{
  294. uint64_t low = LOWER;
  295. while (low){
  296. low >>= 1;
  297. out++;
  298. }
  299. }
  300. return out;
  301. }
  302. std::string uint128_t::str(uint8_t base, const unsigned int & len) const{
  303. if ((base < 2) || (base > 16)){
  304. throw std::invalid_argument("Base must be in the range [2, 16]");
  305. }
  306. std::string out = "";
  307. if (!(*this)){
  308. out = "0";
  309. }
  310. else{
  311. std::pair <uint128_t, uint128_t> qr(*this, uint128_0);
  312. do{
  313. qr = divmod(qr.first, base);
  314. out = "0123456789abcdef"[(uint8_t) qr.second] + out;
  315. } while (qr.first);
  316. }
  317. if (out.size() < len){
  318. out = std::string(len - out.size(), '0') + out;
  319. }
  320. return out;
  321. }
  322. uint128_t operator<<(const bool & lhs, const uint128_t & rhs){
  323. return uint128_t(lhs) << rhs;
  324. }
  325. uint128_t operator<<(const uint8_t & lhs, const uint128_t & rhs){
  326. return uint128_t(lhs) << rhs;
  327. }
  328. uint128_t operator<<(const uint16_t & lhs, const uint128_t & rhs){
  329. return uint128_t(lhs) << rhs;
  330. }
  331. uint128_t operator<<(const uint32_t & lhs, const uint128_t & rhs){
  332. return uint128_t(lhs) << rhs;
  333. }
  334. uint128_t operator<<(const uint64_t & lhs, const uint128_t & rhs){
  335. return uint128_t(lhs) << rhs;
  336. }
  337. uint128_t operator<<(const int8_t & lhs, const uint128_t & rhs){
  338. return uint128_t(lhs) << rhs;
  339. }
  340. uint128_t operator<<(const int16_t & lhs, const uint128_t & rhs){
  341. return uint128_t(lhs) << rhs;
  342. }
  343. uint128_t operator<<(const int32_t & lhs, const uint128_t & rhs){
  344. return uint128_t(lhs) << rhs;
  345. }
  346. uint128_t operator<<(const int64_t & lhs, const uint128_t & rhs){
  347. return uint128_t(lhs) << rhs;
  348. }
  349. uint128_t operator>>(const bool & lhs, const uint128_t & rhs){
  350. return uint128_t(lhs) >> rhs;
  351. }
  352. uint128_t operator>>(const uint8_t & lhs, const uint128_t & rhs){
  353. return uint128_t(lhs) >> rhs;
  354. }
  355. uint128_t operator>>(const uint16_t & lhs, const uint128_t & rhs){
  356. return uint128_t(lhs) >> rhs;
  357. }
  358. uint128_t operator>>(const uint32_t & lhs, const uint128_t & rhs){
  359. return uint128_t(lhs) >> rhs;
  360. }
  361. uint128_t operator>>(const uint64_t & lhs, const uint128_t & rhs){
  362. return uint128_t(lhs) >> rhs;
  363. }
  364. uint128_t operator>>(const int8_t & lhs, const uint128_t & rhs){
  365. return uint128_t(lhs) >> rhs;
  366. }
  367. uint128_t operator>>(const int16_t & lhs, const uint128_t & rhs){
  368. return uint128_t(lhs) >> rhs;
  369. }
  370. uint128_t operator>>(const int32_t & lhs, const uint128_t & rhs){
  371. return uint128_t(lhs) >> rhs;
  372. }
  373. uint128_t operator>>(const int64_t & lhs, const uint128_t & rhs){
  374. return uint128_t(lhs) >> rhs;
  375. }
  376. std::ostream & operator<<(std::ostream & stream, const uint128_t & rhs){
  377. if (stream.flags() & stream.oct){
  378. stream << rhs.str(8);
  379. }
  380. else if (stream.flags() & stream.dec){
  381. stream << rhs.str(10);
  382. }
  383. else if (stream.flags() & stream.hex){
  384. stream << rhs.str(16);
  385. }
  386. return stream;
  387. }