[Python-Dev] Floor division

Tim Peters tim.peters at gmail.com
Tue Jan 23 12:27:29 CET 2007


[Tim Peters]
>> Please read the whole thread.  Maybe you did, but you said nothing
>> here that indicated you had.  The issues aren't about tiny integers
>> that happen to be in float format, where the result is exactly
>> representable as a float too.  Those don't create problems for any
>> definition of mod.  But even non-tiny exact integers can.

[Anders J. Munch]
> I did read the whole thread, and I saw your -1%1e100 example.  Mixing
> floating-point numbers of very different magnitude can get you in
> trouble - e.g. -1+1e100==1e100.  I don't think -1%1e100 is all that
> worse.

Except that it's very easy to return an exactly correct result in that
case:  -1.  This isn't like floating addition, where rounding errors
/must/ occur at times.  It's never necessary to suffer rounding errors
for a mod function defined with floats in mind.  Indeed, that's why
the C standards define fmod the way they do, and why IBM's proposed
standard for decimal floating arithmetic defines it the same way.

Python's definition of mod makes great sense for integers, but doesn't
generalize nicely.

>>> It's only Decimal.__mod__ that's inconsistent.  float.__mod__ has the
>>> usual floating-point inaccuracies, but then with float that goes with
>>> the territory.

>> No.  Decimal.__mod_  always returns the mathematically exact result.

> I meant inconsistent with integers.

While I was responding to your second sentence there, not your first.
You can tell because I didn't say anything after your first sentence
;-)

No, it's not always true that "with float [inaccuracies] goes with the
territory".  mod "should be" like absolute value and unary minus this
way:  always exact.

> People are familiar with the semantics of % on integers, because they use
> it all the time.

I'm not sure how many people are actually familiar with the semantics
of integer % when mixing signs, in part because there's no consistency
across languages in that area so people with a lot of experience tend
to avoid it.  I agree integer % is heavily used regardless.

> % on float is a natural extension of that and hence unsurprising.

It was natural to /want/ to extend it to floats.  That didn't work
well, and to the contrary it's surprising precisely /because/ the
behavior people enjoy with integers can fail when it's applied to
floats.  Having cases where abs(a%b) >= abs(b) is a
crash-the-space-shuttle level of surprise, especially since I know of
no other language in which that's possible.  It's not possible with
ints or longs in Python either -- or with math.fmod applied to floats.

> % on Decimal is exact and correct, but surprising all the same.

Which is why I don't want binary or decimal floats to support infix
"%" as a spelling in P3K.  I don't believe floating mod is heavily
used, and if so there's scant need for a one-character spelling -- and
if there's a method or function name to look up in the docs, a user
can read about what they're getting.

In fact, I expect the decimal module's "remainder-near" is what most
people using mod on floats actually want most of the time:  they
couldn't care less about the sign of the result, but they do want its
absolute value to as small as possible.  This is because floating
mod's one "natural" mixed-sign use is for argument reduction before
feeding the remainder into a series expansion.


More information about the Python-Dev mailing list