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