diff options
author | Phil Mesnier <mesnier_p@ociweb.com> | 2015-06-24 09:18:27 -0500 |
---|---|---|
committer | Phil Mesnier <mesnier_p@ociweb.com> | 2015-06-24 09:18:27 -0500 |
commit | fba94d061ecdf31bf853f1c7a52bba7f54429e25 (patch) | |
tree | f98a7dce7d23b9a2cb7f45e53bab61b9fb1652d3 | |
parent | b589dc30458fa73e2ab757cb1413702bbdaa98eb (diff) | |
parent | ceb825a446f74288f4bdb66170aaba8e096996f5 (diff) | |
download | ATCD-fba94d061ecdf31bf853f1c7a52bba7f54429e25.tar.gz |
Merge pull request #96 from jrw972/master
Rewrote normalize to fix off-by-one error. Fixed bug in division and added test.
This only impacts the new Fixed type.
-rw-r--r-- | ACE/ace/CDR_Base.cpp | 47 | ||||
-rw-r--r-- | ACE/tests/CDR_Fixed_Test.cpp | 3 |
2 files changed, 19 insertions, 31 deletions
diff --git a/ACE/ace/CDR_Base.cpp b/ACE/ace/CDR_Base.cpp index 92702361a7a..daca058f704 100644 --- a/ACE/ace/CDR_Base.cpp +++ b/ACE/ace/CDR_Base.cpp @@ -917,36 +917,19 @@ void ACE_CDR::Fixed::normalize (UShort min_scale) if (this->value_[15] & 0xf0 || !this->scale_) return; - 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); - } + // 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; } ACE_CDR::Fixed ACE_CDR::Fixed::from_string (const char *str) @@ -1394,7 +1377,8 @@ ACE_CDR::Fixed &ACE_CDR::Fixed::operator/= (const Fixed &rhs) if (neg) this->value_[15] = (this->value_[15] & 0xf0) | POSITIVE; - Fixed r, q = this->div_helper2 (rhs_no_scale, r); + Fixed r; + Fixed q = this->div_helper2 (rhs_no_scale, r); if (!r) return *this = neg ? -q : q;; @@ -1461,6 +1445,7 @@ 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 83c175a2f46..f9611bbf529 100644 --- a/ACE/tests/CDR_Fixed_Test.cpp +++ b/ACE/tests/CDR_Fixed_Test.cpp @@ -224,6 +224,9 @@ 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; } |