From 4234eb76aa943a862c6f8eda4eb67e4eca6b3f17 Mon Sep 17 00:00:00 2001 From: Yoan Lecoq Date: Sun, 3 Feb 2019 15:21:18 +0100 Subject: [PATCH] libm fallback for Pow, factorize MulAdd --- README.md | 4 ++-- src/ops/mul_add.rs | 54 +++++++--------------------------------------- src/pow.rs | 29 +++++++++++++------------ 3 files changed, 25 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 2b9cbcb..2aa1dd7 100644 --- a/README.md +++ b/README.md @@ -31,13 +31,13 @@ the default `std` feature. Use this in `Cargo.toml`: [dependencies.num-traits] version = "0.2" default-features = false -# features = ["libm"] # <--- Uncomment if you wish to use `Float` and `Real` +# features = ["libm"] # <--- Uncomment if you wish to use `Float` and `Real` without `std` ``` The `Float` and `Real` traits are only available when either `std` or `libm` is enabled. The `FloatCore` trait is always available. `MulAdd` and `MulAddAssign` for `f32` -and `f64` also require `std`, as do implementations of signed and floating- +and `f64` also require `std` or `libm`, as do implementations of signed and floating- point exponents in `Pow`. Implementations for `i128` and `u128` are only available with Rust 1.26 and diff --git a/src/ops/mul_add.rs b/src/ops/mul_add.rs index 54b9a71..b217ece 100644 --- a/src/ops/mul_add.rs +++ b/src/ops/mul_add.rs @@ -34,47 +34,26 @@ pub trait MulAddAssign { fn mul_add_assign(&mut self, a: A, b: B); } -#[cfg(feature = "std")] +#[cfg(any(feature = "std", feature = "libm"))] impl MulAdd for f32 { type Output = Self; #[inline] fn mul_add(self, a: Self, b: Self) -> Self::Output { - f32::mul_add(self, a, b) + ::mul_add(self, a, b) } } -#[cfg(feature = "std")] +#[cfg(any(feature = "std", feature = "libm"))] impl MulAdd for f64 { type Output = Self; #[inline] fn mul_add(self, a: Self, b: Self) -> Self::Output { - f64::mul_add(self, a, b) + ::mul_add(self, a, b) } } -#[cfg(all(not(feature = "std"), feature = "libm"))] -impl MulAdd for f32 { - type Output = Self; - - #[inline] - fn mul_add(self, a: Self, b: Self) -> Self::Output { - ::mul_add(self, a, b) - } -} - -#[cfg(all(not(feature = "std"), feature = "libm"))] -impl MulAdd for f64 { - type Output = Self; - - #[inline] - fn mul_add(self, a: Self, b: Self) -> Self::Output { - ::mul_add(self, a, b) - } -} - - macro_rules! mul_add_impl { ($trait_name:ident for $($t:ty)*) => {$( impl $trait_name for $t { @@ -92,39 +71,22 @@ mul_add_impl!(MulAdd for isize usize i8 u8 i16 u16 i32 u32 i64 u64); #[cfg(has_i128)] mul_add_impl!(MulAdd for i128 u128); -#[cfg(feature = "std")] +#[cfg(any(feature = "std", feature = "libm"))] impl MulAddAssign for f32 { #[inline] fn mul_add_assign(&mut self, a: Self, b: Self) { - *self = f32::mul_add(*self, a, b) + *self = ::mul_add(*self, a, b) } } -#[cfg(feature = "std")] +#[cfg(any(feature = "std", feature = "libm"))] impl MulAddAssign for f64 { #[inline] fn mul_add_assign(&mut self, a: Self, b: Self) { - *self = f64::mul_add(*self, a, b) + *self = ::mul_add(*self, a, b) } } -#[cfg(all(not(feature = "std"), feature = "libm"))] -impl MulAddAssign for f32 { - #[inline] - fn mul_add_assign(&mut self, a: Self, b: Self) { - *self = ::mul_add(*self, a, b) - } -} - -#[cfg(all(not(feature = "std"), feature = "libm"))] -impl MulAddAssign for f64 { - #[inline] - fn mul_add_assign(&mut self, a: Self, b: Self) { - *self = ::mul_add(*self, a, b) - } -} - - macro_rules! mul_add_assign_impl { ($trait_name:ident for $($t:ty)*) => {$( impl $trait_name for $t { diff --git a/src/pow.rs b/src/pow.rs index daf7b41..df2ef9f 100644 --- a/src/pow.rs +++ b/src/pow.rs @@ -152,23 +152,24 @@ pow_impl!(Wrapping); // pow_impl!(usize, u64); // pow_impl!(isize, u64); -#[cfg(feature = "std")] +#[cfg(any(feature = "std", feature = "libm"))] mod float_impls { use super::Pow; + use ::Float; - pow_impl!(f32, i8, i32, f32::powi); - pow_impl!(f32, u8, i32, f32::powi); - pow_impl!(f32, i16, i32, f32::powi); - pow_impl!(f32, u16, i32, f32::powi); - pow_impl!(f32, i32, i32, f32::powi); - pow_impl!(f64, i8, i32, f64::powi); - pow_impl!(f64, u8, i32, f64::powi); - pow_impl!(f64, i16, i32, f64::powi); - pow_impl!(f64, u16, i32, f64::powi); - pow_impl!(f64, i32, i32, f64::powi); - pow_impl!(f32, f32, f32, f32::powf); - pow_impl!(f64, f32, f64, f64::powf); - pow_impl!(f64, f64, f64, f64::powf); + pow_impl!(f32, i8, i32, ::powi); + pow_impl!(f32, u8, i32, ::powi); + pow_impl!(f32, i16, i32, ::powi); + pow_impl!(f32, u16, i32, ::powi); + pow_impl!(f32, i32, i32, ::powi); + pow_impl!(f64, i8, i32, ::powi); + pow_impl!(f64, u8, i32, ::powi); + pow_impl!(f64, i16, i32, ::powi); + pow_impl!(f64, u16, i32, ::powi); + pow_impl!(f64, i32, i32, ::powi); + pow_impl!(f32, f32, f32, ::powf); + pow_impl!(f64, f32, f64, ::powf); + pow_impl!(f64, f64, f64, ::powf); } /// Raises a value to the power of exp, using exponentiation by squaring.