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