Skip to content

Instantly share code, notes, and snippets.

@WiwilZ
Last active September 2, 2024 09:24
Show Gist options
  • Select an option

  • Save WiwilZ/9b20586f51c8cf8c92680f3bad3284e9 to your computer and use it in GitHub Desktop.

Select an option

Save WiwilZ/9b20586f51c8cf8c92680f3bad3284e9 to your computer and use it in GitHub Desktop.
count the number of digits in radix 10 of an integer
#include <cstddef>
#include <cstdint>
#include <bit>
#include <utility>
constexpr size_t count_digits10(uint32_t x) noexcept {
static constexpr uint64_t table[]{
(1ull << 32) | -10u, (1ull << 32) | -10u, (1ull << 32) | -10u, (1ull << 32) | -10u, (1ull << 32) | -10u, (1ull << 32) | -10u, // [1, 64)
(2ull << 32) | -100u, (2ull << 32) | -100u, (2ull << 32) | -100u, // [64, 512)
(3ull << 32) | -1000u, (3ull << 32) | -1000u, (3ull << 32) | -1000u, (3ull << 32) | -1000u, // [512, 8192)
(4ull << 32) | -10000u, (4ull << 32) | -10000u, (4ull << 32) | -10000u, // [8192, 65536)
(5ull << 32) | -100000u, (5ull << 32) | -100000u, (5ull << 32) | -100000u, // [65536, 524288)
(6ull << 32) | -1000000u, (6ull << 32) | -1000000u, (6ull << 32) | -1000000u, (6ull << 32) | -1000000u, // [524288, 8388608)
(7ull << 32) | -10000000u, (7ull << 32) | -10000000u, (7ull << 32) | -10000000u, // [8388608, 67108864]
(8ull << 32) | -100000000u, (8ull << 32) | -100000000u, (8ull << 32) | -100000000u, // [67108864, 536870912)
(9ull << 32) | -1000000000u, (9ull << 32) | -1000000000u, (9ull << 32) | -1000000000u // [536870912, 4294967295]
};
return (x + table[std::bit_width(x | 1) - 1]) >> 32;
}
constexpr size_t count_digits10(uint64_t x) noexcept {
static constexpr std::pair<size_t, uint64_t> table[]{
{1, 10}, {1, 10}, {1, 10}, {1, 10}, {1, 10}, {1, 10}, // [1, 64)
{2, 100}, {2, 100}, {2, 100}, // [64, 512)
{3, 1000}, {3, 1000}, {3, 1000}, {3, 1000}, // [512, 8192)
{4, 10000}, {4, 10000}, {4, 10000}, // [8192, 65536)
{5, 100000}, {5, 100000}, {5, 100000}, // [65536, 524288)
{6, 1000000}, {6, 1000000}, {6, 1000000}, {6, 1000000}, // [524288, 8388608)
{7, 10000000}, {7, 10000000}, {7, 10000000}, // [8388608, 67108864]
{8, 100000000}, {8, 100000000}, {8, 100000000}, // [67108864, 536870912)
{9, 1000000000}, {9, 1000000000}, {9, 1000000000}, {9, 1000000000}, // [536870912, 8589934592)
{10, 10000000000}, {10, 10000000000}, {10, 10000000000}, // [8589934592, 68719476736)
{11, 100000000000}, {11, 100000000000}, {11, 100000000000}, // [68719476736, 549755813888)
{12, 1000000000000}, {12, 1000000000000}, {12, 1000000000000}, {12, 1000000000000}, // [549755813888, 8796093022208)
{13, 10000000000000}, {13, 10000000000000}, {13, 10000000000000}, // [8796093022208, 70368744177664)
{14, 100000000000000}, {14, 100000000000000}, {14, 100000000000000}, // [70368744177664, 562949953421312)
{15, 1000000000000000}, {15, 1000000000000000}, {15, 1000000000000000}, {15, 1000000000000000}, // [562949953421312, 9007199254740992)
{16, 10000000000000000}, {16, 10000000000000000}, {16, 10000000000000000}, // [9007199254740992, 72057594037927936)
{17, 100000000000000000}, {17, 100000000000000000}, {17, 100000000000000000}, // [72057594037927936, 576460752303423488)
{18, 1000000000000000000}, {18, 1000000000000000000}, {18, 1000000000000000000}, {18, 1000000000000000000}, // [576460752303423488, 9223372036854775808)
{19, 10000000000000000000ull} // [9223372036854775808, 18446744073709551615]
};
const auto [digits, limit] = table[std::bit_width(x | 1) - 1];
return digits + (x >= limit);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment