[Python-checkins] CVS: python/dist/src/Objects intobject.c,2.70,2.71 longobject.c,1.99,1.100

Tim Peters tim_one@users.sourceforge.net
Mon, 03 Sep 2001 23:17:38 -0700


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

Modified Files:
	intobject.c longobject.c 
Log Message:
Change long/long true division to return as many good bits as it can;
e.g., (1L << 40000)/(1L << 40001) returns 0.5, not Inf or NaN or whatever.


Index: intobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v
retrieving revision 2.70
retrieving revision 2.71
diff -C2 -d -r2.70 -r2.71
*** intobject.c	2001/09/04 05:52:47	2.70
--- intobject.c	2001/09/04 06:17:36	2.71
***************
*** 536,540 ****
  int_true_divide(PyObject *v, PyObject *w)
  {
! 	return PyFloat_Type.tp_as_number->nb_true_divide(v, w);
  }
  
--- 536,547 ----
  int_true_divide(PyObject *v, PyObject *w)
  {
! 	/* If they aren't both ints, give someone else a chance.  In
! 	   particular, this lets int/long get handled by longs, which
! 	   underflows to 0 gracefully if the long is too big to convert
! 	   to float. */
! 	if (PyInt_Check(v) && PyInt_Check(w))
! 		return PyFloat_Type.tp_as_number->nb_true_divide(v, w);
! 	Py_INCREF(Py_NotImplemented);
! 	return Py_NotImplemented;
  }
  

Index: longobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v
retrieving revision 1.99
retrieving revision 1.100
diff -C2 -d -r1.99 -r1.100
*** longobject.c	2001/09/04 05:31:47	1.99
--- longobject.c	2001/09/04 06:17:36	1.100
***************
*** 1585,1589 ****
  long_true_divide(PyObject *v, PyObject *w)
  {
! 	return PyFloat_Type.tp_as_number->nb_divide(v, w);
  }
  
--- 1585,1620 ----
  long_true_divide(PyObject *v, PyObject *w)
  {
! 	PyLongObject *a, *b;
! 	double ad, bd;
! 	int aexp, bexp;
! 
! 	CONVERT_BINOP(v, w, &a, &b);
! 	ad = _PyLong_AsScaledDouble((PyObject *)a, &aexp);
! 	bd = _PyLong_AsScaledDouble((PyObject *)b, &bexp);
! 	if ((ad == -1.0 || bd == -1.0) && PyErr_Occurred())
! 		return NULL;
! 
! 	if (bd == 0.0) {
! 		PyErr_SetString(PyExc_ZeroDivisionError,
! 			"long division or modulo by zero");
! 		return NULL;
! 	}
! 
! 	/* True value is very close to ad/bd * 2**(SHIFT*(aexp-bexp)) */
! 	ad /= bd;	/* overflow/underflow impossible here */
! 	aexp -= bexp;
! 	if (aexp > INT_MAX / SHIFT)
! 		goto overflow;
! 	errno = 0;
! 	ad = ldexp(ad, aexp * SHIFT);
! 	if (ad != 0 && errno == ERANGE) /* ignore underflow to 0.0 */
! 		goto overflow;
! 	return PyFloat_FromDouble(ad);
! 
! overflow:
! 	PyErr_SetString(PyExc_OverflowError,
! 		"long/long too large for a float");
! 	return NULL;
! 	
  }