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