Mercurial > cpython-lru_cache-weakref
diff Python/bltinmodule.c @ 44488:94eeaeeb3ce9 legacy-trunk
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.
| author | Jeffrey Yasskin <jyasskin@gmail.com> |
|---|---|
| date | Sat, 05 Jan 2008 08:47:13 +0000 |
| parents | 4f9723d9ca32 |
| children | 9caf8a7b11a6 |
line wrap: on
line diff
--- a/Python/bltinmodule.c Sat Jan 05 04:38:38 2008 +0000 +++ b/Python/bltinmodule.c Sat Jan 05 08:47:13 2008 +0000 @@ -1926,31 +1926,39 @@ 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)
