Skip to content

Commit

Permalink
Fix two's complement abs
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielKrawisz committed Dec 29, 2023
1 parent ad222e5 commit 6b90fd0
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 13 deletions.
3 changes: 2 additions & 1 deletion include/data/encoding/integer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,7 @@ namespace data::encoding::signed_decimal {

template <endian::order r>
std::ostream &write (std::ostream &w, const math::number::Z_bytes<r, complement::twos> &z) {
if (math::is_zero (z)) return w << "0";
if (math::is_negative (z)) w << "-";
return decimal::write (w, math::number::N_bytes<r>::read (data::abs (z)));
}
Expand Down Expand Up @@ -1370,7 +1371,7 @@ namespace data::math {
template <hex_case zz>
hex::int2<zz> inline abs<hex::int2<zz>>::operator () (const hex::int2<zz> &x) {
if (!x.valid ()) throw exception {} << "invalid hexidecimal string: " << x;
return math::number::sign_bit_set (x) ? -x : math::number::trim (x);
return math::is_negative (x) ? -x : x;
}

}
Expand Down
2 changes: 1 addition & 1 deletion include/data/math/number/bytes/Z.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ namespace data::math {
abs<number::Z_bytes<r, number::complement::twos>>::operator ()
(const number::Z_bytes<r, number::complement::twos> &x)
{
return number::arithmetic::trim<r, number::complement::twos, byte> (number::arithmetic::twos::abs<r, byte> (x));
return is_negative (x) ? -x : x;
}

template <endian::order r>
Expand Down
16 changes: 7 additions & 9 deletions test/testTwosComplement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,16 @@ namespace data::math::number {
} struct test_abs : virtual test_zero<Z> {
test_abs () {

// abs always converts to the minimal representation.
// abs will not change the number if it is not negative.
// otherwise, it will return the minimal representation.

auto zero0 = Z::zero (0, false);
auto abs_zero1neg = data::abs (Z::zero (1, true));

EXPECT_TRUE (identical (abs_zero1neg, zero0)) << "expected " << abs_zero1neg << " === " << zero0;
EXPECT_TRUE (identical (data::abs (Z::zero (2, true)), zero0));
EXPECT_TRUE (identical (data::abs (Z::zero (3, true)), zero0));
EXPECT_TRUE (identical (data::abs (Z::zero (1, true)), Z::zero (1, true)));
EXPECT_TRUE (identical (data::abs (Z::zero (2, true)), Z::zero (2, true)));
EXPECT_TRUE (identical (data::abs (Z::zero (3, true)), Z::zero (3, true)));

EXPECT_TRUE (identical (data::abs (Z::read ("0x01")), Z::read ("0x01")));
EXPECT_TRUE (identical (data::abs (Z::read ("0x0001")), Z::read ("0x01")));
EXPECT_TRUE (identical (data::abs (Z::read ("0x000001")), Z::read ("0x01")));
EXPECT_TRUE (identical (data::abs (Z::read ("0x0001")), Z::read ("0x0001")));
EXPECT_TRUE (identical (data::abs (Z::read ("0x000001")), Z::read ("0x000001")));

EXPECT_TRUE (data::identical (data::abs (Z::read ("0x81")), -Z::read ("0x81")));
EXPECT_TRUE (data::identical (data::abs (Z::read ("0x8001")), -Z::read ("0x81")));
Expand Down
4 changes: 2 additions & 2 deletions test/testZBytes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ namespace data {

auto write_zb = encoding::signed_decimal::write (zb);
auto write_zl = encoding::signed_decimal::write (zl);
EXPECT_EQ (write_zb, "0") << "expected " << std::hex << zb << " to write as " << write_zb;
EXPECT_EQ (write_zl, "0") << "expected " << std::hex << zl << " to write as " << write_zl;
EXPECT_EQ (write_zb, "0") << "expected " << std::hex << zb << " to write as 0 but got " << write_zb;
EXPECT_EQ (write_zl, "0") << "expected " << std::hex << zl << " to write as 0 but got " << write_zl;
}
}

Expand Down

0 comments on commit 6b90fd0

Please sign in to comment.