template inline constexpr T div_ceil(T a, T b) { return (a / b) + ((a % b) != 0); } static_assert(div_ceil(2, 2) == 1); static_assert(div_ceil(3, 2) == 2); static_assert(div_ceil(55, 8) == 7); static_assert(div_ceil(55, 11) == 5); template inline constexpr T sqrt_floor(T a) { if (a == 0) return 0; constexpr int num_bits = (sizeof (T)) * 8; T x = 1 << div_ceil(num_bits, 2); while (true) { T y = (x + (a / x)) / 2; if (y >= x) return x; x = y; } } static_assert(sqrt_floor(4) == 2); static_assert(sqrt_floor(9) == 3); static_assert(sqrt_floor(7056) == 84); static_assert(sqrt_floor(7211) == 84); static_assert(sqrt_floor(7225) == 85); static_assert(sqrt_floor(7226) == 85); template inline constexpr T sqrt_ceil(T a) { T q = sqrt_floor(a); if (q * q != a) q += 1; return q; } static_assert(sqrt_ceil(7056) == 84); static_assert(sqrt_ceil(7211) == 85); static_assert(sqrt_ceil(7225) == 85); static_assert(sqrt_ceil(7226) == 86);