diff options
author | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-03-03 21:05:25 +0000 |
---|---|---|
committer | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-03-03 21:05:25 +0000 |
commit | a70cdc4d3ec2216293f59598fb45d823e6610b5a (patch) | |
tree | 26213461b0c6135daf4a67a7798733511e134c37 /ace/Basic_Types.i | |
parent | c04d6b9edfcbf35197bfa9c8d2b55fe3203a0feb (diff) | |
download | ATCD-a70cdc4d3ec2216293f59598fb45d823e6610b5a.tar.gz |
(ACE_U_LongLong::operator*=): updated with James' implementation
Diffstat (limited to 'ace/Basic_Types.i')
-rw-r--r-- | ace/Basic_Types.i | 88 |
1 files changed, 77 insertions, 11 deletions
diff --git a/ace/Basic_Types.i b/ace/Basic_Types.i index ab5d9d53695..eb88d6f72d9 100644 --- a/ace/Basic_Types.i +++ b/ace/Basic_Types.i @@ -177,21 +177,87 @@ ACE_U_LongLong::operator+= (const ACE_U_LongLong &n) return *this; } -ACE_INLINE ACE_U_LongLong & -ACE_U_LongLong::operator*= (const ACE_UINT32 n) +#define ACE_HIGHBIT (~(~0UL >> 1)) + +ACE_UINT32 +ACE_U_LongLong::ul_shift (ACE_UINT32 a, ACE_UINT32 c_in, ACE_UINT32 *c_out) { - // Save the current lo_. - const ACE_UINT32 lo = lo_; + const ACE_UINT32 b = (a << 1) | c_in; + *c_out = (*c_out << 1) + ((a & ACE_HIGHBIT) > 0); - lo_ = 0; - if (n == 0) - hi_ = 0; + return b; +} - // Repeatedly add in the lo_ value that was saved above. - for (ACE_UINT32 i = 0; i < n; ++i) - operator+= (lo); +ACE_U_LongLong +ACE_U_LongLong::ull_shift (ACE_U_LongLong a, ACE_UINT32 c_in, + ACE_UINT32 *c_out) +{ + ACE_U_LongLong b; - return *this; + b.lo_ = (a.lo_ << 1) | c_in; + c_in = ((a.lo_ & ACE_HIGHBIT) > 0); + b.hi_ = (a.hi_ << 1) | c_in; + *c_out = (*c_out << 1) + ((a.hi_ & ACE_HIGHBIT) > 0); + + return b; +} + +ACE_U_LongLong +ACE_U_LongLong::ull_add (ACE_U_LongLong a, ACE_U_LongLong b, ACE_UINT32 *carry) +{ + ACE_U_LongLong r (0, 0); + ACE_UINT32 c1, c2, c3, c4; + + c1 = a.lo_ % 2; + c2 = b.lo_ % 2; + c3 = 0; + + r.lo_ = a.lo_/2 + b.lo_/2 + (c1+c2)/2; + r.lo_ = ul_shift (r.lo_, (c1+c2)%2, &c3); + + c1 = a.hi_ % 2; + c2 = b.hi_ % 2; + c4 = 0; + + r.hi_ = a.hi_/2 + b.hi_/2 + (c1+c2+c3)/2; + r.hi_ = ul_shift (r.hi_, (c1+c2+c3)%2, &c4); + + *carry = c4; + + return r; +} + +ACE_U_LongLong +ACE_U_LongLong::ull_mult (ACE_U_LongLong a, ACE_UINT32 b, ACE_UINT32 *carry) +{ + register ACE_UINT32 mask = ACE_HIGHBIT; + const ACE_U_LongLong zero (0, 0); + ACE_U_LongLong accum (0, 0); + ACE_UINT32 c; + + *carry = 0; + if (b > 0) + do + { + accum = ull_shift (accum, 0U, carry); + if (b & mask) + accum = ull_add (accum, a, &c); + else + accum = ull_add (accum, zero, &c); + *carry += c; + mask >>= 1; + } + while (mask > 0); + + return accum; +} + +ACE_INLINE ACE_U_LongLong & +ACE_U_LongLong::operator*= (const ACE_UINT32 n) +{ + ACE_UINT32 carry; // will throw the carry away + + return *this = ull_mult (*this, n, &carry); } ACE_INLINE ACE_U_LongLong & |