Rational.h
Go to the documentation of this file.
1 /****
2  * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
3  * Created 2015 by Skurydin Alexey
4  * http://github.com/SmingHub/Sming
5  * All files of the Sming Core are provided under the LGPL v3 license.
6  *
7  * Rational.h - Run-time rational number handling
8  *
9  * @author mikee47 <mike@sillyhouse.net>
10  *
11  * Where calculations all involve constant values use std::ratio to have computations performed at compile time.
12  *
13  ****/
14 
15 #pragma once
16 
17 #include <cstdint>
18 #include <ratio>
19 #include <algorithm>
20 #include <muldiv.h>
21 #include <WString.h>
22 
37 template <typename T> struct BasicRatio {
38  T num;
39  T den;
40 
41  operator String() const
42  {
43  String s(num);
44  s += '/';
45  s += den;
46  return s;
47  }
48 };
49 
53 
65 template <typename T> struct Ratio : public BasicRatio<T> {
66  Ratio() = default;
67 
68  Ratio(const BasicRatio<T>& r)
69  {
70  this->num = r.num;
71  this->den = r.den;
72  }
73 
74  explicit Ratio(T num, T den = 1)
75  {
76  set(num, den);
77  }
78 
83  template <T num, T den> void set()
84  {
85  using R = std::ratio<num, den>;
86  this->num = R::num;
87  this->den = R::den;
88  }
89 
94  void set(T num, T den = 1)
95  {
96  // Note: Officially added std::numerics::gcd in C++17
97  auto g = std::__gcd(num, den);
98  this->num = num / g;
99  this->den = den / g;
100  }
101 
102  template <typename ValueType> explicit operator ValueType() const
103  {
104  return muldiv(this->num, T(1), this->den);
105  }
106 
110  friend Ratio operator*(const Ratio& lhs, const Ratio& rhs)
111  {
112  return Ratio(lhs.num * rhs.num, lhs.den * rhs.den);
113  }
114 
118  template <typename ValueType> friend ValueType operator*(ValueType lhs, const Ratio& rhs)
119  {
120  return muldiv(lhs, rhs.num, rhs.den);
121  }
122 
126  template <typename ValueType> friend ValueType operator*(const Ratio& lhs, const ValueType& rhs)
127  {
128  return rhs * lhs;
129  }
130 
134  friend Ratio operator/(const Ratio& lhs, const Ratio& rhs)
135  {
136  return Ratio(lhs.num * rhs.den, lhs.den * rhs.num);
137  }
138 
142  template <typename ValueType> friend Ratio operator/(Ratio lhs, const ValueType& rhs)
143  {
144  return Ratio(lhs.num, lhs.den * rhs);
145  }
146 
150  template <typename ValueType> friend ValueType operator/(ValueType lhs, const Ratio& rhs)
151  {
152  return muldiv(lhs, rhs.den, rhs.num);
153  }
154 };
155 
159 
The String class.
Definition: WString.h:137
ValType muldiv(const ValType &value, const NumDenType &num, const NumDenType &den)
Perform muldiv using unsigned integer types.
Definition: muldiv.h:110
A basic rational fraction, constexpr-compatible.
Definition: Rational.h:37
T num
Definition: Rational.h:38
T den
Definition: Rational.h:39
Class to simplify calculations of finite rationals at runtime.
Definition: Rational.h:65
friend Ratio operator/(Ratio lhs, const ValueType &rhs)
Evaluate value = Ratio / value
Definition: Rational.h:142
Ratio(T num, T den=1)
Definition: Rational.h:74
void set(T num, T den=1)
Set ratio and minimise.
Definition: Rational.h:94
friend Ratio operator/(const Ratio &lhs, const Ratio &rhs)
Evaluate ratio = ratio1 / ratio2 and minimise.
Definition: Rational.h:134
void set()
Method template to set ratio and minimise.
Definition: Rational.h:83
Ratio()=default
Ratio(const BasicRatio< T > &r)
Definition: Rational.h:68
friend ValueType operator*(const Ratio &lhs, const ValueType &rhs)
Evaluate value = ratio * value
Definition: Rational.h:126
friend Ratio operator*(const Ratio &lhs, const Ratio &rhs)
Evaluate ratio = ratio1 * ratio2 and minimise.
Definition: Rational.h:110
friend ValueType operator/(ValueType lhs, const Ratio &rhs)
Evaluate value = value / ratio
Definition: Rational.h:150
friend ValueType operator*(ValueType lhs, const Ratio &rhs)
Evaluate value = value * ratio
Definition: Rational.h:118