1use crate::{
4 ibig::IBig,
5 primitive::PrimitiveUnsigned,
6 sign::Sign::*,
7 ubig::{Repr::*, UBig},
8};
9
10impl UBig {
11 #[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 #[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}