Skip to main content

malachite_nz/natural/arithmetic/
root.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MP Library.
4//
5//      Contributed by Paul Zimmermann (algorithm) and Paul Zimmermann and Torbjörn Granlund
6//      (implementation). Marco Bodrato wrote `logbased_root` to seed the loop.
7//
8//      Copyright © 2002, 2005, 2009-2012, 2015 Free Software Foundation, Inc.
9//
10// This file is part of Malachite.
11//
12// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
13// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
14// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
15
16use crate::natural::InnerNatural::{Large, Small};
17use crate::natural::arithmetic::div::{limbs_div_limb_to_out, limbs_div_to_out};
18use crate::natural::arithmetic::mul::limb::limbs_slice_mul_limb_in_place;
19use crate::natural::arithmetic::mul::{
20    limbs_mul_greater_to_out, limbs_mul_greater_to_out_scratch_len,
21};
22use crate::natural::arithmetic::pow::limbs_pow;
23use crate::natural::arithmetic::shl::limbs_slice_shl_in_place;
24use crate::natural::arithmetic::shr::limbs_shr_to_out;
25use crate::natural::arithmetic::sub::{
26    limbs_sub_greater_in_place_left, limbs_sub_greater_to_out, limbs_sub_limb_in_place,
27    limbs_sub_limb_to_out,
28};
29use crate::natural::comparison::cmp::limbs_cmp_same_length;
30use crate::natural::{Natural, bit_to_limb_count_floor, limb_to_bit_count};
31use crate::platform::Limb;
32use alloc::vec::Vec;
33use core::cmp::Ordering::*;
34use malachite_base::fail_on_untested_path;
35use malachite_base::num::arithmetic::traits::{
36    CeilingRoot, CeilingRootAssign, CeilingSqrt, CheckedRoot, CheckedSqrt, DivMod, DivRound,
37    FloorRoot, FloorRootAssign, FloorSqrt, ModPowerOf2Assign, PowerOf2, RootAssignRem, RootRem,
38    SqrtRem,
39};
40use malachite_base::num::basic::integers::PrimitiveInt;
41use malachite_base::num::basic::traits::{One, Zero};
42use malachite_base::num::conversion::traits::{ExactFrom, WrappingFrom};
43use malachite_base::num::logic::traits::{LeadingZeros, LowMask, SignificantBits};
44use malachite_base::rounding_modes::RoundingMode::*;
45use malachite_base::slices::{slice_set_zero, slice_trailing_zeros};
46
47// # Worst-case complexity
48// $T(n) = O(n)$
49//
50// $M(n) = O(1)$
51//
52// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
53fn limbs_shl_helper(xs: &mut [Limb], len: usize, out_start_index: usize, bits: u64) -> Limb {
54    assert!(bits < Limb::WIDTH);
55    if len == 0 {
56        0
57    } else {
58        xs.copy_within(0..len, out_start_index);
59        if bits == 0 {
60            0
61        } else {
62            limbs_slice_shl_in_place(&mut xs[out_start_index..out_start_index + len], bits)
63        }
64    }
65}
66
67// # Worst-case complexity
68// $T(n) = O(n)$
69//
70// $M(n) = O(1)$
71//
72// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
73fn shr_helper(out: &mut [Limb], xs: &[Limb], shift: u64) {
74    if shift == 0 {
75        out[..xs.len()].copy_from_slice(xs);
76    } else {
77        limbs_shr_to_out(out, xs, shift);
78    }
79}
80
81// # Worst-case complexity
82// $T(n) = O(n)$
83//
84// $M(n) = O(1)$
85//
86// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
87fn div_helper(qs: &mut [Limb], ns: &mut [Limb], ds: &mut [Limb]) {
88    assert!(*ns.last().unwrap() != 0);
89    assert!(*ds.last().unwrap() != 0);
90    if ns.len() == 1 {
91        if ds.len() == 1 {
92            qs[0] = ns[0] / ds[0];
93        } else {
94            qs[0] = 0;
95        }
96    } else if ds.len() == 1 {
97        limbs_div_limb_to_out(qs, ns, ds[0]);
98    } else {
99        limbs_div_to_out(qs, ns, ds);
100    }
101}
102
103// vlog=vector(256,i,floor((log(256+i)/log(2)-8)*256)-(i>255))
104const V_LOG: [u8; 256] = [
105    1, 2, 4, 5, 7, 8, 9, 11, 12, 14, 15, 16, 18, 19, 21, 22, 23, 25, 26, 27, 29, 30, 31, 33, 34,
106    35, 37, 38, 39, 40, 42, 43, 44, 46, 47, 48, 49, 51, 52, 53, 54, 56, 57, 58, 59, 61, 62, 63, 64,
107    65, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84, 85, 87, 88, 89, 90, 91, 92,
108    93, 94, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 108, 109, 110, 111, 112, 113, 114,
109    115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 131, 132, 133, 134,
110    135, 136, 137, 138, 139, 140, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152,
111    153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 162, 163, 164, 165, 166, 167, 168, 169, 170,
112    171, 172, 173, 173, 174, 175, 176, 177, 178, 179, 180, 181, 181, 182, 183, 184, 185, 186, 187,
113    188, 188, 189, 190, 191, 192, 193, 194, 194, 195, 196, 197, 198, 199, 200, 200, 201, 202, 203,
114    204, 205, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 214, 214, 215, 216, 217, 218, 218,
115    219, 220, 221, 222, 222, 223, 224, 225, 225, 226, 227, 228, 229, 229, 230, 231, 232, 232, 233,
116    234, 235, 235, 236, 237, 238, 239, 239, 240, 241, 242, 242, 243, 244, 245, 245, 246, 247, 247,
117    248, 249, 250, 250, 251, 252, 253, 253, 254, 255, 255,
118];
119
120// vexp=vector(256,i,floor(2^(8+i/256)-256)-(i>255))
121const V_EXP: [u8; 256] = [
122    0, 1, 2, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19,
123    20, 20, 21, 22, 23, 23, 24, 25, 26, 26, 27, 28, 29, 30, 30, 31, 32, 33, 33, 34, 35, 36, 37, 37,
124    38, 39, 40, 41, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 50, 51, 52, 53, 54, 55, 55, 56, 57,
125    58, 59, 60, 61, 61, 62, 63, 64, 65, 66, 67, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78,
126    79, 80, 81, 82, 83, 84, 85, 86, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
127    101, 102, 103, 104, 105, 106, 107, 108, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 119,
128    120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
129    139, 140, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 154, 155, 156, 157, 158, 159,
130    160, 161, 163, 164, 165, 166, 167, 168, 169, 171, 172, 173, 174, 175, 176, 178, 179, 180, 181,
131    182, 183, 185, 186, 187, 188, 189, 191, 192, 193, 194, 196, 197, 198, 199, 200, 202, 203, 204,
132    205, 207, 208, 209, 210, 212, 213, 214, 216, 217, 218, 219, 221, 222, 223, 225, 226, 227, 229,
133    230, 231, 232, 234, 235, 236, 238, 239, 240, 242, 243, 245, 246, 247, 249, 250, 251, 253, 254,
134    255,
135];
136
137const LOGROOT_USED_BITS: u64 = 8;
138const LOGROOT_NEEDS_TWO_CORRECTIONS: bool = true;
139const NEEDED_CORRECTIONS: u64 = if LOGROOT_NEEDS_TWO_CORRECTIONS { 2 } else { 1 };
140const LOGROOT_RETURNED_BITS: u64 = if LOGROOT_NEEDS_TWO_CORRECTIONS {
141    LOGROOT_USED_BITS + 1
142} else {
143    LOGROOT_USED_BITS
144};
145
146// # Worst-case complexity
147// Constant time and additional memory.
148//
149// This is equivalent to `logbased_root` from `mpn/generic/rootrem.c`, GMP 6.2.1.
150fn log_based_root(out: &mut Limb, x: Limb, mut bit_count: u64, exp: u64) -> u64 {
151    const LOGROOT_USED_BITS_COMP: u64 = Limb::WIDTH - LOGROOT_USED_BITS;
152    let len;
153    let b = u64::from(V_LOG[usize::exact_from(x >> LOGROOT_USED_BITS_COMP)]);
154    if bit_count.significant_bits() > LOGROOT_USED_BITS_COMP {
155        // In this branch, the input is unreasonably large. In the unlikely case, we use two
156        // divisions and a modulo.
157        fail_on_untested_path("bit_count.significant_bits() > LOGROOT_USED_BITS_COMP");
158        let r;
159        (len, r) = bit_count.div_mod(exp);
160        bit_count = ((r << LOGROOT_USED_BITS) | b) / exp;
161    } else {
162        bit_count = ((bit_count << LOGROOT_USED_BITS) | b) / exp;
163        len = bit_count >> LOGROOT_USED_BITS;
164        bit_count.mod_power_of_2_assign(LOGROOT_USED_BITS);
165    }
166    assert!(bit_count.significant_bits() <= LOGROOT_USED_BITS);
167    *out = Limb::power_of_2(LOGROOT_USED_BITS) | Limb::from(V_EXP[usize::exact_from(bit_count)]);
168    if !LOGROOT_NEEDS_TWO_CORRECTIONS {
169        *out >>= 1;
170    }
171    len
172}
173
174// If approx is non-zero, does not compute the final remainder.
175//
176/// # Worst-case complexity
177// $T(n) = O(n (\log n)^2 \log\log n)$
178//
179// $M(n) = O(n \log n)$
180//
181// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
182//
183// This is equivalent to `mpn_rootrem_internal` from `mpn/generic/rootrem.c`, GMP 6.2.1.
184fn limbs_root_to_out_internal(
185    out_root: &mut [Limb],
186    out_rem: Option<&mut [Limb]>,
187    xs: &[Limb],
188    exp: u64,
189    approx: bool,
190) -> usize {
191    let mut xs_len = xs.len();
192    let mut xs_hi = xs[xs_len - 1];
193    let leading_zeros = LeadingZeros::leading_zeros(xs_hi) + 1;
194    let bit_count = limb_to_bit_count(xs_len) - leading_zeros;
195    let out_rem_is_some = out_rem.is_some();
196    if bit_count < exp {
197        // root is 1
198        out_root[0] = 1;
199        if out_rem_is_some {
200            let out_rem = out_rem.unwrap();
201            limbs_sub_limb_to_out(out_rem, xs, 1);
202            // There should be at most one zero limb, if we demand x to be normalized
203            if out_rem[xs_len - 1] == 0 {
204                xs_len -= 1;
205            }
206        } else if xs[0] == 1 {
207            xs_len -= 1;
208        }
209        return xs_len;
210    }
211    xs_hi = if leading_zeros == Limb::WIDTH {
212        xs[xs_len - 2]
213    } else {
214        let mut i = xs_len - 1;
215        if xs_len != 1 {
216            i -= 1;
217        }
218        (xs_hi << leading_zeros) | (xs[i] >> (Limb::WIDTH - leading_zeros))
219    };
220    assert!(xs_len != 1 || xs[xs_len - 1] >> (Limb::WIDTH - leading_zeros) == 1);
221    // - root_bits + 1 is the number of bits of the root R
222    // - APPROX_BITS + 1 is the number of bits of the current approximation S
223    let mut root_bits = log_based_root(&mut out_root[0], xs_hi, bit_count, exp);
224    const APPROX_BITS: u64 = LOGROOT_RETURNED_BITS - 1;
225    let mut input_bits = exp * root_bits; // number of truncated bits in the input
226    xs_hi = (Limb::exact_from(exp) - 1) >> 1;
227    let mut log_exp = 3;
228    loop {
229        xs_hi >>= 1;
230        if xs_hi == 0 {
231            break;
232        }
233        log_exp += 1;
234    }
235    // log_exp = ceil(log_2(exp)) + 1
236    let mut i = 0;
237    let mut sizes = [0u64; (Limb::WIDTH + 1) as usize];
238    loop {
239        // Invariant: here we want root_bits + 1 total bits for the kth root. If c is the new value
240        // of root_bits, this means that we'll go from a root of c + 1 bits (say s') to a root of
241        // root_bits + 1 bits. It is proved in the book "Modern Computer Arithmetic" by Brent and
242        // Zimmermann, Chapter 1, that if s' >= exp * beta, then at most one correction is
243        // necessary. Here beta = 2 ^ (root_bits - c), and s' >= 2 ^ c, thus it suffices that c >=
244        // ceil((root_bits + log_2(exp)) / 2).
245        sizes[i] = root_bits;
246        if root_bits <= APPROX_BITS {
247            break;
248        }
249        if root_bits > log_exp {
250            root_bits = (root_bits + log_exp) >> 1;
251        } else {
252            // add just one bit at a time
253            root_bits -= 1;
254        }
255        i += 1;
256    }
257    out_root[0] >>= APPROX_BITS - root_bits;
258    input_bits -= root_bits;
259    assert!(i < usize::wrapping_from(Limb::WIDTH + 1));
260    // We have sizes[0] = next_bits > sizes[1] > ... > sizes[ni] = 0, with sizes[i] <= 2 * sizes[i +
261    // 1]. Newton iteration will first compute sizes[i - 1] extra bits, then sizes[i - 2], ..., then
262    // sizes[0] = next_bits. qs and ws need enough space to store S' ^ exp, where S' is an
263    // approximate root. Since S' can be as large as S + 2, the worst case is when S = 2 and S' = 4.
264    // But then since we know the number of bits of S in advance, S' can only be 3 at most.
265    // Similarly for S = 4, then S' can be 6 at most. So the worst case is S' / S = 3 / 2, thus S' ^
266    // exp <= (3 / 2) ^ exp * S ^ exp. Since S ^ exp fits in xs_len limbs, the number of extra limbs
267    // needed is bounded by ceil(exp * log_2(3 / 2) / B), where B is `Limb::WIDTH`.
268    let extra = (((0.585 * (exp as f64)) / (Limb::WIDTH as f64)) as usize) + 2;
269    let mut big_scratch = vec![0; 3 * xs_len + 2 * extra + 1];
270    let (scratch, remainder) = big_scratch.split_at_mut(xs_len + 1);
271    // - qs will contain quotient and remainder of R / (exp * S ^ (exp - 1)).
272    // - ws will contain S ^ (k-1) and exp *S^(k-1).
273    let (qs, ws) = remainder.split_at_mut(xs_len + extra);
274    let rs = if out_rem_is_some {
275        out_rem.unwrap()
276    } else {
277        scratch
278    };
279    let ss = out_root;
280    // Initial approximation has one limb
281    let mut ss_len = 1;
282    let mut next_bits = root_bits;
283    let mut rs_len = 0;
284    let mut save_1;
285    let mut save_2 = 0;
286    let mut qs_len;
287    let mut pow_cmp;
288    while i != 0 {
289        // Loop invariant:
290        // - &ss[..ss_len] is the current approximation of the root, which has exactly 1 + sizes[i]
291        //   bits.
292        // - &rs[..rs_len] is the current remainder.
293        // - &ws[..ws_len] = ss[..ss_len] ^ (exp - 1)
294        // - input_bits = number of truncated bits of the input
295        //
296        // Since each iteration treats next_bits bits from the root and thus exp * next_bits bits
297        // from the input, and we already considered next_bits bits from the input, we now have to
298        // take another (exp - 1) * next_bits bits from the input.
299        input_bits -= (exp - 1) * next_bits;
300        // &rs[..rs_len] = floor(&xs[..xs_len] / 2 ^ input_bits)
301        let input_len = bit_to_limb_count_floor(input_bits);
302        let input_bits_rem = input_bits & Limb::WIDTH_MASK;
303        shr_helper(rs, &xs[input_len..xs_len], input_bits_rem);
304        rs_len = xs_len - input_len;
305        if rs[rs_len - 1] == 0 {
306            rs_len -= 1;
307        }
308        // Current buffers: &ss[..ss_len], &ss[..ss_len]
309        let mut correction = 0;
310        let mut ws_len;
311        loop {
312            // - Compute S ^ exp in &qs[..qs_len]
313            // - W <- S ^ (exp - 1) for the next iteration, and S ^ k = W * S.
314            let ss_trimmed = &mut ss[..ss_len];
315            let pow_xs = limbs_pow(ss_trimmed, exp - 1);
316            ws[..pow_xs.len()].copy_from_slice(&pow_xs);
317            ws_len = pow_xs.len();
318            let mut mul_scratch = vec![0; limbs_mul_greater_to_out_scratch_len(ws_len, ss_len)];
319            limbs_mul_greater_to_out(qs, &ws[..ws_len], ss_trimmed, &mut mul_scratch);
320            qs_len = ws_len + ss_len;
321            if qs[qs_len - 1] == 0 {
322                qs_len -= 1;
323            }
324            pow_cmp = Greater;
325            // if S^k > floor(U/2^input_bits), the root approximation was too large
326            let mut need_adjust = qs_len > rs_len;
327            if !need_adjust && qs_len == rs_len {
328                pow_cmp = limbs_cmp_same_length(&qs[..rs_len], &rs[..rs_len]);
329                need_adjust = pow_cmp == Greater;
330            }
331            if need_adjust {
332                assert!(!limbs_sub_limb_in_place(ss_trimmed, 1));
333            } else {
334                break;
335            }
336            correction += 1;
337        }
338        // - Current buffers: &ss[..ss_len], &rs[..rs_len], &qs[..qs_len], &ws[..ws_len]
339        // - Sometimes two corrections are needed with logbased_root.
340        assert!(correction <= NEEDED_CORRECTIONS);
341        assert!(rs_len >= qs_len);
342        // next_bits is the number of bits to compute in the next iteration.
343        next_bits = sizes[i - 1] - sizes[i];
344        // next_len is the lowest limb from the high part of rs, after shift.
345        let next_len = bit_to_limb_count_floor(next_bits);
346        let next_bits_rem = next_bits & Limb::WIDTH_MASK;
347        input_bits -= next_bits;
348        let input_len = bit_to_limb_count_floor(input_bits);
349        let input_bits_rem = input_bits & Limb::WIDTH_MASK;
350        // - n_len is the number of limbs in x which contain bits
351        // - [input_bits, input_bits + next_bits - 1]
352        //
353        // n_len = 1 + floor((input_bits + next_bits - 1) / B) - floor(input_bits / B) <= 1 +
354        // (input_bits + next_bits - 1) / B - (input_bits - B + 1) / B = 2 + (next_bits - 2) / B,
355        // where B is `Limb::WIDTH`.
356        //
357        // Thus, since n_len is an integer: n_len <= 2 + floor(next_bits / B) <= 2 + next_len.
358        let n_len = bit_to_limb_count_floor(input_bits + next_bits - 1) + 1 - input_len;
359        // - Current buffers: &ss[..ss_len], &rs[..rs_len], &ws[..ws_len]
360        // - R = R - Q = floor(X / 2 ^ input_bits) - S ^ exp
361        if pow_cmp == Equal {
362            rs_len = next_len;
363            save_2 = 0;
364            save_1 = 0;
365        } else {
366            let rs_trimmed = &mut rs[..rs_len];
367            limbs_sub_greater_in_place_left(rs_trimmed, &qs[..qs_len]);
368            rs_len -= slice_trailing_zeros(rs_trimmed);
369            // first multiply the remainder by 2^next_bits
370            let carry = limbs_shl_helper(rs, rs_len, next_len, next_bits_rem);
371            rs_len += next_len;
372            if carry != 0 {
373                rs[rs_len] = carry;
374                rs_len += 1;
375            }
376            save_1 = rs[next_len];
377            // we have to save rs[next_len] up to rs[n_len - 1], i.e. 1 or 2 limbs
378            if n_len - 1 > next_len {
379                save_2 = rs[next_len + 1];
380            }
381        }
382        // - Current buffers: &ss[..ss_len], &rs[..rs_len], &ws[..ws_len]
383        // - Now insert bits [input_bits, input_bits + next_bits - 1] from the input X
384        shr_helper(rs, &xs[input_len..input_len + n_len], input_bits_rem);
385        // Set to zero high bits of rs[next_len]
386        rs[next_len].mod_power_of_2_assign(next_bits_rem);
387        // Restore corresponding bits
388        rs[next_len] |= save_1;
389        if n_len - 1 > next_len {
390            // The low next_bits bits go in rs[0..next_len] only, since they start by bit 0 in
391            // rs[0], so they use at most ceil(next_bits / B) limbs
392            rs[next_len + 1] = save_2;
393        }
394        // - Current buffers: &ss[..ss_len], &rs[..rs_len], &ws[..ws_len]
395        // - Compute &ws[..ws_len] = exp * &ss[..ss_len] ^ (exp-1).
396        let carry = limbs_slice_mul_limb_in_place(&mut ws[..ws_len], Limb::exact_from(exp));
397        ws[ws_len] = carry;
398        if carry != 0 {
399            ws_len += 1;
400        }
401        // - Current buffers: &ss[..ss_len], &qs[..qs_len]
402        // - Multiply the root approximation by 2 ^ next_bits
403        let carry = limbs_shl_helper(ss, ss_len, next_len, next_bits_rem);
404        ss_len += next_len;
405        if carry != 0 {
406            ss[ss_len] = carry;
407            ss_len += 1;
408        }
409        save_1 = ss[next_len];
410        // Number of limbs used by next_bits bits, when least significant bit is aligned to least
411        // limb
412        let b_rem = bit_to_limb_count_floor(next_bits - 1) + 1;
413        // - Current buffers: &ss[..ss_len], &rs[..rs_len], &ws[..ws_len]
414        // - Now divide &rs[..rs_len] by &ws[..ws_len] to get the low part of the root
415        if rs_len < ws_len {
416            slice_set_zero(&mut ss[..b_rem]);
417        } else {
418            let mut qs_len = rs_len - ws_len; // Expected quotient size
419            if qs_len <= b_rem {
420                // Divide only if result is not too big.
421                div_helper(qs, &mut rs[..rs_len], &mut ws[..ws_len]);
422                if qs[qs_len] != 0 {
423                    qs_len += 1;
424                }
425            } else {
426                fail_on_untested_path("limbs_root_to_out_internal, qs_len > b_rem");
427            }
428            // - Current buffers: &ss[..ss_len], &qs[..qs_len]
429            // - Note: &rs[..rs_len]is not needed any more since we'll compute it from scratch at
430            //   the end of the loop.
431            //
432            // The quotient should be smaller than 2 ^ next_bits, since the previous approximation
433            // was correctly rounded toward zero.
434            if qs_len > b_rem
435                || (qs_len == b_rem
436                    && (next_bits_rem != 0)
437                    && qs[qs_len - 1].significant_bits() > next_bits_rem)
438            {
439                qs_len = 1;
440                while qs_len < b_rem {
441                    ss[qs_len - 1] = Limb::MAX;
442                    qs_len += 1;
443                }
444                ss[qs_len - 1] = Limb::low_mask(((next_bits - 1) & Limb::WIDTH_MASK) + 1);
445            } else {
446                // - Current buffers: &ss[..ss_len], &qs[..qs_len]
447                // - Combine sB and q to form sB + q.
448                let (ss_lo, ss_hi) = ss.split_at_mut(qs_len);
449                ss_lo.copy_from_slice(&qs[..qs_len]);
450                slice_set_zero(&mut ss_hi[..b_rem - qs_len]);
451            }
452        }
453        ss[next_len] |= save_1;
454        // 8: current buffer: &ss[..ss_len]
455        i -= 1;
456    }
457    // otherwise we have rn > 0, thus the return value is ok
458    if !approx || ss[0] <= 1 {
459        let mut c = 0;
460        loop {
461            // - Compute S ^ exp in &qs[..qs_len].
462            // - Last iteration: we don't need W anymore.
463            let pow_xs = limbs_pow(&ss[..ss_len], exp);
464            qs[..pow_xs.len()].copy_from_slice(&pow_xs);
465            qs_len = pow_xs.len();
466            pow_cmp = Greater;
467            let mut need_adjust = qs_len > xs_len;
468            if !need_adjust && qs_len == xs_len {
469                pow_cmp = limbs_cmp_same_length(&qs[..xs_len], &xs[..xs_len]);
470                need_adjust = pow_cmp == Greater;
471            }
472            if need_adjust {
473                assert!(!limbs_sub_limb_in_place(&mut ss[..ss_len], 1));
474            } else {
475                break;
476            }
477            c += 1;
478        }
479        // Sometimes two corrections are needed with log_based_root.
480        assert!(c <= NEEDED_CORRECTIONS);
481        rs_len = usize::from(pow_cmp != Equal);
482        if rs_len != 0 && out_rem_is_some {
483            limbs_sub_greater_to_out(rs, &xs[..xs_len], &qs[..qs_len]);
484            rs_len = xs_len;
485            rs_len -= slice_trailing_zeros(rs);
486        }
487    }
488    rs_len
489}
490
491// Returns the size (in limbs) of the remainder.
492//
493// # Worst-case complexity
494// $T(n) = O(n (\log n)^2 \log\log n)$
495//
496// $M(n) = O(n \log n)$
497//
498// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
499//
500// This is equivalent to `mpn_rootrem` from `mpn/generic/rootrem.c`, GMP 6.2.1, where `k != 2` and
501// `remp` is not `NULL`.
502pub_test! {limbs_root_rem_to_out(
503    out_root: &mut [Limb],
504    out_rem: &mut [Limb],
505    xs: &[Limb],
506    exp: u64,
507) -> usize {
508    let xs_len = xs.len();
509    assert_ne!(xs_len, 0);
510    assert_ne!(xs[xs_len - 1], 0);
511    assert!(exp > 2);
512    // (xs_len - 1) / exp > 2 <=> xs_len > 3 * exp <=> (xs_len + 2) / 3 > exp
513    limbs_root_to_out_internal(out_root, Some(out_rem), xs, exp, false)
514}}
515
516// Returns a non-zero value iff the remainder is non-zero.
517//
518// # Worst-case complexity
519// $T(n) = O(n (\log n)^2 \log\log n)$
520//
521// $M(n) = O(n \log n)$
522//
523// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
524//
525// This is equivalent to `mpn_rootrem` from `mpn/generic/rootrem.c`, GMP 6.2.1, where `remp` is
526// `NULL`.
527pub_test! {limbs_floor_root_to_out(out_root: &mut [Limb], xs: &[Limb], exp: u64) -> bool {
528    let xs_len = xs.len();
529    assert_ne!(xs_len, 0);
530    assert_ne!(xs[xs_len - 1], 0);
531    assert!(exp > 2);
532    // (xs_len - 1) / exp > 2 <=> xs_len > 3 * exp <=> (xs_len + 2) / 3 > exp
533    let u_exp = usize::exact_from(exp);
534    if xs_len.div_ceil(3) > u_exp {
535        // Pad xs with exp zero limbs. This will produce an approximate root with one more limb,
536        // allowing us to compute the exact integral result.
537        let ws_len = xs_len + u_exp;
538        let ss_len = (xs_len - 1) / u_exp + 2; // ceil(xs_len / exp) + 1
539        let mut scratch = vec![0; ws_len + ss_len];
540        // - ws will contain the padded input.
541        // - ss is the approximate root of padded input.
542        let (ws, ss) = scratch.split_at_mut(ws_len);
543        ws[u_exp..].copy_from_slice(xs);
544        let rs_len = limbs_root_to_out_internal(ss, None, ws, exp, true);
545        // The approximate root S = ss is either the correct root of ss, or 1 too large. Thus,
546        // unless the least significant limb of S is 0 or 1, we can deduce the root of xs is S
547        // truncated by one limb. (In case xs[0] = 1, we can deduce the root, but not decide whether
548        // it is exact or not.)
549        out_root[..ss_len - 1].copy_from_slice(&ss[1..]);
550        rs_len != 0
551    } else {
552        limbs_root_to_out_internal(out_root, None, xs, exp, false) != 0
553    }
554}}
555
556// # Worst-case complexity
557// $T(n) = O(n (\log n)^2 \log\log n)$
558//
559// $M(n) = O(n \log n)$
560//
561// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
562pub_test! {limbs_floor_root(xs: &[Limb], exp: u64) -> (Vec<Limb>, bool) {
563    let mut out = vec![
564        0;
565        xs.len()
566            .div_round(usize::exact_from(exp), Ceiling).0
567    ];
568    let inexact = limbs_floor_root_to_out(&mut out, xs, exp);
569    (out, inexact)
570}}
571
572// # Worst-case complexity
573// $T(n) = O(n (\log n)^2 \log\log n)$
574//
575// $M(n) = O(n \log n)$
576//
577// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
578pub_test! {limbs_root_rem(xs: &[Limb], exp: u64) -> (Vec<Limb>, Vec<Limb>) {
579    let mut root_out = vec![
580        0;
581        xs.len()
582            .div_round(usize::exact_from(exp), Ceiling).0
583    ];
584    let mut rem_out = vec![0; xs.len()];
585    let rem_len = limbs_root_rem_to_out(&mut root_out, &mut rem_out, xs, exp);
586    rem_out.truncate(rem_len);
587    (root_out, rem_out)
588}}
589
590impl FloorRoot<u64> for Natural {
591    type Output = Self;
592
593    /// Returns the floor of the $n$th root of a [`Natural`], taking the [`Natural`] by value.
594    ///
595    /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$.
596    ///
597    /// # Worst-case complexity
598    /// $T(n) = O(n (\log n)^2 \log\log n)$
599    ///
600    /// $M(n) = O(n \log n)$
601    ///
602    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
603    ///
604    /// # Panics
605    /// Panics if `exp` is zero.
606    ///
607    /// # Examples
608    /// ```
609    /// use malachite_base::num::arithmetic::traits::FloorRoot;
610    /// use malachite_nz::natural::Natural;
611    ///
612    /// assert_eq!(Natural::from(999u16).floor_root(3), 9);
613    /// assert_eq!(Natural::from(1000u16).floor_root(3), 10);
614    /// assert_eq!(Natural::from(1001u16).floor_root(3), 10);
615    /// assert_eq!(Natural::from(100000000000u64).floor_root(5), 158);
616    /// ```
617    fn floor_root(self, exp: u64) -> Self {
618        match exp {
619            0 => panic!("Cannot take 0th root"),
620            1 => self,
621            2 => self.floor_sqrt(),
622            exp => match self {
623                Self(Small(x)) => Self(Small(x.floor_root(exp))),
624                Self(Large(xs)) => Self::from_owned_limbs_asc(limbs_floor_root(&xs, exp).0),
625            },
626        }
627    }
628}
629
630impl FloorRoot<u64> for &Natural {
631    type Output = Natural;
632
633    /// Returns the floor of the $n$th root of a [`Natural`], taking the [`Natural`] by reference.
634    ///
635    /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$.
636    ///
637    /// # Worst-case complexity
638    /// $T(n) = O(n (\log n)^2 \log\log n)$
639    ///
640    /// $M(n) = O(n \log n)$
641    ///
642    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
643    ///
644    /// # Panics
645    /// Panics if `exp` is zero.
646    ///
647    /// # Examples
648    /// ```
649    /// use malachite_base::num::arithmetic::traits::FloorRoot;
650    /// use malachite_nz::natural::Natural;
651    ///
652    /// assert_eq!((&Natural::from(999u16)).floor_root(3), 9);
653    /// assert_eq!((&Natural::from(1000u16)).floor_root(3), 10);
654    /// assert_eq!((&Natural::from(1001u16)).floor_root(3), 10);
655    /// assert_eq!((&Natural::from(100000000000u64)).floor_root(5), 158);
656    /// ```
657    fn floor_root(self, exp: u64) -> Natural {
658        match exp {
659            0 => panic!("Cannot take 0th root"),
660            1 => self.clone(),
661            2 => self.floor_sqrt(),
662            exp => match self {
663                Natural(Small(x)) => Natural(Small(x.floor_root(exp))),
664                Natural(Large(xs)) => Natural::from_owned_limbs_asc(limbs_floor_root(xs, exp).0),
665            },
666        }
667    }
668}
669
670impl FloorRootAssign<u64> for Natural {
671    /// Replaces a [`Natural`] with the floor of its $n$th root.
672    ///
673    /// $x \gets \lfloor\sqrt\[n\]{x}\rfloor$.
674    ///
675    /// # Worst-case complexity
676    /// $T(n) = O(n (\log n)^2 \log\log n)$
677    ///
678    /// $M(n) = O(n \log n)$
679    ///
680    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
681    ///
682    /// # Panics
683    /// Panics if `exp` is zero.
684    ///
685    /// # Examples
686    /// ```
687    /// use malachite_base::num::arithmetic::traits::FloorRootAssign;
688    /// use malachite_nz::natural::Natural;
689    ///
690    /// let mut x = Natural::from(999u16);
691    /// x.floor_root_assign(3);
692    /// assert_eq!(x, 9);
693    ///
694    /// let mut x = Natural::from(1000u16);
695    /// x.floor_root_assign(3);
696    /// assert_eq!(x, 10);
697    ///
698    /// let mut x = Natural::from(1001u16);
699    /// x.floor_root_assign(3);
700    /// assert_eq!(x, 10);
701    ///
702    /// let mut x = Natural::from(100000000000u64);
703    /// x.floor_root_assign(5);
704    /// assert_eq!(x, 158);
705    /// ```
706    #[inline]
707    fn floor_root_assign(&mut self, exp: u64) {
708        *self = (&*self).floor_root(exp);
709    }
710}
711
712impl CeilingRoot<u64> for Natural {
713    type Output = Self;
714
715    /// Returns the ceiling of the $n$th root of a [`Natural`], taking the [`Natural`] by value.
716    ///
717    /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$.
718    ///
719    /// # Worst-case complexity
720    /// $T(n) = O(n (\log n)^2 \log\log n)$
721    ///
722    /// $M(n) = O(n \log n)$
723    ///
724    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
725    ///
726    /// # Panics
727    /// Panics if `exp` is zero.
728    ///
729    /// # Examples
730    /// ```
731    /// use malachite_base::num::arithmetic::traits::CeilingRoot;
732    /// use malachite_nz::natural::Natural;
733    ///
734    /// assert_eq!(Natural::from(999u16).ceiling_root(3), 10);
735    /// assert_eq!(Natural::from(1000u16).ceiling_root(3), 10);
736    /// assert_eq!(Natural::from(1001u16).ceiling_root(3), 11);
737    /// assert_eq!(Natural::from(100000000000u64).ceiling_root(5), 159);
738    /// ```
739    fn ceiling_root(self, exp: u64) -> Self {
740        match exp {
741            0 => panic!("Cannot take 0th root"),
742            1 => self,
743            2 => self.ceiling_sqrt(),
744            exp => match self {
745                Self(Small(x)) => Self(Small(x.ceiling_root(exp))),
746                Self(Large(xs)) => {
747                    let (floor_root_limbs, inexact) = limbs_floor_root(&xs, exp);
748                    let floor_root = Self::from_owned_limbs_asc(floor_root_limbs);
749                    if inexact {
750                        floor_root + Self::ONE
751                    } else {
752                        floor_root
753                    }
754                }
755            },
756        }
757    }
758}
759
760impl CeilingRoot<u64> for &Natural {
761    type Output = Natural;
762
763    /// Returns the ceiling of the $n$th root of a [`Natural`], taking the [`Natural`] by reference.
764    ///
765    /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$.
766    ///
767    /// # Worst-case complexity
768    /// $T(n) = O(n (\log n)^2 \log\log n)$
769    ///
770    /// $M(n) = O(n \log n)$
771    ///
772    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
773    ///
774    /// # Panics
775    /// Panics if `exp` is zero.
776    ///
777    /// # Examples
778    /// ```
779    /// use malachite_base::num::arithmetic::traits::CeilingRoot;
780    /// use malachite_nz::natural::Natural;
781    ///
782    /// assert_eq!(Natural::from(999u16).ceiling_root(3), 10);
783    /// assert_eq!(Natural::from(1000u16).ceiling_root(3), 10);
784    /// assert_eq!(Natural::from(1001u16).ceiling_root(3), 11);
785    /// assert_eq!(Natural::from(100000000000u64).ceiling_root(5), 159);
786    /// ```
787    fn ceiling_root(self, exp: u64) -> Natural {
788        match exp {
789            0 => panic!("Cannot take 0th root"),
790            1 => self.clone(),
791            2 => self.ceiling_sqrt(),
792            exp => match self {
793                Natural(Small(x)) => Natural(Small(x.ceiling_root(exp))),
794                Natural(Large(xs)) => {
795                    let (floor_root_limbs, inexact) = limbs_floor_root(xs, exp);
796                    let floor_root = Natural::from_owned_limbs_asc(floor_root_limbs);
797                    if inexact {
798                        floor_root + Natural::ONE
799                    } else {
800                        floor_root
801                    }
802                }
803            },
804        }
805    }
806}
807
808impl CeilingRootAssign<u64> for Natural {
809    /// Replaces a [`Natural`] with the ceiling of its $n$th root.
810    ///
811    /// $x \gets \lceil\sqrt\[n\]{x}\rceil$.
812    ///
813    /// # Worst-case complexity
814    /// $T(n) = O(n (\log n)^2 \log\log n)$
815    ///
816    /// $M(n) = O(n \log n)$
817    ///
818    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
819    ///
820    /// # Panics
821    /// Panics if `exp` is zero.
822    ///
823    /// # Examples
824    /// ```
825    /// use malachite_base::num::arithmetic::traits::CeilingRootAssign;
826    /// use malachite_nz::natural::Natural;
827    ///
828    /// let mut x = Natural::from(999u16);
829    /// x.ceiling_root_assign(3);
830    /// assert_eq!(x, 10);
831    ///
832    /// let mut x = Natural::from(1000u16);
833    /// x.ceiling_root_assign(3);
834    /// assert_eq!(x, 10);
835    ///
836    /// let mut x = Natural::from(1001u16);
837    /// x.ceiling_root_assign(3);
838    /// assert_eq!(x, 11);
839    ///
840    /// let mut x = Natural::from(100000000000u64);
841    /// x.ceiling_root_assign(5);
842    /// assert_eq!(x, 159);
843    /// ```
844    #[inline]
845    fn ceiling_root_assign(&mut self, exp: u64) {
846        *self = (&*self).ceiling_root(exp);
847    }
848}
849
850impl CheckedRoot<u64> for Natural {
851    type Output = Self;
852
853    /// Returns the the $n$th root of a [`Natural`], or `None` if the [`Natural`] is not a perfect
854    /// $n$th power. The [`Natural`] is taken by value.
855    ///
856    /// $$
857    /// f(x, n) = \\begin{cases}
858    ///     \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\
859    ///     \operatorname{None} & \textrm{otherwise}.
860    /// \\end{cases}
861    /// $$
862    ///
863    /// # Worst-case complexity
864    /// $T(n) = O(n (\log n)^2 \log\log n)$
865    ///
866    /// $M(n) = O(n \log n)$
867    ///
868    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
869    ///
870    /// # Panics
871    /// Panics if `exp` is zero.
872    ///
873    /// # Examples
874    /// ```
875    /// use malachite_base::num::arithmetic::traits::CheckedRoot;
876    /// use malachite_base::strings::ToDebugString;
877    /// use malachite_nz::natural::Natural;
878    ///
879    /// assert_eq!(
880    ///     Natural::from(999u16).checked_root(3).to_debug_string(),
881    ///     "None"
882    /// );
883    /// assert_eq!(
884    ///     Natural::from(1000u16).checked_root(3).to_debug_string(),
885    ///     "Some(10)"
886    /// );
887    /// assert_eq!(
888    ///     Natural::from(1001u16).checked_root(3).to_debug_string(),
889    ///     "None"
890    /// );
891    /// assert_eq!(
892    ///     Natural::from(100000000000u64)
893    ///         .checked_root(5)
894    ///         .to_debug_string(),
895    ///     "None"
896    /// );
897    /// assert_eq!(
898    ///     Natural::from(10000000000u64)
899    ///         .checked_root(5)
900    ///         .to_debug_string(),
901    ///     "Some(100)"
902    /// );
903    /// ```
904    fn checked_root(self, exp: u64) -> Option<Self> {
905        match exp {
906            0 => panic!("Cannot take 0th root"),
907            1 => Some(self),
908            2 => self.checked_sqrt(),
909            exp => match self {
910                Self(Small(x)) => x.checked_root(exp).map(|x| Self(Small(x))),
911                Self(Large(xs)) => {
912                    let (floor_root_limbs, inexact) = limbs_floor_root(&xs, exp);
913                    let floor_root = Self::from_owned_limbs_asc(floor_root_limbs);
914                    if inexact { None } else { Some(floor_root) }
915                }
916            },
917        }
918    }
919}
920
921impl CheckedRoot<u64> for &Natural {
922    type Output = Natural;
923
924    /// Returns the the $n$th root of a [`Natural`], or `None` if the [`Natural`] is not a perfect
925    /// $n$th power. The [`Natural`] is taken by reference.
926    ///
927    /// $$
928    /// f(x, n) = \\begin{cases}
929    ///     \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\
930    ///     \operatorname{None} & \textrm{otherwise}.
931    /// \\end{cases}
932    /// $$
933    ///
934    /// # Worst-case complexity
935    /// $T(n) = O(n (\log n)^2 \log\log n)$
936    ///
937    /// $M(n) = O(n \log n)$
938    ///
939    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
940    ///
941    /// # Panics
942    /// Panics if `exp` is zero.
943    ///
944    /// # Examples
945    /// ```
946    /// use malachite_base::num::arithmetic::traits::CheckedRoot;
947    /// use malachite_base::strings::ToDebugString;
948    /// use malachite_nz::natural::Natural;
949    ///
950    /// assert_eq!(
951    ///     (&Natural::from(999u16)).checked_root(3).to_debug_string(),
952    ///     "None"
953    /// );
954    /// assert_eq!(
955    ///     (&Natural::from(1000u16)).checked_root(3).to_debug_string(),
956    ///     "Some(10)"
957    /// );
958    /// assert_eq!(
959    ///     (&Natural::from(1001u16)).checked_root(3).to_debug_string(),
960    ///     "None"
961    /// );
962    /// assert_eq!(
963    ///     (&Natural::from(100000000000u64))
964    ///         .checked_root(5)
965    ///         .to_debug_string(),
966    ///     "None"
967    /// );
968    /// assert_eq!(
969    ///     (&Natural::from(10000000000u64))
970    ///         .checked_root(5)
971    ///         .to_debug_string(),
972    ///     "Some(100)"
973    /// );
974    /// ```
975    fn checked_root(self, exp: u64) -> Option<Natural> {
976        match exp {
977            0 => panic!("Cannot take 0th root"),
978            1 => Some(self.clone()),
979            2 => self.checked_sqrt(),
980            exp => match self {
981                Natural(Small(x)) => x.checked_root(exp).map(|x| Natural(Small(x))),
982                Natural(Large(xs)) => {
983                    let (floor_root_limbs, inexact) = limbs_floor_root(xs, exp);
984                    let floor_root = Natural::from_owned_limbs_asc(floor_root_limbs);
985                    if inexact { None } else { Some(floor_root) }
986                }
987            },
988        }
989    }
990}
991
992impl RootRem<u64> for Natural {
993    type RootOutput = Self;
994    type RemOutput = Self;
995
996    /// Returns the floor of the $n$th root of a [`Natural`], and the remainder (the difference
997    /// between the [`Natural`] and the $n$th power of the floor). The [`Natural`] is taken by
998    /// value.
999    ///
1000    /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^n)$.
1001    ///
1002    /// # Worst-case complexity
1003    /// $T(n) = O(n (\log n)^2 \log\log n)$
1004    ///
1005    /// $M(n) = O(n \log n)$
1006    ///
1007    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1008    ///
1009    /// # Examples
1010    /// ```
1011    /// use malachite_base::num::arithmetic::traits::RootRem;
1012    /// use malachite_base::strings::ToDebugString;
1013    /// use malachite_nz::natural::Natural;
1014    ///
1015    /// assert_eq!(
1016    ///     Natural::from(999u16).root_rem(3).to_debug_string(),
1017    ///     "(9, 270)"
1018    /// );
1019    /// assert_eq!(
1020    ///     Natural::from(1000u16).root_rem(3).to_debug_string(),
1021    ///     "(10, 0)"
1022    /// );
1023    /// assert_eq!(
1024    ///     Natural::from(1001u16).root_rem(3).to_debug_string(),
1025    ///     "(10, 1)"
1026    /// );
1027    /// assert_eq!(
1028    ///     Natural::from(100000000000u64).root_rem(5).to_debug_string(),
1029    ///     "(158, 1534195232)"
1030    /// );
1031    /// ```
1032    fn root_rem(self, exp: u64) -> (Self, Self) {
1033        match exp {
1034            0 => panic!("Cannot take 0th root"),
1035            1 => (self, Self::ZERO),
1036            2 => self.sqrt_rem(),
1037            exp => match self {
1038                Self(Small(x)) => {
1039                    let (root, rem) = x.root_rem(exp);
1040                    (Self(Small(root)), Self(Small(rem)))
1041                }
1042                Self(Large(xs)) => {
1043                    let (root_limbs, rem_limbs) = limbs_root_rem(&xs, exp);
1044                    (
1045                        Self::from_owned_limbs_asc(root_limbs),
1046                        Self::from_owned_limbs_asc(rem_limbs),
1047                    )
1048                }
1049            },
1050        }
1051    }
1052}
1053
1054impl RootRem<u64> for &Natural {
1055    type RootOutput = Natural;
1056    type RemOutput = Natural;
1057
1058    /// Returns the floor of the $n$th root of a [`Natural`], and the remainder (the difference
1059    /// between the [`Natural`] and the $n$th power of the floor). The [`Natural`] is taken by
1060    /// reference.
1061    ///
1062    /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^n)$.
1063    ///
1064    /// # Worst-case complexity
1065    /// $T(n) = O(n (\log n)^2 \log\log n)$
1066    ///
1067    /// $M(n) = O(n \log n)$
1068    ///
1069    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1070    ///
1071    /// # Examples
1072    /// ```
1073    /// use malachite_base::num::arithmetic::traits::RootRem;
1074    /// use malachite_base::strings::ToDebugString;
1075    /// use malachite_nz::natural::Natural;
1076    ///
1077    /// assert_eq!(
1078    ///     (&Natural::from(999u16)).root_rem(3).to_debug_string(),
1079    ///     "(9, 270)"
1080    /// );
1081    /// assert_eq!(
1082    ///     (&Natural::from(1000u16)).root_rem(3).to_debug_string(),
1083    ///     "(10, 0)"
1084    /// );
1085    /// assert_eq!(
1086    ///     (&Natural::from(1001u16)).root_rem(3).to_debug_string(),
1087    ///     "(10, 1)"
1088    /// );
1089    /// assert_eq!(
1090    ///     (&Natural::from(100000000000u64))
1091    ///         .root_rem(5)
1092    ///         .to_debug_string(),
1093    ///     "(158, 1534195232)"
1094    /// );
1095    /// ```
1096    fn root_rem(self, exp: u64) -> (Natural, Natural) {
1097        match exp {
1098            0 => panic!("Cannot take 0th root"),
1099            1 => (self.clone(), Natural::ZERO),
1100            2 => self.sqrt_rem(),
1101            exp => match self {
1102                Natural(Small(x)) => {
1103                    let (root, rem) = x.root_rem(exp);
1104                    (Natural(Small(root)), Natural(Small(rem)))
1105                }
1106                Natural(Large(xs)) => {
1107                    let (root_limbs, rem_limbs) = limbs_root_rem(xs, exp);
1108                    (
1109                        Natural::from_owned_limbs_asc(root_limbs),
1110                        Natural::from_owned_limbs_asc(rem_limbs),
1111                    )
1112                }
1113            },
1114        }
1115    }
1116}
1117
1118impl RootAssignRem<u64> for Natural {
1119    type RemOutput = Self;
1120
1121    /// Replaces a [`Natural`] with the floor of its $n$th root, and returns the remainder (the
1122    /// difference between the original [`Natural`] and the $n$th power of the floor).
1123    ///
1124    /// $f(x, n) = x - \lfloor\sqrt\[n\]{x}\rfloor^n$,
1125    ///
1126    /// $x \gets \lfloor\sqrt\[n\]{x}\rfloor$.
1127    ///
1128    /// # Worst-case complexity
1129    /// $T(n) = O(n (\log n)^2 \log\log n)$
1130    ///
1131    /// $M(n) = O(n \log n)$
1132    ///
1133    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
1134    ///
1135    /// # Examples
1136    /// ```
1137    /// use malachite_base::num::arithmetic::traits::RootAssignRem;
1138    /// use malachite_nz::natural::Natural;
1139    ///
1140    /// let mut x = Natural::from(999u16);
1141    /// assert_eq!(x.root_assign_rem(3), 270);
1142    /// assert_eq!(x, 9);
1143    ///
1144    /// let mut x = Natural::from(1000u16);
1145    /// assert_eq!(x.root_assign_rem(3), 0);
1146    /// assert_eq!(x, 10);
1147    ///
1148    /// let mut x = Natural::from(1001u16);
1149    /// assert_eq!(x.root_assign_rem(3), 1);
1150    /// assert_eq!(x, 10);
1151    ///
1152    /// let mut x = Natural::from(100000000000u64);
1153    /// assert_eq!(x.root_assign_rem(5), 1534195232);
1154    /// assert_eq!(x, 158);
1155    /// ```
1156    #[inline]
1157    fn root_assign_rem(&mut self, exp: u64) -> Self {
1158        let rem;
1159        (*self, rem) = (&*self).root_rem(exp);
1160        rem
1161    }
1162}