/*
 * Copyright (c) 2008-2016 Stefan Krah. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */


#include "mpdecimal.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <math.h>
#include "basearith.h"
#include "bits.h"
#include "convolute.h"
#include "crt.h"
#include "mpalloc.h"
#include "typearith.h"
#include "umodarith.h"

#ifdef PPRO
  #if defined(_MSC_VER)
    #include <float.h>
    #pragma float_control(precise, on)
    #pragma fenv_access(on)
  #elif !defined(__OpenBSD__) && !defined(__NetBSD__)
    /* C99 */
    #include <fenv.h>
    #pragma STDC FENV_ACCESS ON
  #endif
#endif


#if defined(_MSC_VER)
  #define ALWAYS_INLINE __forceinline
#elif defined(LEGACY_COMPILER)
  #define ALWAYS_INLINE
  #undef inline
  #define inline
#else
  #ifdef TEST_COVERAGE
    #define ALWAYS_INLINE
  #else
    #define ALWAYS_INLINE inline __attribute__ ((always_inline))
  #endif
#endif


#define MPD_NEWTONDIV_CUTOFF 1024L

#define MPD_NEW_STATIC(name, flags, exp, digits, len) \
        mpd_uint_t name##_data[MPD_MINALLOC_MAX];                    \
        mpd_t name = {flags|MPD_STATIC|MPD_STATIC_DATA, exp, digits, \
                      len, MPD_MINALLOC_MAX, name##_data}

#define MPD_NEW_CONST(name, flags, exp, digits, len, alloc, initval) \
        mpd_uint_t name##_data[alloc] = {initval};                   \
        mpd_t name = {flags|MPD_STATIC|MPD_CONST_DATA, exp, digits,  \
                      len, alloc, name##_data}

#define MPD_NEW_SHARED(name, a) \
        mpd_t name = {(a->flags&~MPD_DATAFLAGS)|MPD_STATIC|MPD_SHARED_DATA, \
                      a->exp, a->digits, a->len, a->alloc, a->data}


static mpd_uint_t data_one[1] = {1};
static mpd_uint_t data_zero[1] = {0};
static const mpd_t one = {MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1, data_one};
static const mpd_t minus_one = {MPD_NEG|MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1,
                                data_one};
static const mpd_t zero = {MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1, data_zero};

static inline void _mpd_check_exp(mpd_t *dec, const mpd_context_t *ctx,
                                  uint32_t *status);
static void _settriple(mpd_t *result, uint8_t sign, mpd_uint_t a,
                       mpd_ssize_t exp);
static inline mpd_ssize_t _mpd_real_size(mpd_uint_t *data, mpd_ssize_t size);

static int _mpd_cmp_abs(const mpd_t *a, const mpd_t *b);

static void _mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b,
                      const mpd_context_t *ctx, uint32_t *status);
static inline void _mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b,
                             const mpd_context_t *ctx, uint32_t *status);
static void _mpd_base_ndivmod(mpd_t *q, mpd_t *r, const mpd_t *a,
                              const mpd_t *b, uint32_t *status);
static inline void _mpd_qpow_uint(mpd_t *result, const mpd_t *base,
                                  mpd_uint_t exp, uint8_t resultsign,
                                  const mpd_context_t *ctx, uint32_t *status);

static mpd_uint_t mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n);


/******************************************************************************/
/*                                  Version                                   */
/******************************************************************************/

const char *
mpd_version(void)
{
    return MPD_VERSION;
}


/******************************************************************************/
/*                  Performance critical inline functions                     */
/******************************************************************************/

#ifdef CONFIG_64
/* Digits in a word, primarily useful for the most significant word. */
ALWAYS_INLINE int
mpd_word_digits(mpd_uint_t word)
{
    if (word < mpd_pow10[9]) {
        if (word < mpd_pow10[4]) {
            if (word < mpd_pow10[2]) {
                return (word < mpd_pow10[1]) ? 1 : 2;
            }
            return (word < mpd_pow10[3]) ? 3 : 4;
        }
        if (word < mpd_pow10[6]) {
            return (word < mpd_pow10[5]) ? 5 : 6;
        }
        if (word < mpd_pow10[8]) {
            return (word < mpd_pow10[7]) ? 7 : 8;
        }
        return 9;
    }
    if (word < mpd_pow10[14]) {
        if (word < mpd_pow10[11]) {
            return (word < mpd_pow10[10]) ? 10 : 11;
        }
        if (word < mpd_pow10[13]) {
            return (word < mpd_pow10[12]) ? 12 : 13;
        }
        return 14;
    }
    if (word < mpd_pow10[18]) {
        if (word < mpd_pow10[16]) {
            return (word < mpd_pow10[15]) ? 15 : 16;
        }
        return (word < mpd_pow10[17]) ? 17 : 18;
    }

    return (word < mpd_pow10[19]) ? 19 : 20;
}
#else
ALWAYS_INLINE int
mpd_word_digits(mpd_uint_t word)
{
    if (word < mpd_pow10[4]) {
        if (word < mpd_pow10[2]) {
            return (word < mpd_pow10[1]) ? 1 : 2;
        }
        return (word < mpd_pow10[3]) ? 3 : 4;
    }
    if (word < mpd_pow10[6]) {
        return (word < mpd_pow10[5]) ? 5 : 6;
    }
    if (word < mpd_pow10[8]) {
        return (word < mpd_pow10[7]) ? 7 : 8;
    }

    return (word < mpd_pow10[9]) ? 9 : 10;
}
#endif


/* Adjusted exponent */
ALWAYS_INLINE mpd_ssize_t
mpd_adjexp(const mpd_t *dec)
{
    return (dec->exp + dec->digits) - 1;
}

/* Etiny */
ALWAYS_INLINE mpd_ssize_t
mpd_etiny(const mpd_context_t *ctx)
{
    return ctx->emin - (ctx->prec - 1);
}

/* Etop: used for folding down in IEEE clamping */
ALWAYS_INLINE mpd_ssize_t
mpd_etop(const mpd_context_t *ctx)
{
    return ctx->emax - (ctx->prec - 1);
}

/* Most significant word */
ALWAYS_INLINE mpd_uint_t
mpd_msword(const mpd_t *dec)
{
    assert(dec->len > 0);
    return dec->data[dec->len-1];
}

/* Most significant digit of a word */
inline mpd_uint_t
mpd_msd(mpd_uint_t word)
{
    int n;

    n = mpd_word_digits(word);
    return word / mpd_pow10[n-1];
}

/* Least significant digit of a word */
ALWAYS_INLINE mpd_uint_t
mpd_lsd(mpd_uint_t word)
{
    return word % 10;
}

/* Coefficient size needed to store 'digits' */
ALWAYS_INLINE mpd_ssize_t
mpd_digits_to_size(mpd_ssize_t digits)
{
    mpd_ssize_t q, r;

    _mpd_idiv_word(&q, &r, digits, MPD_RDIGITS);
    return (r == 0) ? q : q+1;
}

/* Number of digits in the exponent. Not defined for MPD_SSIZE_MIN. */
inline int
mpd_exp_digits(mpd_ssize_t exp)
{
    exp = (exp < 0) ? -exp : exp;
    return mpd_word_digits(exp);
}

/* Canonical */
ALWAYS_INLINE int
mpd_iscanonical(const mpd_t *dec UNUSED)
{
    return 1;
}

/* Finite */
ALWAYS_INLINE int
mpd_isfinite(const mpd_t *dec)
{
    return !(dec->flags & MPD_SPECIAL);
}

/* Infinite */
ALWAYS_INLINE int
mpd_isinfinite(const mpd_t *dec)
{
    return dec->flags & MPD_INF;
}

/* NaN */
ALWAYS_INLINE int
mpd_isnan(const mpd_t *dec)
{
    return dec->flags & (MPD_NAN|MPD_SNAN);
}

/* Negative */
ALWAYS_INLINE int
mpd_isnegative(const mpd_t *dec)
{
    return dec->flags & MPD_NEG;
}

/* Positive */
ALWAYS_INLINE int
mpd_ispositive(const mpd_t *dec)
{
    return !(dec->flags & MPD_NEG);
}

/* qNaN */
ALWAYS_INLINE int
mpd_isqnan(const mpd_t *dec)
{
    return dec->flags & MPD_NAN;
}

/* Signed */
ALWAYS_INLINE int
mpd_issigned(const mpd_t *dec)
{
    return dec->flags & MPD_NEG;
}

/* sNaN */
ALWAYS_INLINE int
mpd_issnan(const mpd_t *dec)
{
    return dec->flags & MPD_SNAN;
}

/* Special */
ALWAYS_INLINE int
mpd_isspecial(const mpd_t *dec)
{
    return dec->flags & MPD_SPECIAL;
}

/* Zero */
ALWAYS_INLINE int
mpd_iszero(const mpd_t *dec)
{
    return !mpd_isspecial(dec) && mpd_msword(dec) == 0;
}

/* Test for zero when specials have been ruled out already */
ALWAYS_INLINE int
mpd_iszerocoeff(const mpd_t *dec)
{
    return mpd_msword(dec) == 0;
}

/* Normal */
inline int
mpd_isnormal(const mpd_t *dec, const mpd_context_t *ctx)
{
    if (mpd_isspecial(dec)) return 0;
    if (mpd_iszerocoeff(dec)) return 0;

    return mpd_adjexp(dec) >= ctx->emin;
}

/* Subnormal */
inline int
mpd_issubnormal(const mpd_t *dec, const mpd_context_t *ctx)
{
    if (mpd_isspecial(dec)) return 0;
    if (mpd_iszerocoeff(dec)) return 0;

    return mpd_adjexp(dec) < ctx->emin;
}

/* Odd word */
ALWAYS_INLINE int
mpd_isoddword(mpd_uint_t word)
{
    return word & 1;
}

/* Odd coefficient */
ALWAYS_INLINE int
mpd_isoddcoeff(const mpd_t *dec)
{
    return mpd_isoddword(dec->data[0]);
}

/* 0 if dec is positive, 1 if dec is negative */
ALWAYS_INLINE uint8_t
mpd_sign(const mpd_t *dec)
{
    return dec->flags & MPD_NEG;
}

/* 1 if dec is positive, -1 if dec is negative */
ALWAYS_INLINE int
mpd_arith_sign(const mpd_t *dec)
{
    return 1 - 2 * mpd_isnegative(dec);
}

/* Radix */
ALWAYS_INLINE long
mpd_radix(void)
{
    return 10;
}

/* Dynamic decimal */
ALWAYS_INLINE int
mpd_isdynamic(const mpd_t *dec)
{
    return !(dec->flags & MPD_STATIC);
}

/* Static decimal */
ALWAYS_INLINE int
mpd_isstatic(const mpd_t *dec)
{
    return dec->flags & MPD_STATIC;
}

/* Data of decimal is dynamic */
ALWAYS_INLINE int
mpd_isdynamic_data(const mpd_t *dec)
{
    return !(dec->flags & MPD_DATAFLAGS);
}

/* Data of decimal is static */
ALWAYS_INLINE int
mpd_isstatic_data(const mpd_t *dec)
{
    return dec->flags & MPD_STATIC_DATA;
}

/* Data of decimal is shared */
ALWAYS_INLINE int
mpd_isshared_data(const mpd_t *dec)
{
    return dec->flags & MPD_SHARED_DATA;
}

/* Data of decimal is const */
ALWAYS_INLINE int
mpd_isconst_data(const mpd_t *dec)
{
    return dec->flags & MPD_CONST_DATA;
}


/******************************************************************************/
/*                         Inline memory handling                             */
/******************************************************************************/

/* Fill destination with zeros */
ALWAYS_INLINE void
mpd_uint_zero(mpd_uint_t *dest, mpd_size_t len)
{
    mpd_size_t i;

    for (i = 0; i < len; i++) {
        dest[i] = 0;
    }
}

/* Free a decimal */
ALWAYS_INLINE void
mpd_del(mpd_t *dec)
{
    if (mpd_isdynamic_data(dec)) {
        mpd_free(dec->data);
    }
    if (mpd_isdynamic(dec)) {
        mpd_free(dec);
    }
}

/*
 * Resize the coefficient. Existing data up to 'nwords' is left untouched.
 * Return 1 on success, 0 otherwise.
 *
 * Input invariant: MPD_MINALLOC <= result->alloc.
 *
 * Case nwords == result->alloc:
 *     'result' is unchanged. Return 1.
 *
 * Case nwords > result->alloc:
 *   Case realloc success:
 *     The value of 'result' does not change. Return 1.
 *   Case realloc failure:
 *     'result' is NaN, status is updated with MPD_Malloc_error. Return 0.
 *
 * Case nwords < result->alloc:
 *   Case is_static_data or realloc failure [1]:
 *     'result' is unchanged. Return 1.
 *   Case realloc success:
 *     The value of result is undefined (expected). Return 1.
 *
 *
 * [1] In that case the old (now oversized) area is still valid.
 */
ALWAYS_INLINE int
mpd_qresize(mpd_t *result, mpd_ssize_t nwords, uint32_t *status)
{
    assert(!mpd_isconst_data(result)); /* illegal operation for a const */
    assert(!mpd_isshared_data(result)); /* illegal operation for a shared */
    assert(MPD_MINALLOC <= result->alloc);

    nwords = (nwords <= MPD_MINALLOC) ? MPD_MINALLOC : nwords;
    if (nwords == result->alloc) {
        return 1;
    }
    if (mpd_isstatic_data(result)) {
        if (nwords > result->alloc) {
            return mpd_switch_to_dyn(result, nwords, status);
        }
        return 1;
    }

    return mpd_realloc_dyn(result, nwords, status);
}

/* Same as mpd_qresize, but the complete coefficient (including the old
 * memory area!) is initialized to zero. */
ALWAYS_INLINE int
mpd_qresize_zero(mpd_t *result, mpd_ssize_t nwords, uint32_t *status)
{
    assert(!mpd_isconst_data(result)); /* illegal operation for a const */
    assert(!mpd_isshared_data(result)); /* illegal operation for a shared */
    assert(MPD_MINALLOC <= result->alloc);

    nwords = (nwords <= MPD_MINALLOC) ? MPD_MINALLOC : nwords;
    if (nwords != result->alloc) {
        if (mpd_isstatic_data(result)) {
            if (nwords > result->alloc) {
                return mpd_switch_to_dyn_zero(result, nwords, status);
            }
        }
        else if (!mpd_realloc_dyn(result, nwords, status)) {
            return 0;
        }
    }

    mpd_uint_zero(result->data, nwords);
    return 1;
}

/*
 * Reduce memory size for the coefficient to MPD_MINALLOC. In theory,
 * realloc may fail even when reducing the memory size. But in that case
 * the old memory area is always big enough, so checking for MPD_Malloc_error
 * is not imperative.
 */
ALWAYS_INLINE void
mpd_minalloc(mpd_t *result)
{
    assert(!mpd_isconst_data(result)); /* illegal operation for a const */
    assert(!mpd_isshared_data(result)); /* illegal operation for a shared */

    if (!mpd_isstatic_data(result) && result->alloc > MPD_MINALLOC) {
        uint8_t err = 0;
        result->data = mpd_realloc(result->data, MPD_MINALLOC,
                                   sizeof *result->data, &err);
        if (!err) {
            result->alloc = MPD_MINALLOC;
        }
    }
}

int
mpd_resize(mpd_t *result, mpd_ssize_t nwords, mpd_context_t *ctx)
{
    uint32_t status = 0;
    if (!mpd_qresize(result, nwords, &status)) {
        mpd_addstatus_raise(ctx, status);
        return 0;
    }
    return 1;
}

int
mpd_resize_zero(mpd_t *result, mpd_ssize_t nwords, mpd_context_t *ctx)
{
    uint32_t status = 0;
    if (!mpd_qresize_zero(result, nwords, &status)) {
        mpd_addstatus_raise(ctx, status);
        return 0;
    }
    return 1;
}


/******************************************************************************/
/*                       Set attributes of a decimal                          */
/******************************************************************************/

/* Set digits. Assumption: result->len is initialized and > 0. */
inline void
mpd_setdigits(mpd_t *result)
{
    mpd_ssize_t wdigits = mpd_word_digits(mpd_msword(result));
    result->digits = wdigits + (result->len-1) * MPD_RDIGITS;
}

/* Set sign */
ALWAYS_INLINE void
mpd_set_sign(mpd_t *result, uint8_t sign)
{
    result->flags &= ~MPD_NEG;
    result->flags |= sign;
}

/* Copy sign from another decimal */
ALWAYS_INLINE void
mpd_signcpy(mpd_t *result, const mpd_t *a)
{
    uint8_t sign = a->flags&MPD_NEG;

    result->flags &= ~MPD_NEG;
    result->flags |= sign;
}

/* Set infinity */
ALWAYS_INLINE void
mpd_set_infinity(mpd_t *result)
{
    result->flags &= ~MPD_SPECIAL;
    result->flags |= MPD_INF;
}

/* Set qNaN */
ALWAYS_INLINE void
mpd_set_qnan(mpd_t *result)
{
    result->flags &= ~MPD_SPECIAL;
    result->flags |= MPD_NAN;
}

/* Set sNaN */
ALWAYS_INLINE void
mpd_set_snan(mpd_t *result)
{
    result->flags &= ~MPD_SPECIAL;
    result->flags |= MPD_SNAN;
}

/* Set to negative */
ALWAYS_INLINE void
mpd_set_negative(mpd_t *result)
{
    result->flags |= MPD_NEG;
}

/* Set to positive */
ALWAYS_INLINE void
mpd_set_positive(mpd_t *result)
{
    result->flags &= ~MPD_NEG;
}

/* Set to dynamic */
ALWAYS_INLINE void
mpd_set_dynamic(mpd_t *result)
{
    result->flags &= ~MPD_STATIC;
}

/* Set to static */
ALWAYS_INLINE void
mpd_set_static(mpd_t *result)
{
    result->flags |= MPD_STATIC;
}

/* Set data to dynamic */
ALWAYS_INLINE void
mpd_set_dynamic_data(mpd_t *result)
{
    result->flags &= ~MPD_DATAFLAGS;
}

/* Set data to static */
ALWAYS_INLINE void
mpd_set_static_data(mpd_t *result)
{
    result->flags &= ~MPD_DATAFLAGS;
    result->flags |= MPD_STATIC_DATA;
}

/* Set data to shared */
ALWAYS_INLINE void
mpd_set_shared_data(mpd_t *result)
{
    result->flags &= ~MPD_DATAFLAGS;
    result->flags |= MPD_SHARED_DATA;
}

/* Set data to const */
ALWAYS_INLINE void
mpd_set_const_data(mpd_t *result)
{
    result->flags &= ~MPD_DATAFLAGS;
    result->flags |= MPD_CONST_DATA;
}

/* Clear flags, preserving memory attributes. */
ALWAYS_INLINE void
mpd_clear_flags(mpd_t *result)
{
    result->flags &= (MPD_STATIC|MPD_DATAFLAGS);
}

/* Set flags, preserving memory attributes. */
ALWAYS_INLINE void
mpd_set_flags(mpd_t *result, uint8_t flags)
{
    result->flags &= (MPD_STATIC|MPD_DATAFLAGS);
    result->flags |= flags;
}

/* Copy flags, preserving memory attributes of result. */
ALWAYS_INLINE void
mpd_copy_flags(mpd_t *result, const mpd_t *a)
{
    uint8_t aflags = a->flags;
    result->flags &= (MPD_STATIC|MPD_DATAFLAGS);
    result->flags |= (aflags & ~(MPD_STATIC|MPD_DATAFLAGS));
}

/* Initialize a workcontext from ctx. Set traps, flags and newtrap to 0. */
static inline void
mpd_workcontext(mpd_context_t *workctx, const mpd_context_t *ctx)
{
    workctx->prec = ctx->prec;
    workctx->emax = ctx->emax;
    workctx->emin = ctx->emin;
    workctx->round = ctx->round;
    workctx->traps = 0;
    workctx->status = 0;
    workctx->newtrap = 0;
    workctx->clamp = ctx->clamp;
    workctx->allcr = ctx->allcr;
}


/******************************************************************************/
/*                  Getting and setting parts of decimals                     */
/******************************************************************************/

/* Flip the sign of a decimal */
static inline void
_mpd_negate(mpd_t *dec)
{
    dec->flags ^= MPD_NEG;
}

/* Set coefficient to zero */
void
mpd_zerocoeff(mpd_t *result)
{
    mpd_minalloc(result);
    result->digits = 1;
    result->len = 1;
    result->data[0] = 0;
}

/* Set the coefficient to all nines. */
void
mpd_qmaxcoeff(mpd_t *result, const mpd_context_t *ctx, uint32_t *status)
{
    mpd_ssize_t len, r;

    _mpd_idiv_word(&len, &r, ctx->prec, MPD_RDIGITS);
    len = (r == 0) ? len : len+1;

    if (!mpd_qresize(result, len, status)) {
        return;
    }

    result->len = len;
    result->digits = ctx->prec;

    --len;
    if (r > 0) {
        result->data[len--] = mpd_pow10[r]-1;
    }
    for (; len >= 0; --len) {
        result->data[len] = MPD_RADIX-1;
    }
}

/*
 * Cut off the most significant digits so that the rest fits in ctx->prec.
 * Cannot fail.
 */
static void
_mpd_cap(mpd_t *result, const mpd_context_t *ctx)
{
    uint32_t dummy;
    mpd_ssize_t len, r;

    if (result->len > 0 && result->digits > ctx->prec) {
        _mpd_idiv_word(&len, &r, ctx->prec, MPD_RDIGITS);
        len = (r == 0) ? len : len+1;

        if (r != 0) {
            result->data[len-1] %= mpd_pow10[r];
        }

        len = _mpd_real_size(result->data, len);
        /* resize to fewer words cannot fail */
        mpd_qresize(result, len, &dummy);
        result->len = len;
        mpd_setdigits(result);
    }
    if (mpd_iszero(result)) {
        _settriple(result, mpd_sign(result), 0, result->exp);
    }
}

/*
 * Cut off the most significant digits of a NaN payload so that the rest
 * fits in ctx->prec - ctx->clamp. Cannot fail.
 */
static void
_mpd_fix_nan(mpd_t *result, const mpd_context_t *ctx)
{
    uint32_t dummy;
    mpd_ssize_t prec;
    mpd_ssize_t len, r;

    prec = ctx->prec - ctx->clamp;
    if (result->len > 0 && result->digits > prec) {
        if (prec == 0) {
            mpd_minalloc(result);
            result->len = result->digits = 0;
        }
        else {
            _mpd_idiv_word(&len, &r, prec, MPD_RDIGITS);
            len = (r == 0) ? len : len+1;

            if (r != 0) {
                 result->data[len-1] %= mpd_pow10[r];
            }

            len = _mpd_real_size(result->data, len);
            /* resize to fewer words cannot fail */
            mpd_qresize(result, len, &dummy);
            result->len = len;
            mpd_setdigits(result);
            if (mpd_iszerocoeff(result)) {
                /* NaN0 is not a valid representation */
                result->len = result->digits = 0;
            }
        }
    }
}

/*
 * Get n most significant digits from a decimal, where 0 < n <= MPD_UINT_DIGITS.
 * Assumes MPD_UINT_DIGITS == MPD_RDIGITS+1, which is true for 32 and 64 bit
 * machines.
 *
 * The result of the operation will be in lo. If the operation is impossible,
 * hi will be nonzero. This is used to indicate an error.
 */
static inline void
_mpd_get_msdigits(mpd_uint_t *hi, mpd_uint_t *lo, const mpd_t *dec,
                  unsigned int n)
{
    mpd_uint_t r, tmp;

    assert(0 < n && n <= MPD_RDIGITS+1);

    _mpd_div_word(&tmp, &r, dec->digits, MPD_RDIGITS);
    r = (r == 0) ? MPD_RDIGITS : r; /* digits in the most significant word */

    *hi = 0;
    *lo = dec->data[dec->len-1];
    if (n <= r) {
        *lo /= mpd_pow10[r-n];
    }
    else if (dec->len > 1) {
        /* at this point 1 <= r < n <= MPD_RDIGITS+1 */
        _mpd_mul_words(hi, lo, *lo, mpd_pow10[n-r]);
        tmp = dec->data[dec->len-2] / mpd_pow10[MPD_RDIGITS-(n-r)];
        *lo = *lo + tmp;
        if (*lo < tmp) (*hi)++;
    }
}


/******************************************************************************/
/*                   Gathering information about a decimal                    */
/******************************************************************************/

/* The real size of the coefficient without leading zero words. */
static inline mpd_ssize_t
_mpd_real_size(mpd_uint_t *data, mpd_ssize_t size)
{
    while (size > 1 && data[size-1] == 0) {
        size--;
    }

    return size;
}

/* Return number of trailing zeros. No errors are possible. */
mpd_ssize_t
mpd_trail_zeros(const mpd_t *dec)
{
    mpd_uint_t word;
    mpd_ssize_t i, tz = 0;

    for (i=0; i < dec->len; ++i) {
        if (dec->data[i] != 0) {
            word = dec->data[i];
            tz = i * MPD_RDIGITS;
            while (word % 10 == 0) {
                word /= 10;
                tz++;
            }
            break;
        }
    }

    return tz;
}

/* Integer: Undefined for specials */
static int
_mpd_isint(const mpd_t *dec)
{
    mpd_ssize_t tz;

    if (mpd_iszerocoeff(dec)) {
        return 1;
    }

    tz = mpd_trail_zeros(dec);
    return (dec->exp + tz >= 0);
}

/* Integer */
int
mpd_isinteger(const mpd_t *dec)
{
    if (mpd_isspecial(dec)) {
        return 0;
    }
    return _mpd_isint(dec);
}

/* Word is a power of 10 */
static int
mpd_word_ispow10(mpd_uint_t word)
{
    int n;

    n = mpd_word_digits(word);
    if (word == mpd_pow10[n-1]) {
        return 1;
    }

    return 0;
}

/* Coefficient is a power of 10 */
static int
mpd_coeff_ispow10(const mpd_t *dec)
{
    if (mpd_word_ispow10(mpd_msword(dec))) {
        if (_mpd_isallzero(dec->data, dec->len-1)) {
            return 1;
        }
    }

    return 0;
}

/* All digits of a word are nines */
static int
mpd_word_isallnine(mpd_uint_t word)
{
    int n;

    n = mpd_word_digits(word);
    if (word == mpd_pow10[n]-1) {
        return 1;
    }

    return 0;
}

/* All digits of the coefficient are nines */
static int
mpd_coeff_isallnine(const mpd_t *dec)
{
    if (mpd_word_isallnine(mpd_msword(dec))) {
        if (_mpd_isallnine(dec->data, dec->len-1)) {
            return 1;
        }
    }

    return 0;
}

/* Odd decimal: Undefined for non-integers! */
int
mpd_isodd(const mpd_t *dec)
{
    mpd_uint_t q, r;
    assert(mpd_isinteger(dec));
    if (mpd_iszerocoeff(dec)) return 0;
    if (dec->exp < 0) {
        _mpd_div_word(&q, &r, -dec->exp, MPD_RDIGITS);
        q = dec->data[q] / mpd_pow10[r];
        return mpd_isoddword(q);
    }
    return dec->exp == 0 && mpd_isoddword(dec->data[0]);
}

/* Even: Undefined for non-integers! */
int
mpd_iseven(const mpd_t *dec)
{
    return !mpd_isodd(dec);
}

/******************************************************************************/
/*                      Getting and setting decimals                          */
/******************************************************************************/

/* Internal function: Set a static decimal from a triple, no error checking. */
static void
_ssettriple(mpd_t *result, uint8_t sign, mpd_uint_t a, mpd_ssize_t exp)
{
    mpd_set_flags(result, sign);
    result->exp = exp;
    _mpd_div_word(&result->data[1], &result->data[0], a, MPD_RADIX);
    result->len = (result->data[1] == 0) ? 1 : 2;
    mpd_setdigits(result);
}

/* Internal function: Set a decimal from a triple, no error checking. */
static void
_settriple(mpd_t *result, uint8_t sign, mpd_uint_t a, mpd_ssize_t exp)
{
    mpd_minalloc(result);
    mpd_set_flags(result, sign);
    result->exp = exp;
    _mpd_div_word(&result->data[1], &result->data[0], a, MPD_RADIX);
    result->len = (result->data[1] == 0) ? 1 : 2;
    mpd_setdigits(result);
}

/* Set a special number from a triple */
void
mpd_setspecial(mpd_t *result, uint8_t sign, uint8_t type)
{
    mpd_minalloc(result);
    result->flags &= ~(MPD_NEG|MPD_SPECIAL);
    result->flags |= (sign|type);
    result->exp = result->digits = result->len = 0;
}

/* Set result of NaN with an error status */
void
mpd_seterror(mpd_t *result, uint32_t flags, uint32_t *status)
{
    mpd_minalloc(result);
    mpd_set_qnan(result);
    mpd_set_positive(result);
    result->exp = result->digits = result->len = 0;
    *status |= flags;
}

/* quietly set a static decimal from an mpd_ssize_t */
void
mpd_qsset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx,
                uint32_t *status)
{
    mpd_uint_t u;
    uint8_t sign = MPD_POS;

    if (a < 0) {
        if (a == MPD_SSIZE_MIN) {
            u = (mpd_uint_t)MPD_SSIZE_MAX +
                (-(MPD_SSIZE_MIN+MPD_SSIZE_MAX));
        }
        else {
            u = -a;
        }
        sign = MPD_NEG;
    }
    else {
        u = a;
    }
    _ssettriple(result, sign, u, 0);
    mpd_qfinalize(result, ctx, status);
}

/* quietly set a static decimal from an mpd_uint_t */
void
mpd_qsset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx,
               uint32_t *status)
{
    _ssettriple(result, MPD_POS, a, 0);
    mpd_qfinalize(result, ctx, status);
}

/* quietly set a static decimal from an int32_t */
void
mpd_qsset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx,
              uint32_t *status)
{
    mpd_qsset_ssize(result, a, ctx, status);
}

/* quietly set a static decimal from a uint32_t */
void
mpd_qsset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx,
              uint32_t *status)
{
    mpd_qsset_uint(result, a, ctx, status);
}

#ifdef CONFIG_64
/* quietly set a static decimal from an int64_t */
void
mpd_qsset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx,
              uint32_t *status)
{
    mpd_qsset_ssize(result, a, ctx, status);
}

/* quietly set a static decimal from a uint64_t */
void
mpd_qsset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx,
              uint32_t *status)
{
    mpd_qsset_uint(result, a, ctx, status);
}
#endif

/* quietly set a decimal from an mpd_ssize_t */
void
mpd_qset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx,
               uint32_t *status)
{
    mpd_minalloc(result);
    mpd_qsset_ssize(result, a, ctx, status);
}

/* quietly set a decimal from an mpd_uint_t */
void
mpd_qset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx,
              uint32_t *status)
{
    _settriple(result, MPD_POS, a, 0);
    mpd_qfinalize(result, ctx, status);
}

/* quietly set a decimal from an int32_t */
void
mpd_qset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx,
             uint32_t *status)
{
    mpd_qset_ssize(result, a, ctx, status);
}

/* quietly set a decimal from a uint32_t */
void
mpd_qset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx,
             uint32_t *status)
{
    mpd_qset_uint(result, a, ctx, status);
}

#if defined(CONFIG_32) && !defined(LEGACY_COMPILER)
/* set a decimal from a uint64_t */
static void
_c32setu64(mpd_t *result, uint64_t u, uint8_t sign, uint32_t *status)
{
    mpd_uint_t w[3];
    uint64_t q;
    int i, len;

    len = 0;
    do {
        q = u / MPD_RADIX;
        w[len] = (mpd_uint_t)(u - q * MPD_RADIX);
        u = q; len++;
    } while (u != 0);

    if (!mpd_qresize(result, len, status)) {
        return;
    }
    for (i = 0; i < len; i++) {
        result->data[i] = w[i];
    }

    mpd_set_sign(result, sign);
    result->exp = 0;
    result->len = len;
    mpd_setdigits(result);
}

