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}