Skip to content

Issue with Round Function in Python #123811

Description

@lykan89

Bug report

Bug description:

Description of the Issue:
The round function does not seem to handle certain floating-point numbers correctly. For example, when rounding the number -1357.1357 to negative 4 decimal places, the function returns -0.0 instead of the expected 0.0.

Steps to Reproduce:

  1. Open a Python interpreter.
  2. Execute the following code:
print(round(-1357.1357, -4))
  1. Observe the output.

Expected Result: The output should be 0.0.
Actual Result: The output is -0.0.

Environment Details Tested:
--Python Version: 3.12.5, Operating System: Windows 11.
--Python Version: 3.12.3, Operating System: Ubuntu.

Additional Information: I have verified this issue on multiple machines and with different Python versions. The issue persists across all tested environments.

CPython versions tested on:

3.12, 3.13

Operating systems tested on:

Linux, Windows

Linked PRs

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    on Sep 7, 2024
  2. ZeroIntensity commented on Sep 7, 2024

    @ZeroIntensity
    Member

    Hmm, is this causing any actual problems in practice? 0.0 and -0.0 are, more or less, equivalent numbers.

  3. serhiy-storchaka commented on Sep 7, 2024

    @serhiy-storchaka
    Member

    This is an intentional behavior. It is here at least since e6a076d (which fixed bpo-1869, bpo-4707, bpo-5118, bpo-5473, bpo-1456775) and may be even earlier. It is consistent between float and Decimal.

    Although this case is not explicitly documented and tested.

  4. serhiy-storchaka commented on Sep 7, 2024

    @serhiy-storchaka
    Member

    @mdickinson, @tim-one, what are your thoughts? Should we explicitly document that round() can return a negative zero?

    I think that we should add tests for this in any case, to prevent code degradation.

  5. tim-one commented on Sep 7, 2024

    @tim-one
    Member

    It shouldn't be changed. It's a form of "underflow to 0", and all relevant standards require that the sign bit be retained in such cases. Python's round() isn't mentioned in the standards, so this is a "to be consistent with the obvious intent of ..." thing.

    Mixed feelings about documenting it. Hardly anyone will care, and filtering out irrelevant (to them) "doc bloat" is an ongoing burden for all other readers. If it has to be documented, I'd recommend a footnote.

    But, yes, it absolutely should be tested.

  6. skirpichev commented on Sep 8, 2024

    @skirpichev
    Member

    In some sense, it's tested, e.g. here:

    self.assertEqual(round(-123.456, n), -0.0)

    This test just ignores difference between 0.0 and -0.0. Probably, that line could be just changed to use assertFloatsAreIdentical() (see also #121071). Or did I miss something and we need more test cases?

    Edit: pr is ready, #123829

  7. added a commit that references this issue on Sep 8, 2024
  8. tim-one commented on Sep 8, 2024

    @tim-one
    Member

    This isn't worth much effort. assertFloatsAreIdentical() certainly - equality testing is useless (+0.0 == -0.0). In addition to checking that round(-123.456, n) returns -0.0, also check that +0.0 is returned if the first argument is negated. Good enough, I think.

  9. skirpichev commented on Sep 8, 2024

    @skirpichev
    Member

    also check that +0.0 is returned if the first argument is negated

    Yeah, that one was right above. I just did replace for all tests with ±0.0 on rhs.

    But I dislike adding assertFloatsAreIdentical() helper yet in another place. So, I would appreciate if something like #121071 will be merged first.

  10. added a commit that references this issue on Sep 11, 2024
  11. added 2 commits that reference this issue on Sep 11, 2024
  12. vstinner commented on Sep 11, 2024

    @vstinner
    Member

    @skirpichev: Can we close this issue or do you plan further changes?

  13. skirpichev commented on Sep 11, 2024

    @skirpichev
    Member

    @vstinner, on my taste - documentation shouldn't be changed. This looks as a very special corner case with natural behaviour for whose who do care about distinction between 0.0 and -0.0. Most users, probably, won't notice this because zeros are equal.

    As Serhiy asked Mark too - lets wait his opinion. Tim Peters seems to be -0 on this.

  14. added a commit that references this issue on Sep 11, 2024
  15. 7 remaining items

  16. serhiy-storchaka commented on Sep 12, 2024

    @serhiy-storchaka
    Member

    Fist try to make __round__() converting a negative zero to positive zero and check whether anything fails.

  17. added a commit that references this issue on Sep 12, 2024
  18. skirpichev commented on Sep 12, 2024

    @skirpichev
    Member

    New pr: #124007

  19. added a commit that references this issue on Sep 13, 2024
  20. added 2 commits that reference this issue on Sep 13, 2024
  21. added a commit that references this issue on Sep 13, 2024
  22. skirpichev commented on Sep 17, 2024

    @skirpichev
    Member

    Two backport pr aren't merged.

  23. added 2 commits that reference this issue on Sep 24, 2024
  24. skirpichev commented on Oct 5, 2024

    @skirpichev
    Member

    Now merged.

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

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions