From c1f4118b4e161fcde40be80d979b138c9f62e20b Mon Sep 17 00:00:00 2001 From: Clar Charr Date: Mon, 19 Feb 2018 15:00:36 -0500 Subject: [PATCH] Fix Inv trait, add Pow trait. --- src/lib.rs | 1 + src/ops/inv.rs | 49 ++++++++++++++++++++-------------- src/ops/mod.rs | 3 ++- src/ops/pow.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 20 deletions(-) create mode 100644 src/ops/pow.rs diff --git a/src/lib.rs b/src/lib.rs index 2b4844b..bf98f2b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,6 +34,7 @@ pub use float::FloatConst; // pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`. pub use identities::{Zero, One, zero, one}; pub use ops::inv::Inv; +pub use ops::pow::Pow; pub use ops::checked::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, CheckedShl, CheckedShr}; pub use ops::wrapping::{WrappingAdd, WrappingMul, WrappingSub}; pub use ops::saturating::Saturating; diff --git a/src/ops/inv.rs b/src/ops/inv.rs index 16f3643..9d04cd2 100644 --- a/src/ops/inv.rs +++ b/src/ops/inv.rs @@ -3,27 +3,38 @@ pub trait Inv { /// The result after applying the operator. type Output; - /// Returns the multiplicative inverse of `Self`. + /// Returns the multiplicative inverse of `self`. + /// + /// # Examples + /// + /// ``` + /// use num_traits::{Inv, One}; + /// + /// let x = 7.0; + /// let y = -0.0; + /// assert_eq!(x.inv() * x, One::one()); + /// assert_eq!(y.inv() * y, One::one()); + /// ``` fn inv(self) -> Self::Output; } -macro_rules! inv_impl { - ($t:ty, $out:ty, $fn:expr) => { - impl<'a> Inv for $t { - type Output = $out; - - #[inline] - fn inv(self) -> $out { - ($fn)(self) - } - } - } +impl Inv for f32 { + type Output = f32; + #[inline] + fn inv(self) -> f32 { 1.0 / self } } - -#[cfg(feature = "std")] -mod float_impls { - inv_impl!(f32, f32, f32::recip); - inv_impl!(f64, f64, f64::recip); - inv_impl!(&'a f32, f32, f32::recip); - inv_impl!(&'a f64, f64, f64::recip); +impl Inv for f64 { + type Output = f64; + #[inline] + fn inv(self) -> f64 { 1.0 / self } +} +impl<'a> Inv for &'a f32 { + type Output = f32; + #[inline] + fn inv(self) -> f32 { 1.0 / *self } +} +impl<'a> Inv for &'a f64 { + type Output = f64; + #[inline] + fn inv(self) -> f64 { 1.0 / *self } } diff --git a/src/ops/mod.rs b/src/ops/mod.rs index b83a2a5..6f7f022 100644 --- a/src/ops/mod.rs +++ b/src/ops/mod.rs @@ -1,4 +1,5 @@ pub mod saturating; pub mod checked; pub mod wrapping; -pub mod new; +pub mod inv; +pub mod pow; diff --git a/src/ops/pow.rs b/src/ops/pow.rs new file mode 100644 index 0000000..9f7dd1e --- /dev/null +++ b/src/ops/pow.rs @@ -0,0 +1,71 @@ +/// Binary operator for raising a value to a power. +pub trait Pow { + /// The result after applying the operator. + type Output; + + /// Returns `self` to the power `rhs`. + /// + /// # Examples + /// + /// ``` + /// use num_traits::Pow; + /// assert_eq!(10.pow(2), 100); + /// ``` + fn pow(self, rhs: RHS) -> Self::Output; +} + +macro_rules! pow_impl { + ($t:ty, $rhs:ty, $method:ident) => { + impl Pow<$rhs> for $t { + type Output = $t; + + #[inline] + fn pow(self, rhs: $rhs) -> $t { + <$t>::$method(self, rhs) + } + } + + impl<'a> Pow<&'a $rhs> for $t { + type Output = $t; + #[inline] + fn pow(self, rhs: &'a $rhs) -> $t { + <$t>::$method(self, *rhs) + } + } + + impl<'a> Pow<$rhs> for &'a $t { + type Output = $t; + #[inline] + fn pow(self, rhs: $rhs) -> $t { + <$t>::$method(*self, rhs) + } + } + + impl<'a, 'b> Pow<&'a $rhs> for &'b $t { + type Output = $t; + #[inline] + fn pow(self, rhs: &'a $rhs) -> $t { + <$t>::$method(*self, *rhs) + } + } + } +} + +pow_impl!(u8, u32, pow); +pow_impl!(i8, u32, pow); +pow_impl!(u16, u32, pow); +pow_impl!(i16, u32, pow); +pow_impl!(u32, u32, pow); +pow_impl!(i32, u32, pow); +pow_impl!(u64, u32, pow); +pow_impl!(i64, u32, pow); +pow_impl!(usize, u32, pow); +pow_impl!(isize, u32, pow); + +#[cfg(feature = "std")] +mod float_impls { + pow_impl!(f32, i32, powi); + pow_impl!(f64, i32, powi); + pow_impl!(f32, f32, powf); + pow_impl!(f64, f64, powf); +}