I'm new to using boost.
Besides simply doing x.numerator()/x.denominator, is there a proper 'boost-type' way of invoking the floor(x) function (i.e. truncation towards zero) when using the boost rational library?
Thanks
There isn't. I've looked closely at it, and the only function that even deals with conversion to a continued-fraction representation starts of with the exact same operation (formatted for legibility):
struct {
Rat::int_type n, d, q, r;
} ts = {
l.numerator(), l.denominator(),
static_cast<Rat::int_type>(l.numerator() / l.denominator()), static_cast<Rat::int_type>(l.numerator() % l.denominator())
},
rs = {
r.numerator(), r.denominator(),
static_cast<Rat::int_type>(r.numerator() / r.denominator()), static_cast<Rat::int_type>(r.numerator() % r.denominator())
};
While this might slightly disappoint you, it does validate your approach, which is good.
If you want you can provide your own floor
overload to be found via ADL ¹
Here's my generalist suggestion, assuming you're injecting it into namespace boost
:
namespace boost {
template <typename IntType>
constexpr IntType floor(rational<IntType> const& r) {
return static_cast<IntType>(r.numerator() / r.denominator());
}
}
#include <boost/rational.hpp>
namespace boost {
template <typename IntType>
constexpr IntType floor(rational<IntType> const& r) {
return static_cast<IntType>(r.numerator() / r.denominator());
}
}
#include <iostream>
template <typename IntType> void test()
{
boost::rational<IntType> a(230,7), b(222*111111,-777777);
std::cout << "a: " << a << " -> " << floor(a) << "\n";
std::cout << "b: " << b << " -> " << floor(b) << "\n";
}
#include <boost/multiprecision/cpp_int.hpp>
int main() {
test<int>();
test<boost::multiprecision::cpp_int>();
}
Prints
a: 230/7 -> 32
b: -222/7 -> -31
a: 230/7 -> 32
b: -222/7 -> -31
¹ declare it in the namespace declaring your integer type, or inside namespace ::boost
in order to let it kick in.