Skip to content

Commit dd1a5e4

Browse files
Add saturating abs/neg
1 parent 4a6b4c0 commit dd1a5e4

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

Diff for: crates/core_simd/src/math.rs

+35
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,41 @@ macro_rules! impl_int_arith {
7878
pub fn saturating_sub(self, second: Self) -> Self {
7979
unsafe { crate::intrinsics::simd_saturating_sub(self, second) }
8080
}
81+
82+
/// Lanewise saturating absolute value, implemented in Rust.
83+
///
84+
/// # Examples
85+
/// # use core_simd::*;
86+
#[doc = concat!("# use core::", stringify!($n), "::{MIN, MAX};")]
87+
#[doc = concat!("let x = ", stringify!($name), "::splat([MIN, -2, 0, 3]);")]
88+
/// let unsat = x.abs();
89+
/// let sat = x.saturating_abs();
90+
#[doc = concat!("assert_eq!(unsat, ", stringify!($name), "::from_array([MIN, 2, 0, 3]);")]
91+
#[doc = concat!("assert_eq!(sat, ", stringify!($name), "::from_array([MAX, 2, 0, 3]));")]
92+
/// ```
93+
#[inline]
94+
pub fn saturating_abs(self) -> Self {
95+
// arith shift for -1 or 0 mask based on sign bit, giving 2s complement
96+
const SHR: $n = <$n>::BITS as $n - 1;
97+
let m = self >> SHR;
98+
(self^m).saturating_sub(m)
99+
}
100+
101+
/// Lanewise saturating negation, implemented in Rust.
102+
///
103+
/// # Examples
104+
/// # use core_simd::*;
105+
#[doc = concat!("# use core::", stringify!($n), "::{MIN, MAX};")]
106+
#[doc = concat!("let x = ", stringify!($name), "::splat([MIN, -2, 3, MAX]);")]
107+
/// let unsat = -x;
108+
/// let sat = x.saturating_neg();
109+
#[doc = concat!("assert_eq!(unsat, ", stringify!($name), "::from_array([MIN, 2, -3, MIN + 1]);")]
110+
#[doc = concat!("assert_eq!(sat, ", stringify!($name), "::from_array([MAX, 2, -3, MIN + 1]));")]
111+
/// ```
112+
#[inline]
113+
pub fn saturating_neg(self) -> Self {
114+
Self::splat(0).saturating_sub(self)
115+
}
81116
})+
82117
}
83118
}

0 commit comments

Comments
 (0)