Rounding a number to nearest even

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

    Rounding a number to nearest even

    The built-in function round( ) will always "round up", that is 1.5 is
    rounded to 2.0 and 2.5 is rounded to 3.0.

    If I want to round to the nearest even, that is

    my_round(1.5) = 2 # As expected
    my_round(2.5) = 2 # Not 3, which is an odd num

    I'm interested in rounding numbers of the form "x.5" depending upon
    whether x is odd or even. Any idea about how to implement it ?
  • colas.francis@gmail.com

    #2
    Re: Rounding a number to nearest even

    On 11 avr, 12:14, bdsatish <bdsat...@gmail .comwrote:
    The built-in function round( ) will always "round up", that is 1.5 is
    rounded to 2.0 and 2.5 is rounded to 3.0.
    >
    If I want to round to the nearest even, that is
    >
    my_round(1.5) = 2 # As expected
    my_round(2.5) = 2 # Not 3, which is an odd num
    >
    I'm interested in rounding numbers of the form "x.5" depending upon
    whether x is odd or even. Any idea about how to implement it ?
    When you say "round to the nearest even", you mean new_round(3) <3?

    Is so, you can try:

    In [37]: def new_round(x):
    ....: return round(x/2.)*2
    ....:

    In [38]: new_round(1.5)
    Out[38]: 2.0

    In [39]: new_round(2.5)
    Out[39]: 2.0

    In [40]: new_round(3)
    Out[40]: 4.0

    Comment

    • bdsatish

      #3
      Re: Rounding a number to nearest even

      On Apr 11, 3:27 pm, colas.fran...@g mail.com wrote:
      On 11 avr, 12:14, bdsatish <bdsat...@gmail .comwrote:
      >
      The built-in function round( ) will always "round up", that is 1.5 is
      rounded to 2.0 and 2.5 is rounded to 3.0.
      >
      If I want to round to the nearest even, that is
      >
      my_round(1.5) = 2 # As expected
      my_round(2.5) = 2 # Not 3, which is an odd num
      >
      I'm interested in rounding numbers of the form "x.5" depending upon
      whether x is odd or even. Any idea about how to implement it ?
      >
      When you say "round to the nearest even", you mean new_round(3) <3?
      No. not at all. The clause "nearest even" comes into picture only when
      a number is of form "x.5" or else it's same as builtin round( ).
      new_round(3.0) must be 3.0 itself. Here is the mathematical definition
      of what I want:

      If 'n' is an integer,

      new_round(n+0.5 ) = n if n/2 is integer
      new_round(n+0.5 ) = (n+1) if (n+1)/2 is integer

      In all other cases, new_round() behave similarly as round( ). Here are
      the results I expect:

      new_round(3.2) = 3
      new_round(3.6) = 4
      new_round(3.5) = 4
      new_round(2.5) = 2
      new_round(-0.5) = 0.0
      new_round(-1.5) = -2.0
      new_round(-1.3) = -1.0
      new_round(-1.8) = -2
      new_round(-2.5) = -2.0

      The built-in function doesnt meet my needs for round(-2.5) or
      round(2.5)

      Comment

      • cokofreedom@gmail.com

        #4
        Re: Rounding a number to nearest even

        couldn't you just do.

        #untested
        new_round(n):
        answer = round(n)
        # is answer now odd
        if answer % 2:
        return answer - 1
        else:
        return answer

        Comment

        • cokofreedom@gmail.com

          #5
          Re: Rounding a number to nearest even

          On Apr 11, 1:19 pm, cokofree...@gma il.com wrote:
          couldn't you just do.
          >
          #untested
          new_round(n):
          answer = round(n)
          # is answer now odd
          if answer % 2:
          return answer - 1
          else:
          return answer
          Whoops, this also affects odd numbers...

          Will try and find a GOOD solution later...

          Strange request though, why do you need it that way, because 2.5 is
          CLOSER to 3 than to 2...

          Comment

          • bdsatish

            #6
            Re: Rounding a number to nearest even

            On Apr 11, 4:19 pm, cokofree...@gma il.com wrote:
            couldn't you just do.
            >
            #untested
            new_round(n):
            answer = round(n)
            # is answer now odd
            if answer % 2:
            return answer - 1
            else:
            return answer
            It fails for negative numbers: For -2.5 it gives -4.0 as answer
            whereas I expect -2.0

            Comment

            • Scott David Daniels

              #7
              Re: Rounding a number to nearest even

              bdsatish wrote:
              The built-in function round( ) will always "round up", that is 1.5 is
              rounded to 2.0 and 2.5 is rounded to 3.0.
              >
              If I want to round to the nearest even, that is
              >
              my_round(1.5) = 2 # As expected
              my_round(2.5) = 2 # Not 3, which is an odd num
              >
              I'm interested in rounding numbers of the form "x.5" depending upon
              whether x is odd or even. Any idea about how to implement it ?
              def rounded(v):
              rounded = round(v)
              if divmod(v, 1)[1] == .5 and divmod(rounded, 2)[1] == 1:
              if v 0:
              return rounded - 1
              return rounded + 1
              return rounded

              last = None
              for n in range(-29, 28):
              x = n * .25
              r = xr(x)
              if r != last:
              last = r
              print
              print '%s->%s' % (x, xr(x)),

              -7.25->-7.0 -7.0->-7.0 -6.75->-7.0
              -6.5->-6.0 -6.25->-6.0 -6.0->-6.0 -5.75->-6.0 -5.5->-6.0
              -5.25->-5.0 -5.0->-5.0 -4.75->-5.0
              -4.5->-4.0 -4.25->-4.0 -4.0->-4.0 -3.75->-4.0 -3.5->-4.0
              -3.25->-3.0 -3.0->-3.0 -2.75->-3.0
              -2.5->-2.0 -2.25->-2.0 -2.0->-2.0 -1.75->-2.0 -1.5->-2.0
              -1.25->-1.0 -1.0->-1.0 -0.75->-1.0
              -0.5->0.0 -0.25->-0.0 0.0->0.0 0.25->0.0 0.5->0.0
              0.75->1.0 1.0->1.0 1.25->1.0
              1.5->2.0 1.75->2.0 2.0->2.0 2.25->2.0 2.5->2.0
              2.75->3.0 3.0->3.0 3.25->3.0
              3.5->4.0 3.75->4.0 4.0->4.0 4.25->4.0 4.5->4.0
              4.75->5.0 5.0->5.0 5.25->5.0
              5.5->6.0 5.75->6.0 6.0->6.0 6.25->6.0 6.5->6.0
              6.75->7.0

              Comment

              • bdsatish

                #8
                Re: Rounding a number to nearest even

                On Apr 11, 4:24 pm, cokofree...@gma il.com wrote:
                On Apr 11, 1:19 pm, cokofree...@gma il.com wrote:
                >
                couldn't you just do.
                >
                #untested
                new_round(n):
                answer = round(n)
                # is answer now odd
                if answer % 2:
                return answer - 1
                else:
                return answer
                >
                Whoops, this also affects odd numbers...
                >
                Will try and find a GOOD solution later...
                >
                Strange request though, why do you need it that way, because 2.5 is
                CLOSER to 3 than to 2...
                It also fails for negative numbers. For -2.5 as input, I get -4.0
                whereas I expect -2.0

                This is a lengthy solution I came-up with:

                def round_even(x):
                temp = round(abs(x))
                if (abs(x) - 0.5)%2.0 == 0.0: temp=temp-1
                return signum(x)*temp

                def signum(x):
                if x>0: return 1
                if x<0: return -1
                return 0

                But i guess there are better ways. I need it 'cos I'm translating some
                code from Mathematica to Python. And Math..ica's Round[ ] behaves this
                way (as I requested)

                Comment

                • bdsatish

                  #9
                  Re: Rounding a number to nearest even

                  On Apr 11, 4:37 pm, Scott David Daniels <Scott.Dani...@ Acm.Orgwrote:
                  bdsatish wrote:
                  The built-in function round( ) will always "round up", that is 1.5 is
                  def rounded(v):
                  rounded = round(v)
                  if divmod(v, 1)[1] == .5 and divmod(rounded, 2)[1] == 1:
                  if v 0:
                  return rounded - 1
                  return rounded + 1
                  return rounded
                  >
                  last = None
                  for n in range(-29, 28):
                  x = n * .25
                  r = xr(x)
                  if r != last:
                  last = r
                  print
                  print '%s->%s' % (x, xr(x)),
                  >
                  Hi Scott,
                  This is what I was looking for.. I forgot about divmod( ) thanks for
                  reminding.

                  Comment

                  • Ivan Illarionov

                    #10
                    Re: Rounding a number to nearest even

                    On Apr 11, 2:14 pm, bdsatish <bdsat...@gmail .comwrote:
                    The built-in function round( ) will always "round up", that is 1.5 is
                    rounded to 2.0 and 2.5 is rounded to 3.0.
                    >
                    If I want to round to the nearest even, that is
                    >
                    my_round(1.5) = 2 # As expected
                    my_round(2.5) = 2 # Not 3, which is an odd num
                    >
                    I'm interested in rounding numbers of the form "x.5" depending upon
                    whether x is odd or even. Any idea about how to implement it ?
                    def even_round(x):
                    if x % 1 == .5 and not (int(x) % 2):
                    return float(int(x))
                    else:
                    return round(x)

                    nums = [ 3.2, 3.6, 3.5, 2.5, -.5, -1.5, -1.3, -1.8, -2.5 ]
                    for num in nums:
                    print num, '->', even_round(num)

                    3.2 -3.0
                    3.6 -4.0
                    3.5 -4.0
                    2.5 -2.0
                    -0.5 -0.0
                    -1.5 --2.0
                    -1.3 --1.0
                    -1.8 --2.0
                    -2.5 --2.0

                    Comment

                    • Graham Breed

                      #11
                      Re: Rounding a number to nearest even

                      On Apr 11, 6:14 pm, bdsatish <bdsat...@gmail .comwrote:
                      The built-in function round( ) will always "round up", that is 1.5 is
                      rounded to 2.0 and 2.5 is rounded to 3.0.
                      >
                      If I want to round to the nearest even, that is
                      >
                      my_round(1.5) = 2 # As expected
                      my_round(2.5) = 2 # Not 3, which is an odd num
                      If you care about such details, you may be better off using decimals
                      instead of floats.
                      I'm interested in rounding numbers of the form "x.5" depending upon
                      whether x is odd or even. Any idea about how to implement it ?
                      import decimal
                      decimal.Decimal ("1.5").to_inte gral(
                      rounding=decima l.ROUND_HALF_EV EN)
                      decimal.Decimal ("2.5").to_inte gral(
                      rounding=decima l.ROUND_HALF_EV EN)

                      ROUND_HALF_EVEN is the default, but maybe that can be changed, so
                      explicit is safest.

                      If you really insist,

                      import decimal
                      def my_round(f):
                      d = decimal.Decimal (str(f))
                      rounded = d.to_integral(r ounding=decimal .ROUND_HALF_EVE N)
                      return int(rounded)


                      Graham

                      Comment

                      • Robert Kern

                        #12
                        Re: Rounding a number to nearest even

                        cokofreedom@gma il.com wrote:
                        Strange request though, why do you need it that way, because 2.5 is
                        CLOSER to 3 than to 2...
                        Uhhh, no it isn't. (3 - 2.5) == (2.5 - 2)

                        --
                        Robert Kern

                        "I have come to believe that the whole world is an enigma, a harmless enigma
                        that is made terrible by our own mad attempt to interpret it as though it had
                        an underlying truth."
                        -- Umberto Eco

                        Comment

                        • Mark Dickinson

                          #13
                          Re: Rounding a number to nearest even

                          On Apr 11, 10:29 am, hdante <hda...@gmail.c omwrote:
                          Strangely, a "faster" version is:
                          >
                          def fast_round(x):
                          if x % 1 != 0.5: return round(x)
                          return 2.0*round(x/2.0)
                          You should be a little bit careful with the test
                          x%1 == 0.5 if x might be negative:
                          >>x = -0.5 + 2**-54
                          >>x # not an exact half...
                          -0.4999999999999 9994
                          >>x % 1 # ... and yet x%1 == 0.5
                          0.5

                          But for x positive, it should be safe. And for this
                          particular application, it turns out that it doesn't
                          matter: it gives the right result for this input anyway.

                          Mark

                          Comment

                          • Mark Dickinson

                            #14
                            Re: Rounding a number to nearest even

                            On Apr 11, 2:33 pm, Lie <Lie.1...@gmail .comwrote:
                            In this table, we consider that a number is rounded down when the
                            number is equal to truncated value (the number without fractional
                            part), while round up is equal to truncated value + 1 or truncated
                            value -1 if value is negative (Actually this is not round-half-up
                            algorithm, it's a round-half-away-from-zero algorithm, but lets just
                            consider that to be the same for now). In this revised table, you get
                            10 round ups and 10 round down (i.e. Average Rounding Error == 0),
                            while by rounding to nearest even you get 9 round up and 11 round down
                            (i.e. Average Rounding Error != 0).
                            No: if you interpret average to mean 'mean' (add up the (signed)
                            rounding errors from the 20 cases you list and divide by 20) you'll
                            find that the average rounding error is indeed 0 for round-half-to-
                            even,
                            and 0.05 for round-half-away-from-0, just as Mikael said.
                            Another mistake, in an unquantized value the probability of getting
                            exactly 0.5 (or any other number specified) is not 0 but an
                            infinitesimal (i.e. lim(x) where x -0 (BUT NOT ZERO))
                            I'm not sure you'll get many takers for this point of view. If X is
                            a random variable uniformly distributed on the interval [0, 1) then
                            the probability that X == 0.5 is indeed exactly 0, using conventional
                            definitions. (And if you're not using conventional definitions, you
                            should say so....)

                            Mark

                            Comment

                            • Arnaud Delobelle

                              #15
                              Re: Rounding a number to nearest even

                              On Apr 11, 8:27 pm, Mark Dickinson <dicki...@gmail .comwrote:
                              On Apr 11, 2:33 pm, Lie <Lie.1...@gmail .comwrote:
                              [...]
                              Another mistake, in an unquantized value the probability of getting
                              exactly 0.5 (or any other number specified) is not 0 but an
                              infinitesimal (i.e. lim(x) where x -0 (BUT NOT ZERO))
                              >
                              I'm not sure you'll get many takers for this point of view.  If X is
                              a random variable uniformly distributed on the interval [0, 1) then
                              the probability that X == 0.5 is indeed exactly 0, using conventional
                              definitions.  (And if you're not using conventional definitions, you
                              should say so....)
                              And I would like to know what unconventional - but mathematically
                              meaningful - definitions lead to

                              lim x != 0
                              x -0

                              --
                              Arnaud

                              Comment

                              Working...