summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorJeffrey Yasskin <jyasskin@gmail.com>2008-01-05 08:47:13 (GMT)
committerJeffrey Yasskin <jyasskin@gmail.com>2008-01-05 08:47:13 (GMT)
commit9871d8fe22566acf68bf336d04d3a1dbd51f3269 (patch)
tree89540b4ff5f893e36c916534be2f07b5a7166fc1 /Python
parentf7476c4d463b5770b98d980bcd9bff3db981445d (diff)
downloadcpython-9871d8fe22566acf68bf336d04d3a1dbd51f3269.zip
cpython-9871d8fe22566acf68bf336d04d3a1dbd51f3269.tar.gz
cpython-9871d8fe22566acf68bf336d04d3a1dbd51f3269.tar.bz2
Continue rolling back pep-3141 changes that changed behavior from 2.5. This
round included: * Revert round to its 2.6 behavior (half away from 0). * Because round, floor, and ceil always return float again, it's no longer necessary to have them delegate to __xxx___, so I've ripped that out of their implementations and the Real ABC. This also helps in implementing types that work in both 2.6 and 3.0: you return int from the __xxx__ methods, and let it get enabled by the version upgrade. * Make pow(-1, .5) raise a ValueError again.
Diffstat (limited to 'Python')
-rw-r--r--Python/bltinmodule.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index a7d77de..84a0008 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1926,31 +1926,39 @@ For most object types, eval(repr(object)) == object.");
static PyObject *
builtin_round(PyObject *self, PyObject *args, PyObject *kwds)
{
-#define UNDEF_NDIGITS (-0x7fffffff) /* Unlikely ndigits value */
- int ndigits = UNDEF_NDIGITS;
+ double number;
+ double f;
+ int ndigits = 0;
+ int i;
static char *kwlist[] = {"number", "ndigits", 0};
- PyObject *number;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:round",
- kwlist, &number, &ndigits))
- return NULL;
-
- // The py3k branch gets better errors for this by using
- // _PyType_Lookup(), but since float's mro isn't set in py2.6,
- // we just use PyObject_CallMethod here.
- if (ndigits == UNDEF_NDIGITS)
- return PyObject_CallMethod(number, "__round__", "");
- else
- return PyObject_CallMethod(number, "__round__", "i", ndigits);
-#undef UNDEF_NDIGITS
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "d|i:round",
+ kwlist, &number, &ndigits))
+ return NULL;
+ f = 1.0;
+ i = abs(ndigits);
+ while (--i >= 0)
+ f = f*10.0;
+ if (ndigits < 0)
+ number /= f;
+ else
+ number *= f;
+ if (number >= 0.0)
+ number = floor(number + 0.5);
+ else
+ number = ceil(number - 0.5);
+ if (ndigits < 0)
+ number *= f;
+ else
+ number /= f;
+ return PyFloat_FromDouble(number);
}
PyDoc_STRVAR(round_doc,
"round(number[, ndigits]) -> floating point number\n\
\n\
Round a number to a given precision in decimal digits (default 0 digits).\n\
-This returns an int when called with one argument, otherwise a float.\n\
-Precision may be negative.");
+This always returns a floating point number. Precision may be negative.");
static PyObject *
builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds)