@@ -168,24 +168,6 @@ constexpr auto num_digits(std::uint64_t x) noexcept -> int
168168# pragma warning(disable: 4307) // MSVC 14.1 warns of intergral constant overflow
169169#endif
170170
171- #if defined(__cpp_lib_array_constexpr) && __cpp_lib_array_constexpr >= 201603L
172-
173- template <typename T, std::size_t N>
174- constexpr auto generate_array () noexcept -> std::array<T, N>
175- {
176- std::array<T, N> values {};
177-
178- values[0 ] = T{1 };
179- for (std::size_t i {1 }; i < N; ++i)
180- {
181- values[i] = values[i - 1 ] * UINT64_C (10 );
182- }
183-
184- return values;
185- }
186-
187- #else
188-
189171constexpr int num_digits (const uint128& x) noexcept
190172{
191173 if (x.high == UINT64_C (0 ))
@@ -214,54 +196,15 @@ constexpr int num_digits(const uint128& x) noexcept
214196 return static_cast <int >(left + 1 );
215197}
216198
217- #endif // Constexpr array
218-
219- #if defined(__cpp_lib_array_constexpr) && __cpp_lib_array_constexpr >= 201603L
220-
221- constexpr int num_digits (const uint256_t & x) noexcept
222- {
223- constexpr auto big_powers_of_10 = generate_array<boost::decimal::detail::uint256_t , 79 >();
224-
225- if (x.high == UINT64_C (0 ) && x.low == UINT64_C (0 ))
226- {
227- return 1 ;
228- }
229-
230- std::uint32_t left = 0U ;
231- std::uint32_t right = 78U ;
232-
233- while (left < right)
234- {
235- std::uint32_t mid = (left + right + 1U ) / 2U ;
236-
237- if (x >= big_powers_of_10[mid])
238- {
239- left = mid;
240- }
241- else
242- {
243- right = mid - 1 ;
244- }
245- }
246-
247- return static_cast <int >(left + 1 );
248- }
249-
250- #else
251-
252199constexpr int num_digits (const uint256_t & x) noexcept
253200{
254201 if (x.high == 0 )
255202 {
256203 return num_digits (x.low );
257204 }
258205
259- constexpr uint256_t max_digits = umul256 ({static_cast <uint128>(UINT64_C (10000000000000000000 )) *
260- static_cast <uint128>(UINT64_C (10000000000000000000 ))},
261- {static_cast <uint128>(UINT64_C (10000000000000000000 )) *
262- static_cast <uint128>(UINT64_C (10000000000000000000 ))});
263-
264- uint256_t current_power_of_10 = max_digits;
206+ // 10^77
207+ auto current_power_of_10 {uint256_t {uint128{UINT64_C (15930919111324522770 ), UINT64_C (5327493063679123134 )}, uint128{UINT64_C (12292710897160462336 ), UINT64_C (0 )}}};
265208
266209 for (int i = 78 ; i > 0 ; --i)
267210 {
@@ -276,47 +219,12 @@ constexpr int num_digits(const uint256_t& x) noexcept
276219 return 1 ;
277220}
278221
279- #endif // Constexpr arrays
280-
281222#ifdef _MSC_VER
282223# pragma warning(pop)
283224#endif
284225
285226#ifdef BOOST_DECIMAL_HAS_INT128
286227
287- #if defined(__cpp_lib_array_constexpr) && __cpp_lib_array_constexpr >= 201603L
288-
289- constexpr auto num_digits (boost::decimal::detail::uint128_t x) noexcept -> int
290- {
291- constexpr auto big_powers_of_10 = generate_array<boost::decimal::detail::uint128_t , 39 >();
292-
293- if (x == 0 )
294- {
295- return 1 ;
296- }
297-
298- std::uint32_t left = 0U ;
299- std::uint32_t right = 38U ;
300-
301- while (left < right)
302- {
303- std::uint32_t mid = (left + right + 1U ) / 2U ;
304-
305- if (x >= big_powers_of_10[mid])
306- {
307- left = mid;
308- }
309- else
310- {
311- right = mid - 1 ;
312- }
313- }
314-
315- return static_cast <int >(left + 1 );
316- }
317-
318- #else
319-
320228constexpr auto num_digits (const uint128_t & x) noexcept -> int
321229{
322230 if (static_cast <std::uint64_t >(x >> 64 ) == UINT64_C (0 ))
@@ -345,8 +253,6 @@ constexpr auto num_digits(const uint128_t& x) noexcept -> int
345253 return static_cast <int >(left + 1 );
346254}
347255
348- #endif // constexpr arrays
349-
350256#endif // Has int128
351257
352258} // namespace detail
0 commit comments