From: Stefan Krah Date: Sun, 17 Jul 2016 12:12:59 +0000 (+0200) Subject: Merge 3.5. X-Git-Tag: v3.6.0a4~157 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=243d8a7866a3ea0e0dde9e80c5258d7171dfdebe;p=python Merge 3.5. --- 243d8a7866a3ea0e0dde9e80c5258d7171dfdebe diff --cc Modules/_decimal/_decimal.c index dd33f973e4,e15941aec8..3ba8e35ce9 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@@ -3385,106 -3394,6 +3393,105 @@@ dec_as_long(PyObject *dec, PyObject *co return (PyObject *) pylong; } +/* Convert a Decimal to its exact integer ratio representation. */ +static PyObject * +dec_as_integer_ratio(PyObject *self, PyObject *args UNUSED) +{ + PyObject *numerator = NULL; + PyObject *denominator = NULL; + PyObject *exponent = NULL; + PyObject *result = NULL; + PyObject *tmp; + mpd_ssize_t exp; + PyObject *context; + uint32_t status = 0; - PyNumberMethods *long_methods = PyLong_Type.tp_as_number; + + if (mpd_isspecial(MPD(self))) { + if (mpd_isnan(MPD(self))) { + PyErr_SetString(PyExc_ValueError, + "cannot convert NaN to integer ratio"); + } + else { + PyErr_SetString(PyExc_OverflowError, + "cannot convert Infinity to integer ratio"); + } + return NULL; + } + + CURRENT_CONTEXT(context); + + tmp = dec_alloc(); + if (tmp == NULL) { + return NULL; + } + + if (!mpd_qcopy(MPD(tmp), MPD(self), &status)) { + Py_DECREF(tmp); + PyErr_NoMemory(); + return NULL; + } + + exp = mpd_iszero(MPD(tmp)) ? 0 : MPD(tmp)->exp; + MPD(tmp)->exp = 0; + + /* context and rounding are unused here: the conversion is exact */ + numerator = dec_as_long(tmp, context, MPD_ROUND_FLOOR); + Py_DECREF(tmp); + if (numerator == NULL) { + goto error; + } + + exponent = PyLong_FromSsize_t(exp < 0 ? -exp : exp); + if (exponent == NULL) { + goto error; + } + + tmp = PyLong_FromLong(10); + if (tmp == NULL) { + goto error; + } + - Py_SETREF(exponent, long_methods->nb_power(tmp, exponent, Py_None)); ++ Py_SETREF(exponent, _py_long_power(tmp, exponent, Py_None)); + Py_DECREF(tmp); + if (exponent == NULL) { + goto error; + } + + if (exp >= 0) { - Py_SETREF(numerator, long_methods->nb_multiply(numerator, exponent)); ++ Py_SETREF(numerator, _py_long_multiply(numerator, exponent)); + if (numerator == NULL) { + goto error; + } + denominator = PyLong_FromLong(1); + if (denominator == NULL) { + goto error; + } + } + else { + denominator = exponent; + exponent = NULL; + tmp = _PyLong_GCD(numerator, denominator); + if (tmp == NULL) { + goto error; + } - Py_SETREF(numerator, long_methods->nb_floor_divide(numerator, tmp)); - Py_SETREF(denominator, long_methods->nb_floor_divide(denominator, tmp)); ++ Py_SETREF(numerator, _py_long_floor_divide(numerator, tmp)); ++ Py_SETREF(denominator, _py_long_floor_divide(denominator, tmp)); + Py_DECREF(tmp); + if (numerator == NULL || denominator == NULL) { + goto error; + } + } + + result = PyTuple_Pack(2, numerator, denominator); + + +error: + Py_XDECREF(exponent); + Py_XDECREF(denominator); + Py_XDECREF(numerator); + return result; +} + static PyObject * PyDec_ToIntegralValue(PyObject *dec, PyObject *args, PyObject *kwds) {