Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ boost rational class, floor function

Tags:

c++

boost

floor

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

like image 999
ppyvabw Avatar asked Sep 17 '25 16:09

ppyvabw


1 Answers

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());
    }
}

Live Demo

Live On Coliru

#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.

like image 54
sehe Avatar answered Sep 19 '25 06:09

sehe