Embedded Template Library 1.0
Loading...
Searching...
No Matches
ratio.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2016 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_RATIO_INCLUDED
32#define ETL_RATIO_INCLUDED
33
34#include "platform.h"
35#include "gcd.h"
36#include "static_assert.h"
37
38#include "type_traits.h"
39
40#include <stdint.h>
41
44
45namespace etl
46{
47 //***********************************************************************
49 //***********************************************************************
50 template <intmax_t Num, intmax_t Den = 1UL>
51 struct ratio
52 {
53 ETL_STATIC_ASSERT(Num != 0, "Numerator cannot be zero");
54 ETL_STATIC_ASSERT(Den != 0, "Denominator cannot be zero");
55
56 static ETL_CONSTANT intmax_t num = Num / etl::gcd_const<Num, Den>::value;
57 static ETL_CONSTANT intmax_t den = Den / etl::gcd_const<Num, Den>::value;
58
59 typedef etl::ratio<num, den> type;
60 };
61
62 template <intmax_t Num, intmax_t Den>
63 ETL_CONSTANT intmax_t ratio<Num, Den>::num;
64
65 template <intmax_t Num, intmax_t Den>
66 ETL_CONSTANT intmax_t ratio<Num, Den>::den;
67
68#if ETL_USING_CPP11
69 //***********************************************************************
71 //***********************************************************************
72 template <typename TRatio1, typename TRatio2>
73 using ratio_add = etl::ratio<(TRatio1::num * TRatio2::den) + (TRatio2::num * TRatio1::den), TRatio1::den * TRatio2::den>;
74
75 //***********************************************************************
77 //***********************************************************************
78 template <typename TRatio1, typename TRatio2>
79 using ratio_subtract = etl::ratio<(TRatio1::num * TRatio2::den) - (TRatio2::num * TRatio1::den), TRatio1::den * TRatio2::den>;
80
81 //***********************************************************************
83 //***********************************************************************
84 template <typename TRatio1, typename TRatio2>
86
87 //***********************************************************************
89 //***********************************************************************
90 template <typename TRatio1, typename TRatio2>
92#endif
93
94 //***********************************************************************
96 //***********************************************************************
97 template <typename TRatio1, typename TRatio2>
98 struct ratio_equal : etl::bool_constant<(TRatio1::num == TRatio2::num) && (TRatio1::den == TRatio2::den)>
99 {
100 };
101
102 //***********************************************************************
104 //***********************************************************************
105 template <typename TRatio1, typename TRatio2>
106 struct ratio_not_equal : etl::bool_constant<!etl::ratio_equal<TRatio1, TRatio2>::value>
107 {
108 };
109
110 //***********************************************************************
112 //***********************************************************************
113 template <typename TRatio1, typename TRatio2>
114 struct ratio_less : etl::bool_constant<(TRatio1::num * TRatio2::den) < (TRatio2::num * TRatio1::den)>
115 {
116 };
117
118 //***********************************************************************
120 //***********************************************************************
121 template <typename TRatio1, typename TRatio2>
122 struct ratio_less_equal : etl::bool_constant<!etl::ratio_less<TRatio2, TRatio1>::value>
123 {
124 };
125
126 //***********************************************************************
128 //***********************************************************************
129 template <typename TRatio1, typename TRatio2>
130 struct ratio_greater : etl::bool_constant<etl::ratio_less<TRatio2, TRatio1>::value>
131 {
132 };
133
134 //***********************************************************************
136 //***********************************************************************
137 template <typename TRatio1, typename TRatio2>
138 struct ratio_greater_equal : etl::bool_constant<!etl::ratio_less<TRatio1, TRatio2>::value>
139 {
140 };
141
142#if ETL_USING_CPP17
143 template <typename R1, typename R2>
144 inline constexpr bool ratio_equal_v = ratio_equal<R1, R2>::value;
145
146 template <typename R1, typename R2>
147 inline constexpr bool ratio_not_equal_v = ratio_not_equal<R1, R2>::value;
148
149 template <typename R1, typename R2>
150 inline constexpr bool ratio_less_v = ratio_less<R1, R2>::value;
151
152 template <typename R1, typename R2>
153 inline constexpr bool ratio_less_equal_v = ratio_less_equal<R1, R2>::value;
154
155 template <typename R1, typename R2>
156 inline constexpr bool ratio_greater_v = ratio_greater<R1, R2>::value;
157
158 template <typename R1, typename R2>
159 inline constexpr bool ratio_greater_equal_v = ratio_greater_equal<R1, R2>::value;
160#endif
161
162//***********************************************************************
164//***********************************************************************
165#if INT_MAX > INT32_MAX
166 // 2022 SI prefix (10^-30)
167 typedef ratio<1, 1000000000000000000LL * 1000000000000LL> quecto;
168 // 2022 SI prefix (10^-27)
169 typedef ratio<1, 1000000000000000000LL * 1000000000LL> ronto;
170 // 10^-24
171 typedef ratio<1, 1000000000000000000LL * 1000000LL> yocto;
172 // 10^-21
173 typedef ratio<1, 1000000000000000000LL * 1000LL> zepto;
174 typedef ratio<1, 1000000000000000000> atto;
175 typedef ratio<1, 1000000000000000> femto;
176 typedef ratio<1, 1000000000000> pico;
177#endif
178
179#if (INT_MAX >= INT32_MAX)
180 typedef ratio<1, 1000000000> nano;
181 typedef ratio<1, 1000000> micro;
182#endif
183
184#if (INT_MAX >= INT16_MAX)
185 typedef ratio<1, 1000> milli;
186 typedef ratio<1, 100> centi;
187 typedef ratio<1, 10> deci;
188 typedef ratio<10, 1> deca;
189 typedef ratio<100, 1> hecto;
190 typedef ratio<1000, 1> kilo;
191#endif
192
193#if (INT_MAX >= INT32_MAX)
194 typedef ratio<1000000, 1> mega;
195 typedef ratio<1000000000, 1> giga;
196#endif
197
198#if INT_MAX > INT32_MAX
199 typedef ratio<1000000000000, 1> tera;
200 typedef ratio<1000000000000000, 1> peta;
201 typedef ratio<1000000000000000000, 1> exa;
202 // 10^21
203 typedef ratio<1000000000000000000LL * 1000LL, 1> zetta;
204 // 10^24
205 typedef ratio<1000000000000000000LL * 1000000LL, 1> yotta;
206 // 2022 SI prefix (10^27)
207 typedef ratio<1000000000000000000LL * 1000000000LL, 1> ronna;
208 // 2022 SI prefix (10^30)
209 typedef ratio<1000000000000000000LL * 1000000000000LL, 1> quetta;
210#endif
211
213 typedef ratio<355, 113> ratio_pi;
214
216 typedef ratio<239, 169> ratio_root2;
217
219 typedef ratio<169, 239> ratio_1_over_root2;
220
222 typedef ratio<326, 120> ratio_e;
223
224#if ETL_USING_CPP11
225 namespace private_ratio
226 {
227 // Primary template for GCD calculation
228 template <typename T, T Value1, T Value2, bool = (Value2 == 0)>
229 struct ratio_gcd;
230
231 // Specialisation for the case when Value2 is not zero
232 template <typename T, T Value1, T Value2>
233 struct ratio_gcd<T, Value1, Value2, false>
234 {
235 static constexpr T value = ratio_gcd<T, Value2, Value1 % Value2>::value;
236 };
237
238 // Specialisation for the case when Value2 is zero
239 template <typename T, T Value1, T Value2>
240 struct ratio_gcd<T, Value1, Value2, true>
241 {
242 static constexpr T value = (Value1 < 0) ? -Value1 : Value1;
243 };
244
245 // Primary template for LCM calculation
246 template <typename T, T Value1, T Value2>
247 struct ratio_lcm
248 {
249 private:
250
251 static constexpr T product = ((Value1 * Value2) < 0) ? -(Value1 * Value2) : Value1 * Value2;
252
253 public:
254
255 static constexpr T value = product / ratio_gcd<T, Value1, Value2>::value;
256 };
257
258 template <typename R1>
259 struct ratio_reduce
260 {
261 private:
262
263 static ETL_CONSTEXPR11 intmax_t gcd = etl::private_ratio::ratio_gcd<intmax_t, R1::num, R1::den>::value;
264
265 public:
266
267 using type = ratio<R1::num / gcd, R1::den / gcd>;
268 };
269
270 template <typename R1, typename R2>
271 struct ratio_add
272 {
273 private:
274
275 static ETL_CONSTEXPR11 intmax_t lcm = etl::private_ratio::ratio_lcm<intmax_t, R1::den, R2::den>::value;
276
277 public:
278
279 using type = typename ratio_reduce< ratio<R1::num * lcm / R1::den + R2::num * lcm / R2::den, lcm>>::type;
280 };
281
282 template <typename R1, typename R2>
283 struct ratio_subtract
284 {
285 public:
286
287 using type = typename ratio_add<R1, ratio<-R2::num, R2::den>>::type;
288 };
289
290 template <typename R1, typename R2>
291 struct ratio_multiply
292 {
293 private:
294
295 static ETL_CONSTEXPR11 intmax_t gcd1 = etl::private_ratio::ratio_gcd<intmax_t, R1::num, R2::den>::value;
296 static ETL_CONSTEXPR11 intmax_t gcd2 = etl::private_ratio::ratio_gcd<intmax_t, R2::num, R1::den>::value;
297
298 public:
299
300 using type = ratio<(R1::num / gcd1) * (R2::num / gcd2), (R1::den / gcd2) * (R2::den / gcd1)>;
301 };
302
303 template <typename R1, typename R2>
304 struct ratio_divide
305 {
306 public:
307
308 using type = typename ratio_multiply<R1, ratio<R2::den, R2::num>>::type;
309 };
310 } // namespace private_ratio
311
312#endif
313} // namespace etl
314
315#endif
Definition absolute.h:40
Definition type_traits.h:97
ratio_equal
Definition ratio.h:99
ratio_not_equal
Definition ratio.h:107
ratio
Definition ratio.h:52