Introduce generic abs and copysign

Add generic versions of `abs` and `copysign`, which will provide an
entrypoint for adding `f16` and `f128`. Since this implementation is
identical to the existing type-specific implementations, make use of it
for `f32` and `f64`.
This commit is contained in:
Trevor Gross 2024-10-26 03:07:58 -05:00 committed by Trevor Gross
parent 51956a53c3
commit b9871da445
8 changed files with 26 additions and 12 deletions

View file

@ -4,9 +4,5 @@
/// first argument, `x`, and the sign of its second argument, `y`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn copysign(x: f64, y: f64) -> f64 {
let mut ux = x.to_bits();
let uy = y.to_bits();
ux &= (!0) >> 1;
ux |= uy & (1 << 63);
f64::from_bits(ux)
super::generic::copysign(x, y)
}

View file

@ -4,9 +4,5 @@
/// first argument, `x`, and the sign of its second argument, `y`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn copysignf(x: f32, y: f32) -> f32 {
let mut ux = x.to_bits();
let uy = y.to_bits();
ux &= 0x7fffffff;
ux |= uy & 0x80000000;
f32::from_bits(ux)
super::generic::copysign(x, y)
}

View file

@ -9,7 +9,7 @@ pub fn fabs(x: f64) -> f64 {
args: x,
}
f64::from_bits(x.to_bits() & (u64::MAX / 2))
super::generic::abs(x)
}
#[cfg(test)]

View file

@ -9,7 +9,7 @@ pub fn fabsf(x: f32) -> f32 {
args: x,
}
f32::from_bits(x.to_bits() & 0x7fffffff)
super::generic::abs(x)
}
// PowerPC tests are failing on LLVM 13: https://github.com/rust-lang/rust/issues/88520

View file

@ -0,0 +1,6 @@
use super::super::Float;
/// Absolute value.
pub fn abs<F: Float>(x: F) -> F {
x.abs()
}

View file

@ -0,0 +1,10 @@
use super::super::Float;
/// Copy the sign of `y` to `x`.
pub fn copysign<F: Float>(x: F, y: F) -> F {
let mut ux = x.to_bits();
let uy = y.to_bits();
ux &= !F::SIGN_MASK;
ux |= uy & (F::SIGN_MASK);
F::from_bits(ux)
}

View file

@ -0,0 +1,5 @@
mod abs;
mod copysign;
pub use abs::abs;
pub use copysign::copysign;

View file

@ -87,6 +87,7 @@ mod support;
mod arch;
mod expo2;
mod fenv;
mod generic;
mod k_cos;
mod k_cosf;
mod k_expo2;