Where is the correct round() method?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • josh logan

    Where is the correct round() method?

    Hello,

    I need a round function that _always_ rounds to the higher integer if
    the argument is equidistant between two integers. In Python 3.0, this
    is not the advertised behavior of the built-in function round() as
    seen below:
    >>round(0.5)
    0
    >>round(1.5)
    2
    >>round(2.5)
    2


    I would think this is a common need, but I cannot find a function in
    the Python library to do it. I wrote my own, but did I miss such a
    method in my search of the Python library?

    Thanks
  • Gary Herron

    #2
    Re: Where is the correct round() method?

    josh logan wrote:
    Hello,
    >
    I need a round function that _always_ rounds to the higher integer if
    the argument is equidistant between two integers. In Python 3.0, this
    is not the advertised behavior of the built-in function round() as
    seen below:
    >
    >
    >>>round(0.5)
    >>>>
    0
    >
    >>>round(1.5)
    >>>>
    2
    >
    >>>round(2.5)
    >>>>
    2
    >
    >
    Huh?
    >>round(2.5)
    3.0


    Works for me on Python 2.5 on Linux running on "Intel(R) Core(TM)2 Duo
    CPU". What system are you on?


    It could be that 2.5 is really 2.49999... which would round down to 2,
    but on any modern CPU (using IEEE floating point), 2.5 should be
    representable exactly.

    However, as with any floating point calculations, if you expect exact
    representation or calculations with any numbers, then you are misusing
    floating points.

    Gary Herron
    I would think this is a common need, but I cannot find a function in
    the Python library to do it. I wrote my own, but did I miss such a
    method in my search of the Python library?
    >
    Thanks
    --

    >

    Comment

    • pigmartian

      #3
      Re: Where is the correct round() method?

      it could be that 3.0 is using "banker's rounding" --- rounding to the
      even digit. the idea behind it behind it being to reduce error
      accumulation when working with large sets of values.

      Works for me on Python 2.5 on Linux running on "Intel(R) Core(TM)2 Duo
      CPU". What system are you on?
      >
      >
      It could be that 2.5 is really 2.49999... which would round down to 2,
      but on any modern CPU (using IEEE floating point), 2.5 should be
      representable exactly.
      >
      >

      Comment

      • josh logan

        #4
        Re: Where is the correct round() method?

        On Jul 27, 7:58 pm, Gary Herron <gher...@island training.comwro te:
        josh logan wrote:
        Hello,
        >
        I need a round function that _always_ rounds to the higher integer if
        the argument is equidistant between two integers. In Python 3.0, this
        is not the advertised behavior of the built-in function round() as
        seen below:
        >
        >>round(0.5)
        >
        0
        >
        >>round(1.5)
        >
        2
        >
        >>round(2.5)
        >
        2
        >
        Huh?
        >
         >>round(2.5)
        3.0
        >
        Works for me on Python 2.5 on Linux running on "Intel(R) Core(TM)2 Duo
        CPU".  What system are you on?
        >
        It could be that 2.5 is really 2.49999... which would round down to 2,
        but on any modern CPU (using IEEE floating point), 2.5 should be
        representable exactly.
        >
        However, as with any floating point calculations, if you expect exact
        representation or calculations with any numbers, then you are misusing
        floating points.
        >
        Gary Herron
        >
        I would think this is a common need, but I cannot find a function in
        the Python library to do it. I wrote my own, but did I miss such a
        method in my search of the Python library?
        >>
        >
        I should reiterate that I am using Python 3.0 and not Python 2.x.
        It looks like the behavior round() has changed between these two
        versions.
        Here is the documentation for round() in Python 3.0:


        Of interest in this discussion is the second paragraph, which explains
        the change:

        Does anyone know the reason behind this change, and what replacement
        method I can use to get the original behavior?

        Comment

        • josh logan

          #5
          Re: Where is the correct round() method?

          On Jul 27, 8:45 pm, pigmartian <scottp...@comc ast.netwrote:
          it could be that 3.0 is using "banker's rounding" --- rounding to the
          even digit.  the idea behind it behind it being to reduce error
          accumulation when working with large sets of values.
          >
          Works for me on Python 2.5 on Linux running on "Intel(R) Core(TM)2 Duo
          CPU".  What system are you on?
          >
          It could be that 2.5 is really 2.49999... which would round down to 2,
          but on any modern CPU (using IEEE floating point), 2.5 should be
          representable exactly.
          >
          >
          That's exactly what's happening, pigmartian. Thank you for explaining
          the reasoning behind this change.
          So am I relegated to building my own round() function that behaves
          like the original function? Or did they move the functionality to a
          new method somewhere for backwards-compatibility?

          Comment

          • Terry Reedy

            #6
            Re: Where is the correct round() method?



            Gary Herron wrote:
            josh logan wrote:
            >I need a round function that _always_ rounds to the higher integer if
            >the argument is equidistant between two integers. In Python 3.0, this
            >is not the advertised behavior of the built-in function round() as
            >seen below:
            >>>>round(2.5 )
            >>>>>
            >2
            Huh?
            >>round(2.5)
            3.0
            As the OP said, PY 3.0, where statisticians' unbiased round to even was
            explicitly adopted. (I think before it was maybe left to the C library?)
            >I would think this is a common need,
            If you need any particular rounding for legal/finance-rule reasons, you
            probably need the decimal module, which has several rounding modes and
            other features catering to money calculation rules.

            For general data analysis with floats, round to even is better.

            tjr

            Comment

            • Larry Bates

              #7
              Re: Where is the correct round() method?

              josh logan wrote:
              Hello,
              >
              I need a round function that _always_ rounds to the higher integer if
              the argument is equidistant between two integers. In Python 3.0, this
              is not the advertised behavior of the built-in function round() as
              seen below:
              >
              >>>round(0.5)
              0
              >>>round(1.5)
              2
              >>>round(2.5)
              2
              >
              >
              I would think this is a common need, but I cannot find a function in
              the Python library to do it. I wrote my own, but did I miss such a
              method in my search of the Python library?
              >
              Thanks
              I think what you want is something like:

              math.ceil(x-0.4999999999999 )

              -Larry

              Comment

              • Paul McGuire

                #8
                Re: Where is the correct round() method?

                On Jul 27, 8:55 pm, Larry Bates <larry.ba...@we bsafe.com`wrote :
                josh logan wrote:
                Hello,
                >
                I need a round function that _always_ rounds to the higher integer if
                the argument is equidistant between two integers. In Python 3.0, this
                is not the advertised behavior of the built-in function round() as
                seen below:
                >
                >>round(0.5)
                0
                >>round(1.5)
                2
                >>round(2.5)
                2
                >
                I would think this is a common need, but I cannot find a function in
                the Python library to do it. I wrote my own, but did I miss such a
                method in my search of the Python library?
                >
                Thanks
                >
                I think what you want is something like:
                >
                math.ceil(x-0.4999999999999 )
                >
                -Larry- Hide quoted text -
                >
                - Show quoted text -
                The version I learned back in my FORTRAN days was:

                int(x + 0.5)

                -- Paul

                Comment

                • Gary Herron

                  #9
                  Re: Where is the correct round() method?

                  josh logan wrote:
                  On Jul 27, 8:45 pm, pigmartian <scottp...@comc ast.netwrote:
                  >
                  >it could be that 3.0 is using "banker's rounding" --- rounding to the
                  >even digit. the idea behind it behind it being to reduce error
                  >accumulation when working with large sets of values.
                  >>
                  >>
                  >>Works for me on Python 2.5 on Linux running on "Intel(R) Core(TM)2 Duo
                  >>CPU". What system are you on?
                  >>>
                  >>It could be that 2.5 is really 2.49999... which would round down to 2,
                  >>but on any modern CPU (using IEEE floating point), 2.5 should be
                  >>representab le exactly.
                  >>>
                  >>
                  >
                  That's exactly what's happening, pigmartian. Thank you for explaining
                  the reasoning behind this change.
                  So am I relegated to building my own round() function that behaves
                  like the original function? Or did they move the functionality to a
                  new method somewhere for backwards-compatibility?
                  >
                  This will work as you wish:
                  math.floor(x+0. 5)

                  Gary Herron

                  Comment

                  • Casey

                    #10
                    Re: Where is the correct round() method?

                    On Jul 28, 12:34 am, Gary Herron <gher...@island training.comwro te:
                    This will work as you wish:
                      math.floor(x+0. 5)
                    This works fine for positive x but what about negative:
                    >>round(2.5)
                    3.0
                    >>floor(2.5 + 0.5)
                    3.0
                    >>round(-2.5)
                    -3.0
                    >>floor(-2.5 + 0.5)
                    -2.0

                    Maybe:

                    def round2(x):
                    return math.floor(x + (0.5 if x >= 0 else -0.5))

                    Comment

                    Working...