While Statement

J. Cliff Dyer jcd at sdf.lonestar.org
Fri May 22 11:21:06 EDT 2009


On Fri, 2009-05-22 at 09:59 -0400, Dave Angel wrote:
> 
> Tim Wintle wrote:
> > On Fri, 2009-05-22 at 13:19 +0200, Andre Engels wrote:
> >   
> >> number/total = 998/999 = 0
> >> number/total*100 = 0*100 = 0
> >> float(number/total*100) = float(0) = 0.0
> >>
> >> Change "float(number/total*100)" to "float(number)/total*100" and it
> >> should work:
> >>     
> >
> > I'd use:
> >
> >  (number * 100.)/total
> >
> > - works because
> >  <int> * <float> => <float> 
> >
> > It's a minor thing, but it's much faster to cast implicitly as you miss
> > the python function call overhead - it's no extra work to write, and for
> > numerical things it can really speed things up.
> >
> >   
> >>>> a = timeit.Timer("float(200)/5*100")
> >>>> b = timeit.Timer("(200*100.)/5")
> >>>> a.timeit(10000000)
> >>>>         
> > 12.282480955123901
> >   
> >>>> b.timeit(10000000)
> >>>>         
> > 3.6434230804443359
> >
> > Tim W
> >
> >
> >
> >   
> It's the old-timer in me, but I'd avoid the float entirely.  You start 
> with ints, and you want to end with ints.  So simply do the multiply 
> first, then the divide.
> 
>  number * 100/total
> 
> will get the same answer.
> 

Also, to get the same behavior (faster integer division) in python 3 or
when using `from __future__ import division`, use the // division
operator instead of /.

In fact, a little experimentation shows that you get the speedup even
when using python 2.6 with old-style division.  Probably because python
doesn't have to check the types of its arguments before deciding to do
integer division.

>>> a = timeit.Timer("(200 * 100.)/5")
>>> b = timeit.Timer("(200 * 100)/5")
>>> c = timeit.Timer("(200 * 100)//5")
>>> d = timeit.Timer("(200 * 100.0)//5")
>>> for each in a, b, c, d:
...     each.timeit(22222222)
... 
2.3681092262268066
2.417525053024292
0.81031703948974609
0.81548619270324707


Cheers,
Cliff







More information about the Python-list mailing list