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