[Python-checkins] python/dist/src/Objects floatobject.c,2.122,2.123

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Sat, 24 May 2003 13:18:26 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1:/tmp/cvs-serv23294/Objects

Modified Files:
	floatobject.c 
Log Message:
SF bug 705231:  Assertion failed, python aborts.
float_pow():  Don't let the platform pow() raise -1.0 to an integer power
anymore; at least glibc gets it wrong in some cases.  Note that
math.pow() will continue to deliver wrong (but platform-native) results
in such cases.


Index: floatobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v
retrieving revision 2.122
retrieving revision 2.123
diff -C2 -d -r2.122 -r2.123
*** floatobject.c	21 Mar 2003 17:10:03 -0000	2.122
--- floatobject.c	24 May 2003 20:18:24 -0000	2.123
***************
*** 573,580 ****
  		return PyFloat_FromDouble(0.0);
  	}
! 	if (iv < 0.0 && iw != floor(iw)) {
! 		PyErr_SetString(PyExc_ValueError,
! 				"negative number cannot be raised to a fractional power");
! 		return NULL;
  	}
  	errno = 0;
--- 573,609 ----
  		return PyFloat_FromDouble(0.0);
  	}
! 	if (iv < 0.0) {
! 		/* Whether this is an error is a mess, and bumps into libm
! 		 * bugs so we have to figure it out ourselves.
! 		 */
! 		if (iw != floor(iw)) {
! 			PyErr_SetString(PyExc_ValueError, "negative number "
! 				"cannot be raised to a fractional power");
! 			return NULL;
! 		}
! 		/* iw is an exact integer, albeit perhaps a very large one.
! 		 * -1 raised to an exact integer should never be exceptional.
! 		 * Alas, some libms (chiefly glibc as of early 2003) return
! 		 * NaN and set EDOM on pow(-1, large_int) if the int doesn't
! 		 * happen to be representable in a *C* integer.  That's a
! 		 * bug; we let that slide in math.pow() (which currently
! 		 * reflects all platform accidents), but not for Python's **.
! 		 */
! 		 if (iv == -1.0 && !Py_IS_INFINITY(iw) && iw == iw) {
! 		 	/* XXX the "iw == iw" was to weed out NaNs.  This
! 		 	 * XXX doesn't actually work on all platforms.
! 		 	 */
! 		 	/* Return 1 if iw is even, -1 if iw is odd; there's
! 		 	 * no guarantee that any C integral type is big
! 		 	 * enough to hold iw, so we have to check this
! 		 	 * indirectly.
! 		 	 */
! 		 	ix = floor(iw * 0.5) * 2.0;
! 			return PyFloat_FromDouble(ix == iw ? 1.0 : -1.0);
! 		}
! 		/* Else iv != -1.0, and overflow or underflow are possible.
! 		 * Unless we're to write pow() ourselves, we have to trust
! 		 * the platform to do this correctly.
! 		 */
  	}
  	errno = 0;
***************
*** 584,589 ****
  	Py_ADJUST_ERANGE1(ix);
  	if (errno != 0) {
! 		assert(errno == ERANGE);
! 		PyErr_SetFromErrno(PyExc_OverflowError);
  		return NULL;
  	}
--- 613,621 ----
  	Py_ADJUST_ERANGE1(ix);
  	if (errno != 0) {
! 		/* We don't expect any errno value other than ERANGE, but
! 		 * the range of libm bugs appears unbounded.
! 		 */
! 		PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError :
! 						     PyExc_ValueError);
  		return NULL;
  	}