[Python-checkins] r60404 - in python/branches/trunk-math: Lib/test/test_math.py Modules/mathmodule.c

mark.dickinson python-checkins at python.org
Tue Jan 29 00:26:59 CET 2008


Author: mark.dickinson
Date: Tue Jan 29 00:26:59 2008
New Revision: 60404

Modified:
   python/branches/trunk-math/Lib/test/test_math.py
   python/branches/trunk-math/Modules/mathmodule.c
Log:
Fix up special-value handling for modf, ldexp and frexp.


Modified: python/branches/trunk-math/Lib/test/test_math.py
==============================================================================
--- python/branches/trunk-math/Lib/test/test_math.py	(original)
+++ python/branches/trunk-math/Lib/test/test_math.py	Tue Jan 29 00:26:59 2008
@@ -289,6 +289,10 @@
         testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
         testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
 
+        self.assertEquals(math.frexp(INF)[0], INF)
+        self.assertEquals(math.frexp(NINF)[0], NINF)
+        self.assert_(math.isnan(math.frexp(NAN)[0]))
+
     def testHypot(self):
         self.assertRaises(TypeError, math.hypot)
         self.ftest('hypot(0,0)', math.hypot(0,0), 0)
@@ -306,6 +310,13 @@
         self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
         self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
         self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
+        self.assertRaises(OverflowError, math.ldexp, 1., 1000000)
+        self.assertRaises(OverflowError, math.ldexp, -1., 1000000)
+        self.assertEquals(math.ldexp(1., -1000000), 0.)
+        self.assertEquals(math.ldexp(-1., -1000000), -0.)
+        self.assertEquals(math.ldexp(INF, 30), INF)
+        self.assertEquals(math.ldexp(NINF, -213), NINF)
+        self.assert_(math.isnan(math.ldexp(NAN, 0)))
 
     def testLog(self):
         self.assertRaises(TypeError, math.log)
@@ -349,6 +360,13 @@
         testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
         testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
 
+        self.assertEquals(math.modf(INF), (0.0, INF))
+        self.assertEquals(math.modf(NINF), (-0.0, NINF))
+
+        modf_nan = math.modf(NAN)
+        self.assert_(math.isnan(modf_nan[0]))
+        self.assert_(math.isnan(modf_nan[1]))
+
     def testPow(self):
         self.assertRaises(TypeError, math.pow)
         self.ftest('pow(0,1)', math.pow(0,1), 0)

Modified: python/branches/trunk-math/Modules/mathmodule.c
==============================================================================
--- python/branches/trunk-math/Modules/mathmodule.c	(original)
+++ python/branches/trunk-math/Modules/mathmodule.c	Tue Jan 29 00:26:59 2008
@@ -233,7 +233,7 @@
 		return NULL;
 	errno = 0;
 	x = frexp(x, &i);
-	Py_SET_ERRNO_ON_MATH_ERROR(x);
+	/* frexp shouldn't set errno;  check, just in case. */
 	if (errno && is_error(x))
 		return NULL;
 	else
@@ -250,19 +250,20 @@
 static PyObject *
 math_ldexp(PyObject *self, PyObject *args)
 {
-	double x;
+	double x, r;
 	int exp;
 	if (! PyArg_ParseTuple(args, "di:ldexp", &x, &exp))
 		return NULL;
 	errno = 0;
 	PyFPE_START_PROTECT("ldexp", return 0)
-	x = ldexp(x, exp);
-	PyFPE_END_PROTECT(x)
-	Py_SET_ERRNO_ON_MATH_ERROR(x);
-	if (errno && is_error(x))
+	r = ldexp(x, exp);
+	PyFPE_END_PROTECT(r)
+	if (Py_IS_FINITE(x) && Py_IS_INFINITY(r))
+		errno = ERANGE;
+	if (errno && is_error(r))
 		return NULL;
 	else
-		return PyFloat_FromDouble(x);
+		return PyFloat_FromDouble(r);
 }
 
 PyDoc_STRVAR(math_ldexp_doc,
@@ -276,7 +277,9 @@
 		return NULL;
 	errno = 0;
 	x = modf(x, &y);
-	Py_SET_ERRNO_ON_MATH_ERROR(x);
+	/* modf should never set errno; if it does, we raise a Python
+	 exception---better to raise an exception than silently return
+	 a possibly wrong value */
 	if (errno && is_error(x))
 		return NULL;
 	else


More information about the Python-checkins mailing list