libm fallback for Pow, factorize MulAdd
This commit is contained in:
parent
4d3cb0a4ba
commit
4234eb76aa
|
@ -31,13 +31,13 @@ the default `std` feature. Use this in `Cargo.toml`:
|
||||||
[dependencies.num-traits]
|
[dependencies.num-traits]
|
||||||
version = "0.2"
|
version = "0.2"
|
||||||
default-features = false
|
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 `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`
|
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`.
|
point exponents in `Pow`.
|
||||||
|
|
||||||
Implementations for `i128` and `u128` are only available with Rust 1.26 and
|
Implementations for `i128` and `u128` are only available with Rust 1.26 and
|
||||||
|
|
|
@ -34,47 +34,26 @@ pub trait MulAddAssign<A = Self, B = Self> {
|
||||||
fn mul_add_assign(&mut self, a: A, b: B);
|
fn mul_add_assign(&mut self, a: A, b: B);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(any(feature = "std", feature = "libm"))]
|
||||||
impl MulAdd<f32, f32> for f32 {
|
impl MulAdd<f32, f32> for f32 {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_add(self, a: Self, b: Self) -> Self::Output {
|
fn mul_add(self, a: Self, b: Self) -> Self::Output {
|
||||||
f32::mul_add(self, a, b)
|
<Self as ::Float>::mul_add(self, a, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(any(feature = "std", feature = "libm"))]
|
||||||
impl MulAdd<f64, f64> for f64 {
|
impl MulAdd<f64, f64> for f64 {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_add(self, a: Self, b: Self) -> Self::Output {
|
fn mul_add(self, a: Self, b: Self) -> Self::Output {
|
||||||
f64::mul_add(self, a, b)
|
<Self as ::Float>::mul_add(self, a, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(not(feature = "std"), feature = "libm"))]
|
|
||||||
impl MulAdd<f32, f32> for f32 {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn mul_add(self, a: Self, b: Self) -> Self::Output {
|
|
||||||
<f32 as ::libm::F32Ext>::mul_add(self, a, b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(all(not(feature = "std"), feature = "libm"))]
|
|
||||||
impl MulAdd<f64, f64> for f64 {
|
|
||||||
type Output = Self;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn mul_add(self, a: Self, b: Self) -> Self::Output {
|
|
||||||
<f64 as ::libm::F64Ext>::mul_add(self, a, b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
macro_rules! mul_add_impl {
|
macro_rules! mul_add_impl {
|
||||||
($trait_name:ident for $($t:ty)*) => {$(
|
($trait_name:ident for $($t:ty)*) => {$(
|
||||||
impl $trait_name for $t {
|
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)]
|
#[cfg(has_i128)]
|
||||||
mul_add_impl!(MulAdd for i128 u128);
|
mul_add_impl!(MulAdd for i128 u128);
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(any(feature = "std", feature = "libm"))]
|
||||||
impl MulAddAssign<f32, f32> for f32 {
|
impl MulAddAssign<f32, f32> for f32 {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_add_assign(&mut self, a: Self, b: Self) {
|
fn mul_add_assign(&mut self, a: Self, b: Self) {
|
||||||
*self = f32::mul_add(*self, a, b)
|
*self = <Self as ::Float>::mul_add(*self, a, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(any(feature = "std", feature = "libm"))]
|
||||||
impl MulAddAssign<f64, f64> for f64 {
|
impl MulAddAssign<f64, f64> for f64 {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul_add_assign(&mut self, a: Self, b: Self) {
|
fn mul_add_assign(&mut self, a: Self, b: Self) {
|
||||||
*self = f64::mul_add(*self, a, b)
|
*self = <Self as ::Float>::mul_add(*self, a, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(not(feature = "std"), feature = "libm"))]
|
|
||||||
impl MulAddAssign<f32, f32> for f32 {
|
|
||||||
#[inline]
|
|
||||||
fn mul_add_assign(&mut self, a: Self, b: Self) {
|
|
||||||
*self = <f32 as ::libm::F32Ext>::mul_add(*self, a, b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(all(not(feature = "std"), feature = "libm"))]
|
|
||||||
impl MulAddAssign<f64, f64> for f64 {
|
|
||||||
#[inline]
|
|
||||||
fn mul_add_assign(&mut self, a: Self, b: Self) {
|
|
||||||
*self = <f64 as ::libm::F64Ext>::mul_add(*self, a, b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
macro_rules! mul_add_assign_impl {
|
macro_rules! mul_add_assign_impl {
|
||||||
($trait_name:ident for $($t:ty)*) => {$(
|
($trait_name:ident for $($t:ty)*) => {$(
|
||||||
impl $trait_name for $t {
|
impl $trait_name for $t {
|
||||||
|
|
29
src/pow.rs
29
src/pow.rs
|
@ -152,23 +152,24 @@ pow_impl!(Wrapping<isize>);
|
||||||
// pow_impl!(usize, u64);
|
// pow_impl!(usize, u64);
|
||||||
// pow_impl!(isize, u64);
|
// pow_impl!(isize, u64);
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(any(feature = "std", feature = "libm"))]
|
||||||
mod float_impls {
|
mod float_impls {
|
||||||
use super::Pow;
|
use super::Pow;
|
||||||
|
use ::Float;
|
||||||
|
|
||||||
pow_impl!(f32, i8, i32, f32::powi);
|
pow_impl!(f32, i8, i32, <f32 as Float>::powi);
|
||||||
pow_impl!(f32, u8, i32, f32::powi);
|
pow_impl!(f32, u8, i32, <f32 as Float>::powi);
|
||||||
pow_impl!(f32, i16, i32, f32::powi);
|
pow_impl!(f32, i16, i32, <f32 as Float>::powi);
|
||||||
pow_impl!(f32, u16, i32, f32::powi);
|
pow_impl!(f32, u16, i32, <f32 as Float>::powi);
|
||||||
pow_impl!(f32, i32, i32, f32::powi);
|
pow_impl!(f32, i32, i32, <f32 as Float>::powi);
|
||||||
pow_impl!(f64, i8, i32, f64::powi);
|
pow_impl!(f64, i8, i32, <f64 as Float>::powi);
|
||||||
pow_impl!(f64, u8, i32, f64::powi);
|
pow_impl!(f64, u8, i32, <f64 as Float>::powi);
|
||||||
pow_impl!(f64, i16, i32, f64::powi);
|
pow_impl!(f64, i16, i32, <f64 as Float>::powi);
|
||||||
pow_impl!(f64, u16, i32, f64::powi);
|
pow_impl!(f64, u16, i32, <f64 as Float>::powi);
|
||||||
pow_impl!(f64, i32, i32, f64::powi);
|
pow_impl!(f64, i32, i32, <f64 as Float>::powi);
|
||||||
pow_impl!(f32, f32, f32, f32::powf);
|
pow_impl!(f32, f32, f32, <f32 as Float>::powf);
|
||||||
pow_impl!(f64, f32, f64, f64::powf);
|
pow_impl!(f64, f32, f64, <f64 as Float>::powf);
|
||||||
pow_impl!(f64, f64, f64, f64::powf);
|
pow_impl!(f64, f64, f64, <f64 as Float>::powf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Raises a value to the power of exp, using exponentiation by squaring.
|
/// Raises a value to the power of exp, using exponentiation by squaring.
|
||||||
|
|
Loading…
Reference in New Issue