Commit a85d67b7 authored by Guido van Rossum's avatar Guido van Rossum

Added long() and support for longs in int() and float();

turned abs() and divmod() into generic versions;
added pow().
parent 3ac31d95
...@@ -42,24 +42,12 @@ builtin_abs(self, v) ...@@ -42,24 +42,12 @@ builtin_abs(self, v)
object *self; object *self;
object *v; object *v;
{ {
/* XXX This should be a method in the as_number struct in the type */ number_methods *nm;
if (v == NULL) { if (v == NULL || (nm = v->ob_type->tp_as_number) == NULL) {
/* */ err_setstr(TypeError, "abs() requires numeric argument");
} return NULL;
else if (is_intobject(v)) {
long x = getintvalue(v);
if (x < 0)
x = -x;
return newintobject(x);
}
else if (is_floatobject(v)) {
double x = getfloatvalue(v);
if (x < 0)
x = -x;
return newfloatobject(x);
} }
err_setstr(TypeError, "abs() argument must be float or int"); return (*nm->nb_absolute)(v);
return NULL;
} }
static object * static object *
...@@ -112,47 +100,18 @@ builtin_divmod(self, v) ...@@ -112,47 +100,18 @@ builtin_divmod(self, v)
object *self; object *self;
object *v; object *v;
{ {
object *x, *y; object *x;
long xi, yi, xdivy, xmody; number_methods *nm;
if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) { if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
err_setstr(TypeError, "divmod() requires 2 int arguments"); err_setstr(TypeError, "divmod() requires 2 arguments");
return NULL; return NULL;
} }
x = gettupleitem(v, 0); x = gettupleitem(v, 0);
y = gettupleitem(v, 1); if ((nm = x->ob_type->tp_as_number) == NULL) {
if (!is_intobject(x) || !is_intobject(y)) { err_setstr(TypeError, "divmod() requires numeric arguments");
err_setstr(TypeError, "divmod() requires 2 int arguments");
return NULL;
}
xi = getintvalue(x);
yi = getintvalue(y);
if (yi == 0) {
err_setstr(TypeError, "divmod() division by zero");
return NULL;
}
if (yi < 0) {
xdivy = -xi / -yi;
}
else {
xdivy = xi / yi;
}
xmody = xi - xdivy*yi;
if (xmody < 0 && yi > 0 || xmody > 0 && yi < 0) {
xmody += yi;
xdivy -= 1;
}
v = newtupleobject(2);
x = newintobject(xdivy);
y = newintobject(xmody);
if (v == NULL || x == NULL || y == NULL ||
settupleitem(v, 0, x) != 0 ||
settupleitem(v, 1, y) != 0) {
XDECREF(v);
XDECREF(x);
XDECREF(y);
return NULL; return NULL;
} }
return v; return (*nm->nb_divmod)(x, gettupleitem(v, 1));
} }
static object * static object *
...@@ -207,15 +166,19 @@ builtin_float(self, v) ...@@ -207,15 +166,19 @@ builtin_float(self, v)
if (v == NULL) { if (v == NULL) {
/* */ /* */
} }
else if (is_floatobject(v)) {
INCREF(v);
return v;
}
else if (is_intobject(v)) { else if (is_intobject(v)) {
long x = getintvalue(v); long x = getintvalue(v);
return newfloatobject((double)x); return newfloatobject((double)x);
} }
err_setstr(TypeError, "float() argument must be float or int"); else if (is_longobject(v)) {
extern double dgetlongvalue();
return newfloatobject(dgetlongvalue(v));
}
else if (is_floatobject(v)) {
INCREF(v);
return v;
}
err_setstr(TypeError, "float() argument must be int, long or float");
return NULL; return NULL;
} }
...@@ -249,11 +212,18 @@ builtin_int(self, v) ...@@ -249,11 +212,18 @@ builtin_int(self, v)
INCREF(v); INCREF(v);
return v; return v;
} }
else if (is_longobject(v)) {
long x;
x = getlongvalue(v);
if (x == -1 && err_occurred())
return NULL;
return newintobject(x);
}
else if (is_floatobject(v)) { else if (is_floatobject(v)) {
double x = getfloatvalue(v); double x = getfloatvalue(v);
return newintobject((long)x); return newintobject((long)x);
} }
err_setstr(TypeError, "int() argument must be float or int"); err_setstr(TypeError, "int() argument must be int, long or float");
return NULL; return NULL;
} }
...@@ -282,6 +252,29 @@ builtin_len(self, v) ...@@ -282,6 +252,29 @@ builtin_len(self, v)
return newintobject(len); return newintobject(len);
} }
static object *
builtin_long(self, v)
object *self;
object *v;
{
if (v == NULL) {
/* */
}
else if (is_intobject(v)) {
return newlongobject(getintvalue(v));
}
else if (is_longobject(v)) {
INCREF(v);
return v;
}
else if (is_floatobject(v)) {
double x = getfloatvalue(v);
return newlongobject((long)x);
}
err_setstr(TypeError, "long() argument must be int, long or float");
return NULL;
}
static object * static object *
min_max(v, sign) min_max(v, sign)
object *v; object *v;
...@@ -366,6 +359,25 @@ builtin_ord(self, v) ...@@ -366,6 +359,25 @@ builtin_ord(self, v)
return newintobject((long)(getstringvalue(v)[0] & 0xff)); return newintobject((long)(getstringvalue(v)[0] & 0xff));
} }
static object *
builtin_pow(self, v)
object *self;
object *v;
{
object *x;
number_methods *nm;
if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
err_setstr(TypeError, "pow() requires 2 arguments");
return NULL;
}
x = gettupleitem(v, 0);
if ((nm = x->ob_type->tp_as_number) == NULL) {
err_setstr(TypeError, "pow() requires numeric arguments");
return NULL;
}
return (*nm->nb_power)(x, gettupleitem(v, 1));
}
static object * static object *
builtin_range(self, v) builtin_range(self, v)
object *self; object *self;
...@@ -476,10 +488,12 @@ static struct methodlist builtin_methods[] = { ...@@ -476,10 +488,12 @@ static struct methodlist builtin_methods[] = {
{"input", builtin_input}, {"input", builtin_input},
{"int", builtin_int}, {"int", builtin_int},
{"len", builtin_len}, {"len", builtin_len},
{"long", builtin_long},
{"max", builtin_max}, {"max", builtin_max},
{"min", builtin_min}, {"min", builtin_min},
{"open", builtin_open}, /* XXX move to OS module */ {"open", builtin_open}, /* XXX move to OS module */
{"ord", builtin_ord}, {"ord", builtin_ord},
{"pow", builtin_pow},
{"range", builtin_range}, {"range", builtin_range},
{"raw_input", builtin_raw_input}, {"raw_input", builtin_raw_input},
{"reload", builtin_reload}, {"reload", builtin_reload},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment