[Python-checkins] CVS: python/dist/src/Objects floatobject.c,2.73,2.74 intobject.c,2.51,2.52 longobject.c,1.67,1.68

Tim Peters python-dev@python.org
Thu, 5 Oct 2000 17:36:12 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory slayer.i.sourceforge.net:/tmp/cvs-serv24366/python/dist/src/Objects

Modified Files:
	floatobject.c intobject.c longobject.c 
Log Message:
SF bug 115831 and Ping's SF patch 101751, 0.0**-2.0 returns inf rather than
raise ValueError.  Checked in the patch as far as it went, but also changed
all of ints, longs and floats to raise ZeroDivisionError instead when raising
0 to a negative number.  This is what 754-inspired stds require, as the "true
result" is an infinity obtained from finite operands, i.e. it's a singularity.
Also changed float pow to not be so timid about using its square-and-multiply
algorithm.  Note that what math.pow does is unrelated to what builtin pow
does, and will still vary by platform.


Index: floatobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v
retrieving revision 2.73
retrieving revision 2.74
diff -C2 -r2.73 -r2.74
*** floatobject.c	2000/09/26 05:46:01	2.73
--- floatobject.c	2000/10/06 00:36:09	2.74
***************
*** 450,467 ****
  	iw = ((PyFloatObject *)w)->ob_fval;
  	intw = (long)iw;
! 	if (iw == intw && -10000 < intw && intw < 10000) {
! 		/* Sort out special cases here instead of relying on pow() */
! 		if (intw == 0) { 		/* x**0 is 1, even 0**0 */
! 			PyFPE_START_PROTECT("pow", return 0)
! 		 	if ((PyObject *)z!=Py_None) {
! 			 	ix=fmod(1.0, z->ob_fval);
! 			 	if (ix!=0 && z->ob_fval<0) ix+=z->ob_fval;
! 			}
! 		 	else ix=1.0;
! 			PyFPE_END_PROTECT(ix)
! 	    		return PyFloat_FromDouble(ix); 
  		}
  		errno = 0;
! 		PyFPE_START_PROTECT("pow", return 0)
  		if (intw > 0)
  			ix = powu(iv, intw);
--- 450,480 ----
  	iw = ((PyFloatObject *)w)->ob_fval;
  	intw = (long)iw;
! 
! 	/* Sort out special cases here instead of relying on pow() */
! 	if (iw == 0) { 		/* x**0 is 1, even 0**0 */
! 		PyFPE_START_PROTECT("pow", return NULL)
! 		if ((PyObject *)z != Py_None) {
! 			ix = fmod(1.0, z->ob_fval);
! 			if (ix != 0 && z->ob_fval < 0)
! 				ix += z->ob_fval;
  		}
+ 		else
+ 			ix = 1.0;
+ 		PyFPE_END_PROTECT(ix)
+ 		return PyFloat_FromDouble(ix); 
+ 	}
+ 	if (iv == 0.0) {
+ 		if (iw < 0.0) {
+ 			PyErr_SetString(PyExc_ZeroDivisionError,
+ 				   "0.0 to a negative power");
+ 			return NULL;
+ 		}
+ 		return PyFloat_FromDouble(0.0);
+ 	}
+ 
+ 	if (iw == intw && intw > LONG_MIN) {
+ 		/* ruled out LONG_MIN because -LONG_MIN isn't representable */
  		errno = 0;
! 		PyFPE_START_PROTECT("pow", return NULL)
  		if (intw > 0)
  			ix = powu(iv, intw);
***************
*** 472,483 ****
  	else {
  		/* Sort out special cases here instead of relying on pow() */
- 		if (iv == 0.0) {
- 			if (iw < 0.0) {
- 				PyErr_SetString(PyExc_ValueError,
- 					   "0.0 to a negative power");
- 				return NULL;
- 			}
- 			return PyFloat_FromDouble(0.0);
- 		}
  		if (iv < 0.0) {
  			PyErr_SetString(PyExc_ValueError,
--- 485,488 ----
***************
*** 486,490 ****
  		}
  		errno = 0;
! 		PyFPE_START_PROTECT("pow", return 0)
  		ix = pow(iv, iw);
  		PyFPE_END_PROTECT(ix)
--- 491,495 ----
  		}
  		errno = 0;
! 		PyFPE_START_PROTECT("pow", return NULL)
  		ix = pow(iv, iw);
  		PyFPE_END_PROTECT(ix)
***************
*** 496,506 ****
  		return NULL;
  	}
!  	if ((PyObject *)z!=Py_None) {
! 		PyFPE_START_PROTECT("pow", return 0)
! 	 	ix=fmod(ix, z->ob_fval);	/* XXX To Be Rewritten */
! 	 	if ( ix!=0 &&
! 		      ((iv<0 && z->ob_fval>0) || (iv>0 && z->ob_fval<0) )) {
! 		     ix+=z->ob_fval;
! 		    }
  		PyFPE_END_PROTECT(ix)
  	}
--- 501,513 ----
  		return NULL;
  	}
! 	if ((PyObject *)z != Py_None) {
! 		PyFPE_START_PROTECT("pow", return NULL)
! 		ix = fmod(ix, z->ob_fval);	/* XXX To Be Rewritten */
! 		if (ix != 0 &&
! 		    ((iv < 0 && z->ob_fval > 0) ||
! 		     (iv > 0 && z->ob_fval < 0)
! 		    )) {
! 		     ix += z->ob_fval;
! 		}
  		PyFPE_END_PROTECT(ix)
  	}

Index: intobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v
retrieving revision 2.51
retrieving revision 2.52
diff -C2 -r2.51 -r2.52
*** intobject.c	2000/10/05 01:42:25	2.51
--- intobject.c	2000/10/06 00:36:09	2.52
***************
*** 484,489 ****
  	iw = w->ob_ival;
  	if (iw < 0) {
! 		PyErr_SetString(PyExc_ValueError,
! 				"integer to the negative power");
  		return NULL;
  	}
--- 484,493 ----
  	iw = w->ob_ival;
  	if (iw < 0) {
! 		if (iv)
! 			PyErr_SetString(PyExc_ValueError,
! 					"integer to a negative power");
! 		else
! 			PyErr_SetString(PyExc_ZeroDivisionError,
! 					"0 to a negative power");
  		return NULL;
  	}

Index: longobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v
retrieving revision 1.67
retrieving revision 1.68
diff -C2 -r1.67 -r1.68
*** longobject.c	2000/09/01 23:29:27	1.67
--- longobject.c	2000/10/06 00:36:09	1.68
***************
*** 1245,1250 ****
  	size_b = b->ob_size;
  	if (size_b < 0) {
! 		PyErr_SetString(PyExc_ValueError,
! 				"long integer to the negative power");
  		return NULL;
  	}
--- 1245,1254 ----
  	size_b = b->ob_size;
  	if (size_b < 0) {
! 		if (a->ob_size)
! 			PyErr_SetString(PyExc_ValueError,
! 					"long integer to a negative power");
! 		else
! 			PyErr_SetString(PyExc_ZeroDivisionError,
! 					"zero to a negative power");
  		return NULL;
  	}