The documentation for sys.float_info says that this is the way to get the smallest possible float:

>>> math.ulp(0.0)
5e-324

The value of sys.float_info.min (part of a previous answer that I deleted) gives the smallest normalized float, a much bigger value.

Answer from Frank Yellin on Stack Overflow
Discussions

The smallest positive usable number
In python to get the smallest positive usable number for a float you can use: numpy.finfo(float).tiny Julia implement the function eps, but I don’t see nothing similar to tiny. Thanks. More on discourse.julialang.org
🌐 discourse.julialang.org
6
1
December 15, 2016
Smallest positive number machine can store
If we run the following code s=1 while s>0 : print(s) s=s/10 the last output is 10^-323 If we run the following one s=1 a=1+s while a> 1: print(s) s=s/10 a=1+s the last output is 10^-15 The two results appear to be inconsistent. In the second one if I change 1 to 16 (adding 4 bits)and run it ... More on discuss.python.org
🌐 discuss.python.org
5
0
June 3, 2021
4.9406564584124654e-324 ---------- This apparently is the smallest usable positive number in Python. ------ Is it the same in R ?
> .Machine$double.xmin
[1] 2.225074e-308

on my computer. YMMV. You do know that different computers can have different floating point?

Often you can work around precision problems by thinking. If you do calculation with no thought -- just pretending that the computer's "real" numbers are real real numbers -- then no amount of precision is enough to always get correct answers.

Edit: BTW "smallest usable positive number" doesn't define anything. That may account for the disagreement in numbers here. Look up denormalized numbers, which most but not all computers have.

More on reddit.com
🌐 r/Rlanguage
4
1
October 7, 2020
Increment a Python floating point value by the smallest possible amount - Stack Overflow
How can I increment a floating point value in python by the smallest possible amount? Background: I'm using floating point values as dictionary keys. Occasionally, very occasionally (and perhaps n... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Julia Programming Language
discourse.julialang.org › general usage
The smallest positive usable number - General Usage - Julia Programming Language
December 15, 2016 - In python to get the smallest positive usable number for a float you can use: numpy.finfo(float).tiny Julia implement the function eps, but I don’t see nothing similar to tiny. Thanks.
🌐
Python.org
discuss.python.org › python help
Smallest positive number machine can store - Python Help - Discussions on Python.org
June 3, 2021 - If we run the following code s=1 while s>0 : print(s) s=s/10 the last output is 10^-323 If we run the following one s=1 a=1+s while a> 1: print(s) s=s/10 a=1+s the last output is 10^-15 The two results appear to be inconsistent.
🌐
Reddit
reddit.com › r/rlanguage › 4.9406564584124654e-324 ---------- this apparently is the smallest usable positive number in python. ------ is it the same in r ?
r/Rlanguage on Reddit: 4.9406564584124654e-324 ---------- This apparently is the smallest usable positive number in Python. ------ Is it the same in R ?
October 7, 2020 -

https://stackoverflow.com/questions/38477908/smallest-positive-float64-number

4.9406564584124654e-324

This apparently is the smallest usable positive number in Python.

  • How does this compare with R, C and other languages ?

  • Don't people doing simulations, (numerical analysis?) etc. want more digits (more precision) ?

Top answer
1 of 15
119

Since Python 3.9 there is math.nextafter in the stdlib. Read on for alternatives in older Python versions.

Increment a python floating point value by the smallest possible amount

The nextafter(x,y) functions return the next discretely different representable floating-point value following x in the direction of y. The nextafter() functions are guaranteed to work on the platform or to return a sensible value to indicate that the next value is not possible.

The nextafter() functions are part of POSIX and ISO C99 standards and is _nextafter() in Visual C. C99 compliant standard math libraries, Visual C, C++, Boost and Java all implement the IEEE recommended nextafter() functions or methods. (I do not honestly know if .NET has nextafter(). Microsoft does not care much about C99 or POSIX.)

