[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
2001年9月03日 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;
!
}