mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Add prototypes.
Change / and % to match divmod.
This commit is contained in:
parent
3d09543472
commit
e32e014c7e
1 changed files with 156 additions and 113 deletions
|
@ -27,10 +27,19 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
/* XXX The functional organization of this file is terrible */
|
/* XXX The functional organization of this file is terrible */
|
||||||
|
|
||||||
#include "allobjects.h"
|
#include "allobjects.h"
|
||||||
|
#include "intrcheck.h"
|
||||||
#include "longintrepr.h"
|
#include "longintrepr.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define ABS(x) ((x) < 0 ? -(x) : (x))
|
||||||
|
|
||||||
|
/* Forward */
|
||||||
|
static longobject *long_normalize PROTO((longobject *));
|
||||||
|
static longobject *mul1 PROTO((longobject *, wdigit));
|
||||||
|
static longobject *muladd1 PROTO((longobject *, wdigit, wdigit));
|
||||||
|
static longobject *divrem1 PROTO((longobject *, wdigit, digit *));
|
||||||
|
|
||||||
static int ticker; /* XXX Could be shared with ceval? */
|
static int ticker; /* XXX Could be shared with ceval? */
|
||||||
|
|
||||||
#define INTRCHECK(block) \
|
#define INTRCHECK(block) \
|
||||||
|
@ -187,7 +196,7 @@ dgetlongvalue(vv)
|
||||||
|
|
||||||
/* Multiply by a single digit, ignoring the sign. */
|
/* Multiply by a single digit, ignoring the sign. */
|
||||||
|
|
||||||
longobject *
|
static longobject *
|
||||||
mul1(a, n)
|
mul1(a, n)
|
||||||
longobject *a;
|
longobject *a;
|
||||||
wdigit n;
|
wdigit n;
|
||||||
|
@ -197,7 +206,7 @@ mul1(a, n)
|
||||||
|
|
||||||
/* Multiply by a single digit and add a single digit, ignoring the sign. */
|
/* Multiply by a single digit and add a single digit, ignoring the sign. */
|
||||||
|
|
||||||
longobject *
|
static longobject *
|
||||||
muladd1(a, n, extra)
|
muladd1(a, n, extra)
|
||||||
longobject *a;
|
longobject *a;
|
||||||
wdigit n;
|
wdigit n;
|
||||||
|
@ -223,7 +232,7 @@ muladd1(a, n, extra)
|
||||||
(as function result) and the remainder (through *prem).
|
(as function result) and the remainder (through *prem).
|
||||||
The sign of a is ignored; n should not be zero. */
|
The sign of a is ignored; n should not be zero. */
|
||||||
|
|
||||||
longobject *
|
static longobject *
|
||||||
divrem1(a, n, prem)
|
divrem1(a, n, prem)
|
||||||
longobject *a;
|
longobject *a;
|
||||||
wdigit n;
|
wdigit n;
|
||||||
|
@ -252,11 +261,12 @@ divrem1(a, n, prem)
|
||||||
If base is 8 or 16, add the proper prefix '0' or '0x'.
|
If base is 8 or 16, add the proper prefix '0' or '0x'.
|
||||||
External linkage: used in bltinmodule.c by hex() and oct(). */
|
External linkage: used in bltinmodule.c by hex() and oct(). */
|
||||||
|
|
||||||
stringobject *
|
object *
|
||||||
long_format(a, base)
|
long_format(aa, base)
|
||||||
longobject *a;
|
object *aa;
|
||||||
int base;
|
int base;
|
||||||
{
|
{
|
||||||
|
register longobject *a = (longobject *)aa;
|
||||||
stringobject *str;
|
stringobject *str;
|
||||||
int i;
|
int i;
|
||||||
int size_a = ABS(a->ob_size);
|
int size_a = ABS(a->ob_size);
|
||||||
|
@ -264,6 +274,10 @@ long_format(a, base)
|
||||||
int bits;
|
int bits;
|
||||||
char sign = '\0';
|
char sign = '\0';
|
||||||
|
|
||||||
|
if (a == NULL || !is_longobject(a)) {
|
||||||
|
err_badcall();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
assert(base >= 2 && base <= 36);
|
assert(base >= 2 && base <= 36);
|
||||||
|
|
||||||
/* Compute a rough upper bound for the length of the string */
|
/* Compute a rough upper bound for the length of the string */
|
||||||
|
@ -330,7 +344,7 @@ long_format(a, base)
|
||||||
q--;
|
q--;
|
||||||
resizestring((object **)&str, (int) (q - GETSTRINGVALUE(str)));
|
resizestring((object **)&str, (int) (q - GETSTRINGVALUE(str)));
|
||||||
}
|
}
|
||||||
return str;
|
return (object *)str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert a string to a long int object, in a given base.
|
/* Convert a string to a long int object, in a given base.
|
||||||
|
@ -386,58 +400,55 @@ long_scan(str, base)
|
||||||
|
|
||||||
static longobject *x_divrem PROTO((longobject *, longobject *, longobject **));
|
static longobject *x_divrem PROTO((longobject *, longobject *, longobject **));
|
||||||
static object *long_pos PROTO((longobject *));
|
static object *long_pos PROTO((longobject *));
|
||||||
|
static long_divrem PROTO((longobject *, longobject *,
|
||||||
|
longobject **, longobject **));
|
||||||
|
|
||||||
/* Long division with remainder, top-level routine */
|
/* Long division with remainder, top-level routine */
|
||||||
|
|
||||||
static longobject *
|
static int
|
||||||
long_divrem(a, b, prem)
|
long_divrem(a, b, pdiv, prem)
|
||||||
longobject *a, *b;
|
longobject *a, *b;
|
||||||
|
longobject **pdiv;
|
||||||
longobject **prem;
|
longobject **prem;
|
||||||
{
|
{
|
||||||
int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
|
int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
|
||||||
longobject *z;
|
longobject *z;
|
||||||
|
|
||||||
if (size_b == 0) {
|
if (size_b == 0) {
|
||||||
if (prem != NULL)
|
err_setstr(ZeroDivisionError, "long division or modulo");
|
||||||
*prem = NULL;
|
return -1;
|
||||||
err_setstr(ZeroDivisionError, "long division or remainder");
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
if (size_a < size_b ||
|
if (size_a < size_b ||
|
||||||
size_a == size_b &&
|
size_a == size_b &&
|
||||||
a->ob_digit[size_a-1] < b->ob_digit[size_b-1]) {
|
a->ob_digit[size_a-1] < b->ob_digit[size_b-1]) {
|
||||||
/* |a| < |b|. */
|
/* |a| < |b|. */
|
||||||
if (prem != NULL) {
|
*pdiv = alloclongobject(0);
|
||||||
INCREF(a);
|
INCREF(a);
|
||||||
*prem = (longobject *) a;
|
*prem = (longobject *) a;
|
||||||
}
|
return 0;
|
||||||
return alloclongobject(0);
|
|
||||||
}
|
}
|
||||||
if (size_b == 1) {
|
if (size_b == 1) {
|
||||||
digit rem = 0;
|
digit rem = 0;
|
||||||
z = divrem1(a, b->ob_digit[0], &rem);
|
z = divrem1(a, b->ob_digit[0], &rem);
|
||||||
if (prem != NULL) {
|
|
||||||
if (z == NULL)
|
if (z == NULL)
|
||||||
*prem = NULL;
|
return -1;
|
||||||
else
|
*prem = (longobject *) newlongobject((long)rem);
|
||||||
*prem = (longobject *)
|
|
||||||
newlongobject((long)rem);
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
else
|
|
||||||
z = x_divrem(a, b, prem);
|
z = x_divrem(a, b, prem);
|
||||||
|
if (z == NULL)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
/* Set the signs.
|
/* Set the signs.
|
||||||
The quotient z has the sign of a*b;
|
The quotient z has the sign of a*b;
|
||||||
the remainder r has the sign of a,
|
the remainder r has the sign of a,
|
||||||
so a = b*z + r. */
|
so a = b*z + r. */
|
||||||
if (z != NULL) {
|
|
||||||
if ((a->ob_size < 0) != (b->ob_size < 0))
|
if ((a->ob_size < 0) != (b->ob_size < 0))
|
||||||
z->ob_size = -(z->ob_size);
|
z->ob_size = -(z->ob_size);
|
||||||
if (prem != NULL && *prem != NULL && a->ob_size < 0 &&
|
if (a->ob_size < 0 && (*prem)->ob_size != 0)
|
||||||
(*prem)->ob_size != 0)
|
|
||||||
(*prem)->ob_size = -((*prem)->ob_size);
|
(*prem)->ob_size = -((*prem)->ob_size);
|
||||||
}
|
*pdiv = z;
|
||||||
return z;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unsigned long division with remainder -- the algorithm */
|
/* Unsigned long division with remainder -- the algorithm */
|
||||||
|
@ -457,8 +468,6 @@ x_divrem(v1, w1, prem)
|
||||||
if (v == NULL || w == NULL) {
|
if (v == NULL || w == NULL) {
|
||||||
XDECREF(v);
|
XDECREF(v);
|
||||||
XDECREF(w);
|
XDECREF(w);
|
||||||
if (prem != NULL)
|
|
||||||
*prem = NULL;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,13 +532,8 @@ x_divrem(v1, w1, prem)
|
||||||
}
|
}
|
||||||
} /* for j, k */
|
} /* for j, k */
|
||||||
|
|
||||||
if (a == NULL) {
|
if (a != NULL) {
|
||||||
if (prem != NULL)
|
|
||||||
*prem = NULL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
a = long_normalize(a);
|
a = long_normalize(a);
|
||||||
if (prem != NULL) {
|
|
||||||
*prem = divrem1(v, d, &d);
|
*prem = divrem1(v, d, &d);
|
||||||
/* d receives the (unused) remainder */
|
/* d receives the (unused) remainder */
|
||||||
if (*prem == NULL) {
|
if (*prem == NULL) {
|
||||||
|
@ -537,7 +541,6 @@ x_divrem(v1, w1, prem)
|
||||||
a = NULL;
|
a = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
DECREF(v);
|
DECREF(v);
|
||||||
DECREF(w);
|
DECREF(w);
|
||||||
return a;
|
return a;
|
||||||
|
@ -545,6 +548,30 @@ x_divrem(v1, w1, prem)
|
||||||
|
|
||||||
/* Methods */
|
/* Methods */
|
||||||
|
|
||||||
|
/* Forward */
|
||||||
|
static void long_dealloc PROTO((longobject *));
|
||||||
|
static int long_print PROTO((longobject *, FILE *, int));
|
||||||
|
static object *long_repr PROTO((longobject *));
|
||||||
|
static int long_compare PROTO((longobject *, longobject *));
|
||||||
|
|
||||||
|
static object *long_add PROTO((longobject *, longobject *));
|
||||||
|
static object *long_sub PROTO((longobject *, longobject *));
|
||||||
|
static object *long_mul PROTO((longobject *, longobject *));
|
||||||
|
static object *long_div PROTO((longobject *, longobject *));
|
||||||
|
static object *long_mod PROTO((longobject *, longobject *));
|
||||||
|
static object *long_divmod PROTO((longobject *, longobject *));
|
||||||
|
static object *long_pow PROTO((longobject *, longobject *));
|
||||||
|
static object *long_neg PROTO((longobject *));
|
||||||
|
static object *long_pos PROTO((longobject *));
|
||||||
|
static object *long_abs PROTO((longobject *));
|
||||||
|
static int long_nonzero PROTO((longobject *));
|
||||||
|
static object *long_invert PROTO((longobject *));
|
||||||
|
static object *long_lshift PROTO((longobject *, longobject *));
|
||||||
|
static object *long_rshift PROTO((longobject *, longobject *));
|
||||||
|
static object *long_and PROTO((longobject *, longobject *));
|
||||||
|
static object *long_xor PROTO((longobject *, longobject *));
|
||||||
|
static object *long_or PROTO((longobject *, longobject *));
|
||||||
|
|
||||||
static void
|
static void
|
||||||
long_dealloc(v)
|
long_dealloc(v)
|
||||||
longobject *v;
|
longobject *v;
|
||||||
|
@ -558,7 +585,7 @@ long_print(v, fp, flags)
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int flags;
|
int flags;
|
||||||
{
|
{
|
||||||
stringobject *str = long_format(v, 10);
|
stringobject *str = (stringobject *) long_format((object *)v, 10);
|
||||||
if (str == NULL)
|
if (str == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
fprintf(fp, "%s", GETSTRINGVALUE(str));
|
fprintf(fp, "%s", GETSTRINGVALUE(str));
|
||||||
|
@ -570,7 +597,7 @@ static object *
|
||||||
long_repr(v)
|
long_repr(v)
|
||||||
longobject *v;
|
longobject *v;
|
||||||
{
|
{
|
||||||
return (object *) long_format(v, 10);
|
return long_format((object *)v, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -782,34 +809,9 @@ long_mul(a, b)
|
||||||
return (object *) long_normalize(z);
|
return (object *) long_normalize(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
static object *
|
/* The / and % operators are now defined in terms of divmod().
|
||||||
long_div(v, w)
|
The expression a mod b has the value a - b*floor(a/b).
|
||||||
longobject *v;
|
The long_divrem function gives the remainder after division of
|
||||||
longobject *w;
|
|
||||||
{
|
|
||||||
return (object *) long_divrem(v, w, (longobject **)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static object *
|
|
||||||
long_rem(v, w)
|
|
||||||
longobject *v;
|
|
||||||
longobject *w;
|
|
||||||
{
|
|
||||||
longobject *div, *rem = NULL;
|
|
||||||
|
|
||||||
div = long_divrem(v, w, &rem);
|
|
||||||
if (div == NULL) {
|
|
||||||
XDECREF(rem);
|
|
||||||
rem = NULL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DECREF(div);
|
|
||||||
}
|
|
||||||
return (object *) rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The expression a mod b has the value a - b*floor(a/b).
|
|
||||||
The divrem function gives the remainder after division of
|
|
||||||
|a| by |b|, with the sign of a. This is also expressed
|
|a| by |b|, with the sign of a. This is also expressed
|
||||||
as a - b*trunc(a/b), if trunc truncates towards zero.
|
as a - b*trunc(a/b), if trunc truncates towards zero.
|
||||||
Some examples:
|
Some examples:
|
||||||
|
@ -822,47 +824,86 @@ long_rem(v, w)
|
||||||
have different signs. We then subtract one from the 'div'
|
have different signs. We then subtract one from the 'div'
|
||||||
part of the outcome to keep the invariant intact. */
|
part of the outcome to keep the invariant intact. */
|
||||||
|
|
||||||
|
static int l_divmod PROTO((longobject *, longobject *,
|
||||||
|
longobject **, longobject **));
|
||||||
|
static int
|
||||||
|
l_divmod(v, w, pdiv, pmod)
|
||||||
|
longobject *v;
|
||||||
|
longobject *w;
|
||||||
|
longobject **pdiv;
|
||||||
|
longobject **pmod;
|
||||||
|
{
|
||||||
|
longobject *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) {
|
||||||
|
longobject *temp;
|
||||||
|
longobject *one;
|
||||||
|
temp = (longobject *) long_add(mod, w);
|
||||||
|
DECREF(mod);
|
||||||
|
mod = temp;
|
||||||
|
if (mod == NULL) {
|
||||||
|
DECREF(div);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
one = (longobject *) newlongobject(1L);
|
||||||
|
if (one == NULL ||
|
||||||
|
(temp = (longobject *) long_sub(div, one)) == NULL) {
|
||||||
|
DECREF(mod);
|
||||||
|
DECREF(div);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
DECREF(div);
|
||||||
|
div = temp;
|
||||||
|
}
|
||||||
|
*pdiv = div;
|
||||||
|
*pmod = mod;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static object *
|
||||||
|
long_div(v, w)
|
||||||
|
longobject *v;
|
||||||
|
longobject *w;
|
||||||
|
{
|
||||||
|
longobject *div, *mod;
|
||||||
|
if (l_divmod(v, w, &div, &mod) < 0)
|
||||||
|
return NULL;
|
||||||
|
DECREF(mod);
|
||||||
|
return (object *)div;
|
||||||
|
}
|
||||||
|
|
||||||
|
static object *
|
||||||
|
long_mod(v, w)
|
||||||
|
longobject *v;
|
||||||
|
longobject *w;
|
||||||
|
{
|
||||||
|
longobject *div, *mod;
|
||||||
|
if (l_divmod(v, w, &div, &mod) < 0)
|
||||||
|
return NULL;
|
||||||
|
DECREF(div);
|
||||||
|
return (object *)mod;
|
||||||
|
}
|
||||||
|
|
||||||
static object *
|
static object *
|
||||||
long_divmod(v, w)
|
long_divmod(v, w)
|
||||||
longobject *v;
|
longobject *v;
|
||||||
longobject *w;
|
longobject *w;
|
||||||
{
|
{
|
||||||
object *z;
|
object *z;
|
||||||
longobject *div, *rem;
|
longobject *div, *mod;
|
||||||
div = long_divrem(v, w, &rem);
|
if (l_divmod(v, w, &div, &mod) < 0)
|
||||||
if (div == NULL) {
|
|
||||||
XDECREF(rem);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
if (rem->ob_size < 0 && w->ob_size > 0 ||
|
|
||||||
rem->ob_size > 0 && w->ob_size < 0) {
|
|
||||||
longobject *temp;
|
|
||||||
longobject *one;
|
|
||||||
temp = (longobject *) long_add(rem, (object *)w);
|
|
||||||
DECREF(rem);
|
|
||||||
rem = temp;
|
|
||||||
if (rem == NULL) {
|
|
||||||
DECREF(div);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
one = (longobject *) newlongobject(1L);
|
|
||||||
if (one == NULL ||
|
|
||||||
(temp = (longobject *) long_sub(div, one)) == NULL) {
|
|
||||||
DECREF(rem);
|
|
||||||
DECREF(div);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
DECREF(div);
|
|
||||||
div = temp;
|
|
||||||
}
|
|
||||||
z = newtupleobject(2);
|
z = newtupleobject(2);
|
||||||
if (z != NULL) {
|
if (z != NULL) {
|
||||||
settupleitem(z, 0, (object *) div);
|
settupleitem(z, 0, (object *) div);
|
||||||
settupleitem(z, 1, (object *) rem);
|
settupleitem(z, 1, (object *) mod);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DECREF(div);
|
DECREF(div);
|
||||||
DECREF(rem);
|
DECREF(mod);
|
||||||
}
|
}
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
@ -892,7 +933,7 @@ long_pow(a, b)
|
||||||
longobject *temp;
|
longobject *temp;
|
||||||
|
|
||||||
if (bi & 1) {
|
if (bi & 1) {
|
||||||
temp = (longobject *)long_mul(z, (object *)a);
|
temp = (longobject *)long_mul(z, a);
|
||||||
DECREF(z);
|
DECREF(z);
|
||||||
z = temp;
|
z = temp;
|
||||||
if (z == NULL)
|
if (z == NULL)
|
||||||
|
@ -901,7 +942,7 @@ long_pow(a, b)
|
||||||
bi >>= 1;
|
bi >>= 1;
|
||||||
if (bi == 0 && i+1 == size_b)
|
if (bi == 0 && i+1 == size_b)
|
||||||
break;
|
break;
|
||||||
temp = (longobject *)long_mul(a, (object *)a);
|
temp = (longobject *)long_mul(a, a);
|
||||||
DECREF(a);
|
DECREF(a);
|
||||||
a = temp;
|
a = temp;
|
||||||
if (a == NULL) {
|
if (a == NULL) {
|
||||||
|
@ -923,8 +964,8 @@ long_invert(v)
|
||||||
{
|
{
|
||||||
/* Implement ~x as -(x+1) */
|
/* Implement ~x as -(x+1) */
|
||||||
longobject *x;
|
longobject *x;
|
||||||
object *w;
|
longobject *w;
|
||||||
w = newlongobject(1L);
|
w = (longobject *)newlongobject(1L);
|
||||||
if (w == NULL)
|
if (w == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
x = (longobject *) long_add(v, w);
|
x = (longobject *) long_add(v, w);
|
||||||
|
@ -1098,7 +1139,9 @@ long_lshift(a, b)
|
||||||
#define MAX(x, y) ((x) < (y) ? (y) : (x))
|
#define MAX(x, y) ((x) < (y) ? (y) : (x))
|
||||||
#define MIN(x, y) ((x) > (y) ? (y) : (x))
|
#define MIN(x, y) ((x) > (y) ? (y) : (x))
|
||||||
|
|
||||||
static object *long_bitwise(a, op, b)
|
static object *long_bitwise PROTO((longobject *, int, longobject *));
|
||||||
|
static object *
|
||||||
|
long_bitwise(a, op, b)
|
||||||
longobject *a;
|
longobject *a;
|
||||||
int op; /* '&', '|', '^' */
|
int op; /* '&', '|', '^' */
|
||||||
longobject *b;
|
longobject *b;
|
||||||
|
@ -1214,7 +1257,7 @@ static number_methods long_as_number = {
|
||||||
long_sub, /*nb_subtract*/
|
long_sub, /*nb_subtract*/
|
||||||
long_mul, /*nb_multiply*/
|
long_mul, /*nb_multiply*/
|
||||||
long_div, /*nb_divide*/
|
long_div, /*nb_divide*/
|
||||||
long_rem, /*nb_remainder*/
|
long_mod, /*nb_remainder*/
|
||||||
long_divmod, /*nb_divmod*/
|
long_divmod, /*nb_divmod*/
|
||||||
long_pow, /*nb_power*/
|
long_pow, /*nb_power*/
|
||||||
long_neg, /*nb_negative*/
|
long_neg, /*nb_negative*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue