Multiprecision rationals

Contents

Multiprecision rationals#

Added in version 0.3.

#include <mp++/rational.hpp>

The rational class#

template<std::size_t SSize>
class mppp::rational#

Multiprecision rational class.

This class represents arbitrary-precision rationals. Internally, the class stores a pair of integers with static size SSize as the numerator and denominator. Rational numbers are represented in the usual canonical form:

  • numerator and denominator are coprime,

  • the denominator is always strictly positive.

Most of the functionality is exposed via plain functions, with the general convention that the functions are named after the corresponding GMP functions minus the leading mpq_ prefix. For instance, the GMP call

mpq_add(rop,a,b);

that writes the result of a + b into rop becomes simply

add(rop,a,b);

where the add() function is resolved via argument-dependent lookup. Function calls with overlapping arguments are allowed, unless noted otherwise.

Various overloaded operators are provided.

The rational class allows to access and manipulate directly the numerator and denominator via the get_num(), get_den(), _get_num() and _get_den() member functions, so that it is possible to use integer functions directly on numerator and denominator. The mutable getters’ names _get_num() and _get_den() are prefixed with an underscore _ to highlight their potentially dangerous nature: it is the user’s responsibility to ensure that the canonical form of the rational is preserved after altering the numerator and/or the denominator via the mutable getters.

A tutorial showcasing various features of rational is available.

using int_t = integer<SSize>#

Underlying integral type.

This is the integer type used for the representation of numerator and denominator.

static constexpr std::size_t ssize = SSize#

Alias for the static size.

rational()#

The default constructor initialises to zero.

rational(const rational &other)#
rational(rational &&other) noexcept#

Copy and move constructors.

The copy constructor will perform a copy of numerator and denominator. The move constructor will leave other in an unspecified but valid state.

Parameters:

other – the construction argument.

template<rational_cvr_interoperable<SSize> T>
explicit rational(T &&x)#

Generic constructor.

Note

This constructor is not explicit if T satisfies rational_integral_interoperable.

This constructor will initialize a rational with the value x. The construction will fail if either:

  • x is a non-finite floating-point value, or,

  • x is a complex value whose imaginary part is not zero or whose real part is not finite.

Parameters:

x – the value that will be used to initialize this.

Throws:

std::domain_error – if x is a non-finite floating-point value, or a complex value with non-zero imaginary part or non-finite real part.

template<rational_cvr_integral_interoperable<SSize> T, rational_cvr_integral_interoperable<SSize> U>
explicit rational(T &&n, U &&d, bool make_canonical = true)#

Constructor from numerator and denominator.

The input value n will be used to initialise the numerator, while d will be used to initialise the denominator. If make_canonical is true (the default), then canonicalise() will be called after the construction of numerator and denominator.

Warning

If this constructor is called with make_canonical set to false, it will be the user’s responsibility to ensure that this is canonicalised before using it with other mp++ functions. Failure to do so will result in undefined behaviour.

Parameters:
  • n – the numerator.

  • d – the denominator.

  • make_canonical – if true, the rational will be canonicalised after the construction of numerator and denominator.

Throws:

zero_division_error – if the denominator is zero.

template<string_type T>
explicit rational(const T &s, int base = 10)#

Constructor from string.

This constructor will initialize this from the string_type s, which must represent a rational value in base base. The expected format is either a numerator-denominator pair separated by the division operator /, or just a numerator (in which case the denominator will be set to one). The format for numerator and denominator is described in the documentation of the constructor from string of integer.

Parameters:
  • s – the input string.

  • base – the base used in the string representation.

Throws:
  • zero_division_error – if the denominator is zero.

  • unspecified – any exception thrown by the string constructor of integer, or by memory errors in standard containers.

explicit rational(const char *begin, const char *end, int base = 10)#

Constructor from a range of characters.

This constructor will initialise this from the content of the input half-open range, which is interpreted as the string representation of a rational in base base.

Internally, the constructor will copy the content of the range to a local buffer, add a string terminator, and invoke the constructor from string.

Parameters:
  • begin – the begin of the input range.

  • end – the end of the input range.

  • base – the base used in the string representation.

Throws:

unspecified – any exception thrown by the constructor from string, or by memory errors in standard containers.

explicit rational(const mpz_t n)#

Constructor from a GMP integer.

This constructor will initialise the numerator of this with a copy of the input GMP integer n, and the denominator to 1.

