tags:

views:

295

answers:

5

What are its smallest and biggest values in python?

+3  A: 

See this post.

Relevant parts of the post:

In [2]: import kinds 
In [3]: kinds.default_float_kind.M 
kinds.default_float_kind.MAX         kinds.default_float_kind.MIN 
kinds.default_float_kind.MAX_10_EXP  kinds.default_float_kind.MIN_10_EXP 
kinds.default_float_kind.MAX_EXP     kinds.default_float_kind.MIN_EXP 
In [3]: kinds.default_float_kind.MIN 
Out[3]: 2.2250738585072014e-308 
Juha Syrjälä
Note that Numeric has been largely superseded by NumPy. I wonder if a more modern equivalent of the kinds modules exists, though…
EOL
+4  A: 

Python uses double-precision floats, which can hold values from about 10 to the -308 to 10 to the 308 power.

http://en.wikipedia.org/wiki/Double%5Fprecision%5Ffloating-point%5Fformat

Try this experiment from the Python prompt:

>>> 1e308
1e+308
>>> 1e309
inf

10 to the 309 power is an overflow, but 10 to the 38 is not. QED.

Actually, you can probably get numbers smaller than 1e-308 via denormals, but there is a significant performance hit to this. I found that Python is able to handle 1e-324 but underflows on 1e-325 and returns 0.0 as the value.

steveha
And how's 1e+308 supposed to be bigger (see question) than infinity? ;)
sfussenegger
+3  A: 

As a kind of theoretical complement to the previous answers, I would like to mention that the "magic" value ±308 comes directly from the binary representation of floats. Double precision floats are of the form ±c*2**q with a "small" fractional value c (~1), and q an integer written with 11 binary digits (1 bit for its sign). The fact that 2**(2**10-1) has 308 (decimal) digits explains the appearance of 10**±308 in the extreme float values.

Check in Python:

print len(repr(2**(2**10-1)).strip('L'))
EOL
+1  A: 

Just playing around; here is an algorithmic method to find the minimum and maximum positive float, hopefully in any python implementation where float("+inf") is acceptable:

def find_float_limits():
    """Return a tuple of min, max positive numbers
    representable by the platform's float"""

    # first, make sure a float's a float
    if 1.0/10*10 == 10.0:
        raise RuntimeError("Your platform's floats aren't")

    minimum= maximum= 1.0
    infinity= float("+inf")

    # first find minimum
    last_minimum= 2*minimum
    while last_minimum > minimum > 0:
        last_minimum= minimum
        minimum*= 0.5

    # now find maximum
    operands= []
    while maximum < infinity:
        operands.append(maximum)
        try:
            maximum*= 2
        except OverflowError:
            break
    last_maximum= maximum= 0
    while operands and maximum < infinity:
        last_maximum= maximum
        maximum+= operands.pop()

    return last_minimum, last_maximum

if __name__ == "__main__":
    print (find_float_limits()) # python 2 and 3 friendly

In my case,

$ python so1835787.py
(4.9406564584124654e-324, 1.7976931348623157e+308)

so denormals are used.

ΤΖΩΤΖΙΟΥ
+5  A: 
>>> import sys
>>> sys.float_info
sys.floatinfo(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)

The smallest is sys.float_info.min (2.2250738585072014e-308) and the biggest is sys.float_info.max (1.7976931348623157e+308). See documentation for other properties.

Update: you can usually get denormalized minimum as sys.float_info.min*sys.float_info.epsilon. But note, that such numbers are represented with a loss of precision.

Denis Otkidach