static void
_c32_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx,
              uint32_t *status)
{
    _c32setu64(result, a, MPD_POS, status);
    mpd_qfinalize(result, ctx, status);
}

/* set a decimal from an int64_t */
static void
_c32_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx,
              uint32_t *status)
{
    uint64_t u;
    uint8_t sign = MPD_POS;

    if (a < 0) {
        if (a == INT64_MIN) {
            u = (uint64_t)INT64_MAX + (-(INT64_MIN+INT64_MAX));
        }
        else {
            u = -a;
        }
        sign = MPD_NEG;
    }
    else {
        u = a;
    }
    _c32setu64(result, u, sign, status);
    mpd_qfinalize(result, ctx, status);
}
#endif /* CONFIG_32 && !LEGACY_COMPILER */

#ifndef LEGACY_COMPILER
/* quietly set a decimal from an int64_t */
void
mpd_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx,
             uint32_t *status)
{
#ifdef CONFIG_64
    mpd_qset_ssize(result, a, ctx, status);
#else
    _c32_qset_i64(result, a, ctx, status);
#endif
}

/* quietly set a decimal from a uint64_t */
void
mpd_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx,
             uint32_t *status)
{
#ifdef CONFIG_64
    mpd_qset_uint(result, a, ctx, status);
#else
    _c32_qset_u64(result, a, ctx, status);
#endif
}
#endif /* !LEGACY_COMPILER */


/*
 * Quietly get an mpd_uint_t from a decimal. Assumes
 * MPD_UINT_DIGITS == MPD_RDIGITS+1, which is true for
 * 32 and 64 bit machines.
 *
 * If the operation is impossible, MPD_Invalid_operation is set.
 */
static mpd_uint_t
_mpd_qget_uint(int use_sign, const mpd_t *a, uint32_t *status)
{
    mpd_t tmp;
    mpd_uint_t tmp_data[2];
    mpd_uint_t lo, hi;

    if (mpd_isspecial(a)) {
        *status |= MPD_Invalid_operation;
        return MPD_UINT_MAX;
    }
    if (mpd_iszero(a)) {
        return 0;
    }
    if (use_sign && mpd_isnegative(a)) {
        *status |= MPD_Invalid_operation;
        return MPD_UINT_MAX;
    }

    if (a->digits+a->exp > MPD_RDIGITS+1) {
        *status |= MPD_Invalid_operation;
        return MPD_UINT_MAX;
    }

    if (a->exp < 0) {
        if (!_mpd_isint(a)) {
            *status |= MPD_Invalid_operation;
            return MPD_UINT_MAX;
        }
        /* At this point a->digits+a->exp <= MPD_RDIGITS+1,
         * so the shift fits. */
        tmp.data = tmp_data;
        tmp.flags = MPD_STATIC|MPD_STATIC_DATA;
        tmp.alloc = 2;
        mpd_qsshiftr(&tmp, a, -a->exp);
        tmp.exp = 0;
        a = &tmp;
    }

    _mpd_get_msdigits(&hi, &lo, a, MPD_RDIGITS+1);
    if (hi) {
        *status |= MPD_Invalid_operation;
        return MPD_UINT_MAX;
    }

    if (a->exp > 0) {
        _mpd_mul_words(&hi, &lo, lo, mpd_pow10[a->exp]);
        if (hi) {
            *status |= MPD_Invalid_operation;
            return MPD_UINT_MAX;
        }
    }

    return lo;
}

/*
 * Sets Invalid_operation for:
 *   - specials
 *   - negative numbers (except negative zero)
 *   - non-integers
 *   - overflow
 */
mpd_uint_t
mpd_qget_uint(const mpd_t *a, uint32_t *status)
{
    return _mpd_qget_uint(1, a, status);
}

/* Same as above, but gets the absolute value, i.e. the sign is ignored. */
mpd_uint_t
mpd_qabs_uint(const mpd_t *a, uint32_t *status)
{
    return _mpd_qget_uint(0, a, status);
}

/* quietly get an mpd_ssize_t from a decimal */
mpd_ssize_t
mpd_qget_ssize(const mpd_t *a, uint32_t *status)
{
    mpd_uint_t u;
    int isneg;

    u = mpd_qabs_uint(a, status);
    if (*status&MPD_Invalid_operation) {
        return MPD_SSIZE_MAX;
    }

    isneg = mpd_isnegative(a);
    if (u <= MPD_SSIZE_MAX) {
        return isneg ? -((mpd_ssize_t)u) : (mpd_ssize_t)u;
    }
    else if (isneg && u+(MPD_SSIZE_MIN+MPD_SSIZE_MAX) == MPD_SSIZE_MAX) {
        return MPD_SSIZE_MIN;
    }

    *status |= MPD_Invalid_operation;
    return MPD_SSIZE_MAX;
}

#if defined(CONFIG_32) && !defined(LEGACY_COMPILER)
/*
 * Quietly get a uint64_t from a decimal. If the operation is impossible,
 * MPD_Invalid_operation is set.
 */
static uint64_t
_c32_qget_u64(int use_sign, const mpd_t *a, uint32_t *status)
{
    MPD_NEW_STATIC(tmp,0,0,20,3);
    mpd_context_t maxcontext;
    uint64_t ret;

    tmp_data[0] = 709551615;
    tmp_data[1] = 446744073;
    tmp_data[2] = 18;

    if (mpd_isspecial(a)) {
        *status |= MPD_Invalid_operation;
        return UINT64_MAX;
    }
    if (mpd_iszero(a)) {
        return 0;
    }
    if (use_sign && mpd_isnegative(a)) {
        *status |= MPD_Invalid_operation;
        return UINT64_MAX;
    }
    if (!_mpd_isint(a)) {
        *status |= MPD_Invalid_operation;
        return UINT64_MAX;
    }

    if (_mpd_cmp_abs(a, &tmp) > 0) {
        *status |= MPD_Invalid_operation;
        return UINT64_MAX;
    }

    mpd_maxcontext(&maxcontext);
    mpd_qrescale(&tmp, a, 0, &maxcontext, &maxcontext.status);
    maxcontext.status &= ~MPD_Rounded;
    if (maxcontext.status != 0) {
        *status |= (maxcontext.status|MPD_Invalid_operation); /* GCOV_NOT_REACHED */
        return UINT64_MAX; /* GCOV_NOT_REACHED */
    }

    ret = 0;
    switch (tmp.len) {
    case 3:
        ret += (uint64_t)tmp_data[2] * 1000000000000000000ULL;
    case 2:
        ret += (uint64_t)tmp_data[1] * 1000000000ULL;
    case 1:
        ret += tmp_data[0];
        break;
    default:
        abort(); /* GCOV_NOT_REACHED */
    }

    return ret;
}

static int64_t
_c32_qget_i64(const mpd_t *a, uint32_t *status)
{
    uint64_t u;
    int isneg;

    u = _c32_qget_u64(0, a, status);
    if (*status&MPD_Invalid_operation) {
        return INT64_MAX;
    }

    isneg = mpd_isnegative(a);
    if (u <= INT64_MAX) {
        return isneg ? -((int64_t)u) : (int64_t)u;
    }
    else if (isneg && u+(INT64_MIN+INT64_MAX) == INT64_MAX) {
        return INT64_MIN;
    }

    *status |= MPD_Invalid_operation;
    return INT64_MAX;
}
#endif /* CONFIG_32 && !LEGACY_COMPILER */

#ifdef CONFIG_64
/* quietly get a uint64_t from a decimal */
uint64_t
mpd_qget_u64(const mpd_t *a, uint32_t *status)
{
    return mpd_qget_uint(a, status);
}

/* quietly get an int64_t from a decimal */
int64_t
mpd_qget_i64(const mpd_t *a, uint32_t *status)
{
    return mpd_qget_ssize(a, status);
}

/* quietly get a uint32_t from a decimal */
uint32_t
mpd_qget_u32(const mpd_t *a, uint32_t *status)
{
    uint64_t x = mpd_qget_uint(a, status);

    if (*status&MPD_Invalid_operation) {
        return UINT32_MAX;
    }
    if (x > UINT32_MAX) {
        *status |= MPD_Invalid_operation;
        return UINT32_MAX;
    }

    return (uint32_t)x;
}

/* quietly get an int32_t from a decimal */
int32_t
mpd_qget_i32(const mpd_t *a, uint32_t *status)
{
    int64_t x = mpd_qget_ssize(a, status);

    if (*status&MPD_Invalid_operation) {
        return INT32_MAX;
    }
    if (x < INT32_MIN || x > INT32_MAX) {
        *status |= MPD_Invalid_operation;
        return INT32_MAX;
    }

    return (int32_t)x;
}
#else
#ifndef LEGACY_COMPILER
/* quietly get a uint64_t from a decimal */
uint64_t
mpd_qget_u64(const mpd_t *a, uint32_t *status)
{
    return _c32_qget_u64(1, a, status);
}

/* quietly get an int64_t from a decimal */
int64_t
mpd_qget_i64(const mpd_t *a, uint32_t *status)
{
    return _c32_qget_i64(a, status);
}
#endif

/* quietly get a uint32_t from a decimal */
uint32_t
mpd_qget_u32(const mpd_t *a, uint32_t *status)
{
    return mpd_qget_uint(a, status);
}

/* quietly get an int32_t from a decimal */
int32_t
mpd_qget_i32(const mpd_t *a, uint32_t *status)
{
    return mpd_qget_ssize(a, status);
}
#endif


/******************************************************************************/
/*         Filtering input of functions, finalizing output of functions       */
/******************************************************************************/

/*
 * Check if the operand is NaN, copy to result and return 1 if this is
 * the case. Copying can fail since NaNs are allowed to have a payload that
 * does not fit in MPD_MINALLOC.
 */
int
mpd_qcheck_nan(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
               uint32_t *status)
{
    if (mpd_isnan(a)) {
        *status |= mpd_issnan(a) ? MPD_Invalid_operation : 0;
        mpd_qcopy(result, a, status);
        mpd_set_qnan(result);
        _mpd_fix_nan(result, ctx);
        return 1;
    }
    return 0;
}

/*
 * Check if either operand is NaN, copy to result and return 1 if this
 * is the case. Copying can fail since NaNs are allowed to have a payload
 * that does not fit in MPD_MINALLOC.
 */
int
mpd_qcheck_nans(mpd_t *result, const mpd_t *a, const mpd_t *b,
                const mpd_context_t *ctx, uint32_t *status)
{
    if ((a->flags|b->flags)&(MPD_NAN|MPD_SNAN)) {
        const mpd_t *choice = b;
        if (mpd_issnan(a)) {
            choice = a;
            *status |= MPD_Invalid_operation;
        }
        else if (mpd_issnan(b)) {
            *status |= MPD_Invalid_operation;
        }
        else if (mpd_isqnan(a)) {
            choice = a;
        }
        mpd_qcopy(result, choice, status);
        mpd_set_qnan(result);
        _mpd_fix_nan(result, ctx);
        return 1;
    }
    return 0;
}

/*
 * Check if one of the operands is NaN, copy to result and return 1 if this
 * is the case. Copying can fail since NaNs are allowed to have a payload
 * that does not fit in MPD_MINALLOC.
 */
static int
mpd_qcheck_3nans(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c,
                 const mpd_context_t *ctx, uint32_t *status)
{
    if ((a->flags|b->flags|c->flags)&(MPD_NAN|MPD_SNAN)) {
        const mpd_t *choice = c;
        if (mpd_issnan(a)) {
            choice = a;
            *status |= MPD_Invalid_operation;
        }
        else if (mpd_issnan(b)) {
            choice = b;
            *status |= MPD_Invalid_operation;
        }
        else if (mpd_issnan(c)) {
            *status |= MPD_Invalid_operation;
        }
        else if (mpd_isqnan(a)) {
            choice = a;
        }
        else if (mpd_isqnan(b)) {
            choice = b;
        }
        mpd_qcopy(result, choice, status);
        mpd_set_qnan(result);
        _mpd_fix_nan(result, ctx);
        return 1;
    }
    return 0;
}

/* Check if rounding digit 'rnd' leads to an increment. */
static inline int
_mpd_rnd_incr(const mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx)
{
    int ld;

    switch (ctx->round) {
    case MPD_ROUND_DOWN: case MPD_ROUND_TRUNC:
        return 0;
    case MPD_ROUND_HALF_UP:
        return (rnd >= 5);
    case MPD_ROUND_HALF_EVEN:
        return (rnd > 5) || ((rnd == 5) && mpd_isoddcoeff(dec));
    case MPD_ROUND_CEILING:
        return !(rnd == 0 || mpd_isnegative(dec));
    case MPD_ROUND_FLOOR:
        return !(rnd == 0 || mpd_ispositive(dec));
    case MPD_ROUND_HALF_DOWN:
        return (rnd > 5);
    case MPD_ROUND_UP:
        return !(rnd == 0);
    case MPD_ROUND_05UP:
        ld = (int)mpd_lsd(dec->data[0]);
        return (!(rnd == 0) && (ld == 0 || ld == 5));
    default:
        /* Without a valid context, further results will be undefined. */
        return 0; /* GCOV_NOT_REACHED */
    }
}

/*
 * Apply rounding to a decimal that has been right-shifted into a full
 * precision decimal. If an increment leads to an overflow of the precision,
 * adjust the coefficient and the exponent and check the new exponent for
 * overflow.
 */
static inline void
_mpd_apply_round(mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx,
                 uint32_t *status)
{
    if (_mpd_rnd_incr(dec, rnd, ctx)) {
        /* We have a number with exactly ctx->prec digits. The increment
         * can only lead to an overflow if the decimal is all nines. In
         * that case, the result is a power of ten with prec+1 digits.
         *
         * If the precision is a multiple of MPD_RDIGITS, this situation is
         * detected by _mpd_baseincr returning a carry.
         * If the precision is not a multiple of MPD_RDIGITS, we have to
         * check if the result has one digit too many.
         */
        mpd_uint_t carry = _mpd_baseincr(dec->data, dec->len);
        if (carry) {
            dec->data[dec->len-1] = mpd_pow10[MPD_RDIGITS-1];
            dec->exp += 1;
            _mpd_check_exp(dec, ctx, status);
            return;
        }
        mpd_setdigits(dec);
        if (dec->digits > ctx->prec) {
            mpd_qshiftr_inplace(dec, 1);
            dec->exp += 1;
            dec->digits = ctx->prec;
            _mpd_check_exp(dec, ctx, status);
        }
    }
}

/*
 * Apply rounding to a decimal. Allow overflow of the precision.
 */
static inline void
_mpd_apply_round_excess(mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx,
                        uint32_t *status)
{
    if (_mpd_rnd_incr(dec, rnd, ctx)) {
        mpd_uint_t carry = _mpd_baseincr(dec->data, dec->len);
        if (carry) {
            if (!mpd_qresize(dec, dec->len+1, status)) {
                return;
            }
            dec->data[dec->len] = 1;
            dec->len += 1;
        }
        mpd_setdigits(dec);
    }
}

/*
 * Apply rounding to a decimal that has been right-shifted into a decimal
 * with full precision or less. Return failure if an increment would
 * overflow the precision.
 */
static inline int
_mpd_apply_round_fit(mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx,
                     uint32_t *status)
{
    if (_mpd_rnd_incr(dec, rnd, ctx)) {
        mpd_uint_t carry = _mpd_baseincr(dec->data, dec->len);
        if (carry) {
            if (!mpd_qresize(dec, dec->len+1, status)) {
                return 0;
            }
            dec->data[dec->len] = 1;
            dec->len += 1;
        }
        mpd_setdigits(dec);
        if (dec->digits > ctx->prec) {
            mpd_seterror(dec, MPD_Invalid_operation, status);
            return 0;
        }
    }
    return 1;
}

/* Check a normal number for overflow, underflow, clamping. If the operand
   is modified, it will be zero, special or (sub)normal with a coefficient
   that fits into the current context precision. */
static inline void
_mpd_check_exp(mpd_t *dec, const mpd_context_t *ctx, uint32_t *status)
{
    mpd_ssize_t adjexp, etiny, shift;
    int rnd;

    adjexp = mpd_adjexp(dec);
    if (adjexp > ctx->emax) {

        if (mpd_iszerocoeff(dec)) {
            dec->exp = ctx->emax;
            if (ctx->clamp) {
                dec->exp -= (ctx->prec-1);
            }
            mpd_zerocoeff(dec);
            *status |= MPD_Clamped;
            return;
        }

        switch (ctx->round) {
        case MPD_ROUND_HALF_UP: case MPD_ROUND_HALF_EVEN:
        case MPD_ROUND_HALF_DOWN: case MPD_ROUND_UP:
        case MPD_ROUND_TRUNC:
            mpd_setspecial(dec, mpd_sign(dec), MPD_INF);
            break;
        case MPD_ROUND_DOWN: case MPD_ROUND_05UP:
            mpd_qmaxcoeff(dec, ctx, status);
            dec->exp = ctx->emax - ctx->prec + 1;
            break;
        case MPD_ROUND_CEILING:
            if (mpd_isnegative(dec)) {
                mpd_qmaxcoeff(dec, ctx, status);
                dec->exp = ctx->emax - ctx->prec + 1;
            }
            else {
                mpd_setspecial(dec, MPD_POS, MPD_INF);
            }
            break;
        case MPD_ROUND_FLOOR:
            if (mpd_ispositive(dec)) {
                mpd_qmaxcoeff(dec, ctx, status);
                dec->exp = ctx->emax - ctx->prec + 1;
            }
            else {
                mpd_setspecial(dec, MPD_NEG, MPD_INF);
            }
            break;
        default: /* debug */
            abort(); /* GCOV_NOT_REACHED */
        }

        *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded;

    } /* fold down */
    else if (ctx->clamp && dec->exp > mpd_etop(ctx)) {
        /* At this point adjexp=exp+digits-1 <= emax and exp > etop=emax-prec+1:
         *   (1) shift = exp -emax+prec-1 > 0
         *   (2) digits+shift = exp+digits-1 - emax + prec <= prec */
        shift = dec->exp - mpd_etop(ctx);
        if (!mpd_qshiftl(dec, dec, shift, status)) {
            return;
        }
        dec->exp -= shift;
        *status |= MPD_Clamped;
        if (!mpd_iszerocoeff(dec) && adjexp < ctx->emin) {
            /* Underflow is impossible, since exp < etiny=emin-prec+1
             * and exp > etop=emax-prec+1 would imply emax < emin. */
            *status |= MPD_Subnormal;
        }
    }
    else if (adjexp < ctx->emin) {

        etiny = mpd_etiny(ctx);

        if (mpd_iszerocoeff(dec)) {
            if (dec->exp < etiny) {
                dec->exp = etiny;
                mpd_zerocoeff(dec);
                *status |= MPD_Clamped;
            }
            return;
        }

        *status |= MPD_Subnormal;
        if (dec->exp < etiny) {
            /* At this point adjexp=exp+digits-1 < emin and exp < etiny=emin-prec+1:
             *   (1) shift = emin-prec+1 - exp > 0
             *   (2) digits-shift = exp+digits-1 - emin + prec < prec */
            shift = etiny - dec->exp;
            rnd = (int)mpd_qshiftr_inplace(dec, shift);
            dec->exp = etiny;
            /* We always have a spare digit in case of an increment. */
            _mpd_apply_round_excess(dec, rnd, ctx, status);
            *status |= MPD_Rounded;
            if (rnd) {
                *status |= (MPD_Inexact|MPD_Underflow);
                if (mpd_iszerocoeff(dec)) {
                    mpd_zerocoeff(dec);
                    *status |= MPD_Clamped;
                }
            }
        }
        /* Case exp >= etiny=emin-prec+1:
         *   (1) adjexp=exp+digits-1 < emin
         *   (2) digits < emin-exp+1 <= prec */
    }
}

/* Transcendental functions do not always set Underflow reliably,
 * since they only use as much precision as is necessary for correct
 * rounding. If a result like 1.0000000000e-101 is finalized, there
 * is no rounding digit that would trigger Underflow. But we can
 * assume Inexact, so a short check suffices. */
static inline void
mpd_check_underflow(mpd_t *dec, const mpd_context_t *ctx, uint32_t *status)
{
    if (mpd_adjexp(dec) < ctx->emin && !mpd_iszero(dec) &&
        dec->exp < mpd_etiny(ctx)) {
        *status |= MPD_Underflow;
    }
}

/* Check if a normal number must be rounded after the exponent has been checked. */
static inline void
_mpd_check_round(mpd_t *dec, const mpd_context_t *ctx, uint32_t *status)
{
    mpd_uint_t rnd;
    mpd_ssize_t shift;

    /* must handle specials: _mpd_check_exp() can produce infinities or NaNs */
    if (mpd_isspecial(dec)) {
        return;
    }

    if (dec->digits > ctx->prec) {
        shift = dec->digits - ctx->prec;
        rnd = mpd_qshiftr_inplace(dec, shift);
        dec->exp += shift;
        _mpd_apply_round(dec, rnd, ctx, status);
        *status |= MPD_Rounded;
        if (rnd) {
            *status |= MPD_Inexact;
        }
    }
}

/* Finalize all operations. */
void
mpd_qfinalize(mpd_t *result, const mpd_context_t *ctx, uint32_t *status)
{
    if (mpd_isspecial(result)) {
        if (mpd_isnan(result)) {
            _mpd_fix_nan(result, ctx);
        }
        return;
    }

    _mpd_check_exp(result, ctx, status);
    _mpd_check_round(result, ctx, status);
}


/******************************************************************************/
/*                                 Copying                                    */
/******************************************************************************/

/* Internal function: Copy a decimal, share data with src: USE WITH CARE! */
static inline void
_mpd_copy_shared(mpd_t *dest, const mpd_t *src)
{
    dest->flags = src->flags;
    dest->exp = src->exp;
    dest->digits = src->digits;
    dest->len = src->len;
    dest->alloc = src->alloc;
    dest->data = src->data;

    mpd_set_shared_data(dest);
}

/*
 * Copy a decimal. In case of an error, status is set to MPD_Malloc_error.
 */
int
mpd_qcopy(mpd_t *result, const mpd_t *a, uint32_t *status)
{
    if (result == a) return 1;

    if (!mpd_qresize(result, a->len, status)) {
        return 0;
    }

    mpd_copy_flags(result, a);
    result->exp = a->exp;
    result->digits = a->digits;
    result->len = a->len;
    memcpy(result->data, a->data, a->len * (sizeof *result->data));

    return 1;
}

/*
 * Copy to a decimal with a static buffer. The caller has to make sure that
 * the buffer is big enough. Cannot fail.
 */
static void
mpd_qcopy_static(mpd_t *result, const mpd_t *a)
{
    if (result == a) return;

    memcpy(result->data, a->data, a->len * (sizeof *result->data));

    mpd_copy_flags(result, a);
    result->exp = a->exp;
    result->digits = a->digits;
    result->len = a->len;
}

/*
 * Return a newly allocated copy of the operand. In case of an error,
 * status is set to MPD_Malloc_error and the return value is NULL.
 */
mpd_t *
mpd_qncopy(const mpd_t *a)
{
    mpd_t *result;

    if ((result = mpd_qnew_size(a->len)) == NULL) {
        return NULL;
    }
    memcpy(result->data, a->data, a->len * (sizeof *result->data));
    mpd_copy_flags(result, a);
    result->exp = a->exp;
    result->digits = a->digits;
    result->len = a->len;

    return result;
}

/*
 * Copy a decimal and set the sign to positive. In case of an error, the
 * status is set to MPD_Malloc_error.
 */
int
mpd_qcopy_abs(mpd_t *result, const mpd_t *a, uint32_t *status)
{
    if (!mpd_qcopy(result, a, status)) {
        return 0;
    }
    mpd_set_positive(result);
    return 1;
}

/*
 * Copy a decimal and negate the sign. In case of an error, the
 * status is set to MPD_Malloc_error.
 */
int
mpd_qcopy_negate(mpd_t *result, const mpd_t *a, uint32_t *status)
{
    if (!mpd_qcopy(result, a, status)) {
        return 0;
    }
    _mpd_negate(result);
    return 1;
}

/*
 * Copy a decimal, setting the sign of the first operand to the sign of the
 * second operand. In case of an error, the status is set to MPD_Malloc_error.
 */
int
mpd_qcopy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, uint32_t *status)
{
    uint8_t sign_b = mpd_sign(b); /* result may equal b! */

    if (!mpd_qcopy(result, a, status)) {
        return 0;
    }
    mpd_set_sign(result, sign_b);
    return 1;
}


/******************************************************************************/
/*                                Comparisons                                 */
/******************************************************************************/

/*
 * For all functions that compare two operands and return an int the usual
 * convention applies to the return value:
 *
 * -1 if op1 < op2
 *  0 if op1 == op2
 *  1 if op1 > op2
 *
 *  INT_MAX for error
 */


/* Convenience macro. If a and b are not equal, return from the calling
 * function with the correct comparison value. */
#define CMP_EQUAL_OR_RETURN(a, b)  \
        if (a != b) {              \
                if (a < b) {       \
                        return -1; \
                }                  \
                return 1;          \
        }

/*
 * Compare the data of big and small. This function does the equivalent
 * of first shifting small to the left and then comparing the data of
 * big and small, except that no allocation for the left shift is needed.
 */
static int
_mpd_basecmp(mpd_uint_t *big, mpd_uint_t *small, mpd_size_t n, mpd_size_t m,
             mpd_size_t shift)
{
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
    /* spurious uninitialized warnings */
    mpd_uint_t l=l, lprev=lprev, h=h;
#else
    mpd_uint_t l, lprev, h;
#endif
    mpd_uint_t q, r;
    mpd_uint_t ph, x;

    assert(m > 0 && n >= m && shift > 0);

    _mpd_div_word(&q, &r, (mpd_uint_t)shift, MPD_RDIGITS);

    if (r != 0) {

        ph = mpd_pow10[r];

        --m; --n;
        _mpd_divmod_pow10(&h, &lprev, small[m--], MPD_RDIGITS-r);
        if (h != 0) {
            CMP_EQUAL_OR_RETURN(big[n], h)
            --n;
        }
        for (; m != MPD_SIZE_MAX; m--,n--) {
            _mpd_divmod_pow10(&h, &l, small[m], MPD_RDIGITS-r);
            x = ph * lprev + h;
            CMP_EQUAL_OR_RETURN(big[n], x)
            lprev = l;
        }
        x = ph * lprev;
        CMP_EQUAL_OR_RETURN(big[q], x)
    }
    else {
        while (--m != MPD_SIZE_MAX) {
            CMP_EQUAL_OR_RETURN(big[m+q], small[m])
        }
    }

    return !_mpd_isallzero(big, q);
}

/* Compare two decimals with the same adjusted exponent. */
static int
_mpd_cmp_same_adjexp(const mpd_t *a, const mpd_t *b)
{
    mpd_ssize_t shift, i;

    if (a->exp != b->exp) {
        /* Cannot wrap: a->exp + a->digits = b->exp + b->digits, so
         * a->exp - b->exp = b->digits - a->digits. */
        shift = a->exp - b->exp;
        if (shift > 0) {
            return -1 * _mpd_basecmp(b->data, a->data, b->len, a->len, shift);
        }
        else {
            return _mpd_basecmp(a->data, b->data, a->len, b->len, -shift);
        }
    }

    /*
     * At this point adjexp(a) == adjexp(b) and a->exp == b->exp,
     * so a->digits == b->digits, therefore a->len == b->len.
     */
    for (i = a->len-1; i >= 0; --i) {
        CMP_EQUAL_OR_RETURN(a->data[i], b->data[i])
    }

    return 0;
}

/* Compare two numerical values. */
static int
_mpd_cmp(const mpd_t *a, const mpd_t *b)
{
    mpd_ssize_t adjexp_a, adjexp_b;

    /* equal pointers */
    if (a == b) {
        return 0;
    }

    /* infinities */
    if (mpd_isinfinite(a)) {
        if (mpd_isinfinite(b)) {
            return mpd_isnegative(b) - mpd_isnegative(a);
        }
        return mpd_arith_sign(a);
    }
    if (mpd_isinfinite(b)) {
        return -mpd_arith_sign(b);
    }

    /* zeros */
    if (mpd_iszerocoeff(a)) {
        if (mpd_iszerocoeff(b)) {
            return 0;
        }
        return -mpd_arith_sign(b);
    }
    if (mpd_iszerocoeff(b)) {
        return mpd_arith_sign(a);
    }

    /* different signs */
    if (mpd_sign(a) != mpd_sign(b)) {
        return mpd_sign(b) - mpd_sign(a);
    }

    /* different adjusted exponents */
    adjexp_a = mpd_adjexp(a);
    adjexp_b = mpd_adjexp(b);
    if (adjexp_a != adjexp_b) {
        if (adjexp_a < adjexp_b) {
            return -1 * mpd_arith_sign(a);
        }
        return mpd_arith_sign(a);
    }

    /* same adjusted exponents */
    return _mpd_cmp_same_adjexp(a, b) * mpd_arith_sign(a);
}

/* Compare the absolutes of two numerical values. */
static int
_mpd_cmp_abs(const mpd_t *a, const mpd_t *b)
{
    mpd_ssize_t adjexp_a, adjexp_b;

    /* equal pointers */
    if (a == b) {
        return 0;
    }

    /* infinities */
    if (mpd_isinfinite(a)) {
        if (mpd_isinfinite(b)) {
            return 0;
        }
        return 1;
    }
    if (mpd_isinfinite(b)) {
        return -1;
    }

    /* zeros */
    if (mpd_iszerocoeff(a)) {
        if (mpd_iszerocoeff(b)) {
            return 0;
        }
        return -1;
    }
    if (mpd_iszerocoeff(b)) {
        return 1;
    }

    /* different adjusted exponents */
    adjexp_a = mpd_adjexp(a);
    adjexp_b = mpd_adjexp(b);
    if (adjexp_a != adjexp_b) {
        if (adjexp_a < adjexp_b) {
            return -1;
        }
        return 1;
    }

    /* same adjusted exponents */
    return _mpd_cmp_same_adjexp(a, b);
}

/* Compare two values and return an integer result. */
int
mpd_qcmp(const mpd_t *a, const mpd_t *b, uint32_t *status)
{
    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_isnan(a) || mpd_isnan(b)) {
            *status |= MPD_Invalid_operation;
            return INT_MAX;
        }
    }

    return _mpd_cmp(a, b);
}

/*
 * Compare a and b, convert the usual integer result to a decimal and
 * store it in 'result'. For convenience, the integer result of the comparison
 * is returned. Comparisons involving NaNs return NaN/INT_MAX.
 */
int
mpd_qcompare(mpd_t *result, const mpd_t *a, const mpd_t *b,
             const mpd_context_t *ctx, uint32_t *status)
{
    int c;

    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
            return INT_MAX;
        }
    }

    c = _mpd_cmp(a, b);
    _settriple(result, (c < 0), (c != 0), 0);
    return c;
}

/* Same as mpd_compare(), but signal for all NaNs, i.e. also for quiet NaNs. */
int
mpd_qcompare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b,
                    const mpd_context_t *ctx, uint32_t *status)
{
    int c;

    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
            *status |= MPD_Invalid_operation;
            return INT_MAX;
        }
    }

    c = _mpd_cmp(a, b);
    _settriple(result, (c < 0), (c != 0), 0);
    return c;
}

/* Compare the operands using a total order. */
int
mpd_cmp_total(const mpd_t *a, const mpd_t *b)
{
    mpd_t aa, bb;
    int nan_a, nan_b;
    int c;

    if (mpd_sign(a) != mpd_sign(b)) {
        return mpd_sign(b) - mpd_sign(a);
    }


    if (mpd_isnan(a)) {
        c = 1;
        if (mpd_isnan(b)) {
            nan_a = (mpd_isqnan(a)) ? 1 : 0;
            nan_b = (mpd_isqnan(b)) ? 1 : 0;
            if (nan_b == nan_a) {
                if (a->len > 0 && b->len > 0) {
                    _mpd_copy_shared(&aa, a);
                    _mpd_copy_shared(&bb, b);
                    aa.exp = bb.exp = 0;
                    /* compare payload */
                    c = _mpd_cmp_abs(&aa, &bb);
                }
                else {
                    c = (a->len > 0) - (b->len > 0);
                }
            }
            else {
                c = nan_a - nan_b;
            }
        }
    }
    else if (mpd_isnan(b)) {
        c = -1;
    }
    else {
        c = _mpd_cmp_abs(a, b);
        if (c == 0 && a->exp != b->exp) {
            c = (a->exp < b->exp) ? -1 : 1;
        }
    }

    return c * mpd_arith_sign(a);
}

/*
 * Compare a and b according to a total order, convert the usual integer result
 * to a decimal and store it in 'result'. For convenience, the integer result
 * of the comparison is returned.
 */
int
mpd_compare_total(mpd_t *result, const mpd_t *a, const mpd_t *b)
{
    int c;

    c = mpd_cmp_total(a, b);
    _settriple(result, (c < 0), (c != 0), 0);
    return c;
}

/* Compare the magnitude of the operands using a total order. */
int
mpd_cmp_total_mag(const mpd_t *a, const mpd_t *b)
{
    mpd_t aa, bb;

    _mpd_copy_shared(&aa, a);
    _mpd_copy_shared(&bb, b);

    mpd_set_positive(&aa);
    mpd_set_positive(&bb);

    return mpd_cmp_total(&aa, &bb);
}

/*
 * Compare the magnitude of a and b according to a total order, convert the
 * the usual integer result to a decimal and store it in 'result'.
 * For convenience, the integer result of the comparison is returned.
 */
int
mpd_compare_total_mag(mpd_t *result, const mpd_t *a, const mpd_t *b)
{
    int c;

    c = mpd_cmp_total_mag(a, b);
    _settriple(result, (c < 0), (c != 0), 0);
    return c;
}

/* Determine an ordering for operands that are numerically equal. */
static inline int
_mpd_cmp_numequal(const mpd_t *a, const mpd_t *b)
{
    int sign_a, sign_b;
    int c;

    sign_a = mpd_sign(a);
    sign_b = mpd_sign(b);
    if (sign_a != sign_b) {
        c = sign_b - sign_a;
    }
    else {
        c = (a->exp < b->exp) ? -1 : 1;
        c *= mpd_arith_sign(a);
    }

    return c;
}


/******************************************************************************/
/*                         Shifting the coefficient                           */
/******************************************************************************/

/*
 * Shift the coefficient of the operand to the left, no check for specials.
 * Both operands may be the same pointer. If the result length has to be
 * increased, mpd_qresize() might fail with MPD_Malloc_error.
 */
int
mpd_qshiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status)
{
    mpd_ssize_t size;

    assert(!mpd_isspecial(a));
    assert(n >= 0);

    if (mpd_iszerocoeff(a) || n == 0) {
        return mpd_qcopy(result, a, status);
    }

    size = mpd_digits_to_size(a->digits+n);
    if (!mpd_qresize(result, size, status)) {
        return 0; /* result is NaN */
    }

    _mpd_baseshiftl(result->data, a->data, size, a->len, n);

    mpd_copy_flags(result, a);
    result->exp = a->exp;
    result->digits = a->digits+n;
    result->len = size;

    return 1;
}

/* Determine the rounding indicator if all digits of the coefficient are shifted
 * out of the picture. */
static mpd_uint_t
_mpd_get_rnd(const mpd_uint_t *data, mpd_ssize_t len, int use_msd)
{
    mpd_uint_t rnd = 0, rest = 0, word;

    word = data[len-1];
    /* special treatment for the most significant digit if shift == digits */
    if (use_msd) {
        _mpd_divmod_pow10(&rnd, &rest, word, mpd_word_digits(word)-1);
        if (len > 1 && rest == 0) {
             rest = !_mpd_isallzero(data, len-1);
        }
    }
    else {
        rest = !_mpd_isallzero(data, len);
    }

    return (rnd == 0 || rnd == 5) ? rnd + !!rest : rnd;
}

/*
 * Same as mpd_qshiftr(), but 'result' is an mpd_t with a static coefficient.
 * It is the caller's responsibility to ensure that the coefficient is big
 * enough. The function cannot fail.
 */
static mpd_uint_t
mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n)
{
    mpd_uint_t rnd;
    mpd_ssize_t size;

    assert(!mpd_isspecial(a));
    assert(n >= 0);

    if (mpd_iszerocoeff(a) || n == 0) {
        mpd_qcopy_static(result, a);
        return 0;
    }

    if (n >= a->digits) {
        rnd = _mpd_get_rnd(a->data, a->len, (n==a->digits));
        mpd_zerocoeff(result);
    }
    else {
        result->digits = a->digits-n;
        size = mpd_digits_to_size(result->digits);
        rnd = _mpd_baseshiftr(result->data, a->data, a->len, n);
        result->len = size;
    }

    mpd_copy_flags(result, a);
    result->exp = a->exp;

    return rnd;
}

/*
 * Inplace shift of the coefficient to the right, no check for specials.
 * Returns the rounding indicator for mpd_rnd_incr().
 * The function cannot fail.
 */
mpd_uint_t
mpd_qshiftr_inplace(mpd_t *result, mpd_ssize_t n)
{
    uint32_t dummy;
    mpd_uint_t rnd;
    mpd_ssize_t size;

    assert(!mpd_isspecial(result));
    assert(n >= 0);

    if (mpd_iszerocoeff(result) || n == 0) {
        return 0;
    }

    if (n >= result->digits) {
        rnd = _mpd_get_rnd(result->data, result->len, (n==result->digits));
        mpd_zerocoeff(result);
    }
    else {
        rnd = _mpd_baseshiftr(result->data, result->data, result->len, n);
        result->digits -= n;
        size = mpd_digits_to_size(result->digits);
        /* reducing the size cannot fail */
        mpd_qresize(result, size, &dummy);
        result->len = size;
    }

    return rnd;
}

/*
 * Shift the coefficient of the operand to the right, no check for specials.
 * Both operands may be the same pointer. Returns the rounding indicator to
 * be used by mpd_rnd_incr(). If the result length has to be increased,
 * mpd_qcopy() or mpd_qresize() might fail with MPD_Malloc_error. In those
 * cases, MPD_UINT_MAX is returned.
 */
mpd_uint_t
mpd_qshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status)
{
    mpd_uint_t rnd;
    mpd_ssize_t size;

    assert(!mpd_isspecial(a));
    assert(n >= 0);

    if (mpd_iszerocoeff(a) || n == 0) {
        if (!mpd_qcopy(result, a, status)) {
            return MPD_UINT_MAX;
        }
        return 0;
    }

    if (n >= a->digits) {
        rnd = _mpd_get_rnd(a->data, a->len, (n==a->digits));
        mpd_zerocoeff(result);
    }
    else {
        result->digits = a->digits-n;
        size = mpd_digits_to_size(result->digits);
        if (result == a) {
            rnd = _mpd_baseshiftr(result->data, a->data, a->len, n);
            /* reducing the size cannot fail */
            mpd_qresize(result, size, status);
        }
        else {
            if (!mpd_qresize(result, size, status)) {
                return MPD_UINT_MAX;
            }
            rnd = _mpd_baseshiftr(result->data, a->data, a->len, n);
        }
        result->len = size;
    }

    mpd_copy_flags(result, a);
    result->exp = a->exp;

    return rnd;
}


/******************************************************************************/
/*                         Miscellaneous operations                           */
/******************************************************************************/

/* Logical And */
void
mpd_qand(mpd_t *result, const mpd_t *a, const mpd_t *b,
         const mpd_context_t *ctx, uint32_t *status)
{
    const mpd_t *big = a, *small = b;
    mpd_uint_t x, y, z, xbit, ybit;
    int k, mswdigits;
    mpd_ssize_t i;

    if (mpd_isspecial(a) || mpd_isspecial(b) ||
        mpd_isnegative(a) || mpd_isnegative(b) ||
        a->exp != 0 || b->exp != 0) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }
    if (b->digits > a->digits) {
        big = b;
        small = a;
    }
    if (!mpd_qresize(result, big->len, status)) {
        return;
    }


    /* full words */
    for (i = 0; i < small->len-1; i++) {
        x = small->data[i];
        y = big->data[i];
        z = 0;
        for (k = 0; k < MPD_RDIGITS; k++) {
            xbit = x % 10;
            x /= 10;
            ybit = y % 10;
            y /= 10;
            if (xbit > 1 || ybit > 1) {
                goto invalid_operation;
            }
            z += (xbit&ybit) ? mpd_pow10[k] : 0;
        }
        result->data[i] = z;
    }
    /* most significant word of small */
    x = small->data[i];
    y = big->data[i];
    z = 0;
    mswdigits = mpd_word_digits(x);
    for (k = 0; k < mswdigits; k++) {
        xbit = x % 10;
        x /= 10;
        ybit = y % 10;
        y /= 10;
        if (xbit > 1 || ybit > 1) {
            goto invalid_operation;
        }
        z += (xbit&ybit) ? mpd_pow10[k] : 0;
    }
    result->data[i++] = z;

    /* scan the rest of y for digits > 1 */
    for (; k < MPD_RDIGITS; k++) {
        ybit = y % 10;
        y /= 10;
        if (ybit > 1) {
            goto invalid_operation;
        }
    }
    /* scan the rest of big for digits > 1 */
    for (; i < big->len; i++) {
        y = big->data[i];
        for (k = 0; k < MPD_RDIGITS; k++) {
            ybit = y % 10;
            y /= 10;
            if (ybit > 1) {
                goto invalid_operation;
            }
        }
    }

    mpd_clear_flags(result);
    result->exp = 0;
    result->len = _mpd_real_size(result->data, small->len);
    mpd_qresize(result, result->len, status);
    mpd_setdigits(result);
    _mpd_cap(result, ctx);
    return;

invalid_operation:
    mpd_seterror(result, MPD_Invalid_operation, status);
}

/* Class of an operand. Returns a pointer to the constant name. */
const char *
mpd_class(const mpd_t *a, const mpd_context_t *ctx)
{
    if (mpd_isnan(a)) {
        if (mpd_isqnan(a))
            return "NaN";
        else
            return "sNaN";
    }
    else if (mpd_ispositive(a)) {
        if (mpd_isinfinite(a))
            return "+Infinity";
        else if (mpd_iszero(a))
            return "+Zero";
        else if (mpd_isnormal(a, ctx))
            return "+Normal";
        else
            return "+Subnormal";
    }
    else {
        if (mpd_isinfinite(a))
            return "-Infinity";
        else if (mpd_iszero(a))
            return "-Zero";
        else if (mpd_isnormal(a, ctx))
            return "-Normal";
        else
            return "-Subnormal";
    }
}

/* Logical Xor */
void
mpd_qinvert(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
            uint32_t *status)
{
    mpd_uint_t x, z, xbit;
    mpd_ssize_t i, digits, len;
    mpd_ssize_t q, r;
    int k;

    if (mpd_isspecial(a) || mpd_isnegative(a) || a->exp != 0) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    digits = (a->digits < ctx->prec) ? ctx->prec : a->digits;
    _mpd_idiv_word(&q, &r, digits, MPD_RDIGITS);
    len = (r == 0) ? q : q+1;
    if (!mpd_qresize(result, len, status)) {
        return;
    }

    for (i = 0; i < len; i++) {
        x = (i < a->len) ? a->data[i] : 0;
        z = 0;
        for (k = 0; k < MPD_RDIGITS; k++) {
            xbit = x % 10;
            x /= 10;
            if (xbit > 1) {
                goto invalid_operation;
            }
            z += !xbit ? mpd_pow10[k] : 0;
        }
        result->data[i] = z;
    }

    mpd_clear_flags(result);
    result->exp = 0;
    result->len = _mpd_real_size(result->data, len);
    mpd_qresize(result, result->len, status);
    mpd_setdigits(result);
    _mpd_cap(result, ctx);
    return;

invalid_operation:
    mpd_seterror(result, MPD_Invalid_operation, status);
}

/* Exponent of the magnitude of the most significant digit of the operand. */
void
mpd_qlogb(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
          uint32_t *status)
{
    if (mpd_isspecial(a)) {
        if (mpd_qcheck_nan(result, a, ctx, status)) {
            return;
        }
        mpd_setspecial(result, MPD_POS, MPD_INF);
    }
    else if (mpd_iszerocoeff(a)) {
        mpd_setspecial(result, MPD_NEG, MPD_INF);
        *status |= MPD_Division_by_zero;
    }
    else {
        mpd_qset_ssize(result, mpd_adjexp(a), ctx, status);
    }
}

/* Logical Or */
void
mpd_qor(mpd_t *result, const mpd_t *a, const mpd_t *b,
        const mpd_context_t *ctx, uint32_t *status)
{
    const mpd_t *big = a, *small = b;
    mpd_uint_t x, y, z, xbit, ybit;
    int k, mswdigits;
    mpd_ssize_t i;

    if (mpd_isspecial(a) || mpd_isspecial(b) ||
        mpd_isnegative(a) || mpd_isnegative(b) ||
        a->exp != 0 || b->exp != 0) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }
    if (b->digits > a->digits) {
        big = b;
        small = a;
    }
    if (!mpd_qresize(result, big->len, status)) {
        return;
    }


    /* full words */
    for (i = 0; i < small->len-1; i++) {
        x = small->data[i];
        y = big->data[i];
        z = 0;
        for (k = 0; k < MPD_RDIGITS; k++) {
            xbit = x % 10;
            x /= 10;
            ybit = y % 10;
            y /= 10;
            if (xbit > 1 || ybit > 1) {
                goto invalid_operation;
            }
            z += (xbit|ybit) ? mpd_pow10[k] : 0;
        }
        result->data[i] = z;
    }
    /* most significant word of small */
    x = small->data[i];
    y = big->data[i];
    z = 0;
    mswdigits = mpd_word_digits(x);
    for (k = 0; k < mswdigits; k++) {
        xbit = x % 10;
        x /= 10;
        ybit = y % 10;
        y /= 10;
        if (xbit > 1 || ybit > 1) {
            goto invalid_operation;
        }
        z += (xbit|ybit) ? mpd_pow10[k] : 0;
    }

    /* scan for digits > 1 and copy the rest of y */
    for (; k < MPD_RDIGITS; k++) {
        ybit = y % 10;
        y /= 10;
        if (ybit > 1) {
            goto invalid_operation;
        }
        z += ybit*mpd_pow10[k];
    }
    result->data[i++] = z;
    /* scan for digits > 1 and copy the rest of big */
    for (; i < big->len; i++) {
        y = big->data[i];
        for (k = 0; k < MPD_RDIGITS; k++) {
            ybit = y % 10;
            y /= 10;
            if (ybit > 1) {
                goto invalid_operation;
            }
        }
        result->data[i] = big->data[i];
    }

    mpd_clear_flags(result);
    result->exp = 0;
    result->len = _mpd_real_size(result->data, big->len);
    mpd_qresize(result, result->len, status);
    mpd_setdigits(result);
    _mpd_cap(result, ctx);
    return;

invalid_operation:
    mpd_seterror(result, MPD_Invalid_operation, status);
}

/*
 * Rotate the coefficient of 'a' by 'b' digits. 'b' must be an integer with
 * exponent 0.
 */
void
mpd_qrotate(mpd_t *result, const mpd_t *a, const mpd_t *b,
            const mpd_context_t *ctx, uint32_t *status)
{
    uint32_t workstatus = 0;
    MPD_NEW_STATIC(tmp,0,0,0,0);
    MPD_NEW_STATIC(big,0,0,0,0);
    MPD_NEW_STATIC(small,0,0,0,0);
    mpd_ssize_t n, lshift, rshift;

    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
            return;
        }
    }
    if (b->exp != 0 || mpd_isinfinite(b)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    n = mpd_qget_ssize(b, &workstatus);
    if (workstatus&MPD_Invalid_operation) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }
    if (n > ctx->prec || n < -ctx->prec) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }
    if (mpd_isinfinite(a)) {
        mpd_qcopy(result, a, status);
        return;
    }

    if (n >= 0) {
        lshift = n;
        rshift = ctx->prec-n;
    }
    else {
        lshift = ctx->prec+n;
        rshift = -n;
    }

    if (a->digits > ctx->prec) {
        if (!mpd_qcopy(&tmp, a, status)) {
            mpd_seterror(result, MPD_Malloc_error, status);
            goto finish;
        }
        _mpd_cap(&tmp, ctx);
        a = &tmp;
    }

    if (!mpd_qshiftl(&big, a, lshift, status)) {
        mpd_seterror(result, MPD_Malloc_error, status);
        goto finish;
    }
    _mpd_cap(&big, ctx);

    if (mpd_qshiftr(&small, a, rshift, status) == MPD_UINT_MAX) {
        mpd_seterror(result, MPD_Malloc_error, status);
        goto finish;
    }
    _mpd_qadd(result, &big, &small, ctx, status);


finish:
    mpd_del(&tmp);
    mpd_del(&big);
    mpd_del(&small);
}

/*
 * b must be an integer with exponent 0 and in the range +-2*(emax + prec).
 * XXX: In my opinion +-(2*emax + prec) would be more sensible.
 * The result is a with the value of b added to its exponent.
 */
void
mpd_qscaleb(mpd_t *result, const mpd_t *a, const mpd_t *b,
            const mpd_context_t *ctx, uint32_t *status)
{
    uint32_t workstatus = 0;
    mpd_uint_t n, maxjump;
#ifndef LEGACY_COMPILER
    int64_t exp;
#else
    mpd_uint_t x;
    int x_sign, n_sign;
    mpd_ssize_t exp;
#endif

    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
            return;
        }
    }
    if (b->exp != 0 || mpd_isinfinite(b)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    n = mpd_qabs_uint(b, &workstatus);
    /* the spec demands this */
    maxjump = 2 * (mpd_uint_t)(ctx->emax + ctx->prec);

    if (n > maxjump || workstatus&MPD_Invalid_operation) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }
    if (mpd_isinfinite(a)) {
        mpd_qcopy(result, a, status);
        return;
    }

#ifndef LEGACY_COMPILER
    exp = a->exp + (int64_t)n * mpd_arith_sign(b);
    exp = (exp > MPD_EXP_INF) ? MPD_EXP_INF : exp;
    exp = (exp < MPD_EXP_CLAMP) ? MPD_EXP_CLAMP : exp;
#else
    x = (a->exp < 0) ? -a->exp : a->exp;
    x_sign = (a->exp < 0) ? 1 : 0;
    n_sign = mpd_isnegative(b) ? 1 : 0;

    if (x_sign == n_sign) {
        x = x + n;
        if (x < n) x = MPD_UINT_MAX;
    }
    else {
        x_sign = (x >= n) ? x_sign : n_sign;
        x = (x >= n) ? x - n : n - x;
    }
    if (!x_sign && x > MPD_EXP_INF) x = MPD_EXP_INF;
    if (x_sign && x > -MPD_EXP_CLAMP) x = -MPD_EXP_CLAMP;
    exp = x_sign ? -((mpd_ssize_t)x) : (mpd_ssize_t)x;
#endif

    mpd_qcopy(result, a, status);
    result->exp = (mpd_ssize_t)exp;

    mpd_qfinalize(result, ctx, status);
}

/*
 * Shift the coefficient by n digits, positive n is a left shift. In the case
 * of a left shift, the result is decapitated to fit the context precision. If
 * you don't want that, use mpd_shiftl().
 */
void
mpd_qshiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, const mpd_context_t *ctx,
            uint32_t *status)
{
    if (mpd_isspecial(a)) {
        if (mpd_qcheck_nan(result, a, ctx, status)) {
            return;
        }
        mpd_qcopy(result, a, status);
        return;
    }

    if (n >= 0 && n <= ctx->prec) {
        mpd_qshiftl(result, a, n, status);
        _mpd_cap(result, ctx);
    }
    else if (n < 0 && n >= -ctx->prec) {
        if (!mpd_qcopy(result, a, status)) {
            return;
        }
        _mpd_cap(result, ctx);
        mpd_qshiftr_inplace(result, -n);
    }
    else {
        mpd_seterror(result, MPD_Invalid_operation, status);
    }
}

/*
 * Same as mpd_shiftn(), but the shift is specified by the decimal b, which
 * must be an integer with a zero exponent. Infinities remain infinities.
 */
void
mpd_qshift(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx,
           uint32_t *status)
{
    uint32_t workstatus = 0;
    mpd_ssize_t n;

    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
            return;
        }
    }
    if (b->exp != 0 || mpd_isinfinite(b)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    n = mpd_qget_ssize(b, &workstatus);
    if (workstatus&MPD_Invalid_operation) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }
    if (n > ctx->prec || n < -ctx->prec) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }
    if (mpd_isinfinite(a)) {
        mpd_qcopy(result, a, status);
        return;
    }

    if (n >= 0) {
        mpd_qshiftl(result, a, n, status);
        _mpd_cap(result, ctx);
    }
    else {
        if (!mpd_qcopy(result, a, status)) {
            return;
        }
        _mpd_cap(result, ctx);
        mpd_qshiftr_inplace(result, -n);
    }
}

/* Logical Xor */
void
mpd_qxor(mpd_t *result, const mpd_t *a, const mpd_t *b,
        const mpd_context_t *ctx, uint32_t *status)
{
    const mpd_t *big = a, *small = b;
    mpd_uint_t x, y, z, xbit, ybit;
    int k, mswdigits;
    mpd_ssize_t i;

    if (mpd_isspecial(a) || mpd_isspecial(b) ||
        mpd_isnegative(a) || mpd_isnegative(b) ||
        a->exp != 0 || b->exp != 0) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }
    if (b->digits > a->digits) {
        big = b;
        small = a;
    }
    if (!mpd_qresize(result, big->len, status)) {
        return;
    }


    /* full words */
    for (i = 0; i < small->len-1; i++) {
        x = small->data[i];
        y = big->data[i];
        z = 0;
        for (k = 0; k < MPD_RDIGITS; k++) {
            xbit = x % 10;
            x /= 10;
            ybit = y % 10;
            y /= 10;
            if (xbit > 1 || ybit > 1) {
                goto invalid_operation;
            }
            z += (xbit^ybit) ? mpd_pow10[k] : 0;
        }
        result->data[i] = z;
    }
    /* most significant word of small */
    x = small->data[i];
    y = big->data[i];
    z = 0;
    mswdigits = mpd_word_digits(x);
    for (k = 0; k < mswdigits; k++) {
        xbit = x % 10;
        x /= 10;
        ybit = y % 10;
        y /= 10;
        if (xbit > 1 || ybit > 1) {
            goto invalid_operation;
        }
        z += (xbit^ybit) ? mpd_pow10[k] : 0;
    }

    /* scan for digits > 1 and copy the rest of y */
    for (; k < MPD_RDIGITS; k++) {
        ybit = y % 10;
        y /= 10;
        if (ybit > 1) {
            goto invalid_operation;
        }
        z += ybit*mpd_pow10[k];
    }
    result->data[i++] = z;
    /* scan for digits > 1 and copy the rest of big */
    for (; i < big->len; i++) {
        y = big->data[i];
        for (k = 0; k < MPD_RDIGITS; k++) {
            ybit = y % 10;
            y /= 10;
            if (ybit > 1) {
                goto invalid_operation;
            }
        }
        result->data[i] = big->data[i];
    }

    mpd_clear_flags(result);
    result->exp = 0;
    result->len = _mpd_real_size(result->data, big->len);
    mpd_qresize(result, result->len, status);
    mpd_setdigits(result);
    _mpd_cap(result, ctx);
    return;

invalid_operation:
    mpd_seterror(result, MPD_Invalid_operation, status);
}


/******************************************************************************/
/*                         Arithmetic operations                              */
/******************************************************************************/

/*
 * The absolute value of a. If a is negative, the result is the same
 * as the result of the minus operation. Otherwise, the result is the
 * result of the plus operation.
 */
void
mpd_qabs(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
         uint32_t *status)
{
    if (mpd_isspecial(a)) {
        if (mpd_qcheck_nan(result, a, ctx, status)) {
            return;
        }
    }

    if (mpd_isnegative(a)) {
        mpd_qminus(result, a, ctx, status);
    }
    else {
        mpd_qplus(result, a, ctx, status);
    }
}

static inline void
_mpd_ptrswap(const mpd_t **a, const mpd_t **b)
{
    const mpd_t *t = *a;
    *a = *b;
    *b = t;
}

/* Add or subtract infinities. */
static void
_mpd_qaddsub_inf(mpd_t *result, const mpd_t *a, const mpd_t *b, uint8_t sign_b,
                 uint32_t *status)
{
    if (mpd_isinfinite(a)) {
        if (mpd_sign(a) != sign_b && mpd_isinfinite(b)) {
            mpd_seterror(result, MPD_Invalid_operation, status);
        }
        else {
            mpd_setspecial(result, mpd_sign(a), MPD_INF);
        }
        return;
    }
    assert(mpd_isinfinite(b));
    mpd_setspecial(result, sign_b, MPD_INF);
}

/* Add or subtract non-special numbers. */
static void
_mpd_qaddsub(mpd_t *result, const mpd_t *a, const mpd_t *b, uint8_t sign_b,
             const mpd_context_t *ctx, uint32_t *status)
{
    const mpd_t *big, *small;
    MPD_NEW_STATIC(big_aligned,0,0,0,0);
    MPD_NEW_CONST(tiny,0,0,1,1,1,1);
    mpd_uint_t carry;
    mpd_ssize_t newsize, shift;
    mpd_ssize_t exp, i;
    int swap = 0;


    /* compare exponents */
    big = a; small = b;
    if (big->exp != small->exp) {
        if (small->exp > big->exp) {
            _mpd_ptrswap(&big, &small);
            swap++;
        }
        /* align the coefficients */
        if (!mpd_iszerocoeff(big)) {
            exp = big->exp - 1;
            exp += (big->digits > ctx->prec) ? 0 : big->digits-ctx->prec-1;
            if (mpd_adjexp(small) < exp) {
                /*
                 * Avoid huge shifts by substituting a value for small that is
                 * guaranteed to produce the same results.
                 *
                 * adjexp(small) < exp if and only if:
                 *
                 *   bdigits <= prec AND
                 *   bdigits+shift >= prec+2+sdigits AND
                 *   exp = bexp+bdigits-prec-2
                 *
                 *     1234567000000000  ->  bdigits + shift
                 *     ----------XX1234  ->  sdigits
                 *     ----------X1      ->  tiny-digits
                 *     |- prec -|
                 *
                 *      OR
                 *
                 *   bdigits > prec AND
                 *   shift > sdigits AND
                 *   exp = bexp-1
                 *
                 *     1234567892100000  ->  bdigits + shift
                 *     ----------XX1234  ->  sdigits
                 *     ----------X1      ->  tiny-digits
                 *     |- prec -|
                 *
                 * If tiny is zero, adding or subtracting is a no-op.
                 * Otherwise, adding tiny generates a non-zero digit either
                 * below the rounding digit or the least significant digit
                 * of big. When subtracting, tiny is in the same position as
                 * the carry that would be generated by subtracting sdigits.
                 */
                mpd_copy_flags(&tiny, small);
                tiny.exp = exp;
                tiny.digits = 1;
                tiny.len = 1;
                tiny.data[0] = mpd_iszerocoeff(small) ? 0 : 1;
                small = &tiny;
            }
            /* This cannot wrap: the difference is positive and <= maxprec */
            shift = big->exp - small->exp;
            if (!mpd_qshiftl(&big_aligned, big, shift, status)) {
                mpd_seterror(result, MPD_Malloc_error, status);
                goto finish;
            }
            big = &big_aligned;
        }
    }
    result->exp = small->exp;


    /* compare length of coefficients */
    if (big->len < small->len) {
        _mpd_ptrswap(&big, &small);
        swap++;
    }

    newsize = big->len;
    if (!mpd_qresize(result, newsize, status)) {
        goto finish;
    }

    if (mpd_sign(a) == sign_b) {

        carry = _mpd_baseadd(result->data, big->data, small->data,
                             big->len, small->len);

        if (carry) {
            newsize = big->len + 1;
            if (!mpd_qresize(result, newsize, status)) {
                goto finish;
            }
            result->data[newsize-1] = carry;
        }

        result->len = newsize;
        mpd_set_flags(result, sign_b);
    }
    else {
        if (big->len == small->len) {
            for (i=big->len-1; i >= 0; --i) {
                if (big->data[i] != small->data[i]) {
                    if (big->data[i] < small->data[i]) {
                        _mpd_ptrswap(&big, &small);
                        swap++;
                    }
                    break;
                }
            }
        }

        _mpd_basesub(result->data, big->data, small->data,
                     big->len, small->len);
        newsize = _mpd_real_size(result->data, big->len);
        /* resize to smaller cannot fail */
        (void)mpd_qresize(result, newsize, status);

        result->len = newsize;
        sign_b = (swap & 1) ? sign_b : mpd_sign(a);
        mpd_set_flags(result, sign_b);

        if (mpd_iszerocoeff(result)) {
            mpd_set_positive(result);
            if (ctx->round == MPD_ROUND_FLOOR) {
                mpd_set_negative(result);
            }
        }
    }

    mpd_setdigits(result);

finish:
    mpd_del(&big_aligned);
}

/* Add a and b. No specials, no finalizing. */
static void
_mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b,
          const mpd_context_t *ctx, uint32_t *status)
{
    _mpd_qaddsub(result, a, b, mpd_sign(b), ctx, status);
}

/* Subtract b from a. No specials, no finalizing. */
static void
_mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b,
          const mpd_context_t *ctx, uint32_t *status)
{
     _mpd_qaddsub(result, a, b, !mpd_sign(b), ctx, status);
}

/* Add a and b. */
void
mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b,
         const mpd_context_t *ctx, uint32_t *status)
{
    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
            return;
        }
        _mpd_qaddsub_inf(result, a, b, mpd_sign(b), status);
        return;
    }

    _mpd_qaddsub(result, a, b, mpd_sign(b), ctx, status);
    mpd_qfinalize(result, ctx, status);
}

/* Add a and b. Set NaN/Invalid_operation if the result is inexact. */
static void
_mpd_qadd_exact(mpd_t *result, const mpd_t *a, const mpd_t *b,
                const mpd_context_t *ctx, uint32_t *status)
{
    uint32_t workstatus = 0;

    mpd_qadd(result, a, b, ctx, &workstatus);
    *status |= workstatus;
    if (workstatus & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
    }
}

/* Subtract b from a. */
void
mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b,
         const mpd_context_t *ctx, uint32_t *status)
{
    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
            return;
        }
        _mpd_qaddsub_inf(result, a, b, !mpd_sign(b), status);
        return;
    }

    _mpd_qaddsub(result, a, b, !mpd_sign(b), ctx, status);
    mpd_qfinalize(result, ctx, status);
}

/* Subtract b from a. Set NaN/Invalid_operation if the result is inexact. */
static void
_mpd_qsub_exact(mpd_t *result, const mpd_t *a, const mpd_t *b,
                const mpd_context_t *ctx, uint32_t *status)
{
    uint32_t workstatus = 0;

    mpd_qsub(result, a, b, ctx, &workstatus);
    *status |= workstatus;
    if (workstatus & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
    }
}

/* Add decimal and mpd_ssize_t. */
void
mpd_qadd_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b,
               const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qsset_ssize(&bb, b, &maxcontext, status);
    mpd_qadd(result, a, &bb, ctx, status);
    mpd_del(&bb);
}

/* Add decimal and mpd_uint_t. */
void
mpd_qadd_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b,
              const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qsset_uint(&bb, b, &maxcontext, status);
    mpd_qadd(result, a, &bb, ctx, status);
    mpd_del(&bb);
}

/* Subtract mpd_ssize_t from decimal. */
void
mpd_qsub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b,
               const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qsset_ssize(&bb, b, &maxcontext, status);
    mpd_qsub(result, a, &bb, ctx, status);
    mpd_del(&bb);
}

/* Subtract mpd_uint_t from decimal. */
void
mpd_qsub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b,
              const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qsset_uint(&bb, b, &maxcontext, status);
    mpd_qsub(result, a, &bb, ctx, status);
    mpd_del(&bb);
}

/* Add decimal and int32_t. */
void
mpd_qadd_i32(mpd_t *result, const mpd_t *a, int32_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qadd_ssize(result, a, b, ctx, status);
}

/* Add decimal and uint32_t. */
void
mpd_qadd_u32(mpd_t *result, const mpd_t *a, uint32_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qadd_uint(result, a, b, ctx, status);
}

#ifdef CONFIG_64
/* Add decimal and int64_t. */
void
mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qadd_ssize(result, a, b, ctx, status);
}

/* Add decimal and uint64_t. */
void
mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qadd_uint(result, a, b, ctx, status);
}
#elif !defined(LEGACY_COMPILER)
/* Add decimal and int64_t. */
void
mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qset_i64(&bb, b, &maxcontext, status);
    mpd_qadd(result, a, &bb, ctx, status);
    mpd_del(&bb);
}

/* Add decimal and uint64_t. */
void
mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qset_u64(&bb, b, &maxcontext, status);
    mpd_qadd(result, a, &bb, ctx, status);
    mpd_del(&bb);
}
#endif

/* Subtract int32_t from decimal. */
void
mpd_qsub_i32(mpd_t *result, const mpd_t *a, int32_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qsub_ssize(result, a, b, ctx, status);
}

/* Subtract uint32_t from decimal. */
void
mpd_qsub_u32(mpd_t *result, const mpd_t *a, uint32_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qsub_uint(result, a, b, ctx, status);
}

#ifdef CONFIG_64
/* Subtract int64_t from decimal. */
void
mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qsub_ssize(result, a, b, ctx, status);
}

/* Subtract uint64_t from decimal. */
void
mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qsub_uint(result, a, b, ctx, status);
}
#elif !defined(LEGACY_COMPILER)
/* Subtract int64_t from decimal. */
void
mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qset_i64(&bb, b, &maxcontext, status);
    mpd_qsub(result, a, &bb, ctx, status);
    mpd_del(&bb);
}

/* Subtract uint64_t from decimal. */
void
mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qset_u64(&bb, b, &maxcontext, status);
    mpd_qsub(result, a, &bb, ctx, status);
    mpd_del(&bb);
}
#endif


/* Divide infinities. */
static void
_mpd_qdiv_inf(mpd_t *result, const mpd_t *a, const mpd_t *b,
              const mpd_context_t *ctx, uint32_t *status)
{
    if (mpd_isinfinite(a)) {
        if (mpd_isinfinite(b)) {
            mpd_seterror(result, MPD_Invalid_operation, status);
            return;
        }
        mpd_setspecial(result, mpd_sign(a)^mpd_sign(b), MPD_INF);
        return;
    }
    assert(mpd_isinfinite(b));
    _settriple(result, mpd_sign(a)^mpd_sign(b), 0, mpd_etiny(ctx));
    *status |= MPD_Clamped;
}

enum {NO_IDEAL_EXP, SET_IDEAL_EXP};
/* Divide a by b. */
static void
_mpd_qdiv(int action, mpd_t *q, const mpd_t *a, const mpd_t *b,
          const mpd_context_t *ctx, uint32_t *status)
{
    MPD_NEW_STATIC(aligned,0,0,0,0);
    mpd_uint_t ld;
    mpd_ssize_t shift, exp, tz;
    mpd_ssize_t newsize;
    mpd_ssize_t ideal_exp;
    mpd_uint_t rem;
    uint8_t sign_a = mpd_sign(a);
    uint8_t sign_b = mpd_sign(b);


    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_qcheck_nans(q, a, b, ctx, status)) {
            return;
        }
        _mpd_qdiv_inf(q, a, b, ctx, status);
        return;
    }
    if (mpd_iszerocoeff(b)) {
        if (mpd_iszerocoeff(a)) {
            mpd_seterror(q, MPD_Division_undefined, status);
        }
        else {
            mpd_setspecial(q, sign_a^sign_b, MPD_INF);
            *status |= MPD_Division_by_zero;
        }
        return;
    }
    if (mpd_iszerocoeff(a)) {
        exp = a->exp - b->exp;
        _settriple(q, sign_a^sign_b, 0, exp);
        mpd_qfinalize(q, ctx, status);
        return;
    }

    shift = (b->digits - a->digits) + ctx->prec + 1;
    ideal_exp = a->exp - b->exp;
    exp = ideal_exp - shift;
    if (shift > 0) {
        if (!mpd_qshiftl(&aligned, a, shift, status)) {
            mpd_seterror(q, MPD_Malloc_error, status);
            goto finish;
        }
        a = &aligned;
    }
    else if (shift < 0) {
        shift = -shift;
        if (!mpd_qshiftl(&aligned, b, shift, status)) {
            mpd_seterror(q, MPD_Malloc_error, status);
            goto finish;
        }
        b = &aligned;
    }


    newsize = a->len - b->len + 1;
    if ((q != b && q != a) || (q == b && newsize > b->len)) {
        if (!mpd_qresize(q, newsize, status)) {
            mpd_seterror(q, MPD_Malloc_error, status);
            goto finish;
        }
    }


    if (b->len == 1) {
        rem = _mpd_shortdiv(q->data, a->data, a->len, b->data[0]);
    }
    else if (b->len <= MPD_NEWTONDIV_CUTOFF) {
        int ret = _mpd_basedivmod(q->data, NULL, a->data, b->data,
                                  a->len, b->len);
        if (ret < 0) {
            mpd_seterror(q, MPD_Malloc_error, status);
            goto finish;
        }
        rem = ret;
    }
    else {
        MPD_NEW_STATIC(r,0,0,0,0);
        _mpd_base_ndivmod(q, &r, a, b, status);
        if (mpd_isspecial(q) || mpd_isspecial(&r)) {
            mpd_setspecial(q, MPD_POS, MPD_NAN);
            mpd_del(&r);
            goto finish;
        }
        rem = !mpd_iszerocoeff(&r);
        mpd_del(&r);
        newsize = q->len;
    }

    newsize = _mpd_real_size(q->data, newsize);
    /* resize to smaller cannot fail */
    mpd_qresize(q, newsize, status);
    mpd_set_flags(q, sign_a^sign_b);
    q->len = newsize;
    mpd_setdigits(q);

    shift = ideal_exp - exp;
    if (rem) {
        ld = mpd_lsd(q->data[0]);
        if (ld == 0 || ld == 5) {
            q->data[0] += 1;
        }
    }
    else if (action == SET_IDEAL_EXP && shift > 0) {
        tz = mpd_trail_zeros(q);
        shift = (tz > shift) ? shift : tz;
        mpd_qshiftr_inplace(q, shift);
        exp += shift;
    }

    q->exp = exp;


finish:
    mpd_del(&aligned);
    mpd_qfinalize(q, ctx, status);
}

/* Divide a by b. */
void
mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b,
         const mpd_context_t *ctx, uint32_t *status)
{
    _mpd_qdiv(SET_IDEAL_EXP, q, a, b, ctx, status);
}

/* Internal function. */
static void
_mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b,
             const mpd_context_t *ctx, uint32_t *status)
{
    MPD_NEW_STATIC(aligned,0,0,0,0);
    mpd_ssize_t qsize, rsize;
    mpd_ssize_t ideal_exp, expdiff, shift;
    uint8_t sign_a = mpd_sign(a);
    uint8_t sign_ab = mpd_sign(a)^mpd_sign(b);


    ideal_exp = (a->exp > b->exp) ?  b->exp : a->exp;
    if (mpd_iszerocoeff(a)) {
        if (!mpd_qcopy(r, a, status)) {
            goto nanresult; /* GCOV_NOT_REACHED */
        }
        r->exp = ideal_exp;
        _settriple(q, sign_ab, 0, 0);
        return;
    }

    expdiff = mpd_adjexp(a) - mpd_adjexp(b);
    if (expdiff < 0) {
        if (a->exp > b->exp) {
            /* positive and less than b->digits - a->digits */
            shift = a->exp - b->exp;
            if (!mpd_qshiftl(r, a, shift, status)) {
                goto nanresult;
            }
            r->exp = ideal_exp;
        }
        else {
            if (!mpd_qcopy(r, a, status)) {
                goto nanresult;
            }
        }
        _settriple(q, sign_ab, 0, 0);
        return;
    }
    if (expdiff > ctx->prec) {
        *status |= MPD_Division_impossible;
        goto nanresult;
    }


    /*
     * At this point we have:
     *   (1) 0 <= a->exp + a->digits - b->exp - b->digits <= prec
     *   (2) a->exp - b->exp >= b->digits - a->digits
     *   (3) a->exp - b->exp <= prec + b->digits - a->digits
     */
    if (a->exp != b->exp) {
        shift = a->exp - b->exp;
        if (shift > 0) {
            /* by (3), after the shift a->digits <= prec + b->digits */
            if (!mpd_qshiftl(&aligned, a, shift, status)) {
                goto nanresult;
            }
            a = &aligned;
        }
        else  {
            shift = -shift;
            /* by (2), after the shift b->digits <= a->digits */
            if (!mpd_qshiftl(&aligned, b, shift, status)) {
                goto nanresult;
            }
            b = &aligned;
        }
    }


    qsize = a->len - b->len + 1;
    if (!(q == a && qsize < a->len) && !(q == b && qsize < b->len)) {
        if (!mpd_qresize(q, qsize, status)) {
            goto nanresult;
        }
    }

    rsize = b->len;
    if (!(r == a && rsize < a->len)) {
        if (!mpd_qresize(r, rsize, status)) {
            goto nanresult;
        }
    }

    if (b->len == 1) {
        if (a->len == 1) {
            _mpd_div_word(&q->data[0], &r->data[0], a->data[0], b->data[0]);
        }
        else {
            r->data[0] = _mpd_shortdiv(q->data, a->data, a->len, b->data[0]);
        }
    }
    else if (b->len <= MPD_NEWTONDIV_CUTOFF) {
        int ret;
        ret = _mpd_basedivmod(q->data, r->data, a->data, b->data,
                              a->len, b->len);
        if (ret == -1) {
            *status |= MPD_Malloc_error;
            goto nanresult;
        }
    }
    else {
        _mpd_base_ndivmod(q, r, a, b, status);
        if (mpd_isspecial(q) || mpd_isspecial(r)) {
            goto nanresult;
        }
        qsize = q->len;
        rsize = r->len;
    }

    qsize = _mpd_real_size(q->data, qsize);
    /* resize to smaller cannot fail */
    mpd_qresize(q, qsize, status);
    q->len = qsize;
    mpd_setdigits(q);
    mpd_set_flags(q, sign_ab);
    q->exp = 0;
    if (q->digits > ctx->prec) {
        *status |= MPD_Division_impossible;
        goto nanresult;
    }

    rsize = _mpd_real_size(r->data, rsize);
    /* resize to smaller cannot fail */
    mpd_qresize(r, rsize, status);
    r->len = rsize;
    mpd_setdigits(r);
    mpd_set_flags(r, sign_a);
    r->exp = ideal_exp;

out:
    mpd_del(&aligned);
    return;

nanresult:
    mpd_setspecial(q, MPD_POS, MPD_NAN);
    mpd_setspecial(r, MPD_POS, MPD_NAN);
    goto out;
}

/* Integer division with remainder. */
void
mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b,
            const mpd_context_t *ctx, uint32_t *status)
{
    uint8_t sign = mpd_sign(a)^mpd_sign(b);

    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_qcheck_nans(q, a, b, ctx, status)) {
            mpd_qcopy(r, q, status);
            return;
        }
        if (mpd_isinfinite(a)) {
            if (mpd_isinfinite(b)) {
                mpd_setspecial(q, MPD_POS, MPD_NAN);
            }
            else {
                mpd_setspecial(q, sign, MPD_INF);
            }
            mpd_setspecial(r, MPD_POS, MPD_NAN);
            *status |= MPD_Invalid_operation;
            return;
        }
        if (mpd_isinfinite(b)) {
            if (!mpd_qcopy(r, a, status)) {
                mpd_seterror(q, MPD_Malloc_error, status);
                return;
            }
            mpd_qfinalize(r, ctx, status);
            _settriple(q, sign, 0, 0);
            return;
        }
        /* debug */
        abort(); /* GCOV_NOT_REACHED */
    }
    if (mpd_iszerocoeff(b)) {
        if (mpd_iszerocoeff(a)) {
            mpd_setspecial(q, MPD_POS, MPD_NAN);
            mpd_setspecial(r, MPD_POS, MPD_NAN);
            *status |= MPD_Division_undefined;
        }
        else {
            mpd_setspecial(q, sign, MPD_INF);
            mpd_setspecial(r, MPD_POS, MPD_NAN);
            *status |= (MPD_Division_by_zero|MPD_Invalid_operation);
        }
        return;
    }

    _mpd_qdivmod(q, r, a, b, ctx, status);
    mpd_qfinalize(q, ctx, status);
    mpd_qfinalize(r, ctx, status);
}

void
mpd_qdivint(mpd_t *q, const mpd_t *a, const mpd_t *b,
            const mpd_context_t *ctx, uint32_t *status)
{
    MPD_NEW_STATIC(r,0,0,0,0);
    uint8_t sign = mpd_sign(a)^mpd_sign(b);

    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_qcheck_nans(q, a, b, ctx, status)) {
            return;
        }
        if (mpd_isinfinite(a) && mpd_isinfinite(b)) {
            mpd_seterror(q, MPD_Invalid_operation, status);
            return;
        }
        if (mpd_isinfinite(a)) {
            mpd_setspecial(q, sign, MPD_INF);
            return;
        }
        if (mpd_isinfinite(b)) {
            _settriple(q, sign, 0, 0);
            return;
        }
        /* debug */
        abort(); /* GCOV_NOT_REACHED */
    }
    if (mpd_iszerocoeff(b)) {
        if (mpd_iszerocoeff(a)) {
            mpd_seterror(q, MPD_Division_undefined, status);
        }
        else {
            mpd_setspecial(q, sign, MPD_INF);
            *status |= MPD_Division_by_zero;
        }
        return;
    }


    _mpd_qdivmod(q, &r, a, b, ctx, status);
    mpd_del(&r);
    mpd_qfinalize(q, ctx, status);
}

/* Divide decimal by mpd_ssize_t. */
void
mpd_qdiv_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b,
               const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qsset_ssize(&bb, b, &maxcontext, status);
    mpd_qdiv(result, a, &bb, ctx, status);
    mpd_del(&bb);
}

/* Divide decimal by mpd_uint_t. */
void
mpd_qdiv_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b,
              const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qsset_uint(&bb, b, &maxcontext, status);
    mpd_qdiv(result, a, &bb, ctx, status);
    mpd_del(&bb);
}

/* Divide decimal by int32_t. */
void
mpd_qdiv_i32(mpd_t *result, const mpd_t *a, int32_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qdiv_ssize(result, a, b, ctx, status);
}

/* Divide decimal by uint32_t. */
void
mpd_qdiv_u32(mpd_t *result, const mpd_t *a, uint32_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qdiv_uint(result, a, b, ctx, status);
}

#ifdef CONFIG_64
/* Divide decimal by int64_t. */
void
mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qdiv_ssize(result, a, b, ctx, status);
}

/* Divide decimal by uint64_t. */
void
mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qdiv_uint(result, a, b, ctx, status);
}
#elif !defined(LEGACY_COMPILER)
/* Divide decimal by int64_t. */
void
mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qset_i64(&bb, b, &maxcontext, status);
    mpd_qdiv(result, a, &bb, ctx, status);
    mpd_del(&bb);
}

/* Divide decimal by uint64_t. */
void
mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qset_u64(&bb, b, &maxcontext, status);
    mpd_qdiv(result, a, &bb, ctx, status);
    mpd_del(&bb);
}
#endif

/* Pad the result with trailing zeros if it has fewer digits than prec. */
static void
_mpd_zeropad(mpd_t *result, const mpd_context_t *ctx, uint32_t *status)
{
    if (!mpd_isspecial(result) && !mpd_iszero(result) &&
        result->digits < ctx->prec) {
       mpd_ssize_t shift = ctx->prec - result->digits;
       mpd_qshiftl(result, result, shift, status);
       result->exp -= shift;
    }
}

/* Check if the result is guaranteed to be one. */
static int
_mpd_qexp_check_one(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
                    uint32_t *status)
{
    MPD_NEW_CONST(lim,0,-(ctx->prec+1),1,1,1,9);
    MPD_NEW_SHARED(aa, a);

    mpd_set_positive(&aa);

    /* abs(a) <= 9 * 10**(-prec-1) */
    if (_mpd_cmp(&aa, &lim) <= 0) {
        _settriple(result, 0, 1, 0);
        *status |= MPD_Rounded|MPD_Inexact;
        return 1;
    }

    return 0;
}

/*
 * Get the number of iterations for the Horner scheme in _mpd_qexp().
 */
static inline mpd_ssize_t
_mpd_get_exp_iterations(const mpd_t *r, mpd_ssize_t p)
{
    mpd_ssize_t log10pbyr; /* lower bound for log10(p / abs(r)) */
    mpd_ssize_t n;

    assert(p >= 10);
    assert(!mpd_iszero(r));
    assert(-p < mpd_adjexp(r) && mpd_adjexp(r) <= -1);

#ifdef CONFIG_64
    if (p > (mpd_ssize_t)(1ULL<<52)) {
        return MPD_SSIZE_MAX;
    }
#endif

    /*
     * Lower bound for log10(p / abs(r)): adjexp(p) - (adjexp(r) + 1)
     * At this point (for CONFIG_64, CONFIG_32 is not problematic):
     *    1) 10 <= p <= 2**52
     *    2) -p < adjexp(r) <= -1
     *    3) 1 <= log10pbyr <= 2**52 + 14
     */
    log10pbyr = (mpd_word_digits(p)-1) - (mpd_adjexp(r)+1);

    /*
     * The numerator in the paper is 1.435 * p - 1.182, calculated
     * exactly. We compensate for rounding errors by using 1.43503.
     * ACL2 proofs:
     *    1) exp-iter-approx-lower-bound: The term below evaluated
     *       in 53-bit floating point arithmetic is greater than or
     *       equal to the exact term used in the paper.
     *    2) exp-iter-approx-upper-bound: The term below is less than
     *       or equal to 3/2 * p <= 3/2 * 2**52.
     */
    n = (mpd_ssize_t)ceil((1.43503*(double)p - 1.182) / (double)log10pbyr);
    return n >= 3 ? n : 3;
}

/*
 * Internal function, specials have been dealt with. Apart from Overflow
 * and Underflow, two cases must be considered for the error of the result:
 *
 *   1) abs(a) <= 9 * 10**(-prec-1)  ==>  result == 1
 *
 *      Absolute error: abs(1 - e**x) < 10**(-prec)
 *      -------------------------------------------
 *
 *   2) abs(a) > 9 * 10**(-prec-1)
 *
 *      Relative error: abs(result - e**x) < 0.5 * 10**(-prec) * e**x
 *      -------------------------------------------------------------
 *
 * The algorithm is from Hull&Abrham, Variable Precision Exponential Function,
 * ACM Transactions on Mathematical Software, Vol. 12, No. 2, June 1986.
 *
 * Main differences:
 *
 *  - The number of iterations for the Horner scheme is calculated using
 *    53-bit floating point arithmetic.
 *
 *  - In the error analysis for ER (relative error accumulated in the
 *    evaluation of the truncated series) the reduced operand r may
 *    have any number of digits.
 *    ACL2 proof: exponent-relative-error
 *
 *  - The analysis for early abortion has been adapted for the mpd_t
 *    ranges.
 */
static void
_mpd_qexp(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
          uint32_t *status)
{
    mpd_context_t workctx;
    MPD_NEW_STATIC(tmp,0,0,0,0);
    MPD_NEW_STATIC(sum,0,0,0,0);
    MPD_NEW_CONST(word,0,0,1,1,1,1);
    mpd_ssize_t j, n, t;

    assert(!mpd_isspecial(a));

    if (mpd_iszerocoeff(a)) {
        _settriple(result, MPD_POS, 1, 0);
        return;
    }

    /*
     * We are calculating e^x = e^(r*10^t) = (e^r)^(10^t), where abs(r) < 1 and t >= 0.
     *
     * If t > 0, we have:
     *
     *   (1) 0.1 <= r < 1, so e^0.1 <= e^r. If t > MAX_T, overflow occurs:
     *
     *     MAX-EMAX+1 < log10(e^(0.1*10*t)) <= log10(e^(r*10^t)) < adjexp(e^(r*10^t))+1
     *
     *   (2) -1 < r <= -0.1, so e^r <= e^-0.1. If t > MAX_T, underflow occurs:
     *
     *     adjexp(e^(r*10^t)) <= log10(e^(r*10^t)) <= log10(e^(-0.1*10^t)) < MIN-ETINY
     */
#if defined(CONFIG_64)
    #define MPD_EXP_MAX_T 19
#elif defined(CONFIG_32)
    #define MPD_EXP_MAX_T 10
#endif
    t = a->digits + a->exp;
    t = (t > 0) ? t : 0;
    if (t > MPD_EXP_MAX_T) {
        if (mpd_ispositive(a)) {
            mpd_setspecial(result, MPD_POS, MPD_INF);
            *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded;
        }
        else {
            _settriple(result, MPD_POS, 0, mpd_etiny(ctx));
            *status |= (MPD_Inexact|MPD_Rounded|MPD_Subnormal|
                        MPD_Underflow|MPD_Clamped);
        }
        return;
    }

    /* abs(a) <= 9 * 10**(-prec-1) */
    if (_mpd_qexp_check_one(result, a, ctx, status)) {
        return;
    }

    mpd_maxcontext(&workctx);
    workctx.prec = ctx->prec + t + 2;
    workctx.prec = (workctx.prec < 10) ? 10 : workctx.prec;
    workctx.round = MPD_ROUND_HALF_EVEN;

    if (!mpd_qcopy(result, a, status)) {
        return;
    }
    result->exp -= t;

    /*
     * At this point:
     *    1) 9 * 10**(-prec-1) < abs(a)
     *    2) 9 * 10**(-prec-t-1) < abs(r)
     *    3) log10(9) - prec - t - 1 < log10(abs(r)) < adjexp(abs(r)) + 1
     *    4) - prec - t - 2 < adjexp(abs(r)) <= -1
     */
    n = _mpd_get_exp_iterations(result, workctx.prec);
    if (n == MPD_SSIZE_MAX) {
        mpd_seterror(result, MPD_Invalid_operation, status); /* GCOV_UNLIKELY */
        return; /* GCOV_UNLIKELY */
    }

    _settriple(&sum, MPD_POS, 1, 0);

    for (j = n-1; j >= 1; j--) {
        word.data[0] = j;
        mpd_setdigits(&word);
        mpd_qdiv(&tmp, result, &word, &workctx, &workctx.status);
        mpd_qfma(&sum, &sum, &tmp, &one, &workctx, &workctx.status);
    }

#ifdef CONFIG_64
    _mpd_qpow_uint(result, &sum, mpd_pow10[t], MPD_POS, &workctx, status);
#else
    if (t <= MPD_MAX_POW10) {
        _mpd_qpow_uint(result, &sum, mpd_pow10[t], MPD_POS, &workctx, status);
    }
    else {
        t -= MPD_MAX_POW10;
        _mpd_qpow_uint(&tmp, &sum, mpd_pow10[MPD_MAX_POW10], MPD_POS,
                       &workctx, status);
        _mpd_qpow_uint(result, &tmp, mpd_pow10[t], MPD_POS, &workctx, status);
    }
#endif

    mpd_del(&tmp);
    mpd_del(&sum);
    *status |= (workctx.status&MPD_Errors);
    *status |= (MPD_Inexact|MPD_Rounded);
}

/* exp(a) */
void
mpd_qexp(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
         uint32_t *status)
{
    mpd_context_t workctx;

    if (mpd_isspecial(a)) {
        if (mpd_qcheck_nan(result, a, ctx, status)) {
            return;
        }
        if (mpd_isnegative(a)) {
            _settriple(result, MPD_POS, 0, 0);
        }
        else {
            mpd_setspecial(result, MPD_POS, MPD_INF);
        }
        return;
    }
    if (mpd_iszerocoeff(a)) {
        _settriple(result, MPD_POS, 1, 0);
        return;
    }

    workctx = *ctx;
    workctx.round = MPD_ROUND_HALF_EVEN;

    if (ctx->allcr) {
        MPD_NEW_STATIC(t1, 0,0,0,0);
        MPD_NEW_STATIC(t2, 0,0,0,0);
        MPD_NEW_STATIC(ulp, 0,0,0,0);
        MPD_NEW_STATIC(aa, 0,0,0,0);
        mpd_ssize_t prec;
        mpd_ssize_t ulpexp;
        uint32_t workstatus;

        if (result == a) {
            if (!mpd_qcopy(&aa, a, status)) {
                mpd_seterror(result, MPD_Malloc_error, status);
                return;
            }
            a = &aa;
        }

        workctx.clamp = 0;
        prec = ctx->prec + 3;
        while (1) {
            workctx.prec = prec;
            workstatus = 0;

            _mpd_qexp(result, a, &workctx, &workstatus);
            *status |= workstatus;

            ulpexp = result->exp + result->digits - workctx.prec;
            if (workstatus & MPD_Underflow) {
                /* The effective work precision is result->digits. */
                ulpexp = result->exp;
            }
            _ssettriple(&ulp, MPD_POS, 1, ulpexp);

            /*
             * At this point [1]:
             *   1) abs(result - e**x) < 0.5 * 10**(-prec) * e**x
             *   2) result - ulp < e**x < result + ulp
             *   3) result - ulp < result < result + ulp
             *
             * If round(result-ulp)==round(result+ulp), then
             * round(result)==round(e**x). Therefore the result
             * is correctly rounded.
             *
             * [1] If abs(a) <= 9 * 10**(-prec-1), use the absolute
             *     error for a similar argument.
             */
            workctx.prec = ctx->prec;
            mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status);
            mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status);
            if (mpd_isspecial(result) || mpd_iszerocoeff(result) ||
                mpd_qcmp(&t1, &t2, status) == 0) {
                workctx.clamp = ctx->clamp;
                _mpd_zeropad(result, &workctx, status);
                mpd_check_underflow(result, &workctx, status);
                mpd_qfinalize(result, &workctx, status);
                break;
            }
            prec += MPD_RDIGITS;
        }
        mpd_del(&t1);
        mpd_del(&t2);
        mpd_del(&ulp);
        mpd_del(&aa);
    }
    else {
        _mpd_qexp(result, a, &workctx, status);
        _mpd_zeropad(result, &workctx, status);
        mpd_check_underflow(result, &workctx, status);
        mpd_qfinalize(result, &workctx, status);
    }
}

/* Fused multiply-add: (a * b) + c, with a single final rounding. */
void
mpd_qfma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c,
         const mpd_context_t *ctx, uint32_t *status)
{
    uint32_t workstatus = 0;
    mpd_t *cc = NULL;

    if (result == c) {
        if ((cc = mpd_qncopy(c)) == NULL) {
            mpd_seterror(result, MPD_Malloc_error, status);
            return;
        }
        c = cc;
    }

    _mpd_qmul(result, a, b, ctx, &workstatus);
    if (!(workstatus&MPD_Invalid_operation)) {
        mpd_qadd(result, result, c, ctx, &workstatus);
    }

    if (cc) mpd_del(cc);
    *status |= workstatus;
}

/*
 * Schedule the optimal precision increase for the Newton iteration.
 *   v := input operand
 *   z_0 := initial approximation
 *   initprec := natural number such that abs(log(v) - z_0) < 10**-initprec
 *   maxprec := target precision
 *
 * For convenience the output klist contains the elements in reverse order:
 *   klist := [k_n-1, ..., k_0], where
 *     1) k_0 <= initprec and
 *     2) abs(log(v) - result) < 10**(-2*k_n-1 + 1) <= 10**-maxprec.
 */
static inline int
ln_schedule_prec(mpd_ssize_t klist[MPD_MAX_PREC_LOG2], mpd_ssize_t maxprec,
                 mpd_ssize_t initprec)
{
    mpd_ssize_t k;
    int i;

    assert(maxprec >= 2 && initprec >= 2);
    if (maxprec <= initprec) return -1;

    i = 0; k = maxprec;
    do {
        k = (k+2) / 2;
        klist[i++] = k;
    } while (k > initprec);

    return i-1;
}

/* The constants have been verified with both decimal.py and mpfr. */
#ifdef CONFIG_64
#if MPD_RDIGITS != 19
  #error "mpdecimal.c: MPD_RDIGITS must be 19."
#endif
static const mpd_uint_t mpd_ln10_data[MPD_MINALLOC_MAX] = {
  6983716328982174407ULL, 9089704281976336583ULL, 1515961135648465461ULL,
  4416816335727555703ULL, 2900988039194170265ULL, 2307925037472986509ULL,
   107598438319191292ULL, 3466624107184669231ULL, 4450099781311469159ULL,
  9807828059751193854ULL, 7713456862091670584ULL, 1492198849978748873ULL,
  6528728696511086257ULL, 2385392051446341972ULL, 8692180205189339507ULL,
  6518769751037497088ULL, 2375253577097505395ULL, 9095610299291824318ULL,
   982748238504564801ULL, 5438635917781170543ULL, 7547331541421808427ULL,
   752371033310119785ULL, 3171643095059950878ULL, 9785265383207606726ULL,
  2932258279850258550ULL, 5497347726624257094ULL, 2976979522110718264ULL,
  9221477656763693866ULL, 1979650047149510504ULL, 6674183485704422507ULL,
  9702766860595249671ULL, 9278096762712757753ULL, 9314848524948644871ULL,
  6826928280848118428ULL,  754403708474699401ULL,  230105703089634572ULL,
  1929203337658714166ULL, 7589402567763113569ULL, 4208241314695689016ULL,
  2922455440575892572ULL, 9356734206705811364ULL, 2684916746550586856ULL,
   644507064800027750ULL, 9476834636167921018ULL, 5659121373450747856ULL,
  2835522011480466371ULL, 6470806855677432162ULL, 7141748003688084012ULL,
  9619404400222105101ULL, 5504893431493939147ULL, 6674744042432743651ULL,
  2287698219886746543ULL, 7773262884616336622ULL, 1985283935053089653ULL,
  4680843799894826233ULL, 8168948290720832555ULL, 8067566662873690987ULL,
  6248633409525465082ULL, 9829834196778404228ULL, 3524802359972050895ULL,
  3327900967572609677ULL,  110148862877297603ULL,  179914546843642076ULL,
  2302585092994045684ULL
};
#else
#if MPD_RDIGITS != 9
  #error "mpdecimal.c: MPD_RDIGITS must be 9."
#endif
static const mpd_uint_t mpd_ln10_data[MPD_MINALLOC_MAX] = {
  401682692UL, 708474699UL, 720754403UL,  30896345UL, 602301057UL, 765871416UL,
  192920333UL, 763113569UL, 589402567UL, 956890167UL,  82413146UL, 589257242UL,
  245544057UL, 811364292UL, 734206705UL, 868569356UL, 167465505UL, 775026849UL,
  706480002UL,  18064450UL, 636167921UL, 569476834UL, 734507478UL, 156591213UL,
  148046637UL, 283552201UL, 677432162UL, 470806855UL, 880840126UL, 417480036UL,
  210510171UL, 940440022UL, 939147961UL, 893431493UL, 436515504UL, 440424327UL,
  654366747UL, 821988674UL, 622228769UL, 884616336UL, 537773262UL, 350530896UL,
  319852839UL, 989482623UL, 468084379UL, 720832555UL, 168948290UL, 736909878UL,
  675666628UL, 546508280UL, 863340952UL, 404228624UL, 834196778UL, 508959829UL,
   23599720UL, 967735248UL,  96757260UL, 603332790UL, 862877297UL, 760110148UL,
  468436420UL, 401799145UL, 299404568UL, 230258509UL
};
#endif
/* _mpd_ln10 is used directly for precisions smaller than MINALLOC_MAX*RDIGITS.
   Otherwise, it serves as the initial approximation for calculating ln(10). */
static const mpd_t _mpd_ln10 = {
  MPD_STATIC|MPD_CONST_DATA, -(MPD_MINALLOC_MAX*MPD_RDIGITS-1),
  MPD_MINALLOC_MAX*MPD_RDIGITS, MPD_MINALLOC_MAX, MPD_MINALLOC_MAX,
  (mpd_uint_t *)mpd_ln10_data
};

/*
 * Set 'result' to log(10).
 *   Ulp error: abs(result - log(10)) < ulp(log(10))
 *   Relative error: abs(result - log(10)) < 5 * 10**-prec * log(10)
 *
 * NOTE: The relative error is not derived from the ulp error, but
 * calculated separately using the fact that 23/10 < log(10) < 24/10.
 */
void
mpd_qln10(mpd_t *result, mpd_ssize_t prec, uint32_t *status)
{
    mpd_context_t varcontext, maxcontext;
    MPD_NEW_STATIC(tmp, 0,0,0,0);
    MPD_NEW_CONST(static10, 0,0,2,1,1,10);
    mpd_ssize_t klist[MPD_MAX_PREC_LOG2];
    mpd_uint_t rnd;
    mpd_ssize_t shift;
    int i;

    assert(prec >= 1);

    shift = MPD_MINALLOC_MAX*MPD_RDIGITS-prec;
    shift = shift < 0 ? 0 : shift;

    rnd = mpd_qshiftr(result, &_mpd_ln10, shift, status);
    if (rnd == MPD_UINT_MAX) {
        mpd_seterror(result, MPD_Malloc_error, status);
        return;
    }
    result->exp = -(result->digits-1);

    mpd_maxcontext(&maxcontext);
    if (prec < MPD_MINALLOC_MAX*MPD_RDIGITS) {
        maxcontext.prec = prec;
        _mpd_apply_round_excess(result, rnd, &maxcontext, status);
        *status |= (MPD_Inexact|MPD_Rounded);
        return;
    }

    mpd_maxcontext(&varcontext);
    varcontext.round = MPD_ROUND_TRUNC;

    i = ln_schedule_prec(klist, prec+2, -result->exp);
    for (; i >= 0; i--) {
        varcontext.prec = 2*klist[i]+3;
        result->flags ^= MPD_NEG;
        _mpd_qexp(&tmp, result, &varcontext, status);
        result->flags ^= MPD_NEG;
        mpd_qmul(&tmp, &static10, &tmp, &varcontext, status);
        mpd_qsub(&tmp, &tmp, &one, &maxcontext, status);
        mpd_qadd(result, result, &tmp, &maxcontext, status);
        if (mpd_isspecial(result)) {
            break;
        }
    }

    mpd_del(&tmp);
    maxcontext.prec = prec;
    mpd_qfinalize(result, &maxcontext, status);
}

/*
 * Initial approximations for the ln() iteration. The values have the
 * following properties (established with both decimal.py and mpfr):
 *
 * Index 0 - 400, logarithms of x in [1.00, 5.00]:
 *   abs(lnapprox[i] * 10**-3 - log((i+100)/100)) < 10**-2
 *   abs(lnapprox[i] * 10**-3 - log((i+1+100)/100)) < 10**-2
 *
 * Index 401 - 899, logarithms of x in (0.500, 0.999]:
 *   abs(-lnapprox[i] * 10**-3 - log((i+100)/1000)) < 10**-2
 *   abs(-lnapprox[i] * 10**-3 - log((i+1+100)/1000)) < 10**-2
 */
static const uint16_t lnapprox[900] = {
  /* index 0 - 400: log((i+100)/100) * 1000 */
  0, 10, 20, 30, 39, 49, 58, 68, 77, 86, 95, 104, 113, 122, 131, 140, 148, 157,
  166, 174, 182, 191, 199, 207, 215, 223, 231, 239, 247, 255, 262, 270, 278,
  285, 293, 300, 308, 315, 322, 329, 336, 344, 351, 358, 365, 372, 378, 385,
  392, 399, 406, 412, 419, 425, 432, 438, 445, 451, 457, 464, 470, 476, 482,
  489, 495, 501, 507, 513, 519, 525, 531, 536, 542, 548, 554, 560, 565, 571,
  577, 582, 588, 593, 599, 604, 610, 615, 621, 626, 631, 637, 642, 647, 652,
  658, 663, 668, 673, 678, 683, 688, 693, 698, 703, 708, 713, 718, 723, 728,
  732, 737, 742, 747, 751, 756, 761, 766, 770, 775, 779, 784, 788, 793, 798,
  802, 806, 811, 815, 820, 824, 829, 833, 837, 842, 846, 850, 854, 859, 863,
  867, 871, 876, 880, 884, 888, 892, 896, 900, 904, 908, 912, 916, 920, 924,
  928, 932, 936, 940, 944, 948, 952, 956, 959, 963, 967, 971, 975, 978, 982,
  986, 990, 993, 997, 1001, 1004, 1008, 1012, 1015, 1019, 1022, 1026, 1030,
  1033, 1037, 1040, 1044, 1047, 1051, 1054, 1058, 1061, 1065, 1068, 1072, 1075,
  1078, 1082, 1085, 1089, 1092, 1095, 1099, 1102, 1105, 1109, 1112, 1115, 1118,
  1122, 1125, 1128, 1131, 1135, 1138, 1141, 1144, 1147, 1151, 1154, 1157, 1160,
  1163, 1166, 1169, 1172, 1176, 1179, 1182, 1185, 1188, 1191, 1194, 1197, 1200,
  1203, 1206, 1209, 1212, 1215, 1218, 1221, 1224, 1227, 1230, 1233, 1235, 1238,
  1241, 1244, 1247, 1250, 1253, 1256, 1258, 1261, 1264, 1267, 1270, 1273, 1275,
  1278, 1281, 1284, 1286, 1289, 1292, 1295, 1297, 1300, 1303, 1306, 1308, 1311,
  1314, 1316, 1319, 1322, 1324, 1327, 1330, 1332, 1335, 1338, 1340, 1343, 1345,
  1348, 1351, 1353, 1356, 1358, 1361, 1364, 1366, 1369, 1371, 1374, 1376, 1379,
  1381, 1384, 1386, 1389, 1391, 1394, 1396, 1399, 1401, 1404, 1406, 1409, 1411,
  1413, 1416, 1418, 1421, 1423, 1426, 1428, 1430, 1433, 1435, 1437, 1440, 1442,
  1445, 1447, 1449, 1452, 1454, 1456, 1459, 1461, 1463, 1466, 1468, 1470, 1472,
  1475, 1477, 1479, 1482, 1484, 1486, 1488, 1491, 1493, 1495, 1497, 1500, 1502,
  1504, 1506, 1509, 1511, 1513, 1515, 1517, 1520, 1522, 1524, 1526, 1528, 1530,
  1533, 1535, 1537, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1556, 1558,
  1560, 1562, 1564, 1567, 1569, 1571, 1573, 1575, 1577, 1579, 1581, 1583, 1585,
  1587, 1589, 1591, 1593, 1595, 1597, 1599, 1601, 1603, 1605, 1607, 1609,
  /* index 401 - 899: -log((i+100)/1000) * 1000 */
  691, 689, 687, 685, 683, 681, 679, 677, 675, 673, 671, 669, 668, 666, 664,
  662, 660, 658, 656, 654, 652, 650, 648, 646, 644, 642, 641, 639, 637, 635,
  633, 631, 629, 627, 626, 624, 622, 620, 618, 616, 614, 612, 611, 609, 607,
  605, 603, 602, 600, 598, 596, 594, 592, 591, 589, 587, 585, 583, 582, 580,
  578, 576, 574, 573, 571, 569, 567, 566, 564, 562, 560, 559, 557, 555, 553,
  552, 550, 548, 546, 545, 543, 541, 540, 538, 536, 534, 533, 531, 529, 528,
  526, 524, 523, 521, 519, 518, 516, 514, 512, 511, 509, 508, 506, 504, 502,
  501, 499, 498, 496, 494, 493, 491, 489, 488, 486, 484, 483, 481, 480, 478,
  476, 475, 473, 472, 470, 468, 467, 465, 464, 462, 460, 459, 457, 456, 454,
  453, 451, 449, 448, 446, 445, 443, 442, 440, 438, 437, 435, 434, 432, 431,
  429, 428, 426, 425, 423, 422, 420, 419, 417, 416, 414, 412, 411, 410, 408,
  406, 405, 404, 402, 400, 399, 398, 396, 394, 393, 392, 390, 389, 387, 386,
  384, 383, 381, 380, 378, 377, 375, 374, 372, 371, 370, 368, 367, 365, 364,
  362, 361, 360, 358, 357, 355, 354, 352, 351, 350, 348, 347, 345, 344, 342,
  341, 340, 338, 337, 336, 334, 333, 331, 330, 328, 327, 326, 324, 323, 322,
  320, 319, 318, 316, 315, 313, 312, 311, 309, 308, 306, 305, 304, 302, 301,
  300, 298, 297, 296, 294, 293, 292, 290, 289, 288, 286, 285, 284, 282, 281,
  280, 278, 277, 276, 274, 273, 272, 270, 269, 268, 267, 265, 264, 263, 261,
  260, 259, 258, 256, 255, 254, 252, 251, 250, 248, 247, 246, 245, 243, 242,
  241, 240, 238, 237, 236, 234, 233, 232, 231, 229, 228, 227, 226, 224, 223,
  222, 221, 219, 218, 217, 216, 214, 213, 212, 211, 210, 208, 207, 206, 205,
  203, 202, 201, 200, 198, 197, 196, 195, 194, 192, 191, 190, 189, 188, 186,
  185, 184, 183, 182, 180, 179, 178, 177, 176, 174, 173, 172, 171, 170, 168,
  167, 166, 165, 164, 162, 161, 160, 159, 158, 157, 156, 154, 153, 152, 151,
  150, 148, 147, 146, 145, 144, 143, 142, 140, 139, 138, 137, 136, 135, 134,
  132, 131, 130, 129, 128, 127, 126, 124, 123, 122, 121, 120, 119, 118, 116,
  115, 114, 113, 112, 111, 110, 109, 108, 106, 105, 104, 103, 102, 101, 100,
  99, 98, 97, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 84, 83, 82, 81, 80, 79,
  78, 77, 76, 75, 74, 73, 72, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59,
  58, 57, 56, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39,
  38, 37, 36, 35, 34, 33, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,
  18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
};

/*
 * Internal ln() function that does not check for specials, zero or one.
 * Relative error: abs(result - log(a)) < 0.1 * 10**-prec * abs(log(a))
 */
static void
_mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
         uint32_t *status)
{
    mpd_context_t varcontext, maxcontext;
    mpd_t *z = (mpd_t *) result;
    MPD_NEW_STATIC(v,0,0,0,0);
    MPD_NEW_STATIC(vtmp,0,0,0,0);
    MPD_NEW_STATIC(tmp,0,0,0,0);
    mpd_ssize_t klist[MPD_MAX_PREC_LOG2];
    mpd_ssize_t maxprec, shift, t;
    mpd_ssize_t a_digits, a_exp;
    mpd_uint_t dummy, x;
    int i;

    assert(!mpd_isspecial(a) && !mpd_iszerocoeff(a));

    /*
     * We are calculating ln(a) = ln(v * 10^t) = ln(v) + t*ln(10),
     * where 0.5 < v <= 5.
     */
    if (!mpd_qcopy(&v, a, status)) {
        mpd_seterror(result, MPD_Malloc_error, status);
        goto finish;
    }

    /* Initial approximation: we have at least one non-zero digit */
    _mpd_get_msdigits(&dummy, &x, &v, 3);
    if (x < 10) x *= 10;
    if (x < 100) x *= 10;
    x -= 100;

    /* a may equal z */
    a_digits = a->digits;
    a_exp = a->exp;

    mpd_minalloc(z);
    mpd_clear_flags(z);
    z->data[0] = lnapprox[x];
    z->len = 1;
    z->exp = -3;
    mpd_setdigits(z);

    if (x <= 400) {
        /* Reduce the input operand to 1.00 <= v <= 5.00. Let y = x + 100,
         * so 100 <= y <= 500. Since y contains the most significant digits
         * of v, y/100 <= v < (y+1)/100 and abs(z - log(v)) < 10**-2. */
        v.exp = -(a_digits - 1);
        t = a_exp + a_digits - 1;
    }
    else {
        /* Reduce the input operand to 0.500 < v <= 0.999. Let y = x + 100,
         * so 500 < y <= 999. Since y contains the most significant digits
         * of v, y/1000 <= v < (y+1)/1000 and abs(z - log(v)) < 10**-2. */
        v.exp = -a_digits;
        t = a_exp + a_digits;
        mpd_set_negative(z);
    }

    mpd_maxcontext(&maxcontext);
    mpd_maxcontext(&varcontext);
    varcontext.round = MPD_ROUND_TRUNC;

    maxprec = ctx->prec + 2;
    if (t == 0 && (x <= 15 || x >= 800)) {
        /* 0.900 <= v <= 1.15: Estimate the magnitude of the logarithm.
         * If ln(v) will underflow, skip the loop. Otherwise, adjust the
         * precision upwards in order to obtain a sufficient number of
         * significant digits.
         *
         *   Case v > 1:
         *      abs((v-1)/10) < abs((v-1)/v) < abs(ln(v)) < abs(v-1)
         *   Case v < 1:
         *      abs(v-1) < abs(ln(v)) < abs((v-1)/v) < abs((v-1)*10)
         */
        int cmp = _mpd_cmp(&v, &one);

        /* Upper bound (assume v > 1): abs(v-1), unrounded */
        _mpd_qsub(&tmp, &v, &one, &maxcontext, &maxcontext.status);
        if (maxcontext.status & MPD_Errors) {
            mpd_seterror(result, MPD_Malloc_error, status);
            goto finish;
        }

        if (cmp < 0) {
            /* v < 1: abs((v-1)*10) */
            tmp.exp += 1;
        }
        if (mpd_adjexp(&tmp) < mpd_etiny(ctx)) {
            /* The upper bound is less than etiny: Underflow to zero */
            _settriple(result, (cmp<0), 1, mpd_etiny(ctx)-1);
            goto finish;
        }
        /* Lower bound: abs((v-1)/10) or abs(v-1) */
        tmp.exp -= 1;
        if (mpd_adjexp(&tmp) < 0) {
            /* Absolute error of the loop: abs(z - log(v)) < 10**-p. If
             * p = ctx->prec+2-adjexp(lower), then the relative error of
             * the result is (using 10**adjexp(x) <= abs(x)):
             *
             *   abs(z - log(v)) / abs(log(v)) < 10**-p / abs(log(v))
             *                                 <= 10**(-ctx->prec-2)
             */
            maxprec = maxprec - mpd_adjexp(&tmp);
        }
    }

    i = ln_schedule_prec(klist, maxprec, 2);
    for (; i >= 0; i--) {
        varcontext.prec = 2*klist[i]+3;
        z->flags ^= MPD_NEG;
        _mpd_qexp(&tmp, z, &varcontext, status);
        z->flags ^= MPD_NEG;

        if (v.digits > varcontext.prec) {
            shift = v.digits - varcontext.prec;
            mpd_qshiftr(&vtmp, &v, shift, status);
            vtmp.exp += shift;
            mpd_qmul(&tmp, &vtmp, &tmp, &varcontext, status);
        }
        else {
            mpd_qmul(&tmp, &v, &tmp, &varcontext, status);
        }

        mpd_qsub(&tmp, &tmp, &one, &maxcontext, status);
        mpd_qadd(z, z, &tmp, &maxcontext, status);
        if (mpd_isspecial(z)) {
            break;
        }
    }

    /*
     * Case t == 0:
     *    t * log(10) == 0, the result does not change and the analysis
     *    above applies. If v < 0.900 or v > 1.15, the relative error is
     *    less than 10**(-ctx.prec-1).
     * Case t != 0:
     *      z := approx(log(v))
     *      y := approx(log(10))
     *      p := maxprec = ctx->prec + 2
     *   Absolute errors:
     *      1) abs(z - log(v)) < 10**-p
     *      2) abs(y - log(10)) < 10**-p
     *   The multiplication is exact, so:
     *      3) abs(t*y - t*log(10)) < t*10**-p
     *   The sum is exact, so:
     *      4) abs((z + t*y) - (log(v) + t*log(10))) < (abs(t) + 1) * 10**-p
     *   Bounds for log(v) and log(10):
     *      5) -7/10 < log(v) < 17/10
     *      6) 23/10 < log(10) < 24/10
     *   Using 4), 5), 6) and t != 0, the relative error is:
     *
     *      7) relerr < ((abs(t) + 1)*10**-p) / abs(log(v) + t*log(10))
     *                < 0.5 * 10**(-p + 1) = 0.5 * 10**(-ctx->prec-1)
     */
    mpd_qln10(&v, maxprec+1, status);
    mpd_qmul_ssize(&tmp, &v, t, &maxcontext, status);
    mpd_qadd(result, &tmp, z, &maxcontext, status);


finish:
    *status |= (MPD_Inexact|MPD_Rounded);
    mpd_del(&v);
    mpd_del(&vtmp);
    mpd_del(&tmp);
}

/* ln(a) */
void
mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
        uint32_t *status)
{
    mpd_context_t workctx;
    mpd_ssize_t adjexp, t;

    if (mpd_isspecial(a)) {
        if (mpd_qcheck_nan(result, a, ctx, status)) {
            return;
        }
        if (mpd_isnegative(a)) {
            mpd_seterror(result, MPD_Invalid_operation, status);
            return;
        }
        mpd_setspecial(result, MPD_POS, MPD_INF);
        return;
    }
    if (mpd_iszerocoeff(a)) {
        mpd_setspecial(result, MPD_NEG, MPD_INF);
        return;
    }
    if (mpd_isnegative(a)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }
    if (_mpd_cmp(a, &one) == 0) {
        _settriple(result, MPD_POS, 0, 0);
        return;
    }
    /*
     * Check if the result will overflow (0 < x, x != 1):
     *   1) log10(x) < 0 iff adjexp(x) < 0
     *   2) 0 < x /\ x <= y ==> adjexp(x) <= adjexp(y)
     *   3) 0 < x /\ x != 1 ==> 2 * abs(log10(x)) < abs(log(x))
     *   4) adjexp(x) <= log10(x) < adjexp(x) + 1
     *
     * Case adjexp(x) >= 0:
     *   5) 2 * adjexp(x) < abs(log(x))
     *   Case adjexp(x) > 0:
     *     6) adjexp(2 * adjexp(x)) <= adjexp(abs(log(x)))
     *   Case adjexp(x) == 0:
     *     mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered)
     *
     * Case adjexp(x) < 0:
     *   7) 2 * (-adjexp(x) - 1) < abs(log(x))
     *   Case adjexp(x) < -1:
     *     8) adjexp(2 * (-adjexp(x) - 1)) <= adjexp(abs(log(x)))
     *   Case adjexp(x) == -1:
     *     mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered)
     */
    adjexp = mpd_adjexp(a);
    t = (adjexp < 0) ? -adjexp-1 : adjexp;
    t *= 2;
    if (mpd_exp_digits(t)-1 > ctx->emax) {
        *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded;
        mpd_setspecial(result, (adjexp<0), MPD_INF);
        return;
    }

    workctx = *ctx;
    workctx.round = MPD_ROUND_HALF_EVEN;

    if (ctx->allcr) {
        MPD_NEW_STATIC(t1, 0,0,0,0);
        MPD_NEW_STATIC(t2, 0,0,0,0);
        MPD_NEW_STATIC(ulp, 0,0,0,0);
        MPD_NEW_STATIC(aa, 0,0,0,0);
        mpd_ssize_t prec;

        if (result == a) {
            if (!mpd_qcopy(&aa, a, status)) {
                mpd_seterror(result, MPD_Malloc_error, status);
                return;
            }
            a = &aa;
        }

        workctx.clamp = 0;
        prec = ctx->prec + 3;
        while (1) {
            workctx.prec = prec;
            _mpd_qln(result, a, &workctx, status);
            _ssettriple(&ulp, MPD_POS, 1,
                        result->exp + result->digits-workctx.prec);

            workctx.prec = ctx->prec;
            mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status);
            mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status);
            if (mpd_isspecial(result) || mpd_iszerocoeff(result) ||
                mpd_qcmp(&t1, &t2, status) == 0) {
                workctx.clamp = ctx->clamp;
                mpd_check_underflow(result, &workctx, status);
                mpd_qfinalize(result, &workctx, status);
                break;
            }
            prec += MPD_RDIGITS;
        }
        mpd_del(&t1);
        mpd_del(&t2);
        mpd_del(&ulp);
        mpd_del(&aa);
    }
    else {
        _mpd_qln(result, a, &workctx, status);
        mpd_check_underflow(result, &workctx, status);
        mpd_qfinalize(result, &workctx, status);
    }
}

/*
 * Internal log10() function that does not check for specials, zero or one.
 * Case SKIP_FINALIZE:
 *   Relative error: abs(result - log10(a)) < 0.1 * 10**-prec * abs(log10(a))
 * Case DO_FINALIZE:
 *   Ulp error: abs(result - log10(a)) < ulp(log10(a))
 */
enum {SKIP_FINALIZE, DO_FINALIZE};
static void
_mpd_qlog10(int action, mpd_t *result, const mpd_t *a,
            const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t workctx;
    MPD_NEW_STATIC(ln10,0,0,0,0);

    mpd_maxcontext(&workctx);
    workctx.prec = ctx->prec + 3;
    /* relative error: 0.1 * 10**(-p-3). The specific underflow shortcut
     * in _mpd_qln() does not change the final result. */
    _mpd_qln(result, a, &workctx, status);
    /* relative error: 5 * 10**(-p-3) */
    mpd_qln10(&ln10, workctx.prec, status);

    if (action == DO_FINALIZE) {
        workctx = *ctx;
        workctx.round = MPD_ROUND_HALF_EVEN;
    }
    /* SKIP_FINALIZE: relative error: 5 * 10**(-p-3) */
    _mpd_qdiv(NO_IDEAL_EXP, result, result, &ln10, &workctx, status);

    mpd_del(&ln10);
}

/* log10(a) */
void
mpd_qlog10(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
           uint32_t *status)
{
    mpd_context_t workctx;
    mpd_ssize_t adjexp, t;

    workctx = *ctx;
    workctx.round = MPD_ROUND_HALF_EVEN;

    if (mpd_isspecial(a)) {
        if (mpd_qcheck_nan(result, a, ctx, status)) {
            return;
        }
        if (mpd_isnegative(a)) {
            mpd_seterror(result, MPD_Invalid_operation, status);
            return;
        }
        mpd_setspecial(result, MPD_POS, MPD_INF);
        return;
    }
    if (mpd_iszerocoeff(a)) {
        mpd_setspecial(result, MPD_NEG, MPD_INF);
        return;
    }
    if (mpd_isnegative(a)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }
    if (mpd_coeff_ispow10(a)) {
        uint8_t sign = 0;
        adjexp = mpd_adjexp(a);
        if (adjexp < 0) {
            sign = 1;
            adjexp = -adjexp;
        }
        _settriple(result, sign, adjexp, 0);
        mpd_qfinalize(result, &workctx, status);
        return;
    }
    /*
     * Check if the result will overflow (0 < x, x != 1):
     *   1) log10(x) < 0 iff adjexp(x) < 0
     *   2) 0 < x /\ x <= y ==> adjexp(x) <= adjexp(y)
     *   3) adjexp(x) <= log10(x) < adjexp(x) + 1
     *
     * Case adjexp(x) >= 0:
     *   4) adjexp(x) <= abs(log10(x))
     *   Case adjexp(x) > 0:
     *     5) adjexp(adjexp(x)) <= adjexp(abs(log10(x)))
     *   Case adjexp(x) == 0:
     *     mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered)
     *
     * Case adjexp(x) < 0:
     *   6) -adjexp(x) - 1 < abs(log10(x))
     *   Case adjexp(x) < -1:
     *     7) adjexp(-adjexp(x) - 1) <= adjexp(abs(log(x)))
     *   Case adjexp(x) == -1:
     *     mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered)
     */
    adjexp = mpd_adjexp(a);
    t = (adjexp < 0) ? -adjexp-1 : adjexp;
    if (mpd_exp_digits(t)-1 > ctx->emax) {
        *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded;
        mpd_setspecial(result, (adjexp<0), MPD_INF);
        return;
    }

    if (ctx->allcr) {
        MPD_NEW_STATIC(t1, 0,0,0,0);
        MPD_NEW_STATIC(t2, 0,0,0,0);
        MPD_NEW_STATIC(ulp, 0,0,0,0);
        MPD_NEW_STATIC(aa, 0,0,0,0);
        mpd_ssize_t prec;

        if (result == a) {
            if (!mpd_qcopy(&aa, a, status)) {
                mpd_seterror(result, MPD_Malloc_error, status);
                return;
            }
            a = &aa;
        }

        workctx.clamp = 0;
        prec = ctx->prec + 3;
        while (1) {
            workctx.prec = prec;
            _mpd_qlog10(SKIP_FINALIZE, result, a, &workctx, status);
            _ssettriple(&ulp, MPD_POS, 1,
                        result->exp + result->digits-workctx.prec);

            workctx.prec = ctx->prec;
            mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status);
            mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status);
            if (mpd_isspecial(result) || mpd_iszerocoeff(result) ||
                mpd_qcmp(&t1, &t2, status) == 0) {
                workctx.clamp = ctx->clamp;
                mpd_check_underflow(result, &workctx, status);
                mpd_qfinalize(result, &workctx, status);
                break;
            }
            prec += MPD_RDIGITS;
        }
        mpd_del(&t1);
        mpd_del(&t2);
        mpd_del(&ulp);
        mpd_del(&aa);
    }
    else {
        _mpd_qlog10(DO_FINALIZE, result, a, &workctx, status);
        mpd_check_underflow(result, &workctx, status);
    }
}

/*
 * Maximum of the two operands. Attention: If one operand is a quiet NaN and the
 * other is numeric, the numeric operand is returned. This may not be what one
 * expects.
 */
void
mpd_qmax(mpd_t *result, const mpd_t *a, const mpd_t *b,
         const mpd_context_t *ctx, uint32_t *status)
{
    int c;

    if (mpd_isqnan(a) && !mpd_isnan(b)) {
        mpd_qcopy(result, b, status);
    }
    else if (mpd_isqnan(b) && !mpd_isnan(a)) {
        mpd_qcopy(result, a, status);
    }
    else if (mpd_qcheck_nans(result, a, b, ctx, status)) {
        return;
    }
    else {
        c = _mpd_cmp(a, b);
        if (c == 0) {
            c = _mpd_cmp_numequal(a, b);
        }

        if (c < 0) {
            mpd_qcopy(result, b, status);
        }
        else {
            mpd_qcopy(result, a, status);
        }
    }

    mpd_qfinalize(result, ctx, status);
}

/*
 * Maximum magnitude: Same as mpd_max(), but compares the operands with their
 * sign ignored.
 */
void
mpd_qmax_mag(mpd_t *result, const mpd_t *a, const mpd_t *b,
             const mpd_context_t *ctx, uint32_t *status)
{
    int c;

    if (mpd_isqnan(a) && !mpd_isnan(b)) {
        mpd_qcopy(result, b, status);
    }
    else if (mpd_isqnan(b) && !mpd_isnan(a)) {
        mpd_qcopy(result, a, status);
    }
    else if (mpd_qcheck_nans(result, a, b, ctx, status)) {
        return;
    }
    else {
        c = _mpd_cmp_abs(a, b);
        if (c == 0) {
            c = _mpd_cmp_numequal(a, b);
        }

        if (c < 0) {
            mpd_qcopy(result, b, status);
        }
        else {
            mpd_qcopy(result, a, status);
        }
    }

    mpd_qfinalize(result, ctx, status);
}

/*
 * Minimum of the two operands. Attention: If one operand is a quiet NaN and the
 * other is numeric, the numeric operand is returned. This may not be what one
 * expects.
 */
void
mpd_qmin(mpd_t *result, const mpd_t *a, const mpd_t *b,
         const mpd_context_t *ctx, uint32_t *status)
{
    int c;

    if (mpd_isqnan(a) && !mpd_isnan(b)) {
        mpd_qcopy(result, b, status);
    }
    else if (mpd_isqnan(b) && !mpd_isnan(a)) {
        mpd_qcopy(result, a, status);
    }
    else if (mpd_qcheck_nans(result, a, b, ctx, status)) {
        return;
    }
    else {
        c = _mpd_cmp(a, b);
        if (c == 0) {
            c = _mpd_cmp_numequal(a, b);
        }

        if (c < 0) {
            mpd_qcopy(result, a, status);
        }
        else {
            mpd_qcopy(result, b, status);
        }
    }

    mpd_qfinalize(result, ctx, status);
}

/*
 * Minimum magnitude: Same as mpd_min(), but compares the operands with their
 * sign ignored.
 */
void
mpd_qmin_mag(mpd_t *result, const mpd_t *a, const mpd_t *b,
             const mpd_context_t *ctx, uint32_t *status)
{
    int c;

    if (mpd_isqnan(a) && !mpd_isnan(b)) {
        mpd_qcopy(result, b, status);
    }
    else if (mpd_isqnan(b) && !mpd_isnan(a)) {
        mpd_qcopy(result, a, status);
    }
    else if (mpd_qcheck_nans(result, a, b, ctx, status)) {
        return;
    }
    else {
        c = _mpd_cmp_abs(a, b);
        if (c == 0) {
            c = _mpd_cmp_numequal(a, b);
        }

        if (c < 0) {
            mpd_qcopy(result, a, status);
        }
        else {
            mpd_qcopy(result, b, status);
        }
    }

    mpd_qfinalize(result, ctx, status);
}

/* Minimum space needed for the result array in _karatsuba_rec(). */
static inline mpd_size_t
_kmul_resultsize(mpd_size_t la, mpd_size_t lb)
{
    mpd_size_t n, m;

    n = add_size_t(la, lb);
    n = add_size_t(n, 1);

    m = (la+1)/2 + 1;
    m = mul_size_t(m, 3);

    return (m > n) ? m : n;
}

/* Work space needed in _karatsuba_rec(). lim >= 4 */
static inline mpd_size_t
_kmul_worksize(mpd_size_t n, mpd_size_t lim)
{
    mpd_size_t m;

    if (n <= lim) {
        return 0;
    }

    m = (n+1)/2 + 1;

    return add_size_t(mul_size_t(m, 2), _kmul_worksize(m, lim));
}


#define MPD_KARATSUBA_BASECASE 16  /* must be >= 4 */

/*
 * Add the product of a and b to c.
 * c must be _kmul_resultsize(la, lb) in size.
 * w is used as a work array and must be _kmul_worksize(a, lim) in size.
 * Roman E. Maeder, Storage Allocation for the Karatsuba Integer Multiplication
 * Algorithm. In "Design and implementation of symbolic computation systems",
 * Springer, 1993, ISBN 354057235X, 9783540572350.
 */
