ibig/
pow.rs

1//! Exponentiation.
2
3use crate::{
4    ibig::IBig,
5    primitive::PrimitiveUnsigned,
6    sign::Sign::*,
7    ubig::{Repr::*, UBig},
8};
9
10impl UBig {
11    /// Raises self to the power of `exp`.
12    ///
13    /// # Example
14    ///
15    /// ```
16    /// # use ibig::ubig;
17    /// assert_eq!(ubig!(3).pow(3), ubig!(27));
18    /// ```
19    #[inline]
20    pub fn pow(&self, exp: usize) -> UBig {
21        match exp {
22            0 => return UBig::from_word(1),
23            1 => return self.clone(),
24            2 => return self * self,
25            _ => {}
26        }
27        match self.repr() {
28            Small(0) => return UBig::from_word(0),
29            Small(1) => return UBig::from_word(1),
30            Small(2) => {
31                let mut x = UBig::from_word(0);
32                x.set_bit(exp);
33                return x;
34            }
35            _ => {}
36        }
37        let mut p = usize::BIT_SIZE - 2 - exp.leading_zeros();
38        let mut res = self * self;
39        loop {
40            if exp & (1 << p) != 0 {
41                res *= self;
42            }
43            if p == 0 {
44                break;
45            }
46            p -= 1;
47            res = &res * &res;
48        }
49        res
50    }
51}
52
53impl IBig {
54    /// Raises self to the power of `exp`.
55    ///
56    /// # Example
57    ///
58    /// ```
59    /// # use ibig::ibig;
60    /// assert_eq!(ibig!(-3).pow(3), ibig!(-27));
61    /// ```
62    #[inline]
63    pub fn pow(&self, exp: usize) -> IBig {
64        let sign = if self.sign() == Negative && exp % 2 == 1 {
65            Negative
66        } else {
67            Positive
68        };
69        IBig::from_sign_magnitude(sign, self.magnitude().pow(exp))
70    }
71}