None of the bit twiddling functions here fully or correctly deal with the edge cases, such as values going though 0.0, negative 0.0, subnormals, infinities, negative values, over or underflows, etc. Here is a reference implementation of nextafter() in C to give an idea of how to do the correct bit twiddling if that is your direction.

There are two solid work arounds to get nextafter() or other excluded POSIX math functions in Python < 3.9:

Use Numpy:

>>> import numpy
>>> numpy.nextafter(0,1)
4.9406564584124654e-324
>>> numpy.nextafter(.1, 1)
0.10000000000000002
>>> numpy.nextafter(1e6, -1)
999999.99999999988
>>> numpy.nextafter(-.1, 1)
-0.099999999999999992

Link directly to the system math DLL:

import ctypes
import sys
from sys import platform as _platform

if _platform == "linux" or _platform == "linux2":
    _libm = ctypes.cdll.LoadLibrary('libm.so.6')
    _funcname = 'nextafter'
elif _platform == "darwin":
    _libm = ctypes.cdll.LoadLibrary('libSystem.dylib')
    _funcname = 'nextafter'
elif _platform == "win32":
    _libm = ctypes.cdll.LoadLibrary('msvcrt.dll')
    _funcname = '_nextafter'
else:
    # these are the ones I have access to...
    # fill in library and function name for your system math dll
    print("Platform", repr(_platform), "is not supported")
    sys.exit(0)

_nextafter = getattr(_libm, _funcname)
_nextafter.restype = ctypes.c_double
_nextafter.argtypes = [ctypes.c_double, ctypes.c_double]

def nextafter(x, y):
    "Returns the next floating-point number after x in the direction of y."
    return _nextafter(x, y)

assert nextafter(0, 1) - nextafter(0, 1) == 0
assert 0.0 + nextafter(0, 1) > 0.0

And if you really really want a pure Python solution:

# handles edge cases correctly on MY computer 
# not extensively QA'd...
import math
# 'double' means IEEE 754 double precision -- c 'double'
epsilon  = math.ldexp(1.0, -53) # smallest double that 0.5+epsilon != 0.5
maxDouble = float(2**1024 - 2**971)  # From the IEEE 754 standard
minDouble  = math.ldexp(1.0, -1022) # min positive normalized double
smallEpsilon  = math.ldexp(1.0, -1074) # smallest increment for doubles < minFloat
infinity = math.ldexp(1.0, 1023) * 2

def nextafter(x,y):    
    """returns the next IEEE double after x in the direction of y if possible"""
    if y==x:
       return y         #if x==y, no increment
             
    # handle NaN
    if x!=x or y!=y:
        return x + y       
    
    if x >= infinity:
        return infinity
        
    if x <= -infinity:
        return -infinity

    if -minDouble < x < minDouble:
        if y > x:
            return x + smallEpsilon
        else:
            return x - smallEpsilon  
        
    m, e = math.frexp(x)        
    if y > x:
        m += epsilon
    else:
        m -= epsilon
        
    return math.ldexp(m,e)

Or, use Mark Dickinson's excellent solution

Obviously the Numpy solution is the easiest.

2 of 15
18

Python 3.9 and above

Starting with Python 3.9, released 2020-10-05, you can use the math.nextafter function:

math.nextafter(x, y)

Return the next floating-point value after x towards y.

If x is equal to y, return y.

Examples:

  • math.nextafter(x, math.inf) goes up: towards positive infinity.

  • math.nextafter(x, -math.inf) goes down: towards minus infinity.

  • math.nextafter(x, 0.0) goes towards zero.

  • math.nextafter(x, math.copysign(math.inf, x)) goes away from zero.

See also math.ulp().

A simpler alternative to math.copysign(math.inf, x) is to simply substitute 2*x.

