:func:`frexp(x) <frexp>` Mantissa and exponent of *x*
:func:`isclose(a, b, rel_tol, abs_tol) <isclose>` Check if the values *a* and *b* are close to each other
:func:`isfinite(x) <isfinite>` Check if *x* is neither an infinity nor a NaN
+:func:`isnormal(x) <isnormal>` Check if *x* is a normal number
+:func:`issubnormal(x) <issubnormal>` Check if *x* is a subnormal number
:func:`isinf(x) <isinf>` Check if *x* is a positive or negative infinity
:func:`isnan(x) <isnan>` Check if *x* is a NaN (not a number)
:func:`ldexp(x, i) <ldexp>` ``x * (2**i)``, inverse of function :func:`frexp`
.. versionadded:: 3.2
+.. function:: isnormal(x)
+
+ Return ``True`` if *x* is a normal number, that is a finite
+ nonzero number that is not a subnormal (see :func:`issubnormal`).
+ Return ``False`` otherwise.
+
+ .. versionadded:: next
+
+
+.. function:: issubnormal(x)
+
+ Return ``True`` if *x* is a subnormal number, that is a finite
+ nonzero number with a magnitude smaller than the smallest positive normal
+ number, see :data:`sys.float_info.min`. Return ``False`` otherwise.
+
+ .. versionadded:: next
+
+
.. function:: isinf(x)
Return ``True`` if *x* is a positive or negative infinity, and
----
* Added more detailed error messages for domain errors in the module.
- (Contributed by by Charlie Zhao and Sergey B Kirpichev in :gh:`101410`.)
+ (Contributed by Charlie Zhao and Sergey B Kirpichev in :gh:`101410`.)
mimetypes
(Contributed by Jiahao Li in :gh:`134580`.)
+math
+----
+
+* Add :func:`math.isnormal` and :func:`math.issubnormal` functions.
+ (Contributed by Sergey B Kirpichev in :gh:`132908`.)
+
+
shelve
------
self.assertFalse(math.isfinite(float("inf")))
self.assertFalse(math.isfinite(float("-inf")))
+ def testIsnormal(self):
+ self.assertTrue(math.isnormal(1.25))
+ self.assertTrue(math.isnormal(-1.0))
+ self.assertFalse(math.isnormal(0.0))
+ self.assertFalse(math.isnormal(-0.0))
+ self.assertFalse(math.isnormal(INF))
+ self.assertFalse(math.isnormal(NINF))
+ self.assertFalse(math.isnormal(NAN))
+ self.assertFalse(math.isnormal(FLOAT_MIN/2))
+ self.assertFalse(math.isnormal(-FLOAT_MIN/2))
+
+ def testIssubnormal(self):
+ self.assertFalse(math.issubnormal(1.25))
+ self.assertFalse(math.issubnormal(-1.0))
+ self.assertFalse(math.issubnormal(0.0))
+ self.assertFalse(math.issubnormal(-0.0))
+ self.assertFalse(math.issubnormal(INF))
+ self.assertFalse(math.issubnormal(NINF))
+ self.assertFalse(math.issubnormal(NAN))
+ self.assertTrue(math.issubnormal(FLOAT_MIN/2))
+ self.assertTrue(math.issubnormal(-FLOAT_MIN/2))
+
def testIsnan(self):
self.assertTrue(math.isnan(float("nan")))
self.assertTrue(math.isnan(float("-nan")))
--- /dev/null
+Add :func:`math.isnormal` and :func:`math.issubnormal` functions. Patch by
+Sergey B Kirpichev.
return return_value;
}
+PyDoc_STRVAR(math_isnormal__doc__,
+"isnormal($module, x, /)\n"
+"--\n"
+"\n"
+"Return True if x is normal, and False otherwise.");
+
+#define MATH_ISNORMAL_METHODDEF \
+ {"isnormal", (PyCFunction)math_isnormal, METH_O, math_isnormal__doc__},
+
+static PyObject *
+math_isnormal_impl(PyObject *module, double x);
+
+static PyObject *
+math_isnormal(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ double x;
+
+ if (PyFloat_CheckExact(arg)) {
+ x = PyFloat_AS_DOUBLE(arg);
+ }
+ else
+ {
+ x = PyFloat_AsDouble(arg);
+ if (x == -1.0 && PyErr_Occurred()) {
+ goto exit;
+ }
+ }
+ return_value = math_isnormal_impl(module, x);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(math_issubnormal__doc__,
+"issubnormal($module, x, /)\n"
+"--\n"
+"\n"
+"Return True if x is subnormal, and False otherwise.");
+
+#define MATH_ISSUBNORMAL_METHODDEF \
+ {"issubnormal", (PyCFunction)math_issubnormal, METH_O, math_issubnormal__doc__},
+
+static PyObject *
+math_issubnormal_impl(PyObject *module, double x);
+
+static PyObject *
+math_issubnormal(PyObject *module, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ double x;
+
+ if (PyFloat_CheckExact(arg)) {
+ x = PyFloat_AS_DOUBLE(arg);
+ }
+ else
+ {
+ x = PyFloat_AsDouble(arg);
+ if (x == -1.0 && PyErr_Occurred()) {
+ goto exit;
+ }
+ }
+ return_value = math_issubnormal_impl(module, x);
+
+exit:
+ return return_value;
+}
+
PyDoc_STRVAR(math_isnan__doc__,
"isnan($module, x, /)\n"
"--\n"
exit:
return return_value;
}
-/*[clinic end generated code: output=77e7b8c161c39843 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=44bba3a0a052a364 input=a9049054013a1b77]*/
}
+/*[clinic input]
+math.isnormal
+
+ x: double
+ /
+
+Return True if x is normal, and False otherwise.
+[clinic start generated code]*/
+
+static PyObject *
+math_isnormal_impl(PyObject *module, double x)
+/*[clinic end generated code: output=c7b302b5b89c3541 input=fdaa00c58aa7bc17]*/
+{
+ return PyBool_FromLong(isnormal(x));
+}
+
+
+/*[clinic input]
+math.issubnormal
+
+ x: double
+ /
+
+Return True if x is subnormal, and False otherwise.
+[clinic start generated code]*/
+
+static PyObject *
+math_issubnormal_impl(PyObject *module, double x)
+/*[clinic end generated code: output=4e76ac98ddcae761 input=9a20aba7107d0d95]*/
+{
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+ return PyBool_FromLong(issubnormal(x));
+#else
+ return PyBool_FromLong(isfinite(x) && x && !isnormal(x));
+#endif
+}
+
+
/*[clinic input]
math.isnan
MATH_HYPOT_METHODDEF
MATH_ISCLOSE_METHODDEF
MATH_ISFINITE_METHODDEF
+ MATH_ISNORMAL_METHODDEF
+ MATH_ISSUBNORMAL_METHODDEF
MATH_ISINF_METHODDEF
MATH_ISNAN_METHODDEF
MATH_ISQRT_METHODDEF