units
Use physical dimensions at compile-time or run-time.
dimval-test.cpp
Go to the documentation of this file.
1 /// @file test/dimval-test.cpp
2 /// @brief Test-cases for vnix::units::dimval.
3 /// @copyright 2019 Thomas E. Vaughan; all rights reserved.
4 /// @license BSD three-clause; see LICENSE.
5 
6 #include "../vnix/units.hpp"
7 #include "catch.hpp"
8 #include <sstream> // for ostringstream
9 
10 using namespace vnix;
11 using namespace vnix::units;
12 
13 
14 TEST_CASE("dimval's dimension is accessible.", "[dimval]") {
15  using namespace flt;
16  dyndim ddv = sqrt(m / s);
17 
18  REQUIRE(ddv.d(dim::off::off(0)) == dim::rat(1, 2));
19  REQUIRE(ddv.d(dim::off::off(2)) == dim::rat(-1, 2));
20 
21  speed sdv = m / s;
22 
23  REQUIRE(sdv.d(dim::off::off(0)) == dim::rat(1));
24  REQUIRE(sdv.d(dim::off::off(2)) == dim::rat(-1));
25 }
26 
27 
28 TEST_CASE("dimval's comparisons work.", "[dimval]") {
29  using namespace dbl;
30  dyndim ddv1 = sqrt(m / s);
31  auto sdv1 = ddv1;
32  dyndim ddv2 = 2.0_s;
33  dbl::time sdv2 = ddv2;
34 
35  REQUIRE(ddv1 == ddv1);
36  REQUIRE(ddv1 == sdv1);
37 
38  REQUIRE(ddv1 != 1.1 * ddv1);
39  REQUIRE(ddv1 != 1.1 * sdv1);
40 
41  REQUIRE(ddv1 < 1.1 * ddv1);
42  REQUIRE(ddv1 < 1.1 * sdv1);
43 
44  REQUIRE(ddv1 <= 1.1 * ddv1);
45  REQUIRE(ddv1 <= 1.1 * sdv1);
46 
47  REQUIRE(ddv1 > 0.9 * ddv1);
48  REQUIRE(ddv1 > 0.9 * sdv1);
49 
50  REQUIRE(ddv1 >= 0.9 * ddv1);
51  REQUIRE(ddv1 >= 0.9 * sdv1);
52 
53  REQUIRE_THROWS(ddv1 == ddv2);
54  REQUIRE_THROWS(ddv1 == sdv2);
55 
56  REQUIRE_THROWS(ddv1 != ddv2);
57  REQUIRE_THROWS(ddv1 != sdv2);
58 
59  REQUIRE_THROWS(ddv1 < ddv2);
60  REQUIRE_THROWS(ddv1 < sdv2);
61 
62  REQUIRE_THROWS(ddv1 <= ddv2);
63  REQUIRE_THROWS(ddv1 <= sdv2);
64 
65  REQUIRE_THROWS(ddv1 > ddv2);
66  REQUIRE_THROWS(ddv1 > sdv2);
67 
68  REQUIRE_THROWS(ddv1 >= ddv2);
69  REQUIRE_THROWS(ddv1 >= sdv2);
70 }
71 
72 
73 TEST_CASE("dimval's addition and subtraction work.", "[dimval]") {
74  using namespace ldbl;
75  dyndim ddv1 = sqrt(m / s);
76  dyndim ddv2 = 2 * s;
77  auto sdv1 = ddv1;
78  ldbl::time sdv2 = ddv2;
79 
80  REQUIRE(ddv1 + ddv1 == 2 * ddv1);
81  REQUIRE(ddv1 + sdv1 == 2 * ddv1);
82  REQUIRE(sdv1 + ddv1 == 2 * ddv1);
83  REQUIRE(sdv1 + sdv1 == 2 * ddv1);
84 
85  REQUIRE(ddv1 - ddv1 == 0 * ddv1);
86  REQUIRE(ddv1 - sdv1 == 0 * ddv1);
87  REQUIRE(sdv1 - ddv1 == 0 * ddv1);
88  REQUIRE(sdv1 - sdv1 == 0 * ddv1);
89 
90  REQUIRE_THROWS(ddv1 + ddv2);
91  REQUIRE_THROWS(ddv1 + sdv2);
92  REQUIRE_THROWS(sdv1 + ddv2);
93  REQUIRE_THROWS(sdv1 + sdv2);
94 
95  REQUIRE_THROWS(ddv1 - ddv2);
96  REQUIRE_THROWS(ddv1 - sdv2);
97  REQUIRE_THROWS(sdv1 - ddv2);
98  REQUIRE_THROWS(sdv1 - sdv2);
99 
100  REQUIRE((ddv1 += sdv1) == 2 * sdv1);
101  REQUIRE((ddv1 -= sdv1) == sdv1);
102  REQUIRE((sdv1 += ddv1) == 2 * ddv1);
103  REQUIRE((sdv1 -= ddv1) == ddv1);
104 
105  REQUIRE((ddv1 += dyndim(sdv1)) == 2 * sdv1);
106  REQUIRE((ddv1 -= dyndim(sdv1)) == sdv1);
107  REQUIRE((sdv2 += dbl::time(ddv2)) == 2 * ddv2);
108  REQUIRE((sdv2 -= flt::time(ddv2)) == ddv2);
109 
110  REQUIRE_THROWS(ddv1 += ddv2);
111  REQUIRE_THROWS(ddv1 += sdv2);
112  REQUIRE_THROWS(sdv1 += ddv2);
113  REQUIRE_THROWS(sdv1 += sdv2);
114 
115  REQUIRE_THROWS(ddv1 -= ddv2);
116  REQUIRE_THROWS(ddv1 -= sdv2);
117  REQUIRE_THROWS(sdv1 -= ddv2);
118  REQUIRE_THROWS(sdv1 -= sdv2);
119 }
120 
121 
122 TEST_CASE("dimval's multiplication and division work.", "[dimval]") {
123  using namespace flt;
124  dyndim ddv1 = 3.0_m;
125  dyndim ddv2 = 2.0_N;
126  length sdv1 = ddv1;
127  force sdv2 = ddv2;
128 
129  REQUIRE(ddv1 * ddv2 == 6 * J);
130  REQUIRE(ddv1 * sdv2 == 6 * J);
131  REQUIRE((ddv1 / ddv2 / m * N).to_number() == Approx(1.5));
132  REQUIRE((ddv1 / sdv2 / m * N).to_number() == Approx(1.5));
133 
134  REQUIRE(sdv1 * ddv2 == 6 * J);
135  REQUIRE(sdv1 * sdv2 == 6 * J);
136  REQUIRE((sdv1 / ddv2 / m * N).to_number() == Approx(1.5));
137  REQUIRE((sdv1 / sdv2 / m * N).to_number() == Approx(1.5));
138 
139  REQUIRE((ddv1 / ddv1).to_number() == 1);
140  REQUIRE((ddv1 / sdv1).to_number() == 1);
141  REQUIRE((sdv1 / sdv1).to_number() == 1);
142  REQUIRE((sdv1 / ddv1).to_number() == 1);
143 
144  REQUIRE((ddv2 * 0.5 / N).to_number() == 1);
145  REQUIRE((sdv2 / N).to_number() == 2);
146 
147  REQUIRE((ddv1 *= 2) == 6 * m);
148  REQUIRE((ddv1 /= 2) == 3 * m);
149 
150  REQUIRE((sdv1 *= 2) == 6 * m);
151  REQUIRE((sdv1 /= 2) == 3 * m);
152 }
153 
154 
155 TEST_CASE("pow and sqrt work for dimval.", "[dimval]") {
156  using namespace dbl;
157  dyndim ddv1 = 3 * m;
158  dyndim ddv2 = pow<2>(ddv1);
159 
160  using volume = decltype(m * m * m);
161  volume sdv1 = pow<3, 2>(ddv2);
162 
163  REQUIRE(ddv2 == 9 * m * m);
164  REQUIRE(sqrt(ddv2) == ddv1);
165  REQUIRE(sdv1 == 27 * m * m * m);
166  REQUIRE((pow<2, 3>(sdv1) / ddv2).to_number() == Approx(1));
167  REQUIRE((pow(sdv1, dim::rat(2, 3)) / ddv2).to_number() == Approx(1));
168  REQUIRE((sqrt(sdv1) / pow<3, 2>(ddv1)).to_number() == Approx(1));
169  std::cout << "sqrt(sdv1) = " << sqrt(sdv1) << std::endl;
170  std::cout << "pow(ddv1, {2,3}) = " << pow(ddv1, {3, 2}) << std::endl;
171  REQUIRE((sqrt(sdv1) / pow(ddv1, {3, 2})).to_number() == Approx(1));
172 }
173 
174 
175 TEST_CASE("Printing works for dimval.", "[dimval]") {
176  std::ostringstream oss;
177  using namespace ldbl;
178  oss << sqrt(1.0 / s) * m;
179  REQUIRE(oss.str() == "1 m s^[-1/2]");
180 }
181 
182 
183 TEST_CASE("Example in 'README.md' works.", "[dimval]") {
184  using namespace flt;
185  length d = 3.0_km;
186  flt::time t = 4.0_ms;
187  std::cout << "d=" << d << " t=" << t << std::endl;
188  auto v = d / t;
189  std::cout << v << std::endl;
190  std::ostringstream oss;
191  oss << v;
192  REQUIRE(oss.str() == "750000 m s^-1");
193 }
constexpr auto m
Constant-expression symbol for m.
Definition: units.hpp:2232
constexpr auto N
Constant-expression symbol for N.
Definition: units.hpp:2008
constexpr auto pow(dimval< T, B > const &v)
Raise dimensioned value to rational power.
Definition: dimval.hpp:448
constexpr auto sqrt(dimval< T, B > const &v)
Take the squre root of a dimensioned quantity.
Definition: dimval.hpp:436
Single-precision dimensions and units.
Definition: units.hpp:1663
constexpr auto m
Constant-expression symbol for m.
Definition: units.hpp:2789
constexpr auto operator/(OT const &d, dimval< T, B > const &v)
Invert dimensioned value by dividing it into number.
Definition: dimval.hpp:425
constexpr rational(stype n=0, stype d=1)
Initialize from numerator and denominator.
Definition: rational.hpp:47
constexpr auto s
Constant-expression symbol for s.
Definition: units.hpp:1825
constexpr T to_number() const
Convert to dimensionless number.
Definition: dimval.hpp:102
Double-precision dimensions and units.
Definition: units.hpp:2220
constexpr auto s
Constant-expression symbol for s.
Definition: units.hpp:2382
constexpr auto J
Constant-expression symbol for J.
Definition: units.hpp:2062
constexpr bool operator==(rational< NB1, DB1 > r1, rational< NB2, DB2 > r2)
Compare rationals for equality.
Definition: rational.hpp:128
Extended-precision dimensions and units.
Definition: units.hpp:2777
constexpr dim::rat d(dim::off off) const
Exponent for base at specified offset.
Definition: dimval.hpp:109
constexpr auto m
Constant-expression symbol for m.
Definition: units.hpp:1675
constexpr auto pow(dimval< T, B > const &v, dim::rat p)
Raise dimensioned value to rational power.
Definition: dimval.hpp:460
Thomas E. Vaughan&#39;s public software.
Definition: rational.hpp:13
Classes and functions supporting a model of physically dimensioned quantities.
constexpr auto s
Constant-expression symbol for s.
Definition: units.hpp:2939