LightLib
PROS library for VEX V5: EKF/MCL localization, RAMSETE path following, high-level chassis API
Loading...
Searching...
No Matches
RQuantity.hpp
Go to the documentation of this file.
1/*
2 * This code is a modified version of Benjamin Jurke's work in 2015. You can read his blog post
3 * here:
4 * https://benjaminjurke.com/content/articles/2015/compile-time-numerical-unit-dimension-checking/
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 */
10#pragma once
11
12#include <cmath>
13#include <ratio>
14
15namespace okapi {
16template <typename MassDim, typename LengthDim, typename TimeDim, typename AngleDim>
17class RQuantity {
18 public:
19 explicit constexpr RQuantity() : value(0.0) {
20 }
21
22 explicit constexpr RQuantity(double val) : value(val) {
23 }
24
25 explicit constexpr RQuantity(long double val) : value(static_cast<double>(val)) {
26 }
27
28 // The intrinsic operations for a quantity with a unit is addition and subtraction
29 constexpr RQuantity const &operator+=(const RQuantity &rhs) {
30 value += rhs.value;
31 return *this;
32 }
33
34 constexpr RQuantity const &operator-=(const RQuantity &rhs) {
35 value -= rhs.value;
36 return *this;
37 }
38
39 constexpr RQuantity operator-() {
40 return RQuantity(value * -1);
41 }
42
43 constexpr RQuantity const &operator*=(const double rhs) {
44 value *= rhs;
45 return *this;
46 }
47
48 constexpr RQuantity const &operator/=(const double rhs) {
49 value /= rhs;
50 return *this;
51 }
52
53 // Returns the value of the quantity in multiples of the specified unit
54 constexpr double convert(const RQuantity &rhs) const {
55 return value / rhs.value;
56 }
57
58 // returns the raw value of the quantity (should not be used)
59 constexpr double getValue() const {
60 return value;
61 }
62
66
68 std::ratio_divide<LengthDim, std::ratio<2>>,
69 std::ratio_divide<TimeDim, std::ratio<2>>,
70 std::ratio_divide<AngleDim, std::ratio<2>>>
71 sqrt() const {
73 std::ratio_divide<LengthDim, std::ratio<2>>,
74 std::ratio_divide<TimeDim, std::ratio<2>>,
75 std::ratio_divide<AngleDim, std::ratio<2>>>(std::sqrt(value));
76 }
77
78 private:
79 double value;
80};
81
82// Predefined (physical unit) quantity types:
83// ------------------------------------------
84#define QUANTITY_TYPE(_Mdim, _Ldim, _Tdim, _Adim, name) \
85 typedef RQuantity<std::ratio<_Mdim>, std::ratio<_Ldim>, std::ratio<_Tdim>, std::ratio<_Adim>> \
86 name;
87
88// Unitless
89QUANTITY_TYPE(0, 0, 0, 0, Number)
90constexpr Number number(1.0);
91
92// Standard arithmetic operators:
93// ------------------------------
94template <typename M, typename L, typename T, typename A>
95constexpr RQuantity<M, L, T, A> operator+(const RQuantity<M, L, T, A> &lhs,
96 const RQuantity<M, L, T, A> &rhs) {
97 return RQuantity<M, L, T, A>(lhs.getValue() + rhs.getValue());
98}
99template <typename M, typename L, typename T, typename A>
101 const RQuantity<M, L, T, A> &rhs) {
102 return RQuantity<M, L, T, A>(lhs.getValue() - rhs.getValue());
103}
104template <typename M1,
105 typename L1,
106 typename T1,
107 typename A1,
108 typename M2,
109 typename L2,
110 typename T2,
111 typename A2>
112constexpr RQuantity<std::ratio_add<M1, M2>,
113 std::ratio_add<L1, L2>,
114 std::ratio_add<T1, T2>,
115 std::ratio_add<A1, A2>>
118 std::ratio_add<L1, L2>,
119 std::ratio_add<T1, T2>,
120 std::ratio_add<A1, A2>>(lhs.getValue() * rhs.getValue());
121}
122template <typename M, typename L, typename T, typename A>
123constexpr RQuantity<M, L, T, A> operator*(const double &lhs, const RQuantity<M, L, T, A> &rhs) {
124 return RQuantity<M, L, T, A>(lhs * rhs.getValue());
125}
126template <typename M, typename L, typename T, typename A>
127constexpr RQuantity<M, L, T, A> operator*(const RQuantity<M, L, T, A> &lhs, const double &rhs) {
128 return RQuantity<M, L, T, A>(lhs.getValue() * rhs);
129}
130template <typename M1,
131 typename L1,
132 typename T1,
133 typename A1,
134 typename M2,
135 typename L2,
136 typename T2,
137 typename A2>
138constexpr RQuantity<std::ratio_subtract<M1, M2>,
139 std::ratio_subtract<L1, L2>,
140 std::ratio_subtract<T1, T2>,
141 std::ratio_subtract<A1, A2>>
144 std::ratio_subtract<L1, L2>,
145 std::ratio_subtract<T1, T2>,
146 std::ratio_subtract<A1, A2>>(lhs.getValue() / rhs.getValue());
147}
148template <typename M, typename L, typename T, typename A>
149constexpr RQuantity<std::ratio_subtract<std::ratio<0>, M>,
150 std::ratio_subtract<std::ratio<0>, L>,
151 std::ratio_subtract<std::ratio<0>, T>,
152 std::ratio_subtract<std::ratio<0>, A>>
153operator/(const double &x, const RQuantity<M, L, T, A> &rhs) {
155 std::ratio_subtract<std::ratio<0>, L>,
156 std::ratio_subtract<std::ratio<0>, T>,
157 std::ratio_subtract<std::ratio<0>, A>>(x / rhs.getValue());
158}
159template <typename M, typename L, typename T, typename A>
160constexpr RQuantity<M, L, T, A> operator/(const RQuantity<M, L, T, A> &rhs, const double &x) {
161 return RQuantity<M, L, T, A>(rhs.getValue() / x);
162}
163
164// Comparison operators for quantities:
165// ------------------------------------
166template <typename M, typename L, typename T, typename A>
167constexpr bool operator==(const RQuantity<M, L, T, A> &lhs, const RQuantity<M, L, T, A> &rhs) {
168 return (lhs.getValue() == rhs.getValue());
169}
170template <typename M, typename L, typename T, typename A>
171constexpr bool operator!=(const RQuantity<M, L, T, A> &lhs, const RQuantity<M, L, T, A> &rhs) {
172 return (lhs.getValue() != rhs.getValue());
173}
174template <typename M, typename L, typename T, typename A>
175constexpr bool operator<=(const RQuantity<M, L, T, A> &lhs, const RQuantity<M, L, T, A> &rhs) {
176 return (lhs.getValue() <= rhs.getValue());
177}
178template <typename M, typename L, typename T, typename A>
179constexpr bool operator>=(const RQuantity<M, L, T, A> &lhs, const RQuantity<M, L, T, A> &rhs) {
180 return (lhs.getValue() >= rhs.getValue());
181}
182template <typename M, typename L, typename T, typename A>
183constexpr bool operator<(const RQuantity<M, L, T, A> &lhs, const RQuantity<M, L, T, A> &rhs) {
184 return (lhs.getValue() < rhs.getValue());
185}
186template <typename M, typename L, typename T, typename A>
187constexpr bool operator>(const RQuantity<M, L, T, A> &lhs, const RQuantity<M, L, T, A> &rhs) {
188 return (lhs.getValue() > rhs.getValue());
189}
190
191// Common math functions:
192// ------------------------------
193
194template <typename M, typename L, typename T, typename A>
196 return RQuantity<M, L, T, A>(std::abs(rhs.getValue()));
197}
198
199template <typename R, typename M, typename L, typename T, typename A>
200constexpr RQuantity<std::ratio_multiply<M, R>,
201 std::ratio_multiply<L, R>,
202 std::ratio_multiply<T, R>,
203 std::ratio_multiply<A, R>>
206 std::ratio_multiply<L, R>,
207 std::ratio_multiply<T, R>,
208 std::ratio_multiply<A, R>>(std::pow(lhs.getValue(), double(R::num) / R::den));
209}
210
211template <int R, typename M, typename L, typename T, typename A>
212constexpr RQuantity<std::ratio_multiply<M, std::ratio<R>>,
213 std::ratio_multiply<L, std::ratio<R>>,
214 std::ratio_multiply<T, std::ratio<R>>,
215 std::ratio_multiply<A, std::ratio<R>>>
218 std::ratio_multiply<L, std::ratio<R>>,
219 std::ratio_multiply<T, std::ratio<R>>,
220 std::ratio_multiply<A, std::ratio<R>>>(std::pow(lhs.getValue(), R));
221}
222
223template <int R, typename M, typename L, typename T, typename A>
224constexpr RQuantity<std::ratio_divide<M, std::ratio<R>>,
225 std::ratio_divide<L, std::ratio<R>>,
226 std::ratio_divide<T, std::ratio<R>>,
227 std::ratio_divide<A, std::ratio<R>>>
230 std::ratio_divide<L, std::ratio<R>>,
231 std::ratio_divide<T, std::ratio<R>>,
232 std::ratio_divide<A, std::ratio<R>>>(std::pow(lhs.getValue(), 1.0 / R));
233}
234
235template <typename M, typename L, typename T, typename A>
236constexpr RQuantity<std::ratio_divide<M, std::ratio<2>>,
237 std::ratio_divide<L, std::ratio<2>>,
238 std::ratio_divide<T, std::ratio<2>>,
239 std::ratio_divide<A, std::ratio<2>>>
242 std::ratio_divide<L, std::ratio<2>>,
243 std::ratio_divide<T, std::ratio<2>>,
244 std::ratio_divide<A, std::ratio<2>>>(std::sqrt(rhs.getValue()));
245}
246
247template <typename M, typename L, typename T, typename A>
248constexpr RQuantity<std::ratio_divide<M, std::ratio<3>>,
249 std::ratio_divide<L, std::ratio<3>>,
250 std::ratio_divide<T, std::ratio<3>>,
251 std::ratio_divide<A, std::ratio<3>>>
254 std::ratio_divide<L, std::ratio<3>>,
255 std::ratio_divide<T, std::ratio<3>>,
256 std::ratio_divide<A, std::ratio<3>>>(std::cbrt(rhs.getValue()));
257}
258
259template <typename M, typename L, typename T, typename A>
260constexpr RQuantity<std::ratio_multiply<M, std::ratio<2>>,
261 std::ratio_multiply<L, std::ratio<2>>,
262 std::ratio_multiply<T, std::ratio<2>>,
263 std::ratio_multiply<A, std::ratio<2>>>
266 std::ratio_multiply<L, std::ratio<2>>,
267 std::ratio_multiply<T, std::ratio<2>>,
268 std::ratio_multiply<A, std::ratio<2>>>(std::pow(rhs.getValue(), 2));
269}
270
271template <typename M, typename L, typename T, typename A>
272constexpr RQuantity<std::ratio_multiply<M, std::ratio<3>>,
273 std::ratio_multiply<L, std::ratio<3>>,
274 std::ratio_multiply<T, std::ratio<3>>,
275 std::ratio_multiply<A, std::ratio<3>>>
278 std::ratio_multiply<L, std::ratio<3>>,
279 std::ratio_multiply<T, std::ratio<3>>,
280 std::ratio_multiply<A, std::ratio<3>>>(std::pow(rhs.getValue(), 3));
281}
282
283template <typename M, typename L, typename T, typename A>
285 const RQuantity<M, L, T, A> &rhs) {
286 return RQuantity<M, L, T, A>(std::hypot(lhs.getValue(), rhs.getValue()));
287}
288
289template <typename M, typename L, typename T, typename A>
291 const RQuantity<M, L, T, A> &rhs) {
292 return RQuantity<M, L, T, A>(std::fmod(lhs.getValue(), rhs.getValue()));
293}
294
295template <typename M1,
296 typename L1,
297 typename T1,
298 typename A1,
299 typename M2,
300 typename L2,
301 typename T2,
302 typename A2>
304 const RQuantity<M2, L2, T2, A2> &rhs) {
305 return RQuantity<M1, L1, T1, A1>(std::copysign(lhs.getValue(), rhs.getValue()));
306}
307
308template <typename M, typename L, typename T, typename A>
310 const RQuantity<M, L, T, A> &rhs) {
311 return RQuantity<M, L, T, A>(std::ceil(lhs.getValue() / rhs.getValue()) * rhs.getValue());
312}
313
314template <typename M, typename L, typename T, typename A>
316 const RQuantity<M, L, T, A> &rhs) {
317 return RQuantity<M, L, T, A>(std::floor(lhs.getValue() / rhs.getValue()) * rhs.getValue());
318}
319
320template <typename M, typename L, typename T, typename A>
322 const RQuantity<M, L, T, A> &rhs) {
323 return RQuantity<M, L, T, A>(std::trunc(lhs.getValue() / rhs.getValue()) * rhs.getValue());
324}
325
326template <typename M, typename L, typename T, typename A>
328 const RQuantity<M, L, T, A> &rhs) {
329 return RQuantity<M, L, T, A>(std::round(lhs.getValue() / rhs.getValue()) * rhs.getValue());
330}
331
332// Common trig functions:
333// ------------------------------
334
335constexpr Number
336sin(const RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>> &rhs) {
337 return Number(std::sin(rhs.getValue()));
338}
339
340constexpr Number
341cos(const RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>> &rhs) {
342 return Number(std::cos(rhs.getValue()));
343}
344
345constexpr Number
346tan(const RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>> &rhs) {
347 return Number(std::tan(rhs.getValue()));
348}
349
350constexpr RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>
351asin(const Number &rhs) {
352 return RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>(
353 std::asin(rhs.getValue()));
354}
355
356constexpr RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>
357acos(const Number &rhs) {
358 return RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>(
359 std::acos(rhs.getValue()));
360}
361
362constexpr RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>
363atan(const Number &rhs) {
364 return RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>(
365 std::atan(rhs.getValue()));
366}
367
368constexpr Number
369sinh(const RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>> &rhs) {
370 return Number(std::sinh(rhs.getValue()));
371}
372
373constexpr Number
374cosh(const RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>> &rhs) {
375 return Number(std::cosh(rhs.getValue()));
376}
377
378constexpr Number
379tanh(const RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>> &rhs) {
380 return Number(std::tanh(rhs.getValue()));
381}
382
383constexpr RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>
384asinh(const Number &rhs) {
385 return RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>(
386 std::asinh(rhs.getValue()));
387}
388
389constexpr RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>
390acosh(const Number &rhs) {
391 return RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>(
392 std::acosh(rhs.getValue()));
393}
394
395constexpr RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>
396atanh(const Number &rhs) {
397 return RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>(
398 std::atanh(rhs.getValue()));
399}
400
401template <typename M, typename L, typename T, typename A>
402constexpr RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>
404 return RQuantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>>(
405 std::atan2(lhs.getValue(), rhs.getValue()));
406}
407
408inline namespace literals {
409constexpr long double operator"" _pi(long double x) {
410 return static_cast<double>(x) * 3.1415926535897932384626433832795;
411}
412constexpr long double operator"" _pi(unsigned long long int x) {
413 return static_cast<double>(x) * 3.1415926535897932384626433832795;
414}
415} // namespace literals
416} // namespace okapi
417
418// Conversion macro, which utilizes the string literals
419#define ConvertTo(_x, _y) (_x).convert(1.0_##_y)
#define QUANTITY_TYPE(_Mdim, _Ldim, _Tdim, _Adim, name)
Definition RQuantity.hpp:84
constexpr RQuantity()
Definition RQuantity.hpp:19
constexpr RQuantity const & operator+=(const RQuantity &rhs)
Definition RQuantity.hpp:29
constexpr RQuantity< MassDim, LengthDim, TimeDim, AngleDim > abs() const
Definition RQuantity.hpp:63
constexpr RQuantity operator-()
Definition RQuantity.hpp:39
constexpr RQuantity const & operator*=(const double rhs)
Definition RQuantity.hpp:43
constexpr RQuantity< std::ratio_divide< MassDim, std::ratio< 2 > >, std::ratio_divide< LengthDim, std::ratio< 2 > >, std::ratio_divide< TimeDim, std::ratio< 2 > >, std::ratio_divide< AngleDim, std::ratio< 2 > > > sqrt() const
Definition RQuantity.hpp:71
constexpr RQuantity(double val)
Definition RQuantity.hpp:22
constexpr double convert(const RQuantity &rhs) const
Definition RQuantity.hpp:54
constexpr RQuantity const & operator-=(const RQuantity &rhs)
Definition RQuantity.hpp:34
constexpr double getValue() const
Definition RQuantity.hpp:59
constexpr RQuantity(long double val)
Definition RQuantity.hpp:25
constexpr RQuantity const & operator/=(const double rhs)
Definition RQuantity.hpp:48
constexpr RQuantity< std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > acosh(const Number &rhs)
constexpr RQuantity< std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > atan(const Number &rhs)
constexpr Number number(1.0)
constexpr bool operator!=(const RQuantity< M, L, T, A > &lhs, const RQuantity< M, L, T, A > &rhs)
constexpr RQuantity< std::ratio_multiply< M, std::ratio< 3 > >, std::ratio_multiply< L, std::ratio< 3 > >, std::ratio_multiply< T, std::ratio< 3 > >, std::ratio_multiply< A, std::ratio< 3 > > > cube(const RQuantity< M, L, T, A > &rhs)
constexpr RQuantity< std::ratio_divide< M, std::ratio< 3 > >, std::ratio_divide< L, std::ratio< 3 > >, std::ratio_divide< T, std::ratio< 3 > >, std::ratio_divide< A, std::ratio< 3 > > > cbrt(const RQuantity< M, L, T, A > &rhs)
constexpr RQuantity< std::ratio_subtract< M1, M2 >, std::ratio_subtract< L1, L2 >, std::ratio_subtract< T1, T2 >, std::ratio_subtract< A1, A2 > > operator/(const RQuantity< M1, L1, T1, A1 > &lhs, const RQuantity< M2, L2, T2, A2 > &rhs)
constexpr RQuantity< std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > asinh(const Number &rhs)
constexpr RQuantity< std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > acos(const Number &rhs)
constexpr Number tanh(const RQuantity< std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > &rhs)
constexpr bool operator==(const RQuantity< M, L, T, A > &lhs, const RQuantity< M, L, T, A > &rhs)
constexpr Number cos(const RQuantity< std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > &rhs)
constexpr RQuantity< M, L, T, A > round(const RQuantity< M, L, T, A > &lhs, const RQuantity< M, L, T, A > &rhs)
AbstractMotor::GearsetRatioPair operator*(AbstractMotor::gearset gearset, double ratio)
constexpr RQuantity< M, L, T, A > abs(const RQuantity< M, L, T, A > &rhs)
constexpr RQuantity< std::ratio_divide< M, std::ratio< 2 > >, std::ratio_divide< L, std::ratio< 2 > >, std::ratio_divide< T, std::ratio< 2 > >, std::ratio_divide< A, std::ratio< 2 > > > sqrt(const RQuantity< M, L, T, A > &rhs)
constexpr bool operator>(const RQuantity< M, L, T, A > &lhs, const RQuantity< M, L, T, A > &rhs)
constexpr RQuantity< std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > atanh(const Number &rhs)
constexpr RQuantity< M, L, T, A > hypot(const RQuantity< M, L, T, A > &lhs, const RQuantity< M, L, T, A > &rhs)
constexpr RQuantity< std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > asin(const Number &rhs)
constexpr RQuantity< std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > atan2(const RQuantity< M, L, T, A > &lhs, const RQuantity< M, L, T, A > &rhs)
constexpr RQuantity< M, L, T, A > operator-(const RQuantity< M, L, T, A > &lhs, const RQuantity< M, L, T, A > &rhs)
constexpr RQuantity< std::ratio_multiply< M, R >, std::ratio_multiply< L, R >, std::ratio_multiply< T, R >, std::ratio_multiply< A, R > > pow(const RQuantity< M, L, T, A > &lhs)
constexpr Number sin(const RQuantity< std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > &rhs)
constexpr Number sinh(const RQuantity< std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > &rhs)
constexpr RQuantity< M, L, T, A > ceil(const RQuantity< M, L, T, A > &lhs, const RQuantity< M, L, T, A > &rhs)
constexpr bool operator<(const RQuantity< M, L, T, A > &lhs, const RQuantity< M, L, T, A > &rhs)
@ x
Roll Axis.
constexpr RQuantity< std::ratio_multiply< M, std::ratio< 2 > >, std::ratio_multiply< L, std::ratio< 2 > >, std::ratio_multiply< T, std::ratio< 2 > >, std::ratio_multiply< A, std::ratio< 2 > > > square(const RQuantity< M, L, T, A > &rhs)
constexpr RQuantity< std::ratio_divide< M, std::ratio< R > >, std::ratio_divide< L, std::ratio< R > >, std::ratio_divide< T, std::ratio< R > >, std::ratio_divide< A, std::ratio< R > > > root(const RQuantity< M, L, T, A > &lhs)
constexpr Number cosh(const RQuantity< std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > &rhs)
constexpr bool operator>=(const RQuantity< M, L, T, A > &lhs, const RQuantity< M, L, T, A > &rhs)
constexpr bool operator<=(const RQuantity< M, L, T, A > &lhs, const RQuantity< M, L, T, A > &rhs)
constexpr Number tan(const RQuantity< std::ratio< 0 >, std::ratio< 0 >, std::ratio< 0 >, std::ratio< 1 > > &rhs)
constexpr RQuantity< M, L, T, A > trunc(const RQuantity< M, L, T, A > &lhs, const RQuantity< M, L, T, A > &rhs)
constexpr RQuantity< M, L, T, A > floor(const RQuantity< M, L, T, A > &lhs, const RQuantity< M, L, T, A > &rhs)
constexpr RQuantity< M1, L1, T1, A1 > copysign(const RQuantity< M1, L1, T1, A1 > &lhs, const RQuantity< M2, L2, T2, A2 > &rhs)
constexpr RQuantity< M, L, T, A > mod(const RQuantity< M, L, T, A > &lhs, const RQuantity< M, L, T, A > &rhs)