summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ACE/ace/CDR_Base.cpp47
-rw-r--r--ACE/tests/CDR_Fixed_Test.cpp3
2 files changed, 31 insertions, 19 deletions
diff --git a/ACE/ace/CDR_Base.cpp b/ACE/ace/CDR_Base.cpp
index daca058f704..92702361a7a 100644
--- a/ACE/ace/CDR_Base.cpp
+++ b/ACE/ace/CDR_Base.cpp
@@ -917,19 +917,36 @@ void ACE_CDR::Fixed::normalize (UShort min_scale)
if (this->value_[15] & 0xf0 || !this->scale_)
return;
- // Calculate the number of nibbles that can be moved.
- size_t nibbles = 0;
- while (digit(nibbles) == 0 && this->scale_ - nibbles > min_scale)
- ++nibbles;
-
- // Move and clear the nibbles.
- for (size_t idx = nibbles; idx != this->digits_; ++idx) {
- digit (idx - nibbles, digit (idx));
- digit (idx, 0);
- }
-
- this->scale_ -= nibbles;
- this->digits_ -= nibbles;
+ size_t bytes = 0; // number of bytes to shift down
+ while (2 * (bytes + 1) < this->scale_
+ && this->scale_ - 2 * (bytes + 1) >= min_scale
+ && !this->value_[14 - bytes])
+ ++bytes;
+
+ const bool extra_nibble = 2 * (bytes + 1) <= this->scale_
+ && this->scale_ - 2 * (bytes + 1) >= min_scale
+ && !(this->value_[14 - bytes] & 0xf);
+ const size_t nibbles = 1 /*[15].high*/ + bytes * 2 + extra_nibble;
+ this->digits_ -= static_cast<Octet> (nibbles);
+ this->scale_ -= static_cast<Octet> (nibbles);
+
+ if (extra_nibble)
+ {
+ const bool sign = this->sign ();
+ std::memmove (this->value_ + bytes + 1, this->value_, 15 - bytes);
+ std::memset (this->value_, 0, bytes + 1);
+ this->value_[15] |= sign ? NEGATIVE : POSITIVE;
+ }
+ else
+ {
+ this->value_[15] = (this->value_[14 - bytes] & 0xf) << 4
+ | (this->value_[15] & 0xf);
+ for (size_t i = 14; i > bytes; --i)
+ this->value_[i] = (this->value_[i - bytes - 1] & 0xf) << 4
+ | (this->value_[i - bytes] >> 4);
+ this->value_[bytes] = this->value_[0] >> 4;
+ std::memset (this->value_, 0, bytes);
+ }
}
ACE_CDR::Fixed ACE_CDR::Fixed::from_string (const char *str)
@@ -1377,8 +1394,7 @@ ACE_CDR::Fixed &ACE_CDR::Fixed::operator/= (const Fixed &rhs)
if (neg)
this->value_[15] = (this->value_[15] & 0xf0) | POSITIVE;
- Fixed r;
- Fixed q = this->div_helper2 (rhs_no_scale, r);
+ Fixed r, q = this->div_helper2 (rhs_no_scale, r);
if (!r)
return *this = neg ? -q : q;;
@@ -1445,7 +1461,6 @@ ACE_CDR::Fixed ACE_CDR::Fixed::div_helper1 (const Fixed &rhs, Fixed &r) const
if (q > 9)
q = 9;
Fixed t = from_integer (LongLong (q)) * rhs;
- t.scale_ = this->scale_;
for (int i = 0; i < 2 && t > *this; ++i)
{
--q;
diff --git a/ACE/tests/CDR_Fixed_Test.cpp b/ACE/tests/CDR_Fixed_Test.cpp
index f9611bbf529..83c175a2f46 100644
--- a/ACE/tests/CDR_Fixed_Test.cpp
+++ b/ACE/tests/CDR_Fixed_Test.cpp
@@ -224,9 +224,6 @@ int run_main (int, ACE_TCHAR *[])
Fixed f29 = Fixed::from_integer (LongLong (1)) / Fixed::from_integer (LongLong (-3));
EXPECT ("-0.333333333333333333333333333333", f29); //TODO: one more 3
- Fixed f30 = Fixed::from_string("-9999752.0000") / Fixed::from_string("-4999876.00");
- EXPECT ("2", f30);
-
ACE_END_TEST;
return failed;
}