]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/math/test/luroth_expansion_test.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / math / test / luroth_expansion_test.cpp
1 /*
2 * Copyright Nick Thompson, 2020
3 * Use, modification and distribution are subject to the
4 * Boost Software License, Version 1.0. (See accompanying file
5 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 */
7
8 #include "math_unit_test.hpp"
9 #include <boost/math/tools/luroth_expansion.hpp>
10 #include <boost/math/constants/constants.hpp>
11 #include <boost/multiprecision/cpp_bin_float.hpp>
12 #ifdef BOOST_HAS_FLOAT128
13 #include <boost/multiprecision/float128.hpp>
14 using boost::multiprecision::float128;
15 #endif
16
17 using boost::math::tools::luroth_expansion;
18 using boost::multiprecision::cpp_bin_float_100;
19 using boost::math::constants::pi;
20
21 template<class Real>
22 void test_integral()
23 {
24 for (int64_t i = -20; i < 20; ++i) {
25 Real ii = i;
26 auto luroth = luroth_expansion<Real>(ii);
27 auto const & a = luroth.digits();
28 CHECK_EQUAL(size_t(1), a.size());
29 CHECK_EQUAL(i, a.front());
30 }
31 }
32
33
34 template<class Real>
35 void test_halves()
36 {
37 // x = n + 1/k => lur(x) = ((n; k - 1))
38 // Note that this is a bit different that Kalpazidou (examine the half-open interval of definition carefully).
39 // One way to examine this definition is correct for rationals (it never happens for irrationals)
40 // is to consider i + 1/3. If you follow Kalpazidou, then you get ((i, 3, 0)); a zero digit!
41 // That's bad since it destroys uniqueness and also breaks the computation of the geometric mean.
42 for (int64_t i = -20; i < 20; ++i) {
43 Real x = i + Real(1)/Real(2);
44 auto luroth = luroth_expansion<Real>(x);
45 auto const & a = luroth.digits();
46 CHECK_EQUAL(size_t(2), a.size());
47 CHECK_EQUAL(i, a.front());
48 CHECK_EQUAL(int64_t(1), a.back());
49 }
50
51 for (int64_t i = -20; i < 20; ++i) {
52 Real x = i + Real(1)/Real(4);
53 auto luroth = luroth_expansion<Real>(x);
54 auto const & a = luroth.digits();
55 CHECK_EQUAL(size_t(2), a.size());
56 CHECK_EQUAL(i, a.front());
57 CHECK_EQUAL(int64_t(3), a.back());
58 }
59
60 for (int64_t i = -20; i < 20; ++i) {
61 Real x = i + Real(1)/Real(8);
62 auto luroth = luroth_expansion<Real>(x);
63 auto const & a = luroth.digits();
64 CHECK_EQUAL(size_t(2), a.size());
65 CHECK_EQUAL(i, a.front());
66 CHECK_EQUAL(int64_t(7), a.back());
67 }
68 // 1/3 is a pain because it's not representable:
69 Real x = Real(1)/Real(3);
70 auto luroth = luroth_expansion<Real>(x);
71 auto const & a = luroth.digits();
72 CHECK_EQUAL(size_t(2), a.size());
73 CHECK_EQUAL(int64_t(0), a.front());
74 CHECK_EQUAL(int64_t(2), a.back());
75 }
76
77
78 int main()
79 {
80 test_integral<float>();
81 test_integral<double>();
82 test_integral<long double>();
83 test_integral<cpp_bin_float_100>();
84
85 test_halves<float>();
86 test_halves<double>();
87 test_halves<long double>();
88 test_halves<cpp_bin_float_100>();
89
90 #ifdef BOOST_HAS_FLOAT128
91 test_integral<float128>();
92 test_halves<float128>();
93 #endif
94 return boost::math::test::report_errors();
95 }