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}