00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "qword.h"
00023
00024 uint64 int_to_qword(int i)
00025 {
00026 uint64 res;
00027 res.lo = i;
00028 res.hi = 0;
00029 return res;
00030 }
00031
00032 sint64 int_to_sint64(int i)
00033 {
00034 sint64 res;
00035 res.lo = i;
00036 res.hi = (i<0) ? ((dword)-1) : 0;
00037 return res;
00038 }
00039
00040 uint64 sint64_to_uint64(sint64 s)
00041 {
00042 uint64 res;
00043 res.lo = s.lo;
00044 res.hi = s.hi;
00045 return res;
00046 }
00047
00048 sint64 uint64_to_sint64(uint64 u)
00049 {
00050 sint64 res;
00051 res.lo = u.lo;
00052 res.hi = u.hi;
00053 return res;
00054 }
00055
00056 sint64 to_sint64(int i)
00057 {
00058 sint64 res;
00059 res.lo = i;
00060 res.hi = (i<0) ? ((dword)-1) : 0;
00061 return res;
00062 }
00063
00064 uint64 to_uint64(UINT i)
00065 {
00066 uint64 res;
00067 res.lo = i;
00068 res.hi = 0;
00069 return res;
00070 }
00071
00072 sint64 to_sint64(const uint64 &u)
00073 {
00074 sint64 res;
00075 res.lo = u.lo;
00076 res.hi = u.hi;
00077 return res;
00078 }
00079
00080 uint64 to_uint64(const sint64 &s)
00081 {
00082 uint64 res;
00083 res.lo = s.lo;
00084 res.hi = s.hi;
00085 return res;
00086 }
00087
00088 int qword_cmp(uint64 a, uint64 b)
00089 {
00090 if (a.hi > b.hi) return 1;
00091 if (a.hi < b.hi) return -1;
00092 if (a.lo > b.lo) return 1;
00093 if (a.lo < b.lo) return -1;
00094 return 0;
00095 }
00096
00097 uint64 qword_add(uint64 a, uint64 b)
00098 {
00099 uint64 res;
00100 res.lo = a.lo + b.lo;
00101 res.hi = a.hi + b.hi;
00102 if (a.lo + b.lo < a.lo) res.hi++;
00103 return res;
00104 }
00105
00106 uint64 qword_sub(uint64 a, uint64 b)
00107 {
00108 uint64 res;
00109 res.lo = a.lo - b.lo;
00110 res.hi = a.hi - b.hi;
00111 if (b.lo > a.lo) res.hi--;
00112 return res;
00113 }
00114
00115 static uint64 uint64_and(const uint64 &a, const uint64 &b)
00116 {
00117 uint64 res;
00118 res.lo = a.lo & b.lo;
00119 res.hi = a.hi & b.hi;
00120 return res;
00121 }
00122
00123 static uint64 uint64_or(const uint64 &a, const uint64 &b)
00124 {
00125 uint64 res;
00126 res.lo = a.lo | b.lo;
00127 res.hi = a.hi | b.hi;
00128 return res;
00129 }
00130
00131 static uint64 uint64_xor(const uint64 &a, const uint64 &b)
00132 {
00133 uint64 res;
00134 res.lo = a.lo ^ b.lo;
00135 res.hi = a.hi ^ b.hi;
00136 return res;
00137 }
00138
00139 static uint64 uint64_shl(const uint64 &A, int b)
00140 {
00141 uint64 res;
00142 uint64 a = A;
00143 if (b >= 32) {
00144 if (b < 64) {
00145 a.hi = a.lo;
00146 a.lo = 0;
00147 b -= 32;
00148 } else {
00149 res.lo = res.hi = 0;
00150 return res;
00151 }
00152 }
00153 res.hi = a.hi << b;
00154 res.hi |= a.lo >> (32-b);
00155 res.lo = a.lo << b;
00156 return res;
00157 }
00158
00159 static uint64 uint64_shr(const uint64 &A, int b)
00160 {
00161 uint64 res;
00162 uint64 a = A;
00163 if (b >= 32) {
00164 if (b < 64) {
00165 a.lo = a.hi;
00166 a.hi = 0;
00167 b -= 32;
00168 } else {
00169 res.lo = res.hi = 0;
00170 return res;
00171 }
00172 }
00173 res.hi = a.hi >> b;
00174 res.lo = a.lo >> b;
00175 res.lo |= a.hi << (32-b);
00176 return res;
00177 }
00178
00179 uint64 qword_mul(uint64 a, uint64 b)
00180 {
00181 uint64 x = a, y = b, z = to_uint64(0);
00182 while (y != to_uint64(0)) {
00183 if (y.lo & 1) z += x;
00184 x = uint64_shl(x, 1);
00185 y = uint64_shr(y, 1);
00186 }
00187 return z;
00188 }
00189
00190 static uint64 uint64_div(const uint64 &a, const uint64 &b)
00191 {
00192
00193 uint64 null = to_uint64(0);
00194 uint64 x = a, y = b, q = null, t = to_uint64(1);
00195 bool ycarry = false;
00196 bool carry = false;
00197 while ((y < x) && (!ycarry)) {
00198 uint64 ynew = uint64_shl(y, 1);
00199 if (ynew < y) ycarry = true;
00200 y = ynew;
00201 t = uint64_shl(t, 1);
00202 }
00203 if (t == null) carry = true;
00204 while ((t != null) || carry) {
00205 if ((x >= y) && !ycarry) {
00206 x = x - y;
00207 q = q + t;
00208 }
00209 if (ycarry) {
00210 y = uint64_shr(y, 1);
00211 y.hi |= 0x80000000;
00212 ycarry = false;
00213 } else {
00214 y = uint64_shr(y, 1);
00215 }
00216 if (carry) {
00217 t.lo = 0;
00218 t.hi = 0x80000000;
00219 carry = false;
00220 } else {
00221 t = uint64_shr(t, 1);
00222 }
00223 }
00224 return q;
00225 }
00226
00227
00228
00229 uint64 operator + (const uint64 &a, const uint64 &b)
00230 {
00231 return qword_add(a, b);
00232 }
00233
00234
00235 uint64& operator ++(uint64 &a)
00236 {
00237 return a += to_uint64(1);
00238 }
00239
00240
00241 uint64 operator ++(uint64 &a, int b)
00242 {
00243 uint64 t = a;
00244 ++a;
00245 return t;
00246 }
00247
00248 uint64& operator += (uint64 &a, const uint64 &b)
00249 {
00250 a = a + b;
00251 return a;
00252 }
00253
00254 uint64 operator - (const uint64 &a, const uint64 &b)
00255 {
00256 return qword_sub(a, b);
00257 }
00258
00259
00260 uint64& operator --(uint64 &a)
00261 {
00262 a -= to_uint64(1);
00263 return a;
00264 }
00265
00266
00267 uint64 operator --(uint64 &a, int b)
00268 {
00269 uint64 t = a;
00270 --a;
00271 return t;
00272 }
00273
00274 uint64& operator -= (uint64 &a, const uint64 &b)
00275 {
00276 a = a - b;
00277 return a;
00278 }
00279
00280 uint64 operator *(const uint64 &a, const uint64 &b)
00281 {
00282 return qword_mul(a, b);
00283 }
00284
00285 uint64& operator *= (uint64 &a, const uint64 &b)
00286 {
00287 a = a * b;
00288 return a;
00289 }
00290
00291 uint64 operator /(const uint64 &a, const uint64 &b)
00292 {
00293 return uint64_div(a, b);
00294 }
00295
00296 uint64& operator /= (uint64 &a, const uint64 &b)
00297 {
00298 a = a / b;
00299 return a;
00300 }
00301
00302 uint64 operator %(const uint64 &a, const uint64 &b)
00303 {
00304
00305 uint64 d = a / b;
00306 uint64 db = d * b;
00307 uint64 adb = a-db;
00308 return adb;
00309 }
00310
00311 uint64& operator %= (uint64 &a, const uint64 &b)
00312 {
00313 a = a % b;
00314 return a;
00315 }
00316
00317 uint64 operator &(const uint64 &a, const uint64 &b)
00318 {
00319 return uint64_and(a, b);
00320 }
00321
00322 uint64& operator &= (uint64 &a, uint64 b)
00323 {
00324 a = a & b;
00325 return a;
00326 }
00327
00328 uint64 operator |(const uint64 &a, const uint64 &b)
00329 {
00330 return uint64_or(a, b);
00331 }
00332
00333 uint64& operator |= (uint64 &a, const uint64 &b)
00334 {
00335 a = a | b;
00336 return a;
00337 }
00338
00339 uint64 operator ^(const uint64 &a, const uint64 &b)
00340 {
00341 return uint64_xor(a, b);
00342 }
00343
00344 uint64& operator ^= (uint64 &a, const uint64 &b)
00345 {
00346 a = a ^ b;
00347 return a;
00348 }
00349
00350 uint64 operator >> (const uint64 &a, byte b)
00351 {
00352 return uint64_shr(a, b);
00353 }
00354
00355 uint64& operator >>= (uint64 &a, byte b)
00356 {
00357 return ((a = a >> b));
00358 }
00359
00360 uint64 operator << (const uint64 &a, byte b)
00361 {
00362 return uint64_shl(a, b);
00363 }
00364
00365 uint64& operator <<= (uint64 &a, byte b)
00366 {
00367 return ((a = a << b));
00368 }
00369
00370 uint64 operator ~(const uint64 &a)
00371 {
00372 uint64 r;
00373 r.lo = ~a.lo;
00374 r.hi = ~a.hi;
00375 return r;
00376 }
00377
00378 uint64 operator -(const uint64 &a)
00379 {
00380 uint64 r = a;
00381 r.lo = ~r.lo;
00382 r.hi = ~r.hi;
00383 return r+to_uint64(1);
00384 }
00385
00386 bool operator < (const uint64 &a, const uint64 &b) { return qword_cmp(a, b) < 0; }
00387
00388 bool operator <= (const uint64 &a, const uint64 &b) { return qword_cmp(a, b) <= 0; }
00389
00390 bool operator > (const uint64 &a, const uint64 &b) { return qword_cmp(a, b) > 0; }
00391
00392 bool operator >= (const uint64 &a, const uint64 &b) { return qword_cmp(a, b) >= 0; }
00393
00394 bool operator == (const uint64 &a, const uint64 &b) { return qword_cmp(a, b) == 0; }
00395
00396 bool operator != (const uint64 &a, const uint64 &b) { return qword_cmp(a, b) != 0; }
00397
00398 bool operator !(const uint64 &a) { return qword_cmp(a, to_uint64(0)) == 0; }
00399
00400
00401
00402
00403
00404 int sint64_cmp(sint64 a, sint64 b)
00405 {
00406 if ((int)a.hi > (int)b.hi) return 1;
00407 if ((int)a.hi < (int)b.hi) return -1;
00408
00409 if (a.lo > b.lo) return 1;
00410 if (a.lo < b.lo) return -1;
00411 return 0;
00412 }
00413
00414 sint64 sint64_add(sint64 a, sint64 b)
00415 {
00416 sint64 res;
00417 res.lo = a.lo + b.lo;
00418 res.hi = a.hi + b.hi;
00419 if (a.lo + b.lo < a.lo) res.hi++;
00420 return res;
00421 }
00422
00423 sint64 sint64_sub(sint64 a, sint64 b)
00424 {
00425 sint64 res;
00426 res.lo = a.lo - b.lo;
00427 res.hi = a.hi - b.hi;
00428 if (b.lo > a.lo) res.hi--;
00429 return res;
00430 }
00431
00432 static sint64 sint64_and(const sint64 &a, const sint64 &b)
00433 {
00434 sint64 res;
00435 res.lo = a.lo & b.lo;
00436 res.hi = a.hi & b.hi;
00437 return res;
00438 }
00439
00440 static sint64 sint64_or(const sint64 &a, const sint64 &b)
00441 {
00442 sint64 res;
00443 res.lo = a.lo | b.lo;
00444 res.hi = a.hi | b.hi;
00445 return res;
00446 }
00447
00448 static sint64 sint64_xor(const sint64 &a, const sint64 &b)
00449 {
00450 sint64 res;
00451 res.lo = a.lo ^ b.lo;
00452 res.hi = a.hi ^ b.hi;
00453 return res;
00454 }
00455
00456 static sint64 sint64_shl(const sint64 &A, int b)
00457 {
00458 sint64 res;
00459 sint64 a = A;
00460 if (b > 32) {
00461 if (b < 64) {
00462 a.hi = a.lo;
00463 a.lo = 0;
00464 b -= 32;
00465 } else {
00466 res.lo = res.hi = 0;
00467 return res;
00468 }
00469 }
00470 res.hi = a.hi << b;
00471 res.lo = a.lo << b;
00472 res.hi |= a.lo >> (32-b);
00473 return res;
00474 }
00475
00476 static sint64 sint64_shr(const sint64 &A, int b)
00477 {
00478
00479 sint64 res;
00480 sint64 a = A;
00481 if (b > 32) {
00482 if (b < 64) {
00483 a.lo = a.hi;
00484 a.hi = 0;
00485 b -= 32;
00486 } else {
00487 res.lo = res.hi = 0;
00488 return res;
00489 }
00490 }
00491 res.hi = a.hi >> b;
00492 res.lo = a.lo >> b;
00493 res.lo |= a.hi << (32-b);
00494 return res;
00495 }
00496
00497 sint64 sint64_mul(sint64 a, sint64 b)
00498 {
00499 sint64 x = a, y = b, z = to_sint64(0);
00500 while (y != to_sint64(0)) {
00501 if (y.lo & 1) z += x;
00502 x = sint64_shl(x, 1);
00503 y = sint64_shr(y, 1);
00504 }
00505 return z;
00506 }
00507
00508 static sint64 sint64_div(const sint64 &a, const sint64 &b)
00509 {
00510 sint64 null = to_sint64(0);
00511 sint64 x = a, y = b, q = null, t = to_sint64(1);
00512 bool ycarry = false;
00513 bool carry = false;
00514 while ((y < x) && (!ycarry)) {
00515 sint64 ynew = sint64_shl(y, 1);
00516 if (ynew < y) ycarry = true;
00517 y = ynew;
00518 t = sint64_shl(t, 1);
00519 }
00520 if (t == null) carry = true;
00521 while ((t != null) || carry) {
00522 if ((x >= y) && !ycarry) {
00523 x = x - y;
00524 q = q + t;
00525 }
00526 if (ycarry) {
00527 y = sint64_shr(y, 1);
00528 y.hi |= 0x80000000;
00529 ycarry = false;
00530 } else {
00531 y = sint64_shr(y, 1);
00532 }
00533 if (carry) {
00534 t.lo = 0;
00535 t.hi = 0x80000000;
00536 carry = false;
00537 } else {
00538 t = sint64_shr(t, 1);
00539 }
00540 }
00541 return q;
00542 }
00543 sint64 operator + (const sint64 &a, const sint64 &b)
00544 {
00545 return sint64_add(a, b);
00546 }
00547
00548
00549 sint64& operator ++(sint64 &a)
00550 {
00551 return a += to_sint64(1);
00552 }
00553
00554
00555 sint64 operator ++(sint64 &a, int b)
00556 {
00557 sint64 t = a;
00558 ++a;
00559 return t;
00560 }
00561
00562 sint64& operator += (sint64 &a, const sint64 &b)
00563 {
00564 a = a + b;
00565 return a;
00566 }
00567
00568 sint64 operator - (const sint64 &a, const sint64 &b)
00569 {
00570 return sint64_sub(a, b);
00571 }
00572
00573
00574 sint64& operator --(sint64 &a)
00575 {
00576 a -= to_sint64(1);
00577 return a;
00578 }
00579
00580
00581 sint64 operator --(sint64 &a, int b)
00582 {
00583 sint64 t = a;
00584 --a;
00585 return t;
00586 }
00587
00588 sint64& operator -= (sint64 &a, const sint64 &b)
00589 {
00590 a = a - b;
00591 return a;
00592 }
00593
00594 sint64 operator *(const sint64 &a, const sint64 &b)
00595 {
00596 return sint64_mul(a, b);
00597 }
00598
00599 sint64& operator *= (sint64 &a, const sint64 &b)
00600 {
00601 a = a * b;
00602 return a;
00603 }
00604
00605 sint64 operator /(const sint64 &a, const sint64 &b)
00606 {
00607 return sint64_div(a, b);
00608 }
00609
00610 sint64& operator /= (sint64 &a, const sint64 &b)
00611 {
00612 a = a / b;
00613 return a;
00614 }
00615
00616 sint64 operator %(const sint64 &a, const sint64 &b)
00617 {
00618
00619 sint64 d = a / b;
00620 sint64 db = d * b;
00621 sint64 adb = a-db;
00622 return adb;
00623 }
00624
00625 sint64& operator %= (sint64 &a, const sint64 &b)
00626 {
00627 a = a % b;
00628 return a;
00629 }
00630
00631 sint64 operator &(const sint64 &a, const sint64 &b)
00632 {
00633 return sint64_and(a, b);
00634 }
00635
00636 sint64& operator &= (sint64 &a, sint64 b)
00637 {
00638 a = a & b;
00639 return a;
00640 }
00641
00642 sint64 operator |(const sint64 &a, const sint64 &b)
00643 {
00644 return sint64_or(a, b);
00645 }
00646
00647 sint64& operator |= (sint64 &a, const sint64 &b)
00648 {
00649 a = a | b;
00650 return a;
00651 }
00652
00653 sint64 operator ^(const sint64 &a, const sint64 &b)
00654 {
00655 return sint64_xor(a, b);
00656 }
00657
00658 sint64& operator ^= (sint64 &a, const sint64 &b)
00659 {
00660 a = a ^ b;
00661 return a;
00662 }
00663
00664 sint64 operator >> (const sint64 &a, byte b)
00665 {
00666 return sint64_shr(a, b);
00667 }
00668
00669 sint64& operator >>= (sint64 &a, byte b)
00670 {
00671 return ((a = a >> b));
00672 }
00673
00674 sint64 operator << (const sint64 &a, byte b)
00675 {
00676 return sint64_shl(a, b);
00677 }
00678
00679 sint64& operator <<= (sint64 &a, byte b)
00680 {
00681 return ((a = a << b));
00682 }
00683
00684 sint64 operator ~(const sint64 &a)
00685 {
00686 sint64 r;
00687 r.lo = ~a.lo;
00688 r.hi = ~a.hi;
00689 return r;
00690 }
00691
00692 sint64 operator -(const sint64 &a)
00693 {
00694 sint64 r = a;
00695 r.lo = ~r.lo;
00696 r.hi = ~r.hi;
00697 return r+to_sint64(1);
00698 }
00699
00700 bool operator < (const sint64 &a, const sint64 &b) { return sint64_cmp(a, b) < 0; }
00701
00702 bool operator <= (const sint64 &a, const sint64 &b) { return sint64_cmp(a, b) <= 0; }
00703
00704 bool operator > (const sint64 &a, const sint64 &b) { return sint64_cmp(a, b) > 0; }
00705
00706 bool operator >= (const sint64 &a, const sint64 &b) { return sint64_cmp(a, b) >= 0; }
00707
00708 bool operator == (const sint64 &a, const sint64 &b) { return sint64_cmp(a, b) == 0; }
00709
00710 bool operator != (const sint64 &a, const sint64 &b) { return sint64_cmp(a, b) != 0; }
00711
00712 bool operator !(const sint64 &a) { return sint64_cmp(a, to_sint64(0)) == 0; }
00713