From bf51981a2b93a634ddb23b26dd205174899450cb Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 26 Oct 2024 03:07:58 -0500 Subject: [PATCH] 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`. --- src/math/copysign.rs | 6 +----- src/math/copysignf.rs | 6 +----- src/math/fabs.rs | 2 +- src/math/fabsf.rs | 2 +- src/math/generic/abs.rs | 6 ++++++ src/math/generic/copysign.rs | 10 ++++++++++ src/math/generic/mod.rs | 5 +++++ src/math/mod.rs | 1 + 8 files changed, 26 insertions(+), 12 deletions(-) create mode 100644 src/math/generic/abs.rs create mode 100644 src/math/generic/copysign.rs create mode 100644 src/math/generic/mod.rs diff --git a/src/math/copysign.rs b/src/math/copysign.rs index 1f4a35a33..552bf3975 100644 --- a/src/math/copysign.rs +++ b/src/math/copysign.rs @@ -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) } diff --git a/src/math/copysignf.rs b/src/math/copysignf.rs index 6c346e3a5..8b9bed4c0 100644 --- a/src/math/copysignf.rs +++ b/src/math/copysignf.rs @@ -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) } diff --git a/src/math/fabs.rs b/src/math/fabs.rs index d083053e1..2163637e7 100644 --- a/src/math/fabs.rs +++ b/src/math/fabs.rs @@ -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)] diff --git a/src/math/fabsf.rs b/src/math/fabsf.rs index eabe87254..ac77c9201 100644 --- a/src/math/fabsf.rs +++ b/src/math/fabsf.rs @@ -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 diff --git a/src/math/generic/abs.rs b/src/math/generic/abs.rs new file mode 100644 index 000000000..2c9a43c12 --- /dev/null +++ b/src/math/generic/abs.rs @@ -0,0 +1,6 @@ +use super::super::Float; + +/// Absolute value. +pub fn abs(x: F) -> F { + x.abs() +} diff --git a/src/math/generic/copysign.rs b/src/math/generic/copysign.rs new file mode 100644 index 000000000..d6b814891 --- /dev/null +++ b/src/math/generic/copysign.rs @@ -0,0 +1,10 @@ +use super::super::Float; + +/// Copy the sign of `y` to `x`. +pub fn copysign(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) +} diff --git a/src/math/generic/mod.rs b/src/math/generic/mod.rs new file mode 100644 index 000000000..1ddd08f0e --- /dev/null +++ b/src/math/generic/mod.rs @@ -0,0 +1,5 @@ +mod abs; +mod copysign; + +pub use abs::abs; +pub use copysign::copysign; diff --git a/src/math/mod.rs b/src/math/mod.rs index 3852c774e..ba1995228 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -87,6 +87,7 @@ mod support; mod arch; mod expo2; mod fenv; +mod generic; mod k_cos; mod k_cosf; mod k_expo2;