Skip to main content

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}