From e6dae78c033ea970a459b1a0ccc2f1310d1bff96 Mon Sep 17 00:00:00 2001 From: Max Nikulin Date: Mon, 8 Jul 2024 17:17:30 +0700 Subject: Fix denominator of roundto result Multiprecision rational created from a double value may have large power of 2 denominator since fractional decimal numbers can not be represented as binary floating point numbers. It leads to failed assertion when result is compared to a value converted directly from strings. Use integer multiprecision arithmetics to round numbers to ensure proper denominator. Inspired by python gmpy2 package The change makes `roundto` symmetric for positive/negative arguments. Halves are rounded to nearest even. Rounded away from zero are discussed in #1663 and it may be achieved with minimal modification. - See #2329 - Closes #1983 --- test/unit/t_balance.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'test/unit/t_balance.cc') diff --git a/test/unit/t_balance.cc b/test/unit/t_balance.cc index b503d02a..066f066e 100644 --- a/test/unit/t_balance.cc +++ b/test/unit/t_balance.cc @@ -451,6 +451,9 @@ BOOST_AUTO_TEST_CASE(testRound) b2 += a5; b2 += a6; + // + // This block modifies b1 and b2, likely it is a bug, + // but otherwise some assertions fails. a1.in_place_roundto(2); a2.in_place_roundto(2); a3.in_place_roundto(2); @@ -465,11 +468,18 @@ BOOST_AUTO_TEST_CASE(testRound) b4 += a5; b4 += a6; + // After fix of #2362 rounded() and in_place_round() + // likely should be replaced with roundto(2) and + // in_place_roundto(2). + // It looks like rounded() and in_place_round() + // need some other tests, perhaps with unround(). BOOST_CHECK_EQUAL(b0.rounded(), b0); BOOST_CHECK_EQUAL(b2.rounded(), b4); + // Relies on b1 modified by amount_t::in_place_roundto(int). BOOST_CHECK_EQUAL(b1.rounded(), b4); b1.in_place_round(); + // Relies on b1 modified by amount_t::in_place_roundto(int). BOOST_CHECK_EQUAL(b1, b3); BOOST_CHECK(b0.valid()); -- cgit v1.2.3