cinap_lenrekadd hg and python4bb9e2215 years agoHistory
3458 lines · 84.5 KB · C
RawDownload
	if (((a->ob_size ^ b->ob_size) < 0) && z)		z->ob_size = -(z->ob_size);	Py_DECREF(a);	Py_DECREF(b);	return (PyObject *)z;} /* The / and % operators are now defined in terms of divmod().   The expression a mod b has the value a - b*floor(a/b).   The long_divrem function gives the remainder after division of   |a| by |b|, with the sign of a.  This is also expressed   as a - b*trunc(a/b), if trunc truncates towards zero.   Some examples:   	 a	 b	a rem b		a mod b   	 13	 10	 3		 3   	-13	 10	-3		 7   	 13	-10	 3		-7   	-13	-10	-3		-3   So, to get from rem to mod, we have to add b if a and b   have different signs.  We then subtract one from the 'div'   part of the outcome to keep the invariant intact. */ /* Compute *     *pdiv, *pmod = divmod(v, w) * NULL can be passed for pdiv or pmod, in which case that part of * the result is simply thrown away.  The caller owns a reference to * each of these it requests (does not pass NULL for). */static intl_divmod(PyLongObject *v, PyLongObject *w,	 PyLongObject **pdiv, PyLongObject **pmod){	PyLongObject *div, *mod; 	if (long_divrem(v, w, &div, &mod) < 0)		return -1;	if ((mod->ob_size < 0 && w->ob_size > 0) ||	    (mod->ob_size > 0 && w->ob_size < 0)) {		PyLongObject *temp;		PyLongObject *one;		temp = (PyLongObject *) long_add(mod, w);		Py_DECREF(mod);		mod = temp;		if (mod == NULL) {			Py_DECREF(div);			return -1;		}		one = (PyLongObject *) PyLong_FromLong(1L);		if (one == NULL ||		    (temp = (PyLongObject *) long_sub(div, one)) == NULL) {			Py_DECREF(mod);			Py_DECREF(div);			Py_XDECREF(one);			return -1;		}		Py_DECREF(one);		Py_DECREF(div);		div = temp;	}	if (pdiv != NULL)		*pdiv = div;	else		Py_DECREF(div); 	if (pmod != NULL)		*pmod = mod;	else		Py_DECREF(mod); 	return 0;} static PyObject *long_div(PyObject *v, PyObject *w){	PyLongObject *a, *b, *div; 	CONVERT_BINOP(v, w, &a, &b);	if (l_divmod(a, b, &div, NULL) < 0)		div = NULL;	Py_DECREF(a);	Py_DECREF(b);	return (PyObject *)div;} static PyObject *long_classic_div(PyObject *v, PyObject *w){	PyLongObject *a, *b, *div; 	CONVERT_BINOP(v, w, &a, &b);	if (Py_DivisionWarningFlag &&	    PyErr_Warn(PyExc_DeprecationWarning, "classic long division") < 0)		div = NULL;	else if (l_divmod(a, b, &div, NULL) < 0)		div = NULL;	Py_DECREF(a);	Py_DECREF(b);	return (PyObject *)div;} static PyObject *long_true_divide(PyObject *v, PyObject *w){	PyLongObject *a, *b;	double ad, bd;	int failed, aexp = -1, bexp = -1; 	CONVERT_BINOP(v, w, &a, &b);	ad = _PyLong_AsScaledDouble((PyObject *)a, &aexp);	bd = _PyLong_AsScaledDouble((PyObject *)b, &bexp);	failed = (ad == -1.0 || bd == -1.0) && PyErr_Occurred();	Py_DECREF(a);	Py_DECREF(b);	if (failed)		return NULL;	/* 'aexp' and 'bexp' were initialized to -1 to silence gcc-4.0.x,	   but should really be set correctly after sucessful calls to	   _PyLong_AsScaledDouble() */	assert(aexp >= 0 && bexp >= 0); 	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;	else if (aexp < -(INT_MAX / SHIFT))		return PyFloat_FromDouble(0.0);	/* underflow to 0 */	errno = 0;	ad = ldexp(ad, aexp * SHIFT);	if (Py_OVERFLOWED(ad)) /* 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; } static PyObject *long_mod(PyObject *v, PyObject *w){	PyLongObject *a, *b, *mod; 	CONVERT_BINOP(v, w, &a, &b); 	if (l_divmod(a, b, NULL, &mod) < 0)		mod = NULL;	Py_DECREF(a);	Py_DECREF(b);	return (PyObject *)mod;} static PyObject *long_divmod(PyObject *v, PyObject *w){	PyLongObject *a, *b, *div, *mod;	PyObject *z; 	CONVERT_BINOP(v, w, &a, &b); 	if (l_divmod(a, b, &div, &mod) < 0) {		Py_DECREF(a);		Py_DECREF(b);		return NULL;	}	z = PyTuple_New(2);	if (z != NULL) {		PyTuple_SetItem(z, 0, (PyObject *) div);		PyTuple_SetItem(z, 1, (PyObject *) mod);	}	else {		Py_DECREF(div);		Py_DECREF(mod);	}	Py_DECREF(a);	Py_DECREF(b);	return z;} /* pow(v, w, x) */static PyObject *long_pow(PyObject *v, PyObject *w, PyObject *x){	PyLongObject *a, *b, *c; /* a,b,c = v,w,x */	int negativeOutput = 0;  /* if x<0 return negative output */ 	PyLongObject *z = NULL;  /* accumulated result */	Py_ssize_t i, j, k;             /* counters */	PyLongObject *temp = NULL; 	/* 5-ary values.  If the exponent is large enough, table is	 * precomputed so that table[i] == a**i % c for i in range(32).	 */	PyLongObject *table[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,				   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 	/* a, b, c = v, w, x */	CONVERT_BINOP(v, w, &a, &b);	if (PyLong_Check(x)) {		c = (PyLongObject *)x;		Py_INCREF(x);	}	else if (PyInt_Check(x)) {		c = (PyLongObject *)PyLong_FromLong(PyInt_AS_LONG(x));		if (c == NULL)			goto Error;	}	else if (x == Py_None)		c = NULL;	else {		Py_DECREF(a);		Py_DECREF(b);		Py_INCREF(Py_NotImplemented);		return Py_NotImplemented;	} 	if (b->ob_size < 0) {  /* if exponent is negative */		if (c) {			PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "			    "cannot be negative when 3rd argument specified");			goto Error;		}		else {			/* else return a float.  This works because we know			   that this calls float_pow() which converts its			   arguments to double. */			Py_DECREF(a);			Py_DECREF(b);			return PyFloat_Type.tp_as_number->nb_power(v, w, x);		}	} 	if (c) {		/* if modulus == 0:		       raise ValueError() */		if (c->ob_size == 0) {			PyErr_SetString(PyExc_ValueError,					"pow() 3rd argument cannot be 0");			goto Error;		} 		/* if modulus < 0:		       negativeOutput = True		       modulus = -modulus */		if (c->ob_size < 0) {			negativeOutput = 1;			temp = (PyLongObject *)_PyLong_Copy(c);			if (temp == NULL)				goto Error;			Py_DECREF(c);			c = temp;			temp = NULL;			c->ob_size = - c->ob_size;		} 		/* if modulus == 1:		       return 0 */		if ((c->ob_size == 1) && (c->ob_digit[0] == 1)) {			z = (PyLongObject *)PyLong_FromLong(0L);			goto Done;		} 		/* if base < 0:		       base = base % modulus		   Having the base positive just makes things easier. */		if (a->ob_size < 0) {			if (l_divmod(a, c, NULL, &temp) < 0)				goto Error;			Py_DECREF(a);			a = temp;			temp = NULL;		}	} 	/* At this point a, b, and c are guaranteed non-negative UNLESS	   c is NULL, in which case a may be negative. */ 	z = (PyLongObject *)PyLong_FromLong(1L);	if (z == NULL)		goto Error; 	/* Perform a modular reduction, X = X % c, but leave X alone if c	 * is NULL.	 */#define REDUCE(X)					\	if (c != NULL) {				\		if (l_divmod(X, c, NULL, &temp) < 0)	\			goto Error;			\		Py_XDECREF(X);				\		X = temp;				\		temp = NULL;				\	} 	/* Multiply two values, then reduce the result:	   result = X*Y % c.  If c is NULL, skip the mod. */#define MULT(X, Y, result)				\{							\	temp = (PyLongObject *)long_mul(X, Y);		\	if (temp == NULL)				\		goto Error;				\	Py_XDECREF(result);				\	result = temp;					\	temp = NULL;					\	REDUCE(result)					\} 	if (b->ob_size <= FIVEARY_CUTOFF) {		/* Left-to-right binary exponentiation (HAC Algorithm 14.79) */		/* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf    */		for (i = b->ob_size - 1; i >= 0; --i) {			digit bi = b->ob_digit[i]; 			for (j = 1 << (SHIFT-1); j != 0; j >>= 1) {				MULT(z, z, z)				if (bi & j)					MULT(z, a, z)			}		}	}	else {		/* Left-to-right 5-ary exponentiation (HAC Algorithm 14.82) */		Py_INCREF(z);	/* still holds 1L */		table[0] = z;		for (i = 1; i < 32; ++i)			MULT(table[i-1], a, table[i]) 		for (i = b->ob_size - 1; i >= 0; --i) {			const digit bi = b->ob_digit[i]; 			for (j = SHIFT - 5; j >= 0; j -= 5) {				const int index = (bi >> j) & 0x1f;				for (k = 0; k < 5; ++k)					MULT(z, z, z)				if (index)					MULT(z, table[index], z)			}		}	} 	if (negativeOutput && (z->ob_size != 0)) {		temp = (PyLongObject *)long_sub(z, c);		if (temp == NULL)			goto Error;		Py_DECREF(z);		z = temp;		temp = NULL;	}	goto Done;  Error: 	if (z != NULL) { 		Py_DECREF(z); 		z = NULL; 	}	/* fall through */ Done:	if (b->ob_size > FIVEARY_CUTOFF) {		for (i = 0; i < 32; ++i)			Py_XDECREF(table[i]);	}	Py_DECREF(a);	Py_DECREF(b);	Py_XDECREF(c);	Py_XDECREF(temp);	return (PyObject *)z;} static PyObject *long_invert(PyLongObject *v){	/* Implement ~x as -(x+1) */	PyLongObject *x;	PyLongObject *w;	w = (PyLongObject *)PyLong_FromLong(1L);	if (w == NULL)		return NULL;	x = (PyLongObject *) long_add(v, w);	Py_DECREF(w);	if (x == NULL)		return NULL;	x->ob_size = -(x->ob_size);	return (PyObject *)x;} static PyObject *long_pos(PyLongObject *v){	if (PyLong_CheckExact(v)) {		Py_INCREF(v);		return (PyObject *)v;	}	else		return _PyLong_Copy(v);} static PyObject *long_neg(PyLongObject *v){	PyLongObject *z;	if (v->ob_size == 0 && PyLong_CheckExact(v)) {		/* -0 == 0 */		Py_INCREF(v);		return (PyObject *) v;	}	z = (PyLongObject *)_PyLong_Copy(v);	if (z != NULL)		z->ob_size = -(v->ob_size);	return (PyObject *)z;} static PyObject *long_abs(PyLongObject *v){	if (v->ob_size < 0)		return long_neg(v);	else		return long_pos(v);} static intlong_nonzero(PyLongObject *v){	return ABS(v->ob_size) != 0;} static PyObject *long_rshift(PyLongObject *v, PyLongObject *w){	PyLongObject *a, *b;	PyLongObject *z = NULL;	long shiftby;	Py_ssize_t newsize, wordshift, loshift, hishift, i, j;	digit lomask, himask; 	CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b); 	if (a->ob_size < 0) {		/* Right shifting negative numbers is harder */		PyLongObject *a1, *a2;		a1 = (PyLongObject *) long_invert(a);		if (a1 == NULL)			goto rshift_error;		a2 = (PyLongObject *) long_rshift(a1, b);		Py_DECREF(a1);		if (a2 == NULL)			goto rshift_error;		z = (PyLongObject *) long_invert(a2);		Py_DECREF(a2);	}	else { 		shiftby = PyLong_AsLong((PyObject *)b);		if (shiftby == -1L && PyErr_Occurred())			goto rshift_error;		if (shiftby < 0) {			PyErr_SetString(PyExc_ValueError,					"negative shift count");			goto rshift_error;		}		wordshift = shiftby / SHIFT;		newsize = ABS(a->ob_size) - wordshift;		if (newsize <= 0) {			z = _PyLong_New(0);			Py_DECREF(a);			Py_DECREF(b);			return (PyObject *)z;		}		loshift = shiftby % SHIFT;		hishift = SHIFT - loshift;		lomask = ((digit)1 << hishift) - 1;		himask = MASK ^ lomask;		z = _PyLong_New(newsize);		if (z == NULL)			goto rshift_error;		if (a->ob_size < 0)			z->ob_size = -(z->ob_size);		for (i = 0, j = wordshift; i < newsize; i++, j++) {			z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;			if (i+1 < newsize)				z->ob_digit[i] |=				  (a->ob_digit[j+1] << hishift) & himask;		}		z = long_normalize(z);	}rshift_error:	Py_DECREF(a);	Py_DECREF(b);	return (PyObject *) z; } 

Lines 2501–3000 of 3458. Previous lines