[Python-Dev] Floor division

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


[Armin]
>>> BTW - isn't that case in contradiction with the general Python rule that
>>> if b > 0, then a % b should return a number between 0 included and b
>>> excluded?

[Tim]
>> Sure.

[Armin]
> You're not addressing my point, though, so I was probably not clear
> enough.

"Sure" is the answer to all possible points :-)

> My surprize was not that a % b was equal to b in this case, and
> so not strictly smaller than b (because I expect such things when
> working with floats).

That's unnecessarily pessimistic:  there's no problem defining modular
reduction for floats that's exact.

>  My surprize was that Decimals don't even try to
> be between 0 and b, and sometimes give a result that is far outside the
> range.  This surprized me because I expected floats and Decimals to try
> to give "approximately equal" results...

Sure, you do expect that, and sure, they don't.  Now what?

The `decimal` module is an implementation of IBM's proposed standard
for decimal arithmetic:

    http://www2.hursley.ibm.com/decimal/

It requires two mod-like operations, neither of which behave like
Python's "number theoretic" mod.  Nobody involved cared to extend the
proposed standard by adding a third mod-like operation.

For some reason `decimal` implemented __mod__ as the proposed
standard's "remainder" operation.  That's the immediate source of your
surprise.  IMO `decimal` should not have implemented __mod__ at all,
as Python's number-theoretic mod is not part of the proposed standard,
is a poor basis for a floating-point mod regardess, and it was a
mistake to implement decimal % decimal in a way so visibly different
from float % float and integer % integer:  it confuses the meaning of
"%".  That's your complaint, right?

My preferred "solution" is to remove __mod__, __divmod__, and
__floordiv__ from all flavors of floats (both binary and decimal) in
P3K.

That addresses your concern in that "decimal % decimal" would raise an
exception in P3K (it wouldn't be implemented).  A user who wanted some
form of decimal float modular reduction would need to read the docs,
decide which of the two supported such functions they want, and
explicitly ask for it.  Similarly, a user who wanted some from of
binary float modular reduction would need to invoke math.fmod()
explicitly -- or, possibly, if someone contributes the code needed to
implement C99's additional "remainder" function cross-platform, that
too:

IBM's spec          same-as C
----------          ---------
remainder           fmod (C89 & C99)
remainder-near      remainder (C99 & IEEE-754)

It's not a coincidence that all standards addressing modular reduction
for floats converge on essentially those two definitions.

I can't be made to feel guilty about this :-)

For P2 I don't propose any changes -- and in which case my only
response is just "sure - yes - right - decimal's __mod__ in fact does
not act like Python's integer __mod__ in mixed-sign cases -- and
neither does decimal's __floordiv__ or decimal's __divmod__ act like
their integer counterparts in mixed-sign cases".


More information about the Python-Dev mailing list