     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73

    use std::ops::Mul;
    use {One, CheckedMul};

    /// Raises a value to the power of exp, using exponentiation by squaring.
    ///
    /// # Example
    ///
    /// ```rust
    /// use num_traits::pow;
    ///
    /// assert_eq!(pow(2i8, 4), 16);
    /// assert_eq!(pow(6u8, 3), 216);
    /// ```
    #[inline]
    pub fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) -> T {
        if exp == 0 { return T::one() }

        while exp & 1 == 0 {
            base = base.clone() * base;
            exp >>= 1;
        }
        if exp == 1 { return base }

        let mut acc = base.clone();
        while exp > 1 {
            exp >>= 1;
            base = base.clone() * base;
            if exp & 1 == 1 {
                acc = acc * base.clone();
            }
        }
        acc
    }

    /// Raises a value to the power of exp, returning `None` if an overflow occurred.
    ///
    /// Otherwise same as the `pow` function.
    ///
    /// # Example
    ///
    /// ```rust
    /// use num_traits::checked_pow;
    ///
    /// assert_eq!(checked_pow(2i8, 4), Some(16));
    /// assert_eq!(checked_pow(7i8, 8), None);
    /// assert_eq!(checked_pow(7u32, 8), Some(5_764_801));
    /// ```
    #[inline]
    pub fn checked_pow<T: Clone + One + CheckedMul>(mut base: T, mut exp: usize) -> Option<T> {
        if exp == 0 { return Some(T::one()) }

        macro_rules! optry {
            ( $ expr : expr ) => {
                if let Some(val) = $expr { val } else { return None }
            }
        }

        while exp & 1 == 0 {
            base = optry!(base.checked_mul(&base));
            exp >>= 1;
        }
        if exp == 1 { return Some(base) }

        let mut acc = base.clone();
        while exp > 1 {
            exp >>= 1;
            base = optry!(base.checked_mul(&base));
            if exp & 1 == 1 {
                acc = optry!(acc.checked_mul(&base));
            }
        }
        Some(acc)
    }

# Help

## Keyboard Shortcuts

?
  Show this help dialog
S
  Focus the search field
⇤
  Move up in search results
⇥
  Move down in search results
⏎
  Go to active search result
+
  Collapse/expand all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)