[Python-Dev] Floor division

Tim Peters tim.peters at gmail.com
Fri Jan 26 07:16:22 CET 2007


[Tim Peters]
>> ...
>> Maybe we could introduce "%" as a unary prefix operator, where
>> %x means "the fractional part of x" ;-)

[Anders J. Munch]
> What'ya talking about?  Obviously it should be a suffix operator ;-)

Na -- that would be confusing ;-)

...

>>      time.sleep(1.0 - math.fmod(now, 1.0))
>>
>> would do the same, except would be easier to reason about because it's
>> trivially guaranteed that 0.0 <= math.fmod(x, 1.0) < 1.0 for any
>> finite float x >= 0.0.  The same may or may not be true of % (I would
>> have to think about that, and craft a proof one way or the other -- if
>> it is true, it would have to invoke something special about the
>> modulus 1.0, as the inequality doesn't hold for % for some other
>> modulus values).

And as you note later, x%y == fmod(x, y) whenever x and y have the
same sign (well, given the way CPython implements float.__mod__
today), so there's actually an easy proof.

> Other modulus values are important:

On an importance scale of 1 to 10, 9 or 10 ;-) ?

> The attraction of Guido's formula is that he could just as easily have
> used 60.0 or 0.001 if minute or millisecond intervals were desired, or
> even som user-specified arbitrary dt.  Then we're comparing dt-now%dt
> to (1.0-int(now/dt))*dt or (math.ceil(now/dt)-now/dt)*dt.

time.time() is never negative in Python (see other reply), so the
trivial respelling dt-fmod(now, dt) does the same.

> Fortunately, for all a,b>0, mathematically math.fmod(a,b) is equal to
> a%b, so if the former is exactly representable, so is the latter.

Yup.  Also when `a` and `b` both less than 0.  This /follows/ from
that when `a` and `b` have the same sign, the mathematical a/b is >=
0, so truncation is the same as the floor.  Therefore the mathematical

    a - floor(a/b)*b   # Python __mod__
and
    a - truncate(a/b)*b  # C fmod

are exactly the same whenever a and b have the same sign.

> Which is borne out in floatobject.c: float_rem and float_divmod just
> pass on the C fmod result if (a < 0) == (b < 0).

Yes.  In fact, I wrote all that code :-)


More information about the Python-Dev mailing list