@@ -56,9 +56,10 @@ std::size_t test_powers_of_10() {
5656
5757 constexpr auto POWERS_OF_10 = aoc::math::gen_powers_of_10<IntegerT>();
5858 std::size_t size = POWERS_OF_10.size ();
59+ test (size, std::numeric_limits<IntegerT>::digits10 + 1 );
5960 IntegerT max = std::numeric_limits<IntegerT>::max ();
6061 int i = 0 ;
61- IntegerT x = 10 ;
62+ IntegerT x = 1 ;
6263 while (x <= max / 10 ) {
6364 test (POWERS_OF_10.at (i), x,
6465 " incorrect element at index " + std::to_string (i));
@@ -82,6 +83,71 @@ std::size_t test_powers_of_10() {
8283 return test.num_failed ();
8384}
8485
86+ template <class IntegerT >
87+ std::size_t test_next_power_of_10 () {
88+ const std::string type_name = util::demangle (typeid (IntegerT).name ());
89+ unit_test::PureTest test (" aoc::math::next_power_of_10<" + type_name + " >" ,
90+ &aoc::math::next_power_of_10<IntegerT>);
91+
92+ test (0 , 1 );
93+ test (1 , 10 );
94+ test (2 , 10 );
95+ test (9 , 10 );
96+ test (10 , 100 );
97+ test (11 , 100 );
98+ test (99 , 100 );
99+ for (unsigned int i = 0 ; i < std::numeric_limits<IntegerT>::digits10; ++i) {
100+ IntegerT p10 = powi (static_cast <IntegerT>(10 ), i);
101+ if (p10 >= 1 ) {
102+ test (p10 - 1 , p10);
103+ }
104+ if (IntegerT (p10 * 10 ) % IntegerT (10 ) == 0 ) {
105+ test (p10, 10 * p10);
106+ test (p10 + 1 , 10 * p10);
107+ }
108+ }
109+
110+ test.done ();
111+ if (test.num_failed () > 0 ) {
112+ std::cout << " POWERS_OF_10: "
113+ << pretty_print::repr (aoc::math::gen_powers_of_10<IntegerT>())
114+ << " \n " ;
115+ }
116+ return test.num_failed ();
117+ }
118+
119+ template <class IntegerT >
120+ std::size_t test_prev_power_of_10 () {
121+ const std::string type_name = util::demangle (typeid (IntegerT).name ());
122+ unit_test::PureTest test (" aoc::math::prev_power_of_10<" + type_name + " >" ,
123+ &aoc::math::prev_power_of_10<IntegerT>);
124+
125+ test (0 , 0 );
126+ test (1 , 0 );
127+ test (2 , 1 );
128+ test (9 , 1 );
129+ test (10 , 1 );
130+ test (11 , 10 );
131+ test (99 , 10 );
132+ for (unsigned int i = 1 ; i <= std::numeric_limits<IntegerT>::digits10;
133+ ++i) {
134+ IntegerT p10 = powi (static_cast <IntegerT>(10 ), i);
135+ if (p10 >= 1 ) {
136+ test (p10 - 1 , p10 / 10 );
137+ }
138+ test (p10, p10 / 10 );
139+ test (p10 + 1 , p10);
140+ }
141+
142+ test.done ();
143+ if (test.num_failed () > 0 ) {
144+ std::cout << " POWERS_OF_10: "
145+ << pretty_print::repr (aoc::math::gen_powers_of_10<IntegerT>())
146+ << " \n " ;
147+ }
148+ return test.num_failed ();
149+ }
150+
85151template <class IntegerT >
86152std::size_t test_num_digits () {
87153 const std::string type_name = util::demangle (typeid (IntegerT).name ());
@@ -184,6 +250,16 @@ int main() {
184250 failed_count += test_powers_of_10<std::int64_t >();
185251 failed_count += test_powers_of_10<std::uint64_t >();
186252
253+ failed_count += test_next_power_of_10<int >();
254+ failed_count += test_next_power_of_10<unsigned int >();
255+ failed_count += test_next_power_of_10<std::int64_t >();
256+ failed_count += test_next_power_of_10<std::uint64_t >();
257+
258+ failed_count += test_prev_power_of_10<int >();
259+ failed_count += test_prev_power_of_10<unsigned int >();
260+ failed_count += test_prev_power_of_10<std::int64_t >();
261+ failed_count += test_prev_power_of_10<std::uint64_t >();
262+
187263 failed_count += test_num_digits<int >();
188264 failed_count += test_num_digits<unsigned int >();
189265 failed_count += test_num_digits<std::int64_t >();
0 commit comments