Added abs_diff for integer types.

This commit is contained in:
Orson Peters 2021-09-09 16:58:41 +02:00
parent 497ee321af
commit 4f5563d027
2 changed files with 61 additions and 0 deletions

View file

@ -2227,6 +2227,46 @@ macro_rules! int_impl {
}
}
/// Computes the absolute difference between `self` and `other`.
///
/// This function always returns the correct answer without overflow or
/// panics by returning an unsigned integer.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(int_abs_diff)]
#[doc = concat!("assert_eq!(100", stringify!($SelfT), ".abs_diff(80), 20", stringify!($UnsignedT), ");")]
#[doc = concat!("assert_eq!(100", stringify!($SelfT), ".abs_diff(110), 10", stringify!($UnsignedT), ");")]
#[doc = concat!("assert_eq!((-100", stringify!($SelfT), ").abs_diff(80), 180", stringify!($UnsignedT), ");")]
#[doc = concat!("assert_eq!((-100", stringify!($SelfT), ").abs_diff(-120), 20", stringify!($UnsignedT), ");")]
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.abs_diff(", stringify!($SelfT), "::MAX), ", stringify!($UnsignedT), "::MAX);")]
/// ```
#[unstable(feature = "int_abs_diff", issue = "none")]
#[inline]
pub const fn abs_diff(self, other: Self) -> $UnsignedT {
if self < other {
// Converting a non-negative x from signed to unsigned by using
// `x as U` is left unchanged, but a negative x is converted
// to value x + 2^N. Thus if `s` and `o` are binary variables
// respectively indicating whether `self` and `other` are
// negative, we are computing the mathematical value:
//
// (other + o*2^N) - (self + s*2^N) mod 2^N
// other - self + (o-s)*2^N mod 2^N
// other - self mod 2^N
//
// Finally, taking the mod 2^N of the mathematical value of
// `other - self` does not change it as it already is
// in the range [0, 2^N).
(other as $UnsignedT).wrapping_sub(self as $UnsignedT)
} else {
(self as $UnsignedT).wrapping_sub(other as $UnsignedT)
}
}
/// Returns a number representing sign of `self`.
///
/// - `0` if the number is zero

View file

@ -1490,6 +1490,27 @@ macro_rules! uint_impl {
(c, b | d)
}
/// Computes the absolute difference between `self` and `other`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(int_abs_diff)]
#[doc = concat!("assert_eq!(100", stringify!($SelfT), ".abs_diff(80), 20", stringify!($SelfT), ");")]
#[doc = concat!("assert_eq!(100", stringify!($SelfT), ".abs_diff(110), 10", stringify!($SelfT), ");")]
/// ```
#[unstable(feature = "int_abs_diff", issue = "none")]
#[inline]
pub const fn abs_diff(self, other: Self) -> Self {
if self < other {
other - self
} else {
self - other
}
}
/// Calculates the multiplication of `self` and `rhs`.
///
/// Returns a tuple of the multiplication along with a boolean