Smallest float different from 0.0?

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Tue Sep 8 00:20:24 EDT 2009


On Mon, 07 Sep 2009 08:23:58 -0700, Mark Dickinson wrote:

> There's sys.float_info.min:
> 
>>>> import sys
>>>> sys.float_info
> sys.float_info(max=1.7976931348623157e+308, max_exp=1024,
> max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021,
> min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.2204460492503131e-16,
> radix=2, rounds=1)
>>>> sys.float_info.min
> 2.2250738585072014e-308
> 
> But that only gives you the smallest *normal* positive float, which is
> 2**-1022 on most systems.  The smallest positive subnormal value is
> usually 2**-1074.  If you want something that would still work if Python
> ever switched to using IEEE 754 binary128 format (or some other IEEE 754
> format), then
> 
> sys.float_info.min * 2**(1-sys.float_info.mant_dig)
> 
> will work.


Here's another implementation to give the next float. It should work for 
"normal" binary implementations:

from struct import pack, unpack

def next(x, y=None):
    """Returns the next float from x in the direction of y.
    If y is not given, the direction is towards positive infinity.
    """
    if x == y:
        return x
    if y is None or y > x:
        delta = cmp(x, 0.0) or 1
    elif y < x:
        delta = -(cmp(x, 0.0) or 1)
    else:
        raise ValueError("unordered x, y: %f, %f" % (x, y))
    return unpack('d', pack('q', unpack('q', pack('d', x))[0]+delta))[0]



>>> next(0.0)
4.9406564584124654e-324
>>> next(0.0, -1)
nan


You can also get signed zero:

>>> x = -next(0.0)
>>> next(x) == 0
True
>>> next(x)
-0.0




-- 
Steven



More information about the Python-list mailing list