static void
_karatsuba_rec(mpd_uint_t *c, const mpd_uint_t *a, const mpd_uint_t *b,
               mpd_uint_t *w, mpd_size_t la, mpd_size_t lb)
{
    mpd_size_t m, lt;

    assert(la >= lb && lb > 0);
    assert(la <= MPD_KARATSUBA_BASECASE || w != NULL);

    if (la <= MPD_KARATSUBA_BASECASE) {
        _mpd_basemul(c, a, b, la, lb);
        return;
    }

    m = (la+1)/2;  /* ceil(la/2) */

    /* lb <= m < la */
    if (lb <= m) {

        /* lb can now be larger than la-m */
        if (lb > la-m) {
            lt = lb + lb + 1;       /* space needed for result array */
            mpd_uint_zero(w, lt);   /* clear result array */
            _karatsuba_rec(w, b, a+m, w+lt, lb, la-m); /* b*ah */
        }
        else {
            lt = (la-m) + (la-m) + 1;  /* space needed for result array */
            mpd_uint_zero(w, lt);      /* clear result array */
            _karatsuba_rec(w, a+m, b, w+lt, la-m, lb); /* ah*b */
        }
        _mpd_baseaddto(c+m, w, (la-m)+lb);      /* add ah*b*B**m */

        lt = m + m + 1;         /* space needed for the result array */
        mpd_uint_zero(w, lt);   /* clear result array */
        _karatsuba_rec(w, a, b, w+lt, m, lb);  /* al*b */
        _mpd_baseaddto(c, w, m+lb);    /* add al*b */

        return;
    }

    /* la >= lb > m */
    memcpy(w, a, m * sizeof *w);
    w[m] = 0;
    _mpd_baseaddto(w, a+m, la-m);

    memcpy(w+(m+1), b, m * sizeof *w);
    w[m+1+m] = 0;
    _mpd_baseaddto(w+(m+1), b+m, lb-m);

    _karatsuba_rec(c+m, w, w+(m+1), w+2*(m+1), m+1, m+1);

    lt = (la-m) + (la-m) + 1;
    mpd_uint_zero(w, lt);

    _karatsuba_rec(w, a+m, b+m, w+lt, la-m, lb-m);

    _mpd_baseaddto(c+2*m, w, (la-m) + (lb-m));
    _mpd_basesubfrom(c+m, w, (la-m) + (lb-m));

    lt = m + m + 1;
    mpd_uint_zero(w, lt);

    _karatsuba_rec(w, a, b, w+lt, m, m);
    _mpd_baseaddto(c, w, m+m);
    _mpd_basesubfrom(c+m, w, m+m);

    return;
}

/*
 * Multiply u and v, using Karatsuba multiplication. Returns a pointer
 * to the result or NULL in case of failure (malloc error).
 * Conditions: ulen >= vlen, ulen >= 4
 */
static mpd_uint_t *
_mpd_kmul(const mpd_uint_t *u, const mpd_uint_t *v,
          mpd_size_t ulen, mpd_size_t vlen,
          mpd_size_t *rsize)
{
    mpd_uint_t *result = NULL, *w = NULL;
    mpd_size_t m;

    assert(ulen >= 4);
    assert(ulen >= vlen);

    *rsize = _kmul_resultsize(ulen, vlen);
    if ((result = mpd_calloc(*rsize, sizeof *result)) == NULL) {
        return NULL;
    }

    m = _kmul_worksize(ulen, MPD_KARATSUBA_BASECASE);
    if (m && ((w = mpd_calloc(m, sizeof *w)) == NULL)) {
        mpd_free(result);
        return NULL;
    }

    _karatsuba_rec(result, u, v, w, ulen, vlen);


    if (w) mpd_free(w);
    return result;
}


/*
 * Determine the minimum length for the number theoretic transform. Valid
 * transform lengths are 2**n or 3*2**n, where 2**n <= MPD_MAXTRANSFORM_2N.
 * The function finds the shortest length m such that rsize <= m.
 */
static inline mpd_size_t
_mpd_get_transform_len(mpd_size_t rsize)
{
    mpd_size_t log2rsize;
    mpd_size_t x, step;

    assert(rsize >= 4);
    log2rsize = mpd_bsr(rsize);

    if (rsize <= 1024) {
        /* 2**n is faster in this range. */
        x = ((mpd_size_t)1)<<log2rsize;
        return (rsize == x) ? x : x<<1;
    }
    else if (rsize <= MPD_MAXTRANSFORM_2N) {
        x = ((mpd_size_t)1)<<log2rsize;
        if (rsize == x) return x;
        step = x>>1;
        x += step;
        return (rsize <= x) ? x : x + step;
    }
    else if (rsize <= MPD_MAXTRANSFORM_2N+MPD_MAXTRANSFORM_2N/2) {
        return MPD_MAXTRANSFORM_2N+MPD_MAXTRANSFORM_2N/2;
    }
    else if (rsize <= 3*MPD_MAXTRANSFORM_2N) {
        return 3*MPD_MAXTRANSFORM_2N;
    }
    else {
        return MPD_SIZE_MAX;
    }
}

#ifdef PPRO
#ifndef _MSC_VER
static inline unsigned short
_mpd_get_control87(void)
{
    unsigned short cw;

    __asm__ __volatile__ ("fnstcw %0" : "=m" (cw));
    return cw;
}

static inline void
_mpd_set_control87(unsigned short cw)
{
    __asm__ __volatile__ ("fldcw %0" : : "m" (cw));
}
#endif

static unsigned int
mpd_set_fenv(void)
{
    unsigned int cw;
#ifdef _MSC_VER
    unsigned int flags =
        _EM_INVALID|_EM_DENORMAL|_EM_ZERODIVIDE|_EM_OVERFLOW|
        _EM_UNDERFLOW|_EM_INEXACT|_RC_CHOP|_PC_64;
    unsigned int mask = _MCW_EM|_MCW_RC|_MCW_PC;
    unsigned int dummy;

    __control87_2(0, 0, &cw, NULL);
    __control87_2(flags, mask, &dummy, NULL);
#else
    cw = _mpd_get_control87();
    _mpd_set_control87(cw|0xF3F);
#endif
    return cw;
}

static void
mpd_restore_fenv(unsigned int cw)
{
#ifdef _MSC_VER
    unsigned int mask = _MCW_EM|_MCW_RC|_MCW_PC;
    unsigned int dummy;

    __control87_2(cw, mask, &dummy, NULL);
#else
    _mpd_set_control87((unsigned short)cw);
#endif
}
#endif /* PPRO */

/*
 * Multiply u and v, using the fast number theoretic transform. Returns
 * a pointer to the result or NULL in case of failure (malloc error).
 */
static mpd_uint_t *
_mpd_fntmul(const mpd_uint_t *u, const mpd_uint_t *v,
            mpd_size_t ulen, mpd_size_t vlen,
            mpd_size_t *rsize)
{
    mpd_uint_t *c1 = NULL, *c2 = NULL, *c3 = NULL, *vtmp = NULL;
    mpd_size_t n;

#ifdef PPRO
    unsigned int cw;
    cw = mpd_set_fenv();
#endif

    *rsize = add_size_t(ulen, vlen);
    if ((n = _mpd_get_transform_len(*rsize)) == MPD_SIZE_MAX) {
        goto malloc_error;
    }

    if ((c1 = mpd_calloc(n, sizeof *c1)) == NULL) {
        goto malloc_error;
    }
    if ((c2 = mpd_calloc(n, sizeof *c2)) == NULL) {
        goto malloc_error;
    }
    if ((c3 = mpd_calloc(n, sizeof *c3)) == NULL) {
        goto malloc_error;
    }

    memcpy(c1, u, ulen * (sizeof *c1));
    memcpy(c2, u, ulen * (sizeof *c2));
    memcpy(c3, u, ulen * (sizeof *c3));

    if (u == v) {
        if (!fnt_autoconvolute(c1, n, P1) ||
            !fnt_autoconvolute(c2, n, P2) ||
            !fnt_autoconvolute(c3, n, P3)) {
            goto malloc_error;
        }
    }
    else {
        if ((vtmp = mpd_calloc(n, sizeof *vtmp)) == NULL) {
            goto malloc_error;
        }

        memcpy(vtmp, v, vlen * (sizeof *vtmp));
        if (!fnt_convolute(c1, vtmp, n, P1)) {
            mpd_free(vtmp);
            goto malloc_error;
        }

        memcpy(vtmp, v, vlen * (sizeof *vtmp));
        mpd_uint_zero(vtmp+vlen, n-vlen);
        if (!fnt_convolute(c2, vtmp, n, P2)) {
            mpd_free(vtmp);
            goto malloc_error;
        }

        memcpy(vtmp, v, vlen * (sizeof *vtmp));
        mpd_uint_zero(vtmp+vlen, n-vlen);
        if (!fnt_convolute(c3, vtmp, n, P3)) {
            mpd_free(vtmp);
            goto malloc_error;
        }

        mpd_free(vtmp);
    }

    crt3(c1, c2, c3, *rsize);

out:
#ifdef PPRO
    mpd_restore_fenv(cw);
#endif
    if (c2) mpd_free(c2);
    if (c3) mpd_free(c3);
    return c1;

malloc_error:
    if (c1) mpd_free(c1);
    c1 = NULL;
    goto out;
}


/*
 * Karatsuba multiplication with FNT/basemul as the base case.
 */
static int
_karatsuba_rec_fnt(mpd_uint_t *c, const mpd_uint_t *a, const mpd_uint_t *b,
                   mpd_uint_t *w, mpd_size_t la, mpd_size_t lb)
{
    mpd_size_t m, lt;

    assert(la >= lb && lb > 0);
    assert(la <= 3*(MPD_MAXTRANSFORM_2N/2) || w != NULL);

    if (la <= 3*(MPD_MAXTRANSFORM_2N/2)) {

        if (lb <= 192) {
            _mpd_basemul(c, b, a, lb, la);
        }
        else {
            mpd_uint_t *result;
            mpd_size_t dummy;

            if ((result = _mpd_fntmul(a, b, la, lb, &dummy)) == NULL) {
                return 0;
            }
            memcpy(c, result, (la+lb) * (sizeof *result));
            mpd_free(result);
        }
        return 1;
    }

    m = (la+1)/2;  /* ceil(la/2) */

    /* lb <= m < la */
    if (lb <= m) {

        /* lb can now be larger than la-m */
        if (lb > la-m) {
            lt = lb + lb + 1;       /* space needed for result array */
            mpd_uint_zero(w, lt);   /* clear result array */
            if (!_karatsuba_rec_fnt(w, b, a+m, w+lt, lb, la-m)) { /* b*ah */
                return 0; /* GCOV_UNLIKELY */
            }
        }
        else {
            lt = (la-m) + (la-m) + 1;  /* space needed for result array */
            mpd_uint_zero(w, lt);      /* clear result array */
            if (!_karatsuba_rec_fnt(w, a+m, b, w+lt, la-m, lb)) { /* ah*b */
                return 0; /* GCOV_UNLIKELY */
            }
        }
        _mpd_baseaddto(c+m, w, (la-m)+lb); /* add ah*b*B**m */

        lt = m + m + 1;         /* space needed for the result array */
        mpd_uint_zero(w, lt);   /* clear result array */
        if (!_karatsuba_rec_fnt(w, a, b, w+lt, m, lb)) {  /* al*b */
            return 0; /* GCOV_UNLIKELY */
        }
        _mpd_baseaddto(c, w, m+lb);       /* add al*b */

        return 1;
    }

    /* la >= lb > m */
    memcpy(w, a, m * sizeof *w);
    w[m] = 0;
    _mpd_baseaddto(w, a+m, la-m);

    memcpy(w+(m+1), b, m * sizeof *w);
    w[m+1+m] = 0;
    _mpd_baseaddto(w+(m+1), b+m, lb-m);

    if (!_karatsuba_rec_fnt(c+m, w, w+(m+1), w+2*(m+1), m+1, m+1)) {
        return 0; /* GCOV_UNLIKELY */
    }

    lt = (la-m) + (la-m) + 1;
    mpd_uint_zero(w, lt);

    if (!_karatsuba_rec_fnt(w, a+m, b+m, w+lt, la-m, lb-m)) {
        return 0; /* GCOV_UNLIKELY */
    }

    _mpd_baseaddto(c+2*m, w, (la-m) + (lb-m));
    _mpd_basesubfrom(c+m, w, (la-m) + (lb-m));

    lt = m + m + 1;
    mpd_uint_zero(w, lt);

    if (!_karatsuba_rec_fnt(w, a, b, w+lt, m, m)) {
        return 0; /* GCOV_UNLIKELY */
    }
    _mpd_baseaddto(c, w, m+m);
    _mpd_basesubfrom(c+m, w, m+m);

    return 1;
}

/*
 * Multiply u and v, using Karatsuba multiplication with the FNT as the
 * base case. Returns a pointer to the result or NULL in case of failure
 * (malloc error). Conditions: ulen >= vlen, ulen >= 4.
 */
static mpd_uint_t *
_mpd_kmul_fnt(const mpd_uint_t *u, const mpd_uint_t *v,
              mpd_size_t ulen, mpd_size_t vlen,
              mpd_size_t *rsize)
{
    mpd_uint_t *result = NULL, *w = NULL;
    mpd_size_t m;

    assert(ulen >= 4);
    assert(ulen >= vlen);

    *rsize = _kmul_resultsize(ulen, vlen);
    if ((result = mpd_calloc(*rsize, sizeof *result)) == NULL) {
        return NULL;
    }

    m = _kmul_worksize(ulen, 3*(MPD_MAXTRANSFORM_2N/2));
    if (m && ((w = mpd_calloc(m, sizeof *w)) == NULL)) {
        mpd_free(result); /* GCOV_UNLIKELY */
        return NULL; /* GCOV_UNLIKELY */
    }

    if (!_karatsuba_rec_fnt(result, u, v, w, ulen, vlen)) {
        mpd_free(result);
        result = NULL;
    }


    if (w) mpd_free(w);
    return result;
}


/* Deal with the special cases of multiplying infinities. */
static void
_mpd_qmul_inf(mpd_t *result, const mpd_t *a, const mpd_t *b, uint32_t *status)
{
    if (mpd_isinfinite(a)) {
        if (mpd_iszero(b)) {
            mpd_seterror(result, MPD_Invalid_operation, status);
        }
        else {
            mpd_setspecial(result, mpd_sign(a)^mpd_sign(b), MPD_INF);
        }
        return;
    }
    assert(mpd_isinfinite(b));
    if (mpd_iszero(a)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
    }
    else {
        mpd_setspecial(result, mpd_sign(a)^mpd_sign(b), MPD_INF);
    }
}

/*
 * Internal function: Multiply a and b. _mpd_qmul deals with specials but
 * does NOT finalize the result. This is for use in mpd_fma().
 */
static inline void
_mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b,
          const mpd_context_t *ctx, uint32_t *status)
{
    const mpd_t *big = a, *small = b;
    mpd_uint_t *rdata = NULL;
    mpd_uint_t rbuf[MPD_MINALLOC_MAX];
    mpd_size_t rsize, i;


    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
            return;
        }
        _mpd_qmul_inf(result, a, b, status);
        return;
    }

    if (small->len > big->len) {
        _mpd_ptrswap(&big, &small);
    }

    rsize = big->len + small->len;

    if (big->len == 1) {
        _mpd_singlemul(result->data, big->data[0], small->data[0]);
        goto finish;
    }
    if (rsize <= (mpd_size_t)MPD_MINALLOC_MAX) {
        if (big->len == 2) {
            _mpd_mul_2_le2(rbuf, big->data, small->data, small->len);
        }
        else {
            mpd_uint_zero(rbuf, rsize);
            if (small->len == 1) {
                _mpd_shortmul(rbuf, big->data, big->len, small->data[0]);
            }
            else {
                _mpd_basemul(rbuf, small->data, big->data, small->len, big->len);
            }
        }
        if (!mpd_qresize(result, rsize, status)) {
            return;
        }
        for(i = 0; i < rsize; i++) {
            result->data[i] = rbuf[i];
        }
        goto finish;
    }


    if (small->len <= 256) {
        rdata = mpd_calloc(rsize, sizeof *rdata);
        if (rdata != NULL) {
            if (small->len == 1) {
                _mpd_shortmul(rdata, big->data, big->len, small->data[0]);
            }
            else {
                _mpd_basemul(rdata, small->data, big->data, small->len, big->len);
            }
        }
    }
    else if (rsize <= 1024) {
        rdata = _mpd_kmul(big->data, small->data, big->len, small->len, &rsize);
    }
    else if (rsize <= 3*MPD_MAXTRANSFORM_2N) {
        rdata = _mpd_fntmul(big->data, small->data, big->len, small->len, &rsize);
    }
    else {
        rdata = _mpd_kmul_fnt(big->data, small->data, big->len, small->len, &rsize);
    }

    if (rdata == NULL) {
        mpd_seterror(result, MPD_Malloc_error, status);
        return;
    }

    if (mpd_isdynamic_data(result)) {
        mpd_free(result->data);
    }
    result->data = rdata;
    result->alloc = rsize;
    mpd_set_dynamic_data(result);


finish:
    mpd_set_flags(result, mpd_sign(a)^mpd_sign(b));
    result->exp = big->exp + small->exp;
    result->len = _mpd_real_size(result->data, rsize);
    /* resize to smaller cannot fail */
    mpd_qresize(result, result->len, status);
    mpd_setdigits(result);
}

/* Multiply a and b. */
void
mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b,
         const mpd_context_t *ctx, uint32_t *status)
{
    _mpd_qmul(result, a, b, ctx, status);
    mpd_qfinalize(result, ctx, status);
}

/* Multiply a and b. Set NaN/Invalid_operation if the result is inexact. */
static void
_mpd_qmul_exact(mpd_t *result, const mpd_t *a, const mpd_t *b,
                const mpd_context_t *ctx, uint32_t *status)
{
    uint32_t workstatus = 0;

    mpd_qmul(result, a, b, ctx, &workstatus);
    *status |= workstatus;
    if (workstatus & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
    }
}

/* Multiply decimal and mpd_ssize_t. */
void
mpd_qmul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b,
               const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qsset_ssize(&bb, b, &maxcontext, status);
    mpd_qmul(result, a, &bb, ctx, status);
    mpd_del(&bb);
}

/* Multiply decimal and mpd_uint_t. */
void
mpd_qmul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b,
              const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qsset_uint(&bb, b, &maxcontext, status);
    mpd_qmul(result, a, &bb, ctx, status);
    mpd_del(&bb);
}

void
mpd_qmul_i32(mpd_t *result, const mpd_t *a, int32_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qmul_ssize(result, a, b, ctx, status);
}

void
mpd_qmul_u32(mpd_t *result, const mpd_t *a, uint32_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qmul_uint(result, a, b, ctx, status);
}

#ifdef CONFIG_64
void
mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qmul_ssize(result, a, b, ctx, status);
}

void
mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_qmul_uint(result, a, b, ctx, status);
}
#elif !defined(LEGACY_COMPILER)
/* Multiply decimal and int64_t. */
void
mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qset_i64(&bb, b, &maxcontext, status);
    mpd_qmul(result, a, &bb, ctx, status);
    mpd_del(&bb);
}

/* Multiply decimal and uint64_t. */
void
mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b,
             const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(bb,0,0,0,0);

    mpd_maxcontext(&maxcontext);
    mpd_qset_u64(&bb, b, &maxcontext, status);
    mpd_qmul(result, a, &bb, ctx, status);
    mpd_del(&bb);
}
#endif

/* Like the minus operator. */
void
mpd_qminus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
           uint32_t *status)
{
    if (mpd_isspecial(a)) {
        if (mpd_qcheck_nan(result, a, ctx, status)) {
            return;
        }
    }

    if (mpd_iszero(a) && ctx->round != MPD_ROUND_FLOOR) {
        mpd_qcopy_abs(result, a, status);
    }
    else {
        mpd_qcopy_negate(result, a, status);
    }

    mpd_qfinalize(result, ctx, status);
}

/* Like the plus operator. */
void
mpd_qplus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
          uint32_t *status)
{
    if (mpd_isspecial(a)) {
        if (mpd_qcheck_nan(result, a, ctx, status)) {
            return;
        }
    }

    if (mpd_iszero(a) && ctx->round != MPD_ROUND_FLOOR) {
        mpd_qcopy_abs(result, a, status);
    }
    else {
        mpd_qcopy(result, a, status);
    }

    mpd_qfinalize(result, ctx, status);
}

/* The largest representable number that is smaller than the operand. */
void
mpd_qnext_minus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
                uint32_t *status)
{
    mpd_context_t workctx;
    MPD_NEW_CONST(tiny,MPD_POS,mpd_etiny(ctx)-1,1,1,1,1);

    if (mpd_isspecial(a)) {
        if (mpd_qcheck_nan(result, a, ctx, status)) {
            return;
        }

        assert(mpd_isinfinite(a));
        if (mpd_isnegative(a)) {
            mpd_qcopy(result, a, status);
            return;
        }
        else {
            mpd_clear_flags(result);
            mpd_qmaxcoeff(result, ctx, status);
            if (mpd_isnan(result)) {
                return;
            }
            result->exp = mpd_etop(ctx);
            return;
        }
    }

    mpd_workcontext(&workctx, ctx);
    workctx.round = MPD_ROUND_FLOOR;

    if (!mpd_qcopy(result, a, status)) {
        return;
    }

    mpd_qfinalize(result, &workctx, &workctx.status);
    if (workctx.status&(MPD_Inexact|MPD_Errors)) {
        *status |= (workctx.status&MPD_Errors);
        return;
    }

    workctx.status = 0;
    mpd_qsub(result, a, &tiny, &workctx, &workctx.status);
    *status |= (workctx.status&MPD_Errors);
}

/* The smallest representable number that is larger than the operand. */
void
mpd_qnext_plus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
               uint32_t *status)
{
    mpd_context_t workctx;
    MPD_NEW_CONST(tiny,MPD_POS,mpd_etiny(ctx)-1,1,1,1,1);

    if (mpd_isspecial(a)) {
        if (mpd_qcheck_nan(result, a, ctx, status)) {
            return;
        }

        assert(mpd_isinfinite(a));
        if (mpd_ispositive(a)) {
            mpd_qcopy(result, a, status);
        }
        else {
            mpd_clear_flags(result);
            mpd_qmaxcoeff(result, ctx, status);
            if (mpd_isnan(result)) {
                return;
            }
            mpd_set_flags(result, MPD_NEG);
            result->exp = mpd_etop(ctx);
        }
        return;
    }

    mpd_workcontext(&workctx, ctx);
    workctx.round = MPD_ROUND_CEILING;

    if (!mpd_qcopy(result, a, status)) {
        return;
    }

    mpd_qfinalize(result, &workctx, &workctx.status);
    if (workctx.status & (MPD_Inexact|MPD_Errors)) {
        *status |= (workctx.status&MPD_Errors);
        return;
    }

    workctx.status = 0;
    mpd_qadd(result, a, &tiny, &workctx, &workctx.status);
    *status |= (workctx.status&MPD_Errors);
}

/*
 * The number closest to the first operand that is in the direction towards
 * the second operand.
 */
void
mpd_qnext_toward(mpd_t *result, const mpd_t *a, const mpd_t *b,
                 const mpd_context_t *ctx, uint32_t *status)
{
    int c;

    if (mpd_qcheck_nans(result, a, b, ctx, status)) {
        return;
    }

    c = _mpd_cmp(a, b);
    if (c == 0) {
        mpd_qcopy_sign(result, a, b, status);
        return;
    }

    if (c < 0) {
        mpd_qnext_plus(result, a, ctx, status);
    }
    else {
        mpd_qnext_minus(result, a, ctx, status);
    }

    if (mpd_isinfinite(result)) {
        *status |= (MPD_Overflow|MPD_Rounded|MPD_Inexact);
    }
    else if (mpd_adjexp(result) < ctx->emin) {
        *status |= (MPD_Underflow|MPD_Subnormal|MPD_Rounded|MPD_Inexact);
        if (mpd_iszero(result)) {
            *status |= MPD_Clamped;
        }
    }
}

/*
 * Internal function: Integer power with mpd_uint_t exponent. The function
 * can fail with MPD_Malloc_error.
 *
 * The error is equal to the error incurred in k-1 multiplications. Assuming
 * the upper bound for the relative error in each operation:
 *
 *   abs(err) = 5 * 10**-prec
 *   result = x**k * (1 + err)**(k-1)
 */
static inline void
_mpd_qpow_uint(mpd_t *result, const mpd_t *base, mpd_uint_t exp,
               uint8_t resultsign, const mpd_context_t *ctx, uint32_t *status)
{
    uint32_t workstatus = 0;
    mpd_uint_t n;

    if (exp == 0) {
        _settriple(result, resultsign, 1, 0); /* GCOV_NOT_REACHED */
        return; /* GCOV_NOT_REACHED */
    }

    if (!mpd_qcopy(result, base, status)) {
        return;
    }

    n = mpd_bits[mpd_bsr(exp)];
    while (n >>= 1) {
        mpd_qmul(result, result, result, ctx, &workstatus);
        if (exp & n) {
            mpd_qmul(result, result, base, ctx, &workstatus);
        }
        if (mpd_isspecial(result) ||
            (mpd_iszerocoeff(result) && (workstatus & MPD_Clamped))) {
            break;
        }
    }

    *status |= workstatus;
    mpd_set_sign(result, resultsign);
}

/*
 * Internal function: Integer power with mpd_t exponent, tbase and texp
 * are modified!! Function can fail with MPD_Malloc_error.
 *
 * The error is equal to the error incurred in k multiplications. Assuming
 * the upper bound for the relative error in each operation:
 *
 *   abs(err) = 5 * 10**-prec
 *   result = x**k * (1 + err)**k
 */
static inline void
_mpd_qpow_mpd(mpd_t *result, mpd_t *tbase, mpd_t *texp, uint8_t resultsign,
              const mpd_context_t *ctx, uint32_t *status)
{
    uint32_t workstatus = 0;
    mpd_context_t maxctx;
    MPD_NEW_CONST(two,0,0,1,1,1,2);


    mpd_maxcontext(&maxctx);

    /* resize to smaller cannot fail */
    mpd_qcopy(result, &one, status);

    while (!mpd_iszero(texp)) {
        if (mpd_isodd(texp)) {
            mpd_qmul(result, result, tbase, ctx, &workstatus);
            *status |= workstatus;
            if (mpd_isspecial(result) ||
                (mpd_iszerocoeff(result) && (workstatus & MPD_Clamped))) {
                break;
            }
        }
        mpd_qmul(tbase, tbase, tbase, ctx, &workstatus);
        mpd_qdivint(texp, texp, &two, &maxctx, &workstatus);
        if (mpd_isnan(tbase) || mpd_isnan(texp)) {
            mpd_seterror(result, workstatus&MPD_Errors, status);
            return;
        }
    }
    mpd_set_sign(result, resultsign);
}

/*
 * The power function for integer exponents. Relative error _before_ the
 * final rounding to prec:
 *   abs(result - base**exp) < 0.1 * 10**-prec * abs(base**exp)
 */
static void
_mpd_qpow_int(mpd_t *result, const mpd_t *base, const mpd_t *exp,
              uint8_t resultsign,
              const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t workctx;
    MPD_NEW_STATIC(tbase,0,0,0,0);
    MPD_NEW_STATIC(texp,0,0,0,0);
    mpd_ssize_t n;


    mpd_workcontext(&workctx, ctx);
    workctx.prec += (exp->digits + exp->exp + 2);
    workctx.round = MPD_ROUND_HALF_EVEN;
    workctx.clamp = 0;
    if (mpd_isnegative(exp)) {
        workctx.prec += 1;
        mpd_qdiv(&tbase, &one, base, &workctx, status);
        if (*status&MPD_Errors) {
            mpd_setspecial(result, MPD_POS, MPD_NAN);
            goto finish;
        }
    }
    else {
        if (!mpd_qcopy(&tbase, base, status)) {
            mpd_setspecial(result, MPD_POS, MPD_NAN);
            goto finish;
        }
    }

    n = mpd_qabs_uint(exp, &workctx.status);
    if (workctx.status&MPD_Invalid_operation) {
        if (!mpd_qcopy(&texp, exp, status)) {
            mpd_setspecial(result, MPD_POS, MPD_NAN); /* GCOV_UNLIKELY */
            goto finish; /* GCOV_UNLIKELY */
        }
        _mpd_qpow_mpd(result, &tbase, &texp, resultsign, &workctx, status);
    }
    else {
        _mpd_qpow_uint(result, &tbase, n, resultsign, &workctx, status);
    }

    if (mpd_isinfinite(result)) {
        /* for ROUND_DOWN, ROUND_FLOOR, etc. */
        _settriple(result, resultsign, 1, MPD_EXP_INF);
    }

finish:
    mpd_del(&tbase);
    mpd_del(&texp);
    mpd_qfinalize(result, ctx, status);
}

/*
 * If the exponent is infinite and base equals one, the result is one
 * with a coefficient of length prec. Otherwise, result is undefined.
 * Return the value of the comparison against one.
 */
static int
_qcheck_pow_one_inf(mpd_t *result, const mpd_t *base, uint8_t resultsign,
                    const mpd_context_t *ctx, uint32_t *status)
{
    mpd_ssize_t shift;
    int cmp;

    if ((cmp = _mpd_cmp(base, &one)) == 0) {
        shift = ctx->prec-1;
        mpd_qshiftl(result, &one, shift, status);
        result->exp = -shift;
        mpd_set_flags(result, resultsign);
        *status |= (MPD_Inexact|MPD_Rounded);
    }

    return cmp;
}

/*
 * If abs(base) equals one, calculate the correct power of one result.
 * Otherwise, result is undefined. Return the value of the comparison
 * against 1.
 *
 * This is an internal function that does not check for specials.
 */
static int
_qcheck_pow_one(mpd_t *result, const mpd_t *base, const mpd_t *exp,
                uint8_t resultsign,
                const mpd_context_t *ctx, uint32_t *status)
{
    uint32_t workstatus = 0;
    mpd_ssize_t shift;
    int cmp;

    if ((cmp = _mpd_cmp_abs(base, &one)) == 0) {
        if (_mpd_isint(exp)) {
            if (mpd_isnegative(exp)) {
                _settriple(result, resultsign, 1, 0);
                return 0;
            }
            /* 1.000**3 = 1.000000000 */
            mpd_qmul_ssize(result, exp, -base->exp, ctx, &workstatus);
            if (workstatus&MPD_Errors) {
                *status |= (workstatus&MPD_Errors);
                return 0;
            }
            /* digits-1 after exponentiation */
            shift = mpd_qget_ssize(result, &workstatus);
            /* shift is MPD_SSIZE_MAX if result is too large */
            if (shift > ctx->prec-1) {
                shift = ctx->prec-1;
                *status |= MPD_Rounded;
            }
        }
        else if (mpd_ispositive(base)) {
            shift = ctx->prec-1;
            *status |= (MPD_Inexact|MPD_Rounded);
        }
        else {
            return -2; /* GCOV_NOT_REACHED */
        }
        if (!mpd_qshiftl(result, &one, shift, status)) {
            return 0;
        }
        result->exp = -shift;
        mpd_set_flags(result, resultsign);
    }

    return cmp;
}

/*
 * Detect certain over/underflow of x**y.
 * ACL2 proof: pow-bounds.lisp.
 *
 *   Symbols:
 *
 *     e: EXP_INF or EXP_CLAMP
 *     x: base
 *     y: exponent
 *
 *     omega(e) = log10(abs(e))
 *     zeta(x)  = log10(abs(log10(x)))
 *     theta(y) = log10(abs(y))
 *
 *   Upper and lower bounds:
 *
 *     ub_omega(e) = ceil(log10(abs(e)))
 *     lb_theta(y) = floor(log10(abs(y)))
 *
 *                  | floor(log10(floor(abs(log10(x))))) if x < 1/10 or x >= 10
 *     lb_zeta(x) = | floor(log10(abs(x-1)/10)) if 1/10 <= x < 1
 *                  | floor(log10(abs((x-1)/100))) if 1 < x < 10
 *
 *   ub_omega(e) and lb_theta(y) are obviously upper and lower bounds
 *   for omega(e) and theta(y).
 *
 *   lb_zeta is a lower bound for zeta(x):
 *
 *     x < 1/10 or x >= 10:
 *
 *       abs(log10(x)) >= 1, so the outer log10 is well defined. Since log10
 *       is strictly increasing, the end result is a lower bound.
 *
 *     1/10 <= x < 1:
 *
 *       We use: log10(x) <= (x-1)/log(10)
 *               abs(log10(x)) >= abs(x-1)/log(10)
 *               abs(log10(x)) >= abs(x-1)/10
 *
 *     1 < x < 10:
 *
 *       We use: (x-1)/(x*log(10)) < log10(x)
 *               abs((x-1)/100) < abs(log10(x))
 *
 *       XXX: abs((x-1)/10) would work, need ACL2 proof.
 *
 *
 *   Let (0 < x < 1 and y < 0) or (x > 1 and y > 0).                  (H1)
 *   Let ub_omega(exp_inf) < lb_zeta(x) + lb_theta(y)                 (H2)
 *
 *   Then:
 *       log10(abs(exp_inf)) < log10(abs(log10(x))) + log10(abs(y)).   (1)
 *                   exp_inf < log10(x) * y                            (2)
 *               10**exp_inf < x**y                                    (3)
 *
 *   Let (0 < x < 1 and y > 0) or (x > 1 and y < 0).                  (H3)
 *   Let ub_omega(exp_clamp) < lb_zeta(x) + lb_theta(y)               (H4)
 *
 *   Then:
 *     log10(abs(exp_clamp)) < log10(abs(log10(x))) + log10(abs(y)).   (4)
 *              log10(x) * y < exp_clamp                               (5)
 *                      x**y < 10**exp_clamp                           (6)
 *
 */
static mpd_ssize_t
_lower_bound_zeta(const mpd_t *x, uint32_t *status)
{
    mpd_context_t maxctx;
    MPD_NEW_STATIC(scratch,0,0,0,0);
    mpd_ssize_t t, u;

    t = mpd_adjexp(x);
    if (t > 0) {
        /* x >= 10 -> floor(log10(floor(abs(log10(x))))) */
        return mpd_exp_digits(t) - 1;
    }
    else if (t < -1) {
        /* x < 1/10 -> floor(log10(floor(abs(log10(x))))) */
        return mpd_exp_digits(t+1) - 1;
    }
    else {
        mpd_maxcontext(&maxctx);
        mpd_qsub(&scratch, x, &one, &maxctx, status);
        if (mpd_isspecial(&scratch)) {
            mpd_del(&scratch);
            return MPD_SSIZE_MAX;
        }
        u = mpd_adjexp(&scratch);
        mpd_del(&scratch);

        /* t == -1, 1/10 <= x < 1 -> floor(log10(abs(x-1)/10))
         * t == 0,  1 < x < 10    -> floor(log10(abs(x-1)/100)) */
        return (t == 0) ? u-2 : u-1;
    }
}

/*
 * Detect cases of certain overflow/underflow in the power function.
 * Assumptions: x != 1, y != 0. The proof above is for positive x.
 * If x is negative and y is an odd integer, x**y == -(abs(x)**y),
 * so the analysis does not change.
 */
static int
_qcheck_pow_bounds(mpd_t *result, const mpd_t *x, const mpd_t *y,
                   uint8_t resultsign,
                   const mpd_context_t *ctx, uint32_t *status)
{
    MPD_NEW_SHARED(abs_x, x);
    mpd_ssize_t ub_omega, lb_zeta, lb_theta;
    uint8_t sign;

    mpd_set_positive(&abs_x);

    lb_theta = mpd_adjexp(y);
    lb_zeta = _lower_bound_zeta(&abs_x, status);
    if (lb_zeta == MPD_SSIZE_MAX) {
        mpd_seterror(result, MPD_Malloc_error, status);
        return 1;
    }

    sign = (mpd_adjexp(&abs_x) < 0) ^ mpd_sign(y);
    if (sign == 0) {
        /* (0 < |x| < 1 and y < 0) or (|x| > 1 and y > 0) */
        ub_omega = mpd_exp_digits(ctx->emax);
        if (ub_omega < lb_zeta + lb_theta) {
            _settriple(result, resultsign, 1, MPD_EXP_INF);
            mpd_qfinalize(result, ctx, status);
            return 1;
        }
    }
    else {
        /* (0 < |x| < 1 and y > 0) or (|x| > 1 and y < 0). */
        ub_omega = mpd_exp_digits(mpd_etiny(ctx));
        if (ub_omega < lb_zeta + lb_theta) {
            _settriple(result, resultsign, 1, mpd_etiny(ctx)-1);
            mpd_qfinalize(result, ctx, status);
            return 1;
        }
    }

    return 0;
}

/*
 * TODO: Implement algorithm for computing exact powers from decimal.py.
 * In order to prevent infinite loops, this has to be called before
 * using Ziv's strategy for correct rounding.
 */
/*
static int
_mpd_qpow_exact(mpd_t *result, const mpd_t *base, const mpd_t *exp,
                const mpd_context_t *ctx, uint32_t *status)
{
    return 0;
}
*/

/*
 * The power function for real exponents.
 *   Relative error: abs(result - e**y) < e**y * 1/5 * 10**(-prec - 1)
 */
static void
_mpd_qpow_real(mpd_t *result, const mpd_t *base, const mpd_t *exp,
               const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t workctx;
    MPD_NEW_STATIC(texp,0,0,0,0);

    if (!mpd_qcopy(&texp, exp, status)) {
        mpd_seterror(result, MPD_Malloc_error, status);
        return;
    }

    mpd_maxcontext(&workctx);
    workctx.prec = (base->digits > ctx->prec) ? base->digits : ctx->prec;
    workctx.prec += (4 + MPD_EXPDIGITS);
    workctx.round = MPD_ROUND_HALF_EVEN;
    workctx.allcr = ctx->allcr;

    /*
     * extra := MPD_EXPDIGITS = MPD_EXP_MAX_T
     * wp := prec + 4 + extra
     * abs(err) < 5 * 10**-wp
     * y := log(base) * exp
     * Calculate:
     *   1)   e**(y * (1 + err)**2) * (1 + err)
     *      = e**y * e**(y * (2*err + err**2)) * (1 + err)
     *        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     * Relative error of the underlined term:
     *   2) abs(e**(y * (2*err + err**2)) - 1)
     * Case abs(y) >= 10**extra:
     *   3) adjexp(y)+1 > log10(abs(y)) >= extra
     *   This triggers the Overflow/Underflow shortcut in _mpd_qexp(),
     *   so no further analysis is necessary.
     * Case abs(y) < 10**extra:
     *   4) abs(y * (2*err + err**2)) < 1/5 * 10**(-prec - 2)
     *   Use (see _mpd_qexp):
     *     5) abs(x) <= 9/10 * 10**-p ==> abs(e**x - 1) < 10**-p
     *   With 2), 4) and 5):
     *     6) abs(e**(y * (2*err + err**2)) - 1) < 10**(-prec - 2)
     *   The complete relative error of 1) is:
     *     7) abs(result - e**y) < e**y * 1/5 * 10**(-prec - 1)
     */
    mpd_qln(result, base, &workctx, &workctx.status);
    mpd_qmul(result, result, &texp, &workctx, &workctx.status);
    mpd_qexp(result, result, &workctx, status);

    mpd_del(&texp);
    *status |= (workctx.status&MPD_Errors);
    *status |= (MPD_Inexact|MPD_Rounded);
}

/* The power function: base**exp */
void
mpd_qpow(mpd_t *result, const mpd_t *base, const mpd_t *exp,
         const mpd_context_t *ctx, uint32_t *status)
{
    uint8_t resultsign = 0;
    int intexp = 0;
    int cmp;

    if (mpd_isspecial(base) || mpd_isspecial(exp)) {
        if (mpd_qcheck_nans(result, base, exp, ctx, status)) {
            return;
        }
    }
    if (mpd_isinteger(exp)) {
        intexp = 1;
        resultsign = mpd_isnegative(base) && mpd_isodd(exp);
    }

    if (mpd_iszero(base)) {
        if (mpd_iszero(exp)) {
            mpd_seterror(result, MPD_Invalid_operation, status);
        }
        else if (mpd_isnegative(exp)) {
            mpd_setspecial(result, resultsign, MPD_INF);
        }
        else {
            _settriple(result, resultsign, 0, 0);
        }
        return;
    }
    if (mpd_isnegative(base)) {
        if (!intexp || mpd_isinfinite(exp)) {
            mpd_seterror(result, MPD_Invalid_operation, status);
            return;
        }
    }
    if (mpd_isinfinite(exp)) {
        /* power of one */
        cmp = _qcheck_pow_one_inf(result, base, resultsign, ctx, status);
        if (cmp == 0) {
            return;
        }
        else {
            cmp *= mpd_arith_sign(exp);
            if (cmp < 0) {
                _settriple(result, resultsign, 0, 0);
            }
            else {
                mpd_setspecial(result, resultsign, MPD_INF);
            }
        }
        return;
    }
    if (mpd_isinfinite(base)) {
        if (mpd_iszero(exp)) {
            _settriple(result, resultsign, 1, 0);
        }
        else if (mpd_isnegative(exp)) {
            _settriple(result, resultsign, 0, 0);
        }
        else {
            mpd_setspecial(result, resultsign, MPD_INF);
        }
        return;
    }
    if (mpd_iszero(exp)) {
        _settriple(result, resultsign, 1, 0);
        return;
    }
    if (_qcheck_pow_one(result, base, exp, resultsign, ctx, status) == 0) {
        return;
    }
    if (_qcheck_pow_bounds(result, base, exp, resultsign, ctx, status)) {
        return;
    }

    if (intexp) {
        _mpd_qpow_int(result, base, exp, resultsign, ctx, status);
    }
    else {
        _mpd_qpow_real(result, base, exp, ctx, status);
        if (!mpd_isspecial(result) && _mpd_cmp(result, &one) == 0) {
            mpd_ssize_t shift = ctx->prec-1;
            mpd_qshiftl(result, &one, shift, status);
            result->exp = -shift;
        }
        if (mpd_isinfinite(result)) {
            /* for ROUND_DOWN, ROUND_FLOOR, etc. */
            _settriple(result, MPD_POS, 1, MPD_EXP_INF);
        }
        mpd_qfinalize(result, ctx, status);
    }
}

/*
 * Internal function: Integer powmod with mpd_uint_t exponent, base is modified!
 * Function can fail with MPD_Malloc_error.
 */
static inline void
_mpd_qpowmod_uint(mpd_t *result, mpd_t *base, mpd_uint_t exp,
                  const mpd_t *mod, uint32_t *status)
{
    mpd_context_t maxcontext;

    mpd_maxcontext(&maxcontext);

    /* resize to smaller cannot fail */
    mpd_qcopy(result, &one, status);

    while (exp > 0) {
        if (exp & 1) {
            _mpd_qmul_exact(result, result, base, &maxcontext, status);
            mpd_qrem(result, result, mod, &maxcontext, status);
        }
        _mpd_qmul_exact(base, base, base, &maxcontext, status);
        mpd_qrem(base, base, mod, &maxcontext, status);
        exp >>= 1;
    }
}

/* The powmod function: (base**exp) % mod */
void
mpd_qpowmod(mpd_t *result, const mpd_t *base, const mpd_t *exp,
            const mpd_t *mod,
            const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(tbase,0,0,0,0);
    MPD_NEW_STATIC(texp,0,0,0,0);
    MPD_NEW_STATIC(tmod,0,0,0,0);
    MPD_NEW_STATIC(tmp,0,0,0,0);
    MPD_NEW_CONST(two,0,0,1,1,1,2);
    mpd_ssize_t tbase_exp, texp_exp;
    mpd_ssize_t i;
    mpd_t t;
    mpd_uint_t r;
    uint8_t sign;


    if (mpd_isspecial(base) || mpd_isspecial(exp) || mpd_isspecial(mod)) {
        if (mpd_qcheck_3nans(result, base, exp, mod, ctx, status)) {
            return;
        }
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }


    if (!_mpd_isint(base) || !_mpd_isint(exp) || !_mpd_isint(mod)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }
    if (mpd_iszerocoeff(mod)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }
    if (mod->digits+mod->exp > ctx->prec) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    sign = (mpd_isnegative(base)) && (mpd_isodd(exp));
    if (mpd_iszerocoeff(exp)) {
        if (mpd_iszerocoeff(base)) {
            mpd_seterror(result, MPD_Invalid_operation, status);
            return;
        }
        r = (_mpd_cmp_abs(mod, &one)==0) ? 0 : 1;
        _settriple(result, sign, r, 0);
        return;
    }
    if (mpd_isnegative(exp)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }
    if (mpd_iszerocoeff(base)) {
        _settriple(result, sign, 0, 0);
        return;
    }

    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_qround_to_int(&tbase, base, &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);
    mpd_qshiftl(result, &one, tbase_exp, status);
    mpd_qrem(result, result, &tmod, &maxcontext, status);
    _mpd_qmul_exact(&tbase, &tbase, result, &maxcontext, status);
    mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status);
    if (mpd_isspecial(&tbase) ||
        mpd_isspecial(&texp) ||
        mpd_isspecial(&tmod)) {
        goto mpd_errors;
    }

    for (i = 0; i < texp_exp; i++) {
        _mpd_qpowmod_uint(&tmp, &tbase, 10, &tmod, status);
        t = tmp;
        tmp = tbase;
        tbase = t;
    }
    if (mpd_isspecial(&tbase)) {
        goto mpd_errors; /* GCOV_UNLIKELY */
    }

    /* resize to smaller cannot fail */
    mpd_qcopy(result, &one, status);
    while (mpd_isfinite(&texp) && !mpd_iszero(&texp)) {
        if (mpd_isodd(&texp)) {
            _mpd_qmul_exact(result, result, &tbase, &maxcontext, status);
            mpd_qrem(result, result, &tmod, &maxcontext, status);
        }
        _mpd_qmul_exact(&tbase, &tbase, &tbase, &maxcontext, status);
        mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status);
        mpd_qdivint(&texp, &texp, &two, &maxcontext, status);
    }
    if (mpd_isspecial(&texp) || mpd_isspecial(&tbase) ||
        mpd_isspecial(&tmod) || mpd_isspecial(result)) {
        /* MPD_Malloc_error */
        goto mpd_errors;
    }
    else {
        mpd_set_sign(result, sign);
    }

out:
    mpd_del(&tbase);
    mpd_del(&texp);
    mpd_del(&tmod);
    mpd_del(&tmp);
    return;

mpd_errors:
    mpd_setspecial(result, MPD_POS, MPD_NAN);
    goto out;
}

void
mpd_qquantize(mpd_t *result, const mpd_t *a, const mpd_t *b,
              const mpd_context_t *ctx, uint32_t *status)
{
    uint32_t workstatus = 0;
    mpd_ssize_t b_exp = b->exp;
    mpd_ssize_t expdiff, shift;
    mpd_uint_t rnd;

    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
            return;
        }
        if (mpd_isinfinite(a) && mpd_isinfinite(b)) {
            mpd_qcopy(result, a, status);
            return;
        }
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    if (b->exp > ctx->emax || b->exp < mpd_etiny(ctx)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    if (mpd_iszero(a)) {
        _settriple(result, mpd_sign(a), 0, b->exp);
        mpd_qfinalize(result, ctx, status);
        return;
    }


    expdiff = a->exp - b->exp;
    if (a->digits + expdiff > ctx->prec) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    if (expdiff >= 0) {
        shift = expdiff;
        if (!mpd_qshiftl(result, a, shift, status)) {
            return;
        }
        result->exp = b_exp;
    }
    else {
        /* At this point expdiff < 0 and a->digits+expdiff <= prec,
         * so the shift before an increment will fit in prec. */
        shift = -expdiff;
        rnd = mpd_qshiftr(result, a, shift, status);
        if (rnd == MPD_UINT_MAX) {
            return;
        }
        result->exp = b_exp;
        if (!_mpd_apply_round_fit(result, rnd, ctx, status)) {
            return;
        }
        workstatus |= MPD_Rounded;
        if (rnd) {
            workstatus |= MPD_Inexact;
        }
    }

    if (mpd_adjexp(result) > ctx->emax ||
        mpd_adjexp(result) < mpd_etiny(ctx)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    *status |= workstatus;
    mpd_qfinalize(result, ctx, status);
}

void
mpd_qreduce(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
            uint32_t *status)
{
    mpd_ssize_t shift, maxexp, maxshift;
    uint8_t sign_a = mpd_sign(a);

    if (mpd_isspecial(a)) {
        if (mpd_qcheck_nan(result, a, ctx, status)) {
            return;
        }
        mpd_qcopy(result, a, status);
        return;
    }

    if (!mpd_qcopy(result, a, status)) {
        return;
    }
    mpd_qfinalize(result, ctx, status);
    if (mpd_isspecial(result)) {
        return;
    }
    if (mpd_iszero(result)) {
        _settriple(result, sign_a, 0, 0);
        return;
    }

    shift = mpd_trail_zeros(result);
    maxexp = (ctx->clamp) ? mpd_etop(ctx) : ctx->emax;
    /* After the finalizing above result->exp <= maxexp. */
    maxshift = maxexp - result->exp;
    shift = (shift > maxshift) ? maxshift : shift;

    mpd_qshiftr_inplace(result, shift);
    result->exp += shift;
}

void
mpd_qrem(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx,
         uint32_t *status)
{
    MPD_NEW_STATIC(q,0,0,0,0);

    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_qcheck_nans(r, a, b, ctx, status)) {
            return;
        }
        if (mpd_isinfinite(a)) {
            mpd_seterror(r, MPD_Invalid_operation, status);
            return;
        }
        if (mpd_isinfinite(b)) {
            mpd_qcopy(r, a, status);
            mpd_qfinalize(r, ctx, status);
            return;
        }
        /* debug */
        abort(); /* GCOV_NOT_REACHED */
    }
    if (mpd_iszerocoeff(b)) {
        if (mpd_iszerocoeff(a)) {
            mpd_seterror(r, MPD_Division_undefined, status);
        }
        else {
            mpd_seterror(r, MPD_Invalid_operation, status);
        }
        return;
    }

    _mpd_qdivmod(&q, r, a, b, ctx, status);
    mpd_del(&q);
    mpd_qfinalize(r, ctx, status);
}

void
mpd_qrem_near(mpd_t *r, const mpd_t *a, const mpd_t *b,
              const mpd_context_t *ctx, uint32_t *status)
{
    mpd_context_t workctx;
    MPD_NEW_STATIC(btmp,0,0,0,0);
    MPD_NEW_STATIC(q,0,0,0,0);
    mpd_ssize_t expdiff, qdigits;
    int cmp, isodd, allnine;

    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        if (mpd_qcheck_nans(r, a, b, ctx, status)) {
            return;
        }
        if (mpd_isinfinite(a)) {
            mpd_seterror(r, MPD_Invalid_operation, status);
            return;
        }
        if (mpd_isinfinite(b)) {
            mpd_qcopy(r, a, status);
            mpd_qfinalize(r, ctx, status);
            return;
        }
        /* debug */
        abort(); /* GCOV_NOT_REACHED */
    }
    if (mpd_iszerocoeff(b)) {
        if (mpd_iszerocoeff(a)) {
            mpd_seterror(r,  MPD_Division_undefined, status);
        }
        else {
            mpd_seterror(r,  MPD_Invalid_operation, status);
        }
        return;
    }

    if (r == b) {
        if (!mpd_qcopy(&btmp, b, status)) {
            mpd_seterror(r, MPD_Malloc_error, status);
            return;
        }
        b = &btmp;
    }

    _mpd_qdivmod(&q, r, a, b, ctx, status);
    if (mpd_isnan(&q) || mpd_isnan(r)) {
        goto finish;
    }
    if (mpd_iszerocoeff(r)) {
        goto finish;
    }

    expdiff = mpd_adjexp(b) - mpd_adjexp(r);
    if (-1 <= expdiff && expdiff <= 1) {

        allnine = mpd_coeff_isallnine(&q);
        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);
        }
        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_abs(&q, r);
        if (cmp < 0 || (cmp == 0 && isodd)) {
            /* 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);
        }
    }


finish:
    mpd_del(&btmp);
    mpd_del(&q);
    mpd_qfinalize(r, ctx, status);
}

static void
_mpd_qrescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp,
              const mpd_context_t *ctx, uint32_t *status)
{
    mpd_ssize_t expdiff, shift;
    mpd_uint_t rnd;

    if (mpd_isspecial(a)) {
        mpd_qcopy(result, a, status);
        return;
    }

    if (mpd_iszero(a)) {
        _settriple(result, mpd_sign(a), 0, exp);
        return;
    }

    expdiff = a->exp - exp;
    if (expdiff >= 0) {
        shift = expdiff;
        if (a->digits + shift > MPD_MAX_PREC+1) {
            mpd_seterror(result, MPD_Invalid_operation, status);
            return;
        }
        if (!mpd_qshiftl(result, a, shift, status)) {
            return;
        }
        result->exp = exp;
    }
    else {
        shift = -expdiff;
        rnd = mpd_qshiftr(result, a, shift, status);
        if (rnd == MPD_UINT_MAX) {
            return;
        }
        result->exp = exp;
        _mpd_apply_round_excess(result, rnd, ctx, status);
        *status |= MPD_Rounded;
        if (rnd) {
            *status |= MPD_Inexact;
        }
    }

    if (mpd_issubnormal(result, ctx)) {
        *status |= MPD_Subnormal;
    }
}

/*
 * Rescale a number so that it has exponent 'exp'. Does not regard context
 * precision, emax, emin, but uses the rounding mode. Special numbers are
 * quietly copied. Restrictions:
 *
 *     MPD_MIN_ETINY <= exp <= MPD_MAX_EMAX+1
 *     result->digits <= MPD_MAX_PREC+1
 */
void
mpd_qrescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp,
             const mpd_context_t *ctx, uint32_t *status)
{
    if (exp > MPD_MAX_EMAX+1 || exp < MPD_MIN_ETINY) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    _mpd_qrescale(result, a, exp, ctx, status);
}

/*
 * Same as mpd_qrescale, but with relaxed restrictions. The result of this
 * function should only be used for formatting a number and never as input
 * for other operations.
 *
 *     MPD_MIN_ETINY-MPD_MAX_PREC <= exp <= MPD_MAX_EMAX+1
 *     result->digits <= MPD_MAX_PREC+1
 */
void
mpd_qrescale_fmt(mpd_t *result, const mpd_t *a, mpd_ssize_t exp,
                 const mpd_context_t *ctx, uint32_t *status)
{
    if (exp > MPD_MAX_EMAX+1 || exp < MPD_MIN_ETINY-MPD_MAX_PREC) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    _mpd_qrescale(result, a, exp, ctx, status);
}

/* Round to an integer according to 'action' and ctx->round. */
enum {TO_INT_EXACT, TO_INT_SILENT, TO_INT_TRUNC};
static void
_mpd_qround_to_integral(int action, mpd_t *result, const mpd_t *a,
                        const mpd_context_t *ctx, uint32_t *status)
{
    mpd_uint_t rnd;

    if (mpd_isspecial(a)) {
        if (mpd_qcheck_nan(result, a, ctx, status)) {
            return;
        }
        mpd_qcopy(result, a, status);
        return;
    }
    if (a->exp >= 0) {
        mpd_qcopy(result, a, status);
        return;
    }
    if (mpd_iszerocoeff(a)) {
        _settriple(result, mpd_sign(a), 0, 0);
        return;
    }

    rnd = mpd_qshiftr(result, a, -a->exp, status);
    if (rnd == MPD_UINT_MAX) {
        return;
    }
    result->exp = 0;

    if (action == TO_INT_EXACT || action == TO_INT_SILENT) {
        _mpd_apply_round_excess(result, rnd, ctx, status);
        if (action == TO_INT_EXACT) {
            *status |= MPD_Rounded;
            if (rnd) {
                *status |= MPD_Inexact;
            }
        }
    }
}

void
mpd_qround_to_intx(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
                   uint32_t *status)
{
    (void)_mpd_qround_to_integral(TO_INT_EXACT, result, a, ctx, status);
}

void
mpd_qround_to_int(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
                  uint32_t *status)
{
    (void)_mpd_qround_to_integral(TO_INT_SILENT, result, a, ctx, status);
}

void
mpd_qtrunc(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
           uint32_t *status)
{
    (void)_mpd_qround_to_integral(TO_INT_TRUNC, result, a, ctx, status);
}

void
mpd_qfloor(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
           uint32_t *status)
{
    mpd_context_t workctx = *ctx;
    workctx.round = MPD_ROUND_FLOOR;
    (void)_mpd_qround_to_integral(TO_INT_SILENT, result, a,
                                  &workctx, status);
}

void
mpd_qceil(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
          uint32_t *status)
{
    mpd_context_t workctx = *ctx;
    workctx.round = MPD_ROUND_CEILING;
    (void)_mpd_qround_to_integral(TO_INT_SILENT, result, a,
                                  &workctx, status);
}

int
mpd_same_quantum(const mpd_t *a, const mpd_t *b)
{
    if (mpd_isspecial(a) || mpd_isspecial(b)) {
        return ((mpd_isnan(a) && mpd_isnan(b)) ||
                (mpd_isinfinite(a) && mpd_isinfinite(b)));
    }

    return a->exp == b->exp;
}

/* Schedule the increase in precision for the Newton iteration. */
static inline int
recpr_schedule_prec(mpd_ssize_t klist[MPD_MAX_PREC_LOG2],
                    mpd_ssize_t maxprec, mpd_ssize_t initprec)
{
    mpd_ssize_t k;
    int i;

    assert(maxprec > 0 && initprec > 0);
    if (maxprec <= initprec) return -1;

    i = 0; k = maxprec;
    do {
        k = (k+1) / 2;
        klist[i++] = k;
    } while (k > initprec);

    return i-1;
}

/*
 * Initial approximation for the reciprocal:
 *    k_0 := MPD_RDIGITS-2
 *    z_0 := 10**(-k_0) * floor(10**(2*k_0 + 2) / floor(v * 10**(k_0 + 2)))
 * Absolute error:
 *    |1/v - z_0| < 10**(-k_0)
 * ACL2 proof: maxerror-inverse-approx
 */
static void
_mpd_qreciprocal_approx(mpd_t *z, const mpd_t *v, uint32_t *status)
{
    mpd_uint_t p10data[2] = {0, mpd_pow10[MPD_RDIGITS-2]};
    mpd_uint_t dummy, word;
    int n;

    assert(v->exp == -v->digits);

    _mpd_get_msdigits(&dummy, &word, v, MPD_RDIGITS);
    n = mpd_word_digits(word);
    word *= mpd_pow10[MPD_RDIGITS-n];

    mpd_qresize(z, 2, status);
    (void)_mpd_shortdiv(z->data, p10data, 2, word);

    mpd_clear_flags(z);
    z->exp = -(MPD_RDIGITS-2);
    z->len = (z->data[1] == 0) ? 1 : 2;
    mpd_setdigits(z);
}

/*
 * Reciprocal, calculated with Newton's Method. Assumption: result != a.
 * NOTE: The comments in the function show that certain operations are
 * exact. The proof for the maximum error is too long to fit in here.
 * ACL2 proof: maxerror-inverse-complete
 */
static void
_mpd_qreciprocal(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
                 uint32_t *status)
{
    mpd_context_t varcontext, maxcontext;
    mpd_t *z = result;         /* current approximation */
    mpd_t *v;                  /* a, normalized to a number between 0.1 and 1 */
    MPD_NEW_SHARED(vtmp, a);   /* v shares data with a */
    MPD_NEW_STATIC(s,0,0,0,0); /* temporary variable */
    MPD_NEW_STATIC(t,0,0,0,0); /* temporary variable */
    MPD_NEW_CONST(two,0,0,1,1,1,2); /* const 2 */
    mpd_ssize_t klist[MPD_MAX_PREC_LOG2];
    mpd_ssize_t adj, maxprec, initprec;
    uint8_t sign = mpd_sign(a);
    int i;

    assert(result != a);

    v = &vtmp;
    mpd_clear_flags(v);
    adj = v->digits + v->exp;
    v->exp = -v->digits;

    /* Initial approximation */
    _mpd_qreciprocal_approx(z, v, status);

    mpd_maxcontext(&varcontext);
    mpd_maxcontext(&maxcontext);
    varcontext.round = maxcontext.round = MPD_ROUND_TRUNC;
    varcontext.emax = maxcontext.emax = MPD_MAX_EMAX + 100;
    varcontext.emin = maxcontext.emin = MPD_MIN_EMIN - 100;
    maxcontext.prec = MPD_MAX_PREC + 100;

    maxprec = ctx->prec;
    maxprec += 2;
    initprec = MPD_RDIGITS-3;

    i = recpr_schedule_prec(klist, maxprec, initprec);
    for (; i >= 0; i--) {
         /* Loop invariant: z->digits <= klist[i]+7 */
         /* Let s := z**2, exact result */
        _mpd_qmul_exact(&s, z, z, &maxcontext, status);
        varcontext.prec = 2*klist[i] + 5;
        if (v->digits > varcontext.prec) {
            /* Let t := v, truncated to n >= 2*k+5 fraction digits */
            mpd_qshiftr(&t, v, v->digits-varcontext.prec, status);
            t.exp = -varcontext.prec;
            /* Let t := trunc(v)*s, truncated to n >= 2*k+1 fraction digits */
            mpd_qmul(&t, &t, &s, &varcontext, status);
        }
        else { /* v->digits <= 2*k+5 */
            /* Let t := v*s, truncated to n >= 2*k+1 fraction digits */
            mpd_qmul(&t, v, &s, &varcontext, status);
        }
        /* Let s := 2*z, exact result */
        _mpd_qmul_exact(&s, z, &two, &maxcontext, status);
        /* s.digits < t.digits <= 2*k+5, |adjexp(s)-adjexp(t)| <= 1,
         * so the subtraction generates at most 2*k+6 <= klist[i+1]+7
         * digits. The loop invariant is preserved. */
        _mpd_qsub_exact(z, &s, &t, &maxcontext, status);
    }

    if (!mpd_isspecial(z)) {
        z->exp -= adj;
        mpd_set_flags(z, sign);
    }

    mpd_del(&s);
    mpd_del(&t);
    mpd_qfinalize(z, ctx, status);
}

/*
 * Internal function for large numbers:
 *
 *     q, r = divmod(coeff(a), coeff(b))
 *
 * Strategy: Multiply the dividend by the reciprocal of the divisor. The
 * inexact result is fixed by a small loop, using at most one iteration.
 *
 * ACL2 proofs:
 * ------------
 *    1) q is a natural number.  (ndivmod-quotient-natp)
 *    2) r is a natural number.  (ndivmod-remainder-natp)
 *    3) a = q * b + r           (ndivmod-q*b+r==a)
 *    4) r < b                   (ndivmod-remainder-<-b)
 */
