summaryrefslogtreecommitdiff
path: root/ace/Basic_Types.i
diff options
context:
space:
mode:
authorlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-03-03 21:05:25 +0000
committerlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-03-03 21:05:25 +0000
commita70cdc4d3ec2216293f59598fb45d823e6610b5a (patch)
tree26213461b0c6135daf4a67a7798733511e134c37 /ace/Basic_Types.i
parentc04d6b9edfcbf35197bfa9c8d2b55fe3203a0feb (diff)
downloadATCD-a70cdc4d3ec2216293f59598fb45d823e6610b5a.tar.gz
(ACE_U_LongLong::operator*=): updated with James' implementation
Diffstat (limited to 'ace/Basic_Types.i')
-rw-r--r--ace/Basic_Types.i88
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 &