Warning

It is the user’s responsibility to ensure that n has been correctly initialized. Calling this constructor with an uninitialized n results in undefined behaviour.

Parameters:

n – the input GMP integer.

explicit rational(const mpq_t q)#

Constructor from a GMP rational.

This constructor will initialise the numerator and denominator of this with copies of those of the GMP rational q.

Warning

It is the user’s responsibility to ensure that q has been correctly initialized. Calling this constructor with an uninitialized q results in undefined behaviour.

This constructor will not canonicalise this: numerator and denominator are constructed as-is from q.

Parameters:

q – the input GMP rational.

explicit rational(mpq_t &&q)#

Move constructor from a GMP rational.

This constructor will move the numerator and denominator of the GMP rational q into this.

Warning

It is the user’s responsibility to ensure that q has been correctly initialized. Calling this constructor with an uninitialized q results in undefined behaviour.

This constructor will not canonicalise this: numerator and denominator are constructed as-is from q.

The user must ensure that, after construction, mpq_clear() is never called on q: the resources previously owned by q are now owned by this, which will take care of releasing them when the destructor is called.

Note

Due to a compiler bug, this constructor is not available on Microsoft Visual Studio.

Parameters:

q – the input GMP rational.

rational &operator=(const rational &other)#
rational &operator=(rational &&other) noexcept#

Copy and move assignment.

After move-assignment, other is left in an unspecified but valid state.

Parameters:

other – the assignment argument.

Returns:

a reference to this.

template<rational_cvr_interoperable<SSize> T>
rational &operator=(T &&x)#

Generic assignment operator.

This operator will assign x to this.

Parameters:

x – the assignment argument.

Returns:

a reference to this.

Throws:

unspecified – any exception thrown by the generic constructor.

rational &operator=(const real128 &x)#
rational &operator=(const real &x)#
rational &operator=(const complex128 &x)#
rational &operator=(const complex &x)#

Note

The real128 and complex128 overloads are available only if mp++ was configured with the MPPP_WITH_QUADMATH option enabled. The real overload is available only if mp++ was configured with the MPPP_WITH_MPFR option enabled. The complex overload is available only if mp++ was configured with the MPPP_WITH_MPC option enabled.

Added in version 0.20.

Assignment operators from other mp++ classes.

These operators are formally equivalent to converting x to rational and then move-assigning the result to this.

Parameters:

x – the assignment argument.

Returns:

a reference to this.

Throws:

unspecified – any exception raised by the conversion of x to rational.

template<string_type T>
rational &operator=(const T &s)#

Assignment from string.

The body of this operator is equivalent to:

return *this = rational{s};

That is, a temporary rational is constructed from s and it is then move-assigned to this.

Parameters:

s – the string that will be used for the assignment.

Returns:

a reference to this.

Throws:

unspecified – any exception thrown by the constructor from string.

rational &operator=(const mpz_t n)#

Assignment from a GMP integer.

This assignment operator will copy into the numerator of this the value of the GMP integer n, and it will set the denominator to 1 via mppp::integer::set_one().

Warning

It is the user’s responsibility to ensure that n has been correctly initialized. Calling this operator with an uninitialized n results in undefined behaviour.

No aliasing is allowed: the data in n must be completely distinct from the data in this.

Parameters:

n – the input GMP integer.

Returns:

a reference to this.

rational &operator=(const ::mpq_t q)#

Assignment from a GMP rational.

This assignment operator will copy into this the value of the GMP rational q.

Warning

It is the user’s responsibility to ensure that q has been correctly initialized. Calling this operator with an uninitialized q results in undefined behaviour.

This operator will not canonicalise the assigned value: numerator and denominator are assigned as-is from q.

No aliasing is allowed: the data in q must be completely distinct from the data in this.

Parameters:

q – the input GMP rational.

Returns:

a reference to this.

rational &operator=(mpq_t &&q)#

Move assignment from a GMP rational.

This assignment operator will move the GMP rational q into this.

Warning

It is the user’s responsibility to ensure that q has been correctly initialized. Calling this operator with an uninitialized q results in undefined behaviour.

This operator will not canonicalise the assigned value: numerator and denominator are assigned as-is from q.

No aliasing is allowed: the data in q must be completely distinct from the data in this.

The user must ensure that, after the assignment, mpq_clear() is never called on q: the resources previously owned by q are now owned by this, which will take care of releasing them when the destructor is called.

