Skip to content

Commit

Permalink
Add fabsf16, fabsf128, copysignf16, and copysignf128
Browse files Browse the repository at this point in the history
Use the generic implementations to provide these simple methods.
  • Loading branch information
tgross35 committed Jan 6, 2025
1 parent 1b35730 commit 2c0ecd0
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 3 deletions.
24 changes: 21 additions & 3 deletions src/libm_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ macro_rules! libm_helper {
}
};

({$($func:tt);*}) => {
({$($func:tt;)*}) => {
$(
libm_helper! { $func }
)*
Expand Down Expand Up @@ -103,7 +103,7 @@ libm_helper! {
(fn trunc(x: f32) -> (f32); => truncf);
(fn y0(x: f32) -> (f32); => y0f);
(fn y1(x: f32) -> (f32); => y1f);
(fn yn(n: i32, x: f32) -> (f32); => ynf)
(fn yn(n: i32, x: f32) -> (f32); => ynf);
}
}

Expand Down Expand Up @@ -166,6 +166,24 @@ libm_helper! {
(fn trunc(x: f64) -> (f64); => trunc);
(fn y0(x: f64) -> (f64); => y0);
(fn y1(x: f64) -> (f64); => y1);
(fn yn(n: i32, x: f64) -> (f64); => yn)
(fn yn(n: i32, x: f64) -> (f64); => yn);
}
}

#[cfg(f16_enabled)]
libm_helper! {
f16,
funcs: {
(fn copysign(x: f16, y: f16) -> (f16); => copysignf16);
(fn fabs(x: f16) -> (f16); => fabsf16);
}
}

#[cfg(f128_enabled)]
libm_helper! {
f128,
funcs: {
(fn copysign(x: f128, y: f128) -> (f128); => copysignf128);
(fn fabs(x: f128) -> (f128); => fabsf128);
}
}
8 changes: 8 additions & 0 deletions src/math/copysignf128.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/// Sign of Y, magnitude of X (f128)
///
/// Constructs a number with the magnitude (absolute value) of its
/// first argument, `x`, and the sign of its second argument, `y`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn copysignf128(x: f128, y: f128) -> f128 {
super::generic::copysign(x, y)
}
8 changes: 8 additions & 0 deletions src/math/copysignf16.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/// Sign of Y, magnitude of X (f16)
///
/// Constructs a number with the magnitude (absolute value) of its
/// first argument, `x`, and the sign of its second argument, `y`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn copysignf16(x: f16, y: f16) -> f16 {
super::generic::copysign(x, y)
}
1 change: 1 addition & 0 deletions src/math/fabs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/// Absolute value (magnitude) (f64)
///
/// Calculates the absolute value (magnitude) of the argument `x`,
/// by direct manipulation of the bit representation of `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
Expand Down
1 change: 1 addition & 0 deletions src/math/fabsf.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/// Absolute value (magnitude) (f32)
///
/// Calculates the absolute value (magnitude) of the argument `x`,
/// by direct manipulation of the bit representation of `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
Expand Down
37 changes: 37 additions & 0 deletions src/math/fabsf128.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/// Absolute value (magnitude) (f128)
///
/// Calculates the absolute value (magnitude) of the argument `x`,
/// by direct manipulation of the bit representation of `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn fabsf128(x: f128) -> f128 {
select_implementation! {
name: fabsf,
use_intrinsic: target_arch = "wasm32",
args: x,
}

super::generic::fabs(x)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn sanity_check() {
assert_eq!(fabsf128(-1.0), 1.0);
assert_eq!(fabsf128(2.8), 2.8);
}

/// The spec: https://en.cppreference.com/w/cpp/numeric/math/fabs
#[test]
fn spec_tests() {
assert!(fabsf128(f128::NAN).is_nan());
for f in [0.0, -0.0].iter().copied() {
assert_eq!(fabsf128(f), 0.0);
}
for f in [f128::INFINITY, f128::NEG_INFINITY].iter().copied() {
assert_eq!(fabsf128(f), f128::INFINITY);
}
}
}
37 changes: 37 additions & 0 deletions src/math/fabsf16.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/// Absolute value (magnitude) (f16)
///
/// Calculates the absolute value (magnitude) of the argument `x`,
/// by direct manipulation of the bit representation of `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn fabsf16(x: f16) -> f16 {
select_implementation! {
name: fabsf,
use_intrinsic: target_arch = "wasm32",
args: x,
}

super::generic::fabs(x)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn sanity_check() {
assert_eq!(fabsf16(-1.0), 1.0);
assert_eq!(fabsf16(2.8), 2.8);
}

/// The spec: https://en.cppreference.com/w/cpp/numeric/math/fabs
#[test]
fn spec_tests() {
assert!(fabsf16(f16::NAN).is_nan());
for f in [0.0, -0.0].iter().copied() {
assert_eq!(fabsf16(f), 0.0);
}
for f in [f16::INFINITY, f16::NEG_INFINITY].iter().copied() {
assert_eq!(fabsf16(f), f16::INFINITY);
}
}
}
20 changes: 20 additions & 0 deletions src/math/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,26 @@ pub use self::tgammaf::tgammaf;
pub use self::trunc::trunc;
pub use self::truncf::truncf;

cfg_if! {
if #[cfg(f16_enabled)] {
mod copysignf16;
mod fabsf16;

pub use self::copysignf16::copysignf16;
pub use self::fabsf16::fabsf16;
}
}

cfg_if! {
if #[cfg(f128_enabled)] {
mod copysignf128;
mod fabsf128;

pub use self::copysignf128::copysignf128;
pub use self::fabsf128::fabsf128;
}
}

#[inline]
fn get_high_word(x: f64) -> u32 {
(x.to_bits() >> 32) as u32
Expand Down

0 comments on commit 2c0ecd0

Please sign in to comment.