bpo-39310: Add math.ulp(x) (GH-17965)

Add math.ulp(): return the value of the least significant bit
of a float.
diff --git a/Doc/library/math.rst b/Doc/library/math.rst
index c9f2a38..c4c1800 100644
--- a/Doc/library/math.rst
+++ b/Doc/library/math.rst
@@ -226,6 +226,8 @@
    * ``math.nextafter(x, 0.0)`` goes towards zero.
    * ``math.nextafter(x, math.copysign(math.inf, x))`` goes away from zero.
 
+   See also :func:`math.ulp`.
+
    .. versionadded:: 3.9
 
 .. function:: perm(n, k=None)
@@ -284,6 +286,30 @@
    :class:`~numbers.Integral` (usually an integer). Delegates to
    :meth:`x.__trunc__() <object.__trunc__>`.
 
+.. function:: ulp(x)
+
+   Return the value of the least significant bit of the float *x*:
+
+   * If *x* is a NaN (not a number), return *x*.
+   * If *x* is negative, return ``ulp(-x)``.
+   * If *x* is a positive infinity, return *x*.
+   * If *x* is equal to zero, return the smallest positive
+     *denormalized* representable float (smaller than the minimum positive
+     *normalized* float, :data:`sys.float_info.min <sys.float_info>`).
+   * If *x* is equal to the largest positive representable float,
+     return the value of the least significant bit of *x*, such that the first
+     float smaller than *x* is ``x - ulp(x)``.
+   * Otherwise (*x* is a positive finite number), return the value of the least
+     significant bit of *x*, such that the first float bigger than *x*
+     is ``x + ulp(x)``.
+
+   ULP stands for "Unit in the Last Place".
+
+   See also :func:`math.nextafter` and :data:`sys.float_info.epsilon
+   <sys.float_info>`.
+
+   .. versionadded:: 3.9
+
 
 Note that :func:`frexp` and :func:`modf` have a different call/return pattern
 than their C equivalents: they take a single argument and return a pair of