By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,136 Members | 1,267 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,136 IT Pros & Developers. It's quick & easy.

Rounding a number to nearest even

P: n/a
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 ?
Apr 11 '08 #1
Share this Question
Share on Google+
30 Replies


P: n/a
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
Apr 11 '08 #2

P: n/a
On Apr 11, 3:27 pm, colas.fran...@gmail.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)
Apr 11 '08 #3

P: n/a
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
Apr 11 '08 #4

P: n/a
On Apr 11, 1:19 pm, cokofree...@gmail.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...
Apr 11 '08 #5

P: n/a
On Apr 11, 4:19 pm, cokofree...@gmail.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
Apr 11 '08 #6

P: n/a
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
Apr 11 '08 #7

P: n/a
On Apr 11, 4:24 pm, cokofree...@gmail.com wrote:
On Apr 11, 1:19 pm, cokofree...@gmail.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)
Apr 11 '08 #8

P: n/a
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.
Apr 11 '08 #9

P: n/a
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

Apr 11 '08 #10

P: n/a
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_integral(
rounding=decimal.ROUND_HALF_EVEN)
decimal.Decimal("2.5").to_integral(
rounding=decimal.ROUND_HALF_EVEN)

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(rounding=decimal.ROUND_HALF_EVEN)
return int(rounded)
Graham
Apr 11 '08 #11

P: n/a
co*********@gmail.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

Apr 11 '08 #12

P: n/a
On Apr 11, 10:29 am, hdante <hda...@gmail.comwrote:
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.49999999999999994
>>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
Apr 11 '08 #13

P: n/a
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
Apr 11 '08 #14

P: n/a
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
Apr 11 '08 #15

P: n/a
On 11 abr, 15:33, Lie <Lie.1...@gmail.comwrote:
On Apr 11, 10:19 pm, Mikael Olofsson <mik...@isy.liu.sewrote:
That's exactly how I was taught to do rounding in what-ever low-level
class it was. The idea is to avoid a bias, which assumes that the
original values are already quantized. Assume that we have values
quantized to one decimal only, and assume that all values of this
decimal are equally likely. Also assume that the integer part of our
numbers are equally likely to be even or odd. Then the average rounding
error when rounding to integers will be 0.05 if you always round up when
the decimal is 5. If you round towards an even number instead when the
decimal is 5, then you will round up half of those times, and round down
the other half, and the average rounding error will be 0. That's the
idea. Of course you could argue that it would be even more fair to make
the choice based on the tossing of a fair coin.

That old-school rounding method you're taught is based on a wrong
assumption of the nature of number. In the past, rounding algorithm is
based on this:

