1/*
2 * Copyright (c) 2008-2020 Stefan Krah. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28
29#include "mpdecimal.h"
30
31#include <assert.h>
32#include <limits.h>
33#include <math.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37
38#include "basearith.h"
39#include "bits.h"
40#include "constants.h"
41#include "convolute.h"
42#include "crt.h"
43#include "mpalloc.h"
44#include "typearith.h"
45
46#ifdef PPRO
47  #if defined(_MSC_VER)
48    #include <float.h>
49    #pragma float_control(precise, on)
50    #pragma fenv_access(on)
51  #elif !defined(__OpenBSD__) && !defined(__NetBSD__)
52    /* C99 */
53    #include <fenv.h>
54    #pragma STDC FENV_ACCESS ON
55  #endif
56#endif
57
58
59/* Disable warning that is part of -Wextra since gcc 7.0. */
60#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && __GNUC__ >= 7
61  #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
62#endif
63
64
65#if defined(_MSC_VER)
66  #define ALWAYS_INLINE __forceinline
67#elif defined (__IBMC__) || defined(LEGACY_COMPILER)
68  #define ALWAYS_INLINE
69  #undef inline
70  #define inline
71#else
72  #ifdef TEST_COVERAGE
73    #define ALWAYS_INLINE
74  #else
75    #define ALWAYS_INLINE inline __attribute__ ((always_inline))
76  #endif
77#endif
78
79
80#define MPD_NEWTONDIV_CUTOFF 1024L
81
82#define MPD_NEW_STATIC(name, flags, exp, digits, len) \
83        mpd_uint_t name##_data[MPD_MINALLOC_MAX];                    \
84        mpd_t name = {flags|MPD_STATIC|MPD_STATIC_DATA, exp, digits, \
85                      len, MPD_MINALLOC_MAX, name##_data}
86
87#define MPD_NEW_CONST(name, flags, exp, digits, len, alloc, initval) \
88        mpd_uint_t name##_data[alloc] = {initval};                   \
89        mpd_t name = {flags|MPD_STATIC|MPD_CONST_DATA, exp, digits,  \
90                      len, alloc, name##_data}
91
92#define MPD_NEW_SHARED(name, a) \
93        mpd_t name = {(a->flags&~MPD_DATAFLAGS)|MPD_STATIC|MPD_SHARED_DATA, \
94                      a->exp, a->digits, a->len, a->alloc, a->data}
95
96
97static mpd_uint_t data_one[1] = {1};
98static mpd_uint_t data_zero[1] = {0};
99static const mpd_t one = {MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1, data_one};
100static const mpd_t minus_one = {MPD_NEG|MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1,
101                                data_one};
102static const mpd_t zero = {MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1, data_zero};
103
104static inline void _mpd_check_exp(mpd_t *dec, const mpd_context_t *ctx,
105                                  uint32_t *status);
106static void _settriple(mpd_t *result, uint8_t sign, mpd_uint_t a,
107                       mpd_ssize_t exp);
108static inline mpd_ssize_t _mpd_real_size(mpd_uint_t *data, mpd_ssize_t size);
109
110static int _mpd_cmp_abs(const mpd_t *a, const mpd_t *b);
111
112static void _mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b,
113                      const mpd_context_t *ctx, uint32_t *status);
114static inline void _mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b,
115                             const mpd_context_t *ctx, uint32_t *status);
116static void _mpd_base_ndivmod(mpd_t *q, mpd_t *r, const mpd_t *a,
117                              const mpd_t *b, uint32_t *status);
118static inline void _mpd_qpow_uint(mpd_t *result, const mpd_t *base,
119                                  mpd_uint_t exp, uint8_t resultsign,
120                                  const mpd_context_t *ctx, uint32_t *status);
121
122static mpd_uint_t mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n);
123
124
125/******************************************************************************/
126/*                                  Version                                   */
127/******************************************************************************/
128
129const char *
130mpd_version(void)
131{
132    return MPD_VERSION;
133}
134
135
136/******************************************************************************/
137/*                  Performance critical inline functions                     */
138/******************************************************************************/
139
140#ifdef CONFIG_64
141/* Digits in a word, primarily useful for the most significant word. */
142ALWAYS_INLINE int
143mpd_word_digits(mpd_uint_t word)
144{
145    if (word < mpd_pow10[9]) {
146        if (word < mpd_pow10[4]) {
147            if (word < mpd_pow10[2]) {
148                return (word < mpd_pow10[1]) ? 1 : 2;
149            }
150            return (word < mpd_pow10[3]) ? 3 : 4;
151        }
152        if (word < mpd_pow10[6]) {
153            return (word < mpd_pow10[5]) ? 5 : 6;
154        }
155        if (word < mpd_pow10[8]) {
156            return (word < mpd_pow10[7]) ? 7 : 8;
157        }
158        return 9;
159    }
160    if (word < mpd_pow10[14]) {
161        if (word < mpd_pow10[11]) {
162            return (word < mpd_pow10[10]) ? 10 : 11;
163        }
164        if (word < mpd_pow10[13]) {
165            return (word < mpd_pow10[12]) ? 12 : 13;
166        }
167        return 14;
168    }
169    if (word < mpd_pow10[18]) {
170        if (word < mpd_pow10[16]) {
171            return (word < mpd_pow10[15]) ? 15 : 16;
172        }
173        return (word < mpd_pow10[17]) ? 17 : 18;
174    }
175
176    return (word < mpd_pow10[19]) ? 19 : 20;
177}
178#else
179ALWAYS_INLINE int
180mpd_word_digits(mpd_uint_t word)
181{
182    if (word < mpd_pow10[4]) {
183        if (word < mpd_pow10[2]) {
184            return (word < mpd_pow10[1]) ? 1 : 2;
185        }
186        return (word < mpd_pow10[3]) ? 3 : 4;
187    }
188    if (word < mpd_pow10[6]) {
189        return (word < mpd_pow10[5]) ? 5 : 6;
190    }
191    if (word < mpd_pow10[8]) {
192        return (word < mpd_pow10[7]) ? 7 : 8;
193    }
194
195    return (word < mpd_pow10[9]) ? 9 : 10;
196}
197#endif
198
199
200/* Adjusted exponent */
201ALWAYS_INLINE mpd_ssize_t
202mpd_adjexp(const mpd_t *dec)
203{
204    return (dec->exp + dec->digits) - 1;
205}
206
207/* Etiny */
208ALWAYS_INLINE mpd_ssize_t
209mpd_etiny(const mpd_context_t *ctx)
210{
211    return ctx->emin - (ctx->prec - 1);
212}
213
214/* Etop: used for folding down in IEEE clamping */
215ALWAYS_INLINE mpd_ssize_t
216mpd_etop(const mpd_context_t *ctx)
217{
218    return ctx->emax - (ctx->prec - 1);
219}
220
221/* Most significant word */
222ALWAYS_INLINE mpd_uint_t
223mpd_msword(const mpd_t *dec)
224{
225    assert(dec->len > 0);
226    return dec->data[dec->len-1];
227}
228
229/* Most significant digit of a word */
230inline mpd_uint_t
231mpd_msd(mpd_uint_t word)
232{
233    int n;
234
235    n = mpd_word_digits(word);
236    return word / mpd_pow10[n-1];
237}
238
239/* Least significant digit of a word */
240ALWAYS_INLINE mpd_uint_t
241mpd_lsd(mpd_uint_t word)
242{
243    return word % 10;
244}
245
246/* Coefficient size needed to store 'digits' */
247mpd_ssize_t
248mpd_digits_to_size(mpd_ssize_t digits)
249{
250    mpd_ssize_t q, r;
251
252    _mpd_idiv_word(&q, &r, digits, MPD_RDIGITS);
253    return (r == 0) ? q : q+1;
254}
255
256/* Number of digits in the exponent. Not defined for MPD_SSIZE_MIN. */
257inline int
258mpd_exp_digits(mpd_ssize_t exp)
259{
260    exp = (exp < 0) ? -exp : exp;
261    return mpd_word_digits(exp);
262}
263
264/* Canonical */
265ALWAYS_INLINE int
266mpd_iscanonical(const mpd_t *dec)
267{
268    (void)dec;
269    return 1;
270}
271
272/* Finite */
273ALWAYS_INLINE int
274mpd_isfinite(const mpd_t *dec)
275{
276    return !(dec->flags & MPD_SPECIAL);
277}
278
279/* Infinite */
280ALWAYS_INLINE int
281mpd_isinfinite(const mpd_t *dec)
282{
283    return dec->flags & MPD_INF;
284}
285
286/* NaN */
287ALWAYS_INLINE int
288mpd_isnan(const mpd_t *dec)
289{
290    return dec->flags & (MPD_NAN|MPD_SNAN);
291}
292
293/* Negative */
294ALWAYS_INLINE int
295mpd_isnegative(const mpd_t *dec)
296{
297    return dec->flags & MPD_NEG;
298}
299
300/* Positive */
301ALWAYS_INLINE int
302mpd_ispositive(const mpd_t *dec)
303{
304    return !(dec->flags & MPD_NEG);
305}
306
307/* qNaN */
308ALWAYS_INLINE int
309mpd_isqnan(const mpd_t *dec)
310{
311    return dec->flags & MPD_NAN;
312}
313
314/* Signed */
315ALWAYS_INLINE int
316mpd_issigned(const mpd_t *dec)
317{
318    return dec->flags & MPD_NEG;
319}
320
321/* sNaN */
322ALWAYS_INLINE int
323mpd_issnan(const mpd_t *dec)
324{
325    return dec->flags & MPD_SNAN;
326}
327
328/* Special */
329ALWAYS_INLINE int
330mpd_isspecial(const mpd_t *dec)
331{
332    return dec->flags & MPD_SPECIAL;
333}
334
335/* Zero */
336ALWAYS_INLINE int
337mpd_iszero(const mpd_t *dec)
338{
339    return !mpd_isspecial(dec) && mpd_msword(dec) == 0;
340}
341
342/* Test for zero when specials have been ruled out already */
343ALWAYS_INLINE int
344mpd_iszerocoeff(const mpd_t *dec)
345{
346    return mpd_msword(dec) == 0;
347}
348
349/* Normal */
350inline int
351mpd_isnormal(const mpd_t *dec, const mpd_context_t *ctx)
352{
353    if (mpd_isspecial(dec)) return 0;
354    if (mpd_iszerocoeff(dec)) return 0;
355
356    return mpd_adjexp(dec) >= ctx->emin;
357}
358
359/* Subnormal */
360inline int
361mpd_issubnormal(const mpd_t *dec, const mpd_context_t *ctx)
362{
363    if (mpd_isspecial(dec)) return 0;
364    if (mpd_iszerocoeff(dec)) return 0;
365
366    return mpd_adjexp(dec) < ctx->emin;
367}
368
369/* Odd word */
370ALWAYS_INLINE int
371mpd_isoddword(mpd_uint_t word)
372{
373    return word & 1;
374}
375
376/* Odd coefficient */
377ALWAYS_INLINE int
378mpd_isoddcoeff(const mpd_t *dec)
379{
380    return mpd_isoddword(dec->data[0]);
381}
382
383/* 0 if dec is positive, 1 if dec is negative */
384ALWAYS_INLINE uint8_t
385mpd_sign(const mpd_t *dec)
386{
387    return dec->flags & MPD_NEG;
388}
389
390/* 1 if dec is positive, -1 if dec is negative */
391ALWAYS_INLINE int
392mpd_arith_sign(const mpd_t *dec)
393{
394    return 1 - 2 * mpd_isnegative(dec);
395}
396
397/* Radix */
398ALWAYS_INLINE long
399mpd_radix(void)
400{
401    return 10;
402}
403
404/* Dynamic decimal */
405ALWAYS_INLINE int
406mpd_isdynamic(const mpd_t *dec)
407{
408    return !(dec->flags & MPD_STATIC);
409}
410
411/* Static decimal */
412ALWAYS_INLINE int
413mpd_isstatic(const mpd_t *dec)
414{
415    return dec->flags & MPD_STATIC;
416}
417
418/* Data of decimal is dynamic */
419ALWAYS_INLINE int
420mpd_isdynamic_data(const mpd_t *dec)
421{
422    return !(dec->flags & MPD_DATAFLAGS);
423}
424
425/* Data of decimal is static */
426ALWAYS_INLINE int
427mpd_isstatic_data(const mpd_t *dec)
428{
429    return dec->flags & MPD_STATIC_DATA;
430}
431
432/* Data of decimal is shared */
433ALWAYS_INLINE int
434mpd_isshared_data(const mpd_t *dec)
435{
436    return dec->flags & MPD_SHARED_DATA;
437}
438
439/* Data of decimal is const */
440ALWAYS_INLINE int
441mpd_isconst_data(const mpd_t *dec)
442{
443    return dec->flags & MPD_CONST_DATA;
444}
445
446
447/******************************************************************************/
448/*                         Inline memory handling                             */
449/******************************************************************************/
450
451/* Fill destination with zeros */
452ALWAYS_INLINE void
453mpd_uint_zero(mpd_uint_t *dest, mpd_size_t len)
454{
455    mpd_size_t i;
456
457    for (i = 0; i < len; i++) {
458        dest[i] = 0;
459    }
460}
461
462/* Free a decimal */
463ALWAYS_INLINE void
464mpd_del(mpd_t *dec)
465{
466    if (mpd_isdynamic_data(dec)) {
467        mpd_free(dec->data);
468    }
469    if (mpd_isdynamic(dec)) {
470        mpd_free(dec);
471    }
472}
473
474/*
475 * Resize the coefficient. Existing data up to 'nwords' is left untouched.
476 * Return 1 on success, 0 otherwise.
477 *
478 * Input invariant: MPD_MINALLOC <= result->alloc.
479 *
480 * Case nwords == result->alloc:
481 *     'result' is unchanged. Return 1.
482 *
483 * Case nwords > result->alloc:
484 *   Case realloc success:
485 *     The value of 'result' does not change. Return 1.
486 *   Case realloc failure:
487 *     'result' is NaN, status is updated with MPD_Malloc_error. Return 0.
488 *
489 * Case nwords < result->alloc:
490 *   Case is_static_data or realloc failure [1]:
491 *     'result' is unchanged. Return 1.
492 *   Case realloc success:
493 *     The value of result is undefined (expected). Return 1.
494 *
495 *
496 * [1] In that case the old (now oversized) area is still valid.
497 */
498ALWAYS_INLINE int
499mpd_qresize(mpd_t *result, mpd_ssize_t nwords, uint32_t *status)
500{
501    assert(!mpd_isconst_data(result)); /* illegal operation for a const */
502    assert(!mpd_isshared_data(result)); /* illegal operation for a shared */
503    assert(MPD_MINALLOC <= result->alloc);
504
505    nwords = (nwords <= MPD_MINALLOC) ? MPD_MINALLOC : nwords;
506    if (nwords == result->alloc) {
507        return 1;
508    }
509    if (mpd_isstatic_data(result)) {
510        if (nwords > result->alloc) {
511            return mpd_switch_to_dyn(result, nwords, status);
512        }
513        return 1;
514    }
515
516    return mpd_realloc_dyn(result, nwords, status);
517}
518
519/* Same as mpd_qresize, but do not set the result no NaN on failure. */
520static ALWAYS_INLINE int
521mpd_qresize_cxx(mpd_t *result, mpd_ssize_t nwords)
522{
523    assert(!mpd_isconst_data(result)); /* illegal operation for a const */
524    assert(!mpd_isshared_data(result)); /* illegal operation for a shared */
525    assert(MPD_MINALLOC <= result->alloc);
526
527    nwords = (nwords <= MPD_MINALLOC) ? MPD_MINALLOC : nwords;
528    if (nwords == result->alloc) {
529        return 1;
530    }
531    if (mpd_isstatic_data(result)) {
532        if (nwords > result->alloc) {
533            return mpd_switch_to_dyn_cxx(result, nwords);
534        }
535        return 1;
536    }
537
538    return mpd_realloc_dyn_cxx(result, nwords);
539}
540
541/* Same as mpd_qresize, but the complete coefficient (including the old
542 * memory area!) is initialized to zero. */
543ALWAYS_INLINE int
544mpd_qresize_zero(mpd_t *result, mpd_ssize_t nwords, uint32_t *status)
545{
546    assert(!mpd_isconst_data(result)); /* illegal operation for a const */
547    assert(!mpd_isshared_data(result)); /* illegal operation for a shared */
548    assert(MPD_MINALLOC <= result->alloc);
549
550    nwords = (nwords <= MPD_MINALLOC) ? MPD_MINALLOC : nwords;
551    if (nwords != result->alloc) {
552        if (mpd_isstatic_data(result)) {
553            if (nwords > result->alloc) {
554                return mpd_switch_to_dyn_zero(result, nwords, status);
555            }
556        }
557        else if (!mpd_realloc_dyn(result, nwords, status)) {
558            return 0;
559        }
560    }
561
562    mpd_uint_zero(result->data, nwords);
563    return 1;
564}
565
566/*
567 * Reduce memory size for the coefficient to MPD_MINALLOC. In theory,
568 * realloc may fail even when reducing the memory size. But in that case
569 * the old memory area is always big enough, so checking for MPD_Malloc_error
570 * is not imperative.
571 */
572ALWAYS_INLINE void
573mpd_minalloc(mpd_t *result)
574{
575    assert(!mpd_isconst_data(result)); /* illegal operation for a const */
576    assert(!mpd_isshared_data(result)); /* illegal operation for a shared */
577
578    if (!mpd_isstatic_data(result) && result->alloc > MPD_MINALLOC) {
579        uint8_t err = 0;
580        result->data = mpd_realloc(result->data, MPD_MINALLOC,
581                                   sizeof *result->data, &err);
582        if (!err) {
583            result->alloc = MPD_MINALLOC;
584        }
585    }
586}
587
588int
589mpd_resize(mpd_t *result, mpd_ssize_t nwords, mpd_context_t *ctx)
590{
591    uint32_t status = 0;
592    if (!mpd_qresize(result, nwords, &status)) {
593        mpd_addstatus_raise(ctx, status);
594        return 0;
595    }
596    return 1;
597}
598
599int
600mpd_resize_zero(mpd_t *result, mpd_ssize_t nwords, mpd_context_t *ctx)
601{
602    uint32_t status = 0;
603    if (!mpd_qresize_zero(result, nwords, &status)) {
604        mpd_addstatus_raise(ctx, status);
605        return 0;
606    }
607    return 1;
608}
609
610
611/******************************************************************************/
612/*                       Set attributes of a decimal                          */
613/******************************************************************************/
614
615/* Set digits. Assumption: result->len is initialized and > 0. */
616inline void
617mpd_setdigits(mpd_t *result)
618{
619    mpd_ssize_t wdigits = mpd_word_digits(mpd_msword(result));
620    result->digits = wdigits + (result->len-1) * MPD_RDIGITS;
621}
622
623/* Set sign */
624ALWAYS_INLINE void
625mpd_set_sign(mpd_t *result, uint8_t sign)
626{
627    result->flags &= ~MPD_NEG;
628    result->flags |= sign;
629}
630
631/* Copy sign from another decimal */
632ALWAYS_INLINE void
633mpd_signcpy(mpd_t *result, const mpd_t *a)
634{
635    uint8_t sign = a->flags&MPD_NEG;
636
637    result->flags &= ~MPD_NEG;
638    result->flags |= sign;
639}
640
641/* Set infinity */
642ALWAYS_INLINE void
643mpd_set_infinity(mpd_t *result)
644{
645    result->flags &= ~MPD_SPECIAL;
646    result->flags |= MPD_INF;
647}
648
649/* Set qNaN */
650ALWAYS_INLINE void
651mpd_set_qnan(mpd_t *result)
652{
653    result->flags &= ~MPD_SPECIAL;
654    result->flags |= MPD_NAN;
655}
656
657/* Set sNaN */
658ALWAYS_INLINE void
659mpd_set_snan(mpd_t *result)
660{
661    result->flags &= ~MPD_SPECIAL;
662    result->flags |= MPD_SNAN;
663}
664
665/* Set to negative */
666ALWAYS_INLINE void
667mpd_set_negative(mpd_t *result)
668{
669    result->flags |= MPD_NEG;
670}
671
672/* Set to positive */
673ALWAYS_INLINE void
674mpd_set_positive(mpd_t *result)
675{
676    result->flags &= ~MPD_NEG;
677}
678
679/* Set to dynamic */
680ALWAYS_INLINE void
681mpd_set_dynamic(mpd_t *result)
682{
683    result->flags &= ~MPD_STATIC;
684}
685
686/* Set to static */
687ALWAYS_INLINE void
688mpd_set_static(mpd_t *result)
689{
690    result->flags |= MPD_STATIC;
691}
692
693/* Set data to dynamic */
694ALWAYS_INLINE void
695mpd_set_dynamic_data(mpd_t *result)
696{
697    result->flags &= ~MPD_DATAFLAGS;
698}
699
700/* Set data to static */
701ALWAYS_INLINE void
702mpd_set_static_data(mpd_t *result)
703{
704    result->flags &= ~MPD_DATAFLAGS;
705    result->flags |= MPD_STATIC_DATA;
706}
707
708/* Set data to shared */
709ALWAYS_INLINE void
710mpd_set_shared_data(mpd_t *result)
711{
712    result->flags &= ~MPD_DATAFLAGS;
713    result->flags |= MPD_SHARED_DATA;
714}
715
716/* Set data to const */
717ALWAYS_INLINE void
718mpd_set_const_data(mpd_t *result)
719{
720    result->flags &= ~MPD_DATAFLAGS;
721    result->flags |= MPD_CONST_DATA;
722}
723
724/* Clear flags, preserving memory attributes. */
725ALWAYS_INLINE void
726mpd_clear_flags(mpd_t *result)
727{
728    result->flags &= (MPD_STATIC|MPD_DATAFLAGS);
729}
730
731/* Set flags, preserving memory attributes. */
732ALWAYS_INLINE void
733mpd_set_flags(mpd_t *result, uint8_t flags)
734{
735    result->flags &= (MPD_STATIC|MPD_DATAFLAGS);
736    result->flags |= flags;
737}
738
739/* Copy flags, preserving memory attributes of result. */
740ALWAYS_INLINE void
741mpd_copy_flags(mpd_t *result, const mpd_t *a)
742{
743    uint8_t aflags = a->flags;
744    result->flags &= (MPD_STATIC|MPD_DATAFLAGS);
745    result->flags |= (aflags & ~(MPD_STATIC|MPD_DATAFLAGS));
746}
747
748/* Initialize a workcontext from ctx. Set traps, flags and newtrap to 0. */
749static inline void
750mpd_workcontext(mpd_context_t *workctx, const mpd_context_t *ctx)
751{
752    workctx->prec = ctx->prec;
753    workctx->emax = ctx->emax;
754    workctx->emin = ctx->emin;
755    workctx->round = ctx->round;
756    workctx->traps = 0;
757    workctx->status = 0;
758    workctx->newtrap = 0;
759    workctx->clamp = ctx->clamp;
760    workctx->allcr = ctx->allcr;
761}
762
763
764/******************************************************************************/
765/*                  Getting and setting parts of decimals                     */
766/******************************************************************************/
767
768/* Flip the sign of a decimal */
769static inline void
770_mpd_negate(mpd_t *dec)
771{
772    dec->flags ^= MPD_NEG;
773}
774
775/* Set coefficient to zero */
776void
777mpd_zerocoeff(mpd_t *result)
778{
779    mpd_minalloc(result);
780    result->digits = 1;
781    result->len = 1;
782    result->data[0] = 0;
783}
784
785/* Set the coefficient to all nines. */
786void
787mpd_qmaxcoeff(mpd_t *result, const mpd_context_t *ctx, uint32_t *status)
788{
789    mpd_ssize_t len, r;
790
791    _mpd_idiv_word(&len, &r, ctx->prec, MPD_RDIGITS);
792    len = (r == 0) ? len : len+1;
793
794    if (!mpd_qresize(result, len, status)) {
795        return;
796    }
797
798    result->len = len;
799    result->digits = ctx->prec;
800
801    --len;
802    if (r > 0) {
803        result->data[len--] = mpd_pow10[r]-1;
804    }
805    for (; len >= 0; --len) {
806        result->data[len] = MPD_RADIX-1;
807    }
808}
809
810/*
811 * Cut off the most significant digits so that the rest fits in ctx->prec.
812 * Cannot fail.
813 */
814static void
815_mpd_cap(mpd_t *result, const mpd_context_t *ctx)
816{
817    uint32_t dummy;
818    mpd_ssize_t len, r;
819
820    if (result->len > 0 && result->digits > ctx->prec) {
821        _mpd_idiv_word(&len, &r, ctx->prec, MPD_RDIGITS);
822        len = (r == 0) ? len : len+1;
823
824        if (r != 0) {
825            result->data[len-1] %= mpd_pow10[r];
826        }
827
828        len = _mpd_real_size(result->data, len);
829        /* resize to fewer words cannot fail */
830        mpd_qresize(result, len, &dummy);
831        result->len = len;
832        mpd_setdigits(result);
833    }
834    if (mpd_iszero(result)) {
835        _settriple(result, mpd_sign(result), 0, result->exp);
836    }
837}
838
839/*
840 * Cut off the most significant digits of a NaN payload so that the rest
841 * fits in ctx->prec - ctx->clamp. Cannot fail.
842 */
843static void
844_mpd_fix_nan(mpd_t *result, const mpd_context_t *ctx)
845{
846    uint32_t dummy;
847    mpd_ssize_t prec;
848    mpd_ssize_t len, r;
849
850    prec = ctx->prec - ctx->clamp;
851    if (result->len > 0 && result->digits > prec) {
852        if (prec == 0) {
853            mpd_minalloc(result);
854            result->len = result->digits = 0;
855        }
856        else {
857            _mpd_idiv_word(&len, &r, prec, MPD_RDIGITS);
858            len = (r == 0) ? len : len+1;
859
860            if (r != 0) {
861                 result->data[len-1] %= mpd_pow10[r];
862            }
863
864            len = _mpd_real_size(result->data, len);
865            /* resize to fewer words cannot fail */
866            mpd_qresize(result, len, &dummy);
867            result->len = len;
868            mpd_setdigits(result);
869            if (mpd_iszerocoeff(result)) {
870                /* NaN0 is not a valid representation */
871                result->len = result->digits = 0;
872            }
873        }
874    }
875}
876
877/*
878 * Get n most significant digits from a decimal, where 0 < n <= MPD_UINT_DIGITS.
879 * Assumes MPD_UINT_DIGITS == MPD_RDIGITS+1, which is true for 32 and 64 bit
880 * machines.
881 *
882 * The result of the operation will be in lo. If the operation is impossible,
883 * hi will be nonzero. This is used to indicate an error.
884 */
885static inline void
886_mpd_get_msdigits(mpd_uint_t *hi, mpd_uint_t *lo, const mpd_t *dec,
887                  unsigned int n)
888{
889    mpd_uint_t r, tmp;
890
891    assert(0 < n && n <= MPD_RDIGITS+1);
892
893    _mpd_div_word(&tmp, &r, dec->digits, MPD_RDIGITS);
894    r = (r == 0) ? MPD_RDIGITS : r; /* digits in the most significant word */
895
896    *hi = 0;
897    *lo = dec->data[dec->len-1];
898    if (n <= r) {
899        *lo /= mpd_pow10[r-n];
900    }
901    else if (dec->len > 1) {
902        /* at this point 1 <= r < n <= MPD_RDIGITS+1 */
903        _mpd_mul_words(hi, lo, *lo, mpd_pow10[n-r]);
904        tmp = dec->data[dec->len-2] / mpd_pow10[MPD_RDIGITS-(n-r)];
905        *lo = *lo + tmp;
906        if (*lo < tmp) (*hi)++;
907    }
908}
909
910
911/******************************************************************************/
912/*                   Gathering information about a decimal                    */
913/******************************************************************************/
914
915/* The real size of the coefficient without leading zero words. */
916static inline mpd_ssize_t
917_mpd_real_size(mpd_uint_t *data, mpd_ssize_t size)
918{
919    while (size > 1 && data[size-1] == 0) {
920        size--;
921    }
922
923    return size;
924}
925
926/* Return number of trailing zeros. No errors are possible. */
927mpd_ssize_t
928mpd_trail_zeros(const mpd_t *dec)
929{
930    mpd_uint_t word;
931    mpd_ssize_t i, tz = 0;
932
933    for (i=0; i < dec->len; ++i) {
934        if (dec->data[i] != 0) {
935            word = dec->data[i];
936            tz = i * MPD_RDIGITS;
937            while (word % 10 == 0) {
938                word /= 10;
939                tz++;
940            }
941            break;
942        }
943    }
944
945    return tz;
946}
947
948/* Integer: Undefined for specials */
949static int
950_mpd_isint(const mpd_t *dec)
951{
952    mpd_ssize_t tz;
953
954    if (mpd_iszerocoeff(dec)) {
955        return 1;
956    }
957
958    tz = mpd_trail_zeros(dec);
959    return (dec->exp + tz >= 0);
960}
961
962/* Integer */
963int
964mpd_isinteger(const mpd_t *dec)
965{
966    if (mpd_isspecial(dec)) {
967        return 0;
968    }
969    return _mpd_isint(dec);
970}
971
972/* Word is a power of 10 */
973static int
974mpd_word_ispow10(mpd_uint_t word)
975{
976    int n;
977
978    n = mpd_word_digits(word);
979    if (word == mpd_pow10[n-1]) {
980        return 1;
981    }
982
983    return 0;
984}
985
986/* Coefficient is a power of 10 */
987static int
988mpd_coeff_ispow10(const mpd_t *dec)
989{
990    if (mpd_word_ispow10(mpd_msword(dec))) {
991        if (_mpd_isallzero(dec->data, dec->len-1)) {
992            return 1;
993        }
994    }
995
996    return 0;
997}
998
999/* All digits of a word are nines */
1000static int
1001mpd_word_isallnine(mpd_uint_t word)
1002{
1003    int n;
1004
1005    n = mpd_word_digits(word);
1006    if (word == mpd_pow10[n]-1) {
1007        return 1;
1008    }
1009
1010    return 0;
1011}
1012
1013/* All digits of the coefficient are nines */
1014static int
1015mpd_coeff_isallnine(const mpd_t *dec)
1016{
1017    if (mpd_word_isallnine(mpd_msword(dec))) {
1018        if (_mpd_isallnine(dec->data, dec->len-1)) {
1019            return 1;
1020        }
1021    }
1022
1023    return 0;
1024}
1025
1026/* Odd decimal: Undefined for non-integers! */
1027int
1028mpd_isodd(const mpd_t *dec)
1029{
1030    mpd_uint_t q, r;
1031    assert(mpd_isinteger(dec));
1032    if (mpd_iszerocoeff(dec)) return 0;
1033    if (dec->exp < 0) {
1034        _mpd_div_word(&q, &r, -dec->exp, MPD_RDIGITS);
1035        q = dec->data[q] / mpd_pow10[r];
1036        return mpd_isoddword(q);
1037    }
1038    return dec->exp == 0 && mpd_isoddword(dec->data[0]);
1039}
1040
1041/* Even: Undefined for non-integers! */
1042int
1043mpd_iseven(const mpd_t *dec)
1044{
1045    return !mpd_isodd(dec);
1046}
1047
1048/******************************************************************************/
1049/*                      Getting and setting decimals                          */
1050/******************************************************************************/
1051
1052/* Internal function: Set a static decimal from a triple, no error checking. */
1053static void
1054_ssettriple(mpd_t *result, uint8_t sign, mpd_uint_t a, mpd_ssize_t exp)
1055{
1056    mpd_set_flags(result, sign);
1057    result->exp = exp;
1058    _mpd_div_word(&result->data[1], &result->data[0], a, MPD_RADIX);
1059    result->len = (result->data[1] == 0) ? 1 : 2;
1060    mpd_setdigits(result);
1061}
1062
1063/* Internal function: Set a decimal from a triple, no error checking. */
1064static void
1065_settriple(mpd_t *result, uint8_t sign, mpd_uint_t a, mpd_ssize_t exp)
1066{
1067    mpd_minalloc(result);
1068    mpd_set_flags(result, sign);
1069    result->exp = exp;
1070    _mpd_div_word(&result->data[1], &result->data[0], a, MPD_RADIX);
1071    result->len = (result->data[1] == 0) ? 1 : 2;
1072    mpd_setdigits(result);
1073}
1074
1075/* Set a special number from a triple */
1076void
1077mpd_setspecial(mpd_t *result, uint8_t sign, uint8_t type)
1078{
1079    mpd_minalloc(result);
1080    result->flags &= ~(MPD_NEG|MPD_SPECIAL);
1081    result->flags |= (sign|type);
1082    result->exp = result->digits = result->len = 0;
1083}
1084
1085/* Set result of NaN with an error status */
1086void
1087mpd_seterror(mpd_t *result, uint32_t flags, uint32_t *status)
1088{
1089    mpd_minalloc(result);
1090    mpd_set_qnan(result);
1091    mpd_set_positive(result);
1092    result->exp = result->digits = result->len = 0;
1093    *status |= flags;
1094}
1095
1096/* quietly set a static decimal from an mpd_ssize_t */
1097void
1098mpd_qsset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx,
1099                uint32_t *status)
1100{
1101    mpd_uint_t u;
1102    uint8_t sign = MPD_POS;
1103
1104    if (a < 0) {
1105        if (a == MPD_SSIZE_MIN) {
1106            u = (mpd_uint_t)MPD_SSIZE_MAX +
1107                (-(MPD_SSIZE_MIN+MPD_SSIZE_MAX));
1108        }
1109        else {
1110            u = -a;
1111        }
1112        sign = MPD_NEG;
1113    }
1114    else {
1115        u = a;
1116    }
1117    _ssettriple(result, sign, u, 0);
1118    mpd_qfinalize(result, ctx, status);
1119}
1120
1121/* quietly set a static decimal from an mpd_uint_t */
1122void
1123mpd_qsset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx,
1124               uint32_t *status)
1125{
1126    _ssettriple(result, MPD_POS, a, 0);
1127    mpd_qfinalize(result, ctx, status);
1128}
1129
1130/* quietly set a static decimal from an int32_t */
1131void
1132mpd_qsset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx,
1133              uint32_t *status)
1134{
1135    mpd_qsset_ssize(result, a, ctx, status);
1136}
1137
1138/* quietly set a static decimal from a uint32_t */
1139void
1140mpd_qsset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx,
1141              uint32_t *status)
1142{
1143    mpd_qsset_uint(result, a, ctx, status);
1144}
1145
1146#ifdef CONFIG_64
1147/* quietly set a static decimal from an int64_t */
1148void
1149mpd_qsset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx,
1150              uint32_t *status)
1151{
1152    mpd_qsset_ssize(result, a, ctx, status);
1153}
1154
1155/* quietly set a static decimal from a uint64_t */
1156void
1157mpd_qsset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx,
1158              uint32_t *status)
1159{
1160    mpd_qsset_uint(result, a, ctx, status);
1161}
1162#endif
1163
1164/* quietly set a decimal from an mpd_ssize_t */
1165void
1166mpd_qset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx,
1167               uint32_t *status)
1168{
1169    mpd_minalloc(result);
1170    mpd_qsset_ssize(result, a, ctx, status);
1171}
1172
1173/* quietly set a decimal from an mpd_uint_t */
1174void
1175mpd_qset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx,
1176              uint32_t *status)
1177{
1178    _settriple(result, MPD_POS, a, 0);
1179    mpd_qfinalize(result, ctx, status);
1180}
1181
1182/* quietly set a decimal from an int32_t */
1183void
1184mpd_qset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx,
1185             uint32_t *status)
1186{
1187    mpd_qset_ssize(result, a, ctx, status);
1188}
1189
1190/* quietly set a decimal from a uint32_t */
1191void
1192mpd_qset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx,
1193             uint32_t *status)
1194{
1195    mpd_qset_uint(result, a, ctx, status);
1196}
1197
1198#if defined(CONFIG_32) && !defined(LEGACY_COMPILER)
1199/* set a decimal from a uint64_t */
1200static void
1201_c32setu64(mpd_t *result, uint64_t u, uint8_t sign, uint32_t *status)
1202{
1203    mpd_uint_t w[3];
1204    uint64_t q;
1205    int i, len;
1206
1207    len = 0;
1208    do {
1209        q = u / MPD_RADIX;
1210        w[len] = (mpd_uint_t)(u - q * MPD_RADIX);
1211        u = q; len++;
1212    } while (u != 0);
1213
1214    if (!mpd_qresize(result, len, status)) {
1215        return;
1216    }
1217    for (i = 0; i < len; i++) {
1218        result->data[i] = w[i];
1219    }
1220
1221    mpd_set_flags(result, sign);
1222    result->exp = 0;
1223    result->len = len;
1224    mpd_setdigits(result);
1225}
1226
1227static void
1228_c32_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx,
1229              uint32_t *status)
1230{
1231    _c32setu64(result, a, MPD_POS, status);
1232    mpd_qfinalize(result, ctx, status);
1233}
1234
1235/* set a decimal from an int64_t */
1236static void
1237_c32_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx,
1238              uint32_t *status)
1239{
1240    uint64_t u;
1241    uint8_t sign = MPD_POS;
1242
1243    if (a < 0) {
1244        if (a == INT64_MIN) {
1245            u = (uint64_t)INT64_MAX + (-(INT64_MIN+INT64_MAX));
1246        }
1247        else {
1248            u = -a;
1249        }
1250        sign = MPD_NEG;
1251    }
1252    else {
1253        u = a;
1254    }
1255    _c32setu64(result, u, sign, status);
1256    mpd_qfinalize(result, ctx, status);
1257}
1258#endif /* CONFIG_32 && !LEGACY_COMPILER */
1259
1260#ifndef LEGACY_COMPILER
1261/* quietly set a decimal from an int64_t */
1262void
1263mpd_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx,
1264             uint32_t *status)
1265{
1266#ifdef CONFIG_64
1267    mpd_qset_ssize(result, a, ctx, status);
1268#else
1269    _c32_qset_i64(result, a, ctx, status);
1270#endif
1271}
1272
1273/* quietly set a decimal from an int64_t, use a maxcontext for conversion */
1274void
1275mpd_qset_i64_exact(mpd_t *result, int64_t a, uint32_t *status)
1276{
1277    mpd_context_t maxcontext;
1278
1279    mpd_maxcontext(&maxcontext);
1280#ifdef CONFIG_64
1281    mpd_qset_ssize(result, a, &maxcontext, status);
1282#else
1283    _c32_qset_i64(result, a, &maxcontext, status);
1284#endif
1285
1286    if (*status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
1287        /* we want exact results */
1288        mpd_seterror(result, MPD_Invalid_operation, status);
1289    }
1290    *status &= MPD_Errors;
1291}
1292
1293/* quietly set a decimal from a uint64_t */
1294void
1295mpd_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx,
1296             uint32_t *status)
1297{
1298#ifdef CONFIG_64
1299    mpd_qset_uint(result, a, ctx, status);
1300#else
1301    _c32_qset_u64(result, a, ctx, status);
1302#endif
1303}
1304
1305/* quietly set a decimal from a uint64_t, use a maxcontext for conversion */
1306void
1307mpd_qset_u64_exact(mpd_t *result, uint64_t a, uint32_t *status)
1308{
1309    mpd_context_t maxcontext;
1310
1311    mpd_maxcontext(&maxcontext);
1312#ifdef CONFIG_64
1313    mpd_qset_uint(result, a, &maxcontext, status);
1314#else
1315    _c32_qset_u64(result, a, &maxcontext, status);
1316#endif
1317
1318    if (*status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
1319        /* we want exact results */
1320        mpd_seterror(result, MPD_Invalid_operation, status);
1321    }
1322    *status &= MPD_Errors;
1323}
1324#endif /* !LEGACY_COMPILER */
1325
1326/*
1327 * Quietly get an mpd_uint_t from a decimal. Assumes
1328 * MPD_UINT_DIGITS == MPD_RDIGITS+1, which is true for
1329 * 32 and 64 bit machines.
1330 *
1331 * If the operation is impossible, MPD_Invalid_operation is set.
1332 */
1333static mpd_uint_t
1334_mpd_qget_uint(int use_sign, const mpd_t *a, uint32_t *status)
1335{
1336    mpd_t tmp;
1337    mpd_uint_t tmp_data[2];
1338    mpd_uint_t lo, hi;
1339
1340    if (mpd_isspecial(a)) {
1341        *status |= MPD_Invalid_operation;
1342        return MPD_UINT_MAX;
1343    }
1344    if (mpd_iszero(a)) {
1345        return 0;
1346    }
1347    if (use_sign && mpd_isnegative(a)) {
1348        *status |= MPD_Invalid_operation;
1349        return MPD_UINT_MAX;
1350    }
1351
1352    if (a->digits+a->exp > MPD_RDIGITS+1) {
1353        *status |= MPD_Invalid_operation;
1354        return MPD_UINT_MAX;
1355    }
1356
1357    if (a->exp < 0) {
1358        if (!_mpd_isint(a)) {
1359            *status |= MPD_Invalid_operation;
1360            return MPD_UINT_MAX;
1361        }
1362        /* At this point a->digits+a->exp <= MPD_RDIGITS+1,
1363         * so the shift fits. */
1364        tmp.data = tmp_data;
1365        tmp.flags = MPD_STATIC|MPD_STATIC_DATA;
1366        tmp.alloc = 2;
1367        mpd_qsshiftr(&tmp, a, -a->exp);
1368        tmp.exp = 0;
1369        a = &tmp;
1370    }
1371
1372    _mpd_get_msdigits(&hi, &lo, a, MPD_RDIGITS+1);
1373    if (hi) {
1374        *status |= MPD_Invalid_operation;
1375        return MPD_UINT_MAX;
1376    }
1377
1378    if (a->exp > 0) {
1379        _mpd_mul_words(&hi, &lo, lo, mpd_pow10[a->exp]);
1380        if (hi) {
1381            *status |= MPD_Invalid_operation;
1382            return MPD_UINT_MAX;
1383        }
1384    }
1385
1386    return lo;
1387}
1388
1389/*
1390 * Sets Invalid_operation for:
1391 *   - specials
1392 *   - negative numbers (except negative zero)
1393 *   - non-integers
1394 *   - overflow
1395 */
1396mpd_uint_t
1397mpd_qget_uint(const mpd_t *a, uint32_t *status)
1398{
1399    return _mpd_qget_uint(1, a, status);
1400}
1401
1402/* Same as above, but gets the absolute value, i.e. the sign is ignored. */
1403mpd_uint_t
1404mpd_qabs_uint(const mpd_t *a, uint32_t *status)
1405{
1406    return _mpd_qget_uint(0, a, status);
1407}
1408
1409/* quietly get an mpd_ssize_t from a decimal */
1410mpd_ssize_t
1411mpd_qget_ssize(const mpd_t *a, uint32_t *status)
1412{
1413    uint32_t workstatus = 0;
1414    mpd_uint_t u;
1415    int isneg;
1416
1417    u = mpd_qabs_uint(a, &workstatus);
1418    if (workstatus&MPD_Invalid_operation) {
1419        *status |= workstatus;
1420        return MPD_SSIZE_MAX;
1421    }
1422
1423    isneg = mpd_isnegative(a);
1424    if (u <= MPD_SSIZE_MAX) {
1425        return isneg ? -((mpd_ssize_t)u) : (mpd_ssize_t)u;
1426    }
1427    else if (isneg && u+(MPD_SSIZE_MIN+MPD_SSIZE_MAX) == MPD_SSIZE_MAX) {
1428        return MPD_SSIZE_MIN;
1429    }
1430
1431    *status |= MPD_Invalid_operation;
1432    return MPD_SSIZE_MAX;
1433}
1434
1435#if defined(CONFIG_32) && !defined(LEGACY_COMPILER)
1436/*
1437 * Quietly get a uint64_t from a decimal. If the operation is impossible,
1438 * MPD_Invalid_operation is set.
1439 */
1440static uint64_t
1441_c32_qget_u64(int use_sign, const mpd_t *a, uint32_t *status)
1442{
1443    MPD_NEW_STATIC(tmp,0,0,20,3);
1444    mpd_context_t maxcontext;
1445    uint64_t ret;
1446
1447    tmp_data[0] = 709551615;
1448    tmp_data[1] = 446744073;
1449    tmp_data[2] = 18;
1450
1451    if (mpd_isspecial(a)) {
1452        *status |= MPD_Invalid_operation;
1453        return UINT64_MAX;
1454    }
1455    if (mpd_iszero(a)) {
1456        return 0;
1457    }
1458    if (use_sign && mpd_isnegative(a)) {
1459        *status |= MPD_Invalid_operation;
1460        return UINT64_MAX;
1461    }
1462    if (!_mpd_isint(a)) {
1463        *status |= MPD_Invalid_operation;
1464        return UINT64_MAX;
1465    }
1466
1467    if (_mpd_cmp_abs(a, &tmp) > 0) {
1468        *status |= MPD_Invalid_operation;
1469        return UINT64_MAX;
1470    }
1471
1472    mpd_maxcontext(&maxcontext);
1473    mpd_qrescale(&tmp, a, 0, &maxcontext, &maxcontext.status);
1474    maxcontext.status &= ~MPD_Rounded;
1475    if (maxcontext.status != 0) {
1476        *status |= (maxcontext.status|MPD_Invalid_operation); /* GCOV_NOT_REACHED */
1477        return UINT64_MAX; /* GCOV_NOT_REACHED */
1478    }
1479
1480    ret = 0;
1481    switch (tmp.len) {
1482    case 3:
1483        ret += (uint64_t)tmp_data[2] * 1000000000000000000ULL;
1484    case 2:
1485        ret += (uint64_t)tmp_data[1] * 1000000000ULL;
1486    case 1:
1487        ret += tmp_data[0];
1488        break;
1489    default:
1490        abort(); /* GCOV_NOT_REACHED */
1491    }
1492
1493    return ret;
1494}
1495
1496static int64_t
1497_c32_qget_i64(const mpd_t *a, uint32_t *status)
1498{
1499    uint64_t u;
1500    int isneg;
1501
1502    u = _c32_qget_u64(0, a, status);
1503    if (*status&MPD_Invalid_operation) {
1504        return INT64_MAX;
1505    }
1506
1507    isneg = mpd_isnegative(a);
1508    if (u <= INT64_MAX) {
1509        return isneg ? -((int64_t)u) : (int64_t)u;
1510    }
1511    else if (isneg && u+(INT64_MIN+INT64_MAX) == INT64_MAX) {
1512        return INT64_MIN;
1513    }
1514
1515    *status |= MPD_Invalid_operation;
1516    return INT64_MAX;
1517}
1518#endif /* CONFIG_32 && !LEGACY_COMPILER */
1519
1520#ifdef CONFIG_64
1521/* quietly get a uint64_t from a decimal */
1522uint64_t
1523mpd_qget_u64(const mpd_t *a, uint32_t *status)
1524{
1525    return mpd_qget_uint(a, status);
1526}
1527
1528/* quietly get an int64_t from a decimal */
1529int64_t
1530mpd_qget_i64(const mpd_t *a, uint32_t *status)
1531{
1532    return mpd_qget_ssize(a, status);
1533}
1534
1535/* quietly get a uint32_t from a decimal */
1536uint32_t
1537mpd_qget_u32(const mpd_t *a, uint32_t *status)
1538{
1539    uint32_t workstatus = 0;
1540    uint64_t x = mpd_qget_uint(a, &workstatus);
1541
1542    if (workstatus&MPD_Invalid_operation) {
1543        *status |= workstatus;
1544        return UINT32_MAX;
1545    }
1546    if (x > UINT32_MAX) {
1547        *status |= MPD_Invalid_operation;
1548        return UINT32_MAX;
1549    }
1550
1551    return (uint32_t)x;
1552}
1553
1554/* quietly get an int32_t from a decimal */
1555int32_t
1556mpd_qget_i32(const mpd_t *a, uint32_t *status)
1557{
1558    uint32_t workstatus = 0;
1559    int64_t x = mpd_qget_ssize(a, &workstatus);
1560
1561    if (workstatus&MPD_Invalid_operation) {
1562        *status |= workstatus;
1563        return INT32_MAX;
1564    }
1565    if (x < INT32_MIN || x > INT32_MAX) {
1566        *status |= MPD_Invalid_operation;
1567        return INT32_MAX;
1568    }
1569
1570    return (int32_t)x;
1571}
1572#else
1573#ifndef LEGACY_COMPILER
1574/* quietly get a uint64_t from a decimal */
1575uint64_t
1576mpd_qget_u64(const mpd_t *a, uint32_t *status)
1577{
1578    uint32_t workstatus = 0;
1579    uint64_t x = _c32_qget_u64(1, a, &workstatus);
1580    *status |= workstatus;
1581    return x;
1582}
1583
1584/* quietly get an int64_t from a decimal */
1585int64_t
1586mpd_qget_i64(const mpd_t *a, uint32_t *status)
1587{
1588    uint32_t workstatus = 0;
1589    int64_t x = _c32_qget_i64(a, &workstatus);
1590    *status |= workstatus;
1591    return x;
1592}
1593#endif
1594
1595/* quietly get a uint32_t from a decimal */
1596uint32_t
1597mpd_qget_u32(const mpd_t *a, uint32_t *status)
1598{
1599    return mpd_qget_uint(a, status);
1600}
1601
1602/* quietly get an int32_t from a decimal */
1603int32_t
1604mpd_qget_i32(const mpd_t *a, uint32_t *status)
1605{
1606    return mpd_qget_ssize(a, status);
1607}
1608#endif
1609
1610
1611/******************************************************************************/
1612/*         Filtering input of functions, finalizing output of functions       */
1613/******************************************************************************/
1614
1615/*
1616 * Check if the operand is NaN, copy to result and return 1 if this is
1617 * the case. Copying can fail since NaNs are allowed to have a payload that
1618 * does not fit in MPD_MINALLOC.
1619 */
1620int
1621mpd_qcheck_nan(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
1622               uint32_t *status)
1623{
1624    if (mpd_isnan(a)) {
1625        *status |= mpd_issnan(a) ? MPD_Invalid_operation : 0;
1626        mpd_qcopy(result, a, status);
1627        mpd_set_qnan(result);
1628        _mpd_fix_nan(result, ctx);
1629        return 1;
1630    }
1631    return 0;
1632}
1633
1634/*
1635 * Check if either operand is NaN, copy to result and return 1 if this
1636 * is the case. Copying can fail since NaNs are allowed to have a payload
1637 * that does not fit in MPD_MINALLOC.
1638 */
1639int
1640mpd_qcheck_nans(mpd_t *result, const mpd_t *a, const mpd_t *b,
1641                const mpd_context_t *ctx, uint32_t *status)
1642{
1643    if ((a->flags|b->flags)&(MPD_NAN|MPD_SNAN)) {
1644        const mpd_t *choice = b;
1645        if (mpd_issnan(a)) {
1646            choice = a;
1647            *status |= MPD_Invalid_operation;
1648        }
1649        else if (mpd_issnan(b)) {
1650            *status |= MPD_Invalid_operation;
1651        }
1652        else if (mpd_isqnan(a)) {
1653            choice = a;
1654        }
1655        mpd_qcopy(result, choice, status);
1656        mpd_set_qnan(result);
1657        _mpd_fix_nan(result, ctx);
1658        return 1;
1659    }
1660    return 0;
1661}
1662
1663/*
1664 * Check if one of the operands is NaN, copy to result and return 1 if this
1665 * is the case. Copying can fail since NaNs are allowed to have a payload
1666 * that does not fit in MPD_MINALLOC.
1667 */
1668static int
1669mpd_qcheck_3nans(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c,
1670                 const mpd_context_t *ctx, uint32_t *status)
1671{
1672    if ((a->flags|b->flags|c->flags)&(MPD_NAN|MPD_SNAN)) {
1673        const mpd_t *choice = c;
1674        if (mpd_issnan(a)) {
1675            choice = a;
1676            *status |= MPD_Invalid_operation;
1677        }
1678        else if (mpd_issnan(b)) {
1679            choice = b;
1680            *status |= MPD_Invalid_operation;
1681        }
1682        else if (mpd_issnan(c)) {
1683            *status |= MPD_Invalid_operation;
1684        }
1685        else if (mpd_isqnan(a)) {
1686            choice = a;
1687        }
1688        else if (mpd_isqnan(b)) {
1689            choice = b;
1690        }
1691        mpd_qcopy(result, choice, status);
1692        mpd_set_qnan(result);
1693        _mpd_fix_nan(result, ctx);
1694        return 1;
1695    }
1696    return 0;
1697}
1698
1699/* Check if rounding digit 'rnd' leads to an increment. */
1700static inline int
1701_mpd_rnd_incr(const mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx)
1702{
1703    int ld;
1704
1705    switch (ctx->round) {
1706    case MPD_ROUND_DOWN: case MPD_ROUND_TRUNC:
1707        return 0;
1708    case MPD_ROUND_HALF_UP:
1709        return (rnd >= 5);
1710    case MPD_ROUND_HALF_EVEN:
1711        return (rnd > 5) || ((rnd == 5) && mpd_isoddcoeff(dec));
1712    case MPD_ROUND_CEILING:
1713        return !(rnd == 0 || mpd_isnegative(dec));
1714    case MPD_ROUND_FLOOR:
1715        return !(rnd == 0 || mpd_ispositive(dec));
1716    case MPD_ROUND_HALF_DOWN:
1717        return (rnd > 5);
1718    case MPD_ROUND_UP:
1719        return !(rnd == 0);
1720    case MPD_ROUND_05UP:
1721        ld = (int)mpd_lsd(dec->data[0]);
1722        return (!(rnd == 0) && (ld == 0 || ld == 5));
1723    default:
1724        /* Without a valid context, further results will be undefined. */
1725        return 0; /* GCOV_NOT_REACHED */
1726    }
1727}
1728
1729/*
1730 * Apply rounding to a decimal that has been right-shifted into a full
1731 * precision decimal. If an increment leads to an overflow of the precision,
1732 * adjust the coefficient and the exponent and check the new exponent for
1733 * overflow.
1734 */
1735static inline void
1736_mpd_apply_round(mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx,
1737                 uint32_t *status)
1738{
1739    if (_mpd_rnd_incr(dec, rnd, ctx)) {
1740        /* We have a number with exactly ctx->prec digits. The increment
1741         * can only lead to an overflow if the decimal is all nines. In
1742         * that case, the result is a power of ten with prec+1 digits.
1743         *
1744         * If the precision is a multiple of MPD_RDIGITS, this situation is
1745         * detected by _mpd_baseincr returning a carry.
1746         * If the precision is not a multiple of MPD_RDIGITS, we have to
1747         * check if the result has one digit too many.
1748         */
1749        mpd_uint_t carry = _mpd_baseincr(dec->data, dec->len);
1750        if (carry) {
1751            dec->data[dec->len-1] = mpd_pow10[MPD_RDIGITS-1];
1752            dec->exp += 1;
1753            _mpd_check_exp(dec, ctx, status);
1754            return;
1755        }
1756        mpd_setdigits(dec);
1757        if (dec->digits > ctx->prec) {
1758            mpd_qshiftr_inplace(dec, 1);
1759            dec->exp += 1;
1760            dec->digits = ctx->prec;
1761            _mpd_check_exp(dec, ctx, status);
1762        }
1763    }
1764}
1765
1766/*
1767 * Apply rounding to a decimal. Allow overflow of the precision.
1768 */
1769static inline void
1770_mpd_apply_round_excess(mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx,
1771                        uint32_t *status)
1772{
1773    if (_mpd_rnd_incr(dec, rnd, ctx)) {
1774        mpd_uint_t carry = _mpd_baseincr(dec->data, dec->len);
1775        if (carry) {
1776            if (!mpd_qresize(dec, dec->len+1, status)) {
1777                return;
1778            }
1779            dec->data[dec->len] = 1;
1780            dec->len += 1;
1781        }
1782        mpd_setdigits(dec);
1783    }
1784}
1785
1786/*
1787 * Apply rounding to a decimal that has been right-shifted into a decimal
1788 * with full precision or less. Return failure if an increment would
1789 * overflow the precision.
1790 */
1791static inline int
1792_mpd_apply_round_fit(mpd_t *dec, mpd_uint_t rnd, const mpd_context_t *ctx,
1793                     uint32_t *status)
1794{
1795    if (_mpd_rnd_incr(dec, rnd, ctx)) {
1796        mpd_uint_t carry = _mpd_baseincr(dec->data, dec->len);
1797        if (carry) {
1798            if (!mpd_qresize(dec, dec->len+1, status)) {
1799                return 0;
1800            }
1801            dec->data[dec->len] = 1;
1802            dec->len += 1;
1803        }
1804        mpd_setdigits(dec);
1805        if (dec->digits > ctx->prec) {
1806            mpd_seterror(dec, MPD_Invalid_operation, status);
1807            return 0;
1808        }
1809    }
1810    return 1;
1811}
1812
1813/* Check a normal number for overflow, underflow, clamping. If the operand
1814   is modified, it will be zero, special or (sub)normal with a coefficient
1815   that fits into the current context precision. */
1816static inline void
1817_mpd_check_exp(mpd_t *dec, const mpd_context_t *ctx, uint32_t *status)
1818{
1819    mpd_ssize_t adjexp, etiny, shift;
1820    int rnd;
1821
1822    adjexp = mpd_adjexp(dec);
1823    if (adjexp > ctx->emax) {
1824
1825        if (mpd_iszerocoeff(dec)) {
1826            dec->exp = ctx->emax;
1827            if (ctx->clamp) {
1828                dec->exp -= (ctx->prec-1);
1829            }
1830            mpd_zerocoeff(dec);
1831            *status |= MPD_Clamped;
1832            return;
1833        }
1834
1835        switch (ctx->round) {
1836        case MPD_ROUND_HALF_UP: case MPD_ROUND_HALF_EVEN:
1837        case MPD_ROUND_HALF_DOWN: case MPD_ROUND_UP:
1838        case MPD_ROUND_TRUNC:
1839            mpd_setspecial(dec, mpd_sign(dec), MPD_INF);
1840            break;
1841        case MPD_ROUND_DOWN: case MPD_ROUND_05UP:
1842            mpd_qmaxcoeff(dec, ctx, status);
1843            dec->exp = ctx->emax - ctx->prec + 1;
1844            break;
1845        case MPD_ROUND_CEILING:
1846            if (mpd_isnegative(dec)) {
1847                mpd_qmaxcoeff(dec, ctx, status);
1848                dec->exp = ctx->emax - ctx->prec + 1;
1849            }
1850            else {
1851                mpd_setspecial(dec, MPD_POS, MPD_INF);
1852            }
1853            break;
1854        case MPD_ROUND_FLOOR:
1855            if (mpd_ispositive(dec)) {
1856                mpd_qmaxcoeff(dec, ctx, status);
1857                dec->exp = ctx->emax - ctx->prec + 1;
1858            }
1859            else {
1860                mpd_setspecial(dec, MPD_NEG, MPD_INF);
1861            }
1862            break;
1863        default: /* debug */
1864            abort(); /* GCOV_NOT_REACHED */
1865        }
1866
1867        *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded;
1868
1869    } /* fold down */
1870    else if (ctx->clamp && dec->exp > mpd_etop(ctx)) {
1871        /* At this point adjexp=exp+digits-1 <= emax and exp > etop=emax-prec+1:
1872         *   (1) shift = exp -emax+prec-1 > 0
1873         *   (2) digits+shift = exp+digits-1 - emax + prec <= prec */
1874        shift = dec->exp - mpd_etop(ctx);
1875        if (!mpd_qshiftl(dec, dec, shift, status)) {
1876            return;
1877        }
1878        dec->exp -= shift;
1879        *status |= MPD_Clamped;
1880        if (!mpd_iszerocoeff(dec) && adjexp < ctx->emin) {
1881            /* Underflow is impossible, since exp < etiny=emin-prec+1
1882             * and exp > etop=emax-prec+1 would imply emax < emin. */
1883            *status |= MPD_Subnormal;
1884        }
1885    }
1886    else if (adjexp < ctx->emin) {
1887
1888        etiny = mpd_etiny(ctx);
1889
1890        if (mpd_iszerocoeff(dec)) {
1891            if (dec->exp < etiny) {
1892                dec->exp = etiny;
1893                mpd_zerocoeff(dec);
1894                *status |= MPD_Clamped;
1895            }
1896            return;
1897        }
1898
1899        *status |= MPD_Subnormal;
1900        if (dec->exp < etiny) {
1901            /* At this point adjexp=exp+digits-1 < emin and exp < etiny=emin-prec+1:
1902             *   (1) shift = emin-prec+1 - exp > 0
1903             *   (2) digits-shift = exp+digits-1 - emin + prec < prec */
1904            shift = etiny - dec->exp;
1905            rnd = (int)mpd_qshiftr_inplace(dec, shift);
1906            dec->exp = etiny;
1907            /* We always have a spare digit in case of an increment. */
1908            _mpd_apply_round_excess(dec, rnd, ctx, status);
1909            *status |= MPD_Rounded;
1910            if (rnd) {
1911                *status |= (MPD_Inexact|MPD_Underflow);
1912                if (mpd_iszerocoeff(dec)) {
1913                    mpd_zerocoeff(dec);
1914                    *status |= MPD_Clamped;
1915                }
1916            }
1917        }
1918        /* Case exp >= etiny=emin-prec+1:
1919         *   (1) adjexp=exp+digits-1 < emin
1920         *   (2) digits < emin-exp+1 <= prec */
1921    }
1922}
1923
1924/* Transcendental functions do not always set Underflow reliably,
1925 * since they only use as much precision as is necessary for correct
1926 * rounding. If a result like 1.0000000000e-101 is finalized, there
1927 * is no rounding digit that would trigger Underflow. But we can
1928 * assume Inexact, so a short check suffices. */
1929static inline void
1930mpd_check_underflow(mpd_t *dec, const mpd_context_t *ctx, uint32_t *status)
1931{
1932    if (mpd_adjexp(dec) < ctx->emin && !mpd_iszero(dec) &&
1933        dec->exp < mpd_etiny(ctx)) {
1934        *status |= MPD_Underflow;
1935    }
1936}
1937
1938/* Check if a normal number must be rounded after the exponent has been checked. */
1939static inline void
1940_mpd_check_round(mpd_t *dec, const mpd_context_t *ctx, uint32_t *status)
1941{
1942    mpd_uint_t rnd;
1943    mpd_ssize_t shift;
1944
1945    /* must handle specials: _mpd_check_exp() can produce infinities or NaNs */
1946    if (mpd_isspecial(dec)) {
1947        return;
1948    }
1949
1950    if (dec->digits > ctx->prec) {
1951        shift = dec->digits - ctx->prec;
1952        rnd = mpd_qshiftr_inplace(dec, shift);
1953        dec->exp += shift;
1954        _mpd_apply_round(dec, rnd, ctx, status);
1955        *status |= MPD_Rounded;
1956        if (rnd) {
1957            *status |= MPD_Inexact;
1958        }
1959    }
1960}
1961
1962/* Finalize all operations. */
1963void
1964mpd_qfinalize(mpd_t *result, const mpd_context_t *ctx, uint32_t *status)
1965{
1966    if (mpd_isspecial(result)) {
1967        if (mpd_isnan(result)) {
1968            _mpd_fix_nan(result, ctx);
1969        }
1970        return;
1971    }
1972
1973    _mpd_check_exp(result, ctx, status);
1974    _mpd_check_round(result, ctx, status);
1975}
1976
1977
1978/******************************************************************************/
1979/*                                 Copying                                    */
1980/******************************************************************************/
1981
1982/* Internal function: Copy a decimal, share data with src: USE WITH CARE! */
1983static inline void
1984_mpd_copy_shared(mpd_t *dest, const mpd_t *src)
1985{
1986    dest->flags = src->flags;
1987    dest->exp = src->exp;
1988    dest->digits = src->digits;
1989    dest->len = src->len;
1990    dest->alloc = src->alloc;
1991    dest->data = src->data;
1992
1993    mpd_set_shared_data(dest);
1994}
1995
1996/*
1997 * Copy a decimal. In case of an error, status is set to MPD_Malloc_error.
1998 */
1999int
2000mpd_qcopy(mpd_t *result, const mpd_t *a, uint32_t *status)
2001{
2002    if (result == a) return 1;
2003
2004    if (!mpd_qresize(result, a->len, status)) {
2005        return 0;
2006    }
2007
2008    mpd_copy_flags(result, a);
2009    result->exp = a->exp;
2010    result->digits = a->digits;
2011    result->len = a->len;
2012    memcpy(result->data, a->data, a->len * (sizeof *result->data));
2013
2014    return 1;
2015}
2016
2017/* Same as mpd_qcopy, but do not set the result to NaN on failure. */
2018int
2019mpd_qcopy_cxx(mpd_t *result, const mpd_t *a)
2020{
2021    if (result == a) return 1;
2022
2023    if (!mpd_qresize_cxx(result, a->len)) {
2024        return 0;
2025    }
2026
2027    mpd_copy_flags(result, a);
2028    result->exp = a->exp;
2029    result->digits = a->digits;
2030    result->len = a->len;
2031    memcpy(result->data, a->data, a->len * (sizeof *result->data));
2032
2033    return 1;
2034}
2035
2036/*
2037 * Copy to a decimal with a static buffer. The caller has to make sure that
2038 * the buffer is big enough. Cannot fail.
2039 */
2040static void
2041mpd_qcopy_static(mpd_t *result, const mpd_t *a)
2042{
2043    if (result == a) return;
2044
2045    memcpy(result->data, a->data, a->len * (sizeof *result->data));
2046
2047    mpd_copy_flags(result, a);
2048    result->exp = a->exp;
2049    result->digits = a->digits;
2050    result->len = a->len;
2051}
2052
2053/*
2054 * Return a newly allocated copy of the operand. In case of an error,
2055 * status is set to MPD_Malloc_error and the return value is NULL.
2056 */
2057mpd_t *
2058mpd_qncopy(const mpd_t *a)
2059{
2060    mpd_t *result;
2061
2062    if ((result = mpd_qnew_size(a->len)) == NULL) {
2063        return NULL;
2064    }
2065    memcpy(result->data, a->data, a->len * (sizeof *result->data));
2066    mpd_copy_flags(result, a);
2067    result->exp = a->exp;
2068    result->digits = a->digits;
2069    result->len = a->len;
2070
2071    return result;
2072}
2073
2074/*
2075 * Copy a decimal and set the sign to positive. In case of an error, the
2076 * status is set to MPD_Malloc_error.
2077 */
2078int
2079mpd_qcopy_abs(mpd_t *result, const mpd_t *a, uint32_t *status)
2080{
2081    if (!mpd_qcopy(result, a, status)) {
2082        return 0;
2083    }
2084    mpd_set_positive(result);
2085    return 1;
2086}
2087
2088/*
2089 * Copy a decimal and negate the sign. In case of an error, the
2090 * status is set to MPD_Malloc_error.
2091 */
2092int
2093mpd_qcopy_negate(mpd_t *result, const mpd_t *a, uint32_t *status)
2094{
2095    if (!mpd_qcopy(result, a, status)) {
2096        return 0;
2097    }
2098    _mpd_negate(result);
2099    return 1;
2100}
2101
2102/*
2103 * Copy a decimal, setting the sign of the first operand to the sign of the
2104 * second operand. In case of an error, the status is set to MPD_Malloc_error.
2105 */
2106int
2107mpd_qcopy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, uint32_t *status)
2108{
2109    uint8_t sign_b = mpd_sign(b); /* result may equal b! */
2110
2111    if (!mpd_qcopy(result, a, status)) {
2112        return 0;
2113    }
2114    mpd_set_sign(result, sign_b);
2115    return 1;
2116}
2117
2118
2119/******************************************************************************/
2120/*                                Comparisons                                 */
2121/******************************************************************************/
2122
2123/*
2124 * For all functions that compare two operands and return an int the usual
2125 * convention applies to the return value:
2126 *
2127 * -1 if op1 < op2
2128 *  0 if op1 == op2
2129 *  1 if op1 > op2
2130 *
2131 *  INT_MAX for error
2132 */
2133
2134
2135/* Convenience macro. If a and b are not equal, return from the calling
2136 * function with the correct comparison value. */
2137#define CMP_EQUAL_OR_RETURN(a, b)  \
2138        if (a != b) {              \
2139                if (a < b) {       \
2140                        return -1; \
2141                }                  \
2142                return 1;          \
2143        }
2144
2145/*
2146 * Compare the data of big and small. This function does the equivalent
2147 * of first shifting small to the left and then comparing the data of
2148 * big and small, except that no allocation for the left shift is needed.
2149 */
2150static int
2151_mpd_basecmp(mpd_uint_t *big, mpd_uint_t *small, mpd_size_t n, mpd_size_t m,
2152             mpd_size_t shift)
2153{
2154#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
2155    /* spurious uninitialized warnings */
2156    mpd_uint_t l=l, lprev=lprev, h=h;
2157#else
2158    mpd_uint_t l, lprev, h;
2159#endif
2160    mpd_uint_t q, r;
2161    mpd_uint_t ph, x;
2162
2163    assert(m > 0 && n >= m && shift > 0);
2164
2165    _mpd_div_word(&q, &r, (mpd_uint_t)shift, MPD_RDIGITS);
2166
2167    if (r != 0) {
2168
2169        ph = mpd_pow10[r];
2170
2171        --m; --n;
2172        _mpd_divmod_pow10(&h, &lprev, small[m--], MPD_RDIGITS-r);
2173        if (h != 0) {
2174            CMP_EQUAL_OR_RETURN(big[n], h)
2175            --n;
2176        }
2177        for (; m != MPD_SIZE_MAX; m--,n--) {
2178            _mpd_divmod_pow10(&h, &l, small[m], MPD_RDIGITS-r);
2179            x = ph * lprev + h;
2180            CMP_EQUAL_OR_RETURN(big[n], x)
2181            lprev = l;
2182        }
2183        x = ph * lprev;
2184        CMP_EQUAL_OR_RETURN(big[q], x)
2185    }
2186    else {
2187        while (--m != MPD_SIZE_MAX) {
2188            CMP_EQUAL_OR_RETURN(big[m+q], small[m])
2189        }
2190    }
2191
2192    return !_mpd_isallzero(big, q);
2193}
2194
2195/* Compare two decimals with the same adjusted exponent. */
2196static int
2197_mpd_cmp_same_adjexp(const mpd_t *a, const mpd_t *b)
2198{
2199    mpd_ssize_t shift, i;
2200
2201    if (a->exp != b->exp) {
2202        /* Cannot wrap: a->exp + a->digits = b->exp + b->digits, so
2203         * a->exp - b->exp = b->digits - a->digits. */
2204        shift = a->exp - b->exp;
2205        if (shift > 0) {
2206            return -1 * _mpd_basecmp(b->data, a->data, b->len, a->len, shift);
2207        }
2208        else {
2209            return _mpd_basecmp(a->data, b->data, a->len, b->len, -shift);
2210        }
2211    }
2212
2213    /*
2214     * At this point adjexp(a) == adjexp(b) and a->exp == b->exp,
2215     * so a->digits == b->digits, therefore a->len == b->len.
2216     */
2217    for (i = a->len-1; i >= 0; --i) {
2218        CMP_EQUAL_OR_RETURN(a->data[i], b->data[i])
2219    }
2220
2221    return 0;
2222}
2223
2224/* Compare two numerical values. */
2225static int
2226_mpd_cmp(const mpd_t *a, const mpd_t *b)
2227{
2228    mpd_ssize_t adjexp_a, adjexp_b;
2229
2230    /* equal pointers */
2231    if (a == b) {
2232        return 0;
2233    }
2234
2235    /* infinities */
2236    if (mpd_isinfinite(a)) {
2237        if (mpd_isinfinite(b)) {
2238            return mpd_isnegative(b) - mpd_isnegative(a);
2239        }
2240        return mpd_arith_sign(a);
2241    }
2242    if (mpd_isinfinite(b)) {
2243        return -mpd_arith_sign(b);
2244    }
2245
2246    /* zeros */
2247    if (mpd_iszerocoeff(a)) {
2248        if (mpd_iszerocoeff(b)) {
2249            return 0;
2250        }
2251        return -mpd_arith_sign(b);
2252    }
2253    if (mpd_iszerocoeff(b)) {
2254        return mpd_arith_sign(a);
2255    }
2256
2257    /* different signs */
2258    if (mpd_sign(a) != mpd_sign(b)) {
2259        return mpd_sign(b) - mpd_sign(a);
2260    }
2261
2262    /* different adjusted exponents */
2263    adjexp_a = mpd_adjexp(a);
2264    adjexp_b = mpd_adjexp(b);
2265    if (adjexp_a != adjexp_b) {
2266        if (adjexp_a < adjexp_b) {
2267            return -1 * mpd_arith_sign(a);
2268        }
2269        return mpd_arith_sign(a);
2270    }
2271
2272    /* same adjusted exponents */
2273    return _mpd_cmp_same_adjexp(a, b) * mpd_arith_sign(a);
2274}
2275
2276/* Compare the absolutes of two numerical values. */
2277static int
2278_mpd_cmp_abs(const mpd_t *a, const mpd_t *b)
2279{
2280    mpd_ssize_t adjexp_a, adjexp_b;
2281
2282    /* equal pointers */
2283    if (a == b) {
2284        return 0;
2285    }
2286
2287    /* infinities */
2288    if (mpd_isinfinite(a)) {
2289        if (mpd_isinfinite(b)) {
2290            return 0;
2291        }
2292        return 1;
2293    }
2294    if (mpd_isinfinite(b)) {
2295        return -1;
2296    }
2297
2298    /* zeros */
2299    if (mpd_iszerocoeff(a)) {
2300        if (mpd_iszerocoeff(b)) {
2301            return 0;
2302        }
2303        return -1;
2304    }
2305    if (mpd_iszerocoeff(b)) {
2306        return 1;
2307    }
2308
2309    /* different adjusted exponents */
2310    adjexp_a = mpd_adjexp(a);
2311    adjexp_b = mpd_adjexp(b);
2312    if (adjexp_a != adjexp_b) {
2313        if (adjexp_a < adjexp_b) {
2314            return -1;
2315        }
2316        return 1;
2317    }
2318
2319    /* same adjusted exponents */
2320    return _mpd_cmp_same_adjexp(a, b);
2321}
2322
2323/* Compare two values and return an integer result. */
2324int
2325mpd_qcmp(const mpd_t *a, const mpd_t *b, uint32_t *status)
2326{
2327    if (mpd_isspecial(a) || mpd_isspecial(b)) {
2328        if (mpd_isnan(a) || mpd_isnan(b)) {
2329            *status |= MPD_Invalid_operation;
2330            return INT_MAX;
2331        }
2332    }
2333
2334    return _mpd_cmp(a, b);
2335}
2336
2337/*
2338 * Compare a and b, convert the usual integer result to a decimal and
2339 * store it in 'result'. For convenience, the integer result of the comparison
2340 * is returned. Comparisons involving NaNs return NaN/INT_MAX.
2341 */
2342int
2343mpd_qcompare(mpd_t *result, const mpd_t *a, const mpd_t *b,
2344             const mpd_context_t *ctx, uint32_t *status)
2345{
2346    int c;
2347
2348    if (mpd_isspecial(a) || mpd_isspecial(b)) {
2349        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
2350            return INT_MAX;
2351        }
2352    }
2353
2354    c = _mpd_cmp(a, b);
2355    _settriple(result, (c < 0), (c != 0), 0);
2356    return c;
2357}
2358
2359/* Same as mpd_compare(), but signal for all NaNs, i.e. also for quiet NaNs. */
2360int
2361mpd_qcompare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b,
2362                    const mpd_context_t *ctx, uint32_t *status)
2363{
2364    int c;
2365
2366    if (mpd_isspecial(a) || mpd_isspecial(b)) {
2367        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
2368            *status |= MPD_Invalid_operation;
2369            return INT_MAX;
2370        }
2371    }
2372
2373    c = _mpd_cmp(a, b);
2374    _settriple(result, (c < 0), (c != 0), 0);
2375    return c;
2376}
2377
2378/* Compare the operands using a total order. */
2379int
2380mpd_cmp_total(const mpd_t *a, const mpd_t *b)
2381{
2382    mpd_t aa, bb;
2383    int nan_a, nan_b;
2384    int c;
2385
2386    if (mpd_sign(a) != mpd_sign(b)) {
2387        return mpd_sign(b) - mpd_sign(a);
2388    }
2389
2390
2391    if (mpd_isnan(a)) {
2392        c = 1;
2393        if (mpd_isnan(b)) {
2394            nan_a = (mpd_isqnan(a)) ? 1 : 0;
2395            nan_b = (mpd_isqnan(b)) ? 1 : 0;
2396            if (nan_b == nan_a) {
2397                if (a->len > 0 && b->len > 0) {
2398                    _mpd_copy_shared(&aa, a);
2399                    _mpd_copy_shared(&bb, b);
2400                    aa.exp = bb.exp = 0;
2401                    /* compare payload */
2402                    c = _mpd_cmp_abs(&aa, &bb);
2403                }
2404                else {
2405                    c = (a->len > 0) - (b->len > 0);
2406                }
2407            }
2408            else {
2409                c = nan_a - nan_b;
2410            }
2411        }
2412    }
2413    else if (mpd_isnan(b)) {
2414        c = -1;
2415    }
2416    else {
2417        c = _mpd_cmp_abs(a, b);
2418        if (c == 0 && a->exp != b->exp) {
2419            c = (a->exp < b->exp) ? -1 : 1;
2420        }
2421    }
2422
2423    return c * mpd_arith_sign(a);
2424}
2425
2426/*
2427 * Compare a and b according to a total order, convert the usual integer result
2428 * to a decimal and store it in 'result'. For convenience, the integer result
2429 * of the comparison is returned.
2430 */
2431int
2432mpd_compare_total(mpd_t *result, const mpd_t *a, const mpd_t *b)
2433{
2434    int c;
2435
2436    c = mpd_cmp_total(a, b);
2437    _settriple(result, (c < 0), (c != 0), 0);
2438    return c;
2439}
2440
2441/* Compare the magnitude of the operands using a total order. */
2442int
2443mpd_cmp_total_mag(const mpd_t *a, const mpd_t *b)
2444{
2445    mpd_t aa, bb;
2446
2447    _mpd_copy_shared(&aa, a);
2448    _mpd_copy_shared(&bb, b);
2449
2450    mpd_set_positive(&aa);
2451    mpd_set_positive(&bb);
2452
2453    return mpd_cmp_total(&aa, &bb);
2454}
2455
2456/*
2457 * Compare the magnitude of a and b according to a total order, convert the
2458 * the usual integer result to a decimal and store it in 'result'.
2459 * For convenience, the integer result of the comparison is returned.
2460 */
2461int
2462mpd_compare_total_mag(mpd_t *result, const mpd_t *a, const mpd_t *b)
2463{
2464    int c;
2465
2466    c = mpd_cmp_total_mag(a, b);
2467    _settriple(result, (c < 0), (c != 0), 0);
2468    return c;
2469}
2470
2471/* Determine an ordering for operands that are numerically equal. */
2472static inline int
2473_mpd_cmp_numequal(const mpd_t *a, const mpd_t *b)
2474{
2475    int sign_a, sign_b;
2476    int c;
2477
2478    sign_a = mpd_sign(a);
2479    sign_b = mpd_sign(b);
2480    if (sign_a != sign_b) {
2481        c = sign_b - sign_a;
2482    }
2483    else {
2484        c = (a->exp < b->exp) ? -1 : 1;
2485        c *= mpd_arith_sign(a);
2486    }
2487
2488    return c;
2489}
2490
2491
2492/******************************************************************************/
2493/*                         Shifting the coefficient                           */
2494/******************************************************************************/
2495
2496/*
2497 * Shift the coefficient of the operand to the left, no check for specials.
2498 * Both operands may be the same pointer. If the result length has to be
2499 * increased, mpd_qresize() might fail with MPD_Malloc_error.
2500 */
2501int
2502mpd_qshiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status)
2503{
2504    mpd_ssize_t size;
2505
2506    assert(!mpd_isspecial(a));
2507    assert(n >= 0);
2508
2509    if (mpd_iszerocoeff(a) || n == 0) {
2510        return mpd_qcopy(result, a, status);
2511    }
2512
2513    size = mpd_digits_to_size(a->digits+n);
2514    if (!mpd_qresize(result, size, status)) {
2515        return 0; /* result is NaN */
2516    }
2517
2518    _mpd_baseshiftl(result->data, a->data, size, a->len, n);
2519
2520    mpd_copy_flags(result, a);
2521    result->exp = a->exp;
2522    result->digits = a->digits+n;
2523    result->len = size;
2524
2525    return 1;
2526}
2527
2528/* Determine the rounding indicator if all digits of the coefficient are shifted
2529 * out of the picture. */
2530static mpd_uint_t
2531_mpd_get_rnd(const mpd_uint_t *data, mpd_ssize_t len, int use_msd)
2532{
2533    mpd_uint_t rnd = 0, rest = 0, word;
2534
2535    word = data[len-1];
2536    /* special treatment for the most significant digit if shift == digits */
2537    if (use_msd) {
2538        _mpd_divmod_pow10(&rnd, &rest, word, mpd_word_digits(word)-1);
2539        if (len > 1 && rest == 0) {
2540             rest = !_mpd_isallzero(data, len-1);
2541        }
2542    }
2543    else {
2544        rest = !_mpd_isallzero(data, len);
2545    }
2546
2547    return (rnd == 0 || rnd == 5) ? rnd + !!rest : rnd;
2548}
2549
2550/*
2551 * Same as mpd_qshiftr(), but 'result' is an mpd_t with a static coefficient.
2552 * It is the caller's responsibility to ensure that the coefficient is big
2553 * enough. The function cannot fail.
2554 */
2555static mpd_uint_t
2556mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n)
2557{
2558    mpd_uint_t rnd;
2559    mpd_ssize_t size;
2560
2561    assert(!mpd_isspecial(a));
2562    assert(n >= 0);
2563
2564    if (mpd_iszerocoeff(a) || n == 0) {
2565        mpd_qcopy_static(result, a);
2566        return 0;
2567    }
2568
2569    if (n >= a->digits) {
2570        rnd = _mpd_get_rnd(a->data, a->len, (n==a->digits));
2571        mpd_zerocoeff(result);
2572    }
2573    else {
2574        result->digits = a->digits-n;
2575        size = mpd_digits_to_size(result->digits);
2576        rnd = _mpd_baseshiftr(result->data, a->data, a->len, n);
2577        result->len = size;
2578    }
2579
2580    mpd_copy_flags(result, a);
2581    result->exp = a->exp;
2582
2583    return rnd;
2584}
2585
2586/*
2587 * Inplace shift of the coefficient to the right, no check for specials.
2588 * Returns the rounding indicator for mpd_rnd_incr().
2589 * The function cannot fail.
2590 */
2591mpd_uint_t
2592mpd_qshiftr_inplace(mpd_t *result, mpd_ssize_t n)
2593{
2594    uint32_t dummy;
2595    mpd_uint_t rnd;
2596    mpd_ssize_t size;
2597
2598    assert(!mpd_isspecial(result));
2599    assert(n >= 0);
2600
2601    if (mpd_iszerocoeff(result) || n == 0) {
2602        return 0;
2603    }
2604
2605    if (n >= result->digits) {
2606        rnd = _mpd_get_rnd(result->data, result->len, (n==result->digits));
2607        mpd_zerocoeff(result);
2608    }
2609    else {
2610        rnd = _mpd_baseshiftr(result->data, result->data, result->len, n);
2611        result->digits -= n;
2612        size = mpd_digits_to_size(result->digits);
2613        /* reducing the size cannot fail */
2614        mpd_qresize(result, size, &dummy);
2615        result->len = size;
2616    }
2617
2618    return rnd;
2619}
2620
2621/*
2622 * Shift the coefficient of the operand to the right, no check for specials.
2623 * Both operands may be the same pointer. Returns the rounding indicator to
2624 * be used by mpd_rnd_incr(). If the result length has to be increased,
2625 * mpd_qcopy() or mpd_qresize() might fail with MPD_Malloc_error. In those
2626 * cases, MPD_UINT_MAX is returned.
2627 */
2628mpd_uint_t
2629mpd_qshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, uint32_t *status)
2630{
2631    mpd_uint_t rnd;
2632    mpd_ssize_t size;
2633
2634    assert(!mpd_isspecial(a));
2635    assert(n >= 0);
2636
2637    if (mpd_iszerocoeff(a) || n == 0) {
2638        if (!mpd_qcopy(result, a, status)) {
2639            return MPD_UINT_MAX;
2640        }
2641        return 0;
2642    }
2643
2644    if (n >= a->digits) {
2645        rnd = _mpd_get_rnd(a->data, a->len, (n==a->digits));
2646        mpd_zerocoeff(result);
2647    }
2648    else {
2649        result->digits = a->digits-n;
2650        size = mpd_digits_to_size(result->digits);
2651        if (result == a) {
2652            rnd = _mpd_baseshiftr(result->data, a->data, a->len, n);
2653            /* reducing the size cannot fail */
2654            mpd_qresize(result, size, status);
2655        }
2656        else {
2657            if (!mpd_qresize(result, size, status)) {
2658                return MPD_UINT_MAX;
2659            }
2660            rnd = _mpd_baseshiftr(result->data, a->data, a->len, n);
2661        }
2662        result->len = size;
2663    }
2664
2665    mpd_copy_flags(result, a);
2666    result->exp = a->exp;
2667
2668    return rnd;
2669}
2670
2671
2672/******************************************************************************/
2673/*                         Miscellaneous operations                           */
2674/******************************************************************************/
2675
2676/* Logical And */
2677void
2678mpd_qand(mpd_t *result, const mpd_t *a, const mpd_t *b,
2679         const mpd_context_t *ctx, uint32_t *status)
2680{
2681    const mpd_t *big = a, *small = b;
2682    mpd_uint_t x, y, z, xbit, ybit;
2683    int k, mswdigits;
2684    mpd_ssize_t i;
2685
2686    if (mpd_isspecial(a) || mpd_isspecial(b) ||
2687        mpd_isnegative(a) || mpd_isnegative(b) ||
2688        a->exp != 0 || b->exp != 0) {
2689        mpd_seterror(result, MPD_Invalid_operation, status);
2690        return;
2691    }
2692    if (b->digits > a->digits) {
2693        big = b;
2694        small = a;
2695    }
2696    if (!mpd_qresize(result, big->len, status)) {
2697        return;
2698    }
2699
2700
2701    /* full words */
2702    for (i = 0; i < small->len-1; i++) {
2703        x = small->data[i];
2704        y = big->data[i];
2705        z = 0;
2706        for (k = 0; k < MPD_RDIGITS; k++) {
2707            xbit = x % 10;
2708            x /= 10;
2709            ybit = y % 10;
2710            y /= 10;
2711            if (xbit > 1 || ybit > 1) {
2712                goto invalid_operation;
2713            }
2714            z += (xbit&ybit) ? mpd_pow10[k] : 0;
2715        }
2716        result->data[i] = z;
2717    }
2718    /* most significant word of small */
2719    x = small->data[i];
2720    y = big->data[i];
2721    z = 0;
2722    mswdigits = mpd_word_digits(x);
2723    for (k = 0; k < mswdigits; k++) {
2724        xbit = x % 10;
2725        x /= 10;
2726        ybit = y % 10;
2727        y /= 10;
2728        if (xbit > 1 || ybit > 1) {
2729            goto invalid_operation;
2730        }
2731        z += (xbit&ybit) ? mpd_pow10[k] : 0;
2732    }
2733    result->data[i++] = z;
2734
2735    /* scan the rest of y for digits > 1 */
2736    for (; k < MPD_RDIGITS; k++) {
2737        ybit = y % 10;
2738        y /= 10;
2739        if (ybit > 1) {
2740            goto invalid_operation;
2741        }
2742    }
2743    /* scan the rest of big for digits > 1 */
2744    for (; i < big->len; i++) {
2745        y = big->data[i];
2746        for (k = 0; k < MPD_RDIGITS; k++) {
2747            ybit = y % 10;
2748            y /= 10;
2749            if (ybit > 1) {
2750                goto invalid_operation;
2751            }
2752        }
2753    }
2754
2755    mpd_clear_flags(result);
2756    result->exp = 0;
2757    result->len = _mpd_real_size(result->data, small->len);
2758    mpd_qresize(result, result->len, status);
2759    mpd_setdigits(result);
2760    _mpd_cap(result, ctx);
2761    return;
2762
2763invalid_operation:
2764    mpd_seterror(result, MPD_Invalid_operation, status);
2765}
2766
2767/* Class of an operand. Returns a pointer to the constant name. */
2768const char *
2769mpd_class(const mpd_t *a, const mpd_context_t *ctx)
2770{
2771    if (mpd_isnan(a)) {
2772        if (mpd_isqnan(a))
2773            return "NaN";
2774        else
2775            return "sNaN";
2776    }
2777    else if (mpd_ispositive(a)) {
2778        if (mpd_isinfinite(a))
2779            return "+Infinity";
2780        else if (mpd_iszero(a))
2781            return "+Zero";
2782        else if (mpd_isnormal(a, ctx))
2783            return "+Normal";
2784        else
2785            return "+Subnormal";
2786    }
2787    else {
2788        if (mpd_isinfinite(a))
2789            return "-Infinity";
2790        else if (mpd_iszero(a))
2791            return "-Zero";
2792        else if (mpd_isnormal(a, ctx))
2793            return "-Normal";
2794        else
2795            return "-Subnormal";
2796    }
2797}
2798
2799/* Logical Xor */
2800void
2801mpd_qinvert(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
2802            uint32_t *status)
2803{
2804    mpd_uint_t x, z, xbit;
2805    mpd_ssize_t i, digits, len;
2806    mpd_ssize_t q, r;
2807    int k;
2808
2809    if (mpd_isspecial(a) || mpd_isnegative(a) || a->exp != 0) {
2810        mpd_seterror(result, MPD_Invalid_operation, status);
2811        return;
2812    }
2813
2814    digits = (a->digits < ctx->prec) ? ctx->prec : a->digits;
2815    _mpd_idiv_word(&q, &r, digits, MPD_RDIGITS);
2816    len = (r == 0) ? q : q+1;
2817    if (!mpd_qresize(result, len, status)) {
2818        return;
2819    }
2820
2821    for (i = 0; i < len; i++) {
2822        x = (i < a->len) ? a->data[i] : 0;
2823        z = 0;
2824        for (k = 0; k < MPD_RDIGITS; k++) {
2825            xbit = x % 10;
2826            x /= 10;
2827            if (xbit > 1) {
2828                goto invalid_operation;
2829            }
2830            z += !xbit ? mpd_pow10[k] : 0;
2831        }
2832        result->data[i] = z;
2833    }
2834
2835    mpd_clear_flags(result);
2836    result->exp = 0;
2837    result->len = _mpd_real_size(result->data, len);
2838    mpd_qresize(result, result->len, status);
2839    mpd_setdigits(result);
2840    _mpd_cap(result, ctx);
2841    return;
2842
2843invalid_operation:
2844    mpd_seterror(result, MPD_Invalid_operation, status);
2845}
2846
2847/* Exponent of the magnitude of the most significant digit of the operand. */
2848void
2849mpd_qlogb(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
2850          uint32_t *status)
2851{
2852    if (mpd_isspecial(a)) {
2853        if (mpd_qcheck_nan(result, a, ctx, status)) {
2854            return;
2855        }
2856        mpd_setspecial(result, MPD_POS, MPD_INF);
2857    }
2858    else if (mpd_iszerocoeff(a)) {
2859        mpd_setspecial(result, MPD_NEG, MPD_INF);
2860        *status |= MPD_Division_by_zero;
2861    }
2862    else {
2863        mpd_qset_ssize(result, mpd_adjexp(a), ctx, status);
2864    }
2865}
2866
2867/* Logical Or */
2868void
2869mpd_qor(mpd_t *result, const mpd_t *a, const mpd_t *b,
2870        const mpd_context_t *ctx, uint32_t *status)
2871{
2872    const mpd_t *big = a, *small = b;
2873    mpd_uint_t x, y, z, xbit, ybit;
2874    int k, mswdigits;
2875    mpd_ssize_t i;
2876
2877    if (mpd_isspecial(a) || mpd_isspecial(b) ||
2878        mpd_isnegative(a) || mpd_isnegative(b) ||
2879        a->exp != 0 || b->exp != 0) {
2880        mpd_seterror(result, MPD_Invalid_operation, status);
2881        return;
2882    }
2883    if (b->digits > a->digits) {
2884        big = b;
2885        small = a;
2886    }
2887    if (!mpd_qresize(result, big->len, status)) {
2888        return;
2889    }
2890
2891
2892    /* full words */
2893    for (i = 0; i < small->len-1; i++) {
2894        x = small->data[i];
2895        y = big->data[i];
2896        z = 0;
2897        for (k = 0; k < MPD_RDIGITS; k++) {
2898            xbit = x % 10;
2899            x /= 10;
2900            ybit = y % 10;
2901            y /= 10;
2902            if (xbit > 1 || ybit > 1) {
2903                goto invalid_operation;
2904            }
2905            z += (xbit|ybit) ? mpd_pow10[k] : 0;
2906        }
2907        result->data[i] = z;
2908    }
2909    /* most significant word of small */
2910    x = small->data[i];
2911    y = big->data[i];
2912    z = 0;
2913    mswdigits = mpd_word_digits(x);
2914    for (k = 0; k < mswdigits; k++) {
2915        xbit = x % 10;
2916        x /= 10;
2917        ybit = y % 10;
2918        y /= 10;
2919        if (xbit > 1 || ybit > 1) {
2920            goto invalid_operation;
2921        }
2922        z += (xbit|ybit) ? mpd_pow10[k] : 0;
2923    }
2924
2925    /* scan for digits > 1 and copy the rest of y */
2926    for (; k < MPD_RDIGITS; k++) {
2927        ybit = y % 10;
2928        y /= 10;
2929        if (ybit > 1) {
2930            goto invalid_operation;
2931        }
2932        z += ybit*mpd_pow10[k];
2933    }
2934    result->data[i++] = z;
2935    /* scan for digits > 1 and copy the rest of big */
2936    for (; i < big->len; i++) {
2937        y = big->data[i];
2938        for (k = 0; k < MPD_RDIGITS; k++) {
2939            ybit = y % 10;
2940            y /= 10;
2941            if (ybit > 1) {
2942                goto invalid_operation;
2943            }
2944        }
2945        result->data[i] = big->data[i];
2946    }
2947
2948    mpd_clear_flags(result);
2949    result->exp = 0;
2950    result->len = _mpd_real_size(result->data, big->len);
2951    mpd_qresize(result, result->len, status);
2952    mpd_setdigits(result);
2953    _mpd_cap(result, ctx);
2954    return;
2955
2956invalid_operation:
2957    mpd_seterror(result, MPD_Invalid_operation, status);
2958}
2959
2960/*
2961 * Rotate the coefficient of 'a' by 'b' digits. 'b' must be an integer with
2962 * exponent 0.
2963 */
2964void
2965mpd_qrotate(mpd_t *result, const mpd_t *a, const mpd_t *b,
2966            const mpd_context_t *ctx, uint32_t *status)
2967{
2968    uint32_t workstatus = 0;
2969    MPD_NEW_STATIC(tmp,0,0,0,0);
2970    MPD_NEW_STATIC(big,0,0,0,0);
2971    MPD_NEW_STATIC(small,0,0,0,0);
2972    mpd_ssize_t n, lshift, rshift;
2973
2974    if (mpd_isspecial(a) || mpd_isspecial(b)) {
2975        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
2976            return;
2977        }
2978    }
2979    if (b->exp != 0 || mpd_isinfinite(b)) {
2980        mpd_seterror(result, MPD_Invalid_operation, status);
2981        return;
2982    }
2983
2984    n = mpd_qget_ssize(b, &workstatus);
2985    if (workstatus&MPD_Invalid_operation) {
2986        mpd_seterror(result, MPD_Invalid_operation, status);
2987        return;
2988    }
2989    if (n > ctx->prec || n < -ctx->prec) {
2990        mpd_seterror(result, MPD_Invalid_operation, status);
2991        return;
2992    }
2993    if (mpd_isinfinite(a)) {
2994        mpd_qcopy(result, a, status);
2995        return;
2996    }
2997
2998    if (n >= 0) {
2999        lshift = n;
3000        rshift = ctx->prec-n;
3001    }
3002    else {
3003        lshift = ctx->prec+n;
3004        rshift = -n;
3005    }
3006
3007    if (a->digits > ctx->prec) {
3008        if (!mpd_qcopy(&tmp, a, status)) {
3009            mpd_seterror(result, MPD_Malloc_error, status);
3010            goto finish;
3011        }
3012        _mpd_cap(&tmp, ctx);
3013        a = &tmp;
3014    }
3015
3016    if (!mpd_qshiftl(&big, a, lshift, status)) {
3017        mpd_seterror(result, MPD_Malloc_error, status);
3018        goto finish;
3019    }
3020    _mpd_cap(&big, ctx);
3021
3022    if (mpd_qshiftr(&small, a, rshift, status) == MPD_UINT_MAX) {
3023        mpd_seterror(result, MPD_Malloc_error, status);
3024        goto finish;
3025    }
3026    _mpd_qadd(result, &big, &small, ctx, status);
3027
3028
3029finish:
3030    mpd_del(&tmp);
3031    mpd_del(&big);
3032    mpd_del(&small);
3033}
3034
3035/*
3036 * b must be an integer with exponent 0 and in the range +-2*(emax + prec).
3037 * XXX: In my opinion +-(2*emax + prec) would be more sensible.
3038 * The result is a with the value of b added to its exponent.
3039 */
3040void
3041mpd_qscaleb(mpd_t *result, const mpd_t *a, const mpd_t *b,
3042            const mpd_context_t *ctx, uint32_t *status)
3043{
3044    uint32_t workstatus = 0;
3045    mpd_uint_t n, maxjump;
3046#ifndef LEGACY_COMPILER
3047    int64_t exp;
3048#else
3049    mpd_uint_t x;
3050    int x_sign, n_sign;
3051    mpd_ssize_t exp;
3052#endif
3053
3054    if (mpd_isspecial(a) || mpd_isspecial(b)) {
3055        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
3056            return;
3057        }
3058    }
3059    if (b->exp != 0 || mpd_isinfinite(b)) {
3060        mpd_seterror(result, MPD_Invalid_operation, status);
3061        return;
3062    }
3063
3064    n = mpd_qabs_uint(b, &workstatus);
3065    /* the spec demands this */
3066    maxjump = 2 * (mpd_uint_t)(ctx->emax + ctx->prec);
3067
3068    if (n > maxjump || workstatus&MPD_Invalid_operation) {
3069        mpd_seterror(result, MPD_Invalid_operation, status);
3070        return;
3071    }
3072    if (mpd_isinfinite(a)) {
3073        mpd_qcopy(result, a, status);
3074        return;
3075    }
3076
3077#ifndef LEGACY_COMPILER
3078    exp = a->exp + (int64_t)n * mpd_arith_sign(b);
3079    exp = (exp > MPD_EXP_INF) ? MPD_EXP_INF : exp;
3080    exp = (exp < MPD_EXP_CLAMP) ? MPD_EXP_CLAMP : exp;
3081#else
3082    x = (a->exp < 0) ? -a->exp : a->exp;
3083    x_sign = (a->exp < 0) ? 1 : 0;
3084    n_sign = mpd_isnegative(b) ? 1 : 0;
3085
3086    if (x_sign == n_sign) {
3087        x = x + n;
3088        if (x < n) x = MPD_UINT_MAX;
3089    }
3090    else {
3091        x_sign = (x >= n) ? x_sign : n_sign;
3092        x = (x >= n) ? x - n : n - x;
3093    }
3094    if (!x_sign && x > MPD_EXP_INF) x = MPD_EXP_INF;
3095    if (x_sign && x > -MPD_EXP_CLAMP) x = -MPD_EXP_CLAMP;
3096    exp = x_sign ? -((mpd_ssize_t)x) : (mpd_ssize_t)x;
3097#endif
3098
3099    mpd_qcopy(result, a, status);
3100    result->exp = (mpd_ssize_t)exp;
3101
3102    mpd_qfinalize(result, ctx, status);
3103}
3104
3105/*
3106 * Shift the coefficient by n digits, positive n is a left shift. In the case
3107 * of a left shift, the result is decapitated to fit the context precision. If
3108 * you don't want that, use mpd_shiftl().
3109 */
3110void
3111mpd_qshiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, const mpd_context_t *ctx,
3112            uint32_t *status)
3113{
3114    if (mpd_isspecial(a)) {
3115        if (mpd_qcheck_nan(result, a, ctx, status)) {
3116            return;
3117        }
3118        mpd_qcopy(result, a, status);
3119        return;
3120    }
3121
3122    if (n >= 0 && n <= ctx->prec) {
3123        mpd_qshiftl(result, a, n, status);
3124        _mpd_cap(result, ctx);
3125    }
3126    else if (n < 0 && n >= -ctx->prec) {
3127        if (!mpd_qcopy(result, a, status)) {
3128            return;
3129        }
3130        _mpd_cap(result, ctx);
3131        mpd_qshiftr_inplace(result, -n);
3132    }
3133    else {
3134        mpd_seterror(result, MPD_Invalid_operation, status);
3135    }
3136}
3137
3138/*
3139 * Same as mpd_shiftn(), but the shift is specified by the decimal b, which
3140 * must be an integer with a zero exponent. Infinities remain infinities.
3141 */
3142void
3143mpd_qshift(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx,
3144           uint32_t *status)
3145{
3146    uint32_t workstatus = 0;
3147    mpd_ssize_t n;
3148
3149    if (mpd_isspecial(a) || mpd_isspecial(b)) {
3150        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
3151            return;
3152        }
3153    }
3154    if (b->exp != 0 || mpd_isinfinite(b)) {
3155        mpd_seterror(result, MPD_Invalid_operation, status);
3156        return;
3157    }
3158
3159    n = mpd_qget_ssize(b, &workstatus);
3160    if (workstatus&MPD_Invalid_operation) {
3161        mpd_seterror(result, MPD_Invalid_operation, status);
3162        return;
3163    }
3164    if (n > ctx->prec || n < -ctx->prec) {
3165        mpd_seterror(result, MPD_Invalid_operation, status);
3166        return;
3167    }
3168    if (mpd_isinfinite(a)) {
3169        mpd_qcopy(result, a, status);
3170        return;
3171    }
3172
3173    if (n >= 0) {
3174        mpd_qshiftl(result, a, n, status);
3175        _mpd_cap(result, ctx);
3176    }
3177    else {
3178        if (!mpd_qcopy(result, a, status)) {
3179            return;
3180        }
3181        _mpd_cap(result, ctx);
3182        mpd_qshiftr_inplace(result, -n);
3183    }
3184}
3185
3186/* Logical Xor */
3187void
3188mpd_qxor(mpd_t *result, const mpd_t *a, const mpd_t *b,
3189        const mpd_context_t *ctx, uint32_t *status)
3190{
3191    const mpd_t *big = a, *small = b;
3192    mpd_uint_t x, y, z, xbit, ybit;
3193    int k, mswdigits;
3194    mpd_ssize_t i;
3195
3196    if (mpd_isspecial(a) || mpd_isspecial(b) ||
3197        mpd_isnegative(a) || mpd_isnegative(b) ||
3198        a->exp != 0 || b->exp != 0) {
3199        mpd_seterror(result, MPD_Invalid_operation, status);
3200        return;
3201    }
3202    if (b->digits > a->digits) {
3203        big = b;
3204        small = a;
3205    }
3206    if (!mpd_qresize(result, big->len, status)) {
3207        return;
3208    }
3209
3210
3211    /* full words */
3212    for (i = 0; i < small->len-1; i++) {
3213        x = small->data[i];
3214        y = big->data[i];
3215        z = 0;
3216        for (k = 0; k < MPD_RDIGITS; k++) {
3217            xbit = x % 10;
3218            x /= 10;
3219            ybit = y % 10;
3220            y /= 10;
3221            if (xbit > 1 || ybit > 1) {
3222                goto invalid_operation;
3223            }
3224            z += (xbit^ybit) ? mpd_pow10[k] : 0;
3225        }
3226        result->data[i] = z;
3227    }
3228    /* most significant word of small */
3229    x = small->data[i];
3230    y = big->data[i];
3231    z = 0;
3232    mswdigits = mpd_word_digits(x);
3233    for (k = 0; k < mswdigits; k++) {
3234        xbit = x % 10;
3235        x /= 10;
3236        ybit = y % 10;
3237        y /= 10;
3238        if (xbit > 1 || ybit > 1) {
3239            goto invalid_operation;
3240        }
3241        z += (xbit^ybit) ? mpd_pow10[k] : 0;
3242    }
3243
3244    /* scan for digits > 1 and copy the rest of y */
3245    for (; k < MPD_RDIGITS; k++) {
3246        ybit = y % 10;
3247        y /= 10;
3248        if (ybit > 1) {
3249            goto invalid_operation;
3250        }
3251        z += ybit*mpd_pow10[k];
3252    }
3253    result->data[i++] = z;
3254    /* scan for digits > 1 and copy the rest of big */
3255    for (; i < big->len; i++) {
3256        y = big->data[i];
3257        for (k = 0; k < MPD_RDIGITS; k++) {
3258            ybit = y % 10;
3259            y /= 10;
3260            if (ybit > 1) {
3261                goto invalid_operation;
3262            }
3263        }
3264        result->data[i] = big->data[i];
3265    }
3266
3267    mpd_clear_flags(result);
3268    result->exp = 0;
3269    result->len = _mpd_real_size(result->data, big->len);
3270    mpd_qresize(result, result->len, status);
3271    mpd_setdigits(result);
3272    _mpd_cap(result, ctx);
3273    return;
3274
3275invalid_operation:
3276    mpd_seterror(result, MPD_Invalid_operation, status);
3277}
3278
3279
3280/******************************************************************************/
3281/*                         Arithmetic operations                              */
3282/******************************************************************************/
3283
3284/*
3285 * The absolute value of a. If a is negative, the result is the same
3286 * as the result of the minus operation. Otherwise, the result is the
3287 * result of the plus operation.
3288 */
3289void
3290mpd_qabs(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
3291         uint32_t *status)
3292{
3293    if (mpd_isspecial(a)) {
3294        if (mpd_qcheck_nan(result, a, ctx, status)) {
3295            return;
3296        }
3297    }
3298
3299    if (mpd_isnegative(a)) {
3300        mpd_qminus(result, a, ctx, status);
3301    }
3302    else {
3303        mpd_qplus(result, a, ctx, status);
3304    }
3305}
3306
3307static inline void
3308_mpd_ptrswap(const mpd_t **a, const mpd_t **b)
3309{
3310    const mpd_t *t = *a;
3311    *a = *b;
3312    *b = t;
3313}
3314
3315/* Add or subtract infinities. */
3316static void
3317_mpd_qaddsub_inf(mpd_t *result, const mpd_t *a, const mpd_t *b, uint8_t sign_b,
3318                 uint32_t *status)
3319{
3320    if (mpd_isinfinite(a)) {
3321        if (mpd_sign(a) != sign_b && mpd_isinfinite(b)) {
3322            mpd_seterror(result, MPD_Invalid_operation, status);
3323        }
3324        else {
3325            mpd_setspecial(result, mpd_sign(a), MPD_INF);
3326        }
3327        return;
3328    }
3329    assert(mpd_isinfinite(b));
3330    mpd_setspecial(result, sign_b, MPD_INF);
3331}
3332
3333/* Add or subtract non-special numbers. */
3334static void
3335_mpd_qaddsub(mpd_t *result, const mpd_t *a, const mpd_t *b, uint8_t sign_b,
3336             const mpd_context_t *ctx, uint32_t *status)
3337{
3338    const mpd_t *big, *small;
3339    MPD_NEW_STATIC(big_aligned,0,0,0,0);
3340    MPD_NEW_CONST(tiny,0,0,1,1,1,1);
3341    mpd_uint_t carry;
3342    mpd_ssize_t newsize, shift;
3343    mpd_ssize_t exp, i;
3344    int swap = 0;
3345
3346
3347    /* compare exponents */
3348    big = a; small = b;
3349    if (big->exp != small->exp) {
3350        if (small->exp > big->exp) {
3351            _mpd_ptrswap(&big, &small);
3352            swap++;
3353        }
3354        /* align the coefficients */
3355        if (!mpd_iszerocoeff(big)) {
3356            exp = big->exp - 1;
3357            exp += (big->digits > ctx->prec) ? 0 : big->digits-ctx->prec-1;
3358            if (mpd_adjexp(small) < exp) {
3359                /*
3360                 * Avoid huge shifts by substituting a value for small that is
3361                 * guaranteed to produce the same results.
3362                 *
3363                 * adjexp(small) < exp if and only if:
3364                 *
3365                 *   bdigits <= prec AND
3366                 *   bdigits+shift >= prec+2+sdigits AND
3367                 *   exp = bexp+bdigits-prec-2
3368                 *
3369                 *     1234567000000000  ->  bdigits + shift
3370                 *     ----------XX1234  ->  sdigits
3371                 *     ----------X1      ->  tiny-digits
3372                 *     |- prec -|
3373                 *
3374                 *      OR
3375                 *
3376                 *   bdigits > prec AND
3377                 *   shift > sdigits AND
3378                 *   exp = bexp-1
3379                 *
3380                 *     1234567892100000  ->  bdigits + shift
3381                 *     ----------XX1234  ->  sdigits
3382                 *     ----------X1      ->  tiny-digits
3383                 *     |- prec -|
3384                 *
3385                 * If tiny is zero, adding or subtracting is a no-op.
3386                 * Otherwise, adding tiny generates a non-zero digit either
3387                 * below the rounding digit or the least significant digit
3388                 * of big. When subtracting, tiny is in the same position as
3389                 * the carry that would be generated by subtracting sdigits.
3390                 */
3391                mpd_copy_flags(&tiny, small);
3392                tiny.exp = exp;
3393                tiny.digits = 1;
3394                tiny.len = 1;
3395                tiny.data[0] = mpd_iszerocoeff(small) ? 0 : 1;
3396                small = &tiny;
3397            }
3398            /* This cannot wrap: the difference is positive and <= maxprec */
3399            shift = big->exp - small->exp;
3400            if (!mpd_qshiftl(&big_aligned, big, shift, status)) {
3401                mpd_seterror(result, MPD_Malloc_error, status);
3402                goto finish;
3403            }
3404            big = &big_aligned;
3405        }
3406    }
3407    result->exp = small->exp;
3408
3409
3410    /* compare length of coefficients */
3411    if (big->len < small->len) {
3412        _mpd_ptrswap(&big, &small);
3413        swap++;
3414    }
3415
3416    newsize = big->len;
3417    if (!mpd_qresize(result, newsize, status)) {
3418        goto finish;
3419    }
3420
3421    if (mpd_sign(a) == sign_b) {
3422
3423        carry = _mpd_baseadd(result->data, big->data, small->data,
3424                             big->len, small->len);
3425
3426        if (carry) {
3427            newsize = big->len + 1;
3428            if (!mpd_qresize(result, newsize, status)) {
3429                goto finish;
3430            }
3431            result->data[newsize-1] = carry;
3432        }
3433
3434        result->len = newsize;
3435        mpd_set_flags(result, sign_b);
3436    }
3437    else {
3438        if (big->len == small->len) {
3439            for (i=big->len-1; i >= 0; --i) {
3440                if (big->data[i] != small->data[i]) {
3441                    if (big->data[i] < small->data[i]) {
3442                        _mpd_ptrswap(&big, &small);
3443                        swap++;
3444                    }
3445                    break;
3446                }
3447            }
3448        }
3449
3450        _mpd_basesub(result->data, big->data, small->data,
3451                     big->len, small->len);
3452        newsize = _mpd_real_size(result->data, big->len);
3453        /* resize to smaller cannot fail */
3454        (void)mpd_qresize(result, newsize, status);
3455
3456        result->len = newsize;
3457        sign_b = (swap & 1) ? sign_b : mpd_sign(a);
3458        mpd_set_flags(result, sign_b);
3459
3460        if (mpd_iszerocoeff(result)) {
3461            mpd_set_positive(result);
3462            if (ctx->round == MPD_ROUND_FLOOR) {
3463                mpd_set_negative(result);
3464            }
3465        }
3466    }
3467
3468    mpd_setdigits(result);
3469
3470finish:
3471    mpd_del(&big_aligned);
3472}
3473
3474/* Add a and b. No specials, no finalizing. */
3475static void
3476_mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b,
3477          const mpd_context_t *ctx, uint32_t *status)
3478{
3479    _mpd_qaddsub(result, a, b, mpd_sign(b), ctx, status);
3480}
3481
3482/* Subtract b from a. No specials, no finalizing. */
3483static void
3484_mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b,
3485          const mpd_context_t *ctx, uint32_t *status)
3486{
3487     _mpd_qaddsub(result, a, b, !mpd_sign(b), ctx, status);
3488}
3489
3490/* Add a and b. */
3491void
3492mpd_qadd(mpd_t *result, const mpd_t *a, const mpd_t *b,
3493         const mpd_context_t *ctx, uint32_t *status)
3494{
3495    if (mpd_isspecial(a) || mpd_isspecial(b)) {
3496        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
3497            return;
3498        }
3499        _mpd_qaddsub_inf(result, a, b, mpd_sign(b), status);
3500        return;
3501    }
3502
3503    _mpd_qaddsub(result, a, b, mpd_sign(b), ctx, status);
3504    mpd_qfinalize(result, ctx, status);
3505}
3506
3507/* Add a and b. Set NaN/Invalid_operation if the result is inexact. */
3508static void
3509_mpd_qadd_exact(mpd_t *result, const mpd_t *a, const mpd_t *b,
3510                const mpd_context_t *ctx, uint32_t *status)
3511{
3512    uint32_t workstatus = 0;
3513
3514    mpd_qadd(result, a, b, ctx, &workstatus);
3515    *status |= workstatus;
3516    if (workstatus & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
3517        mpd_seterror(result, MPD_Invalid_operation, status);
3518    }
3519}
3520
3521/* Subtract b from a. */
3522void
3523mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b,
3524         const mpd_context_t *ctx, uint32_t *status)
3525{
3526    if (mpd_isspecial(a) || mpd_isspecial(b)) {
3527        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
3528            return;
3529        }
3530        _mpd_qaddsub_inf(result, a, b, !mpd_sign(b), status);
3531        return;
3532    }
3533
3534    _mpd_qaddsub(result, a, b, !mpd_sign(b), ctx, status);
3535    mpd_qfinalize(result, ctx, status);
3536}
3537
3538/* Subtract b from a. Set NaN/Invalid_operation if the result is inexact. */
3539static void
3540_mpd_qsub_exact(mpd_t *result, const mpd_t *a, const mpd_t *b,
3541                const mpd_context_t *ctx, uint32_t *status)
3542{
3543    uint32_t workstatus = 0;
3544
3545    mpd_qsub(result, a, b, ctx, &workstatus);
3546    *status |= workstatus;
3547    if (workstatus & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
3548        mpd_seterror(result, MPD_Invalid_operation, status);
3549    }
3550}
3551
3552/* Add decimal and mpd_ssize_t. */
3553void
3554mpd_qadd_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b,
3555               const mpd_context_t *ctx, uint32_t *status)
3556{
3557    mpd_context_t maxcontext;
3558    MPD_NEW_STATIC(bb,0,0,0,0);
3559
3560    mpd_maxcontext(&maxcontext);
3561    mpd_qsset_ssize(&bb, b, &maxcontext, status);
3562    mpd_qadd(result, a, &bb, ctx, status);
3563    mpd_del(&bb);
3564}
3565
3566/* Add decimal and mpd_uint_t. */
3567void
3568mpd_qadd_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b,
3569              const mpd_context_t *ctx, uint32_t *status)
3570{
3571    mpd_context_t maxcontext;
3572    MPD_NEW_STATIC(bb,0,0,0,0);
3573
3574    mpd_maxcontext(&maxcontext);
3575    mpd_qsset_uint(&bb, b, &maxcontext, status);
3576    mpd_qadd(result, a, &bb, ctx, status);
3577    mpd_del(&bb);
3578}
3579
3580/* Subtract mpd_ssize_t from decimal. */
3581void
3582mpd_qsub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b,
3583               const mpd_context_t *ctx, uint32_t *status)
3584{
3585    mpd_context_t maxcontext;
3586    MPD_NEW_STATIC(bb,0,0,0,0);
3587
3588    mpd_maxcontext(&maxcontext);
3589    mpd_qsset_ssize(&bb, b, &maxcontext, status);
3590    mpd_qsub(result, a, &bb, ctx, status);
3591    mpd_del(&bb);
3592}
3593
3594/* Subtract mpd_uint_t from decimal. */
3595void
3596mpd_qsub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b,
3597              const mpd_context_t *ctx, uint32_t *status)
3598{
3599    mpd_context_t maxcontext;
3600    MPD_NEW_STATIC(bb,0,0,0,0);
3601
3602    mpd_maxcontext(&maxcontext);
3603    mpd_qsset_uint(&bb, b, &maxcontext, status);
3604    mpd_qsub(result, a, &bb, ctx, status);
3605    mpd_del(&bb);
3606}
3607
3608/* Add decimal and int32_t. */
3609void
3610mpd_qadd_i32(mpd_t *result, const mpd_t *a, int32_t b,
3611             const mpd_context_t *ctx, uint32_t *status)
3612{
3613    mpd_qadd_ssize(result, a, b, ctx, status);
3614}
3615
3616/* Add decimal and uint32_t. */
3617void
3618mpd_qadd_u32(mpd_t *result, const mpd_t *a, uint32_t b,
3619             const mpd_context_t *ctx, uint32_t *status)
3620{
3621    mpd_qadd_uint(result, a, b, ctx, status);
3622}
3623
3624#ifdef CONFIG_64
3625/* Add decimal and int64_t. */
3626void
3627mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b,
3628             const mpd_context_t *ctx, uint32_t *status)
3629{
3630    mpd_qadd_ssize(result, a, b, ctx, status);
3631}
3632
3633/* Add decimal and uint64_t. */
3634void
3635mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b,
3636             const mpd_context_t *ctx, uint32_t *status)
3637{
3638    mpd_qadd_uint(result, a, b, ctx, status);
3639}
3640#elif !defined(LEGACY_COMPILER)
3641/* Add decimal and int64_t. */
3642void
3643mpd_qadd_i64(mpd_t *result, const mpd_t *a, int64_t b,
3644             const mpd_context_t *ctx, uint32_t *status)
3645{
3646    mpd_context_t maxcontext;
3647    MPD_NEW_STATIC(bb,0,0,0,0);
3648
3649    mpd_maxcontext(&maxcontext);
3650    mpd_qset_i64(&bb, b, &maxcontext, status);
3651    mpd_qadd(result, a, &bb, ctx, status);
3652    mpd_del(&bb);
3653}
3654
3655/* Add decimal and uint64_t. */
3656void
3657mpd_qadd_u64(mpd_t *result, const mpd_t *a, uint64_t b,
3658             const mpd_context_t *ctx, uint32_t *status)
3659{
3660    mpd_context_t maxcontext;
3661    MPD_NEW_STATIC(bb,0,0,0,0);
3662
3663    mpd_maxcontext(&maxcontext);
3664    mpd_qset_u64(&bb, b, &maxcontext, status);
3665    mpd_qadd(result, a, &bb, ctx, status);
3666    mpd_del(&bb);
3667}
3668#endif
3669
3670/* Subtract int32_t from decimal. */
3671void
3672mpd_qsub_i32(mpd_t *result, const mpd_t *a, int32_t b,
3673             const mpd_context_t *ctx, uint32_t *status)
3674{
3675    mpd_qsub_ssize(result, a, b, ctx, status);
3676}
3677
3678/* Subtract uint32_t from decimal. */
3679void
3680mpd_qsub_u32(mpd_t *result, const mpd_t *a, uint32_t b,
3681             const mpd_context_t *ctx, uint32_t *status)
3682{
3683    mpd_qsub_uint(result, a, b, ctx, status);
3684}
3685
3686#ifdef CONFIG_64
3687/* Subtract int64_t from decimal. */
3688void
3689mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b,
3690             const mpd_context_t *ctx, uint32_t *status)
3691{
3692    mpd_qsub_ssize(result, a, b, ctx, status);
3693}
3694
3695/* Subtract uint64_t from decimal. */
3696void
3697mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b,
3698             const mpd_context_t *ctx, uint32_t *status)
3699{
3700    mpd_qsub_uint(result, a, b, ctx, status);
3701}
3702#elif !defined(LEGACY_COMPILER)
3703/* Subtract int64_t from decimal. */
3704void
3705mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b,
3706             const mpd_context_t *ctx, uint32_t *status)
3707{
3708    mpd_context_t maxcontext;
3709    MPD_NEW_STATIC(bb,0,0,0,0);
3710
3711    mpd_maxcontext(&maxcontext);
3712    mpd_qset_i64(&bb, b, &maxcontext, status);
3713    mpd_qsub(result, a, &bb, ctx, status);
3714    mpd_del(&bb);
3715}
3716
3717/* Subtract uint64_t from decimal. */
3718void
3719mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b,
3720             const mpd_context_t *ctx, uint32_t *status)
3721{
3722    mpd_context_t maxcontext;
3723    MPD_NEW_STATIC(bb,0,0,0,0);
3724
3725    mpd_maxcontext(&maxcontext);
3726    mpd_qset_u64(&bb, b, &maxcontext, status);
3727    mpd_qsub(result, a, &bb, ctx, status);
3728    mpd_del(&bb);
3729}
3730#endif
3731
3732
3733/* Divide infinities. */
3734static void
3735_mpd_qdiv_inf(mpd_t *result, const mpd_t *a, const mpd_t *b,
3736              const mpd_context_t *ctx, uint32_t *status)
3737{
3738    if (mpd_isinfinite(a)) {
3739        if (mpd_isinfinite(b)) {
3740            mpd_seterror(result, MPD_Invalid_operation, status);
3741            return;
3742        }
3743        mpd_setspecial(result, mpd_sign(a)^mpd_sign(b), MPD_INF);
3744        return;
3745    }
3746    assert(mpd_isinfinite(b));
3747    _settriple(result, mpd_sign(a)^mpd_sign(b), 0, mpd_etiny(ctx));
3748    *status |= MPD_Clamped;
3749}
3750
3751enum {NO_IDEAL_EXP, SET_IDEAL_EXP};
3752/* Divide a by b. */
3753static void
3754_mpd_qdiv(int action, mpd_t *q, const mpd_t *a, const mpd_t *b,
3755          const mpd_context_t *ctx, uint32_t *status)
3756{
3757    MPD_NEW_STATIC(aligned,0,0,0,0);
3758    mpd_uint_t ld;
3759    mpd_ssize_t shift, exp, tz;
3760    mpd_ssize_t newsize;
3761    mpd_ssize_t ideal_exp;
3762    mpd_uint_t rem;
3763    uint8_t sign_a = mpd_sign(a);
3764    uint8_t sign_b = mpd_sign(b);
3765
3766
3767    if (mpd_isspecial(a) || mpd_isspecial(b)) {
3768        if (mpd_qcheck_nans(q, a, b, ctx, status)) {
3769            return;
3770        }
3771        _mpd_qdiv_inf(q, a, b, ctx, status);
3772        return;
3773    }
3774    if (mpd_iszerocoeff(b)) {
3775        if (mpd_iszerocoeff(a)) {
3776            mpd_seterror(q, MPD_Division_undefined, status);
3777        }
3778        else {
3779            mpd_setspecial(q, sign_a^sign_b, MPD_INF);
3780            *status |= MPD_Division_by_zero;
3781        }
3782        return;
3783    }
3784    if (mpd_iszerocoeff(a)) {
3785        exp = a->exp - b->exp;
3786        _settriple(q, sign_a^sign_b, 0, exp);
3787        mpd_qfinalize(q, ctx, status);
3788        return;
3789    }
3790
3791    shift = (b->digits - a->digits) + ctx->prec + 1;
3792    ideal_exp = a->exp - b->exp;
3793    exp = ideal_exp - shift;
3794    if (shift > 0) {
3795        if (!mpd_qshiftl(&aligned, a, shift, status)) {
3796            mpd_seterror(q, MPD_Malloc_error, status);
3797            goto finish;
3798        }
3799        a = &aligned;
3800    }
3801    else if (shift < 0) {
3802        shift = -shift;
3803        if (!mpd_qshiftl(&aligned, b, shift, status)) {
3804            mpd_seterror(q, MPD_Malloc_error, status);
3805            goto finish;
3806        }
3807        b = &aligned;
3808    }
3809
3810
3811    newsize = a->len - b->len + 1;
3812    if ((q != b && q != a) || (q == b && newsize > b->len)) {
3813        if (!mpd_qresize(q, newsize, status)) {
3814            mpd_seterror(q, MPD_Malloc_error, status);
3815            goto finish;
3816        }
3817    }
3818
3819
3820    if (b->len == 1) {
3821        rem = _mpd_shortdiv(q->data, a->data, a->len, b->data[0]);
3822    }
3823    else if (b->len <= MPD_NEWTONDIV_CUTOFF) {
3824        int ret = _mpd_basedivmod(q->data, NULL, a->data, b->data,
3825                                  a->len, b->len);
3826        if (ret < 0) {
3827            mpd_seterror(q, MPD_Malloc_error, status);
3828            goto finish;
3829        }
3830        rem = ret;
3831    }
3832    else {
3833        MPD_NEW_STATIC(r,0,0,0,0);
3834        _mpd_base_ndivmod(q, &r, a, b, status);
3835        if (mpd_isspecial(q) || mpd_isspecial(&r)) {
3836            mpd_setspecial(q, MPD_POS, MPD_NAN);
3837            mpd_del(&r);
3838            goto finish;
3839        }
3840        rem = !mpd_iszerocoeff(&r);
3841        mpd_del(&r);
3842        newsize = q->len;
3843    }
3844
3845    newsize = _mpd_real_size(q->data, newsize);
3846    /* resize to smaller cannot fail */
3847    mpd_qresize(q, newsize, status);
3848    mpd_set_flags(q, sign_a^sign_b);
3849    q->len = newsize;
3850    mpd_setdigits(q);
3851
3852    shift = ideal_exp - exp;
3853    if (rem) {
3854        ld = mpd_lsd(q->data[0]);
3855        if (ld == 0 || ld == 5) {
3856            q->data[0] += 1;
3857        }
3858    }
3859    else if (action == SET_IDEAL_EXP && shift > 0) {
3860        tz = mpd_trail_zeros(q);
3861        shift = (tz > shift) ? shift : tz;
3862        mpd_qshiftr_inplace(q, shift);
3863        exp += shift;
3864    }
3865
3866    q->exp = exp;
3867
3868
3869finish:
3870    mpd_del(&aligned);
3871    mpd_qfinalize(q, ctx, status);
3872}
3873
3874/* Divide a by b. */
3875void
3876mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b,
3877         const mpd_context_t *ctx, uint32_t *status)
3878{
3879    MPD_NEW_STATIC(aa,0,0,0,0);
3880    MPD_NEW_STATIC(bb,0,0,0,0);
3881    uint32_t xstatus = 0;
3882
3883    if (q == a) {
3884        if (!mpd_qcopy(&aa, a, status)) {
3885            mpd_seterror(q, MPD_Malloc_error, status);
3886            goto out;
3887        }
3888        a = &aa;
3889    }
3890
3891    if (q == b) {
3892        if (!mpd_qcopy(&bb, b, status)) {
3893            mpd_seterror(q, MPD_Malloc_error, status);
3894            goto out;
3895        }
3896        b = &bb;
3897    }
3898
3899    _mpd_qdiv(SET_IDEAL_EXP, q, a, b, ctx, &xstatus);
3900
3901    if (xstatus & (MPD_Malloc_error|MPD_Division_impossible)) {
3902        /* Inexact quotients (the usual case) fill the entire context precision,
3903         * which can lead to the above errors for very high precisions. Retry
3904         * the operation with a lower precision in case the result is exact.
3905         *
3906         * We need an upper bound for the number of digits of a_coeff / b_coeff
3907         * when the result is exact.  If a_coeff' * 1 / b_coeff' is in lowest
3908         * terms, then maxdigits(a_coeff') + maxdigits(1 / b_coeff') is a suitable
3909         * bound.
3910         *
3911         * 1 / b_coeff' is exact iff b_coeff' exclusively has prime factors 2 or 5.
3912         * The largest amount of digits is generated if b_coeff' is a power of 2 or
3913         * a power of 5 and is less than or equal to log5(b_coeff') <= log2(b_coeff').
3914         *
3915         * We arrive at a total upper bound:
3916         *
3917         *   maxdigits(a_coeff') + maxdigits(1 / b_coeff') <=
3918         *   log10(a_coeff) + log2(b_coeff) =
3919         *   log10(a_coeff) + log10(b_coeff) / log10(2) <=
3920         *   a->digits + b->digits * 4;
3921         */
3922        mpd_context_t workctx = *ctx;
3923        uint32_t ystatus = 0;
3924
3925        workctx.prec = a->digits + b->digits * 4;
3926        if (workctx.prec >= ctx->prec) {
3927            *status |= (xstatus&MPD_Errors);
3928            goto out;  /* No point in retrying, keep the original error. */
3929        }
3930
3931        _mpd_qdiv(SET_IDEAL_EXP, q, a, b, &workctx, &ystatus);
3932        if (ystatus != 0) {
3933            ystatus = *status | ((ystatus|xstatus)&MPD_Errors);
3934            mpd_seterror(q, ystatus, status);
3935        }
3936    }
3937    else {
3938        *status |= xstatus;
3939    }
3940
3941
3942out:
3943    mpd_del(&aa);
3944    mpd_del(&bb);
3945}
3946
3947/* Internal function. */
3948static void
3949_mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b,
3950             const mpd_context_t *ctx, uint32_t *status)
3951{
3952    MPD_NEW_STATIC(aligned,0,0,0,0);
3953    mpd_ssize_t qsize, rsize;
3954    mpd_ssize_t ideal_exp, expdiff, shift;
3955    uint8_t sign_a = mpd_sign(a);
3956    uint8_t sign_ab = mpd_sign(a)^mpd_sign(b);
3957
3958
3959    ideal_exp = (a->exp > b->exp) ?  b->exp : a->exp;
3960    if (mpd_iszerocoeff(a)) {
3961        if (!mpd_qcopy(r, a, status)) {
3962            goto nanresult; /* GCOV_NOT_REACHED */
3963        }
3964        r->exp = ideal_exp;
3965        _settriple(q, sign_ab, 0, 0);
3966        return;
3967    }
3968
3969    expdiff = mpd_adjexp(a) - mpd_adjexp(b);
3970    if (expdiff < 0) {
3971        if (a->exp > b->exp) {
3972            /* positive and less than b->digits - a->digits */
3973            shift = a->exp - b->exp;
3974            if (!mpd_qshiftl(r, a, shift, status)) {
3975                goto nanresult;
3976            }
3977            r->exp = ideal_exp;
3978        }
3979        else {
3980            if (!mpd_qcopy(r, a, status)) {
3981                goto nanresult;
3982            }
3983        }
3984        _settriple(q, sign_ab, 0, 0);
3985        return;
3986    }
3987    if (expdiff > ctx->prec) {
3988        *status |= MPD_Division_impossible;
3989        goto nanresult;
3990    }
3991
3992
3993    /*
3994     * At this point we have:
3995     *   (1) 0 <= a->exp + a->digits - b->exp - b->digits <= prec
3996     *   (2) a->exp - b->exp >= b->digits - a->digits
3997     *   (3) a->exp - b->exp <= prec + b->digits - a->digits
3998     */
3999    if (a->exp != b->exp) {
4000        shift = a->exp - b->exp;
4001        if (shift > 0) {
4002            /* by (3), after the shift a->digits <= prec + b->digits */
4003            if (!mpd_qshiftl(&aligned, a, shift, status)) {
4004                goto nanresult;
4005            }
4006            a = &aligned;
4007        }
4008        else  {
4009            shift = -shift;
4010            /* by (2), after the shift b->digits <= a->digits */
4011            if (!mpd_qshiftl(&aligned, b, shift, status)) {
4012                goto nanresult;
4013            }
4014            b = &aligned;
4015        }
4016    }
4017
4018
4019    qsize = a->len - b->len + 1;
4020    if (!(q == a && qsize < a->len) && !(q == b && qsize < b->len)) {
4021        if (!mpd_qresize(q, qsize, status)) {
4022            goto nanresult;
4023        }
4024    }
4025
4026    rsize = b->len;
4027    if (!(r == a && rsize < a->len)) {
4028        if (!mpd_qresize(r, rsize, status)) {
4029            goto nanresult;
4030        }
4031    }
4032
4033    if (b->len == 1) {
4034        assert(b->data[0] != 0); /* annotation for scan-build */
4035        if (a->len == 1) {
4036            _mpd_div_word(&q->data[0], &r->data[0], a->data[0], b->data[0]);
4037        }
4038        else {
4039            r->data[0] = _mpd_shortdiv(q->data, a->data, a->len, b->data[0]);
4040        }
4041    }
4042    else if (b->len <= MPD_NEWTONDIV_CUTOFF) {
4043        int ret;
4044        ret = _mpd_basedivmod(q->data, r->data, a->data, b->data,
4045                              a->len, b->len);
4046        if (ret == -1) {
4047            *status |= MPD_Malloc_error;
4048            goto nanresult;
4049        }
4050    }
4051    else {
4052        _mpd_base_ndivmod(q, r, a, b, status);
4053        if (mpd_isspecial(q) || mpd_isspecial(r)) {
4054            goto nanresult;
4055        }
4056        qsize = q->len;
4057        rsize = r->len;
4058    }
4059
4060    qsize = _mpd_real_size(q->data, qsize);
4061    /* resize to smaller cannot fail */
4062    mpd_qresize(q, qsize, status);
4063    q->len = qsize;
4064    mpd_setdigits(q);
4065    mpd_set_flags(q, sign_ab);
4066    q->exp = 0;
4067    if (q->digits > ctx->prec) {
4068        *status |= MPD_Division_impossible;
4069        goto nanresult;
4070    }
4071
4072    rsize = _mpd_real_size(r->data, rsize);
4073    /* resize to smaller cannot fail */
4074    mpd_qresize(r, rsize, status);
4075    r->len = rsize;
4076    mpd_setdigits(r);
4077    mpd_set_flags(r, sign_a);
4078    r->exp = ideal_exp;
4079
4080out:
4081    mpd_del(&aligned);
4082    return;
4083
4084nanresult:
4085    mpd_setspecial(q, MPD_POS, MPD_NAN);
4086    mpd_setspecial(r, MPD_POS, MPD_NAN);
4087    goto out;
4088}
4089
4090/* Integer division with remainder. */
4091void
4092mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b,
4093            const mpd_context_t *ctx, uint32_t *status)
4094{
4095    uint8_t sign = mpd_sign(a)^mpd_sign(b);
4096
4097    if (mpd_isspecial(a) || mpd_isspecial(b)) {
4098        if (mpd_qcheck_nans(q, a, b, ctx, status)) {
4099            mpd_qcopy(r, q, status);
4100            return;
4101        }
4102        if (mpd_isinfinite(a)) {
4103            if (mpd_isinfinite(b)) {
4104                mpd_setspecial(q, MPD_POS, MPD_NAN);
4105            }
4106            else {
4107                mpd_setspecial(q, sign, MPD_INF);
4108            }
4109            mpd_setspecial(r, MPD_POS, MPD_NAN);
4110            *status |= MPD_Invalid_operation;
4111            return;
4112        }
4113        if (mpd_isinfinite(b)) {
4114            if (!mpd_qcopy(r, a, status)) {
4115                mpd_seterror(q, MPD_Malloc_error, status);
4116                return;
4117            }
4118            mpd_qfinalize(r, ctx, status);
4119            _settriple(q, sign, 0, 0);
4120            return;
4121        }
4122        /* debug */
4123        abort(); /* GCOV_NOT_REACHED */
4124    }
4125    if (mpd_iszerocoeff(b)) {
4126        if (mpd_iszerocoeff(a)) {
4127            mpd_setspecial(q, MPD_POS, MPD_NAN);
4128            mpd_setspecial(r, MPD_POS, MPD_NAN);
4129            *status |= MPD_Division_undefined;
4130        }
4131        else {
4132            mpd_setspecial(q, sign, MPD_INF);
4133            mpd_setspecial(r, MPD_POS, MPD_NAN);
4134            *status |= (MPD_Division_by_zero|MPD_Invalid_operation);
4135        }
4136        return;
4137    }
4138
4139    _mpd_qdivmod(q, r, a, b, ctx, status);
4140    mpd_qfinalize(q, ctx, status);
4141    mpd_qfinalize(r, ctx, status);
4142}
4143
4144void
4145mpd_qdivint(mpd_t *q, const mpd_t *a, const mpd_t *b,
4146            const mpd_context_t *ctx, uint32_t *status)
4147{
4148    MPD_NEW_STATIC(r,0,0,0,0);
4149    uint8_t sign = mpd_sign(a)^mpd_sign(b);
4150
4151    if (mpd_isspecial(a) || mpd_isspecial(b)) {
4152        if (mpd_qcheck_nans(q, a, b, ctx, status)) {
4153            return;
4154        }
4155        if (mpd_isinfinite(a) && mpd_isinfinite(b)) {
4156            mpd_seterror(q, MPD_Invalid_operation, status);
4157            return;
4158        }
4159        if (mpd_isinfinite(a)) {
4160            mpd_setspecial(q, sign, MPD_INF);
4161            return;
4162        }
4163        if (mpd_isinfinite(b)) {
4164            _settriple(q, sign, 0, 0);
4165            return;
4166        }
4167        /* debug */
4168        abort(); /* GCOV_NOT_REACHED */
4169    }
4170    if (mpd_iszerocoeff(b)) {
4171        if (mpd_iszerocoeff(a)) {
4172            mpd_seterror(q, MPD_Division_undefined, status);
4173        }
4174        else {
4175            mpd_setspecial(q, sign, MPD_INF);
4176            *status |= MPD_Division_by_zero;
4177        }
4178        return;
4179    }
4180
4181
4182    _mpd_qdivmod(q, &r, a, b, ctx, status);
4183    mpd_del(&r);
4184    mpd_qfinalize(q, ctx, status);
4185}
4186
4187/* Divide decimal by mpd_ssize_t. */
4188void
4189mpd_qdiv_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b,
4190               const mpd_context_t *ctx, uint32_t *status)
4191{
4192    mpd_context_t maxcontext;
4193    MPD_NEW_STATIC(bb,0,0,0,0);
4194
4195    mpd_maxcontext(&maxcontext);
4196    mpd_qsset_ssize(&bb, b, &maxcontext, status);
4197    mpd_qdiv(result, a, &bb, ctx, status);
4198    mpd_del(&bb);
4199}
4200
4201/* Divide decimal by mpd_uint_t. */
4202void
4203mpd_qdiv_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b,
4204              const mpd_context_t *ctx, uint32_t *status)
4205{
4206    mpd_context_t maxcontext;
4207    MPD_NEW_STATIC(bb,0,0,0,0);
4208
4209    mpd_maxcontext(&maxcontext);
4210    mpd_qsset_uint(&bb, b, &maxcontext, status);
4211    mpd_qdiv(result, a, &bb, ctx, status);
4212    mpd_del(&bb);
4213}
4214
4215/* Divide decimal by int32_t. */
4216void
4217mpd_qdiv_i32(mpd_t *result, const mpd_t *a, int32_t b,
4218             const mpd_context_t *ctx, uint32_t *status)
4219{
4220    mpd_qdiv_ssize(result, a, b, ctx, status);
4221}
4222
4223/* Divide decimal by uint32_t. */
4224void
4225mpd_qdiv_u32(mpd_t *result, const mpd_t *a, uint32_t b,
4226             const mpd_context_t *ctx, uint32_t *status)
4227{
4228    mpd_qdiv_uint(result, a, b, ctx, status);
4229}
4230
4231#ifdef CONFIG_64
4232/* Divide decimal by int64_t. */
4233void
4234mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b,
4235             const mpd_context_t *ctx, uint32_t *status)
4236{
4237    mpd_qdiv_ssize(result, a, b, ctx, status);
4238}
4239
4240/* Divide decimal by uint64_t. */
4241void
4242mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b,
4243             const mpd_context_t *ctx, uint32_t *status)
4244{
4245    mpd_qdiv_uint(result, a, b, ctx, status);
4246}
4247#elif !defined(LEGACY_COMPILER)
4248/* Divide decimal by int64_t. */
4249void
4250mpd_qdiv_i64(mpd_t *result, const mpd_t *a, int64_t b,
4251             const mpd_context_t *ctx, uint32_t *status)
4252{
4253    mpd_context_t maxcontext;
4254    MPD_NEW_STATIC(bb,0,0,0,0);
4255
4256    mpd_maxcontext(&maxcontext);
4257    mpd_qset_i64(&bb, b, &maxcontext, status);
4258    mpd_qdiv(result, a, &bb, ctx, status);
4259    mpd_del(&bb);
4260}
4261
4262/* Divide decimal by uint64_t. */
4263void
4264mpd_qdiv_u64(mpd_t *result, const mpd_t *a, uint64_t b,
4265             const mpd_context_t *ctx, uint32_t *status)
4266{
4267    mpd_context_t maxcontext;
4268    MPD_NEW_STATIC(bb,0,0,0,0);
4269
4270    mpd_maxcontext(&maxcontext);
4271    mpd_qset_u64(&bb, b, &maxcontext, status);
4272    mpd_qdiv(result, a, &bb, ctx, status);
4273    mpd_del(&bb);
4274}
4275#endif
4276
4277/* Pad the result with trailing zeros if it has fewer digits than prec. */
4278static void
4279_mpd_zeropad(mpd_t *result, const mpd_context_t *ctx, uint32_t *status)
4280{
4281    if (!mpd_isspecial(result) && !mpd_iszero(result) &&
4282        result->digits < ctx->prec) {
4283       mpd_ssize_t shift = ctx->prec - result->digits;
4284       mpd_qshiftl(result, result, shift, status);
4285       result->exp -= shift;
4286    }
4287}
4288
4289/* Check if the result is guaranteed to be one. */
4290static int
4291_mpd_qexp_check_one(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
4292                    uint32_t *status)
4293{
4294    MPD_NEW_CONST(lim,0,-(ctx->prec+1),1,1,1,9);
4295    MPD_NEW_SHARED(aa, a);
4296
4297    mpd_set_positive(&aa);
4298
4299    /* abs(a) <= 9 * 10**(-prec-1) */
4300    if (_mpd_cmp(&aa, &lim) <= 0) {
4301        _settriple(result, 0, 1, 0);
4302        *status |= MPD_Rounded|MPD_Inexact;
4303        return 1;
4304    }
4305
4306    return 0;
4307}
4308
4309/*
4310 * Get the number of iterations for the Horner scheme in _mpd_qexp().
4311 */
4312static inline mpd_ssize_t
4313_mpd_get_exp_iterations(const mpd_t *r, mpd_ssize_t p)
4314{
4315    mpd_ssize_t log10pbyr; /* lower bound for log10(p / abs(r)) */
4316    mpd_ssize_t n;
4317
4318    assert(p >= 10);
4319    assert(!mpd_iszero(r));
4320    assert(-p < mpd_adjexp(r) && mpd_adjexp(r) <= -1);
4321
4322#ifdef CONFIG_64
4323    if (p > (mpd_ssize_t)(1ULL<<52)) {
4324        return MPD_SSIZE_MAX;
4325    }
4326#endif
4327
4328    /*
4329     * Lower bound for log10(p / abs(r)): adjexp(p) - (adjexp(r) + 1)
4330     * At this point (for CONFIG_64, CONFIG_32 is not problematic):
4331     *    1) 10 <= p <= 2**52
4332     *    2) -p < adjexp(r) <= -1
4333     *    3) 1 <= log10pbyr <= 2**52 + 14
4334     */
4335    log10pbyr = (mpd_word_digits(p)-1) - (mpd_adjexp(r)+1);
4336
4337    /*
4338     * The numerator in the paper is 1.435 * p - 1.182, calculated
4339     * exactly. We compensate for rounding errors by using 1.43503.
4340     * ACL2 proofs:
4341     *    1) exp-iter-approx-lower-bound: The term below evaluated
4342     *       in 53-bit floating point arithmetic is greater than or
4343     *       equal to the exact term used in the paper.
4344     *    2) exp-iter-approx-upper-bound: The term below is less than
4345     *       or equal to 3/2 * p <= 3/2 * 2**52.
4346     */
4347    n = (mpd_ssize_t)ceil((1.43503*(double)p - 1.182) / (double)log10pbyr);
4348    return n >= 3 ? n : 3;
4349}
4350
4351/*
4352 * Internal function, specials have been dealt with. Apart from Overflow
4353 * and Underflow, two cases must be considered for the error of the result:
4354 *
4355 *   1) abs(a) <= 9 * 10**(-prec-1)  ==>  result == 1
4356 *
4357 *      Absolute error: abs(1 - e**x) < 10**(-prec)
4358 *      -------------------------------------------
4359 *
4360 *   2) abs(a) > 9 * 10**(-prec-1)
4361 *
4362 *      Relative error: abs(result - e**x) < 0.5 * 10**(-prec) * e**x
4363 *      -------------------------------------------------------------
4364 *
4365 * The algorithm is from Hull&Abrham, Variable Precision Exponential Function,
4366 * ACM Transactions on Mathematical Software, Vol. 12, No. 2, June 1986.
4367 *
4368 * Main differences:
4369 *
4370 *  - The number of iterations for the Horner scheme is calculated using
4371 *    53-bit floating point arithmetic.
4372 *
4373 *  - In the error analysis for ER (relative error accumulated in the
4374 *    evaluation of the truncated series) the reduced operand r may
4375 *    have any number of digits.
4376 *    ACL2 proof: exponent-relative-error
4377 *
4378 *  - The analysis for early abortion has been adapted for the mpd_t
4379 *    ranges.
4380 */
4381static void
4382_mpd_qexp(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
4383          uint32_t *status)
4384{
4385    mpd_context_t workctx;
4386    MPD_NEW_STATIC(tmp,0,0,0,0);
4387    MPD_NEW_STATIC(sum,0,0,0,0);
4388    MPD_NEW_CONST(word,0,0,1,1,1,1);
4389    mpd_ssize_t j, n, t;
4390
4391    assert(!mpd_isspecial(a));
4392
4393    if (mpd_iszerocoeff(a)) {
4394        _settriple(result, MPD_POS, 1, 0);
4395        return;
4396    }
4397
4398    /*
4399     * We are calculating e^x = e^(r*10^t) = (e^r)^(10^t), where abs(r) < 1 and t >= 0.
4400     *
4401     * If t > 0, we have:
4402     *
4403     *   (1) 0.1 <= r < 1, so e^0.1 <= e^r. If t > MAX_T, overflow occurs:
4404     *
4405     *     MAX-EMAX+1 < log10(e^(0.1*10*t)) <= log10(e^(r*10^t)) < adjexp(e^(r*10^t))+1
4406     *
4407     *   (2) -1 < r <= -0.1, so e^r <= e^-0.1. If t > MAX_T, underflow occurs:
4408     *
4409     *     adjexp(e^(r*10^t)) <= log10(e^(r*10^t)) <= log10(e^(-0.1*10^t)) < MIN-ETINY
4410     */
4411#if defined(CONFIG_64)
4412    #define MPD_EXP_MAX_T 19
4413#elif defined(CONFIG_32)
4414    #define MPD_EXP_MAX_T 10
4415#endif
4416    t = a->digits + a->exp;
4417    t = (t > 0) ? t : 0;
4418    if (t > MPD_EXP_MAX_T) {
4419        if (mpd_ispositive(a)) {
4420            mpd_setspecial(result, MPD_POS, MPD_INF);
4421            *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded;
4422        }
4423        else {
4424            _settriple(result, MPD_POS, 0, mpd_etiny(ctx));
4425            *status |= (MPD_Inexact|MPD_Rounded|MPD_Subnormal|
4426                        MPD_Underflow|MPD_Clamped);
4427        }
4428        return;
4429    }
4430
4431    /* abs(a) <= 9 * 10**(-prec-1) */
4432    if (_mpd_qexp_check_one(result, a, ctx, status)) {
4433        return;
4434    }
4435
4436    mpd_maxcontext(&workctx);
4437    workctx.prec = ctx->prec + t + 2;
4438    workctx.prec = (workctx.prec < 10) ? 10 : workctx.prec;
4439    workctx.round = MPD_ROUND_HALF_EVEN;
4440
4441    if (!mpd_qcopy(result, a, status)) {
4442        return;
4443    }
4444    result->exp -= t;
4445
4446    /*
4447     * At this point:
4448     *    1) 9 * 10**(-prec-1) < abs(a)
4449     *    2) 9 * 10**(-prec-t-1) < abs(r)
4450     *    3) log10(9) - prec - t - 1 < log10(abs(r)) < adjexp(abs(r)) + 1
4451     *    4) - prec - t - 2 < adjexp(abs(r)) <= -1
4452     */
4453    n = _mpd_get_exp_iterations(result, workctx.prec);
4454    if (n == MPD_SSIZE_MAX) {
4455        mpd_seterror(result, MPD_Invalid_operation, status); /* GCOV_UNLIKELY */
4456        return; /* GCOV_UNLIKELY */
4457    }
4458
4459    _settriple(&sum, MPD_POS, 1, 0);
4460
4461    for (j = n-1; j >= 1; j--) {
4462        word.data[0] = j;
4463        mpd_setdigits(&word);
4464        mpd_qdiv(&tmp, result, &word, &workctx, &workctx.status);
4465        mpd_qfma(&sum, &sum, &tmp, &one, &workctx, &workctx.status);
4466    }
4467
4468#ifdef CONFIG_64
4469    _mpd_qpow_uint(result, &sum, mpd_pow10[t], MPD_POS, &workctx, status);
4470#else
4471    if (t <= MPD_MAX_POW10) {
4472        _mpd_qpow_uint(result, &sum, mpd_pow10[t], MPD_POS, &workctx, status);
4473    }
4474    else {
4475        t -= MPD_MAX_POW10;
4476        _mpd_qpow_uint(&tmp, &sum, mpd_pow10[MPD_MAX_POW10], MPD_POS,
4477                       &workctx, status);
4478        _mpd_qpow_uint(result, &tmp, mpd_pow10[t], MPD_POS, &workctx, status);
4479    }
4480#endif
4481
4482    mpd_del(&tmp);
4483    mpd_del(&sum);
4484    *status |= (workctx.status&MPD_Errors);
4485    *status |= (MPD_Inexact|MPD_Rounded);
4486}
4487
4488/* exp(a) */
4489void
4490mpd_qexp(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
4491         uint32_t *status)
4492{
4493    mpd_context_t workctx;
4494
4495    if (mpd_isspecial(a)) {
4496        if (mpd_qcheck_nan(result, a, ctx, status)) {
4497            return;
4498        }
4499        if (mpd_isnegative(a)) {
4500            _settriple(result, MPD_POS, 0, 0);
4501        }
4502        else {
4503            mpd_setspecial(result, MPD_POS, MPD_INF);
4504        }
4505        return;
4506    }
4507    if (mpd_iszerocoeff(a)) {
4508        _settriple(result, MPD_POS, 1, 0);
4509        return;
4510    }
4511
4512    workctx = *ctx;
4513    workctx.round = MPD_ROUND_HALF_EVEN;
4514
4515    if (ctx->allcr) {
4516        MPD_NEW_STATIC(t1, 0,0,0,0);
4517        MPD_NEW_STATIC(t2, 0,0,0,0);
4518        MPD_NEW_STATIC(ulp, 0,0,0,0);
4519        MPD_NEW_STATIC(aa, 0,0,0,0);
4520        mpd_ssize_t prec;
4521        mpd_ssize_t ulpexp;
4522        uint32_t workstatus;
4523
4524        if (result == a) {
4525            if (!mpd_qcopy(&aa, a, status)) {
4526                mpd_seterror(result, MPD_Malloc_error, status);
4527                return;
4528            }
4529            a = &aa;
4530        }
4531
4532        workctx.clamp = 0;
4533        prec = ctx->prec + 3;
4534        while (1) {
4535            workctx.prec = prec;
4536            workstatus = 0;
4537
4538            _mpd_qexp(result, a, &workctx, &workstatus);
4539            *status |= workstatus;
4540
4541            ulpexp = result->exp + result->digits - workctx.prec;
4542            if (workstatus & MPD_Underflow) {
4543                /* The effective work precision is result->digits. */
4544                ulpexp = result->exp;
4545            }
4546            _ssettriple(&ulp, MPD_POS, 1, ulpexp);
4547
4548            /*
4549             * At this point [1]:
4550             *   1) abs(result - e**x) < 0.5 * 10**(-prec) * e**x
4551             *   2) result - ulp < e**x < result + ulp
4552             *   3) result - ulp < result < result + ulp
4553             *
4554             * If round(result-ulp)==round(result+ulp), then
4555             * round(result)==round(e**x). Therefore the result
4556             * is correctly rounded.
4557             *
4558             * [1] If abs(a) <= 9 * 10**(-prec-1), use the absolute
4559             *     error for a similar argument.
4560             */
4561            workctx.prec = ctx->prec;
4562            mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status);
4563            mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status);
4564            if (mpd_isspecial(result) || mpd_iszerocoeff(result) ||
4565                mpd_qcmp(&t1, &t2, status) == 0) {
4566                workctx.clamp = ctx->clamp;
4567                _mpd_zeropad(result, &workctx, status);
4568                mpd_check_underflow(result, &workctx, status);
4569                mpd_qfinalize(result, &workctx, status);
4570                break;
4571            }
4572            prec += MPD_RDIGITS;
4573        }
4574        mpd_del(&t1);
4575        mpd_del(&t2);
4576        mpd_del(&ulp);
4577        mpd_del(&aa);
4578    }
4579    else {
4580        _mpd_qexp(result, a, &workctx, status);
4581        _mpd_zeropad(result, &workctx, status);
4582        mpd_check_underflow(result, &workctx, status);
4583        mpd_qfinalize(result, &workctx, status);
4584    }
4585}
4586
4587/* Fused multiply-add: (a * b) + c, with a single final rounding. */
4588void
4589mpd_qfma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c,
4590         const mpd_context_t *ctx, uint32_t *status)
4591{
4592    uint32_t workstatus = 0;
4593    mpd_t *cc = NULL;
4594
4595    if (result == c) {
4596        if ((cc = mpd_qncopy(c)) == NULL) {
4597            mpd_seterror(result, MPD_Malloc_error, status);
4598            return;
4599        }
4600        c = cc;
4601    }
4602
4603    _mpd_qmul(result, a, b, ctx, &workstatus);
4604    if (!(workstatus&MPD_Invalid_operation)) {
4605        mpd_qadd(result, result, c, ctx, &workstatus);
4606    }
4607
4608    if (cc) mpd_del(cc);
4609    *status |= workstatus;
4610}
4611
4612/*
4613 * Schedule the optimal precision increase for the Newton iteration.
4614 *   v := input operand
4615 *   z_0 := initial approximation
4616 *   initprec := natural number such that abs(log(v) - z_0) < 10**-initprec
4617 *   maxprec := target precision
4618 *
4619 * For convenience the output klist contains the elements in reverse order:
4620 *   klist := [k_n-1, ..., k_0], where
4621 *     1) k_0 <= initprec and
4622 *     2) abs(log(v) - result) < 10**(-2*k_n-1 + 1) <= 10**-maxprec.
4623 */
4624static inline int
4625ln_schedule_prec(mpd_ssize_t klist[MPD_MAX_PREC_LOG2], mpd_ssize_t maxprec,
4626                 mpd_ssize_t initprec)
4627{
4628    mpd_ssize_t k;
4629    int i;
4630
4631    assert(maxprec >= 2 && initprec >= 2);
4632    if (maxprec <= initprec) return -1;
4633
4634    i = 0; k = maxprec;
4635    do {
4636        k = (k+2) / 2;
4637        klist[i++] = k;
4638    } while (k > initprec);
4639
4640    return i-1;
4641}
4642
4643/* The constants have been verified with both decimal.py and mpfr. */
4644#ifdef CONFIG_64
4645#if MPD_RDIGITS != 19
4646  #error "mpdecimal.c: MPD_RDIGITS must be 19."
4647#endif
4648static const mpd_uint_t mpd_ln10_data[MPD_MINALLOC_MAX] = {
4649  6983716328982174407ULL, 9089704281976336583ULL, 1515961135648465461ULL,
4650  4416816335727555703ULL, 2900988039194170265ULL, 2307925037472986509ULL,
4651   107598438319191292ULL, 3466624107184669231ULL, 4450099781311469159ULL,
4652  9807828059751193854ULL, 7713456862091670584ULL, 1492198849978748873ULL,
4653  6528728696511086257ULL, 2385392051446341972ULL, 8692180205189339507ULL,
4654  6518769751037497088ULL, 2375253577097505395ULL, 9095610299291824318ULL,
4655   982748238504564801ULL, 5438635917781170543ULL, 7547331541421808427ULL,
4656   752371033310119785ULL, 3171643095059950878ULL, 9785265383207606726ULL,
4657  2932258279850258550ULL, 5497347726624257094ULL, 2976979522110718264ULL,
4658  9221477656763693866ULL, 1979650047149510504ULL, 6674183485704422507ULL,
4659  9702766860595249671ULL, 9278096762712757753ULL, 9314848524948644871ULL,
4660  6826928280848118428ULL,  754403708474699401ULL,  230105703089634572ULL,
4661  1929203337658714166ULL, 7589402567763113569ULL, 4208241314695689016ULL,
4662  2922455440575892572ULL, 9356734206705811364ULL, 2684916746550586856ULL,
4663   644507064800027750ULL, 9476834636167921018ULL, 5659121373450747856ULL,
4664  2835522011480466371ULL, 6470806855677432162ULL, 7141748003688084012ULL,
4665  9619404400222105101ULL, 5504893431493939147ULL, 6674744042432743651ULL,
4666  2287698219886746543ULL, 7773262884616336622ULL, 1985283935053089653ULL,
4667  4680843799894826233ULL, 8168948290720832555ULL, 8067566662873690987ULL,
4668  6248633409525465082ULL, 9829834196778404228ULL, 3524802359972050895ULL,
4669  3327900967572609677ULL,  110148862877297603ULL,  179914546843642076ULL,
4670  2302585092994045684ULL
4671};
4672#else
4673#if MPD_RDIGITS != 9
4674  #error "mpdecimal.c: MPD_RDIGITS must be 9."
4675#endif
4676static const mpd_uint_t mpd_ln10_data[MPD_MINALLOC_MAX] = {
4677  401682692UL, 708474699UL, 720754403UL,  30896345UL, 602301057UL, 765871416UL,
4678  192920333UL, 763113569UL, 589402567UL, 956890167UL,  82413146UL, 589257242UL,
4679  245544057UL, 811364292UL, 734206705UL, 868569356UL, 167465505UL, 775026849UL,
4680  706480002UL,  18064450UL, 636167921UL, 569476834UL, 734507478UL, 156591213UL,
4681  148046637UL, 283552201UL, 677432162UL, 470806855UL, 880840126UL, 417480036UL,
4682  210510171UL, 940440022UL, 939147961UL, 893431493UL, 436515504UL, 440424327UL,
4683  654366747UL, 821988674UL, 622228769UL, 884616336UL, 537773262UL, 350530896UL,
4684  319852839UL, 989482623UL, 468084379UL, 720832555UL, 168948290UL, 736909878UL,
4685  675666628UL, 546508280UL, 863340952UL, 404228624UL, 834196778UL, 508959829UL,
4686   23599720UL, 967735248UL,  96757260UL, 603332790UL, 862877297UL, 760110148UL,
4687  468436420UL, 401799145UL, 299404568UL, 230258509UL
4688};
4689#endif
4690/* _mpd_ln10 is used directly for precisions smaller than MINALLOC_MAX*RDIGITS.
4691   Otherwise, it serves as the initial approximation for calculating ln(10). */
4692static const mpd_t _mpd_ln10 = {
4693  MPD_STATIC|MPD_CONST_DATA, -(MPD_MINALLOC_MAX*MPD_RDIGITS-1),
4694  MPD_MINALLOC_MAX*MPD_RDIGITS, MPD_MINALLOC_MAX, MPD_MINALLOC_MAX,
4695  (mpd_uint_t *)mpd_ln10_data
4696};
4697
4698/*
4699 * Set 'result' to log(10).
4700 *   Ulp error: abs(result - log(10)) < ulp(log(10))
4701 *   Relative error: abs(result - log(10)) < 5 * 10**-prec * log(10)
4702 *
4703 * NOTE: The relative error is not derived from the ulp error, but
4704 * calculated separately using the fact that 23/10 < log(10) < 24/10.
4705 */
4706void
4707mpd_qln10(mpd_t *result, mpd_ssize_t prec, uint32_t *status)
4708{
4709    mpd_context_t varcontext, maxcontext;
4710    MPD_NEW_STATIC(tmp, 0,0,0,0);
4711    MPD_NEW_CONST(static10, 0,0,2,1,1,10);
4712    mpd_ssize_t klist[MPD_MAX_PREC_LOG2];
4713    mpd_uint_t rnd;
4714    mpd_ssize_t shift;
4715    int i;
4716
4717    assert(prec >= 1);
4718
4719    shift = MPD_MINALLOC_MAX*MPD_RDIGITS-prec;
4720    shift = shift < 0 ? 0 : shift;
4721
4722    rnd = mpd_qshiftr(result, &_mpd_ln10, shift, status);
4723    if (rnd == MPD_UINT_MAX) {
4724        mpd_seterror(result, MPD_Malloc_error, status);
4725        return;
4726    }
4727    result->exp = -(result->digits-1);
4728
4729    mpd_maxcontext(&maxcontext);
4730    if (prec < MPD_MINALLOC_MAX*MPD_RDIGITS) {
4731        maxcontext.prec = prec;
4732        _mpd_apply_round_excess(result, rnd, &maxcontext, status);
4733        *status |= (MPD_Inexact|MPD_Rounded);
4734        return;
4735    }
4736
4737    mpd_maxcontext(&varcontext);
4738    varcontext.round = MPD_ROUND_TRUNC;
4739
4740    i = ln_schedule_prec(klist, prec+2, -result->exp);
4741    for (; i >= 0; i--) {
4742        varcontext.prec = 2*klist[i]+3;
4743        result->flags ^= MPD_NEG;
4744        _mpd_qexp(&tmp, result, &varcontext, status);
4745        result->flags ^= MPD_NEG;
4746        mpd_qmul(&tmp, &static10, &tmp, &varcontext, status);
4747        mpd_qsub(&tmp, &tmp, &one, &maxcontext, status);
4748        mpd_qadd(result, result, &tmp, &maxcontext, status);
4749        if (mpd_isspecial(result)) {
4750            break;
4751        }
4752    }
4753
4754    mpd_del(&tmp);
4755    maxcontext.prec = prec;
4756    mpd_qfinalize(result, &maxcontext, status);
4757}
4758
4759/*
4760 * Initial approximations for the ln() iteration. The values have the
4761 * following properties (established with both decimal.py and mpfr):
4762 *
4763 * Index 0 - 400, logarithms of x in [1.00, 5.00]:
4764 *   abs(lnapprox[i] * 10**-3 - log((i+100)/100)) < 10**-2
4765 *   abs(lnapprox[i] * 10**-3 - log((i+1+100)/100)) < 10**-2
4766 *
4767 * Index 401 - 899, logarithms of x in (0.500, 0.999]:
4768 *   abs(-lnapprox[i] * 10**-3 - log((i+100)/1000)) < 10**-2
4769 *   abs(-lnapprox[i] * 10**-3 - log((i+1+100)/1000)) < 10**-2
4770 */
4771static const uint16_t lnapprox[900] = {
4772  /* index 0 - 400: log((i+100)/100) * 1000 */
4773  0, 10, 20, 30, 39, 49, 58, 68, 77, 86, 95, 104, 113, 122, 131, 140, 148, 157,
4774  166, 174, 182, 191, 199, 207, 215, 223, 231, 239, 247, 255, 262, 270, 278,
4775  285, 293, 300, 308, 315, 322, 329, 336, 344, 351, 358, 365, 372, 378, 385,
4776  392, 399, 406, 412, 419, 425, 432, 438, 445, 451, 457, 464, 470, 476, 482,
4777  489, 495, 501, 507, 513, 519, 525, 531, 536, 542, 548, 554, 560, 565, 571,
4778  577, 582, 588, 593, 599, 604, 610, 615, 621, 626, 631, 637, 642, 647, 652,
4779  658, 663, 668, 673, 678, 683, 688, 693, 698, 703, 708, 713, 718, 723, 728,
4780  732, 737, 742, 747, 751, 756, 761, 766, 770, 775, 779, 784, 788, 793, 798,
4781  802, 806, 811, 815, 820, 824, 829, 833, 837, 842, 846, 850, 854, 859, 863,
4782  867, 871, 876, 880, 884, 888, 892, 896, 900, 904, 908, 912, 916, 920, 924,
4783  928, 932, 936, 940, 944, 948, 952, 956, 959, 963, 967, 971, 975, 978, 982,
4784  986, 990, 993, 997, 1001, 1004, 1008, 1012, 1015, 1019, 1022, 1026, 1030,
4785  1033, 1037, 1040, 1044, 1047, 1051, 1054, 1058, 1061, 1065, 1068, 1072, 1075,
4786  1078, 1082, 1085, 1089, 1092, 1095, 1099, 1102, 1105, 1109, 1112, 1115, 1118,
4787  1122, 1125, 1128, 1131, 1135, 1138, 1141, 1144, 1147, 1151, 1154, 1157, 1160,
4788  1163, 1166, 1169, 1172, 1176, 1179, 1182, 1185, 1188, 1191, 1194, 1197, 1200,
4789  1203, 1206, 1209, 1212, 1215, 1218, 1221, 1224, 1227, 1230, 1233, 1235, 1238,
4790  1241, 1244, 1247, 1250, 1253, 1256, 1258, 1261, 1264, 1267, 1270, 1273, 1275,
4791  1278, 1281, 1284, 1286, 1289, 1292, 1295, 1297, 1300, 1303, 1306, 1308, 1311,
4792  1314, 1316, 1319, 1322, 1324, 1327, 1330, 1332, 1335, 1338, 1340, 1343, 1345,
4793  1348, 1351, 1353, 1356, 1358, 1361, 1364, 1366, 1369, 1371, 1374, 1376, 1379,
4794  1381, 1384, 1386, 1389, 1391, 1394, 1396, 1399, 1401, 1404, 1406, 1409, 1411,
4795  1413, 1416, 1418, 1421, 1423, 1426, 1428, 1430, 1433, 1435, 1437, 1440, 1442,
4796  1445, 1447, 1449, 1452, 1454, 1456, 1459, 1461, 1463, 1466, 1468, 1470, 1472,
4797  1475, 1477, 1479, 1482, 1484, 1486, 1488, 1491, 1493, 1495, 1497, 1500, 1502,
4798  1504, 1506, 1509, 1511, 1513, 1515, 1517, 1520, 1522, 1524, 1526, 1528, 1530,
4799  1533, 1535, 1537, 1539, 1541, 1543, 1545, 1548, 1550, 1552, 1554, 1556, 1558,
4800  1560, 1562, 1564, 1567, 1569, 1571, 1573, 1575, 1577, 1579, 1581, 1583, 1585,
4801  1587, 1589, 1591, 1593, 1595, 1597, 1599, 1601, 1603, 1605, 1607, 1609,
4802  /* index 401 - 899: -log((i+100)/1000) * 1000 */
4803  691, 689, 687, 685, 683, 681, 679, 677, 675, 673, 671, 669, 668, 666, 664,
4804  662, 660, 658, 656, 654, 652, 650, 648, 646, 644, 642, 641, 639, 637, 635,
4805  633, 631, 629, 627, 626, 624, 622, 620, 618, 616, 614, 612, 611, 609, 607,
4806  605, 603, 602, 600, 598, 596, 594, 592, 591, 589, 587, 585, 583, 582, 580,
4807  578, 576, 574, 573, 571, 569, 567, 566, 564, 562, 560, 559, 557, 555, 553,
4808  552, 550, 548, 546, 545, 543, 541, 540, 538, 536, 534, 533, 531, 529, 528,
4809  526, 524, 523, 521, 519, 518, 516, 514, 512, 511, 509, 508, 506, 504, 502,
4810  501, 499, 498, 496, 494, 493, 491, 489, 488, 486, 484, 483, 481, 480, 478,
4811  476, 475, 473, 472, 470, 468, 467, 465, 464, 462, 460, 459, 457, 456, 454,
4812  453, 451, 449, 448, 446, 445, 443, 442, 440, 438, 437, 435, 434, 432, 431,
4813  429, 428, 426, 425, 423, 422, 420, 419, 417, 416, 414, 412, 411, 410, 408,
4814  406, 405, 404, 402, 400, 399, 398, 396, 394, 393, 392, 390, 389, 387, 386,
4815  384, 383, 381, 380, 378, 377, 375, 374, 372, 371, 370, 368, 367, 365, 364,
4816  362, 361, 360, 358, 357, 355, 354, 352, 351, 350, 348, 347, 345, 344, 342,
4817  341, 340, 338, 337, 336, 334, 333, 331, 330, 328, 327, 326, 324, 323, 322,
4818  320, 319, 318, 316, 315, 313, 312, 311, 309, 308, 306, 305, 304, 302, 301,
4819  300, 298, 297, 296, 294, 293, 292, 290, 289, 288, 286, 285, 284, 282, 281,
4820  280, 278, 277, 276, 274, 273, 272, 270, 269, 268, 267, 265, 264, 263, 261,
4821  260, 259, 258, 256, 255, 254, 252, 251, 250, 248, 247, 246, 245, 243, 242,
4822  241, 240, 238, 237, 236, 234, 233, 232, 231, 229, 228, 227, 226, 224, 223,
4823  222, 221, 219, 218, 217, 216, 214, 213, 212, 211, 210, 208, 207, 206, 205,
4824  203, 202, 201, 200, 198, 197, 196, 195, 194, 192, 191, 190, 189, 188, 186,
4825  185, 184, 183, 182, 180, 179, 178, 177, 176, 174, 173, 172, 171, 170, 168,
4826  167, 166, 165, 164, 162, 161, 160, 159, 158, 157, 156, 154, 153, 152, 151,
4827  150, 148, 147, 146, 145, 144, 143, 142, 140, 139, 138, 137, 136, 135, 134,
4828  132, 131, 130, 129, 128, 127, 126, 124, 123, 122, 121, 120, 119, 118, 116,
4829  115, 114, 113, 112, 111, 110, 109, 108, 106, 105, 104, 103, 102, 101, 100,
4830  99, 98, 97, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 84, 83, 82, 81, 80, 79,
4831  78, 77, 76, 75, 74, 73, 72, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59,
4832  58, 57, 56, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39,
4833  38, 37, 36, 35, 34, 33, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,
4834  18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
4835};
4836
4837/*
4838 * Internal ln() function that does not check for specials, zero or one.
4839 * Relative error: abs(result - log(a)) < 0.1 * 10**-prec * abs(log(a))
4840 */
4841static void
4842_mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
4843         uint32_t *status)
4844{
4845    mpd_context_t varcontext, maxcontext;
4846    mpd_t *z = result;
4847    MPD_NEW_STATIC(v,0,0,0,0);
4848    MPD_NEW_STATIC(vtmp,0,0,0,0);
4849    MPD_NEW_STATIC(tmp,0,0,0,0);
4850    mpd_ssize_t klist[MPD_MAX_PREC_LOG2];
4851    mpd_ssize_t maxprec, shift, t;
4852    mpd_ssize_t a_digits, a_exp;
4853    mpd_uint_t dummy, x;
4854    int i;
4855
4856    assert(!mpd_isspecial(a) && !mpd_iszerocoeff(a));
4857
4858    /*
4859     * We are calculating ln(a) = ln(v * 10^t) = ln(v) + t*ln(10),
4860     * where 0.5 < v <= 5.
4861     */
4862    if (!mpd_qcopy(&v, a, status)) {
4863        mpd_seterror(result, MPD_Malloc_error, status);
4864        goto finish;
4865    }
4866
4867    /* Initial approximation: we have at least one non-zero digit */
4868    _mpd_get_msdigits(&dummy, &x, &v, 3);
4869    if (x < 10) x *= 10;
4870    if (x < 100) x *= 10;
4871    x -= 100;
4872
4873    /* a may equal z */
4874    a_digits = a->digits;
4875    a_exp = a->exp;
4876
4877    mpd_minalloc(z);
4878    mpd_clear_flags(z);
4879    z->data[0] = lnapprox[x];
4880    z->len = 1;
4881    z->exp = -3;
4882    mpd_setdigits(z);
4883
4884    if (x <= 400) {
4885        /* Reduce the input operand to 1.00 <= v <= 5.00. Let y = x + 100,
4886         * so 100 <= y <= 500. Since y contains the most significant digits
4887         * of v, y/100 <= v < (y+1)/100 and abs(z - log(v)) < 10**-2. */
4888        v.exp = -(a_digits - 1);
4889        t = a_exp + a_digits - 1;
4890    }
4891    else {
4892        /* Reduce the input operand to 0.500 < v <= 0.999. Let y = x + 100,
4893         * so 500 < y <= 999. Since y contains the most significant digits
4894         * of v, y/1000 <= v < (y+1)/1000 and abs(z - log(v)) < 10**-2. */
4895        v.exp = -a_digits;
4896        t = a_exp + a_digits;
4897        mpd_set_negative(z);
4898    }
4899
4900    mpd_maxcontext(&maxcontext);
4901    mpd_maxcontext(&varcontext);
4902    varcontext.round = MPD_ROUND_TRUNC;
4903
4904    maxprec = ctx->prec + 2;
4905    if (t == 0 && (x <= 15 || x >= 800)) {
4906        /* 0.900 <= v <= 1.15: Estimate the magnitude of the logarithm.
4907         * If ln(v) will underflow, skip the loop. Otherwise, adjust the
4908         * precision upwards in order to obtain a sufficient number of
4909         * significant digits.
4910         *
4911         *   Case v > 1:
4912         *      abs((v-1)/10) < abs((v-1)/v) < abs(ln(v)) < abs(v-1)
4913         *   Case v < 1:
4914         *      abs(v-1) < abs(ln(v)) < abs((v-1)/v) < abs((v-1)*10)
4915         */
4916        int cmp = _mpd_cmp(&v, &one);
4917
4918        /* Upper bound (assume v > 1): abs(v-1), unrounded */
4919        _mpd_qsub(&tmp, &v, &one, &maxcontext, &maxcontext.status);
4920        if (maxcontext.status & MPD_Errors) {
4921            mpd_seterror(result, MPD_Malloc_error, status);
4922            goto finish;
4923        }
4924
4925        if (cmp < 0) {
4926            /* v < 1: abs((v-1)*10) */
4927            tmp.exp += 1;
4928        }
4929        if (mpd_adjexp(&tmp) < mpd_etiny(ctx)) {
4930            /* The upper bound is less than etiny: Underflow to zero */
4931            _settriple(result, (cmp<0), 1, mpd_etiny(ctx)-1);
4932            goto finish;
4933        }
4934        /* Lower bound: abs((v-1)/10) or abs(v-1) */
4935        tmp.exp -= 1;
4936        if (mpd_adjexp(&tmp) < 0) {
4937            /* Absolute error of the loop: abs(z - log(v)) < 10**-p. If
4938             * p = ctx->prec+2-adjexp(lower), then the relative error of
4939             * the result is (using 10**adjexp(x) <= abs(x)):
4940             *
4941             *   abs(z - log(v)) / abs(log(v)) < 10**-p / abs(log(v))
4942             *                                 <= 10**(-ctx->prec-2)
4943             */
4944            maxprec = maxprec - mpd_adjexp(&tmp);
4945        }
4946    }
4947
4948    i = ln_schedule_prec(klist, maxprec, 2);
4949    for (; i >= 0; i--) {
4950        varcontext.prec = 2*klist[i]+3;
4951        z->flags ^= MPD_NEG;
4952        _mpd_qexp(&tmp, z, &varcontext, status);
4953        z->flags ^= MPD_NEG;
4954
4955        if (v.digits > varcontext.prec) {
4956            shift = v.digits - varcontext.prec;
4957            mpd_qshiftr(&vtmp, &v, shift, status);
4958            vtmp.exp += shift;
4959            mpd_qmul(&tmp, &vtmp, &tmp, &varcontext, status);
4960        }
4961        else {
4962            mpd_qmul(&tmp, &v, &tmp, &varcontext, status);
4963        }
4964
4965        mpd_qsub(&tmp, &tmp, &one, &maxcontext, status);
4966        mpd_qadd(z, z, &tmp, &maxcontext, status);
4967        if (mpd_isspecial(z)) {
4968            break;
4969        }
4970    }
4971
4972    /*
4973     * Case t == 0:
4974     *    t * log(10) == 0, the result does not change and the analysis
4975     *    above applies. If v < 0.900 or v > 1.15, the relative error is
4976     *    less than 10**(-ctx.prec-1).
4977     * Case t != 0:
4978     *      z := approx(log(v))
4979     *      y := approx(log(10))
4980     *      p := maxprec = ctx->prec + 2
4981     *   Absolute errors:
4982     *      1) abs(z - log(v)) < 10**-p
4983     *      2) abs(y - log(10)) < 10**-p
4984     *   The multiplication is exact, so:
4985     *      3) abs(t*y - t*log(10)) < t*10**-p
4986     *   The sum is exact, so:
4987     *      4) abs((z + t*y) - (log(v) + t*log(10))) < (abs(t) + 1) * 10**-p
4988     *   Bounds for log(v) and log(10):
4989     *      5) -7/10 < log(v) < 17/10
4990     *      6) 23/10 < log(10) < 24/10
4991     *   Using 4), 5), 6) and t != 0, the relative error is:
4992     *
4993     *      7) relerr < ((abs(t) + 1)*10**-p) / abs(log(v) + t*log(10))
4994     *                < 0.5 * 10**(-p + 1) = 0.5 * 10**(-ctx->prec-1)
4995     */
4996    mpd_qln10(&v, maxprec+1, status);
4997    mpd_qmul_ssize(&tmp, &v, t, &maxcontext, status);
4998    mpd_qadd(result, &tmp, z, &maxcontext, status);
4999
5000
5001finish:
5002    *status |= (MPD_Inexact|MPD_Rounded);
5003    mpd_del(&v);
5004    mpd_del(&vtmp);
5005    mpd_del(&tmp);
5006}
5007
5008/* ln(a) */
5009void
5010mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
5011        uint32_t *status)
5012{
5013    mpd_context_t workctx;
5014    mpd_ssize_t adjexp, t;
5015
5016    if (mpd_isspecial(a)) {
5017        if (mpd_qcheck_nan(result, a, ctx, status)) {
5018            return;
5019        }
5020        if (mpd_isnegative(a)) {
5021            mpd_seterror(result, MPD_Invalid_operation, status);
5022            return;
5023        }
5024        mpd_setspecial(result, MPD_POS, MPD_INF);
5025        return;
5026    }
5027    if (mpd_iszerocoeff(a)) {
5028        mpd_setspecial(result, MPD_NEG, MPD_INF);
5029        return;
5030    }
5031    if (mpd_isnegative(a)) {
5032        mpd_seterror(result, MPD_Invalid_operation, status);
5033        return;
5034    }
5035    if (_mpd_cmp(a, &one) == 0) {
5036        _settriple(result, MPD_POS, 0, 0);
5037        return;
5038    }
5039    /*
5040     * Check if the result will overflow (0 < x, x != 1):
5041     *   1) log10(x) < 0 iff adjexp(x) < 0
5042     *   2) 0 < x /\ x <= y ==> adjexp(x) <= adjexp(y)
5043     *   3) 0 < x /\ x != 1 ==> 2 * abs(log10(x)) < abs(log(x))
5044     *   4) adjexp(x) <= log10(x) < adjexp(x) + 1
5045     *
5046     * Case adjexp(x) >= 0:
5047     *   5) 2 * adjexp(x) < abs(log(x))
5048     *   Case adjexp(x) > 0:
5049     *     6) adjexp(2 * adjexp(x)) <= adjexp(abs(log(x)))
5050     *   Case adjexp(x) == 0:
5051     *     mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered)
5052     *
5053     * Case adjexp(x) < 0:
5054     *   7) 2 * (-adjexp(x) - 1) < abs(log(x))
5055     *   Case adjexp(x) < -1:
5056     *     8) adjexp(2 * (-adjexp(x) - 1)) <= adjexp(abs(log(x)))
5057     *   Case adjexp(x) == -1:
5058     *     mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered)
5059     */
5060    adjexp = mpd_adjexp(a);
5061    t = (adjexp < 0) ? -adjexp-1 : adjexp;
5062    t *= 2;
5063    if (mpd_exp_digits(t)-1 > ctx->emax) {
5064        *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded;
5065        mpd_setspecial(result, (adjexp<0), MPD_INF);
5066        return;
5067    }
5068
5069    workctx = *ctx;
5070    workctx.round = MPD_ROUND_HALF_EVEN;
5071
5072    if (ctx->allcr) {
5073        MPD_NEW_STATIC(t1, 0,0,0,0);
5074        MPD_NEW_STATIC(t2, 0,0,0,0);
5075        MPD_NEW_STATIC(ulp, 0,0,0,0);
5076        MPD_NEW_STATIC(aa, 0,0,0,0);
5077        mpd_ssize_t prec;
5078
5079        if (result == a) {
5080            if (!mpd_qcopy(&aa, a, status)) {
5081                mpd_seterror(result, MPD_Malloc_error, status);
5082                return;
5083            }
5084            a = &aa;
5085        }
5086
5087        workctx.clamp = 0;
5088        prec = ctx->prec + 3;
5089        while (1) {
5090            workctx.prec = prec;
5091            _mpd_qln(result, a, &workctx, status);
5092            _ssettriple(&ulp, MPD_POS, 1,
5093                        result->exp + result->digits-workctx.prec);
5094
5095            workctx.prec = ctx->prec;
5096            mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status);
5097            mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status);
5098            if (mpd_isspecial(result) || mpd_iszerocoeff(result) ||
5099                mpd_qcmp(&t1, &t2, status) == 0) {
5100                workctx.clamp = ctx->clamp;
5101                mpd_check_underflow(result, &workctx, status);
5102                mpd_qfinalize(result, &workctx, status);
5103                break;
5104            }
5105            prec += MPD_RDIGITS;
5106        }
5107        mpd_del(&t1);
5108        mpd_del(&t2);
5109        mpd_del(&ulp);
5110        mpd_del(&aa);
5111    }
5112    else {
5113        _mpd_qln(result, a, &workctx, status);
5114        mpd_check_underflow(result, &workctx, status);
5115        mpd_qfinalize(result, &workctx, status);
5116    }
5117}
5118
5119/*
5120 * Internal log10() function that does not check for specials, zero or one.
5121 * Case SKIP_FINALIZE:
5122 *   Relative error: abs(result - log10(a)) < 0.1 * 10**-prec * abs(log10(a))
5123 * Case DO_FINALIZE:
5124 *   Ulp error: abs(result - log10(a)) < ulp(log10(a))
5125 */
5126enum {SKIP_FINALIZE, DO_FINALIZE};
5127static void
5128_mpd_qlog10(int action, mpd_t *result, const mpd_t *a,
5129            const mpd_context_t *ctx, uint32_t *status)
5130{
5131    mpd_context_t workctx;
5132    MPD_NEW_STATIC(ln10,0,0,0,0);
5133
5134    mpd_maxcontext(&workctx);
5135    workctx.prec = ctx->prec + 3;
5136    /* relative error: 0.1 * 10**(-p-3). The specific underflow shortcut
5137     * in _mpd_qln() does not change the final result. */
5138    _mpd_qln(result, a, &workctx, status);
5139    /* relative error: 5 * 10**(-p-3) */
5140    mpd_qln10(&ln10, workctx.prec, status);
5141
5142    if (action == DO_FINALIZE) {
5143        workctx = *ctx;
5144        workctx.round = MPD_ROUND_HALF_EVEN;
5145    }
5146    /* SKIP_FINALIZE: relative error: 5 * 10**(-p-3) */
5147    _mpd_qdiv(NO_IDEAL_EXP, result, result, &ln10, &workctx, status);
5148
5149    mpd_del(&ln10);
5150}
5151
5152/* log10(a) */
5153void
5154mpd_qlog10(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
5155           uint32_t *status)
5156{
5157    mpd_context_t workctx;
5158    mpd_ssize_t adjexp, t;
5159
5160    workctx = *ctx;
5161    workctx.round = MPD_ROUND_HALF_EVEN;
5162
5163    if (mpd_isspecial(a)) {
5164        if (mpd_qcheck_nan(result, a, ctx, status)) {
5165            return;
5166        }
5167        if (mpd_isnegative(a)) {
5168            mpd_seterror(result, MPD_Invalid_operation, status);
5169            return;
5170        }
5171        mpd_setspecial(result, MPD_POS, MPD_INF);
5172        return;
5173    }
5174    if (mpd_iszerocoeff(a)) {
5175        mpd_setspecial(result, MPD_NEG, MPD_INF);
5176        return;
5177    }
5178    if (mpd_isnegative(a)) {
5179        mpd_seterror(result, MPD_Invalid_operation, status);
5180        return;
5181    }
5182    if (mpd_coeff_ispow10(a)) {
5183        uint8_t sign = 0;
5184        adjexp = mpd_adjexp(a);
5185        if (adjexp < 0) {
5186            sign = 1;
5187            adjexp = -adjexp;
5188        }
5189        _settriple(result, sign, adjexp, 0);
5190        mpd_qfinalize(result, &workctx, status);
5191        return;
5192    }
5193    /*
5194     * Check if the result will overflow (0 < x, x != 1):
5195     *   1) log10(x) < 0 iff adjexp(x) < 0
5196     *   2) 0 < x /\ x <= y ==> adjexp(x) <= adjexp(y)
5197     *   3) adjexp(x) <= log10(x) < adjexp(x) + 1
5198     *
5199     * Case adjexp(x) >= 0:
5200     *   4) adjexp(x) <= abs(log10(x))
5201     *   Case adjexp(x) > 0:
5202     *     5) adjexp(adjexp(x)) <= adjexp(abs(log10(x)))
5203     *   Case adjexp(x) == 0:
5204     *     mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered)
5205     *
5206     * Case adjexp(x) < 0:
5207     *   6) -adjexp(x) - 1 < abs(log10(x))
5208     *   Case adjexp(x) < -1:
5209     *     7) adjexp(-adjexp(x) - 1) <= adjexp(abs(log(x)))
5210     *   Case adjexp(x) == -1:
5211     *     mpd_exp_digits(t)-1 == 0 <= emax (the shortcut is not triggered)
5212     */
5213    adjexp = mpd_adjexp(a);
5214    t = (adjexp < 0) ? -adjexp-1 : adjexp;
5215    if (mpd_exp_digits(t)-1 > ctx->emax) {
5216        *status |= MPD_Overflow|MPD_Inexact|MPD_Rounded;
5217        mpd_setspecial(result, (adjexp<0), MPD_INF);
5218        return;
5219    }
5220
5221    if (ctx->allcr) {
5222        MPD_NEW_STATIC(t1, 0,0,0,0);
5223        MPD_NEW_STATIC(t2, 0,0,0,0);
5224        MPD_NEW_STATIC(ulp, 0,0,0,0);
5225        MPD_NEW_STATIC(aa, 0,0,0,0);
5226        mpd_ssize_t prec;
5227
5228        if (result == a) {
5229            if (!mpd_qcopy(&aa, a, status)) {
5230                mpd_seterror(result, MPD_Malloc_error, status);
5231                return;
5232            }
5233            a = &aa;
5234        }
5235
5236        workctx.clamp = 0;
5237        prec = ctx->prec + 3;
5238        while (1) {
5239            workctx.prec = prec;
5240            _mpd_qlog10(SKIP_FINALIZE, result, a, &workctx, status);
5241            _ssettriple(&ulp, MPD_POS, 1,
5242                        result->exp + result->digits-workctx.prec);
5243
5244            workctx.prec = ctx->prec;
5245            mpd_qadd(&t1, result, &ulp, &workctx, &workctx.status);
5246            mpd_qsub(&t2, result, &ulp, &workctx, &workctx.status);
5247            if (mpd_isspecial(result) || mpd_iszerocoeff(result) ||
5248                mpd_qcmp(&t1, &t2, status) == 0) {
5249                workctx.clamp = ctx->clamp;
5250                mpd_check_underflow(result, &workctx, status);
5251                mpd_qfinalize(result, &workctx, status);
5252                break;
5253            }
5254            prec += MPD_RDIGITS;
5255        }
5256        mpd_del(&t1);
5257        mpd_del(&t2);
5258        mpd_del(&ulp);
5259        mpd_del(&aa);
5260    }
5261    else {
5262        _mpd_qlog10(DO_FINALIZE, result, a, &workctx, status);
5263        mpd_check_underflow(result, &workctx, status);
5264    }
5265}
5266
5267/*
5268 * Maximum of the two operands. Attention: If one operand is a quiet NaN and the
5269 * other is numeric, the numeric operand is returned. This may not be what one
5270 * expects.
5271 */
5272void
5273mpd_qmax(mpd_t *result, const mpd_t *a, const mpd_t *b,
5274         const mpd_context_t *ctx, uint32_t *status)
5275{
5276    int c;
5277
5278    if (mpd_isqnan(a) && !mpd_isnan(b)) {
5279        mpd_qcopy(result, b, status);
5280    }
5281    else if (mpd_isqnan(b) && !mpd_isnan(a)) {
5282        mpd_qcopy(result, a, status);
5283    }
5284    else if (mpd_qcheck_nans(result, a, b, ctx, status)) {
5285        return;
5286    }
5287    else {
5288        c = _mpd_cmp(a, b);
5289        if (c == 0) {
5290            c = _mpd_cmp_numequal(a, b);
5291        }
5292
5293        if (c < 0) {
5294            mpd_qcopy(result, b, status);
5295        }
5296        else {
5297            mpd_qcopy(result, a, status);
5298        }
5299    }
5300
5301    mpd_qfinalize(result, ctx, status);
5302}
5303
5304/*
5305 * Maximum magnitude: Same as mpd_max(), but compares the operands with their
5306 * sign ignored.
5307 */
5308void
5309mpd_qmax_mag(mpd_t *result, const mpd_t *a, const mpd_t *b,
5310             const mpd_context_t *ctx, uint32_t *status)
5311{
5312    int c;
5313
5314    if (mpd_isqnan(a) && !mpd_isnan(b)) {
5315        mpd_qcopy(result, b, status);
5316    }
5317    else if (mpd_isqnan(b) && !mpd_isnan(a)) {
5318        mpd_qcopy(result, a, status);
5319    }
5320    else if (mpd_qcheck_nans(result, a, b, ctx, status)) {
5321        return;
5322    }
5323    else {
5324        c = _mpd_cmp_abs(a, b);
5325        if (c == 0) {
5326            c = _mpd_cmp_numequal(a, b);
5327        }
5328
5329        if (c < 0) {
5330            mpd_qcopy(result, b, status);
5331        }
5332        else {
5333            mpd_qcopy(result, a, status);
5334        }
5335    }
5336
5337    mpd_qfinalize(result, ctx, status);
5338}
5339
5340/*
5341 * Minimum of the two operands. Attention: If one operand is a quiet NaN and the
5342 * other is numeric, the numeric operand is returned. This may not be what one
5343 * expects.
5344 */
5345void
5346mpd_qmin(mpd_t *result, const mpd_t *a, const mpd_t *b,
5347         const mpd_context_t *ctx, uint32_t *status)
5348{
5349    int c;
5350
5351    if (mpd_isqnan(a) && !mpd_isnan(b)) {
5352        mpd_qcopy(result, b, status);
5353    }
5354    else if (mpd_isqnan(b) && !mpd_isnan(a)) {
5355        mpd_qcopy(result, a, status);
5356    }
5357    else if (mpd_qcheck_nans(result, a, b, ctx, status)) {
5358        return;
5359    }
5360    else {
5361        c = _mpd_cmp(a, b);
5362        if (c == 0) {
5363            c = _mpd_cmp_numequal(a, b);
5364        }
5365
5366        if (c < 0) {
5367            mpd_qcopy(result, a, status);
5368        }
5369        else {
5370            mpd_qcopy(result, b, status);
5371        }
5372    }
5373
5374    mpd_qfinalize(result, ctx, status);
5375}
5376
5377/*
5378 * Minimum magnitude: Same as mpd_min(), but compares the operands with their
5379 * sign ignored.
5380 */
5381void
5382mpd_qmin_mag(mpd_t *result, const mpd_t *a, const mpd_t *b,
5383             const mpd_context_t *ctx, uint32_t *status)
5384{
5385    int c;
5386
5387    if (mpd_isqnan(a) && !mpd_isnan(b)) {
5388        mpd_qcopy(result, b, status);
5389    }
5390    else if (mpd_isqnan(b) && !mpd_isnan(a)) {
5391        mpd_qcopy(result, a, status);
5392    }
5393    else if (mpd_qcheck_nans(result, a, b, ctx, status)) {
5394        return;
5395    }
5396    else {
5397        c = _mpd_cmp_abs(a, b);
5398        if (c == 0) {
5399            c = _mpd_cmp_numequal(a, b);
5400        }
5401
5402        if (c < 0) {
5403            mpd_qcopy(result, a, status);
5404        }
5405        else {
5406            mpd_qcopy(result, b, status);
5407        }
5408    }
5409
5410    mpd_qfinalize(result, ctx, status);
5411}
5412
5413/* Minimum space needed for the result array in _karatsuba_rec(). */
5414static inline mpd_size_t
5415_kmul_resultsize(mpd_size_t la, mpd_size_t lb)
5416{
5417    mpd_size_t n, m;
5418
5419    n = add_size_t(la, lb);
5420    n = add_size_t(n, 1);
5421
5422    m = (la+1)/2 + 1;
5423    m = mul_size_t(m, 3);
5424
5425    return (m > n) ? m : n;
5426}
5427
5428/* Work space needed in _karatsuba_rec(). lim >= 4 */
5429static inline mpd_size_t
5430_kmul_worksize(mpd_size_t n, mpd_size_t lim)
5431{
5432    mpd_size_t m;
5433
5434    if (n <= lim) {
5435        return 0;
5436    }
5437
5438    m = (n+1)/2 + 1;
5439
5440    return add_size_t(mul_size_t(m, 2), _kmul_worksize(m, lim));
5441}
5442
5443
5444#define MPD_KARATSUBA_BASECASE 16  /* must be >= 4 */
5445
5446/*
5447 * Add the product of a and b to c.
5448 * c must be _kmul_resultsize(la, lb) in size.
5449 * w is used as a work array and must be _kmul_worksize(a, lim) in size.
5450 * Roman E. Maeder, Storage Allocation for the Karatsuba Integer Multiplication
5451 * Algorithm. In "Design and implementation of symbolic computation systems",
5452 * Springer, 1993, ISBN 354057235X, 9783540572350.
5453 */
5454static void
5455_karatsuba_rec(mpd_uint_t *c, const mpd_uint_t *a, const mpd_uint_t *b,
5456               mpd_uint_t *w, mpd_size_t la, mpd_size_t lb)
5457{
5458    mpd_size_t m, lt;
5459
5460    assert(la >= lb && lb > 0);
5461    assert(la <= MPD_KARATSUBA_BASECASE || w != NULL);
5462
5463    if (la <= MPD_KARATSUBA_BASECASE) {
5464        _mpd_basemul(c, a, b, la, lb);
5465        return;
5466    }
5467
5468    m = (la+1)/2;  /* ceil(la/2) */
5469
5470    /* lb <= m < la */
5471    if (lb <= m) {
5472
5473        /* lb can now be larger than la-m */
5474        if (lb > la-m) {
5475            lt = lb + lb + 1;       /* space needed for result array */
5476            mpd_uint_zero(w, lt);   /* clear result array */
5477            _karatsuba_rec(w, b, a+m, w+lt, lb, la-m); /* b*ah */
5478        }
5479        else {
5480            lt = (la-m) + (la-m) + 1;  /* space needed for result array */
5481            mpd_uint_zero(w, lt);      /* clear result array */
5482            _karatsuba_rec(w, a+m, b, w+lt, la-m, lb); /* ah*b */
5483        }
5484        _mpd_baseaddto(c+m, w, (la-m)+lb);      /* add ah*b*B**m */
5485
5486        lt = m + m + 1;         /* space needed for the result array */
5487        mpd_uint_zero(w, lt);   /* clear result array */
5488        _karatsuba_rec(w, a, b, w+lt, m, lb);  /* al*b */
5489        _mpd_baseaddto(c, w, m+lb);    /* add al*b */
5490
5491        return;
5492    }
5493
5494    /* la >= lb > m */
5495    memcpy(w, a, m * sizeof *w);
5496    w[m] = 0;
5497    _mpd_baseaddto(w, a+m, la-m);
5498
5499    memcpy(w+(m+1), b, m * sizeof *w);
5500    w[m+1+m] = 0;
5501    _mpd_baseaddto(w+(m+1), b+m, lb-m);
5502
5503    _karatsuba_rec(c+m, w, w+(m+1), w+2*(m+1), m+1, m+1);
5504
5505    lt = (la-m) + (la-m) + 1;
5506    mpd_uint_zero(w, lt);
5507
5508    _karatsuba_rec(w, a+m, b+m, w+lt, la-m, lb-m);
5509
5510    _mpd_baseaddto(c+2*m, w, (la-m) + (lb-m));
5511    _mpd_basesubfrom(c+m, w, (la-m) + (lb-m));
5512
5513    lt = m + m + 1;
5514    mpd_uint_zero(w, lt);
5515
5516    _karatsuba_rec(w, a, b, w+lt, m, m);
5517    _mpd_baseaddto(c, w, m+m);
5518    _mpd_basesubfrom(c+m, w, m+m);
5519
5520    return;
5521}
5522
5523/*
5524 * Multiply u and v, using Karatsuba multiplication. Returns a pointer
5525 * to the result or NULL in case of failure (malloc error).
5526 * Conditions: ulen >= vlen, ulen >= 4
5527 */
5528static mpd_uint_t *
5529_mpd_kmul(const mpd_uint_t *u, const mpd_uint_t *v,
5530          mpd_size_t ulen, mpd_size_t vlen,
5531          mpd_size_t *rsize)
5532{
5533    mpd_uint_t *result = NULL, *w = NULL;
5534    mpd_size_t m;
5535
5536    assert(ulen >= 4);
5537    assert(ulen >= vlen);
5538
5539    *rsize = _kmul_resultsize(ulen, vlen);
5540    if ((result = mpd_calloc(*rsize, sizeof *result)) == NULL) {
5541        return NULL;
5542    }
5543
5544    m = _kmul_worksize(ulen, MPD_KARATSUBA_BASECASE);
5545    if (m && ((w = mpd_calloc(m, sizeof *w)) == NULL)) {
5546        mpd_free(result);
5547        return NULL;
5548    }
5549
5550    _karatsuba_rec(result, u, v, w, ulen, vlen);
5551
5552
5553    if (w) mpd_free(w);
5554    return result;
5555}
5556
5557
5558/*
5559 * Determine the minimum length for the number theoretic transform. Valid
5560 * transform lengths are 2**n or 3*2**n, where 2**n <= MPD_MAXTRANSFORM_2N.
5561 * The function finds the shortest length m such that rsize <= m.
5562 */
5563static inline mpd_size_t
5564_mpd_get_transform_len(mpd_size_t rsize)
5565{
5566    mpd_size_t log2rsize;
5567    mpd_size_t x, step;
5568
5569    assert(rsize >= 4);
5570    log2rsize = mpd_bsr(rsize);
5571
5572    if (rsize <= 1024) {
5573        /* 2**n is faster in this range. */
5574        x = ((mpd_size_t)1)<<log2rsize;
5575        return (rsize == x) ? x : x<<1;
5576    }
5577    else if (rsize <= MPD_MAXTRANSFORM_2N) {
5578        x = ((mpd_size_t)1)<<log2rsize;
5579        if (rsize == x) return x;
5580        step = x>>1;
5581        x += step;
5582        return (rsize <= x) ? x : x + step;
5583    }
5584    else if (rsize <= MPD_MAXTRANSFORM_2N+MPD_MAXTRANSFORM_2N/2) {
5585        return MPD_MAXTRANSFORM_2N+MPD_MAXTRANSFORM_2N/2;
5586    }
5587    else if (rsize <= 3*MPD_MAXTRANSFORM_2N) {
5588        return 3*MPD_MAXTRANSFORM_2N;
5589    }
5590    else {
5591        return MPD_SIZE_MAX;
5592    }
5593}
5594
5595#ifdef PPRO
5596#ifndef _MSC_VER
5597static inline unsigned short
5598_mpd_get_control87(void)
5599{
5600    unsigned short cw;
5601
5602    __asm__ __volatile__ ("fnstcw %0" : "=m" (cw));
5603    return cw;
5604}
5605
5606static inline void
5607_mpd_set_control87(unsigned short cw)
5608{
5609    __asm__ __volatile__ ("fldcw %0" : : "m" (cw));
5610}
5611#endif
5612
5613static unsigned int
5614mpd_set_fenv(void)
5615{
5616    unsigned int cw;
5617#ifdef _MSC_VER
5618    unsigned int flags =
5619        _EM_INVALID|_EM_DENORMAL|_EM_ZERODIVIDE|_EM_OVERFLOW|
5620        _EM_UNDERFLOW|_EM_INEXACT|_RC_CHOP|_PC_64;
5621    unsigned int mask = _MCW_EM|_MCW_RC|_MCW_PC;
5622    unsigned int dummy;
5623
5624    __control87_2(0, 0, &cw, NULL);
5625    __control87_2(flags, mask, &dummy, NULL);
5626#else
5627    cw = _mpd_get_control87();
5628    _mpd_set_control87(cw|0xF3F);
5629#endif
5630    return cw;
5631}
5632
5633static void
5634mpd_restore_fenv(unsigned int cw)
5635{
5636#ifdef _MSC_VER
5637    unsigned int mask = _MCW_EM|_MCW_RC|_MCW_PC;
5638    unsigned int dummy;
5639
5640    __control87_2(cw, mask, &dummy, NULL);
5641#else
5642    _mpd_set_control87((unsigned short)cw);
5643#endif
5644}
5645#endif /* PPRO */
5646
5647/*
5648 * Multiply u and v, using the fast number theoretic transform. Returns
5649 * a pointer to the result or NULL in case of failure (malloc error).
5650 */
5651static mpd_uint_t *
5652_mpd_fntmul(const mpd_uint_t *u, const mpd_uint_t *v,
5653            mpd_size_t ulen, mpd_size_t vlen,
5654            mpd_size_t *rsize)
5655{
5656    mpd_uint_t *c1 = NULL, *c2 = NULL, *c3 = NULL, *vtmp = NULL;
5657    mpd_size_t n;
5658
5659#ifdef PPRO
5660    unsigned int cw;
5661    cw = mpd_set_fenv();
5662#endif
5663
5664    *rsize = add_size_t(ulen, vlen);
5665    if ((n = _mpd_get_transform_len(*rsize)) == MPD_SIZE_MAX) {
5666        goto malloc_error;
5667    }
5668
5669    if ((c1 = mpd_calloc(n, sizeof *c1)) == NULL) {
5670        goto malloc_error;
5671    }
5672    if ((c2 = mpd_calloc(n, sizeof *c2)) == NULL) {
5673        goto malloc_error;
5674    }
5675    if ((c3 = mpd_calloc(n, sizeof *c3)) == NULL) {
5676        goto malloc_error;
5677    }
5678
5679    memcpy(c1, u, ulen * (sizeof *c1));
5680    memcpy(c2, u, ulen * (sizeof *c2));
5681    memcpy(c3, u, ulen * (sizeof *c3));
5682
5683    if (u == v) {
5684        if (!fnt_autoconvolute(c1, n, P1) ||
5685            !fnt_autoconvolute(c2, n, P2) ||
5686            !fnt_autoconvolute(c3, n, P3)) {
5687            goto malloc_error;
5688        }
5689    }
5690    else {
5691        if ((vtmp = mpd_calloc(n, sizeof *vtmp)) == NULL) {
5692            goto malloc_error;
5693        }
5694
5695        memcpy(vtmp, v, vlen * (sizeof *vtmp));
5696        if (!fnt_convolute(c1, vtmp, n, P1)) {
5697            mpd_free(vtmp);
5698            goto malloc_error;
5699        }
5700
5701        memcpy(vtmp, v, vlen * (sizeof *vtmp));
5702        mpd_uint_zero(vtmp+vlen, n-vlen);
5703        if (!fnt_convolute(c2, vtmp, n, P2)) {
5704            mpd_free(vtmp);
5705            goto malloc_error;
5706        }
5707
5708        memcpy(vtmp, v, vlen * (sizeof *vtmp));
5709        mpd_uint_zero(vtmp+vlen, n-vlen);
5710        if (!fnt_convolute(c3, vtmp, n, P3)) {
5711            mpd_free(vtmp);
5712            goto malloc_error;
5713        }
5714
5715        mpd_free(vtmp);
5716    }
5717
5718    crt3(c1, c2, c3, *rsize);
5719
5720out:
5721#ifdef PPRO
5722    mpd_restore_fenv(cw);
5723#endif
5724    if (c2) mpd_free(c2);
5725    if (c3) mpd_free(c3);
5726    return c1;
5727
5728malloc_error:
5729    if (c1) mpd_free(c1);
5730    c1 = NULL;
5731    goto out;
5732}
5733
5734
5735/*
5736 * Karatsuba multiplication with FNT/basemul as the base case.
5737 */
5738static int
5739_karatsuba_rec_fnt(mpd_uint_t *c, const mpd_uint_t *a, const mpd_uint_t *b,
5740                   mpd_uint_t *w, mpd_size_t la, mpd_size_t lb)
5741{
5742    mpd_size_t m, lt;
5743
5744    assert(la >= lb && lb > 0);
5745    assert(la <= 3*(MPD_MAXTRANSFORM_2N/2) || w != NULL);
5746
5747    if (la <= 3*(MPD_MAXTRANSFORM_2N/2)) {
5748
5749        if (lb <= 192) {
5750            _mpd_basemul(c, b, a, lb, la);
5751        }
5752        else {
5753            mpd_uint_t *result;
5754            mpd_size_t dummy;
5755
5756            if ((result = _mpd_fntmul(a, b, la, lb, &dummy)) == NULL) {
5757                return 0;
5758            }
5759            memcpy(c, result, (la+lb) * (sizeof *result));
5760            mpd_free(result);
5761        }
5762        return 1;
5763    }
5764
5765    m = (la+1)/2;  /* ceil(la/2) */
5766
5767    /* lb <= m < la */
5768    if (lb <= m) {
5769
5770        /* lb can now be larger than la-m */
5771        if (lb > la-m) {
5772            lt = lb + lb + 1;       /* space needed for result array */
5773            mpd_uint_zero(w, lt);   /* clear result array */
5774            if (!_karatsuba_rec_fnt(w, b, a+m, w+lt, lb, la-m)) { /* b*ah */
5775                return 0; /* GCOV_UNLIKELY */
5776            }
5777        }
5778        else {
5779            lt = (la-m) + (la-m) + 1;  /* space needed for result array */
5780            mpd_uint_zero(w, lt);      /* clear result array */
5781            if (!_karatsuba_rec_fnt(w, a+m, b, w+lt, la-m, lb)) { /* ah*b */
5782                return 0; /* GCOV_UNLIKELY */
5783            }
5784        }
5785        _mpd_baseaddto(c+m, w, (la-m)+lb); /* add ah*b*B**m */
5786
5787        lt = m + m + 1;         /* space needed for the result array */
5788        mpd_uint_zero(w, lt);   /* clear result array */
5789        if (!_karatsuba_rec_fnt(w, a, b, w+lt, m, lb)) {  /* al*b */
5790            return 0; /* GCOV_UNLIKELY */
5791        }
5792        _mpd_baseaddto(c, w, m+lb);       /* add al*b */
5793
5794        return 1;
5795    }
5796
5797    /* la >= lb > m */
5798    memcpy(w, a, m * sizeof *w);
5799    w[m] = 0;
5800    _mpd_baseaddto(w, a+m, la-m);
5801
5802    memcpy(w+(m+1), b, m * sizeof *w);
5803    w[m+1+m] = 0;
5804    _mpd_baseaddto(w+(m+1), b+m, lb-m);
5805
5806    if (!_karatsuba_rec_fnt(c+m, w, w+(m+1), w+2*(m+1), m+1, m+1)) {
5807        return 0; /* GCOV_UNLIKELY */
5808    }
5809
5810    lt = (la-m) + (la-m) + 1;
5811    mpd_uint_zero(w, lt);
5812
5813    if (!_karatsuba_rec_fnt(w, a+m, b+m, w+lt, la-m, lb-m)) {
5814        return 0; /* GCOV_UNLIKELY */
5815    }
5816
5817    _mpd_baseaddto(c+2*m, w, (la-m) + (lb-m));
5818    _mpd_basesubfrom(c+m, w, (la-m) + (lb-m));
5819
5820    lt = m + m + 1;
5821    mpd_uint_zero(w, lt);
5822
5823    if (!_karatsuba_rec_fnt(w, a, b, w+lt, m, m)) {
5824        return 0; /* GCOV_UNLIKELY */
5825    }
5826    _mpd_baseaddto(c, w, m+m);
5827    _mpd_basesubfrom(c+m, w, m+m);
5828
5829    return 1;
5830}
5831
5832/*
5833 * Multiply u and v, using Karatsuba multiplication with the FNT as the
5834 * base case. Returns a pointer to the result or NULL in case of failure
5835 * (malloc error). Conditions: ulen >= vlen, ulen >= 4.
5836 */
5837static mpd_uint_t *
5838_mpd_kmul_fnt(const mpd_uint_t *u, const mpd_uint_t *v,
5839              mpd_size_t ulen, mpd_size_t vlen,
5840              mpd_size_t *rsize)
5841{
5842    mpd_uint_t *result = NULL, *w = NULL;
5843    mpd_size_t m;
5844
5845    assert(ulen >= 4);
5846    assert(ulen >= vlen);
5847
5848    *rsize = _kmul_resultsize(ulen, vlen);
5849    if ((result = mpd_calloc(*rsize, sizeof *result)) == NULL) {
5850        return NULL;
5851    }
5852
5853    m = _kmul_worksize(ulen, 3*(MPD_MAXTRANSFORM_2N/2));
5854    if (m && ((w = mpd_calloc(m, sizeof *w)) == NULL)) {
5855        mpd_free(result); /* GCOV_UNLIKELY */
5856        return NULL; /* GCOV_UNLIKELY */
5857    }
5858
5859    if (!_karatsuba_rec_fnt(result, u, v, w, ulen, vlen)) {
5860        mpd_free(result);
5861        result = NULL;
5862    }
5863
5864
5865    if (w) mpd_free(w);
5866    return result;
5867}
5868
5869
5870/* Deal with the special cases of multiplying infinities. */
5871static void
5872_mpd_qmul_inf(mpd_t *result, const mpd_t *a, const mpd_t *b, uint32_t *status)
5873{
5874    if (mpd_isinfinite(a)) {
5875        if (mpd_iszero(b)) {
5876            mpd_seterror(result, MPD_Invalid_operation, status);
5877        }
5878        else {
5879            mpd_setspecial(result, mpd_sign(a)^mpd_sign(b), MPD_INF);
5880        }
5881        return;
5882    }
5883    assert(mpd_isinfinite(b));
5884    if (mpd_iszero(a)) {
5885        mpd_seterror(result, MPD_Invalid_operation, status);
5886    }
5887    else {
5888        mpd_setspecial(result, mpd_sign(a)^mpd_sign(b), MPD_INF);
5889    }
5890}
5891
5892/*
5893 * Internal function: Multiply a and b. _mpd_qmul deals with specials but
5894 * does NOT finalize the result. This is for use in mpd_fma().
5895 */
5896static inline void
5897_mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b,
5898          const mpd_context_t *ctx, uint32_t *status)
5899{
5900    const mpd_t *big = a, *small = b;
5901    mpd_uint_t *rdata = NULL;
5902    mpd_uint_t rbuf[MPD_MINALLOC_MAX];
5903    mpd_size_t rsize, i;
5904
5905
5906    if (mpd_isspecial(a) || mpd_isspecial(b)) {
5907        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
5908            return;
5909        }
5910        _mpd_qmul_inf(result, a, b, status);
5911        return;
5912    }
5913
5914    if (small->len > big->len) {
5915        _mpd_ptrswap(&big, &small);
5916    }
5917
5918    rsize = big->len + small->len;
5919
5920    if (big->len == 1) {
5921        _mpd_singlemul(result->data, big->data[0], small->data[0]);
5922        goto finish;
5923    }
5924    if (rsize <= (mpd_size_t)MPD_MINALLOC_MAX) {
5925        if (big->len == 2) {
5926            _mpd_mul_2_le2(rbuf, big->data, small->data, small->len);
5927        }
5928        else {
5929            mpd_uint_zero(rbuf, rsize);
5930            if (small->len == 1) {
5931                _mpd_shortmul(rbuf, big->data, big->len, small->data[0]);
5932            }
5933            else {
5934                _mpd_basemul(rbuf, small->data, big->data, small->len, big->len);
5935            }
5936        }
5937        if (!mpd_qresize(result, rsize, status)) {
5938            return;
5939        }
5940        for(i = 0; i < rsize; i++) {
5941            result->data[i] = rbuf[i];
5942        }
5943        goto finish;
5944    }
5945
5946
5947    if (small->len <= 256) {
5948        rdata = mpd_calloc(rsize, sizeof *rdata);
5949        if (rdata != NULL) {
5950            if (small->len == 1) {
5951                _mpd_shortmul(rdata, big->data, big->len, small->data[0]);
5952            }
5953            else {
5954                _mpd_basemul(rdata, small->data, big->data, small->len, big->len);
5955            }
5956        }
5957    }
5958    else if (rsize <= 1024) {
5959        rdata = _mpd_kmul(big->data, small->data, big->len, small->len, &rsize);
5960    }
5961    else if (rsize <= 3*MPD_MAXTRANSFORM_2N) {
5962        rdata = _mpd_fntmul(big->data, small->data, big->len, small->len, &rsize);
5963    }
5964    else {
5965        rdata = _mpd_kmul_fnt(big->data, small->data, big->len, small->len, &rsize);
5966    }
5967
5968    if (rdata == NULL) {
5969        mpd_seterror(result, MPD_Malloc_error, status);
5970        return;
5971    }
5972
5973    if (mpd_isdynamic_data(result)) {
5974        mpd_free(result->data);
5975    }
5976    result->data = rdata;
5977    result->alloc = rsize;
5978    mpd_set_dynamic_data(result);
5979
5980
5981finish:
5982    mpd_set_flags(result, mpd_sign(a)^mpd_sign(b));
5983    result->exp = big->exp + small->exp;
5984    result->len = _mpd_real_size(result->data, rsize);
5985    /* resize to smaller cannot fail */
5986    mpd_qresize(result, result->len, status);
5987    mpd_setdigits(result);
5988}
5989
5990/* Multiply a and b. */
5991void
5992mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b,
5993         const mpd_context_t *ctx, uint32_t *status)
5994{
5995    _mpd_qmul(result, a, b, ctx, status);
5996    mpd_qfinalize(result, ctx, status);
5997}
5998
5999/* Multiply a and b. Set NaN/Invalid_operation if the result is inexact. */
6000static void
6001_mpd_qmul_exact(mpd_t *result, const mpd_t *a, const mpd_t *b,
6002                const mpd_context_t *ctx, uint32_t *status)
6003{
6004    uint32_t workstatus = 0;
6005
6006    mpd_qmul(result, a, b, ctx, &workstatus);
6007    *status |= workstatus;
6008    if (workstatus & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
6009        mpd_seterror(result, MPD_Invalid_operation, status);
6010    }
6011}
6012
6013/* Multiply decimal and mpd_ssize_t. */
6014void
6015mpd_qmul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b,
6016               const mpd_context_t *ctx, uint32_t *status)
6017{
6018    mpd_context_t maxcontext;
6019    MPD_NEW_STATIC(bb,0,0,0,0);
6020
6021    mpd_maxcontext(&maxcontext);
6022    mpd_qsset_ssize(&bb, b, &maxcontext, status);
6023    mpd_qmul(result, a, &bb, ctx, status);
6024    mpd_del(&bb);
6025}
6026
6027/* Multiply decimal and mpd_uint_t. */
6028void
6029mpd_qmul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b,
6030              const mpd_context_t *ctx, uint32_t *status)
6031{
6032    mpd_context_t maxcontext;
6033    MPD_NEW_STATIC(bb,0,0,0,0);
6034
6035    mpd_maxcontext(&maxcontext);
6036    mpd_qsset_uint(&bb, b, &maxcontext, status);
6037    mpd_qmul(result, a, &bb, ctx, status);
6038    mpd_del(&bb);
6039}
6040
6041void
6042mpd_qmul_i32(mpd_t *result, const mpd_t *a, int32_t b,
6043             const mpd_context_t *ctx, uint32_t *status)
6044{
6045    mpd_qmul_ssize(result, a, b, ctx, status);
6046}
6047
6048void
6049mpd_qmul_u32(mpd_t *result, const mpd_t *a, uint32_t b,
6050             const mpd_context_t *ctx, uint32_t *status)
6051{
6052    mpd_qmul_uint(result, a, b, ctx, status);
6053}
6054
6055#ifdef CONFIG_64
6056void
6057mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b,
6058             const mpd_context_t *ctx, uint32_t *status)
6059{
6060    mpd_qmul_ssize(result, a, b, ctx, status);
6061}
6062
6063void
6064mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b,
6065             const mpd_context_t *ctx, uint32_t *status)
6066{
6067    mpd_qmul_uint(result, a, b, ctx, status);
6068}
6069#elif !defined(LEGACY_COMPILER)
6070/* Multiply decimal and int64_t. */
6071void
6072mpd_qmul_i64(mpd_t *result, const mpd_t *a, int64_t b,
6073             const mpd_context_t *ctx, uint32_t *status)
6074{
6075    mpd_context_t maxcontext;
6076    MPD_NEW_STATIC(bb,0,0,0,0);
6077
6078    mpd_maxcontext(&maxcontext);
6079    mpd_qset_i64(&bb, b, &maxcontext, status);
6080    mpd_qmul(result, a, &bb, ctx, status);
6081    mpd_del(&bb);
6082}
6083
6084/* Multiply decimal and uint64_t. */
6085void
6086mpd_qmul_u64(mpd_t *result, const mpd_t *a, uint64_t b,
6087             const mpd_context_t *ctx, uint32_t *status)
6088{
6089    mpd_context_t maxcontext;
6090    MPD_NEW_STATIC(bb,0,0,0,0);
6091
6092    mpd_maxcontext(&maxcontext);
6093    mpd_qset_u64(&bb, b, &maxcontext, status);
6094    mpd_qmul(result, a, &bb, ctx, status);
6095    mpd_del(&bb);
6096}
6097#endif
6098
6099/* Like the minus operator. */
6100void
6101mpd_qminus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
6102           uint32_t *status)
6103{
6104    if (mpd_isspecial(a)) {
6105        if (mpd_qcheck_nan(result, a, ctx, status)) {
6106            return;
6107        }
6108    }
6109
6110    if (mpd_iszero(a) && ctx->round != MPD_ROUND_FLOOR) {
6111        mpd_qcopy_abs(result, a, status);
6112    }
6113    else {
6114        mpd_qcopy_negate(result, a, status);
6115    }
6116
6117    mpd_qfinalize(result, ctx, status);
6118}
6119
6120/* Like the plus operator. */
6121void
6122mpd_qplus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
6123          uint32_t *status)
6124{
6125    if (mpd_isspecial(a)) {
6126        if (mpd_qcheck_nan(result, a, ctx, status)) {
6127            return;
6128        }
6129    }
6130
6131    if (mpd_iszero(a) && ctx->round != MPD_ROUND_FLOOR) {
6132        mpd_qcopy_abs(result, a, status);
6133    }
6134    else {
6135        mpd_qcopy(result, a, status);
6136    }
6137
6138    mpd_qfinalize(result, ctx, status);
6139}
6140
6141/* The largest representable number that is smaller than the operand. */
6142void
6143mpd_qnext_minus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
6144                uint32_t *status)
6145{
6146    mpd_context_t workctx;
6147    MPD_NEW_CONST(tiny,MPD_POS,mpd_etiny(ctx)-1,1,1,1,1);
6148
6149    if (mpd_isspecial(a)) {
6150        if (mpd_qcheck_nan(result, a, ctx, status)) {
6151            return;
6152        }
6153
6154        assert(mpd_isinfinite(a));
6155        if (mpd_isnegative(a)) {
6156            mpd_qcopy(result, a, status);
6157            return;
6158        }
6159        else {
6160            mpd_clear_flags(result);
6161            mpd_qmaxcoeff(result, ctx, status);
6162            if (mpd_isnan(result)) {
6163                return;
6164            }
6165            result->exp = mpd_etop(ctx);
6166            return;
6167        }
6168    }
6169
6170    mpd_workcontext(&workctx, ctx);
6171    workctx.round = MPD_ROUND_FLOOR;
6172
6173    if (!mpd_qcopy(result, a, status)) {
6174        return;
6175    }
6176
6177    mpd_qfinalize(result, &workctx, &workctx.status);
6178    if (workctx.status&(MPD_Inexact|MPD_Errors)) {
6179        *status |= (workctx.status&MPD_Errors);
6180        return;
6181    }
6182
6183    workctx.status = 0;
6184    mpd_qsub(result, a, &tiny, &workctx, &workctx.status);
6185    *status |= (workctx.status&MPD_Errors);
6186}
6187
6188/* The smallest representable number that is larger than the operand. */
6189void
6190mpd_qnext_plus(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
6191               uint32_t *status)
6192{
6193    mpd_context_t workctx;
6194    MPD_NEW_CONST(tiny,MPD_POS,mpd_etiny(ctx)-1,1,1,1,1);
6195
6196    if (mpd_isspecial(a)) {
6197        if (mpd_qcheck_nan(result, a, ctx, status)) {
6198            return;
6199        }
6200
6201        assert(mpd_isinfinite(a));
6202        if (mpd_ispositive(a)) {
6203            mpd_qcopy(result, a, status);
6204        }
6205        else {
6206            mpd_clear_flags(result);
6207            mpd_qmaxcoeff(result, ctx, status);
6208            if (mpd_isnan(result)) {
6209                return;
6210            }
6211            mpd_set_flags(result, MPD_NEG);
6212            result->exp = mpd_etop(ctx);
6213        }
6214        return;
6215    }
6216
6217    mpd_workcontext(&workctx, ctx);
6218    workctx.round = MPD_ROUND_CEILING;
6219
6220    if (!mpd_qcopy(result, a, status)) {
6221        return;
6222    }
6223
6224    mpd_qfinalize(result, &workctx, &workctx.status);
6225    if (workctx.status & (MPD_Inexact|MPD_Errors)) {
6226        *status |= (workctx.status&MPD_Errors);
6227        return;
6228    }
6229
6230    workctx.status = 0;
6231    mpd_qadd(result, a, &tiny, &workctx, &workctx.status);
6232    *status |= (workctx.status&MPD_Errors);
6233}
6234
6235/*
6236 * The number closest to the first operand that is in the direction towards
6237 * the second operand.
6238 */
6239void
6240mpd_qnext_toward(mpd_t *result, const mpd_t *a, const mpd_t *b,
6241                 const mpd_context_t *ctx, uint32_t *status)
6242{
6243    int c;
6244
6245    if (mpd_qcheck_nans(result, a, b, ctx, status)) {
6246        return;
6247    }
6248
6249    c = _mpd_cmp(a, b);
6250    if (c == 0) {
6251        mpd_qcopy_sign(result, a, b, status);
6252        return;
6253    }
6254
6255    if (c < 0) {
6256        mpd_qnext_plus(result, a, ctx, status);
6257    }
6258    else {
6259        mpd_qnext_minus(result, a, ctx, status);
6260    }
6261
6262    if (mpd_isinfinite(result)) {
6263        *status |= (MPD_Overflow|MPD_Rounded|MPD_Inexact);
6264    }
6265    else if (mpd_adjexp(result) < ctx->emin) {
6266        *status |= (MPD_Underflow|MPD_Subnormal|MPD_Rounded|MPD_Inexact);
6267        if (mpd_iszero(result)) {
6268            *status |= MPD_Clamped;
6269        }
6270    }
6271}
6272
6273/*
6274 * Internal function: Integer power with mpd_uint_t exponent. The function
6275 * can fail with MPD_Malloc_error.
6276 *
6277 * The error is equal to the error incurred in k-1 multiplications. Assuming
6278 * the upper bound for the relative error in each operation:
6279 *
6280 *   abs(err) = 5 * 10**-prec
6281 *   result = x**k * (1 + err)**(k-1)
6282 */
6283static inline void
6284_mpd_qpow_uint(mpd_t *result, const mpd_t *base, mpd_uint_t exp,
6285               uint8_t resultsign, const mpd_context_t *ctx, uint32_t *status)
6286{
6287    uint32_t workstatus = 0;
6288    mpd_uint_t n;
6289
6290    if (exp == 0) {
6291        _settriple(result, resultsign, 1, 0); /* GCOV_NOT_REACHED */
6292        return; /* GCOV_NOT_REACHED */
6293    }
6294
6295    if (!mpd_qcopy(result, base, status)) {
6296        return;
6297    }
6298
6299    n = mpd_bits[mpd_bsr(exp)];
6300    while (n >>= 1) {
6301        mpd_qmul(result, result, result, ctx, &workstatus);
6302        if (exp & n) {
6303            mpd_qmul(result, result, base, ctx, &workstatus);
6304        }
6305        if (mpd_isspecial(result) ||
6306            (mpd_iszerocoeff(result) && (workstatus & MPD_Clamped))) {
6307            break;
6308        }
6309    }
6310
6311    *status |= workstatus;
6312    mpd_set_sign(result, resultsign);
6313}
6314
6315/*
6316 * Internal function: Integer power with mpd_t exponent, tbase and texp
6317 * are modified!! Function can fail with MPD_Malloc_error.
6318 *
6319 * The error is equal to the error incurred in k multiplications. Assuming
6320 * the upper bound for the relative error in each operation:
6321 *
6322 *   abs(err) = 5 * 10**-prec
6323 *   result = x**k * (1 + err)**k
6324 */
6325static inline void
6326_mpd_qpow_mpd(mpd_t *result, mpd_t *tbase, mpd_t *texp, uint8_t resultsign,
6327              const mpd_context_t *ctx, uint32_t *status)
6328{
6329    uint32_t workstatus = 0;
6330    mpd_context_t maxctx;
6331    MPD_NEW_CONST(two,0,0,1,1,1,2);
6332
6333
6334    mpd_maxcontext(&maxctx);
6335
6336    /* resize to smaller cannot fail */
6337    mpd_qcopy(result, &one, status);
6338
6339    while (!mpd_iszero(texp)) {
6340        if (mpd_isodd(texp)) {
6341            mpd_qmul(result, result, tbase, ctx, &workstatus);
6342            *status |= workstatus;
6343            if (mpd_isspecial(result) ||
6344                (mpd_iszerocoeff(result) && (workstatus & MPD_Clamped))) {
6345                break;
6346            }
6347        }
6348        mpd_qmul(tbase, tbase, tbase, ctx, &workstatus);
6349        mpd_qdivint(texp, texp, &two, &maxctx, &workstatus);
6350        if (mpd_isnan(tbase) || mpd_isnan(texp)) {
6351            mpd_seterror(result, workstatus&MPD_Errors, status);
6352            return;
6353        }
6354    }
6355    mpd_set_sign(result, resultsign);
6356}
6357
6358/*
6359 * The power function for integer exponents. Relative error _before_ the
6360 * final rounding to prec:
6361 *   abs(result - base**exp) < 0.1 * 10**-prec * abs(base**exp)
6362 */
6363static void
6364_mpd_qpow_int(mpd_t *result, const mpd_t *base, const mpd_t *exp,
6365              uint8_t resultsign,
6366              const mpd_context_t *ctx, uint32_t *status)
6367{
6368    mpd_context_t workctx;
6369    MPD_NEW_STATIC(tbase,0,0,0,0);
6370    MPD_NEW_STATIC(texp,0,0,0,0);
6371    mpd_uint_t n;
6372
6373
6374    mpd_workcontext(&workctx, ctx);
6375    workctx.prec += (exp->digits + exp->exp + 2);
6376    workctx.round = MPD_ROUND_HALF_EVEN;
6377    workctx.clamp = 0;
6378    if (mpd_isnegative(exp)) {
6379        uint32_t workstatus = 0;
6380        workctx.prec += 1;
6381        mpd_qdiv(&tbase, &one, base, &workctx, &workstatus);
6382        *status |= workstatus;
6383        if (workstatus&MPD_Errors) {
6384            mpd_setspecial(result, MPD_POS, MPD_NAN);
6385            goto finish;
6386        }
6387    }
6388    else {
6389        if (!mpd_qcopy(&tbase, base, status)) {
6390            mpd_setspecial(result, MPD_POS, MPD_NAN);
6391            goto finish;
6392        }
6393    }
6394
6395    n = mpd_qabs_uint(exp, &workctx.status);
6396    if (workctx.status&MPD_Invalid_operation) {
6397        if (!mpd_qcopy(&texp, exp, status)) {
6398            mpd_setspecial(result, MPD_POS, MPD_NAN); /* GCOV_UNLIKELY */
6399            goto finish; /* GCOV_UNLIKELY */
6400        }
6401        _mpd_qpow_mpd(result, &tbase, &texp, resultsign, &workctx, status);
6402    }
6403    else {
6404        _mpd_qpow_uint(result, &tbase, n, resultsign, &workctx, status);
6405    }
6406
6407    if (mpd_isinfinite(result)) {
6408        /* for ROUND_DOWN, ROUND_FLOOR, etc. */
6409        _settriple(result, resultsign, 1, MPD_EXP_INF);
6410    }
6411
6412finish:
6413    mpd_del(&tbase);
6414    mpd_del(&texp);
6415    mpd_qfinalize(result, ctx, status);
6416}
6417
6418/*
6419 * If the exponent is infinite and base equals one, the result is one
6420 * with a coefficient of length prec. Otherwise, result is undefined.
6421 * Return the value of the comparison against one.
6422 */
6423static int
6424_qcheck_pow_one_inf(mpd_t *result, const mpd_t *base, uint8_t resultsign,
6425                    const mpd_context_t *ctx, uint32_t *status)
6426{
6427    mpd_ssize_t shift;
6428    int cmp;
6429
6430    if ((cmp = _mpd_cmp(base, &one)) == 0) {
6431        shift = ctx->prec-1;
6432        mpd_qshiftl(result, &one, shift, status);
6433        result->exp = -shift;
6434        mpd_set_flags(result, resultsign);
6435        *status |= (MPD_Inexact|MPD_Rounded);
6436    }
6437
6438    return cmp;
6439}
6440
6441/*
6442 * If abs(base) equals one, calculate the correct power of one result.
6443 * Otherwise, result is undefined. Return the value of the comparison
6444 * against 1.
6445 *
6446 * This is an internal function that does not check for specials.
6447 */
6448static int
6449_qcheck_pow_one(mpd_t *result, const mpd_t *base, const mpd_t *exp,
6450                uint8_t resultsign,
6451                const mpd_context_t *ctx, uint32_t *status)
6452{
6453    uint32_t workstatus = 0;
6454    mpd_ssize_t shift;
6455    int cmp;
6456
6457    if ((cmp = _mpd_cmp_abs(base, &one)) == 0) {
6458        if (_mpd_isint(exp)) {
6459            if (mpd_isnegative(exp)) {
6460                _settriple(result, resultsign, 1, 0);
6461                return 0;
6462            }
6463            /* 1.000**3 = 1.000000000 */
6464            mpd_qmul_ssize(result, exp, -base->exp, ctx, &workstatus);
6465            if (workstatus&MPD_Errors) {
6466                *status |= (workstatus&MPD_Errors);
6467                return 0;
6468            }
6469            /* digits-1 after exponentiation */
6470            shift = mpd_qget_ssize(result, &workstatus);
6471            /* shift is MPD_SSIZE_MAX if result is too large */
6472            if (shift > ctx->prec-1) {
6473                shift = ctx->prec-1;
6474                *status |= MPD_Rounded;
6475            }
6476        }
6477        else if (mpd_ispositive(base)) {
6478            shift = ctx->prec-1;
6479            *status |= (MPD_Inexact|MPD_Rounded);
6480        }
6481        else {
6482            return -2; /* GCOV_NOT_REACHED */
6483        }
6484        if (!mpd_qshiftl(result, &one, shift, status)) {
6485            return 0;
6486        }
6487        result->exp = -shift;
6488        mpd_set_flags(result, resultsign);
6489    }
6490
6491    return cmp;
6492}
6493
6494/*
6495 * Detect certain over/underflow of x**y.
6496 * ACL2 proof: pow-bounds.lisp.
6497 *
6498 *   Symbols:
6499 *
6500 *     e: EXP_INF or EXP_CLAMP
6501 *     x: base
6502 *     y: exponent
6503 *
6504 *     omega(e) = log10(abs(e))
6505 *     zeta(x)  = log10(abs(log10(x)))
6506 *     theta(y) = log10(abs(y))
6507 *
6508 *   Upper and lower bounds:
6509 *
6510 *     ub_omega(e) = ceil(log10(abs(e)))
6511 *     lb_theta(y) = floor(log10(abs(y)))
6512 *
6513 *                  | floor(log10(floor(abs(log10(x))))) if x < 1/10 or x >= 10
6514 *     lb_zeta(x) = | floor(log10(abs(x-1)/10)) if 1/10 <= x < 1
6515 *                  | floor(log10(abs((x-1)/100))) if 1 < x < 10
6516 *
6517 *   ub_omega(e) and lb_theta(y) are obviously upper and lower bounds
6518 *   for omega(e) and theta(y).
6519 *
6520 *   lb_zeta is a lower bound for zeta(x):
6521 *
6522 *     x < 1/10 or x >= 10:
6523 *
6524 *       abs(log10(x)) >= 1, so the outer log10 is well defined. Since log10
6525 *       is strictly increasing, the end result is a lower bound.
6526 *
6527 *     1/10 <= x < 1:
6528 *
6529 *       We use: log10(x) <= (x-1)/log(10)
6530 *               abs(log10(x)) >= abs(x-1)/log(10)
6531 *               abs(log10(x)) >= abs(x-1)/10
6532 *
6533 *     1 < x < 10:
6534 *
6535 *       We use: (x-1)/(x*log(10)) < log10(x)
6536 *               abs((x-1)/100) < abs(log10(x))
6537 *
6538 *       XXX: abs((x-1)/10) would work, need ACL2 proof.
6539 *
6540 *
6541 *   Let (0 < x < 1 and y < 0) or (x > 1 and y > 0).                  (H1)
6542 *   Let ub_omega(exp_inf) < lb_zeta(x) + lb_theta(y)                 (H2)
6543 *
6544 *   Then:
6545 *       log10(abs(exp_inf)) < log10(abs(log10(x))) + log10(abs(y)).   (1)
6546 *                   exp_inf < log10(x) * y                            (2)
6547 *               10**exp_inf < x**y                                    (3)
6548 *
6549 *   Let (0 < x < 1 and y > 0) or (x > 1 and y < 0).                  (H3)
6550 *   Let ub_omega(exp_clamp) < lb_zeta(x) + lb_theta(y)               (H4)
6551 *
6552 *   Then:
6553 *     log10(abs(exp_clamp)) < log10(abs(log10(x))) + log10(abs(y)).   (4)
6554 *              log10(x) * y < exp_clamp                               (5)
6555 *                      x**y < 10**exp_clamp                           (6)
6556 *
6557 */
6558static mpd_ssize_t
6559_lower_bound_zeta(const mpd_t *x, uint32_t *status)
6560{
6561    mpd_context_t maxctx;
6562    MPD_NEW_STATIC(scratch,0,0,0,0);
6563    mpd_ssize_t t, u;
6564
6565    t = mpd_adjexp(x);
6566    if (t > 0) {
6567        /* x >= 10 -> floor(log10(floor(abs(log10(x))))) */
6568        return mpd_exp_digits(t) - 1;
6569    }
6570    else if (t < -1) {
6571        /* x < 1/10 -> floor(log10(floor(abs(log10(x))))) */
6572        return mpd_exp_digits(t+1) - 1;
6573    }
6574    else {
6575        mpd_maxcontext(&maxctx);
6576        mpd_qsub(&scratch, x, &one, &maxctx, status);
6577        if (mpd_isspecial(&scratch)) {
6578            mpd_del(&scratch);
6579            return MPD_SSIZE_MAX;
6580        }
6581        u = mpd_adjexp(&scratch);
6582        mpd_del(&scratch);
6583
6584        /* t == -1, 1/10 <= x < 1 -> floor(log10(abs(x-1)/10))
6585         * t == 0,  1 < x < 10    -> floor(log10(abs(x-1)/100)) */
6586        return (t == 0) ? u-2 : u-1;
6587    }
6588}
6589
6590/*
6591 * Detect cases of certain overflow/underflow in the power function.
6592 * Assumptions: x != 1, y != 0. The proof above is for positive x.
6593 * If x is negative and y is an odd integer, x**y == -(abs(x)**y),
6594 * so the analysis does not change.
6595 */
6596static int
6597_qcheck_pow_bounds(mpd_t *result, const mpd_t *x, const mpd_t *y,
6598                   uint8_t resultsign,
6599                   const mpd_context_t *ctx, uint32_t *status)
6600{
6601    MPD_NEW_SHARED(abs_x, x);
6602    mpd_ssize_t ub_omega, lb_zeta, lb_theta;
6603    uint8_t sign;
6604
6605    mpd_set_positive(&abs_x);
6606
6607    lb_theta = mpd_adjexp(y);
6608    lb_zeta = _lower_bound_zeta(&abs_x, status);
6609    if (lb_zeta == MPD_SSIZE_MAX) {
6610        mpd_seterror(result, MPD_Malloc_error, status);
6611        return 1;
6612    }
6613
6614    sign = (mpd_adjexp(&abs_x) < 0) ^ mpd_sign(y);
6615    if (sign == 0) {
6616        /* (0 < |x| < 1 and y < 0) or (|x| > 1 and y > 0) */
6617        ub_omega = mpd_exp_digits(ctx->emax);
6618        if (ub_omega < lb_zeta + lb_theta) {
6619            _settriple(result, resultsign, 1, MPD_EXP_INF);
6620            mpd_qfinalize(result, ctx, status);
6621            return 1;
6622        }
6623    }
6624    else {
6625        /* (0 < |x| < 1 and y > 0) or (|x| > 1 and y < 0). */
6626        ub_omega = mpd_exp_digits(mpd_etiny(ctx));
6627        if (ub_omega < lb_zeta + lb_theta) {
6628            _settriple(result, resultsign, 1, mpd_etiny(ctx)-1);
6629            mpd_qfinalize(result, ctx, status);
6630            return 1;
6631        }
6632    }
6633
6634    return 0;
6635}
6636
6637/*
6638 * TODO: Implement algorithm for computing exact powers from decimal.py.
6639 * In order to prevent infinite loops, this has to be called before
6640 * using Ziv's strategy for correct rounding.
6641 */
6642/*
6643static int
6644_mpd_qpow_exact(mpd_t *result, const mpd_t *base, const mpd_t *exp,
6645                const mpd_context_t *ctx, uint32_t *status)
6646{
6647    return 0;
6648}
6649*/
6650
6651/*
6652 * The power function for real exponents.
6653 *   Relative error: abs(result - e**y) < e**y * 1/5 * 10**(-prec - 1)
6654 */
6655static void
6656_mpd_qpow_real(mpd_t *result, const mpd_t *base, const mpd_t *exp,
6657               const mpd_context_t *ctx, uint32_t *status)
6658{
6659    mpd_context_t workctx;
6660    MPD_NEW_STATIC(texp,0,0,0,0);
6661
6662    if (!mpd_qcopy(&texp, exp, status)) {
6663        mpd_seterror(result, MPD_Malloc_error, status);
6664        return;
6665    }
6666
6667    mpd_maxcontext(&workctx);
6668    workctx.prec = (base->digits > ctx->prec) ? base->digits : ctx->prec;
6669    workctx.prec += (4 + MPD_EXPDIGITS);
6670    workctx.round = MPD_ROUND_HALF_EVEN;
6671    workctx.allcr = ctx->allcr;
6672
6673    /*
6674     * extra := MPD_EXPDIGITS = MPD_EXP_MAX_T
6675     * wp := prec + 4 + extra
6676     * abs(err) < 5 * 10**-wp
6677     * y := log(base) * exp
6678     * Calculate:
6679     *   1)   e**(y * (1 + err)**2) * (1 + err)
6680     *      = e**y * e**(y * (2*err + err**2)) * (1 + err)
6681     *        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6682     * Relative error of the underlined term:
6683     *   2) abs(e**(y * (2*err + err**2)) - 1)
6684     * Case abs(y) >= 10**extra:
6685     *   3) adjexp(y)+1 > log10(abs(y)) >= extra
6686     *   This triggers the Overflow/Underflow shortcut in _mpd_qexp(),
6687     *   so no further analysis is necessary.
6688     * Case abs(y) < 10**extra:
6689     *   4) abs(y * (2*err + err**2)) < 1/5 * 10**(-prec - 2)
6690     *   Use (see _mpd_qexp):
6691     *     5) abs(x) <= 9/10 * 10**-p ==> abs(e**x - 1) < 10**-p
6692     *   With 2), 4) and 5):
6693     *     6) abs(e**(y * (2*err + err**2)) - 1) < 10**(-prec - 2)
6694     *   The complete relative error of 1) is:
6695     *     7) abs(result - e**y) < e**y * 1/5 * 10**(-prec - 1)
6696     */
6697    mpd_qln(result, base, &workctx, &workctx.status);
6698    mpd_qmul(result, result, &texp, &workctx, &workctx.status);
6699    mpd_qexp(result, result, &workctx, status);
6700
6701    mpd_del(&texp);
6702    *status |= (workctx.status&MPD_Errors);
6703    *status |= (MPD_Inexact|MPD_Rounded);
6704}
6705
6706/* The power function: base**exp */
6707void
6708mpd_qpow(mpd_t *result, const mpd_t *base, const mpd_t *exp,
6709         const mpd_context_t *ctx, uint32_t *status)
6710{
6711    uint8_t resultsign = 0;
6712    int intexp = 0;
6713    int cmp;
6714
6715    if (mpd_isspecial(base) || mpd_isspecial(exp)) {
6716        if (mpd_qcheck_nans(result, base, exp, ctx, status)) {
6717            return;
6718        }
6719    }
6720    if (mpd_isinteger(exp)) {
6721        intexp = 1;
6722        resultsign = mpd_isnegative(base) && mpd_isodd(exp);
6723    }
6724
6725    if (mpd_iszero(base)) {
6726        if (mpd_iszero(exp)) {
6727            mpd_seterror(result, MPD_Invalid_operation, status);
6728        }
6729        else if (mpd_isnegative(exp)) {
6730            mpd_setspecial(result, resultsign, MPD_INF);
6731        }
6732        else {
6733            _settriple(result, resultsign, 0, 0);
6734        }
6735        return;
6736    }
6737    if (mpd_isnegative(base)) {
6738        if (!intexp || mpd_isinfinite(exp)) {
6739            mpd_seterror(result, MPD_Invalid_operation, status);
6740            return;
6741        }
6742    }
6743    if (mpd_isinfinite(exp)) {
6744        /* power of one */
6745        cmp = _qcheck_pow_one_inf(result, base, resultsign, ctx, status);
6746        if (cmp == 0) {
6747            return;
6748        }
6749        else {
6750            cmp *= mpd_arith_sign(exp);
6751            if (cmp < 0) {
6752                _settriple(result, resultsign, 0, 0);
6753            }
6754            else {
6755                mpd_setspecial(result, resultsign, MPD_INF);
6756            }
6757        }
6758        return;
6759    }
6760    if (mpd_isinfinite(base)) {
6761        if (mpd_iszero(exp)) {
6762            _settriple(result, resultsign, 1, 0);
6763        }
6764        else if (mpd_isnegative(exp)) {
6765            _settriple(result, resultsign, 0, 0);
6766        }
6767        else {
6768            mpd_setspecial(result, resultsign, MPD_INF);
6769        }
6770        return;
6771    }
6772    if (mpd_iszero(exp)) {
6773        _settriple(result, resultsign, 1, 0);
6774        return;
6775    }
6776    if (_qcheck_pow_one(result, base, exp, resultsign, ctx, status) == 0) {
6777        return;
6778    }
6779    if (_qcheck_pow_bounds(result, base, exp, resultsign, ctx, status)) {
6780        return;
6781    }
6782
6783    if (intexp) {
6784        _mpd_qpow_int(result, base, exp, resultsign, ctx, status);
6785    }
6786    else {
6787        _mpd_qpow_real(result, base, exp, ctx, status);
6788        if (!mpd_isspecial(result) && _mpd_cmp(result, &one) == 0) {
6789            mpd_ssize_t shift = ctx->prec-1;
6790            mpd_qshiftl(result, &one, shift, status);
6791            result->exp = -shift;
6792        }
6793        if (mpd_isinfinite(result)) {
6794            /* for ROUND_DOWN, ROUND_FLOOR, etc. */
6795            _settriple(result, MPD_POS, 1, MPD_EXP_INF);
6796        }
6797        mpd_qfinalize(result, ctx, status);
6798    }
6799}
6800
6801/*
6802 * Internal function: Integer powmod with mpd_uint_t exponent, base is modified!
6803 * Function can fail with MPD_Malloc_error.
6804 */
6805static inline void
6806_mpd_qpowmod_uint(mpd_t *result, mpd_t *base, mpd_uint_t exp,
6807                  const mpd_t *mod, uint32_t *status)
6808{
6809    mpd_context_t maxcontext;
6810
6811    mpd_maxcontext(&maxcontext);
6812
6813    /* resize to smaller cannot fail */
6814    mpd_qcopy(result, &one, status);
6815
6816    while (exp > 0) {
6817        if (exp & 1) {
6818            _mpd_qmul_exact(result, result, base, &maxcontext, status);
6819            mpd_qrem(result, result, mod, &maxcontext, status);
6820        }
6821        _mpd_qmul_exact(base, base, base, &maxcontext, status);
6822        mpd_qrem(base, base, mod, &maxcontext, status);
6823        exp >>= 1;
6824    }
6825}
6826
6827/* The powmod function: (base**exp) % mod */
6828void
6829mpd_qpowmod(mpd_t *result, const mpd_t *base, const mpd_t *exp,
6830            const mpd_t *mod,
6831            const mpd_context_t *ctx, uint32_t *status)
6832{
6833    mpd_context_t maxcontext;
6834    MPD_NEW_STATIC(tbase,0,0,0,0);
6835    MPD_NEW_STATIC(texp,0,0,0,0);
6836    MPD_NEW_STATIC(tmod,0,0,0,0);
6837    MPD_NEW_STATIC(tmp,0,0,0,0);
6838    MPD_NEW_CONST(two,0,0,1,1,1,2);
6839    mpd_ssize_t tbase_exp, texp_exp;
6840    mpd_ssize_t i;
6841    mpd_t t;
6842    mpd_uint_t r;
6843    uint8_t sign;
6844
6845
6846    if (mpd_isspecial(base) || mpd_isspecial(exp) || mpd_isspecial(mod)) {
6847        if (mpd_qcheck_3nans(result, base, exp, mod, ctx, status)) {
6848            return;
6849        }
6850        mpd_seterror(result, MPD_Invalid_operation, status);
6851        return;
6852    }
6853
6854
6855    if (!_mpd_isint(base) || !_mpd_isint(exp) || !_mpd_isint(mod)) {
6856        mpd_seterror(result, MPD_Invalid_operation, status);
6857        return;
6858    }
6859    if (mpd_iszerocoeff(mod)) {
6860        mpd_seterror(result, MPD_Invalid_operation, status);
6861        return;
6862    }
6863    if (mod->digits+mod->exp > ctx->prec) {
6864        mpd_seterror(result, MPD_Invalid_operation, status);
6865        return;
6866    }
6867
6868    sign = (mpd_isnegative(base)) && (mpd_isodd(exp));
6869    if (mpd_iszerocoeff(exp)) {
6870        if (mpd_iszerocoeff(base)) {
6871            mpd_seterror(result, MPD_Invalid_operation, status);
6872            return;
6873        }
6874        r = (_mpd_cmp_abs(mod, &one)==0) ? 0 : 1;
6875        _settriple(result, sign, r, 0);
6876        return;
6877    }
6878    if (mpd_isnegative(exp)) {
6879        mpd_seterror(result, MPD_Invalid_operation, status);
6880        return;
6881    }
6882    if (mpd_iszerocoeff(base)) {
6883        _settriple(result, sign, 0, 0);
6884        return;
6885    }
6886
6887    mpd_maxcontext(&maxcontext);
6888
6889    mpd_qrescale(&tmod, mod, 0, &maxcontext, &maxcontext.status);
6890    if (maxcontext.status&MPD_Errors) {
6891        mpd_seterror(result, maxcontext.status&MPD_Errors, status);
6892        goto out;
6893    }
6894    maxcontext.status = 0;
6895    mpd_set_positive(&tmod);
6896
6897    mpd_qround_to_int(&tbase, base, &maxcontext, status);
6898    mpd_set_positive(&tbase);
6899    tbase_exp = tbase.exp;
6900    tbase.exp = 0;
6901
6902    mpd_qround_to_int(&texp, exp, &maxcontext, status);
6903    texp_exp = texp.exp;
6904    texp.exp = 0;
6905
6906    /* base = (base.int % modulo * pow(10, base.exp, modulo)) % modulo */
6907    mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status);
6908    mpd_qshiftl(result, &one, tbase_exp, status);
6909    mpd_qrem(result, result, &tmod, &maxcontext, status);
6910    _mpd_qmul_exact(&tbase, &tbase, result, &maxcontext, status);
6911    mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status);
6912    if (mpd_isspecial(&tbase) ||
6913        mpd_isspecial(&texp) ||
6914        mpd_isspecial(&tmod)) {
6915        goto mpd_errors;
6916    }
6917
6918    for (i = 0; i < texp_exp; i++) {
6919        _mpd_qpowmod_uint(&tmp, &tbase, 10, &tmod, status);
6920        t = tmp;
6921        tmp = tbase;
6922        tbase = t;
6923    }
6924    if (mpd_isspecial(&tbase)) {
6925        goto mpd_errors; /* GCOV_UNLIKELY */
6926    }
6927
6928    /* resize to smaller cannot fail */
6929    mpd_qcopy(result, &one, status);
6930    while (mpd_isfinite(&texp) && !mpd_iszero(&texp)) {
6931        if (mpd_isodd(&texp)) {
6932            _mpd_qmul_exact(result, result, &tbase, &maxcontext, status);
6933            mpd_qrem(result, result, &tmod, &maxcontext, status);
6934        }
6935        _mpd_qmul_exact(&tbase, &tbase, &tbase, &maxcontext, status);
6936        mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status);
6937        mpd_qdivint(&texp, &texp, &two, &maxcontext, status);
6938    }
6939    if (mpd_isspecial(&texp) || mpd_isspecial(&tbase) ||
6940        mpd_isspecial(&tmod) || mpd_isspecial(result)) {
6941        /* MPD_Malloc_error */
6942        goto mpd_errors;
6943    }
6944    else {
6945        mpd_set_sign(result, sign);
6946    }
6947
6948out:
6949    mpd_del(&tbase);
6950    mpd_del(&texp);
6951    mpd_del(&tmod);
6952    mpd_del(&tmp);
6953    return;
6954
6955mpd_errors:
6956    mpd_setspecial(result, MPD_POS, MPD_NAN);
6957    goto out;
6958}
6959
6960void
6961mpd_qquantize(mpd_t *result, const mpd_t *a, const mpd_t *b,
6962              const mpd_context_t *ctx, uint32_t *status)
6963{
6964    uint32_t workstatus = 0;
6965    mpd_ssize_t b_exp = b->exp;
6966    mpd_ssize_t expdiff, shift;
6967    mpd_uint_t rnd;
6968
6969    if (mpd_isspecial(a) || mpd_isspecial(b)) {
6970        if (mpd_qcheck_nans(result, a, b, ctx, status)) {
6971            return;
6972        }
6973        if (mpd_isinfinite(a) && mpd_isinfinite(b)) {
6974            mpd_qcopy(result, a, status);
6975            return;
6976        }
6977        mpd_seterror(result, MPD_Invalid_operation, status);
6978        return;
6979    }
6980
6981    if (b->exp > ctx->emax || b->exp < mpd_etiny(ctx)) {
6982        mpd_seterror(result, MPD_Invalid_operation, status);
6983        return;
6984    }
6985
6986    if (mpd_iszero(a)) {
6987        _settriple(result, mpd_sign(a), 0, b->exp);
6988        mpd_qfinalize(result, ctx, status);
6989        return;
6990    }
6991
6992
6993    expdiff = a->exp - b->exp;
6994    if (a->digits + expdiff > ctx->prec) {
6995        mpd_seterror(result, MPD_Invalid_operation, status);
6996        return;
6997    }
6998
6999    if (expdiff >= 0) {
7000        shift = expdiff;
7001        if (!mpd_qshiftl(result, a, shift, status)) {
7002            return;
7003        }
7004        result->exp = b_exp;
7005    }
7006    else {
7007        /* At this point expdiff < 0 and a->digits+expdiff <= prec,
7008         * so the shift before an increment will fit in prec. */
7009        shift = -expdiff;
7010        rnd = mpd_qshiftr(result, a, shift, status);
7011        if (rnd == MPD_UINT_MAX) {
7012            return;
7013        }
7014        result->exp = b_exp;
7015        if (!_mpd_apply_round_fit(result, rnd, ctx, status)) {
7016            return;
7017        }
7018        workstatus |= MPD_Rounded;
7019        if (rnd) {
7020            workstatus |= MPD_Inexact;
7021        }
7022    }
7023
7024    if (mpd_adjexp(result) > ctx->emax ||
7025        mpd_adjexp(result) < mpd_etiny(ctx)) {
7026        mpd_seterror(result, MPD_Invalid_operation, status);
7027        return;
7028    }
7029
7030    *status |= workstatus;
7031    mpd_qfinalize(result, ctx, status);
7032}
7033
7034void
7035mpd_qreduce(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
7036            uint32_t *status)
7037{
7038    mpd_ssize_t shift, maxexp, maxshift;
7039    uint8_t sign_a = mpd_sign(a);
7040
7041    if (mpd_isspecial(a)) {
7042        if (mpd_qcheck_nan(result, a, ctx, status)) {
7043            return;
7044        }
7045        mpd_qcopy(result, a, status);
7046        return;
7047    }
7048
7049    if (!mpd_qcopy(result, a, status)) {
7050        return;
7051    }
7052    mpd_qfinalize(result, ctx, status);
7053    if (mpd_isspecial(result)) {
7054        return;
7055    }
7056    if (mpd_iszero(result)) {
7057        _settriple(result, sign_a, 0, 0);
7058        return;
7059    }
7060
7061    shift = mpd_trail_zeros(result);
7062    maxexp = (ctx->clamp) ? mpd_etop(ctx) : ctx->emax;
7063    /* After the finalizing above result->exp <= maxexp. */
7064    maxshift = maxexp - result->exp;
7065    shift = (shift > maxshift) ? maxshift : shift;
7066
7067    mpd_qshiftr_inplace(result, shift);
7068    result->exp += shift;
7069}
7070
7071void
7072mpd_qrem(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx,
7073         uint32_t *status)
7074{
7075    MPD_NEW_STATIC(q,0,0,0,0);
7076
7077    if (mpd_isspecial(a) || mpd_isspecial(b)) {
7078        if (mpd_qcheck_nans(r, a, b, ctx, status)) {
7079            return;
7080        }
7081        if (mpd_isinfinite(a)) {
7082            mpd_seterror(r, MPD_Invalid_operation, status);
7083            return;
7084        }
7085        if (mpd_isinfinite(b)) {
7086            mpd_qcopy(r, a, status);
7087            mpd_qfinalize(r, ctx, status);
7088            return;
7089        }
7090        /* debug */
7091        abort(); /* GCOV_NOT_REACHED */
7092    }
7093    if (mpd_iszerocoeff(b)) {
7094        if (mpd_iszerocoeff(a)) {
7095            mpd_seterror(r, MPD_Division_undefined, status);
7096        }
7097        else {
7098            mpd_seterror(r, MPD_Invalid_operation, status);
7099        }
7100        return;
7101    }
7102
7103    _mpd_qdivmod(&q, r, a, b, ctx, status);
7104    mpd_del(&q);
7105    mpd_qfinalize(r, ctx, status);
7106}
7107
7108void
7109mpd_qrem_near(mpd_t *r, const mpd_t *a, const mpd_t *b,
7110              const mpd_context_t *ctx, uint32_t *status)
7111{
7112    mpd_context_t workctx;
7113    MPD_NEW_STATIC(btmp,0,0,0,0);
7114    MPD_NEW_STATIC(q,0,0,0,0);
7115    mpd_ssize_t expdiff, qdigits;
7116    int cmp, isodd, allnine;
7117
7118    assert(r != NULL); /* annotation for scan-build */
7119
7120    if (mpd_isspecial(a) || mpd_isspecial(b)) {
7121        if (mpd_qcheck_nans(r, a, b, ctx, status)) {
7122            return;
7123        }
7124        if (mpd_isinfinite(a)) {
7125            mpd_seterror(r, MPD_Invalid_operation, status);
7126            return;
7127        }
7128        if (mpd_isinfinite(b)) {
7129            mpd_qcopy(r, a, status);
7130            mpd_qfinalize(r, ctx, status);
7131            return;
7132        }
7133        /* debug */
7134        abort(); /* GCOV_NOT_REACHED */
7135    }
7136    if (mpd_iszerocoeff(b)) {
7137        if (mpd_iszerocoeff(a)) {
7138            mpd_seterror(r,  MPD_Division_undefined, status);
7139        }
7140        else {
7141            mpd_seterror(r,  MPD_Invalid_operation, status);
7142        }
7143        return;
7144    }
7145
7146    if (r == b) {
7147        if (!mpd_qcopy(&btmp, b, status)) {
7148            mpd_seterror(r, MPD_Malloc_error, status);
7149            return;
7150        }
7151        b = &btmp;
7152    }
7153
7154    _mpd_qdivmod(&q, r, a, b, ctx, status);
7155    if (mpd_isnan(&q) || mpd_isnan(r)) {
7156        goto finish;
7157    }
7158    if (mpd_iszerocoeff(r)) {
7159        goto finish;
7160    }
7161
7162    expdiff = mpd_adjexp(b) - mpd_adjexp(r);
7163    if (-1 <= expdiff && expdiff <= 1) {
7164
7165        allnine = mpd_coeff_isallnine(&q);
7166        qdigits = q.digits;
7167        isodd = mpd_isodd(&q);
7168
7169        mpd_maxcontext(&workctx);
7170        if (mpd_sign(a) == mpd_sign(b)) {
7171            /* sign(r) == sign(b) */
7172            _mpd_qsub(&q, r, b, &workctx, &workctx.status);
7173        }
7174        else {
7175            /* sign(r) != sign(b) */
7176            _mpd_qadd(&q, r, b, &workctx, &workctx.status);
7177        }
7178
7179        if (workctx.status&MPD_Errors) {
7180            mpd_seterror(r, workctx.status&MPD_Errors, status);
7181            goto finish;
7182        }
7183
7184        cmp = _mpd_cmp_abs(&q, r);
7185        if (cmp < 0 || (cmp == 0 && isodd)) {
7186            /* abs(r) > abs(b)/2 or abs(r) == abs(b)/2 and isodd(quotient) */
7187            if (allnine && qdigits == ctx->prec) {
7188                /* abs(quotient) + 1 == 10**prec */
7189                mpd_seterror(r, MPD_Division_impossible, status);
7190                goto finish;
7191            }
7192            mpd_qcopy(r, &q, status);
7193        }
7194    }
7195
7196
7197finish:
7198    mpd_del(&btmp);
7199    mpd_del(&q);
7200    mpd_qfinalize(r, ctx, status);
7201}
7202
7203static void
7204_mpd_qrescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp,
7205              const mpd_context_t *ctx, uint32_t *status)
7206{
7207    mpd_ssize_t expdiff, shift;
7208    mpd_uint_t rnd;
7209
7210    if (mpd_isspecial(a)) {
7211        mpd_qcopy(result, a, status);
7212        return;
7213    }
7214
7215    if (mpd_iszero(a)) {
7216        _settriple(result, mpd_sign(a), 0, exp);
7217        return;
7218    }
7219
7220    expdiff = a->exp - exp;
7221    if (expdiff >= 0) {
7222        shift = expdiff;
7223        if (a->digits + shift > MPD_MAX_PREC+1) {
7224            mpd_seterror(result, MPD_Invalid_operation, status);
7225            return;
7226        }
7227        if (!mpd_qshiftl(result, a, shift, status)) {
7228            return;
7229        }
7230        result->exp = exp;
7231    }
7232    else {
7233        shift = -expdiff;
7234        rnd = mpd_qshiftr(result, a, shift, status);
7235        if (rnd == MPD_UINT_MAX) {
7236            return;
7237        }
7238        result->exp = exp;
7239        _mpd_apply_round_excess(result, rnd, ctx, status);
7240        *status |= MPD_Rounded;
7241        if (rnd) {
7242            *status |= MPD_Inexact;
7243        }
7244    }
7245
7246    if (mpd_issubnormal(result, ctx)) {
7247        *status |= MPD_Subnormal;
7248    }
7249}
7250
7251/*
7252 * Rescale a number so that it has exponent 'exp'. Does not regard context
7253 * precision, emax, emin, but uses the rounding mode. Special numbers are
7254 * quietly copied. Restrictions:
7255 *
7256 *     MPD_MIN_ETINY <= exp <= MPD_MAX_EMAX+1
7257 *     result->digits <= MPD_MAX_PREC+1
7258 */
7259void
7260mpd_qrescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp,
7261             const mpd_context_t *ctx, uint32_t *status)
7262{
7263    if (exp > MPD_MAX_EMAX+1 || exp < MPD_MIN_ETINY) {
7264        mpd_seterror(result, MPD_Invalid_operation, status);
7265        return;
7266    }
7267
7268    _mpd_qrescale(result, a, exp, ctx, status);
7269}
7270
7271/*
7272 * Same as mpd_qrescale, but with relaxed restrictions. The result of this
7273 * function should only be used for formatting a number and never as input
7274 * for other operations.
7275 *
7276 *     MPD_MIN_ETINY-MPD_MAX_PREC <= exp <= MPD_MAX_EMAX+1
7277 *     result->digits <= MPD_MAX_PREC+1
7278 */
7279void
7280mpd_qrescale_fmt(mpd_t *result, const mpd_t *a, mpd_ssize_t exp,
7281                 const mpd_context_t *ctx, uint32_t *status)
7282{
7283    if (exp > MPD_MAX_EMAX+1 || exp < MPD_MIN_ETINY-MPD_MAX_PREC) {
7284        mpd_seterror(result, MPD_Invalid_operation, status);
7285        return;
7286    }
7287
7288    _mpd_qrescale(result, a, exp, ctx, status);
7289}
7290
7291/* Round to an integer according to 'action' and ctx->round. */
7292enum {TO_INT_EXACT, TO_INT_SILENT, TO_INT_TRUNC};
7293static void
7294_mpd_qround_to_integral(int action, mpd_t *result, const mpd_t *a,
7295                        const mpd_context_t *ctx, uint32_t *status)
7296{
7297    mpd_uint_t rnd;
7298
7299    if (mpd_isspecial(a)) {
7300        if (mpd_qcheck_nan(result, a, ctx, status)) {
7301            return;
7302        }
7303        mpd_qcopy(result, a, status);
7304        return;
7305    }
7306    if (a->exp >= 0) {
7307        mpd_qcopy(result, a, status);
7308        return;
7309    }
7310    if (mpd_iszerocoeff(a)) {
7311        _settriple(result, mpd_sign(a), 0, 0);
7312        return;
7313    }
7314
7315    rnd = mpd_qshiftr(result, a, -a->exp, status);
7316    if (rnd == MPD_UINT_MAX) {
7317        return;
7318    }
7319    result->exp = 0;
7320
7321    if (action == TO_INT_EXACT || action == TO_INT_SILENT) {
7322        _mpd_apply_round_excess(result, rnd, ctx, status);
7323        if (action == TO_INT_EXACT) {
7324            *status |= MPD_Rounded;
7325            if (rnd) {
7326                *status |= MPD_Inexact;
7327            }
7328        }
7329    }
7330}
7331
7332void
7333mpd_qround_to_intx(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
7334                   uint32_t *status)
7335{
7336    (void)_mpd_qround_to_integral(TO_INT_EXACT, result, a, ctx, status);
7337}
7338
7339void
7340mpd_qround_to_int(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
7341                  uint32_t *status)
7342{
7343    (void)_mpd_qround_to_integral(TO_INT_SILENT, result, a, ctx, status);
7344}
7345
7346void
7347mpd_qtrunc(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
7348           uint32_t *status)
7349{
7350    if (mpd_isspecial(a)) {
7351        mpd_seterror(result, MPD_Invalid_operation, status);
7352        return;
7353    }
7354
7355    (void)_mpd_qround_to_integral(TO_INT_TRUNC, result, a, ctx, status);
7356}
7357
7358void
7359mpd_qfloor(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
7360           uint32_t *status)
7361{
7362    mpd_context_t workctx = *ctx;
7363
7364    if (mpd_isspecial(a)) {
7365        mpd_seterror(result, MPD_Invalid_operation, status);
7366        return;
7367    }
7368
7369    workctx.round = MPD_ROUND_FLOOR;
7370    (void)_mpd_qround_to_integral(TO_INT_SILENT, result, a,
7371                                  &workctx, status);
7372}
7373
7374void
7375mpd_qceil(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
7376          uint32_t *status)
7377{
7378    mpd_context_t workctx = *ctx;
7379
7380    if (mpd_isspecial(a)) {
7381        mpd_seterror(result, MPD_Invalid_operation, status);
7382        return;
7383    }
7384
7385    workctx.round = MPD_ROUND_CEILING;
7386    (void)_mpd_qround_to_integral(TO_INT_SILENT, result, a,
7387                                  &workctx, status);
7388}
7389
7390int
7391mpd_same_quantum(const mpd_t *a, const mpd_t *b)
7392{
7393    if (mpd_isspecial(a) || mpd_isspecial(b)) {
7394        return ((mpd_isnan(a) && mpd_isnan(b)) ||
7395                (mpd_isinfinite(a) && mpd_isinfinite(b)));
7396    }
7397
7398    return a->exp == b->exp;
7399}
7400
7401/* Schedule the increase in precision for the Newton iteration. */
7402static inline int
7403recpr_schedule_prec(mpd_ssize_t klist[MPD_MAX_PREC_LOG2],
7404                    mpd_ssize_t maxprec, mpd_ssize_t initprec)
7405{
7406    mpd_ssize_t k;
7407    int i;
7408
7409    assert(maxprec > 0 && initprec > 0);
7410    if (maxprec <= initprec) return -1;
7411
7412    i = 0; k = maxprec;
7413    do {
7414        k = (k+1) / 2;
7415        klist[i++] = k;
7416    } while (k > initprec);
7417
7418    return i-1;
7419}
7420
7421/*
7422 * Initial approximation for the reciprocal:
7423 *    k_0 := MPD_RDIGITS-2
7424 *    z_0 := 10**(-k_0) * floor(10**(2*k_0 + 2) / floor(v * 10**(k_0 + 2)))
7425 * Absolute error:
7426 *    |1/v - z_0| < 10**(-k_0)
7427 * ACL2 proof: maxerror-inverse-approx
7428 */
7429static void
7430_mpd_qreciprocal_approx(mpd_t *z, const mpd_t *v, uint32_t *status)
7431{
7432    mpd_uint_t p10data[2] = {0, mpd_pow10[MPD_RDIGITS-2]};
7433    mpd_uint_t dummy, word;
7434    int n;
7435
7436    assert(v->exp == -v->digits);
7437
7438    _mpd_get_msdigits(&dummy, &word, v, MPD_RDIGITS);
7439    n = mpd_word_digits(word);
7440    word *= mpd_pow10[MPD_RDIGITS-n];
7441
7442    mpd_qresize(z, 2, status);
7443    (void)_mpd_shortdiv(z->data, p10data, 2, word);
7444
7445    mpd_clear_flags(z);
7446    z->exp = -(MPD_RDIGITS-2);
7447    z->len = (z->data[1] == 0) ? 1 : 2;
7448    mpd_setdigits(z);
7449}
7450
7451/*
7452 * Reciprocal, calculated with Newton's Method. Assumption: result != a.
7453 * NOTE: The comments in the function show that certain operations are
7454 * exact. The proof for the maximum error is too long to fit in here.
7455 * ACL2 proof: maxerror-inverse-complete
7456 */
7457static void
7458_mpd_qreciprocal(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
7459                 uint32_t *status)
7460{
7461    mpd_context_t varcontext, maxcontext;
7462    mpd_t *z = result;         /* current approximation */
7463    mpd_t *v;                  /* a, normalized to a number between 0.1 and 1 */
7464    MPD_NEW_SHARED(vtmp, a);   /* v shares data with a */
7465    MPD_NEW_STATIC(s,0,0,0,0); /* temporary variable */
7466    MPD_NEW_STATIC(t,0,0,0,0); /* temporary variable */
7467    MPD_NEW_CONST(two,0,0,1,1,1,2); /* const 2 */
7468    mpd_ssize_t klist[MPD_MAX_PREC_LOG2];
7469    mpd_ssize_t adj, maxprec, initprec;
7470    uint8_t sign = mpd_sign(a);
7471    int i;
7472
7473    assert(result != a);
7474
7475    v = &vtmp;
7476    mpd_clear_flags(v);
7477    adj = v->digits + v->exp;
7478    v->exp = -v->digits;
7479
7480    /* Initial approximation */
7481    _mpd_qreciprocal_approx(z, v, status);
7482
7483    mpd_maxcontext(&varcontext);
7484    mpd_maxcontext(&maxcontext);
7485    varcontext.round = maxcontext.round = MPD_ROUND_TRUNC;
7486    varcontext.emax = maxcontext.emax = MPD_MAX_EMAX + 100;
7487    varcontext.emin = maxcontext.emin = MPD_MIN_EMIN - 100;
7488    maxcontext.prec = MPD_MAX_PREC + 100;
7489
7490    maxprec = ctx->prec;
7491    maxprec += 2;
7492    initprec = MPD_RDIGITS-3;
7493
7494    i = recpr_schedule_prec(klist, maxprec, initprec);
7495    for (; i >= 0; i--) {
7496         /* Loop invariant: z->digits <= klist[i]+7 */
7497         /* Let s := z**2, exact result */
7498        _mpd_qmul_exact(&s, z, z, &maxcontext, status);
7499        varcontext.prec = 2*klist[i] + 5;
7500        if (v->digits > varcontext.prec) {
7501            /* Let t := v, truncated to n >= 2*k+5 fraction digits */
7502            mpd_qshiftr(&t, v, v->digits-varcontext.prec, status);
7503            t.exp = -varcontext.prec;
7504            /* Let t := trunc(v)*s, truncated to n >= 2*k+1 fraction digits */
7505            mpd_qmul(&t, &t, &s, &varcontext, status);
7506        }
7507        else { /* v->digits <= 2*k+5 */
7508            /* Let t := v*s, truncated to n >= 2*k+1 fraction digits */
7509            mpd_qmul(&t, v, &s, &varcontext, status);
7510        }
7511        /* Let s := 2*z, exact result */
7512        _mpd_qmul_exact(&s, z, &two, &maxcontext, status);
7513        /* s.digits < t.digits <= 2*k+5, |adjexp(s)-adjexp(t)| <= 1,
7514         * so the subtraction generates at most 2*k+6 <= klist[i+1]+7
7515         * digits. The loop invariant is preserved. */
7516        _mpd_qsub_exact(z, &s, &t, &maxcontext, status);
7517    }
7518
7519    if (!mpd_isspecial(z)) {
7520        z->exp -= adj;
7521        mpd_set_flags(z, sign);
7522    }
7523
7524    mpd_del(&s);
7525    mpd_del(&t);
7526    mpd_qfinalize(z, ctx, status);
7527}
7528
7529/*
7530 * Internal function for large numbers:
7531 *
7532 *     q, r = divmod(coeff(a), coeff(b))
7533 *
7534 * Strategy: Multiply the dividend by the reciprocal of the divisor. The
7535 * inexact result is fixed by a small loop, using at most one iteration.
7536 *
7537 * ACL2 proofs:
7538 * ------------
7539 *    1) q is a natural number.  (ndivmod-quotient-natp)
7540 *    2) r is a natural number.  (ndivmod-remainder-natp)
7541 *    3) a = q * b + r           (ndivmod-q*b+r==a)
7542 *    4) r < b                   (ndivmod-remainder-<-b)
7543 */
7544static void
7545_mpd_base_ndivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b,
7546                  uint32_t *status)
7547{
7548    mpd_context_t workctx;
7549    mpd_t *qq = q, *rr = r;
7550    mpd_t aa, bb;
7551    int k;
7552
7553    _mpd_copy_shared(&aa, a);
7554    _mpd_copy_shared(&bb, b);
7555
7556    mpd_set_positive(&aa);
7557    mpd_set_positive(&bb);
7558    aa.exp = 0;
7559    bb.exp = 0;
7560
7561    if (q == a || q == b) {
7562        if ((qq = mpd_qnew()) == NULL) {
7563            *status |= MPD_Malloc_error;
7564            goto nanresult;
7565        }
7566    }
7567    if (r == a || r == b) {
7568        if ((rr = mpd_qnew()) == NULL) {
7569            *status |= MPD_Malloc_error;
7570            goto nanresult;
7571        }
7572    }
7573
7574    mpd_maxcontext(&workctx);
7575
7576    /* Let prec := adigits - bdigits + 4 */
7577    workctx.prec = a->digits - b->digits + 1 + 3;
7578    if (a->digits > MPD_MAX_PREC || workctx.prec > MPD_MAX_PREC) {
7579        *status |= MPD_Division_impossible;
7580        goto nanresult;
7581    }
7582
7583    /* Let x := _mpd_qreciprocal(b, prec)
7584     * Then x is bounded by:
7585     *    1) 1/b - 10**(-prec - bdigits) < x < 1/b + 10**(-prec - bdigits)
7586     *    2) 1/b - 10**(-adigits - 4) < x < 1/b + 10**(-adigits - 4)
7587     */
7588    _mpd_qreciprocal(rr, &bb, &workctx, &workctx.status);
7589
7590    /* Get an estimate for the quotient. Let q := a * x
7591     * Then q is bounded by:
7592     *    3) a/b - 10**-4 < q < a/b + 10**-4
7593     */
7594    _mpd_qmul(qq, &aa, rr, &workctx, &workctx.status);
7595    /* Truncate q to an integer:
7596     *    4) a/b - 2 < trunc(q) < a/b + 1
7597     */
7598    mpd_qtrunc(qq, qq, &workctx, &workctx.status);
7599
7600    workctx.prec = aa.digits + 3;
7601    workctx.emax = MPD_MAX_EMAX + 3;
7602    workctx.emin = MPD_MIN_EMIN - 3;
7603    /* Multiply the estimate for q by b:
7604     *    5) a - 2 * b < trunc(q) * b < a + b
7605     */
7606    _mpd_qmul(rr, &bb, qq, &workctx, &workctx.status);
7607    /* Get the estimate for r such that a = q * b + r. */
7608    _mpd_qsub_exact(rr, &aa, rr, &workctx, &workctx.status);
7609
7610    /* Fix the result. At this point -b < r < 2*b, so the correction loop
7611       takes at most one iteration. */
7612    for (k = 0;; k++) {
7613        if (mpd_isspecial(qq) || mpd_isspecial(rr)) {
7614            *status |= (workctx.status&MPD_Errors);
7615            goto nanresult;
7616        }
7617        if (k > 2) { /* Allow two iterations despite the proof. */
7618            mpd_err_warn("libmpdec: internal error in "       /* GCOV_NOT_REACHED */
7619                         "_mpd_base_ndivmod: please report"); /* GCOV_NOT_REACHED */
7620            *status |= MPD_Invalid_operation;                 /* GCOV_NOT_REACHED */
7621            goto nanresult;                                   /* GCOV_NOT_REACHED */
7622        }
7623        /* r < 0 */
7624        else if (_mpd_cmp(&zero, rr) == 1) {
7625            _mpd_qadd_exact(rr, rr, &bb, &workctx, &workctx.status);
7626            _mpd_qadd_exact(qq, qq, &minus_one, &workctx, &workctx.status);
7627        }
7628        /* 0 <= r < b */
7629        else if (_mpd_cmp(rr, &bb) == -1) {
7630            break;
7631        }
7632        /* r >= b */
7633        else {
7634            _mpd_qsub_exact(rr, rr, &bb, &workctx, &workctx.status);
7635            _mpd_qadd_exact(qq, qq, &one, &workctx, &workctx.status);
7636        }
7637    }
7638
7639    if (qq != q) {
7640        if (!mpd_qcopy(q, qq, status)) {
7641            goto nanresult; /* GCOV_UNLIKELY */
7642        }
7643        mpd_del(qq);
7644    }
7645    if (rr != r) {
7646        if (!mpd_qcopy(r, rr, status)) {
7647            goto nanresult; /* GCOV_UNLIKELY */
7648        }
7649        mpd_del(rr);
7650    }
7651
7652    *status |= (workctx.status&MPD_Errors);
7653    return;
7654
7655
7656nanresult:
7657    if (qq && qq != q) mpd_del(qq);
7658    if (rr && rr != r) mpd_del(rr);
7659    mpd_setspecial(q, MPD_POS, MPD_NAN);
7660    mpd_setspecial(r, MPD_POS, MPD_NAN);
7661}
7662
7663/* LIBMPDEC_ONLY */
7664/*
7665 * Schedule the optimal precision increase for the Newton iteration.
7666 *   v := input operand
7667 *   z_0 := initial approximation
7668 *   initprec := natural number such that abs(sqrt(v) - z_0) < 10**-initprec
7669 *   maxprec := target precision
7670 *
7671 * For convenience the output klist contains the elements in reverse order:
7672 *   klist := [k_n-1, ..., k_0], where
7673 *     1) k_0 <= initprec and
7674 *     2) abs(sqrt(v) - result) < 10**(-2*k_n-1 + 2) <= 10**-maxprec.
7675 */
7676static inline int
7677invroot_schedule_prec(mpd_ssize_t klist[MPD_MAX_PREC_LOG2],
7678                      mpd_ssize_t maxprec, mpd_ssize_t initprec)
7679{
7680    mpd_ssize_t k;
7681    int i;
7682
7683    assert(maxprec >= 3 && initprec >= 3);
7684    if (maxprec <= initprec) return -1;
7685
7686    i = 0; k = maxprec;
7687    do {
7688        k = (k+3) / 2;
7689        klist[i++] = k;
7690    } while (k > initprec);
7691
7692    return i-1;
7693}
7694
7695/*
7696 * Initial approximation for the inverse square root function.
7697 *   Input:
7698 *     v := rational number, with 1 <= v < 100
7699 *     vhat := floor(v * 10**6)
7700 *   Output:
7701 *     z := approximation to 1/sqrt(v), such that abs(z - 1/sqrt(v)) < 10**-3.
7702 */
7703static inline void
7704_invroot_init_approx(mpd_t *z, mpd_uint_t vhat)
7705{
7706    mpd_uint_t lo = 1000;
7707    mpd_uint_t hi = 10000;
7708    mpd_uint_t a, sq;
7709
7710    assert(lo*lo <= vhat && vhat < (hi+1)*(hi+1));
7711
7712    for(;;) {
7713        a = (lo + hi) / 2;
7714        sq = a * a;
7715        if (vhat >= sq) {
7716            if (vhat < sq + 2*a + 1) {
7717                break;
7718            }
7719            lo = a + 1;
7720        }
7721        else {
7722            hi = a - 1;
7723        }
7724    }
7725
7726    /*
7727     * After the binary search we have:
7728     *  1) a**2 <= floor(v * 10**6) < (a + 1)**2
7729     * This implies:
7730     *  2) a**2 <= v * 10**6 < (a + 1)**2
7731     *  3) a <= sqrt(v) * 10**3 < a + 1
7732     * Since 10**3 <= a:
7733     *  4) 0 <= 10**prec/a - 1/sqrt(v) < 10**-prec
7734     * We have:
7735     *  5) 10**3/a - 10**-3 < floor(10**9/a) * 10**-6 <= 10**3/a
7736     * Merging 4) and 5):
7737     *  6) abs(floor(10**9/a) * 10**-6 - 1/sqrt(v)) < 10**-3
7738     */
7739    mpd_minalloc(z);
7740    mpd_clear_flags(z);
7741    z->data[0] = 1000000000UL / a;
7742    z->len = 1;
7743    z->exp = -6;
7744    mpd_setdigits(z);
7745}
7746
7747/*
7748 * Set 'result' to 1/sqrt(a).
7749 *   Relative error: abs(result - 1/sqrt(a)) < 10**-prec * 1/sqrt(a)
7750 */
7751static void
7752_mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
7753              uint32_t *status)
7754{
7755    uint32_t workstatus = 0;
7756    mpd_context_t varcontext, maxcontext;
7757    mpd_t *z = result;         /* current approximation */
7758    mpd_t *v;                  /* a, normalized to a number between 1 and 100 */
7759    MPD_NEW_SHARED(vtmp, a);   /* by default v will share data with a */
7760    MPD_NEW_STATIC(s,0,0,0,0); /* temporary variable */
7761    MPD_NEW_STATIC(t,0,0,0,0); /* temporary variable */
7762    MPD_NEW_CONST(one_half,0,-1,1,1,1,5);
7763    MPD_NEW_CONST(three,0,0,1,1,1,3);
7764    mpd_ssize_t klist[MPD_MAX_PREC_LOG2];
7765    mpd_ssize_t ideal_exp, shift;
7766    mpd_ssize_t adj, tz;
7767    mpd_ssize_t maxprec, fracdigits;
7768    mpd_uint_t vhat, dummy;
7769    int i, n;
7770
7771
7772    ideal_exp = -(a->exp - (a->exp & 1)) / 2;
7773
7774    v = &vtmp;
7775    if (result == a) {
7776        if ((v = mpd_qncopy(a)) == NULL) {
7777            mpd_seterror(result, MPD_Malloc_error, status);
7778            return;
7779        }
7780    }
7781
7782    /* normalize a to 1 <= v < 100 */
7783    if ((v->digits+v->exp) & 1) {
7784        fracdigits = v->digits - 1;
7785        v->exp = -fracdigits;
7786        n = (v->digits > 7) ? 7 : (int)v->digits;
7787        /* Let vhat := floor(v * 10**(2*initprec)) */
7788        _mpd_get_msdigits(&dummy, &vhat, v, n);
7789        if (n < 7) {
7790            vhat *= mpd_pow10[7-n];
7791        }
7792    }
7793    else {
7794        fracdigits = v->digits - 2;
7795        v->exp = -fracdigits;
7796        n = (v->digits > 8) ? 8 : (int)v->digits;
7797        /* Let vhat := floor(v * 10**(2*initprec)) */
7798        _mpd_get_msdigits(&dummy, &vhat, v, n);
7799        if (n < 8) {
7800            vhat *= mpd_pow10[8-n];
7801        }
7802    }
7803    adj = (a->exp-v->exp) / 2;
7804
7805    /* initial approximation */
7806    _invroot_init_approx(z, vhat);
7807
7808    mpd_maxcontext(&maxcontext);
7809    mpd_maxcontext(&varcontext);
7810    varcontext.round = MPD_ROUND_TRUNC;
7811    maxprec = ctx->prec + 1;
7812
7813    /* initprec == 3 */
7814    i = invroot_schedule_prec(klist, maxprec, 3);
7815    for (; i >= 0; i--) {
7816        varcontext.prec = 2*klist[i]+2;
7817        mpd_qmul(&s, z, z, &maxcontext, &workstatus);
7818        if (v->digits > varcontext.prec) {
7819            shift = v->digits - varcontext.prec;
7820            mpd_qshiftr(&t, v, shift, &workstatus);
7821            t.exp += shift;
7822            mpd_qmul(&t, &t, &s, &varcontext, &workstatus);
7823        }
7824        else {
7825            mpd_qmul(&t, v, &s, &varcontext, &workstatus);
7826        }
7827        mpd_qsub(&t, &three, &t, &maxcontext, &workstatus);
7828        mpd_qmul(z, z, &t, &varcontext, &workstatus);
7829        mpd_qmul(z, z, &one_half, &maxcontext, &workstatus);
7830    }
7831
7832    z->exp -= adj;
7833
7834    tz = mpd_trail_zeros(result);
7835    shift = ideal_exp - result->exp;
7836    shift = (tz > shift) ? shift : tz;
7837    if (shift > 0) {
7838        mpd_qshiftr_inplace(result, shift);
7839        result->exp += shift;
7840    }
7841
7842
7843    mpd_del(&s);
7844    mpd_del(&t);
7845    if (v != &vtmp) mpd_del(v);
7846    *status |= (workstatus&MPD_Errors);
7847    *status |= (MPD_Rounded|MPD_Inexact);
7848}
7849
7850void
7851mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
7852             uint32_t *status)
7853{
7854    mpd_context_t workctx;
7855
7856    if (mpd_isspecial(a)) {
7857        if (mpd_qcheck_nan(result, a, ctx, status)) {
7858            return;
7859        }
7860        if (mpd_isnegative(a)) {
7861            mpd_seterror(result, MPD_Invalid_operation, status);
7862            return;
7863        }
7864        /* positive infinity */
7865        _settriple(result, MPD_POS, 0, mpd_etiny(ctx));
7866        *status |= MPD_Clamped;
7867        return;
7868    }
7869    if (mpd_iszero(a)) {
7870        mpd_setspecial(result, mpd_sign(a), MPD_INF);
7871        *status |= MPD_Division_by_zero;
7872        return;
7873    }
7874    if (mpd_isnegative(a)) {
7875        mpd_seterror(result, MPD_Invalid_operation, status);
7876        return;
7877    }
7878
7879    workctx = *ctx;
7880    workctx.prec += 2;
7881    workctx.round = MPD_ROUND_HALF_EVEN;
7882    _mpd_qinvroot(result, a, &workctx, status);
7883    mpd_qfinalize(result, ctx, status);
7884}
7885/* END LIBMPDEC_ONLY */
7886
7887/* Algorithm from decimal.py */
7888static void
7889_mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
7890           uint32_t *status)
7891{
7892    mpd_context_t maxcontext;
7893    MPD_NEW_STATIC(c,0,0,0,0);
7894    MPD_NEW_STATIC(q,0,0,0,0);
7895    MPD_NEW_STATIC(r,0,0,0,0);
7896    MPD_NEW_CONST(two,0,0,1,1,1,2);
7897    mpd_ssize_t prec, ideal_exp;
7898    mpd_ssize_t l, shift;
7899    int exact = 0;
7900
7901
7902    ideal_exp = (a->exp - (a->exp & 1)) / 2;
7903
7904    if (mpd_isspecial(a)) {
7905        if (mpd_qcheck_nan(result, a, ctx, status)) {
7906            return;
7907        }
7908        if (mpd_isnegative(a)) {
7909            mpd_seterror(result, MPD_Invalid_operation, status);
7910            return;
7911        }
7912        mpd_setspecial(result, MPD_POS, MPD_INF);
7913        return;
7914    }
7915    if (mpd_iszero(a)) {
7916        _settriple(result, mpd_sign(a), 0, ideal_exp);
7917        mpd_qfinalize(result, ctx, status);
7918        return;
7919    }
7920    if (mpd_isnegative(a)) {
7921        mpd_seterror(result, MPD_Invalid_operation, status);
7922        return;
7923    }
7924
7925    mpd_maxcontext(&maxcontext);
7926    prec = ctx->prec + 1;
7927
7928    if (!mpd_qcopy(&c, a, status)) {
7929        goto malloc_error;
7930    }
7931    c.exp = 0;
7932
7933    if (a->exp & 1) {
7934        if (!mpd_qshiftl(&c, &c, 1, status)) {
7935            goto malloc_error;
7936        }
7937        l = (a->digits >> 1) + 1;
7938    }
7939    else {
7940        l = (a->digits + 1) >> 1;
7941    }
7942
7943    shift = prec - l;
7944    if (shift >= 0) {
7945        if (!mpd_qshiftl(&c, &c, 2*shift, status)) {
7946            goto malloc_error;
7947        }
7948        exact = 1;
7949    }
7950    else {
7951        exact = !mpd_qshiftr_inplace(&c, -2*shift);
7952    }
7953
7954    ideal_exp -= shift;
7955
7956    /* find result = floor(sqrt(c)) using Newton's method */
7957    if (!mpd_qshiftl(result, &one, prec, status)) {
7958        goto malloc_error;
7959    }
7960
7961    while (1) {
7962        _mpd_qdivmod(&q, &r, &c, result, &maxcontext, &maxcontext.status);
7963        if (mpd_isspecial(result) || mpd_isspecial(&q)) {
7964            mpd_seterror(result, maxcontext.status&MPD_Errors, status);
7965            goto out;
7966        }
7967        if (_mpd_cmp(result, &q) <= 0) {
7968            break;
7969        }
7970        _mpd_qadd_exact(result, result, &q, &maxcontext, &maxcontext.status);
7971        if (mpd_isspecial(result)) {
7972            mpd_seterror(result, maxcontext.status&MPD_Errors, status);
7973            goto out;
7974        }
7975        _mpd_qdivmod(result, &r, result, &two, &maxcontext, &maxcontext.status);
7976    }
7977
7978    if (exact) {
7979        _mpd_qmul_exact(&r, result, result, &maxcontext, &maxcontext.status);
7980        if (mpd_isspecial(&r)) {
7981            mpd_seterror(result, maxcontext.status&MPD_Errors, status);
7982            goto out;
7983        }
7984        exact = (_mpd_cmp(&r, &c) == 0);
7985    }
7986
7987    if (exact) {
7988        if (shift >= 0) {
7989            mpd_qshiftr_inplace(result, shift);
7990        }
7991        else {
7992            if (!mpd_qshiftl(result, result, -shift, status)) {
7993                goto malloc_error;
7994            }
7995        }
7996        ideal_exp += shift;
7997    }
7998    else {
7999        int lsd = (int)mpd_lsd(result->data[0]);
8000        if (lsd == 0 || lsd == 5) {
8001            result->data[0] += 1;
8002        }
8003    }
8004
8005    result->exp = ideal_exp;
8006
8007
8008out:
8009    mpd_del(&c);
8010    mpd_del(&q);
8011    mpd_del(&r);
8012    maxcontext = *ctx;
8013    maxcontext.round = MPD_ROUND_HALF_EVEN;
8014    mpd_qfinalize(result, &maxcontext, status);
8015    return;
8016
8017malloc_error:
8018    mpd_seterror(result, MPD_Malloc_error, status);
8019    goto out;
8020}
8021
8022void
8023mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
8024          uint32_t *status)
8025{
8026    MPD_NEW_STATIC(aa,0,0,0,0);
8027    uint32_t xstatus = 0;
8028
8029    if (result == a) {
8030        if (!mpd_qcopy(&aa, a, status)) {
8031            mpd_seterror(result, MPD_Malloc_error, status);
8032            goto out;
8033        }
8034        a = &aa;
8035    }
8036
8037    _mpd_qsqrt(result, a, ctx, &xstatus);
8038
8039    if (xstatus & (MPD_Malloc_error|MPD_Division_impossible)) {
8040        /* The above conditions can occur at very high context precisions
8041         * if intermediate values get too large. Retry the operation with
8042         * a lower context precision in case the result is exact.
8043         *
8044         * If the result is exact, an upper bound for the number of digits
8045         * is the number of digits in the input.
8046         *
8047         * NOTE: sqrt(40e9) = 2.0e+5 /\ digits(40e9) = digits(2.0e+5) = 2
8048         */
8049        uint32_t ystatus = 0;
8050        mpd_context_t workctx = *ctx;
8051
8052        workctx.prec = a->digits;
8053        if (workctx.prec >= ctx->prec) {
8054            *status |= (xstatus|MPD_Errors);
8055            goto out; /* No point in repeating this, keep the original error. */
8056        }
8057
8058        _mpd_qsqrt(result, a, &workctx, &ystatus);
8059        if (ystatus != 0) {
8060            ystatus = *status | ((xstatus|ystatus)&MPD_Errors);
8061            mpd_seterror(result, ystatus, status);
8062        }
8063    }
8064    else {
8065        *status |= xstatus;
8066    }
8067
8068out:
8069    mpd_del(&aa);
8070}
8071
8072
8073/******************************************************************************/
8074/*                              Base conversions                              */
8075/******************************************************************************/
8076
8077/* Space needed to represent an integer mpd_t in base 'base'. */
8078size_t
8079mpd_sizeinbase(const mpd_t *a, uint32_t base)
8080{
8081    double x;
8082    size_t digits;
8083    double upper_bound;
8084
8085    assert(mpd_isinteger(a));
8086    assert(base >= 2);
8087
8088    if (mpd_iszero(a)) {
8089        return 1;
8090    }
8091
8092    digits = a->digits+a->exp;
8093
8094#ifdef CONFIG_64
8095    /* ceil(2711437152599294 / log10(2)) + 4 == 2**53 */
8096    if (digits > 2711437152599294ULL) {
8097        return SIZE_MAX;
8098    }
8099
8100    upper_bound = (double)((1ULL<<53)-1);
8101#else
8102    upper_bound = (double)(SIZE_MAX-1);
8103#endif
8104
8105    x = (double)digits / log10(base);
8106    return (x > upper_bound) ? SIZE_MAX : (size_t)x + 1;
8107}
8108
8109/* Space needed to import a base 'base' integer of length 'srclen'. */
8110static mpd_ssize_t
8111_mpd_importsize(size_t srclen, uint32_t base)
8112{
8113    double x;
8114    double upper_bound;
8115
8116    assert(srclen > 0);
8117    assert(base >= 2);
8118
8119#if SIZE_MAX == UINT64_MAX
8120    if (srclen > (1ULL<<53)) {
8121        return MPD_SSIZE_MAX;
8122    }
8123
8124    assert((1ULL<<53) <= MPD_MAXIMPORT);
8125    upper_bound = (double)((1ULL<<53)-1);
8126#else
8127    upper_bound = MPD_MAXIMPORT-1;
8128#endif
8129
8130    x = (double)srclen * (log10(base)/MPD_RDIGITS);
8131    return (x > upper_bound) ? MPD_SSIZE_MAX : (mpd_ssize_t)x + 1;
8132}
8133
8134static uint8_t
8135mpd_resize_u16(uint16_t **w, size_t nmemb)
8136{
8137    uint8_t err = 0;
8138    *w = mpd_realloc(*w, nmemb, sizeof **w, &err);
8139    return !err;
8140}
8141
8142static uint8_t
8143mpd_resize_u32(uint32_t **w, size_t nmemb)
8144{
8145    uint8_t err = 0;
8146    *w = mpd_realloc(*w, nmemb, sizeof **w, &err);
8147    return !err;
8148}
8149
8150static size_t
8151_baseconv_to_u16(uint16_t **w, size_t wlen, mpd_uint_t wbase,
8152                 mpd_uint_t *u, mpd_ssize_t ulen)
8153{
8154    size_t n = 0;
8155
8156    assert(wlen > 0 && ulen > 0);
8157    assert(wbase <= (1U<<16));
8158
8159    do {
8160        if (n >= wlen) {
8161            if (!mpd_resize_u16(w, n+1)) {
8162                return SIZE_MAX;
8163            }
8164            wlen = n+1;
8165        }
8166        (*w)[n++] = (uint16_t)_mpd_shortdiv(u, u, ulen, wbase);
8167        /* ulen is at least 1. u[ulen-1] can only be zero if ulen == 1. */
8168        ulen = _mpd_real_size(u, ulen);
8169
8170    } while (u[ulen-1] != 0);
8171
8172    return n;
8173}
8174
8175static size_t
8176_coeff_from_u16(mpd_t *w, mpd_ssize_t wlen,
8177                const mpd_uint_t *u, size_t ulen, uint32_t ubase,
8178                uint32_t *status)
8179{
8180    mpd_ssize_t n = 0;
8181    mpd_uint_t carry;
8182
8183    assert(wlen > 0 && ulen > 0);
8184    assert(ubase <= (1U<<16));
8185
8186    w->data[n++] = u[--ulen];
8187    while (--ulen != SIZE_MAX) {
8188        carry = _mpd_shortmul_c(w->data, w->data, n, ubase);
8189        if (carry) {
8190            if (n >= wlen) {
8191                if (!mpd_qresize(w, n+1, status)) {
8192                    return SIZE_MAX;
8193                }
8194                wlen = n+1;
8195            }
8196            w->data[n++] = carry;
8197        }
8198        carry = _mpd_shortadd(w->data, n, u[ulen]);
8199        if (carry) {
8200            if (n >= wlen) {
8201                if (!mpd_qresize(w, n+1, status)) {
8202                    return SIZE_MAX;
8203                }
8204                wlen = n+1;
8205            }
8206            w->data[n++] = carry;
8207        }
8208    }
8209
8210    return n;
8211}
8212
8213/* target base wbase < source base ubase */
8214static size_t
8215_baseconv_to_smaller(uint32_t **w, size_t wlen, uint32_t wbase,
8216                     mpd_uint_t *u, mpd_ssize_t ulen, mpd_uint_t ubase)
8217{
8218    size_t n = 0;
8219
8220    assert(wlen > 0 && ulen > 0);
8221    assert(wbase < ubase);
8222
8223    do {
8224        if (n >= wlen) {
8225            if (!mpd_resize_u32(w, n+1)) {
8226                return SIZE_MAX;
8227            }
8228            wlen = n+1;
8229        }
8230        (*w)[n++] = (uint32_t)_mpd_shortdiv_b(u, u, ulen, wbase, ubase);
8231        /* ulen is at least 1. u[ulen-1] can only be zero if ulen == 1. */
8232        ulen = _mpd_real_size(u, ulen);
8233
8234    } while (u[ulen-1] != 0);
8235
8236    return n;
8237}
8238
8239#ifdef CONFIG_32
8240/* target base 'wbase' == source base 'ubase' */
8241static size_t
8242_copy_equal_base(uint32_t **w, size_t wlen,
8243                 const uint32_t *u, size_t ulen)
8244{
8245    if (wlen < ulen) {
8246        if (!mpd_resize_u32(w, ulen)) {
8247            return SIZE_MAX;
8248        }
8249    }
8250
8251    memcpy(*w, u, ulen * (sizeof **w));
8252    return ulen;
8253}
8254
8255/* target base 'wbase' > source base 'ubase' */
8256static size_t
8257_baseconv_to_larger(uint32_t **w, size_t wlen, mpd_uint_t wbase,
8258                    const mpd_uint_t *u, size_t ulen, mpd_uint_t ubase)
8259{
8260    size_t n = 0;
8261    mpd_uint_t carry;
8262
8263    assert(wlen > 0 && ulen > 0);
8264    assert(ubase < wbase);
8265
8266    (*w)[n++] = u[--ulen];
8267    while (--ulen != SIZE_MAX) {
8268        carry = _mpd_shortmul_b(*w, *w, n, ubase, wbase);
8269        if (carry) {
8270            if (n >= wlen) {
8271                if (!mpd_resize_u32(w, n+1)) {
8272                    return SIZE_MAX;
8273                }
8274                wlen = n+1;
8275            }
8276            (*w)[n++] = carry;
8277        }
8278        carry = _mpd_shortadd_b(*w, n, u[ulen], wbase);
8279        if (carry) {
8280            if (n >= wlen) {
8281                if (!mpd_resize_u32(w, n+1)) {
8282                    return SIZE_MAX;
8283                }
8284                wlen = n+1;
8285            }
8286            (*w)[n++] = carry;
8287        }
8288    }
8289
8290    return n;
8291}
8292
8293/* target base wbase < source base ubase */
8294static size_t
8295_coeff_from_larger_base(mpd_t *w, size_t wlen, mpd_uint_t wbase,
8296                        mpd_uint_t *u, mpd_ssize_t ulen, mpd_uint_t ubase,
8297                        uint32_t *status)
8298{
8299    size_t n = 0;
8300
8301    assert(wlen > 0 && ulen > 0);
8302    assert(wbase < ubase);
8303
8304    do {
8305        if (n >= wlen) {
8306            if (!mpd_qresize(w, n+1, status)) {
8307                return SIZE_MAX;
8308            }
8309            wlen = n+1;
8310        }
8311        w->data[n++] = (uint32_t)_mpd_shortdiv_b(u, u, ulen, wbase, ubase);
8312        /* ulen is at least 1. u[ulen-1] can only be zero if ulen == 1. */
8313        ulen = _mpd_real_size(u, ulen);
8314
8315    } while (u[ulen-1] != 0);
8316
8317    return n;
8318}
8319#endif
8320
8321/* target base 'wbase' > source base 'ubase' */
8322static size_t
8323_coeff_from_smaller_base(mpd_t *w, mpd_ssize_t wlen, mpd_uint_t wbase,
8324                         const uint32_t *u, size_t ulen, mpd_uint_t ubase,
8325                         uint32_t *status)
8326{
8327    mpd_ssize_t n = 0;
8328    mpd_uint_t carry;
8329
8330    assert(wlen > 0 && ulen > 0);
8331    assert(wbase > ubase);
8332
8333    w->data[n++] = u[--ulen];
8334    while (--ulen != SIZE_MAX) {
8335        carry = _mpd_shortmul_b(w->data, w->data, n, ubase, wbase);
8336        if (carry) {
8337            if (n >= wlen) {
8338                if (!mpd_qresize(w, n+1, status)) {
8339                    return SIZE_MAX;
8340                }
8341                wlen = n+1;
8342            }
8343            w->data[n++] = carry;
8344        }
8345        carry = _mpd_shortadd_b(w->data, n, u[ulen], wbase);
8346        if (carry) {
8347            if (n >= wlen) {
8348                if (!mpd_qresize(w, n+1, status)) {
8349                    return SIZE_MAX;
8350                }
8351                wlen = n+1;
8352            }
8353            w->data[n++] = carry;
8354        }
8355    }
8356
8357    return n;
8358}
8359
8360/*
8361 * Convert an integer mpd_t to a multiprecision integer with base <= 2**16.
8362 * The least significant word of the result is (*rdata)[0].
8363 *
8364 * If rdata is NULL, space is allocated by the function and rlen is irrelevant.
8365 * In case of an error any allocated storage is freed and rdata is set back to
8366 * NULL.
8367 *
8368 * If rdata is non-NULL, it MUST be allocated by one of libmpdec's allocation
8369 * functions and rlen MUST be correct. If necessary, the function will resize
8370 * rdata. In case of an error the caller must free rdata.
8371 *
8372 * Return value: In case of success, the exact length of rdata, SIZE_MAX
8373 * otherwise.
8374 */
8375size_t
8376mpd_qexport_u16(uint16_t **rdata, size_t rlen, uint32_t rbase,
8377                const mpd_t *src, uint32_t *status)
8378{
8379    MPD_NEW_STATIC(tsrc,0,0,0,0);
8380    int alloc = 0; /* rdata == NULL */
8381    size_t n;
8382
8383    assert(rbase <= (1U<<16));
8384
8385    if (mpd_isspecial(src) || !_mpd_isint(src)) {
8386        *status |= MPD_Invalid_operation;
8387        return SIZE_MAX;
8388    }
8389
8390    if (*rdata == NULL) {
8391        rlen = mpd_sizeinbase(src, rbase);
8392        if (rlen == SIZE_MAX) {
8393            *status |= MPD_Invalid_operation;
8394            return SIZE_MAX;
8395        }
8396        *rdata = mpd_alloc(rlen, sizeof **rdata);
8397        if (*rdata == NULL) {
8398            goto malloc_error;
8399        }
8400        alloc = 1;
8401    }
8402
8403    if (mpd_iszero(src)) {
8404        **rdata = 0;
8405        return 1;
8406    }
8407
8408    if (src->exp >= 0) {
8409        if (!mpd_qshiftl(&tsrc, src, src->exp, status)) {
8410            goto malloc_error;
8411        }
8412    }
8413    else {
8414        if (mpd_qshiftr(&tsrc, src, -src->exp, status) == MPD_UINT_MAX) {
8415            goto malloc_error;
8416        }
8417    }
8418
8419    n = _baseconv_to_u16(rdata, rlen, rbase, tsrc.data, tsrc.len);
8420    if (n == SIZE_MAX) {
8421        goto malloc_error;
8422    }
8423
8424
8425out:
8426    mpd_del(&tsrc);
8427    return n;
8428
8429malloc_error:
8430    if (alloc) {
8431        mpd_free(*rdata);
8432        *rdata = NULL;
8433    }
8434    n = SIZE_MAX;
8435    *status |= MPD_Malloc_error;
8436    goto out;
8437}
8438
8439/*
8440 * Convert an integer mpd_t to a multiprecision integer with base<=UINT32_MAX.
8441 * The least significant word of the result is (*rdata)[0].
8442 *
8443 * If rdata is NULL, space is allocated by the function and rlen is irrelevant.
8444 * In case of an error any allocated storage is freed and rdata is set back to
8445 * NULL.
8446 *
8447 * If rdata is non-NULL, it MUST be allocated by one of libmpdec's allocation
8448 * functions and rlen MUST be correct. If necessary, the function will resize
8449 * rdata. In case of an error the caller must free rdata.
8450 *
8451 * Return value: In case of success, the exact length of rdata, SIZE_MAX
8452 * otherwise.
8453 */
8454size_t
8455mpd_qexport_u32(uint32_t **rdata, size_t rlen, uint32_t rbase,
8456                const mpd_t *src, uint32_t *status)
8457{
8458    MPD_NEW_STATIC(tsrc,0,0,0,0);
8459    int alloc = 0; /* rdata == NULL */
8460    size_t n;
8461
8462    if (mpd_isspecial(src) || !_mpd_isint(src)) {
8463        *status |= MPD_Invalid_operation;
8464        return SIZE_MAX;
8465    }
8466
8467    if (*rdata == NULL) {
8468        rlen = mpd_sizeinbase(src, rbase);
8469        if (rlen == SIZE_MAX) {
8470            *status |= MPD_Invalid_operation;
8471            return SIZE_MAX;
8472        }
8473        *rdata = mpd_alloc(rlen, sizeof **rdata);
8474        if (*rdata == NULL) {
8475            goto malloc_error;
8476        }
8477        alloc = 1;
8478    }
8479
8480    if (mpd_iszero(src)) {
8481        **rdata = 0;
8482        return 1;
8483    }
8484
8485    if (src->exp >= 0) {
8486        if (!mpd_qshiftl(&tsrc, src, src->exp, status)) {
8487            goto malloc_error;
8488        }
8489    }
8490    else {
8491        if (mpd_qshiftr(&tsrc, src, -src->exp, status) == MPD_UINT_MAX) {
8492            goto malloc_error;
8493        }
8494    }
8495
8496#ifdef CONFIG_64
8497    n = _baseconv_to_smaller(rdata, rlen, rbase,
8498                             tsrc.data, tsrc.len, MPD_RADIX);
8499#else
8500    if (rbase == MPD_RADIX) {
8501        n = _copy_equal_base(rdata, rlen, tsrc.data, tsrc.len);
8502    }
8503    else if (rbase < MPD_RADIX) {
8504        n = _baseconv_to_smaller(rdata, rlen, rbase,
8505                                 tsrc.data, tsrc.len, MPD_RADIX);
8506    }
8507    else {
8508        n = _baseconv_to_larger(rdata, rlen, rbase,
8509                                tsrc.data, tsrc.len, MPD_RADIX);
8510    }
8511#endif
8512
8513    if (n == SIZE_MAX) {
8514        goto malloc_error;
8515    }
8516
8517
8518out:
8519    mpd_del(&tsrc);
8520    return n;
8521
8522malloc_error:
8523    if (alloc) {
8524        mpd_free(*rdata);
8525        *rdata = NULL;
8526    }
8527    n = SIZE_MAX;
8528    *status |= MPD_Malloc_error;
8529    goto out;
8530}
8531
8532
8533/*
8534 * Converts a multiprecision integer with base <= UINT16_MAX+1 to an mpd_t.
8535 * The least significant word of the source is srcdata[0].
8536 */
8537void
8538mpd_qimport_u16(mpd_t *result,
8539                const uint16_t *srcdata, size_t srclen,
8540                uint8_t srcsign, uint32_t srcbase,
8541                const mpd_context_t *ctx, uint32_t *status)
8542{
8543    mpd_uint_t *usrc; /* uint16_t src copied to an mpd_uint_t array */
8544    mpd_ssize_t rlen; /* length of the result */
8545    size_t n;
8546
8547    assert(srclen > 0);
8548    assert(srcbase <= (1U<<16));
8549
8550    rlen = _mpd_importsize(srclen, srcbase);
8551    if (rlen == MPD_SSIZE_MAX) {
8552        mpd_seterror(result, MPD_Invalid_operation, status);
8553        return;
8554    }
8555
8556    usrc = mpd_alloc((mpd_size_t)srclen, sizeof *usrc);
8557    if (usrc == NULL) {
8558        mpd_seterror(result, MPD_Malloc_error, status);
8559        return;
8560    }
8561    for (n = 0; n < srclen; n++) {
8562        usrc[n] = srcdata[n];
8563    }
8564
8565    if (!mpd_qresize(result, rlen, status)) {
8566        goto finish;
8567    }
8568
8569    n = _coeff_from_u16(result, rlen, usrc, srclen, srcbase, status);
8570    if (n == SIZE_MAX) {
8571        goto finish;
8572    }
8573
8574    mpd_set_flags(result, srcsign);
8575    result->exp = 0;
8576    result->len = n;
8577    mpd_setdigits(result);
8578
8579    mpd_qresize(result, result->len, status);
8580    mpd_qfinalize(result, ctx, status);
8581
8582
8583finish:
8584    mpd_free(usrc);
8585}
8586
8587/*
8588 * Converts a multiprecision integer with base <= UINT32_MAX to an mpd_t.
8589 * The least significant word of the source is srcdata[0].
8590 */
8591void
8592mpd_qimport_u32(mpd_t *result,
8593                const uint32_t *srcdata, size_t srclen,
8594                uint8_t srcsign, uint32_t srcbase,
8595                const mpd_context_t *ctx, uint32_t *status)
8596{
8597    mpd_ssize_t rlen; /* length of the result */
8598    size_t n;
8599
8600    assert(srclen > 0);
8601
8602    rlen = _mpd_importsize(srclen, srcbase);
8603    if (rlen == MPD_SSIZE_MAX) {
8604        mpd_seterror(result, MPD_Invalid_operation, status);
8605        return;
8606    }
8607
8608    if (!mpd_qresize(result, rlen, status)) {
8609        return;
8610    }
8611
8612#ifdef CONFIG_64
8613    n = _coeff_from_smaller_base(result, rlen, MPD_RADIX,
8614                                 srcdata, srclen, srcbase,
8615                                 status);
8616#else
8617    if (srcbase == MPD_RADIX) {
8618        if (!mpd_qresize(result, srclen, status)) {
8619            return;
8620        }
8621        memcpy(result->data, srcdata, srclen * (sizeof *srcdata));
8622        n = srclen;
8623    }
8624    else if (srcbase < MPD_RADIX) {
8625        n = _coeff_from_smaller_base(result, rlen, MPD_RADIX,
8626                                     srcdata, srclen, srcbase,
8627                                     status);
8628    }
8629    else {
8630        mpd_uint_t *usrc = mpd_alloc((mpd_size_t)srclen, sizeof *usrc);
8631        if (usrc == NULL) {
8632            mpd_seterror(result, MPD_Malloc_error, status);
8633            return;
8634        }
8635        for (n = 0; n < srclen; n++) {
8636            usrc[n] = srcdata[n];
8637        }
8638
8639        n = _coeff_from_larger_base(result, rlen, MPD_RADIX,
8640                                    usrc, (mpd_ssize_t)srclen, srcbase,
8641                                    status);
8642        mpd_free(usrc);
8643    }
8644#endif
8645
8646    if (n == SIZE_MAX) {
8647        return;
8648    }
8649
8650    mpd_set_flags(result, srcsign);
8651    result->exp = 0;
8652    result->len = n;
8653    mpd_setdigits(result);
8654
8655    mpd_qresize(result, result->len, status);
8656    mpd_qfinalize(result, ctx, status);
8657}
8658
8659
8660/******************************************************************************/
8661/*                                From triple                                 */
8662/******************************************************************************/
8663
8664#if defined(CONFIG_64) && defined(__SIZEOF_INT128__)
8665static mpd_ssize_t
8666_set_coeff(uint64_t data[3], uint64_t hi, uint64_t lo)
8667{
8668    __uint128_t d = ((__uint128_t)hi << 64) + lo;
8669    __uint128_t q, r;
8670
8671    q = d / MPD_RADIX;
8672    r = d % MPD_RADIX;
8673    data[0] = (uint64_t)r;
8674    d = q;
8675
8676    q = d / MPD_RADIX;
8677    r = d % MPD_RADIX;
8678    data[1] = (uint64_t)r;
8679    d = q;
8680
8681    q = d / MPD_RADIX;
8682    r = d % MPD_RADIX;
8683    data[2] = (uint64_t)r;
8684
8685    if (q != 0) {
8686        abort(); /* GCOV_NOT_REACHED */
8687    }
8688
8689    return data[2] != 0 ? 3 : (data[1] != 0 ? 2 : 1);
8690}
8691#else
8692static size_t
8693_uint_from_u16(mpd_uint_t *w, mpd_ssize_t wlen, const uint16_t *u, size_t ulen)
8694{
8695    const mpd_uint_t ubase = 1U<<16;
8696    mpd_ssize_t n = 0;
8697    mpd_uint_t carry;
8698
8699    assert(wlen > 0 && ulen > 0);
8700
8701    w[n++] = u[--ulen];
8702    while (--ulen != SIZE_MAX) {
8703        carry = _mpd_shortmul_c(w, w, n, ubase);
8704        if (carry) {
8705            if (n >= wlen) {
8706                abort();  /* GCOV_NOT_REACHED */
8707            }
8708            w[n++] = carry;
8709        }
8710        carry = _mpd_shortadd(w, n, u[ulen]);
8711        if (carry) {
8712            if (n >= wlen) {
8713                abort();  /* GCOV_NOT_REACHED */
8714            }
8715            w[n++] = carry;
8716        }
8717    }
8718
8719    return n;
8720}
8721
8722static mpd_ssize_t
8723_set_coeff(mpd_uint_t *data, mpd_ssize_t len, uint64_t hi, uint64_t lo)
8724{
8725    uint16_t u16[8] = {0};
8726
8727    u16[7] = (uint16_t)((hi & 0xFFFF000000000000ULL) >> 48);
8728    u16[6] = (uint16_t)((hi & 0x0000FFFF00000000ULL) >> 32);
8729    u16[5] = (uint16_t)((hi & 0x00000000FFFF0000ULL) >> 16);
8730    u16[4] = (uint16_t) (hi & 0x000000000000FFFFULL);
8731
8732    u16[3] = (uint16_t)((lo & 0xFFFF000000000000ULL) >> 48);
8733    u16[2] = (uint16_t)((lo & 0x0000FFFF00000000ULL) >> 32);
8734    u16[1] = (uint16_t)((lo & 0x00000000FFFF0000ULL) >> 16);
8735    u16[0] = (uint16_t) (lo & 0x000000000000FFFFULL);
8736
8737    return (mpd_ssize_t)_uint_from_u16(data, len, u16, 8);
8738}
8739#endif
8740
8741static int
8742_set_uint128_coeff_exp(mpd_t *result, uint64_t hi, uint64_t lo, mpd_ssize_t exp)
8743{
8744    mpd_uint_t data[5] = {0};
8745    uint32_t status = 0;
8746    mpd_ssize_t len;
8747
8748#if defined(CONFIG_64) && defined(__SIZEOF_INT128__)
8749    len = _set_coeff(data, hi, lo);
8750#else
8751    len = _set_coeff(data, 5, hi, lo);
8752#endif
8753
8754    if (!mpd_qresize(result, len, &status)) {
8755        return -1;
8756    }
8757
8758    for (mpd_ssize_t i = 0; i < len; i++) {
8759        result->data[i] = data[i];
8760    }
8761
8762    result->exp = exp;
8763    result->len = len;
8764    mpd_setdigits(result);
8765
8766    return 0;
8767}
8768
8769int
8770mpd_from_uint128_triple(mpd_t *result, const mpd_uint128_triple_t *triple, uint32_t *status)
8771{
8772    static const mpd_context_t maxcontext = {
8773     .prec=MPD_MAX_PREC,
8774     .emax=MPD_MAX_EMAX,
8775     .emin=MPD_MIN_EMIN,
8776     .round=MPD_ROUND_HALF_EVEN,
8777     .traps=MPD_Traps,
8778     .status=0,
8779     .newtrap=0,
8780     .clamp=0,
8781     .allcr=1,
8782    };
8783    const enum mpd_triple_class tag = triple->tag;
8784    const uint8_t sign = triple->sign;
8785    const uint64_t hi = triple->hi;
8786    const uint64_t lo = triple->lo;
8787    mpd_ssize_t exp;
8788
8789#ifdef CONFIG_32
8790    if (triple->exp < MPD_SSIZE_MIN || triple->exp > MPD_SSIZE_MAX) {
8791        goto conversion_error;
8792    }
8793#endif
8794    exp = (mpd_ssize_t)triple->exp;
8795
8796    switch (tag) {
8797    case MPD_TRIPLE_QNAN: case MPD_TRIPLE_SNAN: {
8798        if (sign > 1 || exp != 0) {
8799            goto conversion_error;
8800        }
8801
8802        const uint8_t flags = tag == MPD_TRIPLE_QNAN ? MPD_NAN : MPD_SNAN;
8803        mpd_setspecial(result, sign, flags);
8804
8805        if (hi == 0 && lo == 0) {  /* no payload */
8806            return 0;
8807        }
8808
8809        if (_set_uint128_coeff_exp(result, hi, lo, exp) < 0) {
8810            goto malloc_error;
8811        }
8812
8813        return 0;
8814    }
8815
8816    case MPD_TRIPLE_INF: {
8817        if (sign > 1 || hi != 0 || lo != 0 || exp != 0) {
8818            goto conversion_error;
8819        }
8820
8821        mpd_setspecial(result, sign, MPD_INF);
8822
8823        return 0;
8824    }
8825
8826    case MPD_TRIPLE_NORMAL: {
8827        if (sign > 1) {
8828            goto conversion_error;
8829        }
8830
8831        const uint8_t flags = sign ? MPD_NEG : MPD_POS;
8832        mpd_set_flags(result, flags);
8833
8834        if (exp > MPD_EXP_INF) {
8835            exp = MPD_EXP_INF;
8836        }
8837        if (exp == MPD_SSIZE_MIN) {
8838            exp = MPD_SSIZE_MIN+1;
8839        }
8840
8841        if (_set_uint128_coeff_exp(result, hi, lo, exp) < 0) {
8842            goto malloc_error;
8843        }
8844
8845        uint32_t workstatus = 0;
8846        mpd_qfinalize(result, &maxcontext, &workstatus);
8847        if (workstatus & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
8848            goto conversion_error;
8849        }
8850
8851        return 0;
8852    }
8853
8854    default:
8855        goto conversion_error;
8856    }
8857
8858conversion_error:
8859    mpd_seterror(result, MPD_Conversion_syntax, status);
8860    return -1;
8861
8862malloc_error:
8863    mpd_seterror(result, MPD_Malloc_error, status);
8864    return -1;
8865}
8866
8867
8868/******************************************************************************/
8869/*                                  As triple                                 */
8870/******************************************************************************/
8871
8872#if defined(CONFIG_64) && defined(__SIZEOF_INT128__)
8873static void
8874_get_coeff(uint64_t *hi, uint64_t *lo, const mpd_t *a)
8875{
8876    __uint128_t u128 = 0;
8877
8878    switch (a->len) {
8879    case 3:
8880        u128 = a->data[2]; /* fall through */
8881    case 2:
8882        u128 = u128 * MPD_RADIX + a->data[1]; /* fall through */
8883    case 1:
8884        u128 = u128 * MPD_RADIX + a->data[0];
8885        break;
8886    default:
8887        abort(); /* GCOV_NOT_REACHED */
8888    }
8889
8890    *hi = u128 >> 64;
8891    *lo = (uint64_t)u128;
8892}
8893#else
8894static size_t
8895_uint_to_u16(uint16_t w[8], mpd_uint_t *u, mpd_ssize_t ulen)
8896{
8897    const mpd_uint_t wbase = 1U<<16;
8898    size_t n = 0;
8899
8900    assert(ulen > 0);
8901
8902    do {
8903        if (n >= 8) {
8904            abort();  /* GCOV_NOT_REACHED */
8905        }
8906        w[n++] = (uint16_t)_mpd_shortdiv(u, u, ulen, wbase);
8907        /* ulen is at least 1. u[ulen-1] can only be zero if ulen == 1. */
8908        ulen = _mpd_real_size(u, ulen);
8909
8910    } while (u[ulen-1] != 0);
8911
8912    return n;
8913}
8914
8915static void
8916_get_coeff(uint64_t *hi, uint64_t *lo, const mpd_t *a)
8917{
8918    uint16_t u16[8] = {0};
8919    mpd_uint_t data[5] = {0};
8920
8921    switch (a->len) {
8922    case 5:
8923        data[4] = a->data[4]; /* fall through */
8924    case 4:
8925        data[3] = a->data[3]; /* fall through */
8926    case 3:
8927        data[2] = a->data[2]; /* fall through */
8928    case 2:
8929        data[1] = a->data[1]; /* fall through */
8930    case 1:
8931        data[0] = a->data[0];
8932        break;
8933    default:
8934        abort();  /* GCOV_NOT_REACHED */
8935    }
8936
8937    _uint_to_u16(u16, data, a->len);
8938
8939    *hi = (uint64_t)u16[7] << 48;
8940    *hi |= (uint64_t)u16[6] << 32;
8941    *hi |= (uint64_t)u16[5] << 16;
8942    *hi |= (uint64_t)u16[4];
8943
8944    *lo = (uint64_t)u16[3] << 48;
8945    *lo |= (uint64_t)u16[2] << 32;
8946    *lo |= (uint64_t)u16[1] << 16;
8947    *lo |= (uint64_t)u16[0];
8948}
8949#endif
8950
8951static enum mpd_triple_class
8952_coeff_as_uint128(uint64_t *hi, uint64_t *lo, const mpd_t *a)
8953{
8954#ifdef CONFIG_64
8955    static mpd_uint_t uint128_max_data[3] = { 3374607431768211455ULL, 4028236692093846346ULL, 3ULL };
8956    static const mpd_t uint128_max = { MPD_STATIC|MPD_CONST_DATA, 0, 39, 3, 3, uint128_max_data };
8957#else
8958    static mpd_uint_t uint128_max_data[5] = { 768211455U, 374607431U, 938463463U, 282366920U, 340U };
8959    static const mpd_t uint128_max = { MPD_STATIC|MPD_CONST_DATA, 0, 39, 5, 5, uint128_max_data };
8960#endif
8961    enum mpd_triple_class ret = MPD_TRIPLE_NORMAL;
8962    uint32_t status = 0;
8963    mpd_t coeff;
8964
8965    *hi = *lo = 0ULL;
8966
8967    if (mpd_isspecial(a)) {
8968        if (mpd_isinfinite(a)) {
8969            return MPD_TRIPLE_INF;
8970        }
8971
8972        ret = mpd_isqnan(a) ? MPD_TRIPLE_QNAN : MPD_TRIPLE_SNAN;
8973        if (a->len == 0) { /* no payload */
8974            return ret;
8975        }
8976    }
8977    else if (mpd_iszero(a)) {
8978        return ret;
8979    }
8980
8981    _mpd_copy_shared(&coeff, a);
8982    mpd_set_flags(&coeff, 0);
8983    coeff.exp = 0;
8984
8985    if (mpd_qcmp(&coeff, &uint128_max, &status) > 0) {
8986        return MPD_TRIPLE_ERROR;
8987    }
8988
8989    _get_coeff(hi, lo, &coeff);
8990    return ret;
8991}
8992
8993mpd_uint128_triple_t
8994mpd_as_uint128_triple(const mpd_t *a)
8995{
8996    mpd_uint128_triple_t triple = { MPD_TRIPLE_ERROR, 0, 0, 0, 0 };
8997
8998    triple.tag = _coeff_as_uint128(&triple.hi, &triple.lo, a);
8999    if (triple.tag == MPD_TRIPLE_ERROR) {
9000        return triple;
9001    }
9002
9003    triple.sign = !!mpd_isnegative(a);
9004    if (triple.tag == MPD_TRIPLE_NORMAL) {
9005        triple.exp = a->exp;
9006    }
9007
9008    return triple;
9009}
9010