1 ///
2 /// @file iroot.cpp
3 /// @brief Test integer nth root function.
4 ///
5 /// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
6 ///
7 /// This file is distributed under the BSD License. See the COPYING
8 /// file in the top level directory.
9 ///
10
11 #include <imath.hpp>
12 #include <int128_t.hpp>
13
14 #include <stdint.h>
15 #include <iostream>
16 #include <cmath>
17 #include <cstdlib>
18
19 using namespace primecount;
20
check(bool OK)21 void check(bool OK)
22 {
23 std::cout << " " << (OK ? "OK" : "ERROR") << "\n";
24 if (!OK)
25 std::exit(1);
26 }
27
main()28 int main()
29 {
30 uint64_t n;
31 uint64_t res1;
32 double res2;
33
34 if (sizeof(long double) > 8)
35 {
36 for (n = 0; n < 100000; n++)
37 {
38 res1 = iroot<2>(n);
39 res2 = std::sqrt((long double) n);
40 std::cout << "iroot<2>(" << n << ") = " << res1;
41 check(res1 == (uint64_t) res2);
42 }
43
44 for (n = 0; n < 100000; n++)
45 {
46 res1 = iroot<3>(n);
47 res2 = std::cbrt((long double) n);
48 std::cout << "iroot<3>(" << n << ") = " << res1;
49 check(res1 == (uint64_t) res2);
50 }
51
52 for (n = 0; n < 100000; n++)
53 {
54 res1 = iroot<4>(n);
55 res2 = std::pow((long double) n, 1.0L / 4);
56 std::cout << "iroot<4>(" << n << ") = " << res1;
57 check(res1 == (uint64_t) res2);
58 }
59
60 for (n = 0; n < 100000; n++)
61 {
62 res1 = iroot<6>(n);
63 res2 = std::pow((long double) n, 1.0L / 6);
64 std::cout << "iroot<6>(" << n << ") = " << res1;
65 check(res1 == (uint64_t) res2);
66 }
67 }
68
69 n = 18446744073709551615ull;
70 res1 = iroot<2>(n);
71 std::cout << "iroot<2>(" << n << ") = " << res1;
72 check(res1 == 4294967295ull);
73
74 n = 18446744073709551615ull;
75 res1 = iroot<3>(n);
76 std::cout << "iroot<3>(" << n << ") = " << res1;
77 check(res1 == 2642245);
78
79 for (uint64_t i = 2000000; i <= 2100000; i++)
80 {
81 n = ipow(i, 3);
82 res1 = iroot<3>(n);
83 std::cout << "iroot<3>(" << n << ") = " << res1;
84 check(res1 == i);
85
86 res1 = iroot<3>(n - 1);
87 std::cout << "iroot<3>(" << n - 1 << ") = " << res1;
88 check(res1 == i - 1);
89 }
90
91 n = 18446744073709551615ull;
92 res1 = iroot<4>(n);
93 std::cout << "iroot<4>(" << n << ") = " << res1;
94 check(res1 == 65535);
95
96 n = 18446744073709551615ull;
97 res1 = iroot<6>(n);
98 std::cout << "iroot<6>(" << n << ") = " << res1;
99 check(res1 == 1625);
100
101 for (uint64_t i = 1; i <= 1625; i++)
102 {
103 n = ipow(i, 6);
104 res1 = iroot<6>(n);
105 std::cout << "iroot<6>(" << n << ") = " << res1;
106 check(res1 == i);
107
108 res1 = iroot<6>(n - 1);
109 std::cout << "iroot<6>(" << n - 1 << ") = " << res1;
110 check(res1 == i - 1);
111 }
112
113 #ifdef HAVE_INT128_T
114
115 int128_t m;
116 int128_t res;
117
118 if (sizeof(long double) > 8)
119 {
120 for (m = 0; m < 100000; m++)
121 {
122 res = iroot<2>(m);
123 res2 = std::sqrt((long double) m);
124 std::cout << "iroot<2>(" << m << ") = " << res;
125 check(res == (int128_t) res2);
126 }
127
128 for (m = 0; m < 100000; m++)
129 {
130 res = iroot<3>(m);
131 res2 = std::cbrt((long double) m);
132 std::cout << "iroot<3>(" << m << ") = " << res;
133 check(res == (int128_t) res2);
134 }
135
136 for (m = 0; m < 100000; m++)
137 {
138 res = iroot<4>(m);
139 res2 = std::pow((long double) m, 1.0L / 4);
140 std::cout << "iroot<4>(" << m << ") = " << res;
141 check(res == (int128_t) res2);
142 }
143
144 for (m = 0; m < 100000; m++)
145 {
146 res = iroot<6>(m);
147 res2 = std::pow((long double) m, 1.0L / 6);
148 std::cout << "iroot<6>(" << m << ") = " << res;
149 check(res == (int128_t) res2);
150 }
151 }
152
153 m = ipow((int128_t) 10, 30);
154 res = iroot<2>(m);
155 std::cout << "iroot<2>(" << m << ") = " << res;
156 check(res == ipow(10ll, 15));
157
158 res = iroot<2>(m - 1);
159 std::cout << "iroot<2>(" << m - 1 << ") = " << res;
160 check(res == ipow(10ll, 15) - 1);
161
162 res = iroot<3>(m);
163 std::cout << "iroot<3>(" << m << ") = " << res;
164 check(res == ipow(10ll, 10));
165
166 res = iroot<3>(m - 1);
167 std::cout << "iroot<3>(" << m - 1 << ") = " << res;
168 check(res == ipow(10ll, 10) - 1);
169
170 res = iroot<6>(m);
171 std::cout << "iroot<6>(" << m << ") = " << res;
172 check(res == ipow(10, 5));
173
174 res = iroot<6>(m - 1);
175 std::cout << "iroot<6>(" << m - 1 << ") = " << res;
176 check(res == ipow(10, 5) - 1);
177
178 m = ipow((int128_t) 10, 28);
179 res = iroot<4>(m);
180 std::cout << "iroot<4>(" << m << ") = " << res;
181 check(res == ipow(10ll, 7));
182
183 res = iroot<4>(m - 1);
184 std::cout << "iroot<4>(" << m - 1 << ") = " << res;
185 check(res == ipow(10ll, 7) - 1);
186
187 #endif
188
189 std::cout << std::endl;
190 std::cout << "All tests passed successfully!" << std::endl;
191
192 return 0;
193 }
194