Integer division and remainder

Tim Peters tim.one at home.com
Wed Aug 15 18:01:45 EDT 2001


[Tim]
> WRT Python, the decision to do flooring integer division was very
> deliberate, and not something Guido (or I -- since I pushed him
> this way, it's my fault <wink>) has ever had cause to regret.  We
> simply regret that division returns an integer at all(!).

[Paul Rubin]
> I thought of doing it that way in gawk (I wrote the original gawk
> interpreter) but wimped out and decided it was best to have two
> separate operators (that never got implemented).  If it's working
> out in python that's great.

It surprises *some* newcomers (depending on their background), but it hasn't
attracted any significant opposition.  People just don't divide 3 apples by
negative 2 people in real life <wink>, but (e.g.) time and date calculations
are inherently modular, so i%j taking the sign of j is most useful most
often (and it seems j is always > 0 in real life).  The identity

   i / 2**j == i >> j

for any int i and any int j>=0 is also pleasant.

> I think C99 made a mistake in specifying it one way or the other.  C
> doesn't have the same goals as python.  Languages like python should
> specify these things precisely.  Languages like C should leave more
> things up to the hardware.

I don't know of any HW that returns the floor for int division, so there was
scant harm in mandating what HW universally did anyway.  It does stop C
compilers from optimizing i/2**j directly to i>>j on machines where signed
right shifts extend the sign bit, i is a signed integral type, and the
compiler can't prove that i>=0 or that the last j bits are all zero.  That's
not giving up much (pointer subtraction in C does an implied division, but
that's usually by a power of 2 and where the compiler *can* assume the last
j bits of the difference are all 0 -- so they can still generate shifts
where it matters a lot).

> I don't know of any computers whose native division instructions do
> flooring integer division like python does.

Me neither, at least not by default.  Fortran mandated truncation very early
on, and it's been a vicious feedback loop ever since <0.5 wink>.

> I also notice that math.fmod (-3, 2) = -1.0, so now there's this weird
> inconsistency between integer % and math.fmod.  I don't know offhand
> what IEEE 796 says to do with fmod.

Umm, 796 is the Microcomputer System Bus std -- I don't think it says
anything about this.  754 (the fp std) has no use for C's fmod; in
*floating* numeric work, it's most useful most often to have mod(x, y)
(however spelled) return a result whose absolute value is no larger than
abs(y/2), and then the sign of the result has nothing to do with the signs
of the inputs.  C99 adds a float "remainder" function to do exactly that.
C99's fmod(x, y):

    The fmod functions return the value x - ny, for some integer n such
    that, if y is nonzero, the result has the same sign as x and
    magnitude less than the magnitude of y.  If y is zero, whether a
    domain error occurs or the fmod functions return zero is
    implementation-defined.

The expression "x-ny" there is to be read as mathematically exact, and n may
not be repesentable without multi-thousand bit integers.

All the Python math.* functions are thin wrappers around the C library
functions of the same names, so Python's math.* functions inherit whatever
the platform C library does (and Python doesn't try to redefine them).

> Finally I see that they added a // operation (floor division) to
> Python 2.2 and it looks like there's more changes like that in
> the pipeline.

Yes, there are several PEPs (Python Enhancement Proposals) open against
Python's numeric model.  Here's a URL:

    http://python.sourceforge.net/peps/

happy-reading!-ly y'rs  - tim





More information about the Python-list mailing list