🌐
Glennrowe
glennrowe.net › programmingpages › 2021 › 04 › 26 › floats-and-the-math-library-in-python
Floats and the math library in Python – Programming pages
You can see the limits of the float ... min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1) Thus the largest positive float is 1.7976931348623157e+308, and the smallest positive float is 2.2250738585072014e-308, with ...
Find elsewhere
🌐
NumPy
numpy.org › doc › 2.1 › reference › generated › numpy.finfo.html
numpy.finfo — NumPy v2.1 Manual
The approximate number of decimal ... the value for the smallest normal. ... The smallest positive floating point number with 0 as leading bit in the mantissa following IEEE-754....
Top answer
1 of 2
11

Of course not, and epsilon has little to do with it. For example,

>>> x = 1e-200
>>> x
1e-200

is far from epsilon, but

>>> x * x
0.0

underflows to 0. If we actually used epsilon instead, then, e.g., multiplying it by 0.25 would underflow to 0 too.

Provided your platform C compiler and hardware support the 754 standard, though, the sign of the zero would match the sign of the multiplicand:

>>> x * -x
-0.0
2 of 2
9

No.

In [1]: import numpy

In [2]: x = numpy.nextafter(0, 1)

In [3]: x
Out[3]: 4.9406564584124654e-324

In [4]: x*x
Out[4]: 0.0

When the exact result is between 0 and the smallest positive float, it has to round to one of those options, and in this case, 0 is closer.

If for some reason you want to customize this behavior, NumPy lets you customize the behavior of underflow and other IEEE 754 floating-point exceptions with numpy.seterr, although it won't affect operations on ordinary Python objects:

In [5]: numpy.seterr(under='raise')
Out[5]: {'divide': 'warn', 'invalid': 'warn', 'over': 'warn', 'under': 'ignore'}

In [6]: x # NumPy float, not regular float, despite its looks
Out[6]: 4.9406564584124654e-324

In [7]: x*x
---------------------------------------------------------------------------
FloatingPointError                        Traceback (most recent call last)
<ipython-input-7-a3ff2a28c75d> in <module>()
----> 1 x*x

FloatingPointError: underflow encountered in double_scalars

In [8]: (4.9406564584124654e-324)**2 # regular float
Out[8]: 0.0

There's no way to change the rounding mode.

🌐
Note.nkmk.me
note.nkmk.me › home › python
Maximum and Minimum float Values in Python | note.nkmk.me
August 11, 2023 - The minimum positive denormalized float value · Note that there is no limit for the integer type (int) in Python 3. Integer (int) has no max limit in Python3 · The float type also has a special value, inf, which represents infinity. Infinity (inf) in Python ·
🌐
NumPy
numpy.org › doc › stable › reference › generated › numpy.finfo.html
numpy.finfo — NumPy v2.5 Manual
The smallest positive floating point number with 0 as leading bit in the mantissa following IEEE-754.
🌐
CSDN
devpress.csdn.net › python › 62fda034c67703293080414d.html
Smallest positive float64 number - Python - DevPress - CSDN
August 18, 2022 - >>> import numpy as np >>> np.nextafter(0, 1) 4.9406564584124654e-324 >>> np.nextafter(np.float32(0), np.float32(1)) 1.4012985e-45
🌐
Moonbooks
moonbooks.org › Articles › How-to-find-the-smallest-positive-value-in-a-list-in-python
How to find the smallest positive value in a list in python
May 26, 2020 - Tags: Python; List; Examples of how to find the smallest positive value in a list in python ? Table of contents · 1 -- Find the minimum value · 2 -- Find the smallest positive value · 3 -- Find the index of the smallest positive value · 4 -- References ·
🌐
NumPy
numpy.org › doc › 2.0 › reference › generated › numpy.finfo.html
numpy.finfo — NumPy v2.0 Manual
The approximate number of decimal ... the value for the smallest normal. ... The smallest positive floating point number with 0 as leading bit in the mantissa following IEEE-754....