Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

qword.cc

Go to the documentation of this file.
00001 /*
00002  *      HT Editor
00003  *      qword.cc
00004  *
00005  *      Copyright (C) 1999-2002 Stefan Weyergraf (stefan@weyergraf.de)
00006  *      Copyright (C) 1999-2002 Sebastian Biallas (sb@web-productions.de)
00007  *
00008  *      This program is free software; you can redistribute it and/or modify
00009  *      it under the terms of the GNU General Public License version 2 as
00010  *      published by the Free Software Foundation.
00011  *
00012  *      This program is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU General Public License
00018  *      along with this program; if not, write to the Free Software
00019  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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         // FIXME: should ignore sign
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 /* operators */
00228 
00229 uint64 operator + (const uint64 &a, const uint64 &b)
00230 {
00231         return qword_add(a, b);
00232 }
00233 
00234 // prefix
00235 uint64& operator ++(uint64 &a)
00236 {
00237         return a += to_uint64(1);
00238 }
00239 
00240 // postfix
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 // prefix
00260 uint64& operator --(uint64 &a)
00261 {
00262         a -= to_uint64(1);
00263         return a;
00264 }
00265 
00266 // postfix
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         // FIXME: PLEASE FIX ME
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  *      signed int 64
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         // a.hi == b.hi => both numbers have the same sign
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         // FIXME: should care about sign
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 // prefix
00549 sint64& operator ++(sint64 &a)
00550 {
00551         return a += to_sint64(1);
00552 }
00553 
00554 // postfix
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 // prefix
00574 sint64& operator --(sint64 &a)
00575 {
00576         a -= to_sint64(1);
00577         return a;
00578 }
00579 
00580 // postfix
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         // FIXME: PLEASE FIX ME
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 

Generated on Fri May 7 21:15:42 2004 by doxygen 1.3.5