[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 :-)