malachite_nz/integer/arithmetic/
pow.rs

1// Copyright © 2025 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 malachite_base::num::arithmetic::traits::{Parity, Pow, PowAssign};
11
12impl Pow<u64> for Integer {
13    type Output = Self;
14
15    /// Raises an [`Integer`] to a power, taking the [`Integer`] by value.
16    ///
17    /// $f(x, n) = x^n$.
18    ///
19    /// # Worst-case complexity
20    /// $T(n, m) = O(nm \log (nm) \log\log (nm))$
21    ///
22    /// $M(n, m) = O(nm \log (nm))$
23    ///
24    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $m$ is
25    /// `exp`.
26    ///
27    /// # Examples
28    /// ```
29    /// use core::str::FromStr;
30    /// use malachite_base::num::arithmetic::traits::Pow;
31    /// use malachite_nz::integer::Integer;
32    ///
33    /// assert_eq!(
34    ///     Integer::from(-3).pow(100).to_string(),
35    ///     "515377520732011331036461129765621272702107522001"
36    /// );
37    /// assert_eq!(
38    ///     Integer::from_str("-12345678987654321")
39    ///         .unwrap()
40    ///         .pow(3)
41    ///         .to_string(),
42    ///     "-1881676411868862234942354805142998028003108518161"
43    /// );
44    /// ```
45    #[inline]
46    fn pow(mut self, exp: u64) -> Self {
47        self.pow_assign(exp);
48        self
49    }
50}
51
52impl Pow<u64> for &Integer {
53    type Output = Integer;
54
55    /// Raises an [`Integer`] to a power, taking the [`Integer`] by reference.
56    ///
57    /// $f(x, n) = x^n$.
58    ///
59    /// # Worst-case complexity
60    /// $T(n, m) = O(nm \log (nm) \log\log (nm))$
61    ///
62    /// $M(n, m) = O(nm \log (nm))$
63    ///
64    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $m$ is
65    /// `exp`.
66    ///
67    /// # Examples
68    /// ```
69    /// use core::str::FromStr;
70    /// use malachite_base::num::arithmetic::traits::Pow;
71    /// use malachite_nz::integer::Integer;
72    ///
73    /// assert_eq!(
74    ///     (&Integer::from(-3)).pow(100).to_string(),
75    ///     "515377520732011331036461129765621272702107522001"
76    /// );
77    /// assert_eq!(
78    ///     (&Integer::from_str("-12345678987654321").unwrap())
79    ///         .pow(3)
80    ///         .to_string(),
81    ///     "-1881676411868862234942354805142998028003108518161"
82    /// );
83    /// ```
84    #[inline]
85    fn pow(self, exp: u64) -> Integer {
86        Integer {
87            sign: exp.even() || self.sign,
88            abs: (&self.abs).pow(exp),
89        }
90    }
91}
92
93impl PowAssign<u64> for Integer {
94    /// Raises an [`Integer`] to a power in place.
95    ///
96    /// $x \gets x^n$.
97    ///
98    /// # Worst-case complexity
99    /// $T(n, m) = O(nm \log (nm) \log\log (nm))$
100    ///
101    /// $M(n, m) = O(nm \log (nm))$
102    ///
103    /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits()`, and $m$ is
104    /// `exp`.
105    ///
106    /// # Examples
107    /// ```
108    /// use core::str::FromStr;
109    /// use malachite_base::num::arithmetic::traits::PowAssign;
110    /// use malachite_nz::integer::Integer;
111    ///
112    /// let mut x = Integer::from(-3);
113    /// x.pow_assign(100);
114    /// assert_eq!(
115    ///     x.to_string(),
116    ///     "515377520732011331036461129765621272702107522001"
117    /// );
118    ///
119    /// let mut x = Integer::from_str("-12345678987654321").unwrap();
120    /// x.pow_assign(3);
121    /// assert_eq!(
122    ///     x.to_string(),
123    ///     "-1881676411868862234942354805142998028003108518161"
124    /// );
125    /// ```
126    fn pow_assign(&mut self, exp: u64) {
127        self.sign = self.sign || exp.even();
128        self.abs.pow_assign(exp);
129    }
130}