Note

Due to a compiler bug, this operator is not available on Microsoft Visual Studio.

Parameters:

q – the input GMP rational.

Returns:

a reference to this.

std::string to_string(int base = 10) const#

Convert to string.

This operator will return a string representation of this in base base. The string format consists of the numerator, followed by the division operator / and the denominator, but only if the denominator is not unitary. Otherwise, only the numerator will be represented in the returned string.

Parameters:

base – the desired base for the string representation.

Returns:

a string representation for this.

Throws:

unspecified – any exception thrown by mppp::integer::to_string().

template<rational_interoperable<SSize> T>
explicit operator T() const#

Generic conversion operator.

This operator will convert this to T. Conversion to bool yields false if this is zero, true otherwise. Conversion to other integral types and to int_t yields the result of the truncated division of the numerator by the denominator, if representable by the target type. Conversion to floating-point and complex types might yield inexact values and infinities.

Returns:

this converted to the target type.

Throws:

std::overflow_error – if the target type is an integral type and the value of this overflows its range.

template<rational_interoperable<SSize> T>
bool get(T &rop) const#

Generic conversion member function.

This member function, similarly to the conversion operator, will convert this to T, storing the result of the conversion into rop. Differently from the conversion operator, this member function does not raise any exception: if the conversion is successful, the member function will return true, otherwise the member function will return false. If the conversion fails, rop will not be altered.

Parameters:

rop – the variable which will store the result of the conversion.

Returns:

true if the conversion succeeded, false otherwise. The conversion can fail only if T is an integral C++ type which cannot represent the truncated value of this.

const int_t &get_num() const#
const int_t &get_den() const#
int_t &_get_num()#
int_t &_get_den()#

Getters for numerator and denominator.

Warning

It is the user’s responsibility to ensure that, after changing the numerator or denominator via one of the mutable getters, the rational is kept in canonical form.

Returns:

a (const) reference to the numerator or denominator.

rational &canonicalise()#

Canonicalise.

This member function will put this in canonical form. In particular, this member function will make sure that:

  • the numerator and denominator are coprime (dividing them by their GCD, if necessary),

  • the denominator is strictly positive.

In general, it is not necessary to call explicitly this member function, as the public API of rational ensures that rationals are kept in canonical form. Calling this member function, however, might be necessary if the numerator and/or denominator are modified manually, or when constructing/assigning from non-canonical mpq_t values.

Returns:

a reference to this.

bool is_canonical() const#

Check canonical form.

Returns:

true if this is the canonical form for rational numbers, false otherwise.

int sgn() const#

Sign function.

Returns:

0 if this is zero, 1 if this is positive, -1 if this is negation.

rational &neg()#

Negate in-place.

This function will set this to its negative.

Returns:

a reference to this.

rational &abs()#

In-place absolute value.

This function will set this to its absolute value.

Returns:

a reference to this.

rational &inv()#

Invert in-place.

This function will set this to its inverse.

Returns:

a reference to this.

Throws:

zero_division_error – if this is zero.

bool is_zero() const#
bool is_one() const#
bool is_negative_one() const#

Test for special values.

Returns:

true if this is, respectively, \(0\), \(1\) or \(-1\), false otherwise.

Types#

type mpq_t#

This is the type used by the GMP library to represent multiprecision rationals. It is defined as an array of size 1 of an unspecified structure.

Concepts#

template<typename T, std::size_t SSize>
concept mppp::rational_interoperable#

This concept is satisfied if the type T can interoperate with a rational with static size SSize. Specifically, this concept will be true if T satisfies integer_cpp_arithmetic or integer_cpp_complex, or it is an integer with static size SSize.

template<typename T, std::size_t SSize>
concept mppp::rational_cvr_interoperable#

This concept is satisfied if the type T, after the removal of reference and cv qualifiers, satisfies rational_interoperable.

template<typename T, std::size_t SSize>
concept mppp::rational_integral_interoperable#

This concept is satisfied if either:

template<typename T, std::size_t SSize>
concept mppp::rational_cvr_integral_interoperable#

This concept is satisfied if the type T, after the removal of reference and cv qualifiers, satisfies rational_integral_interoperable.

template<typename T, typename U>
concept mppp::rational_op_types#

This concept is satisfied if the types T and U are suitable for use in the generic binary operators and functions involving rational. Specifically, the concept will be true if either:

