]> granicus.if.org Git - python/commitdiff
mpd_qpowmod(): calculate result with zero-exponent for compatibility with
authorStefan Krah <skrah@bytereef.org>
Thu, 23 Aug 2012 13:05:29 +0000 (15:05 +0200)
committerStefan Krah <skrah@bytereef.org>
Thu, 23 Aug 2012 13:05:29 +0000 (15:05 +0200)
decimal.py. The hack to remove the ideal exponent is no longer required.

Modules/_decimal/_decimal.c
Modules/_decimal/libmpdec/mpdecimal.c

index 6217a3f556334a20cab070ef8c1138ae225bef39..ecca411fc4b71a5f463ace7ed2b9c1cc20dd9d5c 100644 (file)
@@ -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);
index 9bdb03de55759e2f47a49c9e0ab498cec1f293f1..0558d5e6cc0694e5f1a52f0db80c7b01cfd11d85 100644 (file)
@@ -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: