@@ -78,6 +78,43 @@ 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+ /// As abs(), except the MIN value becomes MAX instead of itself.
84+ ///
85+ /// # Examples
86+ /// # use core_simd::*;
87+ #[ doc = concat!( "# use core::" , stringify!( $n) , "::{MIN, MAX};" ) ]
88+ #[ doc = concat!( "let x = " , stringify!( $name) , "::splat([MIN, -2, 0, 3]);" ) ]
89+ /// let unsat = x.abs();
90+ /// let sat = x.saturating_abs();
91+ #[ doc = concat!( "assert_eq!(unsat, " , stringify!( $name) , "::from_array([MIN, 2, 0, 3]);" ) ]
92+ #[ doc = concat!( "assert_eq!(sat, " , stringify!( $name) , "::from_array([MAX, 2, 0, 3]));" ) ]
93+ /// ```
94+ #[ inline]
95+ pub fn saturating_abs( self ) -> Self {
96+ // arith shift for -1 or 0 mask based on sign bit, giving 2s complement
97+ const SHR : $n = <$n>:: BITS as $n - 1 ;
98+ let m = self >> SHR ;
99+ ( self ^m) . saturating_sub( m)
100+ }
101+
102+ /// Lanewise saturating negation, implemented in Rust.
103+ /// As neg(), except the MIN value becomes MAX instead of itself.
104+ ///
105+ /// # Examples
106+ /// # use core_simd::*;
107+ #[ doc = concat!( "# use core::" , stringify!( $n) , "::{MIN, MAX};" ) ]
108+ #[ doc = concat!( "let x = " , stringify!( $name) , "::splat([MIN, -2, 3, MAX]);" ) ]
109+ /// let unsat = -x;
110+ /// let sat = x.saturating_neg();
111+ #[ doc = concat!( "assert_eq!(unsat, " , stringify!( $name) , "::from_array([MIN, 2, -3, MIN + 1]);" ) ]
112+ #[ doc = concat!( "assert_eq!(sat, " , stringify!( $name) , "::from_array([MAX, 2, -3, MIN + 1]));" ) ]
113+ /// ```
114+ #[ inline]
115+ pub fn saturating_neg( self ) -> Self {
116+ Self :: splat( 0 ) . saturating_sub( self )
117+ }
81118 } ) +
82119 }
83120}
0 commit comments