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