diff options
author | Jeffrey Yasskin <jyasskin@gmail.com> | 2008-01-05 08:47:13 (GMT) |
---|---|---|
committer | Jeffrey Yasskin <jyasskin@gmail.com> | 2008-01-05 08:47:13 (GMT) |
commit | 9871d8fe22566acf68bf336d04d3a1dbd51f3269 (patch) | |
tree | 89540b4ff5f893e36c916534be2f07b5a7166fc1 /Python | |
parent | f7476c4d463b5770b98d980bcd9bff3db981445d (diff) | |
download | cpython-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.c | 42 |
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) |