Velocity Reviews > Rounding a number to nearest even

Rounding a number to nearest even

bdsatish
Guest
Posts: n/a

 04-11-2008
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
Guest
Posts: n/a

 04-11-2008
On 11 avr, 12:14, bdsatish <(E-Mail Removed)> 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 ?

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

bdsatish
Guest
Posts: n/a

 04-11-2008
On Apr 11, 3:27 pm, (E-Mail Removed) wrote:
> On 11 avr, 12:14, bdsatish <(E-Mail Removed)> 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 ?

>
> 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. = -2
new_round(-2.5) = -2.0

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

cokofreedom@gmail.com
Guest
Posts: n/a

 04-11-2008
couldn't you just do.

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

cokofreedom@gmail.com
Guest
Posts: n/a

 04-11-2008
On Apr 11, 1:19 pm, (E-Mail Removed) wrote:
> couldn't you just do.
>
> #untested
> new_round(n):
> answer = round(n)
> # is answer now odd
> if answer % 2:
> return answer - 1
> else:

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...

bdsatish
Guest
Posts: n/a

 04-11-2008
On Apr 11, 4:19 pm, (E-Mail Removed) wrote:
> couldn't you just do.
>
> #untested
> new_round(n):
> answer = round(n)
> # is answer now odd
> if answer % 2:
> return answer - 1
> else:

It fails for negative numbers: For -2.5 it gives -4.0 as answer
whereas I expect -2.0

bdsatish
Guest
Posts: n/a

 04-11-2008
On Apr 11, 4:24 pm, (E-Mail Removed) wrote:
> On Apr 11, 1:19 pm, (E-Mail Removed) 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)

bdsatish
Guest
Posts: n/a

 04-11-2008
On Apr 11, 4:37 pm, Scott David Daniels <(E-Mail Removed)> wrote:
> 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, 2:
> 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.

Gerard Flanagan
Guest
Posts: n/a

 04-11-2008
On Apr 11, 12:14 pm, bdsatish <(E-Mail Removed)> 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 myround(x):
n = int(x)
if abs(x - n) == 0.5:
if n % 2:
#it's odd
return n + 1 - 2 * int(n<0)
else:
return n
else:
return round(x)

assert myround(3.2) == 3
assert myround(3.6) == 4
assert myround(3.5) == 4
assert myround(2.5) == 2
assert myround(-0.5) == 0.0
assert myround(-1.5) == -2.0
assert myround(-1.3) == -1.0
assert myround(-1. == -2
assert myround(-2.5) == -2.0
------------------------------------------------

Gerard Flanagan
Guest
Posts: n/a

 04-11-2008
On Apr 11, 2:05 pm, Gerard Flanagan <(E-Mail Removed)> wrote:
> On Apr 11, 12:14 pm, bdsatish <(E-Mail Removed)> 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 myround(x):
> n = int(x)
> if abs(x - n) == 0.5:
> if n % 2:
> #it's odd
> return n + 1 - 2 * int(n<0)
> else:
> return n
> else:
> return round(x)
>
> ------------------------------------------------

In fact you can avoid the call to the builtin round:

------------------------------------------------
def myround(x):
n = int(x)
if abs(x - n) >= 0.5 and n % 2:
return n + 1 - 2 * int(n<0)
else:
return n

assert myround(3.2) == 3
assert myround(3.6) == 4
assert myround(3.5) == 4
assert myround(2.5) == 2
assert myround(-0.5) == 0.0
assert myround(-1.5) == -2.0
assert myround(-1.3) == -1.0
assert myround(-1. == -2
assert myround(-2.5) == -2.0
------------------------------------------------