25 #include "gnc-rational.hpp"    26 #include "gnc-numeric.hpp"    30     m_num(n.num()), m_den(n.denom())
    40     m_num (n.num), m_den (n.denom)
    65 GncRational::operator gnc_numeric () const noexcept
    71         return {
static_cast<int64_t
>(m_num), static_cast<int64_t>(m_den)};
    73     catch (std::overflow_error&)
   107     *
this = std::move(new_val);
   114     *
this = std::move(new_val);
   121     *
this = std::move(new_val);
   128     *
this = std::move(new_val);
   134     if (m_den == b.
denom())
   136         auto b_num = b.
num();
   137         return m_num < b_num ? -1 : b_num < m_num ? 1 : 0;
   141     return a_num < b_num ? -1 : b_num < a_num ? 1 : 0;
   144 GncRational::round_param
   145 GncRational::prepare_conversion (
GncInt128 new_denom)
 const   148         return {m_num, m_den, 0};
   150     auto red_conv = conversion.reduce();
   152     auto new_num = old_num * red_conv.num();
   153     if (new_num.isOverflow())
   154         throw std::overflow_error(
"Conversion overflow");
   155     auto rem = new_num % red_conv.denom();
   156     new_num /= red_conv.denom();
   157     return {new_num, red_conv.denom(), rem};
   161 GncRational::sigfigs_denom(
unsigned figs) 
const noexcept
   166     auto num_abs = m_num.abs();
   167     bool not_frac = num_abs > m_den;
   168     int64_t val{ not_frac ? num_abs / m_den : m_den / num_abs };
   176             powten(digits < figs ? figs - digits - 1 : 0) : 
   177             powten(figs + digits);
   183     auto gcd = m_den.
gcd(m_num);
   185         throw std::overflow_error(
"Reduce failed, calculation of gcd overflowed.");
   192     unsigned int ll_bits = GncInt128::legbits;
   195     if (!(m_num.
isBig() || m_den.isBig()))
   197     if (m_num.abs() > m_den)
   199         auto quot(m_num / m_den);
   202             std::ostringstream msg;
   203             msg << 
" Cannot be represented as a "   204                 << 
"GncNumeric. Its integer value is too large.\n";
   205             throw std::overflow_error(msg.str());
   212                 new_v = convert<RoundType::half_down>(m_den / (m_num.abs() >> ll_bits));
   219             catch(
const std::overflow_error& err)
   226     auto quot(m_den / m_num);
   232         auto divisor = m_den >> ll_bits;
   236             oldnum.
div(divisor, 
num, rem);
   237             auto den = m_den / divisor;
   238             num += rem * 2 >= den ? 1 : 0;
   247         new_v = convert<RoundType::half_down>(m_den / divisor);
   260     if (!(a.valid() && b.
valid()))
   261         throw std::range_error(
"Operator+ called with out-of-range operand.");
   265         throw std::overflow_error(
"Operator+ overflowed.");
   280     if (!(a.valid() && b.
valid()))
   281         throw std::range_error(
"Operator* called with out-of-range operand.");
   283     if (!(num.valid() && den.valid()))
   284         throw std::overflow_error(
"Operator* overflowed.");
   292     if (!(a.valid() && b.
valid()))
   293         throw std::range_error(
"Operator/ called with out-of-range operand.");
   294     auto a_num = a.num(), b_num = b.
num(), a_den = a.denom(), b_den = b.
denom();
   296         throw std::underflow_error(
"Divide by 0.");
   310     if (a_num.isBig() || a_den.isBig() ||
   311         b_num.isBig() || b_den.isBig())
   318     GncInt128 num(a_num * b_den), den(a_den * b_num);
   319     if (!(num.valid() && den.valid()))
   320         throw std::overflow_error(
"Operator/ overflowed.");
 bool isBig() const noexcept
 
GncInt128 gcd(GncInt128 b) const noexcept
Computes the Greatest Common Divisor between the object and parameter. 
 
GncInt128 denom() const noexcept
Denominator accessor. 
 
GncRational inv() const noexcept
Inverts the number, equivalent of /= {1, 1}. 
 
GncRational reduce() const
Return an equivalent fraction with all common factors between the numerator and the denominator remov...
 
The primary numeric class for representing amounts and values. 
 
Intermediate result overflow. 
 
GncInt128 gcd(int64_t a, int64_t b)
Compute the greatest common denominator of two integers. 
 
bool valid() const noexcept
 
GncRational abs() const noexcept
Absolute value; return value is always >= 0 and of same magnitude. 
 
gnc_numeric gnc_numeric_error(GNCNumericErrorCode error_code)
Create a gnc_numeric object that signals the error condition noted by error_code, rather than a numbe...
 
bool isNan() const noexcept
 
Rational number class using GncInt128 for the numerator and denominator. 
 
bool isZero() const noexcept
 
GncRational round_to_numeric() const
Round to fit an int64_t, finding the closest possible approximation. 
 
GncInt128 lcm(int64_t a, int64_t b)
Compute the least common multiple of two integers. 
 
GncRational()
Default constructor provides the zero value. 
 
bool is_big() const noexcept
Report if either numerator or denominator are too big to fit in an int64_t. 
 
GncInt128 num() const noexcept
Numerator accessor. 
 
int cmp(GncRational b)
Compare function. 
 
bool valid() const noexcept
Report if both members are valid numbers. 
 
GncRational operator-() const noexcept
Make a new GncRational with the opposite sign. 
 
void div(const GncInt128 &d, GncInt128 &q, GncInt128 &r) const noexcept
Computes a quotient and a remainder, passed as reference parameters. 
 
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument. 
 
bool isOverflow() const noexcept