Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

gmp_rational
PrevUpHomeNext

#include <boost/multiprecision/gmp.hpp>

namespace boost{ namespace multiprecision{

class gmp_rational;

typedef number<gmp_rational >         mpq_rational;

}} // namespaces

The gmp_rational back-end is used via the typedef boost::multiprecision::mpq_rational. It acts as a thin wrapper around the GMP mpq_t to provide a rational number type that is a drop-in replacement for the native C++ number types, but with unlimited precision.

As well as the usual conversions from arithmetic and string types, instances of number<gmp_rational> are copy constructible and assignable from:

  • The GMP native types: mpz_t, mpq_t.
  • number<gmp_int>.

There is also a two-argument constructor that accepts a numerator and denominator (both of type number<gmp_int>).

There are also non-member functions:

mpz_int numerator(const mpq_rational&);
mpz_int denominator(const mpq_rational&);

which return the numerator and denominator of the number.

It's also possible to access the underlying mpq_t via the data() member function of mpq_rational.

Things you should know when using this type:

  • Default constructed mpq_rationals have the value zero (this is the GMP default behavior).
  • Division by zero results in a std::overflow_error being thrown.
  • Conversion from a string results in a std::runtime_error being thrown if the string can not be interpreted as a valid rational number.
  • No changes are made to the GMP library's global settings, so this type can coexist with existing GMP code.
  • The code can equally be used with MPIR as the underlying library - indeed that is the preferred option on Win32.
Example:
#include <boost/multiprecision/gmp.hpp>
#include <boost/multiprecision/gmp.hpp>
#include <iostream>

int main()
{
   using namespace boost::multiprecision;

   mpq_rational v = 1;

   // Do some arithmetic:
   for(unsigned i = 1; i <= 1000; ++i)
      v *= i;
   v /= 10;

   std::cout << v << std::endl; // prints 1000! / 10
   std::cout << numerator(v) << std::endl;
   std::cout << denominator(v) << std::endl;

   mpq_rational w(2, 3);  // component wise constructor
   std::cout << w << std::endl; // prints 2/3

   // Access the underlying data:
   mpq_t q;
   mpq_init(q);
   mpq_set(q, v.backend().data());
   mpq_clear(q);
   return 0;
}

PrevUpHomeNext