Christian Heimes added the comment:

The trunk_math_sign_inf_nan patch contains just three new method
isnan(), isinf() and sign(). It also fixes a minor numerical issue with
one function that did small / (small / large) instead of small * (large
/ small).

Added file: http://bugs.python.org/file8989/trunk_math_sign_inf_nan.patch

__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1640>
__________________________________
Index: Lib/test/test_math.py
===================================================================
--- Lib/test/test_math.py	(revision 59558)
+++ Lib/test/test_math.py	(working copy)
@@ -203,6 +203,31 @@
         self.ftest('tanh(0)', math.tanh(0), 0)
         self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
 
+    def testSign(self):
+        self.assertEqual(math.sign(0), 0)
+        self.assertEqual(math.sign(-2), -1)
+        self.assertEqual(math.sign(+2), 1)
+        self.assertEqual(math.sign(0.), 1)
+        self.assertEqual(math.sign(-0.), -1)
+        self.assertEqual(math.sign(-2.), -1)
+        self.assertEqual(math.sign(+2.), 1)
+
+    def testIsnan(self):
+        self.assert_(math.isnan(float("nan")))
+        self.assert_(math.isnan(float("inf")* 0.))
+        self.failIf(math.isnan(float("inf")))
+        self.failIf(math.isnan(0.))
+        self.failIf(math.isnan(1.))
+
+    def testIsinf(self):
+        self.assert_(math.isinf(float("inf")))
+        self.assert_(math.isinf(float("-inf")))
+        self.assert_(math.isinf(1E400))
+        self.assert_(math.isinf(-1E400))
+        self.failIf(math.isinf(float("nan")))
+        self.failIf(math.isinf(0.))
+        self.failIf(math.isinf(1.))
+
     # RED_FLAG 16-Oct-2000 Tim
     # While 2.0 is more consistent about exceptions than previous releases, it
     # still fails this part of the test on some platforms.  For now, we only
@@ -247,3 +272,4 @@
 
 if __name__ == '__main__':
     test_main()
+
Index: Modules/mathmodule.c
===================================================================
--- Modules/mathmodule.c	(revision 59558)
+++ Modules/mathmodule.c	(working copy)
@@ -277,9 +277,8 @@
 PyDoc_STRVAR(math_log10_doc,
 "log10(x) -> the base 10 logarithm of x.");
 
-/* XXX(nnorwitz): Should we use the platform M_PI or something more accurate
-   like: 3.14159265358979323846264338327950288 */
-static const double degToRad = 3.141592653589793238462643383 / 180.0;
+static const double degToRad = Py_MATH_PI / 180.0;
+static const double radToDeg = 180.0 / Py_MATH_PI;
 
 static PyObject *
 math_degrees(PyObject *self, PyObject *arg)
@@ -287,7 +286,7 @@
 	double x = PyFloat_AsDouble(arg);
 	if (x == -1.0 && PyErr_Occurred())
 		return NULL;
-	return PyFloat_FromDouble(x / degToRad);
+	return PyFloat_FromDouble(x * radToDeg);
 }
 
 PyDoc_STRVAR(math_degrees_doc,
@@ -305,6 +304,76 @@
 PyDoc_STRVAR(math_radians_doc,
 "radians(x) -> converts angle x from degrees to radians");
 
+static PyObject *
+math_isnan(PyObject *self, PyObject *arg)
+{
+	double x = PyFloat_AsDouble(arg);
+	if (x == -1.0 && PyErr_Occurred())
+		return NULL;
+	return PyBool_FromLong((long)Py_IS_NAN(x));
+}
+
+PyDoc_STRVAR(math_isnan_doc,
+"isnan(x) -> bool\n\
+Checks if float x is not a number (NaN)");
+
+static PyObject *
+math_isinf(PyObject *self, PyObject *arg)
+{
+	double x = PyFloat_AsDouble(arg);
+	if (x == -1.0 && PyErr_Occurred())
+		return NULL;
+	return PyBool_FromLong((long)Py_IS_INFINITY(x));
+}
+
+PyDoc_STRVAR(math_isinf_doc,
+"isinf(x) -> bool\n\
+Checks if float x is infinite (positive or negative)");
+
+static PyObject *
+math_sign(PyObject *self, PyObject *arg)
+{
+	int result = -2;
+	if (PyInt_Check(arg)) {
+		long l = PyInt_AsLong(arg);
+		if (l == -1.0 && PyErr_Occurred())
+			return NULL;
+		result = l > 0 ? 1 :
+				l < 0 ? -1 : 0;
+		
+	}
+	if (PyLong_Check(arg)) {
+		result = _PyLong_Sign(arg);
+	}
+	else if (PyFloat_Check(arg)) {
+		double x = PyFloat_AsDouble(arg);
+		if (x == -1.0 && PyErr_Occurred())
+			return NULL;
+#ifdef HAVE_COPYSIGN
+		result = (int)copysign(1., x);
+#elif defined(MS_WINDOWS)
+		result = (int)_copysign(1.0, x);
+#else
+		result = x > 0.0 ? 1 :
+				x < 0.0 ? -1 : 0;
+#endif
+	}
+	if (result == -2) {
+		PyErr_Format(PyExc_TypeError,
+			     "sign() expected int, long or float, found %s",
+			     Py_Type(arg)->tp_name);
+		return NULL;
+	}
+	return PyInt_FromLong((long)result);
+}
+
+PyDoc_STRVAR(math_sign_doc,
+"sign(x) -> +1 / 0 / -1\n\
+Return the sign of an int, long or float. On platforms with full IEEE 754\n\
+semantic sign(0.) returns +1 and sign(-0.) returns -1. On other platforms\n\
+sign(0.) always returns 0.");
+
+
 static PyMethodDef math_methods[] = {
 	{"acos",	math_acos,	METH_O,		math_acos_doc},
 	{"asin",	math_asin,	METH_O,		math_asin_doc},
@@ -320,12 +389,15 @@
 	{"fmod",	math_fmod,	METH_VARARGS,	math_fmod_doc},
 	{"frexp",	math_frexp,	METH_O,		math_frexp_doc},
 	{"hypot",	math_hypot,	METH_VARARGS,	math_hypot_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},
 	{"log",		math_log,	METH_VARARGS,	math_log_doc},
 	{"log10",	math_log10,	METH_O,		math_log10_doc},
 	{"modf",	math_modf,	METH_O,		math_modf_doc},
 	{"pow",		math_pow,	METH_VARARGS,	math_pow_doc},
 	{"radians",	math_radians,	METH_O,		math_radians_doc},
+	{"sign",	math_sign,	METH_O,		math_sign_doc},
 	{"sin",		math_sin,	METH_O,		math_sin_doc},
 	{"sinh",	math_sinh,	METH_O,		math_sinh_doc},
 	{"sqrt",	math_sqrt,	METH_O,		math_sqrt_doc},
@@ -351,13 +423,13 @@
 	if (d == NULL)
 		goto finally;
 
-        if (!(v = PyFloat_FromDouble(atan(1.0) * 4.0)))
+        if (!(v = PyFloat_FromDouble(Py_MATH_PI)))
                 goto finally;
 	if (PyDict_SetItemString(d, "pi", v) < 0)
                 goto finally;
 	Py_DECREF(v);
 
-        if (!(v = PyFloat_FromDouble(exp(1.0))))
+        if (!(v = PyFloat_FromDouble(Py_MATH_E)))
                 goto finally;
 	if (PyDict_SetItemString(d, "e", v) < 0)
                 goto finally;
_______________________________________________
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to