Original =(RoundUp(u|d|n), RoundNearestEven(u|d|n)
...
1.0 =1(n), 1(n)
1.1 =1(d), 1(d)
1.2 =1(d), 1(d)
1.3 =1(d), 1(d)
1.4 =1(d), 1(d)
1.5 =2(u), 2(u)
1.6 =2(u), 2(u)
1.7 =2(u), 2(u)
1.8 =2(u), 2(u)
1.9 =2(u), 2(u)
2.0 =2(n), 2(n)
2.1 =2(d), 2(d)
2.2 =2(d), 2(d)
2.3 =2(d), 2(d)
2.4 =2(d), 2(d)
2.5 =3(u), 2(d)
2.6 =3(u), 3(u)
2.7 =3(u), 3(u)
2.8 =3(u), 3(u)
2.9 =3(u), 3(u)
...

In this used-to-be-thought-correct table, Round Ups algorithm have 2
Unrounded, 8 Round Down, and 10 Round Ups which seems incorrect while
Round Even have 2 Unrounded, 9 Round Down, and 9 Round Up which seems
correct. The misunderstanding comes from a view that thinks that there
is such thing as Not Rounded while in fact the only number that is Not
Rounded is 1 and 2 while 1.0 and 2.0 must still be rounded, in
practice we can just say that all number must be rounded somewhere.
That's not correct. If the numbers to be rounded come from a
measurement, the left column is not just a number but the representant
of an interval (as Mikael said, the're quantized). 2.3 means that the
measurement was closer to 2.3 than to 2.2 or 2.4 - that is, [2.25,
2.35) (it doesn't really matter which side is open or closed). It is
this "interval" behavior that forces the "round-to-even-on-halves"
rule.
So, the numbers 1.6-2.4 on the left column cover the interval [1.55,
2.45) and there is no doubt that they should be rounded to 2.0 because
all of them are closer to 2.0 than to any other integer. Similarly
[2.55, 3.45) are all rounded to 3.
But what to do with [2.45, 2.55), the interval represented by 2.5? We
can assume a uniform distribution here even if the whole distribution
is not (because we're talking of the smallest measurable range). So
half of the time the "true value" would have been < 2.5, and we should
round to 2. And half of the time it's 2.5 and we should round to 3.
Rounding always to 3 introduces a certain bias in the process.
Rounding randomly (tossing a coin, by example) would be fair, but
people usually prefer more deterministic approaches. If the number of
intervals is not so small, the "round even" rule provides a way to
choose from that two possibilities with equal probability.
So when we round 2.5 we are actually rounding an interval which could
be equally be rounded to 2 or to 3, and the same for 3.5, 4.5 etc. If
the number of such intervals is big, choosing the even number helps to
make as many rounds up as rounds down.
If the number of such intervals is small, *any* apriori rule will
introduce a bias.
Note that if you do not have quantized values and assuming that the
fraction part is evenly distributed between 0 and 1, than this whole
argument is moot. The probability of getting exactly 0.5 is zero in that
case, just as the probability of getting any other specified number is zero.

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))
That limit IS zero. And the probability of getting exactly a certain
real number, or any finite set of real numbers, is zero too (assuming
the usual definition of probability over infinite sets). But we're not
actually talking about real numbers here.

--
Gabriel Genellina
Jun 27 '08 #16

P: n/a
On Apr 11, 3:33 pm, Lie <Lie.1...@gmail.comwrote:
>
That old-school rounding method you're taught is based on a wrong
assumption of the nature of number. In the past, rounding algorithm is
based on this:

Original =(RoundUp(u|d|n), RoundNearestEven(u|d|n)
...
1.0 =1(n), 1(n)
1.1 =1(d), 1(d)
1.2 =1(d), 1(d)
1.3 =1(d), 1(d)
1.4 =1(d), 1(d)
1.5 =2(u), 2(u)
1.6 =2(u), 2(u)
1.7 =2(u), 2(u)
1.8 =2(u), 2(u)
1.9 =2(u), 2(u)
2.0 =2(n), 2(n)
2.1 =2(d), 2(d)
2.2 =2(d), 2(d)
2.3 =2(d), 2(d)
2.4 =2(d), 2(d)
2.5 =3(u), 2(d)
2.6 =3(u), 3(u)
2.7 =3(u), 3(u)
2.8 =3(u), 3(u)
2.9 =3(u), 3(u)
...

In this used-to-be-thought-correct table, Round Ups algorithm have 2
Unrounded, 8 Round Down, and 10 Round Ups which seems incorrect while
Round Even have 2 Unrounded, 9 Round Down, and 9 Round Up which seems
correct. The misunderstanding comes from a view that thinks that there
is such thing as Not Rounded while in fact the only number that is Not
Rounded is 1 and 2 while 1.0 and 2.0 must still be rounded, in
practice we can just say that all number must be rounded somewhere.

Original =(RoundUp(u|d), RoundNearestEven(u|d)
...
1.0 =1(d), 1(d)
1.1 =1(d), 1(d)
1.2 =1(d), 1(d)
1.3 =1(d), 1(d)
1.4 =1(d), 1(d)
1.5 =2(u), 2(u)
1.6 =2(u), 2(u)
1.7 =2(u), 2(u)
1.8 =2(u), 2(u)
1.9 =2(u), 2(u)
2.0 =2(d), 2(d)
2.1 =2(d), 2(d)
2.2 =2(d), 2(d)
2.3 =2(d), 2(d)
2.4 =2(d), 2(d)
2.5 =3(u), 2(d)
2.6 =3(u), 3(u)
2.7 =3(u), 3(u)
2.8 =3(u), 3(u)
2.9 =3(u), 3(u)
...

In this table, we consider that a number is rounded down when the
But then, the "Round up" table gives inconsistent results if, by the
same argument, we consider 2.0 -2 rounding up. (you get 12 round ups
and 8 round downs just by "rethinking" the argument). So, "rounding
up" is, at the same time, better and worse than rounding to nearest
even.
Another side-note: My 12-year old son is now being taught to always
round up from mid-way between. Yet another example of the degradation of
maths in schools.

A false assertion from a false understanding. The use of Round Up
algorithm is a refinement of the false understanding we used to
practice in the past.
The assertion is false, because there's no problem in rounding up,
truncating, etc. Just consider the amount of code snippets in this
thread. A simpler solution may solve a lot of problems.
Jun 27 '08 #17

P: n/a
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
Jun 27 '08 #18

P: n/a
Lie
On Apr 12, 3:44 am, hdante <hda...@gmail.comwrote:
(snip)
In this table, we consider that a number is rounded down when the

But then, the "Round up" table gives inconsistent results if, by the
same argument, we consider 2.0 -2 rounding up. (you get 12 round ups
and 8 round downs just by "rethinking" the argument). So, "rounding
up" is, at the same time, better and worse than rounding to nearest
even.
It's not round up, why? In the usual sense -- when not comparing
against round-half-even -- the number range we're talking is from x to
lim((x+1)-y)[y -0 from the positive side], e.g. 1 to nearly 2 (thus
the integer 2 itself is not included in the number range we're talking
since it belongs to the next set), then we choose a uniformly
distributed samples, i.e. 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8,
and 1.9. From these samples, we chose which are rounded down and which
are rounded up, it happens that 1.0 is rounded down, while 1.5 is
rounded up.

IF for the sake of argument, you choose the number range to be lim(x +
y)[y -0 from the positive side] to x + 1, e.g. barely above 1 to 2,
then the number sample you use is 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7,
1.8, 1.9, and 2.0, in this second number range, there are 5 round
downs (1.1, 1.2, 1.3, 1.4, 1.5) and 5 round ups (1.6, 1.7, 1.8, 1.9,
2.0), but how logical is it to choose this number range (barely above
1 to 2) against choosing the more natural range (1 to nearly 2): in
the correctly chosen number range (1 to nearly 2) all numbers in the
form of 1.x (where x is any positive number and 0) is contained within
it and there is nothing else in it, but in the second number range
(barely above 1 to 2) the number 1.0 is not included while the number
2.0 is contained in it, clearly not a clean separation of numbers in
the form of y.x where y is pre-determined and x is variable from other
possible values of y.

In short, choosing that x.0 is rounded down and x.5 is rounded up is
arbitrary but not without a reason.
Jun 27 '08 #19

P: n/a
Lie wrote:
On Apr 12, 3:44 am, hdante <hda...@gmail.comwrote:
[snip]
>
In short, choosing that x.0 is rounded down and x.5 is rounded up is
arbitrary but not without a reason.
Don't "arbitrary" and "not without a reason" directly contradict one
another?

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/

Jun 27 '08 #20

P: n/a
On Apr 13, 4:18*am, Lie <Lie.1...@gmail.comwrote:
[...]
it and there is nothing else in it, but in the second number range
(barely above 1 to 2) the number 1.0 is not included while the number
2.0 is contained in it, clearly not a clean separation of numbers in
the form of y.x where y is pre-determined and x is variable from other
possible values of y.
Have you considered the fact that the real numbers of
the form 1.xxxxx... are those in the range [1.0, 2.0],
including *both* endpoints? That is, 2.0 = 1.999999...
Similarly, the midpoint of this range can be written
both in the form 1.500000... and 1.499999...

This is relevant if you think of rounding as an operation
on *decimal representations* of real numbers rather than
as an operation on real numbers themselves. I'm not sure
which point of view you're taking here.

Either way, your arguments don't change the fact that the
average rounding error is strictly positive for positive
quantized results, under round-half-away-from-zero.

Mark
Jun 27 '08 #21

P: n/a
On Apr 11, 4:14*am, bdsatish <bdsat...@gmail.comwrote:
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 ?
Side note: A specialized use for this is in the US Field Artillery,
where it's called "artillery expression." You don't round, but
"express" a fraction to the nearest even whole number. 2.5 is 2.0,
3.5 is 4.0, etc. Or, if you need to express to the tens, 15 is 20, 25
is 20, and so on.
Jun 27 '08 #22

P: n/a
On Fri, 2008-04-11 at 03:14 -0700, 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 ?
This seams to work fine:
evenRound = lambda f: round(f/2.)*2
>>[(f*.5, evenRound(f*.5)) for f in xrange(0,20)]
[(0.0, 0.0),(0.5, 0.0),
(1.0, 2.0), (1.5, 2.0), (2.0, 2.0), (2.5, 2.0),
(3.0, 4.0), (3.5, 4.0), (4.0, 4.0), (4.5, 4.0),
(5.0, 6.0), (5.5, 6.0), (6.0, 6.0), (6.5, 6.0),
(7.0, 8.0), (7.5, 8.0), (8.0, 8.0), (8.5, 8.0),
(9.0, 10.0), (9.5, 10.0)]

--
Best Regards,
Med Venlig Hilsen,
Thomas

Jun 27 '08 #23

P: n/a
Thomas Dybdahl Ahle wrote:
On Fri, 2008-04-11 at 03:14 -0700, 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 ?
This seams to work fine:
evenRound = lambda f: round(f/2.)*2
>>>[(f*.5, evenRound(f*.5)) for f in xrange(0,20)]
[(0.0, 0.0),(0.5, 0.0),
(1.0, 2.0), (1.5, 2.0), (2.0, 2.0), (2.5, 2.0),
(3.0, 4.0), (3.5, 4.0), (4.0, 4.0), (4.5, 4.0),
(5.0, 6.0), (5.5, 6.0), (6.0, 6.0), (6.5, 6.0),
(7.0, 8.0), (7.5, 8.0), (8.0, 8.0), (8.5, 8.0),
(9.0, 10.0), (9.5, 10.0)]
No, this does not work:
>>[(f*.25, evenRound(f*.25)) for f in xrange(0,20)]
[(0.0, 0.0), (0.25, 0.0), (0.5, 0.0), (0.75, 0.0), (1.0, 2.0), (1.25,
2.0), (1.5, 2.0), (1.75, 2.0), (2.0, 2.0), (2.25, 2.0), (2.5, 2.0),
(2.75, 2.0), (3.0, 4.0), (3.25, 4.0), (3.5, 4.0), (3.75, 4.0), (4.0,
4.0), (4.25, 4.0), (4.5, 4.0), (4.75, 4.0)]

x.75 should be rounded up.

--
Sjoerd Mullender
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iQCVAwUBSARzyD7g04AjvIQpAQJALwP+Jp6FWbfgxI9JhOb07T cV5J7Hoyf2js/5
en0imvL7UkZ26JkM5M+2oOzN3ouydXo8fyw/TlYSgICqhI1rSKZBy3UqgsqaxYCm
lfucE4GSE46+y8G/OO8SB3ym2OnJBKNqkSuCYH2k3mDjrae802MDAFaeEkodK2wE
SQHZ9uTXY6E=
=IHSB
-----END PGP SIGNATURE-----

Jun 27 '08 #24

P: n/a
On Apr 15, 11:22*am, Sjoerd Mullender <sjo...@acm.orgwrote:
Thomas Dybdahl Ahle wrote:
On Fri, 2008-04-11 at 03:14 -0700, 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 ?
This seams to work fine:
evenRound = lambda f: round(f/2.)*2
>>[(f*.5, evenRound(f*.5)) for f in xrange(0,20)]
[(0.0, 0.0),(0.5, 0.0),
(1.0, 2.0), (1.5, 2.0), (2.0, 2.0), (2.5, 2.0),
(3.0, 4.0), (3.5, 4.0), (4.0, 4.0), (4.5, 4.0),
(5.0, 6.0), (5.5, 6.0), (6.0, 6.0), (6.5, 6.0),
(7.0, 8.0), (7.5, 8.0), (8.0, 8.0), (8.5, 8.0),
(9.0, 10.0), (9.5, 10.0)]

No, this does not work:>>[(f*.25, evenRound(f*.25)) for f in xrange(0,20)]

[(0.0, 0.0), (0.25, 0.0), (0.5, 0.0), (0.75, 0.0), (1.0, 2.0), (1.25,
2.0), (1.5, 2.0), (1.75, 2.0), (2.0, 2.0), (2.25, 2.0), (2.5, 2.0),
(2.75, 2.0), (3.0, 4.0), (3.25, 4.0), (3.5, 4.0), (3.75, 4.0), (4.0,
4.0), (4.25, 4.0), (4.5, 4.0), (4.75, 4.0)]

x.75 should be rounded up.

--
Sjoerd Mullender

*signature.asc
1KDownload
even is closer to even.75 than even+1.25. Why should it be rounded
up ?
Jun 27 '08 #25

P: n/a
On 14 avr, 20:02, Thomas Dybdahl Ahle <lob...@gmail.comwrote:
On Fri, 2008-04-11 at 03:14 -0700, 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 ?

This seams to work fine:
evenRound = lambda f: round(f/2.)*2
That was the solution I proposed first but it is inadequate since the
op does not want 3 to be rounded to 4.
If you're interested in this discussion, I kindly suggest you read the
whole thread: many interesting proposals and discussions have ensued.

Jun 27 '08 #26

P: n/a
Chris <cw****@gmail.comwrote:
even is closer to even.75 than even+1.25. Why should it be rounded
up ?
Because the OP wants to round values to the nearest integer. Only values of
the form 'x.5' which have two nearest values use 'nearest even' to
disambiguate the result.

See http://en.wikipedia.org/wiki/Roundin...to-even_method

That's the way I was taught to round numbers when at primary school.

Jun 27 '08 #27

P: n/a
On Apr 15, 11:47*am, Duncan Booth <duncan.bo...@invalid.invalid>
wrote:
Chris <cwi...@gmail.comwrote:
even is closer to even.75 than even+1.25. *Why should it be rounded
up ?

Because the OP wants to round values to the nearest integer. Only values of
the form 'x.5' which have two nearest values use 'nearest even' to
disambiguate the result.

Seehttp://en.wikipedia.org/wiki/Rounding#Round-to-even_method

That's the way I was taught to round numbers when at primary school.
My bad, didn't see he only wanted for halves and handle others as
normal.
Jun 27 '08 #28

P: n/a
On Apr 15, 12:33*pm, Chris <cwi...@gmail.comwrote:
On Apr 15, 11:47*am, Duncan Booth <duncan.bo...@invalid.invalid>
wrote:
Chris <cwi...@gmail.comwrote:
even is closer to even.75 than even+1.25. *Why should it be rounded
up ?
Because the OP wants to round values to the nearest integer. Only valuesof
the form 'x.5' which have two nearest values use 'nearest even' to
disambiguate the result.
Seehttp://en.wikipedia.org/wiki/Rounding#Round-to-even_method
That's the way I was taught to round numbers when at primary school.

My bad, didn't see he only wanted for halves and handle others as
normal.
My contribution then:

def my_round(x):
if x < 0:
NEG = 1
x = -x
else:
NEG = 0
if not x%.5 and not int(x)%2:
if NEG: return -round(x-.1)
return round(x-.1)
elif not x%.5 and int(x)%2:
if NEG: return -round(x+.1)
return round(x+.1)
elif NEG:
return round(-x)
else:
return round(x)

[(f*.25, my_round(f*.25)) for f in xrange(-20,20)]

[(-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)]
Jun 27 '08 #29

P: n/a
On 11 Apr, 21:29, Gabriel Genellina <gagsl-...@yahoo.com.arwrote:
... If the numbers to be rounded come from a
measurement, the left column is not just a number but the representant
of an interval (as Mikael said, the're quantized). 2.3 means that the
measurement was closer to 2.3 than to 2.2 or 2.4 - that is, [2.25,
2.35) (it doesn't really matter which side is open or closed). It is
this "interval" behavior that forces the "round-to-even-on-halves"
rule.
So, the numbers 1.6-2.4 on the left column cover the interval [1.55,
2.45) and there is no doubt that they should be rounded to 2.0 because
all of them are closer to 2.0 than to any other integer. Similarly
[2.55, 3.45) are all rounded to 3.
But what to do with [2.45, 2.55), the interval represented by 2.5? We
can assume a uniform distribution here even if the whole distribution
is not (because we're talking of the smallest measurable range). So
half of the time the "true value" would have been < 2.5, and we should
round to 2. And half of the time it's 2.5 and we should round to 3.
Rounding always to 3 introduces a certain bias in the process.
Rounding randomly (tossing a coin, by example) would be fair, but
people usually prefer more deterministic approaches. If the number of
intervals is not so small, the "round even" rule provides a way to
choose from that two possibilities with equal probability.
So when we round 2.5 we are actually rounding an interval which could
be equally be rounded to 2 or to 3, and the same for 3.5, 4.5 etc. If
the number of such intervals is big, choosing the even number helps to
make as many rounds up as rounds down.
If the number of such intervals is small, *any* apriori rule will
introduce a bias.
Great explanation!

--
Arnaud
Jun 27 '08 #30

P: n/a
Lie
On Apr 13, 7:20 pm, Steve Holden <st...@holdenweb.comwrote:
Lie wrote:
On Apr 12, 3:44 am, hdante <hda...@gmail.comwrote:
[snip]
In short, choosing that x.0 is rounded down and x.5 is rounded up is
arbitrary but not without a reason.

Don't "arbitrary" and "not without a reason" directly contradict one
another?
The same as choosing between round-half-odd and round-half-even,
arbitrary but not without a reason.

Language-wise it is a contradiction. In a loose semantic meaning, it
means there is no strong reason for choosing one above the other
(round-up vs round down and round-half-even vs round-half-odd) but
there are slight advantages on one that would seems silly to be
mentioned as the main reason, so arbitrary but not without reason.

On Apr 13, 9:28 pm, Mark Dickinson <dicki...@gmail.comwrote:
On Apr 13, 4:18 am, Lie <Lie.1...@gmail.comwrote:
[...]
it and there is nothing else in it, but in the second number range
(barely above 1 to 2) the number 1.0 is not included while the number
2.0 is contained in it, clearly not a clean separation of numbers in
the form of y.x where y is pre-determined and x is variable from other
possible values of y.

Have you considered the fact that the real numbers of
the form 1.xxxxx... are those in the range [1.0, 2.0],
including *both* endpoints? That is, 2.0 = 1.999999...
Similarly, the midpoint of this range can be written
both in the form 1.500000... and 1.499999...
No, you can only include one of the endpoints, because if both
endpoints are included, the integers would be a included twice on the
various sets of numbers, e.g. in [1.0 - 2.0] and [2.0 - 3.0] the
number 2.0 is included in both ranges, you can't be a member of both
ranges because that means if you have a "fair" random number
generator, the possibility of integral number to appear would be twice
the possibility of non-integral numbers, well that's not a fair random
number generator isn't it?
This is relevant if you think of rounding as an operation
on *decimal representations* of real numbers rather than
as an operation on real numbers themselves. I'm not sure
which point of view you're taking here.
Actually, I'm on the side that think numbers should never be
rounded[1], except for a final representation to human viewer who
should be made aware that the numbers in the presentation should never
be used for further calculation, as they are only informative but not
normative. In this view, the exact rounding method is irrelevant as
numbers used for calculation are never rounded while at the lower
level the amount of change caused by rounding has become irrelevant
because of the extra precision used. In short, if the rounding
algorithm causes you a trouble in the particular field, increase the
precision.

[1] As computers do have limitation on storage of real number
representation, this statement means that real numbers should be kept
as precise as the hardware allows or to use decimal and allow extra
precision generously.
Either way, your arguments don't change the fact that the
average rounding error is strictly positive for positive
quantized results, under round-half-away-from-zero.
If you include negative numbers, the ARE is zero on round-half-away-
from-zero, not in round-up though.
Jun 27 '08 #31

This discussion thread is closed

Replies have been disabled for this discussion.