A use for integer quotients

Daniel Fackrell dfackrell at DELETETHIS.linuxmail.org
Mon Jul 23 18:11:25 CEST 2001

Newbie comment:

Why not add a "from __past__ import division" for those who need old code to
work.  Then there might be a little less resistance to this (arguably good)

"Guido van Rossum" <guido at python.org> wrote in message
news:cpzo9veuml.fsf at cj20424-a.reston1.va.home.com...
> > [David Eppstein]
> > > I don't suppose it would be possible to go through some repository of
> > > Python sources and figure out the relative numbers of divisions
> > > of integer arguments that end up an int versus the ones that are
> > > coerced to floats?
> [Tim Peters]
> > Guido did this for the Python library, and found three instances of "/"
> > would break.
> Alas, all this suggests is that the test suite *still* doesn't have
> enough coverage.  Looking for '/' tokens I found 30 modules using '/'
> amongst Lib/*.py, and a quick inspection suggests that the majority of
> these use integer division -- an expected result, given the
> over-emphasis of the standard library on classic data types and
> algorithms, which were mostly developed in a culture that despises
> floating point numbers as too expensive. :-)
> But I also found a likely bug!  In colorsys.py, there are two routines
> (rgb_to_hls() and rgb_to_hsv()) that seem to be doing floating point
> math using (r, g, b) inputs and don't take any consistent precaution
> to cast these inputs to floats before dividing them.  The outputs are
> definitely intended to be floats.  The inputs are likely RGB triples
> taken from images, which are usually ints.
> This is why making / fractional division and // truncated division
> will reduce the number of bugs in new code: for all occurrences of
> truncated division, the author *knows* she wants truncated division,
> and it's easy to remember to use // because using / gives an
> immediately wrong result.  When the users wants fractional division
> though, it's common to test only with float inputs, or to miss a path
> through the code where ints aren't casts to floats before they are
> being divided.  Then, much later, when an int gets passed and a
> slightly wrong result is calculated, it takes hours of debugging to
> discover the error.
> Note that this kind of bug is unique to Python (or dynamically typed
> languages in general): in C, the arguments would have been declared as
> floats and the problem would have been prevented.
> Reiterating why the current definition of '/' is evil: int and float
> together aren't really two distinct types: they are at most a
> type-and-a-half, and the integers are embedded in the space of floats
> for most practical purposes.  Division is the one exception, and it
> hurts.  Nobody wants to write polymorphic code where '/' means
> truncated division for int arguments but fractional division for float
> arguments.  You know which kind of division you want when you write
> the code, but there's no way to spell it.
> (I've seen this countered with the argument that classes can overload
> / any way they want, and thus you can't rely on the "meaning" of /
> anyway.  But there you get what you ask for, and it's up to the author
> of the class to decide how her class needs to behave in the context of
> other numeric types.  How integers behave in the context of floats is
> already decided: you should be able to pass an int whenever something
> requires a float.)
> Of course, I'm well aware of the issues around maintaining old code.
> We will have to carry around "from __future__ import division" for a
> loooooong time.  Python 2.2 is the first opportunity to introduce it,
> so let's not be shy.
> --Guido van Rossum (home page: http://www.python.org/~guido/)

More information about the Python-list mailing list