bug report: [ #447945 ] time.time() is not non-decreasing

Tim Peters tim.one at home.com
Sat Aug 4 22:41:04 EDT 2001


[zooko at zooko.com]
> ...
> I would really like to know if there is an efficient way to pick
> the *very next* floating point number up.

Your platform C library probably has a function with a name like nextafter()
for this; C99 requires it, but before that's universally implemented by C
vendors it's not likely to show up in Python.

Short of that, the following should work for your purposes (and all the
weasle-word disclaimers in the comments before nextafter() should hint at
why a fully correct version needs to know a lot about the platform float
representation -- that's why X3J11 insisted vendors supply this):

eps = 1.0
NBITS = 0
while (1. + eps) - 1. == eps:
    NBITS += 1
    if NBITS > 128:
        raise SystemError("machine floats are too bizarre to deal with")
    eps *= 0.5
del eps

from math import ldexp as _ldexp, frexp as _frexp

# Return closest representable float in the direction of +Inf.
# Inf or NaN arguments may return nonsense.
# 0 and denorm arguments may return nonsense.
# Normal x with 0 < x < Inf should be OK.

def nextafter(x, lastbit_wrt_half=_ldexp(1.0, -NBITS)):
    mantissa, exponent = _frexp(x)
    return _ldexp(mantissa + lastbit_wrt_half, exponent)



For example,

>>> 1.0
1.0
>>> nextafter(_)
1.0000000000000002
>>> nextafter(_)
1.0000000000000004
>>> nextafter(_)
1.0000000000000007
>>> nextafter(_)
1.0000000000000009
>>> nextafter(_)
1.0000000000000011
>>> nextafter(_)
1.0000000000000013
>>> 2. - 2.**-53
2.0
>>> 2. - 2.**-52
1.9999999999999998
>>> nextafter(_)
2.0
>>>





More information about the Python-list mailing list