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 <numeric>
21 #include <muldiv.h>
22 #include <WString.h>
23 
38 template <typename T> struct BasicRatio {
39  T num;
40  T den;
41 
42  operator String() const
43  {
44  String s(num);
45  s += '/';
46  s += den;
47  return s;
48  }
49 };
50 
54 
66 template <typename T> struct Ratio : public BasicRatio<T> {
67  Ratio() = default;
68 
69  Ratio(const BasicRatio<T>& r)
70  {
71  this->num = r.num;
72  this->den = r.den;
73  }
74 
75  explicit Ratio(T num, T den = 1)
76  {
77  set(num, den);
78  }
79 
84  template <T num, T den> void set()
85  {
86  using R = std::ratio<num, den>;
87  this->num = R::num;
88  this->den = R::den;
89  }
90 
95  void set(T num, T den = 1)
96  {
97  // Note: Officially added std::numerics::gcd in C++17
98  auto g = std::gcd(num, den);
99  this->num = num / g;
100  this->den = den / g;
101  }
102 
103  template <typename ValueType> explicit operator ValueType() const
104  {
105  return muldiv(this->num, T(1), this->den);
106  }
107 
111  friend Ratio operator*(const Ratio& lhs, const Ratio& rhs)
112  {
113  return Ratio(lhs.num * rhs.num, lhs.den * rhs.den);
114  }
115 
119  template <typename ValueType> friend ValueType operator*(ValueType lhs, const Ratio& rhs)
120  {
121  return muldiv(lhs, rhs.num, rhs.den);
122  }
123 
127  template <typename ValueType> friend ValueType operator*(const Ratio& lhs, const ValueType& rhs)
128  {
129  return rhs * lhs;
130  }
131 
135  friend Ratio operator/(const Ratio& lhs, const Ratio& rhs)
136  {
137  return Ratio(lhs.num * rhs.den, lhs.den * rhs.num);
138  }
139 
143  template <typename ValueType> friend Ratio operator/(Ratio lhs, const ValueType& rhs)
144  {
145  return Ratio(lhs.num, lhs.den * rhs);
146  }
147 
151  template <typename ValueType> friend ValueType operator/(ValueType lhs, const Ratio& rhs)
152  {
153  return muldiv(lhs, rhs.den, rhs.num);
154  }
155 };
156 
160 
The String class.
Definition: WString.h:133
ValType muldiv(const ValType &value, const NumDenType &num, const NumDenType &den)
Perform muldiv using unsigned integer types.
Definition: muldiv.h:109
A basic rational fraction, constexpr-compatible.
Definition: Rational.h:38
T num
Definition: Rational.h:39
T den
Definition: Rational.h:40
Class to simplify calculations of finite rationals at runtime.
Definition: Rational.h:66
friend Ratio operator/(Ratio lhs, const ValueType &rhs)
Evaluate value = Ratio / value
Definition: Rational.h:143
Ratio(T num, T den=1)
Definition: Rational.h:75
void set(T num, T den=1)
Set ratio and minimise.
Definition: Rational.h:95
friend Ratio operator/(const Ratio &lhs, const Ratio &rhs)
Evaluate ratio = ratio1 / ratio2 and minimise.
Definition: Rational.h:135
void set()
Method template to set ratio and minimise.
Definition: Rational.h:84
Ratio()=default
Ratio(const BasicRatio< T > &r)
Definition: Rational.h:69
friend ValueType operator*(const Ratio &lhs, const ValueType &rhs)
Evaluate value = ratio * value
Definition: Rational.h:127
friend Ratio operator*(const Ratio &lhs, const Ratio &rhs)
Evaluate ratio = ratio1 * ratio2 and minimise.
Definition: Rational.h:111
friend ValueType operator/(ValueType lhs, const Ratio &rhs)
Evaluate value = value / ratio
Definition: Rational.h:151
friend ValueType operator*(ValueType lhs, const Ratio &rhs)
Evaluate value = value * ratio
Definition: Rational.h:119