200 lines
5.8 KiB
C++
200 lines
5.8 KiB
C++
//=============================================================================
|
|
// MuseScore
|
|
// Music Composition & Notation
|
|
//
|
|
// Copyright (C) 2009 Werner Schweer
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License version 2
|
|
// as published by the Free Software Foundation and appearing in
|
|
// the file LICENCE.GPL
|
|
//=============================================================================
|
|
|
|
#include "fraction.h"
|
|
#include "mscore.h"
|
|
|
|
|
|
namespace Ms {
|
|
|
|
//---------------------------------------------------------
|
|
// gcd
|
|
// greatest common divisor
|
|
//---------------------------------------------------------
|
|
|
|
static int gcd(int a, int b)
|
|
{
|
|
if (b == 0)
|
|
return a < 0 ? -a : a;
|
|
return gcd(b, a % b);
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// lcm
|
|
// least common multiple
|
|
//---------------------------------------------------------
|
|
|
|
static unsigned lcm(int a, int b)
|
|
{
|
|
return a * b / gcd(a, b);
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// Fraction
|
|
//---------------------------------------------------------
|
|
|
|
Fraction::Fraction(int z, int n)
|
|
: _numerator(z), _denominator(n)
|
|
{
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// reduce
|
|
//---------------------------------------------------------
|
|
|
|
void Fraction::reduce()
|
|
{
|
|
int tmp = gcd(_numerator, _denominator);
|
|
_numerator /= tmp;
|
|
_denominator /= tmp;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// reduced
|
|
//---------------------------------------------------------
|
|
|
|
Fraction Fraction::reduced() const
|
|
{
|
|
int tmp = gcd(_numerator, _denominator);
|
|
return Fraction(_numerator / tmp, _denominator / tmp);
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// absValue
|
|
//---------------------------------------------------------
|
|
|
|
Fraction Fraction::absValue() const
|
|
{
|
|
return Fraction(qAbs(_numerator), qAbs(_denominator));
|
|
}
|
|
|
|
// --- comparison --- //
|
|
|
|
bool Fraction::operator<(const Fraction& val) const
|
|
{
|
|
const int v = lcm(_denominator, val._denominator);
|
|
return _numerator * (v / _denominator) < val._numerator * (v / val._denominator);
|
|
}
|
|
|
|
bool Fraction::operator<=(const Fraction& val) const
|
|
{
|
|
const int v = lcm(_denominator, val._denominator);
|
|
return _numerator * (v / _denominator) <= val._numerator * (v / val._denominator);
|
|
}
|
|
|
|
bool Fraction::operator>=(const Fraction& val) const
|
|
{
|
|
const int v = lcm(_denominator, val._denominator);
|
|
return _numerator * (v / _denominator) >= val._numerator * (v / val._denominator);
|
|
}
|
|
|
|
bool Fraction::operator>(const Fraction& val) const
|
|
{
|
|
const int v = lcm(_denominator, val._denominator);
|
|
return (_numerator * (v / _denominator)) > (val._numerator * (v / val._denominator));
|
|
}
|
|
|
|
bool Fraction::operator==(const Fraction& val) const
|
|
{
|
|
const int v = lcm(_denominator, val._denominator);
|
|
return (_numerator * (v / _denominator)) == (val._numerator * (v / val._denominator));
|
|
// return (_numerator == val._numerator) && (_denominator == val._denominator);
|
|
}
|
|
|
|
bool Fraction::operator!=(const Fraction& val) const
|
|
{
|
|
const int v = lcm(_denominator, val._denominator);
|
|
return (_numerator * (v / _denominator)) != (val._numerator * (v / val._denominator));
|
|
// return (_numerator != val._numerator) || (_denominator != val._denominator);
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// operator+=
|
|
//---------------------------------------------------------
|
|
|
|
Fraction& Fraction::operator+=(const Fraction& val)
|
|
{
|
|
const int tmp = lcm(_denominator, val._denominator);
|
|
_numerator = _numerator * (tmp / _denominator) + val._numerator * (tmp / val._denominator);
|
|
_denominator = tmp;
|
|
return *this;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// operator-=
|
|
//---------------------------------------------------------
|
|
|
|
Fraction& Fraction::operator-=(const Fraction& val)
|
|
{
|
|
const unsigned tmp = lcm(_denominator, val._denominator);
|
|
_numerator = _numerator * (tmp / _denominator) - val._numerator * (tmp / val._denominator);
|
|
_denominator = tmp;
|
|
return *this;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// operator*=
|
|
//---------------------------------------------------------
|
|
|
|
Fraction& Fraction::operator*=(const Fraction& val)
|
|
{
|
|
_numerator *= val._numerator;
|
|
_denominator *= val._denominator;
|
|
return *this;
|
|
}
|
|
|
|
Fraction& Fraction::operator*=(int val)
|
|
{
|
|
_numerator *= val;
|
|
return *this;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// operator/=
|
|
//---------------------------------------------------------
|
|
|
|
Fraction& Fraction::operator/=(const Fraction& val)
|
|
{
|
|
_numerator *= val._denominator;
|
|
_denominator *= val._numerator;
|
|
return *this;
|
|
}
|
|
|
|
Fraction& Fraction::operator/=(int val)
|
|
{
|
|
_denominator *= val;
|
|
return *this;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// fromTicks
|
|
//---------------------------------------------------------
|
|
|
|
Fraction Fraction::fromTicks(int ticks)
|
|
{
|
|
return Fraction(ticks, MScore::division * 4).reduced();
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// ticks
|
|
//---------------------------------------------------------
|
|
|
|
int Fraction::ticks() const
|
|
{
|
|
// MScore::division - ticks per quarter note
|
|
// MScore::division * 4 - ticks per whole note
|
|
// result: rounded (MScore::division * 4 * _numerator * 1.0 / _denominator) value
|
|
return (_numerator * MScore::division * 4 + (_denominator/2)) / _denominator;
|
|
}
|
|
|
|
} // namespace Ms
|
|
|