Date: Fri, 14 Jun 1996 10:30:22 +0200 (MET DST) From: Kees Jan Koster <dutchman@spase.nl> To: DARREND@novell.com (Darren Davis) Subject: Re: 64bit support? - Reply Message-ID: <199606140830.KAA00692@phobos.spase.nl> In-Reply-To: <s1bfed67.038@fromGW> from "Darren Davis" at Jun 13, 96 10:38:09 am
next in thread | previous in thread | raw e-mail | index | archive | help
> > Yes, I would be very interested in it. I actually came to the conclusion > that moving to C++ was probably my best approach and allready started writing > a quad class. It would be nice to see what you did. > Well. Eventually I found it back, I had to rip it from the production source. I'm sorry, but I made some last-minute changes that I could not test. Someone had copied the contents of the original quad.h into another file %-( Anyway, here it is. I am interested in any changes/fixes you may have. CAVEATS: - The multiplication code is flaky. I never needed it ;) - Now that I look at the code again, perhaps the passing of 'const quad' as 'const quad &'. Gee, I really learned some more c++ in the past year ;) - There are plenty of details to improve. Groetjes, Kees Jan (dutchman@spase.nl) ======- snip -=============================================== // // quad.h, by Kees Jan Koster. // Defines two 64-bit types, quad and u_quad. // #ifndef QUAD_H #define QUAD_H // // Definitions // #include <sys/types.h> #ifdef __GNUC__ typedef unsigned long long int u_quad; #else #ifndef __cplusplus #error Use c++ to compile classes quad and u_quad. #endif class quad { public: /* Construction... */ quad () {} quad (const long int low) { hi = (low < 0L ? -1L : 0L); lo = (u_long) low; } quad (const long int high, const u_long low) {hi = high; lo = low;} quad (const quad &q) {hi = q.hi; lo = q.lo;} /* Comparing... */ int operator == (const quad q) {return hi == q.hi && lo == q.lo;} int operator != (const quad q) {return hi != q.hi || lo != q.lo;} int operator > (const quad q) {return (hi == q.hi ? lo > q.lo : hi > q.hi);} int operator < (const quad q) {return (hi == q.hi ? lo < q.lo : hi < q.hi);} int operator >= (const quad q) {return (hi == q.hi ? lo >= q.lo : hi > q.hi);} int operator <= (const quad q) {return (hi == q.hi ? lo <= q.lo : hi < q.hi);} /* Logical operations... */ long int operator & (u_long mask) {return lo & mask;} quad operator & (const quad &mask) {return quad (hi & mask.hi, lo & mask.lo);} quad operator | (const quad &mask) {return quad (hi | mask.hi, lo | mask.lo);} quad operator ^ (const quad &mask) {return quad (hi ^ mask.hi, lo ^ mask.lo);} quad operator &= (const quad &mask) {return quad (hi &= mask.hi, lo &= mask.lo);} quad operator |= (const quad &mask) {return quad (hi |= mask.hi, lo |= mask.lo);} /* Unary operations... */ quad operator ~ (void) {return quad (~hi, ~lo);} quad operator ! (void) {return quad (0L, (hi || lo ? 0L : 1L));} quad operator + (void) {return *this;} quad operator - (void) { register u_long low = (~lo) + 1L; /* If the result (low) is zero, there was carry. */ return quad (~hi + (lo ? 0L : 1L), low); } /* Shifting... */ quad operator >> (const int shift) { return shift > 32 ? quad ((hi < 0L ? -1L : 0L), hi >> (shift - 32)) : quad (hi >> shift, (lo >> shift) | (hi << (32 - shift))); } quad operator << (const int shift) { return shift > 32 ? quad (lo << (shift - 32), 0L) : quad ((hi << shift) | (lo >> (32 - shift)), lo << shift); } /* Arithmetic operations... */ quad operator + (const quad q) { register u_long low = lo + q.lo; /* If the result (low) is smaller than lo (or q.lo), there was carry. */ return quad (hi + q.hi + (low < lo ? 1L : 0L), low); } quad operator - (const quad q) { register quad r = q; /* Hack to avoid q being variable... */ return (*this) + -r; /* C++ won't accept -q if q is constant */ } quad operator * (quad q) /* ** Note: This implementation only multiplies the lower long ints */ { register const long int a = lo & 0xffffL, b = (lo >> 16) & 0xffffL; register const long int c = q.lo & 0xffffL, d = (q.lo >> 16) & 0xffffL; register sign = 0; if (hi < 0) {sign = !sign; lo = -lo;} if (q.hi < 0) {sign = !sign; q.lo = -q.lo;} if (sign) return -(quad (0L, a*c) + (quad (0L, b*c) << 16) + (quad (0L, a*d) << 16) + quad (b*d, 0L)); else return quad (0L, a*c) + (quad (0L, b*c) << 16) + (quad (0L, a*d) << 16) + quad (b*d, 0L); } /* Other stuff... */ void print (FILE *file) { fprintf (file, "0x%08lx%08lx", hi, lo); } char* hex(char *s) { sprintf (s, "0x%08lx%08lx", hi, lo); return s; } private: long int hi; u_long lo; } class u_quad { public: /* Construction... */ u_quad (void) {hi=0L;lo=0L;} u_quad (const u_long low) {hi = 0L;lo = low;} u_quad (const u_long high, const u_long low) {hi = high; lo = low;} u_quad (const u_quad& q ) {hi = q.hi; lo = q.lo;} /* Comparing... */ int operator == (const u_quad q) {return hi == q.hi && lo == q.lo;} int operator != (const u_quad q) {return hi != q.hi || lo != q.lo;} int operator > (const u_quad q) {return (hi == q.hi ? lo > q.lo : hi > q.hi);} int operator < (const u_quad q) {return (hi == q.hi ? lo < q.lo : hi < q.hi);} int operator >= (const u_quad q) {return (hi == q.hi ? lo >= q.lo : hi > q.hi);} int operator <= (const u_quad q) {return (hi == q.hi ? lo <= q.lo : hi < q.hi);} /* Logical operations... */ long int operator & (u_long mask) {return lo & mask;} u_quad operator & (const u_quad &mask) {return u_quad (hi & mask.hi, lo & mask.lo);} u_quad operator | (const u_quad &mask) {return u_quad (hi | mask.hi, lo | mask.lo);} u_quad operator ^ (const u_quad &mask) {return u_quad (hi ^ mask.hi, lo ^ mask.lo);} u_quad& operator &= (const u_quad &mask) {hi &= mask.hi; lo &= mask.lo; return *this;} u_quad& operator |= (const u_quad &mask) {hi |= mask.hi; lo |= mask.lo; return *this;} /* Unary operations... */ u_quad operator ~ (void) {return u_quad (~hi, ~lo);} u_quad operator ! (void) {return u_quad (0L, (hi || lo ? 0L : 1L));} u_quad operator + (void) {return *this;} quad operator - (void) { register u_long low = (~lo) + 1L; /* If the result (low) is zero, there was carry. */ return quad (~hi + (lo ? 0L : 1L), low); } /* Shifting... */ u_quad operator >> (const int shift) { return (shift == 0) ? u_quad(hi,lo) : ( shift > 32 ? u_quad (0L, hi >> (shift - 32) ) : u_quad (hi >> shift, (lo >> shift) | (hi << (32 - shift))) ) ; } u_quad operator << (const int shift) { return (shift == 0) ? u_quad(hi,lo) : ( shift > 32 ? u_quad ((shift > 63 ? 0L : lo << (shift - 32)), 0L) : u_quad ((hi << shift) | (lo >> (32 - shift)), lo << shift) ); } /* Arithmetic operations... */ u_quad operator + (const u_quad q) { u_quad result; register u_long low = lo + q.lo; // If the result (low) is smaller than lo (or q.lo), there was carry. return u_quad (hi + q.hi + ((low < lo) || (low < q.lo)), low); } u_quad operator * (u_quad q); /* u_quad operator * (u_quad q) { // CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION // CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION // // SIGNED MULTIPLICATION !!! // // CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION // CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION // remeber sign int sign = !!((hi & 0x80000000L) ^ (q.hi & 0x80000000L)); u_long a_hi=hi,a_lo=lo; u_long b_hi=q.hi,b_lo=q.lo; // remove signs if (a_hi & 0x80000000L) { // negate //invert a_hi=~a_hi;a_lo=~a_lo; // add one if(a_lo==0xFFFFFFFFL) { a_hi=a_hi+1L;a_lo=0L; } else { a_lo++; } } if (b_hi & 0x80000000L) { // negate // invert b_hi=~b_hi;b_lo=~b_lo; // add one if(b_lo==0xFFFFFFFFL) { b_hi=b_hi+1L;b_lo=0L; } else { b_lo++; } } // multiply int i; u_long c_hi=0L,c_lo=0L; for(i=0;i<32;i++) { // addition if (a_lo & 1) { // c = c + b c_lo = c_lo + b_lo; c_hi = c_hi + b_hi + ((c_lo < b_lo) ? 1L : 0L); } // shift // a >> 1 a_lo >>= 1; a_lo |= ((a_hi & 1L)?(0x80000000L):0L); a_hi >>= 1; // b << 1 b_hi <<= 1; b_hi |= ((b_lo & 0x80000000L)?1L:0L); b_lo <<= 1; } // set sign if (sign) { // c = -c //invert c_hi=~c_hi;c_lo=~c_lo; // add one if(c_lo==0xFFFFFFFFL) { c_hi=c_hi+1L;c_lo=0L; } else { c_lo++; } } return u_quad(c_hi,c_lo); } */ /* Other stuff... */ void print (FILE *file) { fprintf (file, "0x%08lx%08lx", hi, lo); } char* hex(char *s) { sprintf (s, "0x%08lx%08lx", hi, lo); return s; } private: u_long hi; u_long lo; } #endif // __GNUC__ #endif // QUAD_H // // -eof-
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199606140830.KAA00692>