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

christian.heimes python-checkins at python.org
Wed Jan 23 16:44:46 CET 2008


Author: christian.heimes
Date: Wed Jan 23 16:44:46 2008
New Revision: 60217

Modified:
   python/branches/trunk-math/Lib/test/test_math.py
   python/branches/trunk-math/Modules/mathmodule.c
   python/branches/trunk-math/Objects/floatobject.c
Log:
Make 1**x and pow(1,x) always return 1, even for nan and inf

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	Wed Jan 23 16:44:46 2008
@@ -320,7 +320,16 @@
             self.assertRaises(ValueError, math.pow, 1, INF)
             self.assertRaises(ValueError, math.pow, 1, NINF)
         self.assert_(math.isnan(math.pow(NAN, 1)))
-        self.assert_(math.isnan(math.pow(1, NAN)))
+        self.assert_(math.isnan(math.pow(2, NAN)))
+        self.assertEqual(math.pow(1, NAN), 1)
+        self.assertEqual(1**NAN, 1)
+        self.assertEqual(1**INF, 1)
+        self.assertEqual(1**NINF, 1)
+        self.assertEqual(1**0, 1)
+        self.assertEqual(1.**NAN, 1)
+        self.assertEqual(1.**INF, 1)
+        self.assertEqual(1.**NINF, 1)
+        self.assertEqual(1.**0, 1)
 
     def testRadians(self):
         self.assertRaises(TypeError, math.radians)

Modified: python/branches/trunk-math/Modules/mathmodule.c
==============================================================================
--- python/branches/trunk-math/Modules/mathmodule.c	(original)
+++ python/branches/trunk-math/Modules/mathmodule.c	Wed Jan 23 16:44:46 2008
@@ -133,8 +133,6 @@
       "  x % y may differ.")
 FUNC2(hypot, hypot,
       "hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).")
-FUNC2(pow, pow,
-      "pow(x,y)\n\nReturn x**y (x to the power of y).")
 FUNC1(sin, sin,
       "sin(x)\n\nReturn the sine of x (measured in radians).")
 FUNC1(sinh, sinh,
@@ -316,6 +314,38 @@
 PyDoc_STRVAR(math_log10_doc,
 "log10(x) -> the base 10 logarithm of x.");
 
+static PyObject *
+math_pow(PyObject *self, PyObject *args)
+{
+	PyObject *ox, *oy;
+	double x, y;
+	if (! PyArg_UnpackTuple(args, "pow", 2, 2, &ox, &oy))
+		return NULL;
+	x = PyFloat_AsDouble(ox);
+	y = PyFloat_AsDouble(oy);
+	if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
+		return NULL;
+	/* 1^x returns 1., even NaN and INF */
+	if (x == 1.0)
+		return PyFloat_FromDouble(1.);
+#ifndef __GNUC__ /* Windows et al */
+	if (Py_IS_NAN(x) || Py_IS_NAN(y))
+		return PyFloat_FromDouble(x+y);
+#endif
+	errno = 0;
+	PyFPE_START_PROTECT("in math_pow", return 0)
+	x = pow(x, y);
+	PyFPE_END_PROTECT(x)
+	Py_SET_ERRNO_ON_MATH_ERROR(x);
+	if (errno && is_error(x))
+		return NULL;
+	else
+		return PyFloat_FromDouble(x);
+}
+
+PyDoc_STRVAR(math_pow_doc,
+"pow(x,y)\n\nReturn x**y (x to the power of y).");
+
 static const double degToRad = Py_MATH_PI / 180.0;
 static const double radToDeg = 180.0 / Py_MATH_PI;
 

Modified: python/branches/trunk-math/Objects/floatobject.c
==============================================================================
--- python/branches/trunk-math/Objects/floatobject.c	(original)
+++ python/branches/trunk-math/Objects/floatobject.c	Wed Jan 23 16:44:46 2008
@@ -1029,6 +1029,9 @@
 			return NULL;
 		}
 		return PyFloat_FromDouble(0.0);
+	if (iv == 1.0) { /* 1**w is 1, even 1**inf and 1**nan */
+		return PyFloat_FromDouble(1.0);
+	}
 	}
 	if (iv < 0.0) {
 		/* Whether this is an error is a mess, and bumps into libm


More information about the Python-checkins mailing list