bug report: [ #447945 ] time.time() is not non-decreasing
Ken Seehof
kseehof at neuralintegrator.com
Sat Aug 4 23:12:45 EDT 2001
import time
class IncreasingTimer:
def __init__(self):
trye = 1.0
self.lasttime=time.time()
while (self.lasttime + trye) > self.lasttime:
olde = trye
trye = trye / 2.0
# Multiplying by 2.0 once should be enough to deal with the unlikely
# possibility that time() will increase it's binary order of
magnitude.
# It is not necessary to do this more than once unless you are
# planning a continuous run of more than 30 years. Well, I guess
# that -could- happen (unless you are using windows).
# Let's multiply by 4.0. I'm shy about boundary conditions. :-)
self._TIME_EPSILON = olde*4.0
def time(self):
t = time.time()
lasttime = self.lasttime
if t <= lasttime:
t = lasttime + self._TIME_EPSILON
self.lasttime = t
return t
By getting rid of the delta logic, we allow time() to catch up with actual
time, rather than accumulate the error in an increasing delta.
>>> for i in range(20):
... print t.time() - time.time()
...
0.0
4.76837158203e-007
0.0
4.76837158203e-007
9.53674316406e-007
1.43051147461e-006
1.90734863281e-006
2.38418579102e-006
0.0
4.76837158203e-007
9.53674316406e-007
1.43051147461e-006
1.90734863281e-006
2.38418579102e-006
0.0
4.76837158203e-007
9.53674316406e-007
1.43051147461e-006
1.90734863281e-006
2.38418579102e-006
----- Original Message -----
From: <zooko at zooko.com>
To: "Bruce Sass" <bsass at freenet.edmonton.ab.ca>
Cc: <python-list at python.org>
Sent: Saturday, August 04, 2001 3:53 PM
Subject: Re: bug report: [ #447945 ] time.time() is not non-decreasing
>
> I have committed a cleaned up version of the IncreasingTimer which does
less
> floating point arithmetic and which contains comments showing exactly what
> I don't know about floating point.
>
>
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/~checkout~/mojonation/evil/co
mmon/timeutil.py?content-type=text/plain
>
> The relevant excerpt of the source is appended.
>
> Regards,
>
> Zooko
>
>
> class IncreasingTimer:
> def __init__(self):
> self.lasttime = time.time() # This stores the most recent answer
that we returned from `time()'.
> self.delta = 0 # We add this to the result from the underlying
`time.time()'.
>
> # How big of an increment do we need to add in order to make the
new float greater than the old float?
> trye = 1.0
> while (self.lasttime + trye) > self.lasttime:
> olde = trye
> trye = trye / 2.0
> self._TIME_EPSILON = olde
>
> def time(self):
> t = time.time() + self.delta
> lasttime = self.lasttime
>
> if t <= lasttime:
> self.delta = self.delta + (lasttime - t) + self._TIME_EPSILON
> t = lasttime + self._TIME_EPSILON
>
> # XXX if you were sure that you could generate a bigger float in
one pass, you could change
> # this `while' to an `if' and optimize out a test.
> while t <= lasttime:
> # We can get into here only if self._TIME_EPSILON is too small
to make the time float "tick over" to a new higher value.
> # So we (permanently) double self._TIME_EPSILON.
> # XXX is doubling epsilon the best way to quickly get a
minimally bigger float?
> self._TIME_EPSILON = self._TIME_EPSILON * 2.0
> # Delta, having smaller magnitude than t, can be incremented
by more than t was incremented. (Up to the old epsilon more.) That's OK.
> self.delta = self.delta + self._TIME_EPSILON
> t = t + self._TIME_EPSILON
>
> self.lasttime = t
> return t
>
> --
> http://mail.python.org/mailman/listinfo/python-list
More information about the Python-list
mailing list