]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Units - A C++ library for zero-overhead dimensional analysis and |
2 | // unit/quantity manipulation and conversion | |
3 | // | |
4 | // Copyright (C) 2014 Erik Erlandson | |
5 | // | |
6 | // Distributed under the Boost Software License, Version 1.0. (See | |
7 | // accompanying file LICENSE_1_0.txt or copy at | |
8 | // http://www.boost.org/LICENSE_1_0.txt) | |
9 | ||
10 | #include <iostream> | |
11 | #include <sstream> | |
12 | ||
13 | #include <boost/units/quantity.hpp> | |
14 | #include <boost/units/conversion.hpp> | |
15 | #include <boost/units/io.hpp> | |
16 | ||
17 | #include <boost/units/systems/si/prefixes.hpp> | |
18 | #include <boost/units/systems/si/time.hpp> | |
19 | ||
20 | // All information systems definitions | |
21 | #include <boost/units/systems/information.hpp> | |
22 | ||
23 | using std::cout; | |
24 | using std::cerr; | |
25 | using std::endl; | |
26 | using std::stringstream; | |
27 | ||
28 | namespace bu = boost::units; | |
29 | namespace si = boost::units::si; | |
30 | ||
31 | using bu::quantity; | |
32 | ||
33 | using bu::information::bit_base_unit; | |
34 | using bu::information::byte_base_unit; | |
35 | using bu::information::nat_base_unit; | |
36 | using bu::information::hartley_base_unit; | |
37 | using bu::information::shannon_base_unit; | |
38 | ||
39 | ||
1e59de90 | 40 | #include "test_close.hpp" |
7c673cae FG |
41 | |
42 | #include <boost/multiprecision/cpp_int.hpp> | |
43 | ||
44 | const double close_fraction = 0.0000001; | |
45 | ||
46 | // checks that cf(u2,u1) == expected | |
47 | // also checks invariant property that cf(u2,u1) * cf(u1,u2) == 1 | |
48 | #define CHECK_DIRECT_CF(u1, u2, expected) \ | |
1e59de90 TL |
49 | BOOST_UNITS_TEST_CLOSE(bu::conversion_factor((u2), (u1)), (expected), close_fraction); \ |
50 | BOOST_UNITS_TEST_CLOSE(bu::conversion_factor((u2), (u1)) * bu::conversion_factor((u1), (u2)), 1.0, close_fraction); | |
7c673cae FG |
51 | |
52 | // check transitive conversion factors | |
53 | // invariant: cf(u1,u3) = cf(u1,u2)*cf(u2,u3) | |
54 | #define CHECK_TRANSITIVE_CF(u1, u2, u3) { \ | |
11fdf7f2 TL |
55 | BOOST_CONSTEXPR_OR_CONST double cf12 = bu::conversion_factor((u2), (u1)) ; \ |
56 | BOOST_CONSTEXPR_OR_CONST double cf23 = bu::conversion_factor((u3), (u2)) ; \ | |
57 | BOOST_CONSTEXPR_OR_CONST double cf13 = bu::conversion_factor((u3), (u1)) ; \ | |
1e59de90 | 58 | BOOST_UNITS_TEST_CLOSE(cf13, cf12*cf23, close_fraction); \ |
11fdf7f2 TL |
59 | BOOST_CONSTEXPR_OR_CONST double cf32 = bu::conversion_factor((u2), (u3)) ; \ |
60 | BOOST_CONSTEXPR_OR_CONST double cf21 = bu::conversion_factor((u1), (u2)) ; \ | |
61 | BOOST_CONSTEXPR_OR_CONST double cf31 = bu::conversion_factor((u1), (u3)) ; \ | |
1e59de90 | 62 | BOOST_UNITS_TEST_CLOSE(cf31, cf32*cf21, close_fraction); \ |
7c673cae FG |
63 | } |
64 | ||
65 | ||
1e59de90 | 66 | void test_cf_bit_byte() { |
7c673cae FG |
67 | CHECK_DIRECT_CF(bit_base_unit::unit_type(), byte_base_unit::unit_type(), 8.0); |
68 | } | |
69 | ||
1e59de90 | 70 | void test_cf_bit_nat() { |
7c673cae FG |
71 | CHECK_DIRECT_CF(bit_base_unit::unit_type(), nat_base_unit::unit_type(), 1.442695040888964); |
72 | } | |
73 | ||
1e59de90 | 74 | void test_cf_bit_hartley() { |
7c673cae FG |
75 | CHECK_DIRECT_CF(bit_base_unit::unit_type(), hartley_base_unit::unit_type(), 3.321928094887363); |
76 | } | |
77 | ||
1e59de90 | 78 | void test_cf_bit_shannon() { |
7c673cae FG |
79 | CHECK_DIRECT_CF(bit_base_unit::unit_type(), shannon_base_unit::unit_type(), 1.0); |
80 | } | |
81 | ||
82 | ///////////////////////////////////////////////////////////////////////////////////// | |
83 | // spot-check that these are automatically transitive, thru central "hub unit" bit: | |
84 | // basic pattern is to test invariant property: cf(c,a) = cf(c,b)*cf(b,a) | |
85 | ||
1e59de90 | 86 | void test_transitive_byte_nat() { |
7c673cae FG |
87 | CHECK_TRANSITIVE_CF(byte_base_unit::unit_type(), bit_base_unit::unit_type(), nat_base_unit::unit_type()); |
88 | } | |
1e59de90 | 89 | void test_transitive_nat_hartley() { |
7c673cae FG |
90 | CHECK_TRANSITIVE_CF(nat_base_unit::unit_type(), bit_base_unit::unit_type(), hartley_base_unit::unit_type()); |
91 | } | |
1e59de90 | 92 | void test_transitive_hartley_shannon() { |
7c673cae FG |
93 | CHECK_TRANSITIVE_CF(hartley_base_unit::unit_type(), bit_base_unit::unit_type(), shannon_base_unit::unit_type()); |
94 | } | |
1e59de90 | 95 | void test_transitive_shannon_byte() { |
7c673cae FG |
96 | CHECK_TRANSITIVE_CF(shannon_base_unit::unit_type(), bit_base_unit::unit_type(), byte_base_unit::unit_type()); |
97 | } | |
98 | ||
99 | // test transitive factors, none of which are bit, just for good measure | |
1e59de90 | 100 | void test_transitive_byte_nat_hartley() { |
7c673cae FG |
101 | CHECK_TRANSITIVE_CF(byte_base_unit::unit_type(), nat_base_unit::unit_type(), hartley_base_unit::unit_type()); |
102 | } | |
103 | ||
1e59de90 | 104 | void test_byte_quantity_is_default() { |
7c673cae | 105 | using namespace bu::information; |
20effc67 | 106 | using bu::information::byte; |
11fdf7f2 | 107 | BOOST_CONSTEXPR_OR_CONST quantity<info, double> qd(2 * byte); |
1e59de90 | 108 | BOOST_TEST_EQ(qd.value(), double(2)); |
11fdf7f2 | 109 | BOOST_CONSTEXPR_OR_CONST quantity<info, long> ql(2 * byte); |
1e59de90 | 110 | BOOST_TEST_EQ(ql.value(), long(2)); |
7c673cae FG |
111 | } |
112 | ||
1e59de90 | 113 | void test_byte_quantity_explicit() { |
7c673cae | 114 | using namespace bu::information; |
20effc67 | 115 | using bu::information::byte; |
11fdf7f2 | 116 | BOOST_CONSTEXPR_OR_CONST quantity<hu::byte::info, double> qd(2 * byte); |
1e59de90 | 117 | BOOST_TEST_EQ(qd.value(), double(2)); |
11fdf7f2 | 118 | BOOST_CONSTEXPR_OR_CONST quantity<hu::byte::info, long> ql(2 * byte); |
1e59de90 | 119 | BOOST_TEST_EQ(ql.value(), long(2)); |
7c673cae FG |
120 | } |
121 | ||
1e59de90 | 122 | void test_bit_quantity() { |
7c673cae | 123 | using namespace bu::information; |
11fdf7f2 | 124 | BOOST_CONSTEXPR_OR_CONST quantity<hu::bit::info, double> qd(2 * bit); |
1e59de90 | 125 | BOOST_TEST_EQ(qd.value(), double(2)); |
11fdf7f2 | 126 | BOOST_CONSTEXPR_OR_CONST quantity<hu::bit::info, long> ql(2 * bit); |
1e59de90 | 127 | BOOST_TEST_EQ(ql.value(), long(2)); |
7c673cae FG |
128 | } |
129 | ||
1e59de90 | 130 | void test_nat_quantity() { |
7c673cae | 131 | using namespace bu::information; |
11fdf7f2 | 132 | BOOST_CONSTEXPR_OR_CONST quantity<hu::nat::info, double> qd(2 * nat); |
1e59de90 | 133 | BOOST_TEST_EQ(qd.value(), double(2)); |
11fdf7f2 | 134 | BOOST_CONSTEXPR_OR_CONST quantity<hu::nat::info, long> ql(2 * nat); |
1e59de90 | 135 | BOOST_TEST_EQ(ql.value(), long(2)); |
7c673cae FG |
136 | } |
137 | ||
1e59de90 | 138 | void test_hartley_quantity() { |
7c673cae | 139 | using namespace bu::information; |
11fdf7f2 | 140 | BOOST_CONSTEXPR_OR_CONST quantity<hu::hartley::info, double> qd(2 * hartley); |
1e59de90 | 141 | BOOST_TEST_EQ(qd.value(), double(2)); |
11fdf7f2 | 142 | BOOST_CONSTEXPR_OR_CONST quantity<hu::hartley::info, long> ql(2 * hartley); |
1e59de90 | 143 | BOOST_TEST_EQ(ql.value(), long(2)); |
7c673cae FG |
144 | } |
145 | ||
1e59de90 | 146 | void test_shannon_quantity() { |
7c673cae | 147 | using namespace bu::information; |
11fdf7f2 | 148 | BOOST_CONSTEXPR_OR_CONST quantity<hu::shannon::info, double> qd(2 * shannon); |
1e59de90 | 149 | BOOST_TEST_EQ(qd.value(), double(2)); |
11fdf7f2 | 150 | BOOST_CONSTEXPR_OR_CONST quantity<hu::shannon::info, long> ql(2 * shannon); |
1e59de90 | 151 | BOOST_TEST_EQ(ql.value(), long(2)); |
7c673cae FG |
152 | } |
153 | ||
1e59de90 | 154 | void test_mixed_hu() { |
7c673cae | 155 | using namespace bu::information; |
11fdf7f2 | 156 | BOOST_CONSTEXPR_OR_CONST double cf = 0.001; |
1e59de90 TL |
157 | BOOST_UNITS_TEST_CLOSE((quantity<hu::bit::info>(1.0 * bits)).value(), 1.0, cf); |
158 | BOOST_UNITS_TEST_CLOSE((quantity<hu::byte::info>(1.0 * bits)).value(), 1.0/8.0, cf); | |
159 | BOOST_UNITS_TEST_CLOSE((quantity<hu::nat::info>(1.0 * bits)).value(), 0.69315, cf); | |
160 | BOOST_UNITS_TEST_CLOSE((quantity<hu::hartley::info>(1.0 * bits)).value(), 0.30102, cf); | |
161 | BOOST_UNITS_TEST_CLOSE((quantity<hu::shannon::info>(1.0 * bits)).value(), 1.0, cf); | |
7c673cae FG |
162 | } |
163 | ||
1e59de90 | 164 | void test_info_prefixes() { |
7c673cae | 165 | using namespace bu::information; |
20effc67 | 166 | using bu::information::byte; |
11fdf7f2 | 167 | BOOST_CONSTEXPR_OR_CONST quantity<info, long long> q10(1LL * kibi * byte); |
1e59de90 | 168 | BOOST_TEST_EQ(q10.value(), 1024LL); |
7c673cae | 169 | |
11fdf7f2 | 170 | BOOST_CONSTEXPR_OR_CONST quantity<info, long long> q20(1LL * mebi * byte); |
1e59de90 | 171 | BOOST_TEST_EQ(q20.value(), 1048576LL); |
7c673cae | 172 | |
11fdf7f2 | 173 | BOOST_CONSTEXPR_OR_CONST quantity<info, long long> q30(1LL * gibi * byte); |
1e59de90 | 174 | BOOST_TEST_EQ(q30.value(), 1073741824LL); |
7c673cae | 175 | |
11fdf7f2 | 176 | BOOST_CONSTEXPR_OR_CONST quantity<info, long long> q40(1LL * tebi * byte); |
1e59de90 | 177 | BOOST_TEST_EQ(q40.value(), 1099511627776LL); |
7c673cae | 178 | |
11fdf7f2 | 179 | BOOST_CONSTEXPR_OR_CONST quantity<info, long long> q50(1LL * pebi * byte); |
1e59de90 | 180 | BOOST_TEST_EQ(q50.value(), 1125899906842624LL); |
7c673cae | 181 | |
11fdf7f2 | 182 | BOOST_CONSTEXPR_OR_CONST quantity<info, long long> q60(1LL * exbi * byte); |
1e59de90 | 183 | BOOST_TEST_EQ(q60.value(), 1152921504606846976LL); |
7c673cae FG |
184 | |
185 | using boost::multiprecision::int128_t; | |
186 | ||
11fdf7f2 | 187 | const quantity<info, int128_t> q70(1LL * zebi * byte); |
1e59de90 | 188 | BOOST_TEST_EQ(q70.value(), int128_t("1180591620717411303424")); |
7c673cae | 189 | |
11fdf7f2 | 190 | const quantity<info, int128_t> q80(1LL * yobi * byte); |
1e59de90 | 191 | BOOST_TEST_EQ(q80.value(), int128_t("1208925819614629174706176")); |
7c673cae FG |
192 | |
193 | // sanity check: si prefixes should also operate | |
11fdf7f2 | 194 | BOOST_CONSTEXPR_OR_CONST quantity<info, long long> q1e3(1LL * si::kilo * byte); |
1e59de90 | 195 | BOOST_TEST_EQ(q1e3.value(), 1000LL); |
7c673cae | 196 | |
11fdf7f2 | 197 | BOOST_CONSTEXPR_OR_CONST quantity<info, long long> q1e6(1LL * si::mega * byte); |
1e59de90 | 198 | BOOST_TEST_EQ(q1e6.value(), 1000000LL); |
7c673cae FG |
199 | } |
200 | ||
1e59de90 | 201 | void test_unit_constant_io() { |
7c673cae FG |
202 | using namespace bu::information; |
203 | ||
204 | std::stringstream ss; | |
205 | ss << bu::symbol_format << bytes; | |
1e59de90 | 206 | BOOST_TEST_EQ(ss.str(), "B"); |
7c673cae FG |
207 | |
208 | ss.str(""); | |
209 | ss << bu::name_format << bytes; | |
1e59de90 | 210 | BOOST_TEST_EQ(ss.str(), "byte"); |
7c673cae FG |
211 | |
212 | ss.str(""); | |
213 | ss << bu::symbol_format << bits; | |
1e59de90 | 214 | BOOST_TEST_EQ(ss.str(), "b"); |
7c673cae FG |
215 | |
216 | ss.str(""); | |
217 | ss << bu::name_format << bits; | |
1e59de90 | 218 | BOOST_TEST_EQ(ss.str(), "bit"); |
7c673cae FG |
219 | |
220 | ss.str(""); | |
221 | ss << bu::symbol_format << nats; | |
1e59de90 | 222 | BOOST_TEST_EQ(ss.str(), "nat"); |
7c673cae FG |
223 | |
224 | ss.str(""); | |
225 | ss << bu::name_format << nats; | |
1e59de90 | 226 | BOOST_TEST_EQ(ss.str(), "nat"); |
7c673cae FG |
227 | |
228 | ss.str(""); | |
229 | ss << bu::symbol_format << hartleys; | |
1e59de90 | 230 | BOOST_TEST_EQ(ss.str(), "Hart"); |
7c673cae FG |
231 | |
232 | ss.str(""); | |
233 | ss << bu::name_format << hartleys; | |
1e59de90 | 234 | BOOST_TEST_EQ(ss.str(), "hartley"); |
7c673cae FG |
235 | |
236 | ss.str(""); | |
237 | ss << bu::symbol_format << shannons; | |
1e59de90 | 238 | BOOST_TEST_EQ(ss.str(), "Sh"); |
7c673cae FG |
239 | |
240 | ss.str(""); | |
241 | ss << bu::name_format << shannons; | |
1e59de90 TL |
242 | BOOST_TEST_EQ(ss.str(), "shannon"); |
243 | } | |
244 | ||
245 | int main() | |
246 | { | |
247 | test_cf_bit_byte(); | |
248 | test_cf_bit_nat(); | |
249 | test_cf_bit_hartley(); | |
250 | test_cf_bit_shannon(); | |
251 | test_transitive_byte_nat(); | |
252 | test_transitive_nat_hartley(); | |
253 | test_transitive_hartley_shannon(); | |
254 | test_transitive_shannon_byte(); | |
255 | test_transitive_byte_nat_hartley(); | |
256 | test_byte_quantity_is_default(); | |
257 | test_byte_quantity_explicit(); | |
258 | test_bit_quantity(); | |
259 | test_nat_quantity(); | |
260 | test_hartley_quantity(); | |
261 | test_shannon_quantity(); | |
262 | test_mixed_hu(); | |
263 | test_info_prefixes(); | |
264 | test_unit_constant_io(); | |
265 | return boost::report_errors(); | |
7c673cae | 266 | } |