Pow no longer returns 1 when 0⁰ is given.
pow now panics in case of 0⁰ check_pow now returns None in case of 0⁰ pow and checked_pow now requires the trait 'Zero' as we need it to check if base is zero when exp is zero. Added basic seperate tests to check that basic behaivor works, and that bought pow and checked_pow behaves correclty when 0⁰ is given. Updated the documentation to state behavior in 0⁰ case. Fixes #77
This commit is contained in:
parent
a415e2a751
commit
8736892882
39
src/pow.rs
39
src/pow.rs
|
@ -1,6 +1,6 @@
|
|||
use core::num::Wrapping;
|
||||
use core::ops::Mul;
|
||||
use {CheckedMul, One};
|
||||
use {CheckedMul, Zero, One};
|
||||
|
||||
/// Binary operator for raising a value to a power.
|
||||
pub trait Pow<RHS> {
|
||||
|
@ -172,6 +172,7 @@ mod float_impls {
|
|||
}
|
||||
|
||||
/// Raises a value to the power of exp, using exponentiation by squaring.
|
||||
/// Panics if pow(0, 0) (0⁰ is undefined)
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -182,9 +183,13 @@ mod float_impls {
|
|||
/// assert_eq!(pow(6u8, 3), 216);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) -> T {
|
||||
pub fn pow<T: Clone + Zero + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) -> T {
|
||||
if exp == 0 {
|
||||
return T::one();
|
||||
return if base.is_zero() {
|
||||
panic!("0⁰ is undefined")
|
||||
} else {
|
||||
T::one()
|
||||
}
|
||||
}
|
||||
|
||||
while exp & 1 == 0 {
|
||||
|
@ -207,6 +212,7 @@ pub fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) ->
|
|||
}
|
||||
|
||||
/// Raises a value to the power of exp, returning `None` if an overflow occurred.
|
||||
/// Also returns None if checked_pow(0, 0) was entered (0⁰ is undefined)
|
||||
///
|
||||
/// Otherwise same as the `pow` function.
|
||||
///
|
||||
|
@ -218,11 +224,16 @@ pub fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) ->
|
|||
/// 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));
|
||||
/// assert_eq!(checked_pow(0i8, 0), None); //undefined
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn checked_pow<T: Clone + One + CheckedMul>(mut base: T, mut exp: usize) -> Option<T> {
|
||||
pub fn checked_pow<T: Clone + Zero + One + CheckedMul>(mut base: T, mut exp: usize) -> Option<T> {
|
||||
if exp == 0 {
|
||||
return Some(T::one());
|
||||
return if base.is_zero() {
|
||||
None
|
||||
} else {
|
||||
Some(T::one())
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! optry {
|
||||
|
@ -253,3 +264,21 @@ pub fn checked_pow<T: Clone + One + CheckedMul>(mut base: T, mut exp: usize) ->
|
|||
}
|
||||
Some(acc)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn pow_3_3() {
|
||||
assert_eq!(super::checked_pow(3, 3), Some(27));
|
||||
assert_eq!(super::pow(3, 3), 27);
|
||||
}
|
||||
#[test]
|
||||
fn checked_pow_0_0() {
|
||||
assert_eq!(super::checked_pow(0, 0), None);
|
||||
}
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn pow_0_0() {
|
||||
super::pow(0, 0);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue