@@ -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