Newbie help looping/reducing code

Paul Rubin http
Mon Feb 19 19:52:44 EST 2007


Lance Hoffmeyer <lance at augustmail.com> writes:
> def even_odd_round(num):
> 	if(round(num,2) + .5 == int(round(num,2)) + 1):
> 		if num > .5:
> 		     if(int(num) % 2):
> 		     	num = round(num,2) + .1 #an odd number
> 		     else:
> 		     	num = round(num,2) - .1 #an even number
> 		else:
> 		   num = 1
> 	rounded_num = int(round(num,0))
> 	return rounded_num

I would also rewrite this function.  It's quite hard to figure out
what it's intended to do.  At minimum it should be carefully
documented.  I have the impression it's supposed to be something like
the IEEE rounding mode, that rounds floating point numbers to the
nearest integer, rounding to the even neighbor if the fractional
part (sometimes called the mantissa) is close to 0.5.

> 	if(round(num,2) + .5 == int(round(num,2)) + 1):

The above is true if the mantissa is >= 0.495.  So you're going to
round 3.495 up to 4, even though it's actually closer to 3.  Is that
really what you want?  You're rounding based on a printed
representation rather than on the actual number.

> 		if num > .5:

It looks like for display purposes you're trying to avoid displaying
positive numbers as zero if they're slightly below 0.5.  However, that
doesn't prevent the round-to-even behavior if the number is slightly
above 0.5.  So you get the anomaly that even_odd_round(0.499) = 1,
but even_odd_round(0.501) = 0.  My guess is that's not what you wanted
and that it's a bug.

> 		     if(int(num) % 2):
> 		     	num = round(num,2) + .1 #an odd number
> 		     else:
> 		     	num = round(num,2) - .1 #an even number

If the integer part is odd, round upward, else round downward, ok.
So basically you're going to round to the even neighbor if the
mantissa is close to 0.5, otherwise round to the nearest integer.

I notice also that when num is negative, your function rounds to
the odd neighbor (at least sometimes), differing from IEEE rounding.

I think it's clearer to just separate out the integer and fractional
parts and branch on the fractional part directly.  I'll ignore the
issue with negative inputs since I'm guessing you only care about
positive ones:

def even_odd_round(num):
   assert num >= 0

   # separate the number's integer and fractional parts
   intpart, fracpart = int(num), num % 1.0

   # decide what to do based on the fractional part
   if fracpart < 0.495:
      return intpart                    # round downward
   elif fracpart > 0.505 or intpart==0:
      return intpart+1                  # round upward
   else:
      return intpart + intpart % 2      # round to even



More information about the Python-list mailing list