diff options
author | Stefan Krah <skrah@bytereef.org> | 2012-08-23 13:05:29 (GMT) |
---|---|---|
committer | Stefan Krah <skrah@bytereef.org> | 2012-08-23 13:05:29 (GMT) |
commit | f21587e3a805f8ced02dc65c54195bb26740a0ad (patch) | |
tree | 1921553c449263990c4ddd285d5f13c74203af15 | |
parent | bbd3437c27873dfe8b056a1a6ea698cf03d60853 (diff) | |
download | cpython-f21587e3a805f8ced02dc65c54195bb26740a0ad.zip cpython-f21587e3a805f8ced02dc65c54195bb26740a0ad.tar.gz cpython-f21587e3a805f8ced02dc65c54195bb26740a0ad.tar.bz2 |
mpd_qpowmod(): calculate result with zero-exponent for compatibility with
decimal.py. The hack to remove the ideal exponent is no longer required.
-rw-r--r-- | Modules/_decimal/_decimal.c | 8 | ||||
-rw-r--r-- | Modules/_decimal/libmpdec/mpdecimal.c | 32 |
2 files changed, 17 insertions, 23 deletions
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 6217a3f..ecca411 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -3872,10 +3872,6 @@ nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod) else { mpd_qpowmod(MPD(result), MPD(a), MPD(b), MPD(c), CTX(context), &status); - status = (status == MPD_Clamped) ? 0 : status; - /* remove ideal exponent for compatibility with decimal.py */ - mpd_qquantize(MPD(result), MPD(result), &zero, - CTX(context), &status); Py_DECREF(c); } Py_DECREF(a); @@ -4905,10 +4901,6 @@ ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds) else { mpd_qpowmod(MPD(result), MPD(a), MPD(b), MPD(c), CTX(context), &status); - status = (status == MPD_Clamped) ? 0 : status; - /* remove ideal exponent for compatibility with decimal.py */ - mpd_qquantize(MPD(result), MPD(result), &zero, - CTX(context), &status); Py_DECREF(c); } Py_DECREF(a); diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c index 9bdb03d..0558d5e 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.c +++ b/Modules/_decimal/libmpdec/mpdecimal.c @@ -6372,7 +6372,7 @@ mpd_qpow(mpd_t *result, const mpd_t *base, const mpd_t *exp, */ static inline void _mpd_qpowmod_uint(mpd_t *result, mpd_t *base, mpd_uint_t exp, - mpd_t *mod, uint32_t *status) + const mpd_t *mod, uint32_t *status) { mpd_context_t maxcontext; @@ -6383,10 +6383,10 @@ _mpd_qpowmod_uint(mpd_t *result, mpd_t *base, mpd_uint_t exp, while (exp > 0) { if (exp & 1) { - mpd_qmul(result, result, base, &maxcontext, status); + _mpd_qmul_exact(result, result, base, &maxcontext, status); mpd_qrem(result, result, mod, &maxcontext, status); } - mpd_qmul(base, base, base, &maxcontext, status); + _mpd_qmul_exact(base, base, base, &maxcontext, status); mpd_qrem(base, base, mod, &maxcontext, status); exp >>= 1; } @@ -6452,27 +6452,30 @@ mpd_qpowmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, return; } - if (!mpd_qcopy(&tmod, mod, status)) { - goto mpd_errors; + mpd_maxcontext(&maxcontext); + + mpd_qrescale(&tmod, mod, 0, &maxcontext, &maxcontext.status); + if (maxcontext.status&MPD_Errors) { + mpd_seterror(result, maxcontext.status&MPD_Errors, status); + goto out; } + maxcontext.status = 0; mpd_set_positive(&tmod); - mpd_maxcontext(&maxcontext); - mpd_qround_to_int(&tbase, base, &maxcontext, status); - mpd_qround_to_int(&texp, exp, &maxcontext, status); - mpd_qround_to_int(&tmod, &tmod, &maxcontext, status); - + mpd_set_positive(&tbase); tbase_exp = tbase.exp; tbase.exp = 0; + + mpd_qround_to_int(&texp, exp, &maxcontext, status); texp_exp = texp.exp; texp.exp = 0; /* base = (base.int % modulo * pow(10, base.exp, modulo)) % modulo */ mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status); - _settriple(result, MPD_POS, 1, tbase_exp); + mpd_qshiftl(result, &one, tbase_exp, status); mpd_qrem(result, result, &tmod, &maxcontext, status); - mpd_qmul(&tbase, &tbase, result, &maxcontext, status); + _mpd_qmul_exact(&tbase, &tbase, result, &maxcontext, status); mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status); if (mpd_isspecial(&tbase) || mpd_isspecial(&texp) || @@ -6494,10 +6497,10 @@ mpd_qpowmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, mpd_qcopy(result, &one, status); while (mpd_isfinite(&texp) && !mpd_iszero(&texp)) { if (mpd_isodd(&texp)) { - mpd_qmul(result, result, &tbase, &maxcontext, status); + _mpd_qmul_exact(result, result, &tbase, &maxcontext, status); mpd_qrem(result, result, &tmod, &maxcontext, status); } - mpd_qmul(&tbase, &tbase, &tbase, &maxcontext, status); + _mpd_qmul_exact(&tbase, &tbase, &tbase, &maxcontext, status); mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status); mpd_qdivint(&texp, &texp, &two, &maxcontext, status); } @@ -6515,7 +6518,6 @@ out: mpd_del(&texp); mpd_del(&tmod); mpd_del(&tmp); - mpd_qfinalize(result, ctx, status); return; mpd_errors: |