Skip to content

Tracking Issue for round_ties_even #96710

Closed

Description

@Jules-Bertholet

Feature gate: #![feature(round_ties_even)]

This is a tracking issue for the round_ties_even feature, which adds a new method to f32 and f64 for rounding to the nearest integer, with ties rounded to the nearest even number.

Public API

impl f32 {
    fn round_ties_even(self) -> f32;
}

impl f64 {
    fn round_ties_even(self) -> f64;
}

Steps / History

Unresolved Questions

  • Naming: round_ties_even, round_even, round_to_even, round_banker... many ways to paint this bikeshed
  • Should the behavior of the round function be changed to this?
  • Is it okay to use rint in the implementaton? (see Add round_ties_even to f32 and f64 #95317 (comment))

Activity

  1. added
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    T-libs-api[DEPRECATED; DO NOT USE]
    on May 4, 2022
  2. Miksel12 commented on Aug 19, 2022

    @Miksel12

    I think round should be changed to round ties to even, both x86 and ARM use it as the default rounding mode and IEEE 754 states it should be the default. It is also the mode with the least amount of bias.
    As for round ties away from zero, which is the current mode used for round, it is actually not required by IEEE 754 for binary representation and is thus not implemented by ARM and x86. Which makes the current round pretty slow: #55107.
    I don't know why round ties away from zero was chosen but it is pretty clear it is the wrong default.
    If round was to be changed to ties to even, then the four rounding modes (round, ceil, floor and trunc) would match the required IEEE rounding modes and the rounding implemented by x86 and ARM (and probably most other ISA's, though RISC-V supports round ties away from zero).

  3. ajtribick commented on Nov 20, 2022

    @ajtribick
    Contributor

    From the perspective of maintaining a crate that implements a custom floating point type that tries to provide a similar API to the built-in f32/f64, I'd be somewhat against changing round from its documented behavior at this point (although I'd agree it isn't ideal as a choice for the default round function). It might also be worth getting some opinion from the num folks on this as they have also implemented round on their rational number types as rounding ties away from zero, similarly the documentation of round on the Float/FloatCore in num_traits.

    My suspicion for why away-from-zero was chosen is that it matches how round is specified to operate in C (and similarly std::round in C++), e.g. N1570 section 7.12.9.6:

    The round functions round their argument to the nearest integer value in floating-point format, rounding halfway cases away from zero, regardless of the current rounding direction.

    I definitely think having a function with the round ties to even mode should be available though. My preference would be round_ties_even over round_even (because to me the latter sounds more like rounding to an even number), but it's not a particularly strong preference there.

  4. added a commit that references this issue on Mar 15, 2023
  5. added a commit that references this issue on Jun 19, 2023
  6. tgross35 commented on Aug 9, 2023

    @tgross35
    Member

    Could this do something like use roundeven when available but fallback to rint when it isn't?

  7. tjallingt commented on Jan 3, 2024

    @tjallingt

    I hope this is appropriate/helpful, I would like this feature stabilized so I will attempt a stabilization report.
    I can also make a stabilization PR but it seems FCP should happen before that.

    Request for Stabilization

    I think the round_ties_even methods should be stabilized in version 1.77.0 (beta on 2 February, stable on 21 March).

    Implementation history

    These methods have been added in #95317 (merged 7 March, 2023) which corresponds to the 1.70 timeframe (branched on 14 April, 2023).

    API Summary

    The round_ties_even feature will be stabilized wich adds the following methods to std:

    impl f32 {
        fn round_ties_even(self) -> f32;
    }
    
    impl f64 {
        fn round_ties_even(self) -> f64;
    }

    Experience reports

    These methods are used in several projects:

    There are also references to this feature/tracking issue on manual implementations of round_ties_even which are waiting for this to be stabilized:

    Documentation

    Both methods have been documented in the std rustdoc

    Unresolved questions

    The following questions are still unresolved:

    1. Naming: round_ties_even, round_even, round_to_even, round_banker... many ways to paint this bikeshed
    2. Should the behavior of the round function be changed to this?
    3. Is it okay to use rint in the implementaton? (see Add round_ties_even to f32 and f64 #95317 (comment))

    I will try to answer these questions

    1. Naming

    No further comments have been made about the naming of these method. round_ties_even seems to be a clear, descriptive name for this functionality. This name also places it close to round in the docs to ensure it will be discoverable.

    2. Changing round

    While the default behaviour of round is not ideal it seems to be consistent with C and C++. Changing the behaviour of round would likely be a difficult and lengthy process and would involve adding round_ties_zero methods (I believe). This could be done as a followup to stabilizing round_ties_even if desired but, in my opinion, should not block the stabilization of this feature given that this rounding mode is currently not available in Rusts standard library.

    3. Use rint

    Not only does Rust assume the default rounding mode, so do the LLVM floating-point intrinsics that back it.

    source

    As you said though, Rust already assumes the default rounding mode, so it doesn't matter too much. I think roundeven is the "more correct" choice to use but it's not well supported so it's OK to just use rint for now. Ideally we should support both in libm.

    source

    From these comments it appears that using rint poses no immediate problems. Rust already assumes the default rounding mode is used. It seems safe to extend that assumption to round_ties_even.

    There does seem to be agreement that roundeven should be preferred once it is well supported.
    I don't have enough knowledge to say for sure but; it seems likely that chaning from using rint to roundeven should be backwards compatible and therefore should not block the stabilization of this feature.

  8. tjallingt commented on Jan 4, 2024

    @tjallingt

    I'm not sure the previous post will be seen by anyone without a ping/mention.
    I hope it is okay to mention you @m-ou-se I hope I'm following the right process 😅

  9. 15 remaining items

  10. RalfJung commented on Jan 11, 2024

    @RalfJung
    Member

    While rounding away from zero is what I learned in elementary school, I don't think that what young children are taught is generally what people (engineers) would expect.

    In my totally representative survey of 2 CS PhD students, neither of them knew why "round ties to even" would be preferable over "round away from zero". I think it's not just elementary school children that are surprised by the seemingly unnecessarily complicated "ties to even" semantics.

  11. TennyZhuang commented on Jan 11, 2024

    @TennyZhuang
    Contributor

    Changing the behavior of round is definitely dangerous even across the edition boundaries. Users may focus on the compilation failure, but not the runtime breaking change.

    If it’s better to change the function to correct behavior, I propose to fully remove round function in edition 2024, and introduce round_ties_zero instead. This compilation error can be easily fixed automatically.

    We can introduce round back in edition 2027, since I believe few crate will upgrade across three editions.

  12. added
    to-announceAnnounce this issue on triage meeting
    and removed
    final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.
    on Jan 19, 2024
  13. rfcbot commented on Jan 19, 2024

    @rfcbot

    The final comment period, with a disposition to merge, as per the review above, is now complete.

    As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

    This will be merged soon.

  14. added a commit that references this issue on Jan 20, 2024
    862d3fe
  15. added a commit that references this issue on Jan 20, 2024
    28e2f94
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-floating-pointArea: Floating point numbers and arithmeticC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-libs-api[DEPRECATED; DO NOT USE]disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions