diff options
author | Stefan Krah <skrah@bytereef.org> | 2012-06-20 21:34:58 (GMT) |
---|---|---|
committer | Stefan Krah <skrah@bytereef.org> | 2012-06-20 21:34:58 (GMT) |
commit | 22385011ed32d528d2d736e60f28d890f17ee122 (patch) | |
tree | e7a336da10f2b481ec5ab3baf5d7054da1ef802c /Modules/_decimal/libmpdec | |
parent | 42c9b04278205ce0a7d3a91a552d60d7d1eb6d86 (diff) | |
download | cpython-22385011ed32d528d2d736e60f28d890f17ee122.zip cpython-22385011ed32d528d2d736e60f28d890f17ee122.tar.gz cpython-22385011ed32d528d2d736e60f28d890f17ee122.tar.bz2 |
Many cleanups of redundant code in mpd_qrem_near():
1) _mpd_qdivmod() uses the context precision only in two places, and
the new code should be exactly equivalent to the previous code.
2) Remove misleading comment.
3) The quotient *is* an integer with exponent 0, so calling mpd_qtrunc()
is pointless.
4) Replace two instances of identical code by a single one.
5) Use _mpd_cmp_abs() instead of mpd_cmp_total_mag(): the operands
are not special.
6) Don't clear MPD_Rounded in the status (with the current code it should
not be set within the function).
Diffstat (limited to 'Modules/_decimal/libmpdec')
-rw-r--r-- | Modules/_decimal/libmpdec/mpdecimal.c | 38 |
1 files changed, 15 insertions, 23 deletions
diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c index 38756e0..09a51fc 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.c +++ b/Modules/_decimal/libmpdec/mpdecimal.c @@ -6679,7 +6679,7 @@ mpd_qrem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t workctx; MPD_NEW_STATIC(btmp,0,0,0,0); MPD_NEW_STATIC(q,0,0,0,0); - mpd_ssize_t expdiff, floordigits; + mpd_ssize_t expdiff, qdigits; int cmp, isodd, allnine; if (mpd_isspecial(a) || mpd_isspecial(b)) { @@ -6716,53 +6716,45 @@ mpd_qrem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, b = &btmp; } - workctx = *ctx; - workctx.prec = a->digits; - workctx.prec = (workctx.prec > ctx->prec) ? workctx.prec : ctx->prec; - - _mpd_qdivmod(&q, r, a, b, &workctx, status); - if (mpd_isnan(&q) || mpd_isnan(r) || q.digits > ctx->prec) { - mpd_seterror(r, MPD_Division_impossible, status); + _mpd_qdivmod(&q, r, a, b, ctx, status); + if (mpd_isnan(&q) || mpd_isnan(r)) { goto finish; } if (mpd_iszerocoeff(r)) { goto finish; } - /* Deal with cases like rmnx078: - * remaindernear 999999999.5 1 -> NaN Division_impossible */ expdiff = mpd_adjexp(b) - mpd_adjexp(r); if (-1 <= expdiff && expdiff <= 1) { - mpd_qtrunc(&q, &q, &workctx, &workctx.status); allnine = mpd_coeff_isallnine(&q); - floordigits = q.digits; + qdigits = q.digits; isodd = mpd_isodd(&q); mpd_maxcontext(&workctx); if (mpd_sign(a) == mpd_sign(b)) { + /* sign(r) == sign(b) */ _mpd_qsub(&q, r, b, &workctx, &workctx.status); - if (workctx.status&MPD_Errors) { - mpd_seterror(r, workctx.status&MPD_Errors, status); - goto finish; - } } else { + /* sign(r) != sign(b) */ _mpd_qadd(&q, r, b, &workctx, &workctx.status); - if (workctx.status&MPD_Errors) { - mpd_seterror(r, workctx.status&MPD_Errors, status); - goto finish; - } } - cmp = mpd_cmp_total_mag(&q, r); + if (workctx.status&MPD_Errors) { + mpd_seterror(r, workctx.status&MPD_Errors, status); + goto finish; + } + + cmp = _mpd_cmp_abs(&q, r); if (cmp < 0 || (cmp == 0 && isodd)) { - if (allnine && floordigits == ctx->prec) { + /* abs(r) > abs(b)/2 or abs(r) == abs(b)/2 and isodd(quotient) */ + if (allnine && qdigits == ctx->prec) { + /* abs(quotient) + 1 == 10**prec */ mpd_seterror(r, MPD_Division_impossible, status); goto finish; } mpd_qcopy(r, &q, status); - *status &= ~MPD_Rounded; } } |