Coverage Report

Created: 2024-11-21 07:03

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