units
Use physical dimensions at compile-time or run-time.
common-denom.hpp
Go to the documentation of this file.
1 /// @file vnix/rat/common-denom.hpp
2 /// @brief Definition of vnix::rat::common_denom.
3 /// @copyright 2019 Thomas E. Vaughan; all rights reserved.
4 /// @license BSD Three-Clause; see LICENSE.
5 
6 #ifndef VNIX_RAT_COMMON_DENOM_HPP
7 #define VNIX_RAT_COMMON_DENOM_HPP
8 
9 #include <vnix/gcd.hpp> // for gcd
10 #include <vnix/int-types.hpp> // for int_types
11 
12 namespace vnix {
13 namespace rat {
14 
15 
16 template <unsigned NB, unsigned DB> class rational;
17 
18 
19 template <unsigned NB1, unsigned DB1, unsigned NB2, unsigned DB2>
20 struct common_denom_params;
21 
22 
23 /// Compute least common denominator and corresponding numerators for the
24 /// comparison of a pair of rational numbers.
25 ///
26 /// @tparam NB1 Number of bits for numerator of first rational.
27 /// @tparam DB1 Number of bits for denominator of first rational.
28 /// @tparam NB2 Number of bits for numerator of second rational.
29 /// @tparam DB2 Number of bits for denominator of second rational.
30 /// @param r1 First input rational number.
31 /// @param r2 Second input rational number.
32 /// @return Instance of common_denom_pairs.
33 template <unsigned NB1, unsigned DB1, unsigned NB2, unsigned DB2>
34 constexpr common_denom_params<NB1, DB1, NB2, DB2>
35 common_denom(rational<NB1, DB1> r1, rational<NB2, DB2> r2) {
36  using cdp = common_denom_params<NB1, DB1, NB2, DB2>;
37  using UF1 = typename int_types<DB1>::UF;
38  using UF2 = typename int_types<DB2>::UF;
39  using gcd_t = gcd_promoted<UF1, UF2>;
40  gcd_t const g = gcd(r1.d(), r2.d()); // GCD of input denominators.
41  UF1 const d1g = r1.d() / g; // First input denominator divided by g.
42  UF2 const d2g = r2.d() / g; // Second input denominator divided by g.
43  return cdp(d1g * r2.d(), r1.n() * d2g, r2.n() * d1g);
44 };
45 
46 
47 /// Least common denominator (LCD) and corresponding numerators for the
48 /// comparison of a pair of rational numbers.
49 ///
50 /// An instance of common_denom_params is returned by common_denom().
51 ///
52 /// @tparam NB1 Number of bits for numerator of first rational.
53 /// @tparam DB1 Number of bits for denominator of first rational.
54 /// @tparam NB2 Number of bits for numerator of second rational.
55 /// @tparam DB2 Number of bits for denominator of second rational.
56 template <unsigned NB1, unsigned DB1, unsigned NB2, unsigned DB2>
57 struct common_denom_params {
58  /// Clamp an unsigned number at the maximum value of 64.
59  /// @param n Unsigned input.
60  /// @return Clamped output.
61  constexpr static unsigned clamp64(unsigned n) { return n > 64 ? 64 : n; }
62 
63  /// Number of bits required for storage of various items.
64  enum {
65  LCD_BITS = clamp64(DB1 + DB2), ///< For storage of LCD.
66  N1_BITS = clamp64(NB1 + DB2), ///< For storage of first numerator.
67  N2_BITS = clamp64(NB2 + DB1), ///< For storage of second numerator.
68  /// For use by client for storage of sum of numerators.
70  };
71 
72  using lcd_t = typename int_types<LCD_BITS>::UF; ///< Type of LCD.
73  using n1_t = typename int_types<N1_BITS>::SF; ///< Type of first numerator.
74  using n2_t = typename int_types<N2_BITS>::SF; ///< Type of secnd numerator.
75 
76  lcd_t const lcd; ///< LCD.
77  n1_t const n1; ///< First numerator.
78  n2_t const n2; ///< Second numerator.
79 
80 private:
81  using rat1 = rational<NB1, DB1>; ///< Type of first rational.
82  using rat2 = rational<NB2, DB2>; ///< Type of second rational.
83 
84  /// Allow common_denom() to call private constructor.
85  constexpr friend common_denom_params
87 
88  /// Construct from list of initializers.
89  /// @param ll Least common denominator.
90  /// @param nn1 First numerator.
91  /// @param nn2 Second numerator.
92  constexpr common_denom_params(lcd_t ll, n1_t nn1, n2_t nn2)
93  : lcd(ll), n1(nn1), n2(nn2) {}
94 };
95 
96 
97 } // namespace rat
98 } // namespace vnix
99 
100 #endif // ndef VNIX_RAT_COMMON_DENOM_HPP
constexpr common_denom_params< NB1, DB1, NB2, DB2 > common_denom(rational< NB1, DB1 > r1, rational< NB2, DB2 > r2)
Compute least common denominator and corresponding numerators for the comparison of a pair of rationa...
For use by client for storage of sum of numerators.
constexpr common_denom_params(lcd_t ll, n1_t nn1, n2_t nn2)
Construct from list of initializers.
Smallest integer types for holding certain number of bits.
Definition: int-types.hpp:21
static constexpr unsigned clamp64(unsigned n)
Clamp an unsigned number at the maximum value of 64.
friend std::ostream & operator<<(std::ostream &s, basic_dim d)
Print to to output stream.
Definition: dim.hpp:251
For storage of first numerator.
n1_t const n1
First numerator.
n2_t const n2
Second numerator.
For storage of second numerator.
Thomas E. Vaughan&#39;s public software.
Definition: rational.hpp:13
Model of a fixed-precision rational number.
Definition: rational.hpp:27
Classes and functions supporting a model of a fixed-precision rational number.
Definition: rational.hpp:17