29#include "musx/dom/Fundamentals.h"
41 int m_denominator = 1;
47 static constexpr std::pair<int, int> reduce(
int num,
int den) {
48 int gcd = std::gcd(num, den);
61 constexpr static Fraction fromConstExpr(
int num,
int den)
63 auto [n, d] = reduce(num, den);
65 result.m_denominator = d;
69 friend class std::numeric_limits<
Fraction>;
84 throw std::invalid_argument(
"Denominator cannot be zero.");
87 auto [n, d] = reduce(num, den);
97 constexpr Fraction(
int value) : m_numerator(value), m_denominator(1) {}
126 return m_numerator / m_denominator;
134 return fromConstExpr(m_numerator % m_denominator, m_denominator);
140 return Fraction(m_denominator, m_numerator);
152 using Wide = std::int64_t;
155 const auto num = Wide(m_numerator) * Wide(EDU_PER_WHOLE_NOTE);
156 const auto den = Wide(m_denominator);
159 auto rounded = Wide{};
161 rounded = (num + den / 2) / den;
163 rounded = (num - den / 2) / den;
167 constexpr auto maxEdu =
static_cast<Wide
>((std::numeric_limits<Edu>::max)());
168 constexpr auto minEdu =
static_cast<Wide
>((std::numeric_limits<Edu>::min)());
170 if (rounded > maxEdu) {
172 }
else if (rounded < minEdu) {
176 return Edu(
static_cast<int>(rounded));
185 return fromConstExpr(-numerator(), denominator());
193 return double(m_numerator) / double(m_denominator);
202 return fromConstExpr(
203 m_numerator * other.m_denominator + other.m_numerator * m_denominator,
204 m_denominator * other.m_denominator
214 return fromConstExpr(
215 m_numerator * other.m_denominator - other.m_numerator * m_denominator,
216 m_denominator * other.m_denominator
226 return fromConstExpr(
227 m_numerator * other.m_numerator,
228 m_denominator * other.m_denominator
241 m_numerator * other.m_denominator,
242 m_denominator * other.m_numerator
252 *
this = *
this + other;
262 *
this = *
this - other;
272 *
this = *
this * other;
283 *
this = *
this / other;
293 return m_numerator == other.m_numerator && m_denominator == other.m_denominator;
302 return !(*
this == other);
311 double lhs =
static_cast<double>(m_numerator) / m_denominator;
312 double rhs =
static_cast<double>(other.m_numerator) / other.m_denominator;
322 return *
this < other || *
this == other;
331 return !(*
this <= other);
340 return !(*
this < other);
347 constexpr explicit operator bool() const noexcept {
348 return m_numerator != 0;
358 os << frac.m_numerator;
359 if (frac.m_denominator != 1) {
360 os <<
"/" << frac.m_denominator;
375 is >> num >> sep >> den;
376 if (sep !=
'/' || den == 0) {
377 throw std::invalid_argument(
"Invalid fraction format or zero m_denominator.");
385constexpr Fraction abs(
const Fraction& v)
noexcept
393#ifndef DOXYGEN_SHOULD_IGNORE_THIS
398class numeric_limits<
musx::util::Fraction> {
400 static constexpr bool is_specialized =
true;
404 return musx::util::Fraction::fromConstExpr(1, std::numeric_limits<int>::max());
417 static constexpr int digits = std::numeric_limits<int>::digits;
418 static constexpr int digits10 = std::numeric_limits<int>::digits10;
420 static constexpr bool is_signed =
true;
421 static constexpr bool is_integer =
false;
422 static constexpr bool is_exact =
true;
423 static constexpr bool has_infinity =
false;
424 static constexpr bool has_quiet_NaN =
false;
425 static constexpr bool has_signaling_NaN =
false;
428 return musx::util::Fraction::fromConstExpr(1, std::numeric_limits<int>::max());
435 static constexpr int radix = 2;
441 static constexpr bool is_iec559 =
false;
442 static constexpr bool is_bounded =
true;
443 static constexpr bool is_modulo =
false;
444 static constexpr bool traps =
true;
445 static constexpr bool tinyness_before =
false;
446 static constexpr float_round_style round_style = round_indeterminate;
450struct hash<
musx::util::Fraction>
455 size_t seed = std::hash<int>{}(frac.numerator());
456 seed ^= std::hash<int>{}(frac.denominator()) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
A class to represent fractions with integer m_numerator and m_denominator, automatically reduced to s...
Definition Fraction.h:38
constexpr int quotient() const
Returns the integer (whole number) part of the fraction.
Definition Fraction.h:125
constexpr double toDouble() const
Converts the fraction to floating point double.
Definition Fraction.h:192
constexpr int numerator() const
Gets the m_numerator of the fraction.
Definition Fraction.h:113
static constexpr Fraction fromPercent(int percent)
Constructs a Fraction from a percent (where 100 is 100%)
Definition Fraction.h:107
Fraction constexpr operator*(const Fraction &other) const
Multiplies two fractions.
Definition Fraction.h:225
constexpr Fraction & operator-=(const Fraction &other)
Compound subtraction assignment operator.
Definition Fraction.h:261
constexpr bool operator<(const Fraction &other) const
Less-than comparison operator.
Definition Fraction.h:310
constexpr int denominator() const
Gets the m_denominator of the fraction.
Definition Fraction.h:119
Fraction reciprocal() const
Returns the reciprocal fraction.
Definition Fraction.h:139
Fraction(int num, int den)
Constructs a Fraction object.
Definition Fraction.h:81
constexpr bool operator<=(const Fraction &other) const
Less-than-or-equal-to comparison operator.
Definition Fraction.h:321
static constexpr Fraction fromEdu(dom::Edu edu)
Constructs a Fraction from edu.
Definition Fraction.h:103
Fraction constexpr operator+(const Fraction &other) const
Adds two fractions.
Definition Fraction.h:201
constexpr dom::Edu calcEduDuration() const
Calculates duration as a fraction of a whole note. The result is rounded to the nearest integer Edu v...
Definition Fraction.h:149
constexpr Fraction abs() const
Calculates the absolute value of a Fraction.
Definition Fraction.h:182
friend std::ostream & operator<<(std::ostream &os, const Fraction &frac)
Stream output operator.
Definition Fraction.h:357
Fraction constexpr remainder() const
Returns the fractional part of the fraction.
Definition Fraction.h:133
friend std::istream & operator>>(std::istream &is, Fraction &frac)
Stream input operator.
Definition Fraction.h:372
constexpr Fraction(int value)
Constructs a Fraction object from an integer.
Definition Fraction.h:97
constexpr bool operator>(const Fraction &other) const
Greater-than comparison operator.
Definition Fraction.h:330
constexpr Fraction & operator*=(const Fraction &other)
Compound multiplication assignment operator.
Definition Fraction.h:271
Fraction constexpr operator-(const Fraction &other) const
Subtracts one fraction from another.
Definition Fraction.h:213
constexpr Fraction & operator+=(const Fraction &other)
Compound addition assignment operator.
Definition Fraction.h:251
constexpr bool operator!=(const Fraction &other) const
Inequality comparison operator.
Definition Fraction.h:301
Fraction operator/(const Fraction &other) const
Divides one fraction by another.
Definition Fraction.h:239
Fraction & operator/=(const Fraction &other)
Compound division assignment operator.
Definition Fraction.h:282
constexpr bool operator==(const Fraction &other) const
Equality comparison operator. (This depends on the fact that instances of Fraction are always reduced...
Definition Fraction.h:292
constexpr bool operator>=(const Fraction &other) const
Greater-than-or-equal-to comparison operator.
Definition Fraction.h:339
int32_t Edu
"Enigma Durational Units" value (1024 per quarter note)
Definition Fundamentals.h:61
object model for musx file (enigmaxml)
Definition BaseClasses.h:36