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):
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):
> # is answer now odd
> 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):
> # is answer now odd
> 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):
> > # 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...

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

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post =?ISO-8859-1?Q?G=F6ran_Andersson?= ASP .Net 1 04-28-2006 08:29 AM chaz ASP .Net 0 04-27-2006 01:25 PM Greg Young [MVP] ASP .Net 0 04-27-2006 12:09 PM Derek Basch Python 8 02-28-2006 11:54 PM Shea Martin C++ 7 10-30-2003 04:51 PM