435,136 Members | 1,267 Online + 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
30 Replies

 P: n/a On 11 avr, 12:14, bdsatish

 P: n/a On Apr 11, 3:27 pm, colas.fran...@gmail.com wrote: On 11 avr, 12:14, bdsatish

 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) == .5 and divmod(rounded, 2) == 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 %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 ', 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

 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 >x = -0.5 + 2**-54x # 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

 P: n/a On Apr 11, 8:27*pm, Mark Dickinson

 P: n/a On 11 abr, 15:33, Lie

 P: n/a On Apr 11, 3:33 pm, Lie 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

 P: n/a On Apr 12, 3:44 am, hdante

 P: n/a Lie wrote: On Apr 12, 3:44 am, hdante 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

 P: n/a On Apr 11, 4:14*am, bdsatish

 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 isrounded to 2.0 and 2.5 is rounded to 3.0.If I want to round to the nearest even, that ismy_round(1.5) = 2 # As expectedmy_round(2.5) = 2 # Not 3, which is an odd numI'm interested in rounding numbers of the form "x.5" depending uponwhether 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 >[(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

 P: n/a Chris

 P: n/a On Apr 15, 11:47*am, Duncan Booth wrote: Chris

 P: n/a On Apr 15, 12:33*pm, Chris wrote: Chris

 P: n/a On 11 Apr, 21:29, Gabriel Genellina

 P: n/a On Apr 13, 7:20 pm, Steve Holden

This discussion thread is closed

Replies have been disabled for this discussion. 