chore(cpp): implement isqrt

Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
Matej Focko 2023-08-12 23:20:17 +02:00
parent 1bb9745299
commit afe1859bc6
Signed by: mfocko
GPG key ID: 7C47D46246790496

View file

@ -158,6 +158,28 @@ long pow(long base, long exp) {
return half * half * base;
}
template <typename T>
T isqrt(T x) {
assert(x >= 0);
auto max_shift = 8 * sizeof(T) - 1;
auto shift = (max_shift - std::countl_zero(x)) & ~1;
auto bit = 1 << shift;
T result = 0;
while (bit != 0) {
if (x >= (result + bit)) {
x -= result + bit;
result = (result >> 1) + bit;
} else {
result = (result >> 1);
}
bit = bit >> 2;
}
return result;
}
template <std::int64_t MODULO = 1000000007>
struct Z {
Z(std::int64_t x = 0) : x(x % MODULO) {}