template<typename T, typename U>
concept mppp::rational_real_op_types#

This concept will be true if:

Functions#

Much of the functionality of the rational class is exposed via plain functions. These functions mimic the GMP API where appropriate, but a variety of convenience/generic overloads is provided as well.

Assignment#

template<std::size_t SSize>
void mppp::swap(mppp::rational<SSize> &q1, mppp::rational<SSize> &q2) noexcept#

Added in version 0.15.

Swap.

This function will efficiently swap the values of q1 and q2.

Parameters:
  • q1 – the first argument.

  • q2 – the second argument.

Conversion#

template<std::size_t SSize, mppp::rational_interoperable<SSize> T>
bool mppp::get(T &rop, const mppp::rational<SSize> &q)#

Generic conversion function.

This function will convert the input rational q to a rational_interoperable type, storing the result of the conversion into rop. If the conversion is successful, the function will return true, otherwise the function will return false. If the conversion fails, rop will not be altered.

Parameters:
  • rop – the variable which will store the result of the conversion.

  • q – the input argument.

Returns:

true if the conversion succeeded, false otherwise. The conversion can fail only if T is an integral C++ type which cannot represent the truncated value of q.

Arithmetic#

template<std::size_t SSize>
mppp::rational<SSize> &mppp::add(mppp::rational<SSize> &rop, const mppp::rational<SSize> &x, const mppp::rational<SSize> &y)#
template<std::size_t SSize>
mppp::rational<SSize> &mppp::sub(mppp::rational<SSize> &rop, const mppp::rational<SSize> &x, const mppp::rational<SSize> &y)#
template<std::size_t SSize>
mppp::rational<SSize> &mppp::mul(mppp::rational<SSize> &rop, const mppp::rational<SSize> &x, const mppp::rational<SSize> &y)#
template<std::size_t SSize>
mppp::rational<SSize> &mppp::div(mppp::rational<SSize> &rop, const mppp::rational<SSize> &x, const mppp::rational<SSize> &y)#

Ternary arithmetic primitives.

These functions will set rop to, respectively:

  • \(x + y\),

  • \(x - y\),

  • \(x \times y\),

  • \(\frac{x}{y}\).

Parameters:
  • rop – the return value.

  • x – the first operand.

  • y – the second operand.

Returns:

a reference to rop.

Throws:

mppp::zero_division_error – if, in a division operation, y is zero.

template<std::size_t SSize>
mppp::rational<SSize> &mppp::neg(mppp::rational<SSize> &rop, const mppp::rational<SSize> &x)#
template<std::size_t SSize>
mppp::rational<SSize> &mppp::abs(mppp::rational<SSize> &rop, const mppp::rational<SSize> &x)#

Binary negation and absolute value.

These functions will set rop to, respectively, \(-x\) and \(\left| x \right|\).

Parameters:
  • rop – the return value.

  • x – the input value.

Returns:

a reference to rop.

template<std::size_t SSize>
mppp::rational<SSize> mppp::neg(const mppp::rational<SSize> &x)#
template<std::size_t SSize>
mppp::rational<SSize> mppp::abs(const mppp::rational<SSize> &x)#

Unary negation and absolute value.

Parameters:

x – the input value.

Returns:

\(-x\) and \(\left| x \right|\) respectively.

template<std::size_t SSize>
mppp::rational<SSize> &mppp::inv(mppp::rational<SSize> &rop, const mppp::rational<SSize> &x)#

Binary inversion.

This function will set rop to \(x^{-1}\).

Parameters:
  • rop – the return value.

  • x – the input value.

Returns:

a reference to rop.

Throws:

unspecified – any exception thrown by mppp::rational::inv().

template<std::size_t SSize>
mppp::rational<SSize> mppp::inv(const mppp::rational<SSize> &x)#

Unary inversion.

Parameters:

x – the input value.

Returns:

\(x^{-1}\).

Throws:

unspecified – any exception thrown by mppp::rational::inv().

Comparison#

template<std::size_t SSize>
int mppp::cmp(const mppp::rational<SSize> &x, const mppp::rational<SSize> &y)#
template<std::size_t SSize>
int mppp::cmp(const mppp::rational<SSize> &x, const mppp::integer<SSize> &y)#
template<std::size_t SSize>
int mppp::cmp(const mppp::integer<SSize> &x, const mppp::rational<SSize> &y)#

Three-way comparisons.

These functions will return 0 if \(x=y\), a negative value if \(x<y\) and a positive value if \(x>y\).

Parameters:
  • x – the first operand.

  • y – the second operand.

Returns:

the result of the comparison.

template<std::size_t SSize>
int mppp::sgn(const mppp::rational<SSize> &q)#

Sign function.

Parameters:

q – the input argument.

Returns:

0 if q is zero, 1 if q is positive, -1 if q is negative.

template<std::size_t SSize>
bool mppp::is_zero(const mppp::rational<SSize> &q)#
template<std::size_t SSize>
bool mppp::is_one(const mppp::rational<SSize> &q)#
template<std::size_t SSize>
bool mppp::is_negative_one(const mppp::rational<SSize> &q)#

Test for special values.

Parameters:

q – the input argument.

Returns:

true if, respectively, \(q=0\), \(q=1\) or \(q=-1\), false otherwise.

Number theoretic functions#

Added in version 0.8.

template<std::size_t SSize, mppp::rational_integral_interoperable<SSize> T>
mppp::rational<SSize> mppp::binomial(const mppp::rational<SSize> &x, const T &y)#

Binomial coefficient.

This function will compute the binomial coefficient \({x \choose y}\). If x represents an integral value, the calculation is forwarded to the implementation of the binomial coefficient for integer. Otherwise, an implementation based on the falling factorial is employed.

Parameters:
  • x – the top value.

  • y – the bottom value.

Returns:

\({x \choose y}\).

Throws:

unspecified – any exception thrown by the implementation of the binomial coefficient for integer.

Exponentiation#

template<typename T, mppp::rational_op_types<T> U>
auto mppp::pow(const T &x, const U &y)#

Exponentiation.

This function will return \(x^y\). If one of the arguments is a floating-point or complex value, then the result will be computed via std::pow() and it will also be a floating-point or complex value. Otherwise, the result will be a rational.

When floating-point and complex types are not involved, the implementation is based on the integral exponentiation of numerator and denominator. Thus, if y is a rational value, the exponentiation will be successful only in a few special cases (e.g., unitary base, zero exponent, etc.).

Parameters:
  • x – the base.

  • y – the exponent.

Returns:

\(x^y\).

Throws:
  • mppp::zero_division_error – if floating-point or complex types are not involved, and x is zero and y negative.

  • std::domain_error – if floating-point or complex types are not involved and y is a rational value (except in a handful of special cases).

Input/Output#

template<std::size_t SSize>
std::ostream &mppp::operator<<(std::ostream &os, const mppp::rational<SSize> &q)#

Stream insertion operator.

This function will direct to the output stream os the input rational q.

Parameters:
  • os – the output stream.

  • q – the input rational.

Returns:

a reference to os.

Throws:
  • std::overflow_error – in case of (unlikely) overflow errors.

  • unspecified – any exception raised by the public interface of std::ostream or by memory allocation errors.

Other#

template<std::size_t SSize>
mppp::rational<SSize> &mppp::canonicalise(mppp::rational<SSize> &rop)#

Canonicalise.

This function will put rop in canonical form. Internally, this function will employ mppp::rational::canonicalise().

Parameters:

rop – the rational that will be canonicalised.

Returns:

a reference to rop.

template<std::size_t SSize>
std::size_t mppp::hash(const mppp::rational<SSize> &q)#

Hash value.

This function will return a hash value for q.

A specialisation of the standard std::hash functor is also provided, so that it is possible to use rational in standard unordered associative containers out of the box.

Parameters:

q – the rational whose hash value will be computed.

Returns:

a hash value for q.

Mathematical operators#

Overloaded operators are provided for convenience. Their interface is generic, and their implementation is typically built on top of basic functions.

template<std::size_t SSize>
mppp::rational<SSize> mppp::operator+(const mppp::rational<SSize> &q)#
template<std::size_t SSize>
mppp::rational<SSize> mppp::operator-(const mppp::rational<SSize> &q)#

Identity and negation operators.

Parameters:

q – the input value.

Returns:

\(q\) and \(-q\) respectively.

template<typename T, mppp::rational_op_types<T> U>
auto mppp::operator+(const T &x, const U &y)#
template<typename T, mppp::rational_op_types<T> U>
auto mppp::operator-(const T &x, const U &y)#
template<typename T, mppp::rational_op_types<T> U>
auto mppp::operator*(const T &x, const U &y)#
template<typename T, mppp::rational_op_types<T> U>
auto mppp::operator/(const T &x, const U &y)#

