@@ -78,6 +78,43 @@ macro_rules! impl_int_arith {
78
78
pub fn saturating_sub( self , second: Self ) -> Self {
79
79
unsafe { crate :: intrinsics:: simd_saturating_sub( self , second) }
80
80
}
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
+ }
81
118
} ) +
82
119
}
83
120
}
0 commit comments