static void
_mpd_base_ndivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b,
                  uint32_t *status)
{
    mpd_context_t workctx;
    mpd_t *qq = q, *rr = r;
    mpd_t aa, bb;
    int k;

    _mpd_copy_shared(&aa, a);
    _mpd_copy_shared(&bb, b);

    mpd_set_positive(&aa);
    mpd_set_positive(&bb);
    aa.exp = 0;
    bb.exp = 0;

    if (q == a || q == b) {
        if ((qq = mpd_qnew()) == NULL) {
            *status |= MPD_Malloc_error;
            goto nanresult;
        }
    }
    if (r == a || r == b) {
        if ((rr = mpd_qnew()) == NULL) {
            *status |= MPD_Malloc_error;
            goto nanresult;
        }
    }

    mpd_maxcontext(&workctx);

    /* Let prec := adigits - bdigits + 4 */
    workctx.prec = a->digits - b->digits + 1 + 3;
    if (a->digits > MPD_MAX_PREC || workctx.prec > MPD_MAX_PREC) {
        *status |= MPD_Division_impossible;
        goto nanresult;
    }

    /* Let x := _mpd_qreciprocal(b, prec)
     * Then x is bounded by:
     *    1) 1/b - 10**(-prec - bdigits) < x < 1/b + 10**(-prec - bdigits)
     *    2) 1/b - 10**(-adigits - 4) < x < 1/b + 10**(-adigits - 4)
     */
    _mpd_qreciprocal(rr, &bb, &workctx, &workctx.status);

    /* Get an estimate for the quotient. Let q := a * x
     * Then q is bounded by:
     *    3) a/b - 10**-4 < q < a/b + 10**-4
     */
    _mpd_qmul(qq, &aa, rr, &workctx, &workctx.status);
    /* Truncate q to an integer:
     *    4) a/b - 2 < trunc(q) < a/b + 1
     */
    mpd_qtrunc(qq, qq, &workctx, &workctx.status);

    workctx.prec = aa.digits + 3;
    workctx.emax = MPD_MAX_EMAX + 3;
    workctx.emin = MPD_MIN_EMIN - 3;
    /* Multiply the estimate for q by b:
     *    5) a - 2 * b < trunc(q) * b < a + b
     */
    _mpd_qmul(rr, &bb, qq, &workctx, &workctx.status);
    /* Get the estimate for r such that a = q * b + r. */
    _mpd_qsub_exact(rr, &aa, rr, &workctx, &workctx.status);

    /* Fix the result. At this point -b < r < 2*b, so the correction loop
       takes at most one iteration. */
    for (k = 0;; k++) {
        if (mpd_isspecial(qq) || mpd_isspecial(rr)) {
            *status |= (workctx.status&MPD_Errors);
            goto nanresult;
        }
        if (k > 2) { /* Allow two iterations despite the proof. */
            mpd_err_warn("libmpdec: internal error in "       /* GCOV_NOT_REACHED */
                         "_mpd_base_ndivmod: please report"); /* GCOV_NOT_REACHED */
            *status |= MPD_Invalid_operation;                 /* GCOV_NOT_REACHED */
            goto nanresult;                                   /* GCOV_NOT_REACHED */
        }
        /* r < 0 */
        else if (_mpd_cmp(&zero, rr) == 1) {
            _mpd_qadd_exact(rr, rr, &bb, &workctx, &workctx.status);
            _mpd_qadd_exact(qq, qq, &minus_one, &workctx, &workctx.status);
        }
        /* 0 <= r < b */
        else if (_mpd_cmp(rr, &bb) == -1) {
            break;
        }
        /* r >= b */
        else {
            _mpd_qsub_exact(rr, rr, &bb, &workctx, &workctx.status);
            _mpd_qadd_exact(qq, qq, &one, &workctx, &workctx.status);
        }
    }

    if (qq != q) {
        if (!mpd_qcopy(q, qq, status)) {
            goto nanresult; /* GCOV_UNLIKELY */
        }
        mpd_del(qq);
    }
    if (rr != r) {
        if (!mpd_qcopy(r, rr, status)) {
            goto nanresult; /* GCOV_UNLIKELY */
        }
        mpd_del(rr);
    }

    *status |= (workctx.status&MPD_Errors);
    return;


nanresult:
    if (qq && qq != q) mpd_del(qq);
    if (rr && rr != r) mpd_del(rr);
    mpd_setspecial(q, MPD_POS, MPD_NAN);
    mpd_setspecial(r, MPD_POS, MPD_NAN);
}

/* LIBMPDEC_ONLY */
/*
 * Schedule the optimal precision increase for the Newton iteration.
 *   v := input operand
 *   z_0 := initial approximation
 *   initprec := natural number such that abs(sqrt(v) - z_0) < 10**-initprec
 *   maxprec := target precision
 *
 * For convenience the output klist contains the elements in reverse order:
 *   klist := [k_n-1, ..., k_0], where
 *     1) k_0 <= initprec and
 *     2) abs(sqrt(v) - result) < 10**(-2*k_n-1 + 2) <= 10**-maxprec.
 */
static inline int
invroot_schedule_prec(mpd_ssize_t klist[MPD_MAX_PREC_LOG2],
                      mpd_ssize_t maxprec, mpd_ssize_t initprec)
{
    mpd_ssize_t k;
    int i;

    assert(maxprec >= 3 && initprec >= 3);
    if (maxprec <= initprec) return -1;

    i = 0; k = maxprec;
    do {
        k = (k+3) / 2;
        klist[i++] = k;
    } while (k > initprec);

    return i-1;
}

/*
 * Initial approximation for the inverse square root function.
 *   Input:
 *     v := rational number, with 1 <= v < 100
 *     vhat := floor(v * 10**6)
 *   Output:
 *     z := approximation to 1/sqrt(v), such that abs(z - 1/sqrt(v)) < 10**-3.
 */
static inline void
_invroot_init_approx(mpd_t *z, mpd_uint_t vhat)
{
    mpd_uint_t lo = 1000;
    mpd_uint_t hi = 10000;
    mpd_uint_t a, sq;

    assert(lo*lo <= vhat && vhat < (hi+1)*(hi+1));

    for(;;) {
        a = (lo + hi) / 2;
        sq = a * a;
        if (vhat >= sq) {
            if (vhat < sq + 2*a + 1) {
                break;
            }
            lo = a + 1;
        }
        else {
            hi = a - 1;
        }
    }

    /*
     * After the binary search we have:
     *  1) a**2 <= floor(v * 10**6) < (a + 1)**2
     * This implies:
     *  2) a**2 <= v * 10**6 < (a + 1)**2
     *  3) a <= sqrt(v) * 10**3 < a + 1
     * Since 10**3 <= a:
     *  4) 0 <= 10**prec/a - 1/sqrt(v) < 10**-prec
     * We have:
     *  5) 10**3/a - 10**-3 < floor(10**9/a) * 10**-6 <= 10**3/a
     * Merging 4) and 5):
     *  6) abs(floor(10**9/a) * 10**-6 - 1/sqrt(v)) < 10**-3
     */
    mpd_minalloc(z);
    mpd_clear_flags(z);
    z->data[0] = 1000000000UL / a;
    z->len = 1;
    z->exp = -6;
    mpd_setdigits(z);
}

/*
 * Set 'result' to 1/sqrt(a).
 *   Relative error: abs(result - 1/sqrt(a)) < 10**-prec * 1/sqrt(a)
 */
static void
_mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
              uint32_t *status)
{
    uint32_t workstatus = 0;
    mpd_context_t varcontext, maxcontext;
    mpd_t *z = result;         /* current approximation */
    mpd_t *v;                  /* a, normalized to a number between 1 and 100 */
    MPD_NEW_SHARED(vtmp, a);   /* by default v will share data with a */
    MPD_NEW_STATIC(s,0,0,0,0); /* temporary variable */
    MPD_NEW_STATIC(t,0,0,0,0); /* temporary variable */
    MPD_NEW_CONST(one_half,0,-1,1,1,1,5);
    MPD_NEW_CONST(three,0,0,1,1,1,3);
    mpd_ssize_t klist[MPD_MAX_PREC_LOG2];
    mpd_ssize_t ideal_exp, shift;
    mpd_ssize_t adj, tz;
    mpd_ssize_t maxprec, fracdigits;
    mpd_uint_t vhat, dummy;
    int i, n;


    ideal_exp = -(a->exp - (a->exp & 1)) / 2;

    v = &vtmp;
    if (result == a) {
        if ((v = mpd_qncopy(a)) == NULL) {
            mpd_seterror(result, MPD_Malloc_error, status);
            return;
        }
    }

    /* normalize a to 1 <= v < 100 */
    if ((v->digits+v->exp) & 1) {
        fracdigits = v->digits - 1;
        v->exp = -fracdigits;
        n = (v->digits > 7) ? 7 : (int)v->digits;
        /* Let vhat := floor(v * 10**(2*initprec)) */
        _mpd_get_msdigits(&dummy, &vhat, v, n);
        if (n < 7) {
            vhat *= mpd_pow10[7-n];
        }
    }
    else {
        fracdigits = v->digits - 2;
        v->exp = -fracdigits;
        n = (v->digits > 8) ? 8 : (int)v->digits;
        /* Let vhat := floor(v * 10**(2*initprec)) */
        _mpd_get_msdigits(&dummy, &vhat, v, n);
        if (n < 8) {
            vhat *= mpd_pow10[8-n];
        }
    }
    adj = (a->exp-v->exp) / 2;

    /* initial approximation */
    _invroot_init_approx(z, vhat);

    mpd_maxcontext(&maxcontext);
    mpd_maxcontext(&varcontext);
    varcontext.round = MPD_ROUND_TRUNC;
    maxprec = ctx->prec + 1;

    /* initprec == 3 */
    i = invroot_schedule_prec(klist, maxprec, 3);
    for (; i >= 0; i--) {
        varcontext.prec = 2*klist[i]+2;
        mpd_qmul(&s, z, z, &maxcontext, &workstatus);
        if (v->digits > varcontext.prec) {
            shift = v->digits - varcontext.prec;
            mpd_qshiftr(&t, v, shift, &workstatus);
            t.exp += shift;
            mpd_qmul(&t, &t, &s, &varcontext, &workstatus);
        }
        else {
            mpd_qmul(&t, v, &s, &varcontext, &workstatus);
        }
        mpd_qsub(&t, &three, &t, &maxcontext, &workstatus);
        mpd_qmul(z, z, &t, &varcontext, &workstatus);
        mpd_qmul(z, z, &one_half, &maxcontext, &workstatus);
    }

    z->exp -= adj;

    tz = mpd_trail_zeros(result);
    shift = ideal_exp - result->exp;
    shift = (tz > shift) ? shift : tz;
    if (shift > 0) {
        mpd_qshiftr_inplace(result, shift);
        result->exp += shift;
    }


    mpd_del(&s);
    mpd_del(&t);
    if (v != &vtmp) mpd_del(v);
    *status |= (workstatus&MPD_Errors);
    *status |= (MPD_Rounded|MPD_Inexact);
}

void
mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
             uint32_t *status)
{
    mpd_context_t workctx;

    if (mpd_isspecial(a)) {
        if (mpd_qcheck_nan(result, a, ctx, status)) {
            return;
        }
        if (mpd_isnegative(a)) {
            mpd_seterror(result, MPD_Invalid_operation, status);
            return;
        }
        /* positive infinity */
        _settriple(result, MPD_POS, 0, mpd_etiny(ctx));
        *status |= MPD_Clamped;
        return;
    }
    if (mpd_iszero(a)) {
        mpd_setspecial(result, mpd_sign(a), MPD_INF);
        *status |= MPD_Division_by_zero;
        return;
    }
    if (mpd_isnegative(a)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    workctx = *ctx;
    workctx.prec += 2;
    workctx.round = MPD_ROUND_HALF_EVEN;
    _mpd_qinvroot(result, a, &workctx, status);
    mpd_qfinalize(result, ctx, status);
}
/* END LIBMPDEC_ONLY */

/* Algorithm from decimal.py */
void
mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
          uint32_t *status)
{
    mpd_context_t maxcontext;
    MPD_NEW_STATIC(c,0,0,0,0);
    MPD_NEW_STATIC(q,0,0,0,0);
    MPD_NEW_STATIC(r,0,0,0,0);
    MPD_NEW_CONST(two,0,0,1,1,1,2);
    mpd_ssize_t prec, ideal_exp;
    mpd_ssize_t l, shift;
    int exact = 0;


    ideal_exp = (a->exp - (a->exp & 1)) / 2;

    if (mpd_isspecial(a)) {
        if (mpd_qcheck_nan(result, a, ctx, status)) {
            return;
        }
        if (mpd_isnegative(a)) {
            mpd_seterror(result, MPD_Invalid_operation, status);
            return;
        }
        mpd_setspecial(result, MPD_POS, MPD_INF);
        return;
    }
    if (mpd_iszero(a)) {
        _settriple(result, mpd_sign(a), 0, ideal_exp);
        mpd_qfinalize(result, ctx, status);
        return;
    }
    if (mpd_isnegative(a)) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    mpd_maxcontext(&maxcontext);
    prec = ctx->prec + 1;

    if (!mpd_qcopy(&c, a, status)) {
        goto malloc_error;
    }
    c.exp = 0;

    if (a->exp & 1) {
        if (!mpd_qshiftl(&c, &c, 1, status)) {
            goto malloc_error;
        }
        l = (a->digits >> 1) + 1;
    }
    else {
        l = (a->digits + 1) >> 1;
    }

    shift = prec - l;
    if (shift >= 0) {
        if (!mpd_qshiftl(&c, &c, 2*shift, status)) {
            goto malloc_error;
        }
        exact = 1;
    }
    else {
        exact = !mpd_qshiftr_inplace(&c, -2*shift);
    }

    ideal_exp -= shift;

    /* find result = floor(sqrt(c)) using Newton's method */
    if (!mpd_qshiftl(result, &one, prec, status)) {
        goto malloc_error;
    }

    while (1) {
        _mpd_qdivmod(&q, &r, &c, result, &maxcontext, &maxcontext.status);
        if (mpd_isspecial(result) || mpd_isspecial(&q)) {
            mpd_seterror(result, maxcontext.status&MPD_Errors, status);
            goto out;
        }
        if (_mpd_cmp(result, &q) <= 0) {
            break;
        }
        _mpd_qadd_exact(result, result, &q, &maxcontext, &maxcontext.status);
        if (mpd_isspecial(result)) {
            mpd_seterror(result, maxcontext.status&MPD_Errors, status);
            goto out;
        }
        _mpd_qdivmod(result, &r, result, &two, &maxcontext, &maxcontext.status);
    }

    if (exact) {
        _mpd_qmul_exact(&r, result, result, &maxcontext, &maxcontext.status);
        if (mpd_isspecial(&r)) {
            mpd_seterror(result, maxcontext.status&MPD_Errors, status);
            goto out;
        }
        exact = (_mpd_cmp(&r, &c) == 0);
    }

    if (exact) {
        if (shift >= 0) {
            mpd_qshiftr_inplace(result, shift);
        }
        else {
            if (!mpd_qshiftl(result, result, -shift, status)) {
                goto malloc_error;
            }
        }
        ideal_exp += shift;
    }
    else {
        int lsd = (int)mpd_lsd(result->data[0]);
        if (lsd == 0 || lsd == 5) {
            result->data[0] += 1;
        }
    }

    result->exp = ideal_exp;


out:
    mpd_del(&c);
    mpd_del(&q);
    mpd_del(&r);
    maxcontext = *ctx;
    maxcontext.round = MPD_ROUND_HALF_EVEN;
    mpd_qfinalize(result, &maxcontext, status);
    return;

malloc_error:
    mpd_seterror(result, MPD_Malloc_error, status);
    goto out;
}


/******************************************************************************/
/*                              Base conversions                              */
/******************************************************************************/

/* Space needed to represent an integer mpd_t in base 'base'. */
size_t
mpd_sizeinbase(const mpd_t *a, uint32_t base)
{
    double x;
    size_t digits;

    assert(mpd_isinteger(a));
    assert(base >= 2);

    if (mpd_iszero(a)) {
        return 1;
    }

    digits = a->digits+a->exp;
    assert(digits > 0);

#ifdef CONFIG_64
    /* ceil(2711437152599294 / log10(2)) + 4 == 2**53 */
    if (digits > 2711437152599294ULL) {
        return SIZE_MAX;
    }
#endif

    x = (double)digits / log10(base);
    return (x > SIZE_MAX-1) ? SIZE_MAX : (size_t)x + 1;
}

/* Space needed to import a base 'base' integer of length 'srclen'. */
static mpd_ssize_t
_mpd_importsize(size_t srclen, uint32_t base)
{
    double x;

    assert(srclen > 0);
    assert(base >= 2);

#if SIZE_MAX == UINT64_MAX
    if (srclen > (1ULL<<53)) {
        return MPD_SSIZE_MAX;
    }
#endif

    x = (double)srclen * (log10(base)/MPD_RDIGITS);
    return (x >= MPD_MAXIMPORT) ? MPD_SSIZE_MAX : (mpd_ssize_t)x + 1;
}

static uint8_t
mpd_resize_u16(uint16_t **w, size_t nmemb)
{
    uint8_t err = 0;
    *w = mpd_realloc(*w, nmemb, sizeof **w, &err);
    return !err;
}

static uint8_t
mpd_resize_u32(uint32_t **w, size_t nmemb)
{
    uint8_t err = 0;
    *w = mpd_realloc(*w, nmemb, sizeof **w, &err);
    return !err;
}

static size_t
_baseconv_to_u16(uint16_t **w, size_t wlen, mpd_uint_t wbase,
                 mpd_uint_t *u, mpd_ssize_t ulen)
{
    size_t n = 0;

    assert(wlen > 0 && ulen > 0);
    assert(wbase <= (1U<<16));

    do {
        if (n >= wlen) {
            if (!mpd_resize_u16(w, n+1)) {
                return SIZE_MAX;
            }
            wlen = n+1;
        }
        (*w)[n++] = (uint16_t)_mpd_shortdiv(u, u, ulen, wbase);
        /* ulen is at least 1. u[ulen-1] can only be zero if ulen == 1. */
        ulen = _mpd_real_size(u, ulen);

    } while (u[ulen-1] != 0);

    return n;
}

static size_t
_coeff_from_u16(mpd_t *w, mpd_ssize_t wlen,
                const mpd_uint_t *u, size_t ulen, uint32_t ubase,
                uint32_t *status)
{
    mpd_ssize_t n = 0;
    mpd_uint_t carry;

    assert(wlen > 0 && ulen > 0);
    assert(ubase <= (1U<<16));

    w->data[n++] = u[--ulen];
    while (--ulen != SIZE_MAX) {
        carry = _mpd_shortmul_c(w->data, w->data, n, ubase);
        if (carry) {
            if (n >= wlen) {
                if (!mpd_qresize(w, n+1, status)) {
                    return SIZE_MAX;
                }
                wlen = n+1;
            }
            w->data[n++] = carry;
        }
        carry = _mpd_shortadd(w->data, n, u[ulen]);
        if (carry) {
            if (n >= wlen) {
                if (!mpd_qresize(w, n+1, status)) {
                    return SIZE_MAX;
                }
                wlen = n+1;
            }
            w->data[n++] = carry;
        }
    }

    return n;
}

/* target base wbase < source base ubase */
static size_t
_baseconv_to_smaller(uint32_t **w, size_t wlen, uint32_t wbase,
                     mpd_uint_t *u, mpd_ssize_t ulen, mpd_uint_t ubase)
{
    size_t n = 0;

    assert(wlen > 0 && ulen > 0);
    assert(wbase < ubase);

    do {
        if (n >= wlen) {
            if (!mpd_resize_u32(w, n+1)) {
                return SIZE_MAX;
            }
            wlen = n+1;
        }
        (*w)[n++] = (uint32_t)_mpd_shortdiv_b(u, u, ulen, wbase, ubase);
        /* ulen is at least 1. u[ulen-1] can only be zero if ulen == 1. */
        ulen = _mpd_real_size(u, ulen);

    } while (u[ulen-1] != 0);

    return n;
}

#ifdef CONFIG_32
/* target base 'wbase' == source base 'ubase' */
static size_t
_copy_equal_base(uint32_t **w, size_t wlen,
                 const uint32_t *u, size_t ulen)
{
    if (wlen < ulen) {
        if (!mpd_resize_u32(w, ulen)) {
            return SIZE_MAX;
        }
    }

    memcpy(*w, u, ulen * (sizeof **w));
    return ulen;
}

/* target base 'wbase' > source base 'ubase' */
static size_t
_baseconv_to_larger(uint32_t **w, size_t wlen, mpd_uint_t wbase,
                    const mpd_uint_t *u, size_t ulen, mpd_uint_t ubase)
{
    size_t n = 0;
    mpd_uint_t carry;

    assert(wlen > 0 && ulen > 0);
    assert(ubase < wbase);

    (*w)[n++] = u[--ulen];
    while (--ulen != SIZE_MAX) {
        carry = _mpd_shortmul_b(*w, *w, n, ubase, wbase);
        if (carry) {
            if (n >= wlen) {
                if (!mpd_resize_u32(w, n+1)) {
                    return SIZE_MAX;
                }
                wlen = n+1;
            }
            (*w)[n++] = carry;
        }
        carry = _mpd_shortadd_b(*w, n, u[ulen], wbase);
        if (carry) {
            if (n >= wlen) {
                if (!mpd_resize_u32(w, n+1)) {
                    return SIZE_MAX;
                }
                wlen = n+1;
            }
            (*w)[n++] = carry;
        }
    }

    return n;
}

/* target base wbase < source base ubase */
static size_t
_coeff_from_larger_base(mpd_t *w, size_t wlen, mpd_uint_t wbase,
                        mpd_uint_t *u, mpd_ssize_t ulen, mpd_uint_t ubase,
                        uint32_t *status)
{
    size_t n = 0;

    assert(wlen > 0 && ulen > 0);
    assert(wbase < ubase);

    do {
        if (n >= wlen) {
            if (!mpd_qresize(w, n+1, status)) {
                return SIZE_MAX;
            }
            wlen = n+1;
        }
        w->data[n++] = (uint32_t)_mpd_shortdiv_b(u, u, ulen, wbase, ubase);
        /* ulen is at least 1. u[ulen-1] can only be zero if ulen == 1. */
        ulen = _mpd_real_size(u, ulen);

    } while (u[ulen-1] != 0);

    return n;
}
#endif

/* target base 'wbase' > source base 'ubase' */
static size_t
_coeff_from_smaller_base(mpd_t *w, mpd_ssize_t wlen, mpd_uint_t wbase,
                         const uint32_t *u, size_t ulen, mpd_uint_t ubase,
                         uint32_t *status)
{
    mpd_ssize_t n = 0;
    mpd_uint_t carry;

    assert(wlen > 0 && ulen > 0);
    assert(wbase > ubase);

    w->data[n++] = u[--ulen];
    while (--ulen != SIZE_MAX) {
        carry = _mpd_shortmul_b(w->data, w->data, n, ubase, wbase);
        if (carry) {
            if (n >= wlen) {
                if (!mpd_qresize(w, n+1, status)) {
                    return SIZE_MAX;
                }
                wlen = n+1;
            }
            w->data[n++] = carry;
        }
        carry = _mpd_shortadd_b(w->data, n, u[ulen], wbase);
        if (carry) {
            if (n >= wlen) {
                if (!mpd_qresize(w, n+1, status)) {
                    return SIZE_MAX;
                }
                wlen = n+1;
            }
            w->data[n++] = carry;
        }
    }

    return n;
}

/*
 * Convert an integer mpd_t to a multiprecision integer with base <= 2**16.
 * The least significant word of the result is (*rdata)[0].
 *
 * If rdata is NULL, space is allocated by the function and rlen is irrelevant.
 * In case of an error any allocated storage is freed and rdata is set back to
 * NULL.
 *
 * If rdata is non-NULL, it MUST be allocated by one of libmpdec's allocation
 * functions and rlen MUST be correct. If necessary, the function will resize
 * rdata. In case of an error the caller must free rdata.
 *
 * Return value: In case of success, the exact length of rdata, SIZE_MAX
 * otherwise.
 */
size_t
mpd_qexport_u16(uint16_t **rdata, size_t rlen, uint32_t rbase,
                const mpd_t *src, uint32_t *status)
{
    MPD_NEW_STATIC(tsrc,0,0,0,0);
    int alloc = 0; /* rdata == NULL */
    size_t n;

    assert(rbase <= (1U<<16));

    if (mpd_isspecial(src) || !_mpd_isint(src)) {
        *status |= MPD_Invalid_operation;
        return SIZE_MAX;
    }

    if (*rdata == NULL) {
        rlen = mpd_sizeinbase(src, rbase);
        if (rlen == SIZE_MAX) {
            *status |= MPD_Invalid_operation;
            return SIZE_MAX;
        }
        *rdata = mpd_alloc(rlen, sizeof **rdata);
        if (*rdata == NULL) {
            goto malloc_error;
        }
        alloc = 1;
    }

    if (mpd_iszero(src)) {
        **rdata = 0;
        return 1;
    }

    if (src->exp >= 0) {
        if (!mpd_qshiftl(&tsrc, src, src->exp, status)) {
            goto malloc_error;
        }
    }
    else {
        if (mpd_qshiftr(&tsrc, src, -src->exp, status) == MPD_UINT_MAX) {
            goto malloc_error;
        }
    }

    n = _baseconv_to_u16(rdata, rlen, rbase, tsrc.data, tsrc.len);
    if (n == SIZE_MAX) {
        goto malloc_error;
    }


out:
    mpd_del(&tsrc);
    return n;

malloc_error:
    if (alloc) {
        mpd_free(*rdata);
        *rdata = NULL;
    }
    n = SIZE_MAX;
    *status |= MPD_Malloc_error;
    goto out;
}

/*
 * Convert an integer mpd_t to a multiprecision integer with base<=UINT32_MAX.
 * The least significant word of the result is (*rdata)[0].
 *
 * If rdata is NULL, space is allocated by the function and rlen is irrelevant.
 * In case of an error any allocated storage is freed and rdata is set back to
 * NULL.
 *
 * If rdata is non-NULL, it MUST be allocated by one of libmpdec's allocation
 * functions and rlen MUST be correct. If necessary, the function will resize
 * rdata. In case of an error the caller must free rdata.
 *
 * Return value: In case of success, the exact length of rdata, SIZE_MAX
 * otherwise.
 */
size_t
mpd_qexport_u32(uint32_t **rdata, size_t rlen, uint32_t rbase,
                const mpd_t *src, uint32_t *status)
{
    MPD_NEW_STATIC(tsrc,0,0,0,0);
    int alloc = 0; /* rdata == NULL */
    size_t n;

    if (mpd_isspecial(src) || !_mpd_isint(src)) {
        *status |= MPD_Invalid_operation;
        return SIZE_MAX;
    }

    if (*rdata == NULL) {
        rlen = mpd_sizeinbase(src, rbase);
        if (rlen == SIZE_MAX) {
            *status |= MPD_Invalid_operation;
            return SIZE_MAX;
        }
        *rdata = mpd_alloc(rlen, sizeof **rdata);
        if (*rdata == NULL) {
            goto malloc_error;
        }
        alloc = 1;
    }

    if (mpd_iszero(src)) {
        **rdata = 0;
        return 1;
    }

    if (src->exp >= 0) {
        if (!mpd_qshiftl(&tsrc, src, src->exp, status)) {
            goto malloc_error;
        }
    }
    else {
        if (mpd_qshiftr(&tsrc, src, -src->exp, status) == MPD_UINT_MAX) {
            goto malloc_error;
        }
    }

#ifdef CONFIG_64
    n = _baseconv_to_smaller(rdata, rlen, rbase,
                             tsrc.data, tsrc.len, MPD_RADIX);
#else
    if (rbase == MPD_RADIX) {
        n = _copy_equal_base(rdata, rlen, tsrc.data, tsrc.len);
    }
    else if (rbase < MPD_RADIX) {
        n = _baseconv_to_smaller(rdata, rlen, rbase,
                                 tsrc.data, tsrc.len, MPD_RADIX);
    }
    else {
        n = _baseconv_to_larger(rdata, rlen, rbase,
                                tsrc.data, tsrc.len, MPD_RADIX);
    }
#endif

    if (n == SIZE_MAX) {
        goto malloc_error;
    }


out:
    mpd_del(&tsrc);
    return n;

malloc_error:
    if (alloc) {
        mpd_free(*rdata);
        *rdata = NULL;
    }
    n = SIZE_MAX;
    *status |= MPD_Malloc_error;
    goto out;
}


/*
 * Converts a multiprecision integer with base <= UINT16_MAX+1 to an mpd_t.
 * The least significant word of the source is srcdata[0].
 */
void
mpd_qimport_u16(mpd_t *result,
                const uint16_t *srcdata, size_t srclen,
                uint8_t srcsign, uint32_t srcbase,
                const mpd_context_t *ctx, uint32_t *status)
{
    mpd_uint_t *usrc; /* uint16_t src copied to an mpd_uint_t array */
    mpd_ssize_t rlen; /* length of the result */
    size_t n;

    assert(srclen > 0);
    assert(srcbase <= (1U<<16));

    rlen = _mpd_importsize(srclen, srcbase);
    if (rlen == MPD_SSIZE_MAX) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    usrc = mpd_alloc((mpd_size_t)srclen, sizeof *usrc);
    if (usrc == NULL) {
        mpd_seterror(result, MPD_Malloc_error, status);
        return;
    }
    for (n = 0; n < srclen; n++) {
        usrc[n] = srcdata[n];
    }

    if (!mpd_qresize(result, rlen, status)) {
        goto finish;
    }

    n = _coeff_from_u16(result, rlen, usrc, srclen, srcbase, status);
    if (n == SIZE_MAX) {
        goto finish;
    }

    mpd_set_flags(result, srcsign);
    result->exp = 0;
    result->len = n;
    mpd_setdigits(result);

    mpd_qresize(result, result->len, status);
    mpd_qfinalize(result, ctx, status);


finish:
    mpd_free(usrc);
}

/*
 * Converts a multiprecision integer with base <= UINT32_MAX to an mpd_t.
 * The least significant word of the source is srcdata[0].
 */
void
mpd_qimport_u32(mpd_t *result,
                const uint32_t *srcdata, size_t srclen,
                uint8_t srcsign, uint32_t srcbase,
                const mpd_context_t *ctx, uint32_t *status)
{
    mpd_ssize_t rlen; /* length of the result */
    size_t n;

    assert(srclen > 0);

    rlen = _mpd_importsize(srclen, srcbase);
    if (rlen == MPD_SSIZE_MAX) {
        mpd_seterror(result, MPD_Invalid_operation, status);
        return;
    }

    if (!mpd_qresize(result, rlen, status)) {
        return;
    }

#ifdef CONFIG_64
    n = _coeff_from_smaller_base(result, rlen, MPD_RADIX,
                                 srcdata, srclen, srcbase,
                                 status);
#else
    if (srcbase == MPD_RADIX) {
        if (!mpd_qresize(result, srclen, status)) {
            return;
        }
        memcpy(result->data, srcdata, srclen * (sizeof *srcdata));
        n = srclen;
    }
    else if (srcbase < MPD_RADIX) {
        n = _coeff_from_smaller_base(result, rlen, MPD_RADIX,
                                     srcdata, srclen, srcbase,
                                     status);
    }
    else {
        mpd_uint_t *usrc = mpd_alloc((mpd_size_t)srclen, sizeof *usrc);
        if (usrc == NULL) {
            mpd_seterror(result, MPD_Malloc_error, status);
            return;
        }
        for (n = 0; n < srclen; n++) {
            usrc[n] = srcdata[n];
        }

        n = _coeff_from_larger_base(result, rlen, MPD_RADIX,
                                    usrc, (mpd_ssize_t)srclen, srcbase,
                                    status);
        mpd_free(usrc);
    }
#endif

    if (n == SIZE_MAX) {
        return;
    }

    mpd_set_flags(result, srcsign);
    result->exp = 0;
    result->len = n;
    mpd_setdigits(result);

    mpd_qresize(result, result->len, status);
    mpd_qfinalize(result, ctx, status);
}



