From fbf648c9a4c751fc3041c14983ff55c3254a5c56 Mon Sep 17 00:00:00 2001 From: Giovanni Mascellani Date: Wed, 8 Apr 2020 09:00:33 +0200 Subject: [PATCH] Implement floor() and ceil() for rational types. --- .../boost/multiprecision/rational_adaptor.hpp | 20 +++++++++++++++++++ test/test_arithmetic.hpp | 11 ++++++++++ 2 files changed, 31 insertions(+) diff --git a/include/boost/multiprecision/rational_adaptor.hpp b/include/boost/multiprecision/rational_adaptor.hpp index 2d839bb1c..dc2e29124 100644 --- a/include/boost/multiprecision/rational_adaptor.hpp +++ b/include/boost/multiprecision/rational_adaptor.hpp @@ -318,6 +318,26 @@ inline number denominator(const number +inline number floor(const number, ET>& val) +{ + // Here we use the assumption that denominator is always positive + // and numerator has the sign + if (val >= 0) + return numerator(val) / denominator(val); + else + return (numerator(val) + 1) / denominator(val) - 1; +} +template +inline number ceil(const number, ET>& val) +{ + // Here we use the assumption that denominator is always positive + // and numerator has the sign + if (val >= 0) + return (numerator(val) - 1) / denominator(val) + 1; + else + return numerator(val) / denominator(val); +} #ifdef BOOST_NO_SFINAE_EXPR diff --git a/test/test_arithmetic.hpp b/test/test_arithmetic.hpp index 301a6b5b1..c1e52fc43 100644 --- a/test/test_arithmetic.hpp +++ b/test/test_arithmetic.hpp @@ -293,6 +293,17 @@ void test_rational(const boost::mpl::false_&) #endif b = Real("2/3"); BOOST_CHECK_EQUAL(a, b); + + const static int floor_ceil_data[][4] = {{-11, 10, -2, -1}, {-10, 10, -1, -1}, {-9, 10, -1, 0}, + {-1, 10, -1, 0}, {0, 10, 0, 0}, {1, 10, 0, 1}, + {9, 10, 0, 1}, {10, 10, 1, 1}, {11, 10, 1, 2}}; + for (unsigned int i = 0; i < sizeof(floor_ceil_data) / sizeof(floor_ceil_data[0]); i++) { + Real c(floor_ceil_data[i][0]); + c /= floor_ceil_data[i][1]; + BOOST_CHECK_EQUAL(floor(c), floor_ceil_data[i][2]); + BOOST_CHECK_EQUAL(ceil(c), floor_ceil_data[i][3]); + } + // // Check IO code: //