1
Fork 0

Auto merge of #95317 - Jules-Bertholet:round_ties_to_even, r=pnkfelix,m-ou-se,scottmcm

Add `round_ties_even` to `f32` and `f64`

Tracking issue: #96710

Redux of #82273. See also #55107

Adds a new method, `round_ties_even`, to `f32` and `f64`, that rounds the float to the nearest integer , rounding halfway cases to the number with an even least significant bit. Uses the `roundeven` LLVM intrinsic to do this.

Of the five IEEE 754 rounding modes, this is the only one that doesn't already have a round-to-integer function exposed by Rust (others are `round`, `floor`, `ceil`, and `trunc`).  Ties-to-even is also the rounding mode used for int-to-float and float-to-float `as` casts, as well as float arithmentic operations. So not having an explicit rounding method for it seems like an oversight.

Bikeshed: this PR currently uses `round_ties_even` for the name of the method. But maybe `round_ties_to_even` is better, or `round_even`, or `round_to_even`?
This commit is contained in:
bors 2023-03-07 09:43:12 +00:00
commit 0a3b557d52
12 changed files with 128 additions and 0 deletions

View file

@ -78,10 +78,14 @@ impl f64 {
/// let f = 3.3_f64;
/// let g = -3.3_f64;
/// let h = -3.7_f64;
/// let i = 3.5_f64;
/// let j = 4.5_f64;
///
/// assert_eq!(f.round(), 3.0);
/// assert_eq!(g.round(), -3.0);
/// assert_eq!(h.round(), -4.0);
/// assert_eq!(i.round(), 4.0);
/// assert_eq!(j.round(), 5.0);
/// ```
#[rustc_allow_incoherent_impl]
#[must_use = "method returns a new number and does not mutate the original value"]
@ -91,6 +95,32 @@ impl f64 {
unsafe { intrinsics::roundf64(self) }
}
/// Returns the nearest integer to a number. Rounds half-way cases to the number
/// with an even least significant digit.
///
/// # Examples
///
/// ```
/// #![feature(round_ties_even)]
///
/// let f = 3.3_f64;
/// let g = -3.3_f64;
/// let h = 3.5_f64;
/// let i = 4.5_f64;
///
/// assert_eq!(f.round_ties_even(), 3.0);
/// assert_eq!(g.round_ties_even(), -3.0);
/// assert_eq!(h.round_ties_even(), 4.0);
/// assert_eq!(i.round_ties_even(), 4.0);
/// ```
#[rustc_allow_incoherent_impl]
#[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "round_ties_even", issue = "96710")]
#[inline]
pub fn round_ties_even(self) -> f64 {
unsafe { intrinsics::rintf64(self) }
}
/// Returns the integer part of `self`.
/// This means that non-integer numbers are always truncated towards zero.
///