From 8e0c9968731ac7f1d94bddff348544c70833b52b Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 11 Jul 2010 17:38:24 +0000 Subject: [PATCH] Issue #9165: Add math.isfinite and cmath.isfinite. --- Doc/library/cmath.rst | 6 ++++++ Doc/library/math.rst | 6 ++++++ Lib/test/test_cmath.py | 9 +++++++++ Lib/test/test_math.py | 9 +++++++++ Misc/NEWS | 3 +++ Modules/cmathmodule.c | 14 ++++++++++++++ Modules/mathmodule.c | 14 ++++++++++++++ 7 files changed, 61 insertions(+) diff --git a/Doc/library/cmath.rst b/Doc/library/cmath.rst index 14b909bd28c..ae940398c8f 100644 --- a/Doc/library/cmath.rst +++ b/Doc/library/cmath.rst @@ -187,6 +187,12 @@ Hyperbolic functions Classification functions ------------------------ +.. function:: isfinite(x) + + Return ``True`` if both the real and imaginary parts of *x* are finite, + and ``False`` otherwise. + + .. function:: isinf(x) Return *True* if the real or the imaginary part of x is positive diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 9c3bd03698e..22f6f5fba9e 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -97,6 +97,12 @@ Number-theoretic and representation functions `_\. +.. function:: isfinite(x) + + Return ``True`` if *x* is neither an infinity nor a NaN, and + ``False`` otherwise. (Note that ``0.0`` *is* considered finite.) + + .. function:: isinf(x) Check if the float *x* is positive or negative infinity. diff --git a/Lib/test/test_cmath.py b/Lib/test/test_cmath.py index e6c80d2a1d3..a589f8db7ea 100644 --- a/Lib/test/test_cmath.py +++ b/Lib/test/test_cmath.py @@ -442,6 +442,15 @@ class CMathTests(unittest.TestCase): self.assertCEqual(rect(1, pi/2), (0, 1.)) self.assertCEqual(rect(1, -pi/2), (0, -1.)) + def test_isfinite(self): + real_vals = [float('-inf'), -2.3, -0.0, + 0.0, 2.3, float('inf'), float('nan')] + for x in real_vals: + for y in real_vals: + z = complex(x, y) + self.assertEquals(cmath.isfinite(z), + math.isfinite(x) and math.isfinite(y)) + def test_isnan(self): self.assertFalse(cmath.isnan(1)) self.assertFalse(cmath.isnan(1j)) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 12e7f98b02f..90bd3635e3f 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -915,6 +915,15 @@ class MathTests(unittest.TestCase): self.assertRaises(TypeError, math.trunc, 1, 2) self.assertRaises(TypeError, math.trunc, TestNoTrunc()) + def testIsfinite(self): + self.assertTrue(math.isfinite(0.0)) + self.assertTrue(math.isfinite(-0.0)) + self.assertTrue(math.isfinite(1.0)) + self.assertTrue(math.isfinite(-1.0)) + self.assertFalse(math.isfinite(float("nan"))) + self.assertFalse(math.isfinite(float("inf"))) + self.assertFalse(math.isfinite(float("-inf"))) + def testIsnan(self): self.assertTrue(math.isnan(float("nan"))) self.assertTrue(math.isnan(float("inf")* 0.)) diff --git a/Misc/NEWS b/Misc/NEWS index 0c11639aa1c..11ccc0e7c86 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1415,6 +1415,9 @@ Library Extension Modules ----------------- +- Issue #9165: Add new functions math.isfinite and cmath.isfinite, to + accompany existing isinf and isnan functions. + - Issue #1578269: Implement os.symlink for Windows 6.0+. Patch by Jason R. Coombs diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c index 2af2e53b88f..986b241e29a 100644 --- a/Modules/cmathmodule.c +++ b/Modules/cmathmodule.c @@ -1023,6 +1023,19 @@ PyDoc_STRVAR(cmath_rect_doc, "rect(r, phi) -> z: complex\n\n\ Convert from polar coordinates to rectangular coordinates."); +static PyObject * +cmath_isfinite(PyObject *self, PyObject *args) +{ + Py_complex z; + if (!PyArg_ParseTuple(args, "D:isfinite", &z)) + return NULL; + return PyBool_FromLong(Py_IS_FINITE(z.real) && Py_IS_FINITE(z.imag)); +} + +PyDoc_STRVAR(cmath_isfinite_doc, +"isfinite(z) -> bool\n\ +Return True if both the real and imaginary parts of z are finite, else False."); + static PyObject * cmath_isnan(PyObject *self, PyObject *args) { @@ -1065,6 +1078,7 @@ static PyMethodDef cmath_methods[] = { {"cos", cmath_cos, METH_VARARGS, c_cos_doc}, {"cosh", cmath_cosh, METH_VARARGS, c_cosh_doc}, {"exp", cmath_exp, METH_VARARGS, c_exp_doc}, + {"isfinite", cmath_isfinite, METH_VARARGS, cmath_isfinite_doc}, {"isinf", cmath_isinf, METH_VARARGS, cmath_isinf_doc}, {"isnan", cmath_isnan, METH_VARARGS, cmath_isnan_doc}, {"log", cmath_log, METH_VARARGS, cmath_log_doc}, diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 7f9372af86b..152788f401a 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1817,6 +1817,19 @@ PyDoc_STRVAR(math_radians_doc, "radians(x)\n\n\ Convert angle x from degrees to radians."); +static PyObject * +math_isfinite(PyObject *self, PyObject *arg) +{ + double x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + return PyBool_FromLong((long)Py_IS_FINITE(x)); +} + +PyDoc_STRVAR(math_isfinite_doc, +"isfinite(x) -> bool\n\n\ +Check if float x is finite (not an infinity or NaN)."); + static PyObject * math_isnan(PyObject *self, PyObject *arg) { @@ -1868,6 +1881,7 @@ static PyMethodDef math_methods[] = { {"fsum", math_fsum, METH_O, math_fsum_doc}, {"gamma", math_gamma, METH_O, math_gamma_doc}, {"hypot", math_hypot, METH_VARARGS, math_hypot_doc}, + {"isfinite", math_isfinite, METH_O, math_isfinite_doc}, {"isinf", math_isinf, METH_O, math_isinf_doc}, {"isnan", math_isnan, METH_O, math_isnan_doc}, {"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc},