malachite_nz/integer/arithmetic/root.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::integer::Integer;
10use crate::natural::Natural;
11use core::ops::Neg;
12use malachite_base::num::arithmetic::traits::{
13 CeilingRoot, CeilingRootAssign, CheckedRoot, FloorRoot, FloorRootAssign, Parity, Pow,
14 RootAssignRem, RootRem, UnsignedAbs,
15};
16use malachite_base::num::basic::traits::{One, Zero};
17
18impl FloorRoot<u64> for Integer {
19 type Output = Self;
20
21 /// Returns the floor of the $n$th root of an [`Integer`], taking the [`Integer`] by value.
22 ///
23 /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$.
24 ///
25 /// # Worst-case complexity
26 /// $T(n) = O(n (\log n)^2 \log\log n)$
27 ///
28 /// $M(n) = O(n \log n)$
29 ///
30 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
31 ///
32 /// # Panics
33 /// Panics if `exp` is zero, or if `exp` is even and `self` is negative.
34 ///
35 /// # Examples
36 /// ```
37 /// use malachite_base::num::arithmetic::traits::FloorRoot;
38 /// use malachite_nz::integer::Integer;
39 ///
40 /// assert_eq!(Integer::from(999).floor_root(3), 9);
41 /// assert_eq!(Integer::from(1000).floor_root(3), 10);
42 /// assert_eq!(Integer::from(1001).floor_root(3), 10);
43 /// assert_eq!(Integer::from(100000000000i64).floor_root(5), 158);
44 /// assert_eq!(Integer::from(-100000000000i64).floor_root(5), -159);
45 /// ```
46 #[inline]
47 fn floor_root(mut self, exp: u64) -> Self {
48 self.floor_root_assign(exp);
49 self
50 }
51}
52
53impl FloorRoot<u64> for &Integer {
54 type Output = Integer;
55
56 /// Returns the floor of the $n$th root of an [`Integer`], taking the [`Integer`] by reference.
57 ///
58 /// $f(x, n) = \lfloor\sqrt\[n\]{x}\rfloor$.
59 ///
60 /// # Worst-case complexity
61 /// $T(n) = O(n (\log n)^2 \log\log n)$
62 ///
63 /// $M(n) = O(n \log n)$
64 ///
65 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
66 ///
67 /// # Panics
68 /// Panics if `exp` is zero, or if `exp` is even and `self` is negative.
69 ///
70 /// # Examples
71 /// ```
72 /// use malachite_base::num::arithmetic::traits::FloorRoot;
73 /// use malachite_nz::integer::Integer;
74 ///
75 /// assert_eq!((&Integer::from(999)).floor_root(3), 9);
76 /// assert_eq!((&Integer::from(1000)).floor_root(3), 10);
77 /// assert_eq!((&Integer::from(1001)).floor_root(3), 10);
78 /// assert_eq!((&Integer::from(100000000000i64)).floor_root(5), 158);
79 /// assert_eq!((&Integer::from(-100000000000i64)).floor_root(5), -159);
80 /// ```
81 #[inline]
82 fn floor_root(self, exp: u64) -> Integer {
83 if *self >= 0u32 {
84 Integer::from(self.unsigned_abs_ref().floor_root(exp))
85 } else if exp.odd() {
86 -self.unsigned_abs_ref().ceiling_root(exp)
87 } else {
88 panic!("Cannot take even root of {self}")
89 }
90 }
91}
92
93impl FloorRootAssign<u64> for Integer {
94 /// Replaces an [`Integer`] with the floor of its $n$th root.
95 ///
96 /// $x \gets \lfloor\sqrt\[n\]{x}\rfloor$.
97 ///
98 /// # Worst-case complexity
99 /// $T(n) = O(n (\log n)^2 \log\log n)$
100 ///
101 /// $M(n) = O(n \log n)$
102 ///
103 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
104 ///
105 /// # Panics
106 /// Panics if `exp` is zero, or if `exp` is even and `self` is negative.
107 ///
108 /// # Examples
109 /// ```
110 /// use malachite_base::num::arithmetic::traits::FloorRootAssign;
111 /// use malachite_nz::integer::Integer;
112 ///
113 /// let mut x = Integer::from(999);
114 /// x.floor_root_assign(3);
115 /// assert_eq!(x, 9);
116 ///
117 /// let mut x = Integer::from(1000);
118 /// x.floor_root_assign(3);
119 /// assert_eq!(x, 10);
120 ///
121 /// let mut x = Integer::from(1001);
122 /// x.floor_root_assign(3);
123 /// assert_eq!(x, 10);
124 ///
125 /// let mut x = Integer::from(100000000000i64);
126 /// x.floor_root_assign(5);
127 /// assert_eq!(x, 158);
128 ///
129 /// let mut x = Integer::from(-100000000000i64);
130 /// x.floor_root_assign(5);
131 /// assert_eq!(x, -159);
132 /// ```
133 #[inline]
134 fn floor_root_assign(&mut self, exp: u64) {
135 if *self >= 0u32 {
136 self.mutate_unsigned_abs(|n| n.floor_root_assign(exp));
137 } else if exp.odd() {
138 self.mutate_unsigned_abs(|n| n.ceiling_root_assign(exp));
139 } else {
140 panic!("Cannot take even root of {self}")
141 }
142 }
143}
144
145impl CeilingRoot<u64> for Integer {
146 type Output = Self;
147
148 /// Returns the ceiling of the $n$th root of an [`Integer`], taking the [`Integer`] by value.
149 ///
150 /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$.
151 ///
152 /// # Worst-case complexity
153 /// $T(n) = O(n (\log n)^2 \log\log n)$
154 ///
155 /// $M(n) = O(n \log n)$
156 ///
157 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
158 ///
159 /// # Panics
160 /// Panics if `exp` is zero, or if `exp` is even and `self` is negative.
161 ///
162 /// # Examples
163 /// ```
164 /// use malachite_base::num::arithmetic::traits::CeilingRoot;
165 /// use malachite_nz::integer::Integer;
166 ///
167 /// assert_eq!(Integer::from(999).ceiling_root(3), 10);
168 /// assert_eq!(Integer::from(1000).ceiling_root(3), 10);
169 /// assert_eq!(Integer::from(1001).ceiling_root(3), 11);
170 /// assert_eq!(Integer::from(100000000000i64).ceiling_root(5), 159);
171 /// assert_eq!(Integer::from(-100000000000i64).ceiling_root(5), -158);
172 /// ```
173 #[inline]
174 fn ceiling_root(mut self, exp: u64) -> Self {
175 self.ceiling_root_assign(exp);
176 self
177 }
178}
179
180impl CeilingRoot<u64> for &Integer {
181 type Output = Integer;
182
183 /// Returns the ceiling of the $n$th root of an [`Integer`], taking the [`Integer`] by
184 /// reference.
185 ///
186 /// $f(x, n) = \lceil\sqrt\[n\]{x}\rceil$.
187 ///
188 /// # Worst-case complexity
189 /// $T(n) = O(n (\log n)^2 \log\log n)$
190 ///
191 /// $M(n) = O(n \log n)$
192 ///
193 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
194 ///
195 /// # Panics
196 /// Panics if `exp` is zero, or if `exp` is even and `self` is negative.
197 ///
198 /// # Examples
199 /// ```
200 /// use malachite_base::num::arithmetic::traits::CeilingRoot;
201 /// use malachite_nz::integer::Integer;
202 ///
203 /// assert_eq!(Integer::from(999).ceiling_root(3), 10);
204 /// assert_eq!(Integer::from(1000).ceiling_root(3), 10);
205 /// assert_eq!(Integer::from(1001).ceiling_root(3), 11);
206 /// assert_eq!(Integer::from(100000000000i64).ceiling_root(5), 159);
207 /// assert_eq!(Integer::from(-100000000000i64).ceiling_root(5), -158);
208 /// ```
209 #[inline]
210 fn ceiling_root(self, exp: u64) -> Integer {
211 if *self >= 0u32 {
212 Integer::from(self.unsigned_abs_ref().ceiling_root(exp))
213 } else if exp.odd() {
214 -self.unsigned_abs_ref().floor_root(exp)
215 } else {
216 panic!("Cannot take even root of {self}")
217 }
218 }
219}
220
221impl CeilingRootAssign<u64> for Integer {
222 /// Replaces an [`Integer`] with the ceiling of its $n$th root.
223 ///
224 /// $x \gets \lceil\sqrt\[n\]{x}\rceil$.
225 ///
226 /// # Worst-case complexity
227 /// $T(n) = O(n (\log n)^2 \log\log n)$
228 ///
229 /// $M(n) = O(n \log n)$
230 ///
231 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
232 ///
233 /// # Panics
234 /// Panics if `exp` is zero, or if `exp` is even and `self` is negative.
235 ///
236 /// # Examples
237 /// ```
238 /// use malachite_base::num::arithmetic::traits::CeilingRootAssign;
239 /// use malachite_nz::integer::Integer;
240 ///
241 /// let mut x = Integer::from(999);
242 /// x.ceiling_root_assign(3);
243 /// assert_eq!(x, 10);
244 ///
245 /// let mut x = Integer::from(1000);
246 /// x.ceiling_root_assign(3);
247 /// assert_eq!(x, 10);
248 ///
249 /// let mut x = Integer::from(1001);
250 /// x.ceiling_root_assign(3);
251 /// assert_eq!(x, 11);
252 ///
253 /// let mut x = Integer::from(100000000000i64);
254 /// x.ceiling_root_assign(5);
255 /// assert_eq!(x, 159);
256 ///
257 /// let mut x = Integer::from(-100000000000i64);
258 /// x.ceiling_root_assign(5);
259 /// assert_eq!(x, -158);
260 /// ```
261 #[inline]
262 fn ceiling_root_assign(&mut self, exp: u64) {
263 if *self >= 0u32 {
264 self.mutate_unsigned_abs(|n| n.ceiling_root_assign(exp));
265 } else if exp.odd() {
266 self.mutate_unsigned_abs(|n| n.floor_root_assign(exp));
267 } else {
268 panic!("Cannot take even root of {self}")
269 }
270 }
271}
272
273impl CheckedRoot<u64> for Integer {
274 type Output = Self;
275
276 /// Returns the the $n$th root of an [`Integer`], or `None` if the [`Integer`] is not a perfect
277 /// $n$th power. The [`Integer`] is taken by value.
278 ///
279 /// $$
280 /// f(x, n) = \\begin{cases}
281 /// \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\
282 /// \operatorname{None} & \textrm{otherwise}.
283 /// \\end{cases}
284 /// $$
285 ///
286 /// # Worst-case complexity
287 /// $T(n) = O(n (\log n)^2 \log\log n)$
288 ///
289 /// $M(n) = O(n \log n)$
290 ///
291 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
292 ///
293 /// # Panics
294 /// Panics if `exp` is zero, or if `exp` is even and `self` is negative.
295 ///
296 /// # Examples
297 /// ```
298 /// use malachite_base::num::arithmetic::traits::CheckedRoot;
299 /// use malachite_base::strings::ToDebugString;
300 /// use malachite_nz::integer::Integer;
301 ///
302 /// assert_eq!(Integer::from(999).checked_root(3).to_debug_string(), "None");
303 /// assert_eq!(
304 /// Integer::from(1000).checked_root(3).to_debug_string(),
305 /// "Some(10)"
306 /// );
307 /// assert_eq!(
308 /// Integer::from(1001).checked_root(3).to_debug_string(),
309 /// "None"
310 /// );
311 /// assert_eq!(
312 /// Integer::from(100000000000i64)
313 /// .checked_root(5)
314 /// .to_debug_string(),
315 /// "None"
316 /// );
317 /// assert_eq!(
318 /// Integer::from(-100000000000i64)
319 /// .checked_root(5)
320 /// .to_debug_string(),
321 /// "None"
322 /// );
323 /// assert_eq!(
324 /// Integer::from(10000000000i64)
325 /// .checked_root(5)
326 /// .to_debug_string(),
327 /// "Some(100)"
328 /// );
329 /// assert_eq!(
330 /// Integer::from(-10000000000i64)
331 /// .checked_root(5)
332 /// .to_debug_string(),
333 /// "Some(-100)"
334 /// );
335 /// ```
336 #[inline]
337 fn checked_root(self, exp: u64) -> Option<Self> {
338 if self >= 0u32 {
339 self.unsigned_abs().checked_root(exp).map(Self::from)
340 } else if exp.odd() {
341 self.unsigned_abs().checked_root(exp).map(Natural::neg)
342 } else {
343 panic!("Cannot take even root of {self}")
344 }
345 }
346}
347
348impl CheckedRoot<u64> for &Integer {
349 type Output = Integer;
350
351 /// Returns the the $n$th root of an [`Integer`], or `None` if the [`Integer`] is not a perfect
352 /// $n$th power. The [`Integer`] is taken by reference.
353 ///
354 /// $$
355 /// f(x, n) = \\begin{cases}
356 /// \operatorname{Some}(sqrt\[n\]{x}) & \text{if} \\quad \sqrt\[n\]{x} \in \Z, \\\\
357 /// \operatorname{None} & \textrm{otherwise}.
358 /// \\end{cases}
359 /// $$
360 ///
361 /// # Worst-case complexity
362 /// $T(n) = O(n (\log n)^2 \log\log n)$
363 ///
364 /// $M(n) = O(n \log n)$
365 ///
366 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
367 ///
368 /// # Panics
369 /// Panics if `exp` is zero, or if `exp` is even and `self` is negative.
370 ///
371 /// # Examples
372 /// ```
373 /// use malachite_base::num::arithmetic::traits::CheckedRoot;
374 /// use malachite_base::strings::ToDebugString;
375 /// use malachite_nz::integer::Integer;
376 ///
377 /// assert_eq!(
378 /// (&Integer::from(999)).checked_root(3).to_debug_string(),
379 /// "None"
380 /// );
381 /// assert_eq!(
382 /// (&Integer::from(1000)).checked_root(3).to_debug_string(),
383 /// "Some(10)"
384 /// );
385 /// assert_eq!(
386 /// (&Integer::from(1001)).checked_root(3).to_debug_string(),
387 /// "None"
388 /// );
389 /// assert_eq!(
390 /// (&Integer::from(100000000000i64))
391 /// .checked_root(5)
392 /// .to_debug_string(),
393 /// "None"
394 /// );
395 /// assert_eq!(
396 /// (&Integer::from(-100000000000i64))
397 /// .checked_root(5)
398 /// .to_debug_string(),
399 /// "None"
400 /// );
401 /// assert_eq!(
402 /// (&Integer::from(10000000000i64))
403 /// .checked_root(5)
404 /// .to_debug_string(),
405 /// "Some(100)"
406 /// );
407 /// assert_eq!(
408 /// (&Integer::from(-10000000000i64))
409 /// .checked_root(5)
410 /// .to_debug_string(),
411 /// "Some(-100)"
412 /// );
413 /// ```
414 #[inline]
415 fn checked_root(self, exp: u64) -> Option<Integer> {
416 if *self >= 0u32 {
417 self.unsigned_abs_ref().checked_root(exp).map(Integer::from)
418 } else if exp.odd() {
419 self.unsigned_abs_ref().checked_root(exp).map(Natural::neg)
420 } else {
421 panic!("Cannot take even root of {self}")
422 }
423 }
424}
425
426// The floor root of a negative value is the negated ceiling root of its absolute value, so the
427// remainder is what the absolute value falls short of that ceiling root's power.
428fn root_rem_neg(abs: Natural, exp: u64) -> (Integer, Integer) {
429 let (floor, rem) = (&abs).root_rem(exp);
430 if rem == 0u32 {
431 (-Integer::from(floor), Integer::ZERO)
432 } else {
433 let ceiling = floor + Natural::ONE;
434 let rem = (&ceiling).pow(exp) - abs;
435 (-Integer::from(ceiling), Integer::from(rem))
436 }
437}
438
439impl RootRem<u64> for Integer {
440 type RootOutput = Self;
441 type RemOutput = Self;
442
443 /// Returns the floor of the $n$th root of an [`Integer`], and the remainder (the difference
444 /// between the [`Integer`] and the $n$th power of the floor).
445 ///
446 /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^n)$.
447 ///
448 /// The remainder is always non-negative, because the root is rounded toward negative infinity.
449 /// GMP's `mpz_rootrem` truncates toward zero instead, so on a negative operand its root is this
450 /// one plus 1, unless the root is exact, and its remainder is negative; see [`CeilingRoot`] for
451 /// that convention.
452 ///
453 /// # Worst-case complexity
454 /// $T(n) = O(n (\log n)^2 \log\log n)$
455 ///
456 /// $M(n) = O(n \log n)$
457 ///
458 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
459 ///
460 /// # Panics
461 /// Panics if `exp` is zero, or if `self` is negative and `exp` is even.
462 ///
463 /// The [`Integer`] is taken by value.
464 ///
465 /// # Examples
466 /// ```
467 /// use malachite_base::num::arithmetic::traits::RootRem;
468 /// use malachite_base::num::basic::traits::{One, Zero};
469 /// use malachite_nz::integer::Integer;
470 ///
471 /// assert_eq!(
472 /// Integer::from(999).root_rem(3),
473 /// (Integer::from(9), Integer::from(270))
474 /// );
475 /// assert_eq!(
476 /// Integer::from(1000).root_rem(3),
477 /// (Integer::from(10), Integer::ZERO)
478 /// );
479 /// // the root is rounded down, so the remainder stays non-negative
480 /// assert_eq!(
481 /// Integer::from(-999).root_rem(3),
482 /// (Integer::from(-10), Integer::ONE)
483 /// );
484 /// assert_eq!(
485 /// Integer::from(-1000).root_rem(3),
486 /// (Integer::from(-10), Integer::ZERO)
487 /// );
488 /// ```
489 fn root_rem(self, exp: u64) -> (Self, Self) {
490 if self >= 0u32 {
491 let (root, rem) = self.unsigned_abs().root_rem(exp);
492 (Self::from(root), Self::from(rem))
493 } else if exp.odd() {
494 root_rem_neg(self.unsigned_abs(), exp)
495 } else {
496 panic!("Cannot take even root of a negative Integer")
497 }
498 }
499}
500
501impl RootRem<u64> for &Integer {
502 type RootOutput = Integer;
503 type RemOutput = Integer;
504
505 /// Returns the floor of the $n$th root of an [`Integer`], and the remainder (the difference
506 /// between the [`Integer`] and the $n$th power of the floor).
507 ///
508 /// $f(x, n) = (\lfloor\sqrt\[n\]{x}\rfloor, x - \lfloor\sqrt\[n\]{x}\rfloor^n)$.
509 ///
510 /// The remainder is always non-negative, because the root is rounded toward negative infinity.
511 /// GMP's `mpz_rootrem` truncates toward zero instead, so on a negative operand its root is this
512 /// one plus 1, unless the root is exact, and its remainder is negative; see [`CeilingRoot`] for
513 /// that convention.
514 ///
515 /// # Worst-case complexity
516 /// $T(n) = O(n (\log n)^2 \log\log n)$
517 ///
518 /// $M(n) = O(n \log n)$
519 ///
520 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
521 ///
522 /// # Panics
523 /// Panics if `exp` is zero, or if `self` is negative and `exp` is even.
524 ///
525 /// The [`Integer`] is taken by reference.
526 ///
527 /// # Examples
528 /// ```
529 /// use malachite_base::num::arithmetic::traits::RootRem;
530 /// use malachite_base::num::basic::traits::{One, Zero};
531 /// use malachite_nz::integer::Integer;
532 ///
533 /// assert_eq!(
534 /// (&Integer::from(999)).root_rem(3),
535 /// (Integer::from(9), Integer::from(270))
536 /// );
537 /// assert_eq!(
538 /// (&Integer::from(1000)).root_rem(3),
539 /// (Integer::from(10), Integer::ZERO)
540 /// );
541 /// // the root is rounded down, so the remainder stays non-negative
542 /// assert_eq!(
543 /// (&Integer::from(-999)).root_rem(3),
544 /// (Integer::from(-10), Integer::ONE)
545 /// );
546 /// assert_eq!(
547 /// (&Integer::from(-1000)).root_rem(3),
548 /// (Integer::from(-10), Integer::ZERO)
549 /// );
550 /// ```
551 fn root_rem(self, exp: u64) -> (Integer, Integer) {
552 if *self >= 0u32 {
553 let (root, rem) = self.unsigned_abs_ref().root_rem(exp);
554 (Integer::from(root), Integer::from(rem))
555 } else if exp.odd() {
556 root_rem_neg(self.unsigned_abs(), exp)
557 } else {
558 panic!("Cannot take even root of a negative Integer")
559 }
560 }
561}
562
563impl RootAssignRem<u64> for Integer {
564 type RemOutput = Self;
565
566 /// Replaces an [`Integer`] with the floor of its $n$th root, and returns the remainder (the
567 /// difference between the original [`Integer`] and the $n$th power of the floor).
568 ///
569 /// $f(x, n) = x - \lfloor\sqrt\[n\]{x}\rfloor^n$,
570 ///
571 /// $x \gets \lfloor\sqrt\[n\]{x}\rfloor$.
572 ///
573 /// The remainder is always non-negative; see [`RootRem`] for how that compares with GMP.
574 ///
575 /// # Worst-case complexity
576 /// $T(n) = O(n (\log n)^2 \log\log n)$
577 ///
578 /// $M(n) = O(n \log n)$
579 ///
580 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
581 ///
582 /// # Panics
583 /// Panics if `exp` is zero, or if `self` is negative and `exp` is even.
584 ///
585 /// # Examples
586 /// ```
587 /// use malachite_base::num::arithmetic::traits::RootAssignRem;
588 /// use malachite_nz::integer::Integer;
589 ///
590 /// let mut x = Integer::from(999);
591 /// assert_eq!(x.root_assign_rem(3), 270);
592 /// assert_eq!(x, 9);
593 ///
594 /// let mut x = Integer::from(-999);
595 /// assert_eq!(x.root_assign_rem(3), 1);
596 /// assert_eq!(x, -10);
597 /// ```
598 fn root_assign_rem(&mut self, exp: u64) -> Self {
599 let (root, rem) = core::mem::take(self).root_rem(exp);
600 *self = root;
601 rem
602 }
603}