Binary arithmetic operators.

These operators will return, respectively:

  • \(x+y\),

  • \(x-y\),

  • \(x \times y\),

  • \(\frac{x}{y}\).

The return type of these operators is determined as follows:

  • if the non-rational argument is a floating-point or complex value, then the type of the result is floating-point or complex; otherwise,

  • the type of the result is rational.

Parameters:
  • x – the first operand.

  • y – the second operand.

Returns:

the result of the operation.

Throws:

mppp::zero_division_error – if, in a division not involving floating-point or complex values, y is zero.

template<typename T, mppp::rational_op_types<T> U>
auto mppp::operator+=(T &x, const U &y)#
template<typename T, mppp::rational_op_types<T> U>
auto mppp::operator-=(T &x, const U &y)#
template<typename T, mppp::rational_op_types<T> U>
auto mppp::operator*=(T &x, const U &y)#
template<typename T, mppp::rational_op_types<T> U>
auto mppp::operator/=(T &x, const U &y)#

In-place arithmetic operators.

These operators will set x to, respectively:

  • \(x+y\),

  • \(x-y\),

  • \(x \times y\),

  • \(\frac{x}{y}\).

Parameters:
  • x – the first operand.

  • y – the second operand.

Returns:

a reference to x.

Throws:
  • mppp::zero_division_error – if, in a division not involving floating-point or complex values, y is zero.

  • unspecified – any exception thrown by the assignment/conversion operators of rational.

template<std::size_t SSize>
mppp::rational<SSize> &mppp::operator++(mppp::rational<SSize> &q)#
template<std::size_t SSize>
mppp::rational<SSize> &mppp::operator--(mppp::rational<SSize> &q)#

Prefix increment/decrement.

Parameters:

q – the input argument.

Returns:

a reference to q after the increment/decrement.

template<std::size_t SSize>
mppp::rational<SSize> mppp::operator++(mppp::rational<SSize> &q, int)#
template<std::size_t SSize>
mppp::rational<SSize> mppp::operator--(mppp::rational<SSize> &q, int)#

Suffix increment/decrement.

Parameters:

q – the input argument.

Returns:

a copy of q before the increment/decrement.

template<typename T, mppp::rational_op_types<T> U>
bool mppp::operator==(const T &op1, const U &op2)#
template<typename T, mppp::rational_op_types<T> U>
bool mppp::operator!=(const T &op1, const U &op2)#
template<typename T, mppp::rational_op_types<T> U>
bool mppp::operator<(const T &op1, const U &op2)#
template<typename T, mppp::rational_op_types<T> U>
bool mppp::operator<=(const T &op1, const U &op2)#
template<typename T, mppp::rational_op_types<T> U>
bool mppp::operator>(const T &op1, const U &op2)#
template<typename T, mppp::rational_op_types<T> U>
bool mppp::operator>=(const T &op1, const U &op2)#

Binary comparison operators.

Parameters:
  • op1 – first argument.

  • op2 – second argument.

Returns:

the result of the comparison.

Standard library specialisations#

template<std::size_t SSize>
class std::hash<mppp::rational<SSize>>#

Specialisation of std::hash for mppp::rational.

using argument_type = mppp::rational<SSize>#
using result_type = std::size_t#

Note

The argument_type and result_type type aliases are defined only until C++14.

std::size_t operator()(const mppp::rational<SSize> &q) const#
Parameters:

q – the input mppp::rational.

Returns:

a hash value for q.

User-defined literals#

Added in version 0.19.

template<char... Chars>
mppp::rational<1> mppp::literals::operator""_q1()#
template<char... Chars>
mppp::rational<2> mppp::literals::operator""_q2()#
template<char... Chars>
mppp::rational<3> mppp::literals::operator""_q3()#

User-defined rational literals.

These numeric literal operator templates can be used to construct rational instances with, respectively, 1, 2 and 3 limbs of static storage. Literals in binary, octal, decimal and hexadecimal format are supported.

Note that only integral values (i.e., rationals with unitary denominator) can be constructed via these literals.

Throws:

std::invalid_argument – if the input sequence of characters is not a valid integer literal (as defined by the C++ standard).