haar_lib/math/
kth_root.rs1pub fn kth_root(a: u64, k: u64) -> u64 {
8 assert!(k >= 1);
9
10 match (a, k) {
11 (0, _) => 0,
12 (1, _) => 1,
13 (a, 1) => a,
14 (_, k) if k > 64 => 1,
15 (a, k) => {
16 let mut lb = 0;
17 let mut ub = a;
18 while ub - lb > 1 {
19 let mid = midpoint(ub, lb);
20 if check(mid, k, a) {
21 lb = mid;
22 } else {
23 ub = mid;
24 }
25 }
26
27 lb
28 }
29 }
30}
31
32fn check(mut a: u64, mut k: u64, n: u64) -> bool {
33 let mut r: u64 = 1;
34
35 while k > 0 {
36 if k % 2 == 1 {
37 let Some(_r) = r.checked_mul(a) else {
38 return false;
39 };
40 r = _r;
41 }
42 if let Some(_a) = a.checked_mul(a) {
43 a = _a;
44 } else if k > 1 {
45 return false;
46 }
47 k >>= 1;
48 }
49
50 r <= n
51}
52
53fn midpoint(a: u64, b: u64) -> u64 {
54 ((a ^ b) >> 1) + (a & b)
55}