intl/icu/source/i18n/decNumber.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/intl/icu/source/i18n/decNumber.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,8184 @@
     1.4 +/* ------------------------------------------------------------------ */
     1.5 +/* Decimal Number arithmetic module                                   */
     1.6 +/* ------------------------------------------------------------------ */
     1.7 +/* Copyright (c) IBM Corporation, 2000-2012.  All rights reserved.    */
     1.8 +/*                                                                    */
     1.9 +/* This software is made available under the terms of the             */
    1.10 +/* ICU License -- ICU 1.8.1 and later.                                */
    1.11 +/*                                                                    */
    1.12 +/* The description and User's Guide ("The decNumber C Library") for   */
    1.13 +/* this software is called decNumber.pdf.  This document is           */
    1.14 +/* available, together with arithmetic and format specifications,     */
    1.15 +/* testcases, and Web links, on the General Decimal Arithmetic page.  */
    1.16 +/*                                                                    */
    1.17 +/* Please send comments, suggestions, and corrections to the author:  */
    1.18 +/*   mfc@uk.ibm.com                                                   */
    1.19 +/*   Mike Cowlishaw, IBM Fellow                                       */
    1.20 +/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
    1.21 +/* ------------------------------------------------------------------ */
    1.22 +
    1.23 +/* Modified version, for use from within ICU.
    1.24 + *    Renamed public functions, to avoid an unwanted export of the 
    1.25 + *    standard names from the ICU library.
    1.26 + *
    1.27 + *    Use ICU's uprv_malloc() and uprv_free()
    1.28 + *
    1.29 + *    Revert comment syntax to plain C
    1.30 + *
    1.31 + *    Remove a few compiler warnings.
    1.32 + */
    1.33 +
    1.34 +/* This module comprises the routines for arbitrary-precision General */
    1.35 +/* Decimal Arithmetic as defined in the specification which may be    */
    1.36 +/* found on the General Decimal Arithmetic pages.  It implements both */
    1.37 +/* the full ('extended') arithmetic and the simpler ('subset')        */
    1.38 +/* arithmetic.                                                        */
    1.39 +/*                                                                    */
    1.40 +/* Usage notes:                                                       */
    1.41 +/*                                                                    */
    1.42 +/* 1. This code is ANSI C89 except:                                   */
    1.43 +/*                                                                    */
    1.44 +/*    a) C99 line comments (double forward slash) are used.  (Most C  */
    1.45 +/*       compilers accept these.  If yours does not, a simple script  */
    1.46 +/*       can be used to convert them to ANSI C comments.)             */
    1.47 +/*                                                                    */
    1.48 +/*    b) Types from C99 stdint.h are used.  If you do not have this   */
    1.49 +/*       header file, see the User's Guide section of the decNumber   */
    1.50 +/*       documentation; this lists the necessary definitions.         */
    1.51 +/*                                                                    */
    1.52 +/*    c) If DECDPUN>4 or DECUSE64=1, the C99 64-bit int64_t and       */
    1.53 +/*       uint64_t types may be used.  To avoid these, set DECUSE64=0  */
    1.54 +/*       and DECDPUN<=4 (see documentation).                          */
    1.55 +/*                                                                    */
    1.56 +/*    The code also conforms to C99 restrictions; in particular,      */
    1.57 +/*    strict aliasing rules are observed.                             */
    1.58 +/*                                                                    */
    1.59 +/* 2. The decNumber format which this library uses is optimized for   */
    1.60 +/*    efficient processing of relatively short numbers; in particular */
    1.61 +/*    it allows the use of fixed sized structures and minimizes copy  */
    1.62 +/*    and move operations.  It does, however, support arbitrary       */
    1.63 +/*    precision (up to 999,999,999 digits) and arbitrary exponent     */
    1.64 +/*    range (Emax in the range 0 through 999,999,999 and Emin in the  */
    1.65 +/*    range -999,999,999 through 0).  Mathematical functions (for     */
    1.66 +/*    example decNumberExp) as identified below are restricted more   */
    1.67 +/*    tightly: digits, emax, and -emin in the context must be <=      */
    1.68 +/*    DEC_MAX_MATH (999999), and their operand(s) must be within      */
    1.69 +/*    these bounds.                                                   */
    1.70 +/*                                                                    */
    1.71 +/* 3. Logical functions are further restricted; their operands must   */
    1.72 +/*    be finite, positive, have an exponent of zero, and all digits   */
    1.73 +/*    must be either 0 or 1.  The result will only contain digits     */
    1.74 +/*    which are 0 or 1 (and will have exponent=0 and a sign of 0).    */
    1.75 +/*                                                                    */
    1.76 +/* 4. Operands to operator functions are never modified unless they   */
    1.77 +/*    are also specified to be the result number (which is always     */
    1.78 +/*    permitted).  Other than that case, operands must not overlap.   */
    1.79 +/*                                                                    */
    1.80 +/* 5. Error handling: the type of the error is ORed into the status   */
    1.81 +/*    flags in the current context (decContext structure).  The       */
    1.82 +/*    SIGFPE signal is then raised if the corresponding trap-enabler  */
    1.83 +/*    flag in the decContext is set (is 1).                           */
    1.84 +/*                                                                    */
    1.85 +/*    It is the responsibility of the caller to clear the status      */
    1.86 +/*    flags as required.                                              */
    1.87 +/*                                                                    */
    1.88 +/*    The result of any routine which returns a number will always    */
    1.89 +/*    be a valid number (which may be a special value, such as an     */
    1.90 +/*    Infinity or NaN).                                               */
    1.91 +/*                                                                    */
    1.92 +/* 6. The decNumber format is not an exchangeable concrete            */
    1.93 +/*    representation as it comprises fields which may be machine-     */
    1.94 +/*    dependent (packed or unpacked, or special length, for example). */
    1.95 +/*    Canonical conversions to and from strings are provided; other   */
    1.96 +/*    conversions are available in separate modules.                  */
    1.97 +/*                                                                    */
    1.98 +/* 7. Normally, input operands are assumed to be valid.  Set DECCHECK */
    1.99 +/*    to 1 for extended operand checking (including NULL operands).   */
   1.100 +/*    Results are undefined if a badly-formed structure (or a NULL    */
   1.101 +/*    pointer to a structure) is provided, though with DECCHECK       */
   1.102 +/*    enabled the operator routines are protected against exceptions. */
   1.103 +/*    (Except if the result pointer is NULL, which is unrecoverable.) */
   1.104 +/*                                                                    */
   1.105 +/*    However, the routines will never cause exceptions if they are   */
   1.106 +/*    given well-formed operands, even if the value of the operands   */
   1.107 +/*    is inappropriate for the operation and DECCHECK is not set.     */
   1.108 +/*    (Except for SIGFPE, as and where documented.)                   */
   1.109 +/*                                                                    */
   1.110 +/* 8. Subset arithmetic is available only if DECSUBSET is set to 1.   */
   1.111 +/* ------------------------------------------------------------------ */
   1.112 +/* Implementation notes for maintenance of this module:               */
   1.113 +/*                                                                    */
   1.114 +/* 1. Storage leak protection:  Routines which use malloc are not     */
   1.115 +/*    permitted to use return for fastpath or error exits (i.e.,      */
   1.116 +/*    they follow strict structured programming conventions).         */
   1.117 +/*    Instead they have a do{}while(0); construct surrounding the     */
   1.118 +/*    code which is protected -- break may be used to exit this.      */
   1.119 +/*    Other routines can safely use the return statement inline.      */
   1.120 +/*                                                                    */
   1.121 +/*    Storage leak accounting can be enabled using DECALLOC.          */
   1.122 +/*                                                                    */
   1.123 +/* 2. All loops use the for(;;) construct.  Any do construct does     */
   1.124 +/*    not loop; it is for allocation protection as just described.    */
   1.125 +/*                                                                    */
   1.126 +/* 3. Setting status in the context must always be the very last      */
   1.127 +/*    action in a routine, as non-0 status may raise a trap and hence */
   1.128 +/*    the call to set status may not return (if the handler uses long */
   1.129 +/*    jump).  Therefore all cleanup must be done first.  In general,  */
   1.130 +/*    to achieve this status is accumulated and is only applied just  */
   1.131 +/*    before return by calling decContextSetStatus (via decStatus).   */
   1.132 +/*                                                                    */
   1.133 +/*    Routines which allocate storage cannot, in general, use the     */
   1.134 +/*    'top level' routines which could cause a non-returning          */
   1.135 +/*    transfer of control.  The decXxxxOp routines are safe (do not   */
   1.136 +/*    call decStatus even if traps are set in the context) and should */
   1.137 +/*    be used instead (they are also a little faster).                */
   1.138 +/*                                                                    */
   1.139 +/* 4. Exponent checking is minimized by allowing the exponent to      */
   1.140 +/*    grow outside its limits during calculations, provided that      */
   1.141 +/*    the decFinalize function is called later.  Multiplication and   */
   1.142 +/*    division, and intermediate calculations in exponentiation,      */
   1.143 +/*    require more careful checks because of the risk of 31-bit       */
   1.144 +/*    overflow (the most negative valid exponent is -1999999997, for  */
   1.145 +/*    a 999999999-digit number with adjusted exponent of -999999999). */
   1.146 +/*                                                                    */
   1.147 +/* 5. Rounding is deferred until finalization of results, with any    */
   1.148 +/*    'off to the right' data being represented as a single digit     */
   1.149 +/*    residue (in the range -1 through 9).  This avoids any double-   */
   1.150 +/*    rounding when more than one shortening takes place (for         */
   1.151 +/*    example, when a result is subnormal).                           */
   1.152 +/*                                                                    */
   1.153 +/* 6. The digits count is allowed to rise to a multiple of DECDPUN    */
   1.154 +/*    during many operations, so whole Units are handled and exact    */
   1.155 +/*    accounting of digits is not needed.  The correct digits value   */
   1.156 +/*    is found by decGetDigits, which accounts for leading zeros.     */
   1.157 +/*    This must be called before any rounding if the number of digits */
   1.158 +/*    is not known exactly.                                           */
   1.159 +/*                                                                    */
   1.160 +/* 7. The multiply-by-reciprocal 'trick' is used for partitioning     */
   1.161 +/*    numbers up to four digits, using appropriate constants.  This   */
   1.162 +/*    is not useful for longer numbers because overflow of 32 bits    */
   1.163 +/*    would lead to 4 multiplies, which is almost as expensive as     */
   1.164 +/*    a divide (unless a floating-point or 64-bit multiply is         */
   1.165 +/*    assumed to be available).                                       */
   1.166 +/*                                                                    */
   1.167 +/* 8. Unusual abbreviations that may be used in the commentary:       */
   1.168 +/*      lhs -- left hand side (operand, of an operation)              */
   1.169 +/*      lsd -- least significant digit (of coefficient)               */
   1.170 +/*      lsu -- least significant Unit (of coefficient)                */
   1.171 +/*      msd -- most significant digit (of coefficient)                */
   1.172 +/*      msi -- most significant item (in an array)                    */
   1.173 +/*      msu -- most significant Unit (of coefficient)                 */
   1.174 +/*      rhs -- right hand side (operand, of an operation)             */
   1.175 +/*      +ve -- positive                                               */
   1.176 +/*      -ve -- negative                                               */
   1.177 +/*      **  -- raise to the power                                     */
   1.178 +/* ------------------------------------------------------------------ */
   1.179 +
   1.180 +#include <stdlib.h>                /* for malloc, free, etc.  */
   1.181 +/*  #include <stdio.h>   */        /* for printf [if needed]  */
   1.182 +#include <string.h>                /* for strcpy  */
   1.183 +#include <ctype.h>                 /* for lower  */
   1.184 +#include "cmemory.h"               /* for uprv_malloc, etc., in ICU */
   1.185 +#include "decNumber.h"             /* base number library  */
   1.186 +#include "decNumberLocal.h"        /* decNumber local types, etc.  */
   1.187 +#include "uassert.h"
   1.188 +
   1.189 +/* Constants */
   1.190 +/* Public lookup table used by the D2U macro  */
   1.191 +static const uByte d2utable[DECMAXD2U+1]=D2UTABLE;
   1.192 +
   1.193 +#define DECVERB     1              /* set to 1 for verbose DECCHECK  */
   1.194 +#define powers      DECPOWERS      /* old internal name  */
   1.195 +
   1.196 +/* Local constants  */
   1.197 +#define DIVIDE      0x80           /* Divide operators  */
   1.198 +#define REMAINDER   0x40           /* ..  */
   1.199 +#define DIVIDEINT   0x20           /* ..  */
   1.200 +#define REMNEAR     0x10           /* ..  */
   1.201 +#define COMPARE     0x01           /* Compare operators  */
   1.202 +#define COMPMAX     0x02           /* ..  */
   1.203 +#define COMPMIN     0x03           /* ..  */
   1.204 +#define COMPTOTAL   0x04           /* ..  */
   1.205 +#define COMPNAN     0x05           /* .. [NaN processing]  */
   1.206 +#define COMPSIG     0x06           /* .. [signaling COMPARE]  */
   1.207 +#define COMPMAXMAG  0x07           /* ..  */
   1.208 +#define COMPMINMAG  0x08           /* ..  */
   1.209 +
   1.210 +#define DEC_sNaN     0x40000000    /* local status: sNaN signal  */
   1.211 +#define BADINT  (Int)0x80000000    /* most-negative Int; error indicator  */
   1.212 +/* Next two indicate an integer >= 10**6, and its parity (bottom bit)  */
   1.213 +#define BIGEVEN (Int)0x80000002
   1.214 +#define BIGODD  (Int)0x80000003
   1.215 +
   1.216 +static const Unit uarrone[1]={1};   /* Unit array of 1, used for incrementing  */
   1.217 +
   1.218 +/* ------------------------------------------------------------------ */
   1.219 +/* round-for-reround digits                                           */
   1.220 +/* ------------------------------------------------------------------ */
   1.221 +static const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
   1.222 +
   1.223 +/* ------------------------------------------------------------------ */
   1.224 +/* Powers of ten (powers[n]==10**n, 0<=n<=9)                          */
   1.225 +/* ------------------------------------------------------------------ */
   1.226 +static const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
   1.227 +                          10000000, 100000000, 1000000000};
   1.228 +
   1.229 +
   1.230 +/* Granularity-dependent code */
   1.231 +#if DECDPUN<=4
   1.232 +  #define eInt  Int           /* extended integer  */
   1.233 +  #define ueInt uInt          /* unsigned extended integer  */
   1.234 +  /* Constant multipliers for divide-by-power-of five using reciprocal  */
   1.235 +  /* multiply, after removing powers of 2 by shifting, and final shift  */
   1.236 +  /* of 17 [we only need up to **4]  */
   1.237 +  static const uInt multies[]={131073, 26215, 5243, 1049, 210};
   1.238 +  /* QUOT10 -- macro to return the quotient of unit u divided by 10**n  */
   1.239 +  #define QUOT10(u, n) ((((uInt)(u)>>(n))*multies[n])>>17)
   1.240 +#else
   1.241 +  /* For DECDPUN>4 non-ANSI-89 64-bit types are needed.  */
   1.242 +  #if !DECUSE64
   1.243 +    #error decNumber.c: DECUSE64 must be 1 when DECDPUN>4
   1.244 +  #endif
   1.245 +  #define eInt  Long          /* extended integer  */
   1.246 +  #define ueInt uLong         /* unsigned extended integer  */
   1.247 +#endif
   1.248 +
   1.249 +/* Local routines */
   1.250 +static decNumber * decAddOp(decNumber *, const decNumber *, const decNumber *,
   1.251 +                              decContext *, uByte, uInt *);
   1.252 +static Flag        decBiStr(const char *, const char *, const char *);
   1.253 +static uInt        decCheckMath(const decNumber *, decContext *, uInt *);
   1.254 +static void        decApplyRound(decNumber *, decContext *, Int, uInt *);
   1.255 +static Int         decCompare(const decNumber *lhs, const decNumber *rhs, Flag);
   1.256 +static decNumber * decCompareOp(decNumber *, const decNumber *,
   1.257 +                              const decNumber *, decContext *,
   1.258 +                              Flag, uInt *);
   1.259 +static void        decCopyFit(decNumber *, const decNumber *, decContext *,
   1.260 +                              Int *, uInt *);
   1.261 +static decNumber * decDecap(decNumber *, Int);
   1.262 +static decNumber * decDivideOp(decNumber *, const decNumber *,
   1.263 +                              const decNumber *, decContext *, Flag, uInt *);
   1.264 +static decNumber * decExpOp(decNumber *, const decNumber *,
   1.265 +                              decContext *, uInt *);
   1.266 +static void        decFinalize(decNumber *, decContext *, Int *, uInt *);
   1.267 +static Int         decGetDigits(Unit *, Int);
   1.268 +static Int         decGetInt(const decNumber *);
   1.269 +static decNumber * decLnOp(decNumber *, const decNumber *,
   1.270 +                              decContext *, uInt *);
   1.271 +static decNumber * decMultiplyOp(decNumber *, const decNumber *,
   1.272 +                              const decNumber *, decContext *,
   1.273 +                              uInt *);
   1.274 +static decNumber * decNaNs(decNumber *, const decNumber *,
   1.275 +                              const decNumber *, decContext *, uInt *);
   1.276 +static decNumber * decQuantizeOp(decNumber *, const decNumber *,
   1.277 +                              const decNumber *, decContext *, Flag,
   1.278 +                              uInt *);
   1.279 +static void        decReverse(Unit *, Unit *);
   1.280 +static void        decSetCoeff(decNumber *, decContext *, const Unit *,
   1.281 +                              Int, Int *, uInt *);
   1.282 +static void        decSetMaxValue(decNumber *, decContext *);
   1.283 +static void        decSetOverflow(decNumber *, decContext *, uInt *);
   1.284 +static void        decSetSubnormal(decNumber *, decContext *, Int *, uInt *);
   1.285 +static Int         decShiftToLeast(Unit *, Int, Int);
   1.286 +static Int         decShiftToMost(Unit *, Int, Int);
   1.287 +static void        decStatus(decNumber *, uInt, decContext *);
   1.288 +static void        decToString(const decNumber *, char[], Flag);
   1.289 +static decNumber * decTrim(decNumber *, decContext *, Flag, Flag, Int *);
   1.290 +static Int         decUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
   1.291 +                              Unit *, Int);
   1.292 +static Int         decUnitCompare(const Unit *, Int, const Unit *, Int, Int);
   1.293 +
   1.294 +#if !DECSUBSET
   1.295 +/* decFinish == decFinalize when no subset arithmetic needed */
   1.296 +#define decFinish(a,b,c,d) decFinalize(a,b,c,d)
   1.297 +#else
   1.298 +static void        decFinish(decNumber *, decContext *, Int *, uInt *);
   1.299 +static decNumber * decRoundOperand(const decNumber *, decContext *, uInt *);
   1.300 +#endif
   1.301 +
   1.302 +/* Local macros */
   1.303 +/* masked special-values bits  */
   1.304 +#define SPECIALARG  (rhs->bits & DECSPECIAL)
   1.305 +#define SPECIALARGS ((lhs->bits | rhs->bits) & DECSPECIAL)
   1.306 +
   1.307 +/* For use in ICU */
   1.308 +#define malloc(a) uprv_malloc(a)
   1.309 +#define free(a) uprv_free(a)
   1.310 +
   1.311 +/* Diagnostic macros, etc. */
   1.312 +#if DECALLOC
   1.313 +/* Handle malloc/free accounting.  If enabled, our accountable routines  */
   1.314 +/* are used; otherwise the code just goes straight to the system malloc  */
   1.315 +/* and free routines.  */
   1.316 +#define malloc(a) decMalloc(a)
   1.317 +#define free(a) decFree(a)
   1.318 +#define DECFENCE 0x5a              /* corruption detector  */
   1.319 +/* 'Our' malloc and free:  */
   1.320 +static void *decMalloc(size_t);
   1.321 +static void  decFree(void *);
   1.322 +uInt decAllocBytes=0;              /* count of bytes allocated  */
   1.323 +/* Note that DECALLOC code only checks for storage buffer overflow.  */
   1.324 +/* To check for memory leaks, the decAllocBytes variable must be  */
   1.325 +/* checked to be 0 at appropriate times (e.g., after the test  */
   1.326 +/* harness completes a set of tests).  This checking may be unreliable  */
   1.327 +/* if the testing is done in a multi-thread environment.  */
   1.328 +#endif
   1.329 +
   1.330 +#if DECCHECK
   1.331 +/* Optional checking routines.  Enabling these means that decNumber  */
   1.332 +/* and decContext operands to operator routines are checked for  */
   1.333 +/* correctness.  This roughly doubles the execution time of the  */
   1.334 +/* fastest routines (and adds 600+ bytes), so should not normally be  */
   1.335 +/* used in 'production'.  */
   1.336 +/* decCheckInexact is used to check that inexact results have a full  */
   1.337 +/* complement of digits (where appropriate -- this is not the case  */
   1.338 +/* for Quantize, for example)  */
   1.339 +#define DECUNRESU ((decNumber *)(void *)0xffffffff)
   1.340 +#define DECUNUSED ((const decNumber *)(void *)0xffffffff)
   1.341 +#define DECUNCONT ((decContext *)(void *)(0xffffffff))
   1.342 +static Flag decCheckOperands(decNumber *, const decNumber *,
   1.343 +                             const decNumber *, decContext *);
   1.344 +static Flag decCheckNumber(const decNumber *);
   1.345 +static void decCheckInexact(const decNumber *, decContext *);
   1.346 +#endif
   1.347 +
   1.348 +#if DECTRACE || DECCHECK
   1.349 +/* Optional trace/debugging routines (may or may not be used)  */
   1.350 +void decNumberShow(const decNumber *);  /* displays the components of a number  */
   1.351 +static void decDumpAr(char, const Unit *, Int);
   1.352 +#endif
   1.353 +
   1.354 +/* ================================================================== */
   1.355 +/* Conversions                                                        */
   1.356 +/* ================================================================== */
   1.357 +
   1.358 +/* ------------------------------------------------------------------ */
   1.359 +/* from-int32 -- conversion from Int or uInt                          */
   1.360 +/*                                                                    */
   1.361 +/*  dn is the decNumber to receive the integer                        */
   1.362 +/*  in or uin is the integer to be converted                          */
   1.363 +/*  returns dn                                                        */
   1.364 +/*                                                                    */
   1.365 +/* No error is possible.                                              */
   1.366 +/* ------------------------------------------------------------------ */
   1.367 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberFromInt32(decNumber *dn, Int in) {
   1.368 +  uInt unsig;
   1.369 +  if (in>=0) unsig=in;
   1.370 +   else {                               /* negative (possibly BADINT)  */
   1.371 +    if (in==BADINT) unsig=(uInt)1073741824*2; /* special case  */
   1.372 +     else unsig=-in;                    /* invert  */
   1.373 +    }
   1.374 +  /* in is now positive  */
   1.375 +  uprv_decNumberFromUInt32(dn, unsig);
   1.376 +  if (in<0) dn->bits=DECNEG;            /* sign needed  */
   1.377 +  return dn;
   1.378 +  } /* decNumberFromInt32  */
   1.379 +
   1.380 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberFromUInt32(decNumber *dn, uInt uin) {
   1.381 +  Unit *up;                             /* work pointer  */
   1.382 +  uprv_decNumberZero(dn);                    /* clean  */
   1.383 +  if (uin==0) return dn;                /* [or decGetDigits bad call]  */
   1.384 +  for (up=dn->lsu; uin>0; up++) {
   1.385 +    *up=(Unit)(uin%(DECDPUNMAX+1));
   1.386 +    uin=uin/(DECDPUNMAX+1);
   1.387 +    }
   1.388 +  dn->digits=decGetDigits(dn->lsu, up-dn->lsu);
   1.389 +  return dn;
   1.390 +  } /* decNumberFromUInt32  */
   1.391 +
   1.392 +/* ------------------------------------------------------------------ */
   1.393 +/* to-int32 -- conversion to Int or uInt                              */
   1.394 +/*                                                                    */
   1.395 +/*  dn is the decNumber to convert                                    */
   1.396 +/*  set is the context for reporting errors                           */
   1.397 +/*  returns the converted decNumber, or 0 if Invalid is set           */
   1.398 +/*                                                                    */
   1.399 +/* Invalid is set if the decNumber does not have exponent==0 or if    */
   1.400 +/* it is a NaN, Infinite, or out-of-range.                            */
   1.401 +/* ------------------------------------------------------------------ */
   1.402 +U_CAPI Int U_EXPORT2 uprv_decNumberToInt32(const decNumber *dn, decContext *set) {
   1.403 +  #if DECCHECK
   1.404 +  if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
   1.405 +  #endif
   1.406 +
   1.407 +  /* special or too many digits, or bad exponent  */
   1.408 +  if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0) ; /* bad  */
   1.409 +   else { /* is a finite integer with 10 or fewer digits  */
   1.410 +    Int d;                         /* work  */
   1.411 +    const Unit *up;                /* ..  */
   1.412 +    uInt hi=0, lo;                 /* ..  */
   1.413 +    up=dn->lsu;                    /* -> lsu  */
   1.414 +    lo=*up;                        /* get 1 to 9 digits  */
   1.415 +    #if DECDPUN>1                  /* split to higher  */
   1.416 +      hi=lo/10;
   1.417 +      lo=lo%10;
   1.418 +    #endif
   1.419 +    up++;
   1.420 +    /* collect remaining Units, if any, into hi  */
   1.421 +    for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];
   1.422 +    /* now low has the lsd, hi the remainder  */
   1.423 +    if (hi>214748364 || (hi==214748364 && lo>7)) { /* out of range?  */
   1.424 +      /* most-negative is a reprieve  */
   1.425 +      if (dn->bits&DECNEG && hi==214748364 && lo==8) return 0x80000000;
   1.426 +      /* bad -- drop through  */
   1.427 +      }
   1.428 +     else { /* in-range always  */
   1.429 +      Int i=X10(hi)+lo;
   1.430 +      if (dn->bits&DECNEG) return -i;
   1.431 +      return i;
   1.432 +      }
   1.433 +    } /* integer  */
   1.434 +  uprv_decContextSetStatus(set, DEC_Invalid_operation); /* [may not return]  */
   1.435 +  return 0;
   1.436 +  } /* decNumberToInt32  */
   1.437 +
   1.438 +U_CAPI uInt U_EXPORT2 uprv_decNumberToUInt32(const decNumber *dn, decContext *set) {
   1.439 +  #if DECCHECK
   1.440 +  if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
   1.441 +  #endif
   1.442 +  /* special or too many digits, or bad exponent, or negative (<0)  */
   1.443 +  if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0
   1.444 +    || (dn->bits&DECNEG && !ISZERO(dn)));                   /* bad  */
   1.445 +   else { /* is a finite integer with 10 or fewer digits  */
   1.446 +    Int d;                         /* work  */
   1.447 +    const Unit *up;                /* ..  */
   1.448 +    uInt hi=0, lo;                 /* ..  */
   1.449 +    up=dn->lsu;                    /* -> lsu  */
   1.450 +    lo=*up;                        /* get 1 to 9 digits  */
   1.451 +    #if DECDPUN>1                  /* split to higher  */
   1.452 +      hi=lo/10;
   1.453 +      lo=lo%10;
   1.454 +    #endif
   1.455 +    up++;
   1.456 +    /* collect remaining Units, if any, into hi  */
   1.457 +    for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];
   1.458 +
   1.459 +    /* now low has the lsd, hi the remainder  */
   1.460 +    if (hi>429496729 || (hi==429496729 && lo>5)) ; /* no reprieve possible  */
   1.461 +     else return X10(hi)+lo;
   1.462 +    } /* integer  */
   1.463 +  uprv_decContextSetStatus(set, DEC_Invalid_operation); /* [may not return]  */
   1.464 +  return 0;
   1.465 +  } /* decNumberToUInt32  */
   1.466 +
   1.467 +/* ------------------------------------------------------------------ */
   1.468 +/* to-scientific-string -- conversion to numeric string               */
   1.469 +/* to-engineering-string -- conversion to numeric string              */
   1.470 +/*                                                                    */
   1.471 +/*   decNumberToString(dn, string);                                   */
   1.472 +/*   decNumberToEngString(dn, string);                                */
   1.473 +/*                                                                    */
   1.474 +/*  dn is the decNumber to convert                                    */
   1.475 +/*  string is the string where the result will be laid out            */
   1.476 +/*                                                                    */
   1.477 +/*  string must be at least dn->digits+14 characters long             */
   1.478 +/*                                                                    */
   1.479 +/*  No error is possible, and no status can be set.                   */
   1.480 +/* ------------------------------------------------------------------ */
   1.481 +U_CAPI char * U_EXPORT2 uprv_decNumberToString(const decNumber *dn, char *string){
   1.482 +  decToString(dn, string, 0);
   1.483 +  return string;
   1.484 +  } /* DecNumberToString  */
   1.485 +
   1.486 +U_CAPI char * U_EXPORT2 uprv_decNumberToEngString(const decNumber *dn, char *string){
   1.487 +  decToString(dn, string, 1);
   1.488 +  return string;
   1.489 +  } /* DecNumberToEngString  */
   1.490 +
   1.491 +/* ------------------------------------------------------------------ */
   1.492 +/* to-number -- conversion from numeric string                        */
   1.493 +/*                                                                    */
   1.494 +/* decNumberFromString -- convert string to decNumber                 */
   1.495 +/*   dn        -- the number structure to fill                        */
   1.496 +/*   chars[]   -- the string to convert ('\0' terminated)             */
   1.497 +/*   set       -- the context used for processing any error,          */
   1.498 +/*                determining the maximum precision available         */
   1.499 +/*                (set.digits), determining the maximum and minimum   */
   1.500 +/*                exponent (set.emax and set.emin), determining if    */
   1.501 +/*                extended values are allowed, and checking the       */
   1.502 +/*                rounding mode if overflow occurs or rounding is     */
   1.503 +/*                needed.                                             */
   1.504 +/*                                                                    */
   1.505 +/* The length of the coefficient and the size of the exponent are     */
   1.506 +/* checked by this routine, so the correct error (Underflow or        */
   1.507 +/* Overflow) can be reported or rounding applied, as necessary.       */
   1.508 +/*                                                                    */
   1.509 +/* If bad syntax is detected, the result will be a quiet NaN.         */
   1.510 +/* ------------------------------------------------------------------ */
   1.511 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberFromString(decNumber *dn, const char chars[],
   1.512 +                                decContext *set) {
   1.513 +  Int   exponent=0;                /* working exponent [assume 0]  */
   1.514 +  uByte bits=0;                    /* working flags [assume +ve]  */
   1.515 +  Unit  *res;                      /* where result will be built  */
   1.516 +  Unit  resbuff[SD2U(DECBUFFER+9)];/* local buffer in case need temporary  */
   1.517 +                                   /* [+9 allows for ln() constants]  */
   1.518 +  Unit  *allocres=NULL;            /* -> allocated result, iff allocated  */
   1.519 +  Int   d=0;                       /* count of digits found in decimal part  */
   1.520 +  const char *dotchar=NULL;        /* where dot was found  */
   1.521 +  const char *cfirst=chars;        /* -> first character of decimal part  */
   1.522 +  const char *last=NULL;           /* -> last digit of decimal part  */
   1.523 +  const char *c;                   /* work  */
   1.524 +  Unit  *up;                       /* ..  */
   1.525 +  #if DECDPUN>1
   1.526 +  Int   cut, out;                  /* ..  */
   1.527 +  #endif
   1.528 +  Int   residue;                   /* rounding residue  */
   1.529 +  uInt  status=0;                  /* error code  */
   1.530 +
   1.531 +  #if DECCHECK
   1.532 +  if (decCheckOperands(DECUNRESU, DECUNUSED, DECUNUSED, set))
   1.533 +    return uprv_decNumberZero(dn);
   1.534 +  #endif
   1.535 +
   1.536 +  do {                             /* status & malloc protection  */
   1.537 +    for (c=chars;; c++) {          /* -> input character  */
   1.538 +      if (*c>='0' && *c<='9') {    /* test for Arabic digit  */
   1.539 +        last=c;
   1.540 +        d++;                       /* count of real digits  */
   1.541 +        continue;                  /* still in decimal part  */
   1.542 +        }
   1.543 +      if (*c=='.' && dotchar==NULL) { /* first '.'  */
   1.544 +        dotchar=c;                 /* record offset into decimal part  */
   1.545 +        if (c==cfirst) cfirst++;   /* first digit must follow  */
   1.546 +        continue;}
   1.547 +      if (c==chars) {              /* first in string...  */
   1.548 +        if (*c=='-') {             /* valid - sign  */
   1.549 +          cfirst++;
   1.550 +          bits=DECNEG;
   1.551 +          continue;}
   1.552 +        if (*c=='+') {             /* valid + sign  */
   1.553 +          cfirst++;
   1.554 +          continue;}
   1.555 +        }
   1.556 +      /* *c is not a digit, or a valid +, -, or '.'  */
   1.557 +      break;
   1.558 +      } /* c  */
   1.559 +
   1.560 +    if (last==NULL) {              /* no digits yet  */
   1.561 +      status=DEC_Conversion_syntax;/* assume the worst  */
   1.562 +      if (*c=='\0') break;         /* and no more to come...  */
   1.563 +      #if DECSUBSET
   1.564 +      /* if subset then infinities and NaNs are not allowed  */
   1.565 +      if (!set->extended) break;   /* hopeless  */
   1.566 +      #endif
   1.567 +      /* Infinities and NaNs are possible, here  */
   1.568 +      if (dotchar!=NULL) break;    /* .. unless had a dot  */
   1.569 +      uprv_decNumberZero(dn);           /* be optimistic  */
   1.570 +      if (decBiStr(c, "infinity", "INFINITY")
   1.571 +       || decBiStr(c, "inf", "INF")) {
   1.572 +        dn->bits=bits | DECINF;
   1.573 +        status=0;                  /* is OK  */
   1.574 +        break; /* all done  */
   1.575 +        }
   1.576 +      /* a NaN expected  */
   1.577 +      /* 2003.09.10 NaNs are now permitted to have a sign  */
   1.578 +      dn->bits=bits | DECNAN;      /* assume simple NaN  */
   1.579 +      if (*c=='s' || *c=='S') {    /* looks like an sNaN  */
   1.580 +        c++;
   1.581 +        dn->bits=bits | DECSNAN;
   1.582 +        }
   1.583 +      if (*c!='n' && *c!='N') break;    /* check caseless "NaN"  */
   1.584 +      c++;
   1.585 +      if (*c!='a' && *c!='A') break;    /* ..  */
   1.586 +      c++;
   1.587 +      if (*c!='n' && *c!='N') break;    /* ..  */
   1.588 +      c++;
   1.589 +      /* now either nothing, or nnnn payload, expected  */
   1.590 +      /* -> start of integer and skip leading 0s [including plain 0]  */
   1.591 +      for (cfirst=c; *cfirst=='0';) cfirst++;
   1.592 +      if (*cfirst=='\0') {         /* "NaN" or "sNaN", maybe with all 0s  */
   1.593 +        status=0;                  /* it's good  */
   1.594 +        break;                     /* ..  */
   1.595 +        }
   1.596 +      /* something other than 0s; setup last and d as usual [no dots]  */
   1.597 +      for (c=cfirst;; c++, d++) {
   1.598 +        if (*c<'0' || *c>'9') break; /* test for Arabic digit  */
   1.599 +        last=c;
   1.600 +        }
   1.601 +      if (*c!='\0') break;         /* not all digits  */
   1.602 +      if (d>set->digits-1) {
   1.603 +        /* [NB: payload in a decNumber can be full length unless  */
   1.604 +        /* clamped, in which case can only be digits-1]  */
   1.605 +        if (set->clamp) break;
   1.606 +        if (d>set->digits) break;
   1.607 +        } /* too many digits?  */
   1.608 +      /* good; drop through to convert the integer to coefficient  */
   1.609 +      status=0;                    /* syntax is OK  */
   1.610 +      bits=dn->bits;               /* for copy-back  */
   1.611 +      } /* last==NULL  */
   1.612 +
   1.613 +     else if (*c!='\0') {          /* more to process...  */
   1.614 +      /* had some digits; exponent is only valid sequence now  */
   1.615 +      Flag nege;                   /* 1=negative exponent  */
   1.616 +      const char *firstexp;        /* -> first significant exponent digit  */
   1.617 +      status=DEC_Conversion_syntax;/* assume the worst  */
   1.618 +      if (*c!='e' && *c!='E') break;
   1.619 +      /* Found 'e' or 'E' -- now process explicit exponent */
   1.620 +      /* 1998.07.11: sign no longer required  */
   1.621 +      nege=0;
   1.622 +      c++;                         /* to (possible) sign  */
   1.623 +      if (*c=='-') {nege=1; c++;}
   1.624 +       else if (*c=='+') c++;
   1.625 +      if (*c=='\0') break;
   1.626 +
   1.627 +      for (; *c=='0' && *(c+1)!='\0';) c++;  /* strip insignificant zeros  */
   1.628 +      firstexp=c;                            /* save exponent digit place  */
   1.629 +      for (; ;c++) {
   1.630 +        if (*c<'0' || *c>'9') break;         /* not a digit  */
   1.631 +        exponent=X10(exponent)+(Int)*c-(Int)'0';
   1.632 +        } /* c  */
   1.633 +      /* if not now on a '\0', *c must not be a digit  */
   1.634 +      if (*c!='\0') break;
   1.635 +
   1.636 +      /* (this next test must be after the syntax checks)  */
   1.637 +      /* if it was too long the exponent may have wrapped, so check  */
   1.638 +      /* carefully and set it to a certain overflow if wrap possible  */
   1.639 +      if (c>=firstexp+9+1) {
   1.640 +        if (c>firstexp+9+1 || *firstexp>'1') exponent=DECNUMMAXE*2;
   1.641 +        /* [up to 1999999999 is OK, for example 1E-1000000998]  */
   1.642 +        }
   1.643 +      if (nege) exponent=-exponent;     /* was negative  */
   1.644 +      status=0;                         /* is OK  */
   1.645 +      } /* stuff after digits  */
   1.646 +
   1.647 +    /* Here when whole string has been inspected; syntax is good  */
   1.648 +    /* cfirst->first digit (never dot), last->last digit (ditto)  */
   1.649 +
   1.650 +    /* strip leading zeros/dot [leave final 0 if all 0's]  */
   1.651 +    if (*cfirst=='0') {                 /* [cfirst has stepped over .]  */
   1.652 +      for (c=cfirst; c<last; c++, cfirst++) {
   1.653 +        if (*c=='.') continue;          /* ignore dots  */
   1.654 +        if (*c!='0') break;             /* non-zero found  */
   1.655 +        d--;                            /* 0 stripped  */
   1.656 +        } /* c  */
   1.657 +      #if DECSUBSET
   1.658 +      /* make a rapid exit for easy zeros if !extended  */
   1.659 +      if (*cfirst=='0' && !set->extended) {
   1.660 +        uprv_decNumberZero(dn);              /* clean result  */
   1.661 +        break;                          /* [could be return]  */
   1.662 +        }
   1.663 +      #endif
   1.664 +      } /* at least one leading 0  */
   1.665 +
   1.666 +    /* Handle decimal point...  */
   1.667 +    if (dotchar!=NULL && dotchar<last)  /* non-trailing '.' found?  */
   1.668 +      exponent-=(last-dotchar);         /* adjust exponent  */
   1.669 +    /* [we can now ignore the .]  */
   1.670 +
   1.671 +    /* OK, the digits string is good.  Assemble in the decNumber, or in  */
   1.672 +    /* a temporary units array if rounding is needed  */
   1.673 +    if (d<=set->digits) res=dn->lsu;    /* fits into supplied decNumber  */
   1.674 +     else {                             /* rounding needed  */
   1.675 +      Int needbytes=D2U(d)*sizeof(Unit);/* bytes needed  */
   1.676 +      res=resbuff;                      /* assume use local buffer  */
   1.677 +      if (needbytes>(Int)sizeof(resbuff)) { /* too big for local  */
   1.678 +        allocres=(Unit *)malloc(needbytes);
   1.679 +        if (allocres==NULL) {status|=DEC_Insufficient_storage; break;}
   1.680 +        res=allocres;
   1.681 +        }
   1.682 +      }
   1.683 +    /* res now -> number lsu, buffer, or allocated storage for Unit array  */
   1.684 +
   1.685 +    /* Place the coefficient into the selected Unit array  */
   1.686 +    /* [this is often 70% of the cost of this function when DECDPUN>1]  */
   1.687 +    #if DECDPUN>1
   1.688 +    out=0;                         /* accumulator  */
   1.689 +    up=res+D2U(d)-1;               /* -> msu  */
   1.690 +    cut=d-(up-res)*DECDPUN;        /* digits in top unit  */
   1.691 +    for (c=cfirst;; c++) {         /* along the digits  */
   1.692 +      if (*c=='.') continue;       /* ignore '.' [don't decrement cut]  */
   1.693 +      out=X10(out)+(Int)*c-(Int)'0';
   1.694 +      if (c==last) break;          /* done [never get to trailing '.']  */
   1.695 +      cut--;
   1.696 +      if (cut>0) continue;         /* more for this unit  */
   1.697 +      *up=(Unit)out;               /* write unit  */
   1.698 +      up--;                        /* prepare for unit below..  */
   1.699 +      cut=DECDPUN;                 /* ..  */
   1.700 +      out=0;                       /* ..  */
   1.701 +      } /* c  */
   1.702 +    *up=(Unit)out;                 /* write lsu  */
   1.703 +
   1.704 +    #else
   1.705 +    /* DECDPUN==1  */
   1.706 +    up=res;                        /* -> lsu  */
   1.707 +    for (c=last; c>=cfirst; c--) { /* over each character, from least  */
   1.708 +      if (*c=='.') continue;       /* ignore . [don't step up]  */
   1.709 +      *up=(Unit)((Int)*c-(Int)'0');
   1.710 +      up++;
   1.711 +      } /* c  */
   1.712 +    #endif
   1.713 +
   1.714 +    dn->bits=bits;
   1.715 +    dn->exponent=exponent;
   1.716 +    dn->digits=d;
   1.717 +
   1.718 +    /* if not in number (too long) shorten into the number  */
   1.719 +    if (d>set->digits) {
   1.720 +      residue=0;
   1.721 +      decSetCoeff(dn, set, res, d, &residue, &status);
   1.722 +      /* always check for overflow or subnormal and round as needed  */
   1.723 +      decFinalize(dn, set, &residue, &status);
   1.724 +      }
   1.725 +     else { /* no rounding, but may still have overflow or subnormal  */
   1.726 +      /* [these tests are just for performance; finalize repeats them]  */
   1.727 +      if ((dn->exponent-1<set->emin-dn->digits)
   1.728 +       || (dn->exponent-1>set->emax-set->digits)) {
   1.729 +        residue=0;
   1.730 +        decFinalize(dn, set, &residue, &status);
   1.731 +        }
   1.732 +      }
   1.733 +    /* decNumberShow(dn);  */
   1.734 +    } while(0);                         /* [for break]  */
   1.735 +
   1.736 +  if (allocres!=NULL) free(allocres);   /* drop any storage used  */
   1.737 +  if (status!=0) decStatus(dn, status, set);
   1.738 +  return dn;
   1.739 +  } /* decNumberFromString */
   1.740 +
   1.741 +/* ================================================================== */
   1.742 +/* Operators                                                          */
   1.743 +/* ================================================================== */
   1.744 +
   1.745 +/* ------------------------------------------------------------------ */
   1.746 +/* decNumberAbs -- absolute value operator                            */
   1.747 +/*                                                                    */
   1.748 +/*   This computes C = abs(A)                                         */
   1.749 +/*                                                                    */
   1.750 +/*   res is C, the result.  C may be A                                */
   1.751 +/*   rhs is A                                                         */
   1.752 +/*   set is the context                                               */
   1.753 +/*                                                                    */
   1.754 +/* See also decNumberCopyAbs for a quiet bitwise version of this.     */
   1.755 +/* C must have space for set->digits digits.                          */
   1.756 +/* ------------------------------------------------------------------ */
   1.757 +/* This has the same effect as decNumberPlus unless A is negative,    */
   1.758 +/* in which case it has the same effect as decNumberMinus.            */
   1.759 +/* ------------------------------------------------------------------ */
   1.760 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberAbs(decNumber *res, const decNumber *rhs,
   1.761 +                         decContext *set) {
   1.762 +  decNumber dzero;                      /* for 0  */
   1.763 +  uInt status=0;                        /* accumulator  */
   1.764 +
   1.765 +  #if DECCHECK
   1.766 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
   1.767 +  #endif
   1.768 +
   1.769 +  uprv_decNumberZero(&dzero);                /* set 0  */
   1.770 +  dzero.exponent=rhs->exponent;         /* [no coefficient expansion]  */
   1.771 +  decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status);
   1.772 +  if (status!=0) decStatus(res, status, set);
   1.773 +  #if DECCHECK
   1.774 +  decCheckInexact(res, set);
   1.775 +  #endif
   1.776 +  return res;
   1.777 +  } /* decNumberAbs  */
   1.778 +
   1.779 +/* ------------------------------------------------------------------ */
   1.780 +/* decNumberAdd -- add two Numbers                                    */
   1.781 +/*                                                                    */
   1.782 +/*   This computes C = A + B                                          */
   1.783 +/*                                                                    */
   1.784 +/*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
   1.785 +/*   lhs is A                                                         */
   1.786 +/*   rhs is B                                                         */
   1.787 +/*   set is the context                                               */
   1.788 +/*                                                                    */
   1.789 +/* C must have space for set->digits digits.                          */
   1.790 +/* ------------------------------------------------------------------ */
   1.791 +/* This just calls the routine shared with Subtract                   */
   1.792 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberAdd(decNumber *res, const decNumber *lhs,
   1.793 +                         const decNumber *rhs, decContext *set) {
   1.794 +  uInt status=0;                        /* accumulator  */
   1.795 +  decAddOp(res, lhs, rhs, set, 0, &status);
   1.796 +  if (status!=0) decStatus(res, status, set);
   1.797 +  #if DECCHECK
   1.798 +  decCheckInexact(res, set);
   1.799 +  #endif
   1.800 +  return res;
   1.801 +  } /* decNumberAdd  */
   1.802 +
   1.803 +/* ------------------------------------------------------------------ */
   1.804 +/* decNumberAnd -- AND two Numbers, digitwise                         */
   1.805 +/*                                                                    */
   1.806 +/*   This computes C = A & B                                          */
   1.807 +/*                                                                    */
   1.808 +/*   res is C, the result.  C may be A and/or B (e.g., X=X&X)         */
   1.809 +/*   lhs is A                                                         */
   1.810 +/*   rhs is B                                                         */
   1.811 +/*   set is the context (used for result length and error report)     */
   1.812 +/*                                                                    */
   1.813 +/* C must have space for set->digits digits.                          */
   1.814 +/*                                                                    */
   1.815 +/* Logical function restrictions apply (see above); a NaN is          */
   1.816 +/* returned with Invalid_operation if a restriction is violated.      */
   1.817 +/* ------------------------------------------------------------------ */
   1.818 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberAnd(decNumber *res, const decNumber *lhs,
   1.819 +                         const decNumber *rhs, decContext *set) {
   1.820 +  const Unit *ua, *ub;                  /* -> operands  */
   1.821 +  const Unit *msua, *msub;              /* -> operand msus  */
   1.822 +  Unit *uc,  *msuc;                     /* -> result and its msu  */
   1.823 +  Int   msudigs;                        /* digits in res msu  */
   1.824 +  #if DECCHECK
   1.825 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
   1.826 +  #endif
   1.827 +
   1.828 +  if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
   1.829 +   || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
   1.830 +    decStatus(res, DEC_Invalid_operation, set);
   1.831 +    return res;
   1.832 +    }
   1.833 +
   1.834 +  /* operands are valid  */
   1.835 +  ua=lhs->lsu;                          /* bottom-up  */
   1.836 +  ub=rhs->lsu;                          /* ..  */
   1.837 +  uc=res->lsu;                          /* ..  */
   1.838 +  msua=ua+D2U(lhs->digits)-1;           /* -> msu of lhs  */
   1.839 +  msub=ub+D2U(rhs->digits)-1;           /* -> msu of rhs  */
   1.840 +  msuc=uc+D2U(set->digits)-1;           /* -> msu of result  */
   1.841 +  msudigs=MSUDIGITS(set->digits);       /* [faster than remainder]  */
   1.842 +  for (; uc<=msuc; ua++, ub++, uc++) {  /* Unit loop  */
   1.843 +    Unit a, b;                          /* extract units  */
   1.844 +    if (ua>msua) a=0;
   1.845 +     else a=*ua;
   1.846 +    if (ub>msub) b=0;
   1.847 +     else b=*ub;
   1.848 +    *uc=0;                              /* can now write back  */
   1.849 +    if (a|b) {                          /* maybe 1 bits to examine  */
   1.850 +      Int i, j;
   1.851 +      *uc=0;                            /* can now write back  */
   1.852 +      /* This loop could be unrolled and/or use BIN2BCD tables  */
   1.853 +      for (i=0; i<DECDPUN; i++) {
   1.854 +        if (a&b&1) *uc=*uc+(Unit)powers[i];  /* effect AND  */
   1.855 +        j=a%10;
   1.856 +        a=a/10;
   1.857 +        j|=b%10;
   1.858 +        b=b/10;
   1.859 +        if (j>1) {
   1.860 +          decStatus(res, DEC_Invalid_operation, set);
   1.861 +          return res;
   1.862 +          }
   1.863 +        if (uc==msuc && i==msudigs-1) break; /* just did final digit  */
   1.864 +        } /* each digit  */
   1.865 +      } /* both OK  */
   1.866 +    } /* each unit  */
   1.867 +  /* [here uc-1 is the msu of the result]  */
   1.868 +  res->digits=decGetDigits(res->lsu, uc-res->lsu);
   1.869 +  res->exponent=0;                      /* integer  */
   1.870 +  res->bits=0;                          /* sign=0  */
   1.871 +  return res;  /* [no status to set]  */
   1.872 +  } /* decNumberAnd  */
   1.873 +
   1.874 +/* ------------------------------------------------------------------ */
   1.875 +/* decNumberCompare -- compare two Numbers                            */
   1.876 +/*                                                                    */
   1.877 +/*   This computes C = A ? B                                          */
   1.878 +/*                                                                    */
   1.879 +/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
   1.880 +/*   lhs is A                                                         */
   1.881 +/*   rhs is B                                                         */
   1.882 +/*   set is the context                                               */
   1.883 +/*                                                                    */
   1.884 +/* C must have space for one digit (or NaN).                          */
   1.885 +/* ------------------------------------------------------------------ */
   1.886 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCompare(decNumber *res, const decNumber *lhs,
   1.887 +                             const decNumber *rhs, decContext *set) {
   1.888 +  uInt status=0;                        /* accumulator  */
   1.889 +  decCompareOp(res, lhs, rhs, set, COMPARE, &status);
   1.890 +  if (status!=0) decStatus(res, status, set);
   1.891 +  return res;
   1.892 +  } /* decNumberCompare  */
   1.893 +
   1.894 +/* ------------------------------------------------------------------ */
   1.895 +/* decNumberCompareSignal -- compare, signalling on all NaNs          */
   1.896 +/*                                                                    */
   1.897 +/*   This computes C = A ? B                                          */
   1.898 +/*                                                                    */
   1.899 +/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
   1.900 +/*   lhs is A                                                         */
   1.901 +/*   rhs is B                                                         */
   1.902 +/*   set is the context                                               */
   1.903 +/*                                                                    */
   1.904 +/* C must have space for one digit (or NaN).                          */
   1.905 +/* ------------------------------------------------------------------ */
   1.906 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCompareSignal(decNumber *res, const decNumber *lhs,
   1.907 +                                   const decNumber *rhs, decContext *set) {
   1.908 +  uInt status=0;                        /* accumulator  */
   1.909 +  decCompareOp(res, lhs, rhs, set, COMPSIG, &status);
   1.910 +  if (status!=0) decStatus(res, status, set);
   1.911 +  return res;
   1.912 +  } /* decNumberCompareSignal  */
   1.913 +
   1.914 +/* ------------------------------------------------------------------ */
   1.915 +/* decNumberCompareTotal -- compare two Numbers, using total ordering */
   1.916 +/*                                                                    */
   1.917 +/*   This computes C = A ? B, under total ordering                    */
   1.918 +/*                                                                    */
   1.919 +/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
   1.920 +/*   lhs is A                                                         */
   1.921 +/*   rhs is B                                                         */
   1.922 +/*   set is the context                                               */
   1.923 +/*                                                                    */
   1.924 +/* C must have space for one digit; the result will always be one of  */
   1.925 +/* -1, 0, or 1.                                                       */
   1.926 +/* ------------------------------------------------------------------ */
   1.927 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCompareTotal(decNumber *res, const decNumber *lhs,
   1.928 +                                  const decNumber *rhs, decContext *set) {
   1.929 +  uInt status=0;                        /* accumulator  */
   1.930 +  decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
   1.931 +  if (status!=0) decStatus(res, status, set);
   1.932 +  return res;
   1.933 +  } /* decNumberCompareTotal  */
   1.934 +
   1.935 +/* ------------------------------------------------------------------ */
   1.936 +/* decNumberCompareTotalMag -- compare, total ordering of magnitudes  */
   1.937 +/*                                                                    */
   1.938 +/*   This computes C = |A| ? |B|, under total ordering                */
   1.939 +/*                                                                    */
   1.940 +/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
   1.941 +/*   lhs is A                                                         */
   1.942 +/*   rhs is B                                                         */
   1.943 +/*   set is the context                                               */
   1.944 +/*                                                                    */
   1.945 +/* C must have space for one digit; the result will always be one of  */
   1.946 +/* -1, 0, or 1.                                                       */
   1.947 +/* ------------------------------------------------------------------ */
   1.948 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCompareTotalMag(decNumber *res, const decNumber *lhs,
   1.949 +                                     const decNumber *rhs, decContext *set) {
   1.950 +  uInt status=0;                   /* accumulator  */
   1.951 +  uInt needbytes;                  /* for space calculations  */
   1.952 +  decNumber bufa[D2N(DECBUFFER+1)];/* +1 in case DECBUFFER=0  */
   1.953 +  decNumber *allocbufa=NULL;       /* -> allocated bufa, iff allocated  */
   1.954 +  decNumber bufb[D2N(DECBUFFER+1)];
   1.955 +  decNumber *allocbufb=NULL;       /* -> allocated bufb, iff allocated  */
   1.956 +  decNumber *a, *b;                /* temporary pointers  */
   1.957 +
   1.958 +  #if DECCHECK
   1.959 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
   1.960 +  #endif
   1.961 +
   1.962 +  do {                                  /* protect allocated storage  */
   1.963 +    /* if either is negative, take a copy and absolute  */
   1.964 +    if (decNumberIsNegative(lhs)) {     /* lhs<0  */
   1.965 +      a=bufa;
   1.966 +      needbytes=sizeof(decNumber)+(D2U(lhs->digits)-1)*sizeof(Unit);
   1.967 +      if (needbytes>sizeof(bufa)) {     /* need malloc space  */
   1.968 +        allocbufa=(decNumber *)malloc(needbytes);
   1.969 +        if (allocbufa==NULL) {          /* hopeless -- abandon  */
   1.970 +          status|=DEC_Insufficient_storage;
   1.971 +          break;}
   1.972 +        a=allocbufa;                    /* use the allocated space  */
   1.973 +        }
   1.974 +      uprv_decNumberCopy(a, lhs);            /* copy content  */
   1.975 +      a->bits&=~DECNEG;                 /* .. and clear the sign  */
   1.976 +      lhs=a;                            /* use copy from here on  */
   1.977 +      }
   1.978 +    if (decNumberIsNegative(rhs)) {     /* rhs<0  */
   1.979 +      b=bufb;
   1.980 +      needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
   1.981 +      if (needbytes>sizeof(bufb)) {     /* need malloc space  */
   1.982 +        allocbufb=(decNumber *)malloc(needbytes);
   1.983 +        if (allocbufb==NULL) {          /* hopeless -- abandon  */
   1.984 +          status|=DEC_Insufficient_storage;
   1.985 +          break;}
   1.986 +        b=allocbufb;                    /* use the allocated space  */
   1.987 +        }
   1.988 +      uprv_decNumberCopy(b, rhs);            /* copy content  */
   1.989 +      b->bits&=~DECNEG;                 /* .. and clear the sign  */
   1.990 +      rhs=b;                            /* use copy from here on  */
   1.991 +      }
   1.992 +    decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
   1.993 +    } while(0);                         /* end protected  */
   1.994 +
   1.995 +  if (allocbufa!=NULL) free(allocbufa); /* drop any storage used  */
   1.996 +  if (allocbufb!=NULL) free(allocbufb); /* ..  */
   1.997 +  if (status!=0) decStatus(res, status, set);
   1.998 +  return res;
   1.999 +  } /* decNumberCompareTotalMag  */
  1.1000 +
  1.1001 +/* ------------------------------------------------------------------ */
  1.1002 +/* decNumberDivide -- divide one number by another                    */
  1.1003 +/*                                                                    */
  1.1004 +/*   This computes C = A / B                                          */
  1.1005 +/*                                                                    */
  1.1006 +/*   res is C, the result.  C may be A and/or B (e.g., X=X/X)         */
  1.1007 +/*   lhs is A                                                         */
  1.1008 +/*   rhs is B                                                         */
  1.1009 +/*   set is the context                                               */
  1.1010 +/*                                                                    */
  1.1011 +/* C must have space for set->digits digits.                          */
  1.1012 +/* ------------------------------------------------------------------ */
  1.1013 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberDivide(decNumber *res, const decNumber *lhs,
  1.1014 +                            const decNumber *rhs, decContext *set) {
  1.1015 +  uInt status=0;                        /* accumulator  */
  1.1016 +  decDivideOp(res, lhs, rhs, set, DIVIDE, &status);
  1.1017 +  if (status!=0) decStatus(res, status, set);
  1.1018 +  #if DECCHECK
  1.1019 +  decCheckInexact(res, set);
  1.1020 +  #endif
  1.1021 +  return res;
  1.1022 +  } /* decNumberDivide  */
  1.1023 +
  1.1024 +/* ------------------------------------------------------------------ */
  1.1025 +/* decNumberDivideInteger -- divide and return integer quotient       */
  1.1026 +/*                                                                    */
  1.1027 +/*   This computes C = A # B, where # is the integer divide operator  */
  1.1028 +/*                                                                    */
  1.1029 +/*   res is C, the result.  C may be A and/or B (e.g., X=X#X)         */
  1.1030 +/*   lhs is A                                                         */
  1.1031 +/*   rhs is B                                                         */
  1.1032 +/*   set is the context                                               */
  1.1033 +/*                                                                    */
  1.1034 +/* C must have space for set->digits digits.                          */
  1.1035 +/* ------------------------------------------------------------------ */
  1.1036 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberDivideInteger(decNumber *res, const decNumber *lhs,
  1.1037 +                                   const decNumber *rhs, decContext *set) {
  1.1038 +  uInt status=0;                        /* accumulator  */
  1.1039 +  decDivideOp(res, lhs, rhs, set, DIVIDEINT, &status);
  1.1040 +  if (status!=0) decStatus(res, status, set);
  1.1041 +  return res;
  1.1042 +  } /* decNumberDivideInteger  */
  1.1043 +
  1.1044 +/* ------------------------------------------------------------------ */
  1.1045 +/* decNumberExp -- exponentiation                                     */
  1.1046 +/*                                                                    */
  1.1047 +/*   This computes C = exp(A)                                         */
  1.1048 +/*                                                                    */
  1.1049 +/*   res is C, the result.  C may be A                                */
  1.1050 +/*   rhs is A                                                         */
  1.1051 +/*   set is the context; note that rounding mode has no effect        */
  1.1052 +/*                                                                    */
  1.1053 +/* C must have space for set->digits digits.                          */
  1.1054 +/*                                                                    */
  1.1055 +/* Mathematical function restrictions apply (see above); a NaN is     */
  1.1056 +/* returned with Invalid_operation if a restriction is violated.      */
  1.1057 +/*                                                                    */
  1.1058 +/* Finite results will always be full precision and Inexact, except   */
  1.1059 +/* when A is a zero or -Infinity (giving 1 or 0 respectively).        */
  1.1060 +/*                                                                    */
  1.1061 +/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
  1.1062 +/* almost always be correctly rounded, but may be up to 1 ulp in      */
  1.1063 +/* error in rare cases.                                               */
  1.1064 +/* ------------------------------------------------------------------ */
  1.1065 +/* This is a wrapper for decExpOp which can handle the slightly wider */
  1.1066 +/* (double) range needed by Ln (which has to be able to calculate     */
  1.1067 +/* exp(-a) where a can be the tiniest number (Ntiny).                 */
  1.1068 +/* ------------------------------------------------------------------ */
  1.1069 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberExp(decNumber *res, const decNumber *rhs,
  1.1070 +                         decContext *set) {
  1.1071 +  uInt status=0;                        /* accumulator  */
  1.1072 +  #if DECSUBSET
  1.1073 +  decNumber *allocrhs=NULL;        /* non-NULL if rounded rhs allocated  */
  1.1074 +  #endif
  1.1075 +
  1.1076 +  #if DECCHECK
  1.1077 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  1.1078 +  #endif
  1.1079 +
  1.1080 +  /* Check restrictions; these restrictions ensure that if h=8 (see  */
  1.1081 +  /* decExpOp) then the result will either overflow or underflow to 0.  */
  1.1082 +  /* Other math functions restrict the input range, too, for inverses.  */
  1.1083 +  /* If not violated then carry out the operation.  */
  1.1084 +  if (!decCheckMath(rhs, set, &status)) do { /* protect allocation  */
  1.1085 +    #if DECSUBSET
  1.1086 +    if (!set->extended) {
  1.1087 +      /* reduce operand and set lostDigits status, as needed  */
  1.1088 +      if (rhs->digits>set->digits) {
  1.1089 +        allocrhs=decRoundOperand(rhs, set, &status);
  1.1090 +        if (allocrhs==NULL) break;
  1.1091 +        rhs=allocrhs;
  1.1092 +        }
  1.1093 +      }
  1.1094 +    #endif
  1.1095 +    decExpOp(res, rhs, set, &status);
  1.1096 +    } while(0);                         /* end protected  */
  1.1097 +
  1.1098 +  #if DECSUBSET
  1.1099 +  if (allocrhs !=NULL) free(allocrhs);  /* drop any storage used  */
  1.1100 +  #endif
  1.1101 +  /* apply significant status  */
  1.1102 +  if (status!=0) decStatus(res, status, set);
  1.1103 +  #if DECCHECK
  1.1104 +  decCheckInexact(res, set);
  1.1105 +  #endif
  1.1106 +  return res;
  1.1107 +  } /* decNumberExp  */
  1.1108 +
  1.1109 +/* ------------------------------------------------------------------ */
  1.1110 +/* decNumberFMA -- fused multiply add                                 */
  1.1111 +/*                                                                    */
  1.1112 +/*   This computes D = (A * B) + C with only one rounding             */
  1.1113 +/*                                                                    */
  1.1114 +/*   res is D, the result.  D may be A or B or C (e.g., X=FMA(X,X,X)) */
  1.1115 +/*   lhs is A                                                         */
  1.1116 +/*   rhs is B                                                         */
  1.1117 +/*   fhs is C [far hand side]                                         */
  1.1118 +/*   set is the context                                               */
  1.1119 +/*                                                                    */
  1.1120 +/* Mathematical function restrictions apply (see above); a NaN is     */
  1.1121 +/* returned with Invalid_operation if a restriction is violated.      */
  1.1122 +/*                                                                    */
  1.1123 +/* C must have space for set->digits digits.                          */
  1.1124 +/* ------------------------------------------------------------------ */
  1.1125 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberFMA(decNumber *res, const decNumber *lhs,
  1.1126 +                         const decNumber *rhs, const decNumber *fhs,
  1.1127 +                         decContext *set) {
  1.1128 +  uInt status=0;                   /* accumulator  */
  1.1129 +  decContext dcmul;                /* context for the multiplication  */
  1.1130 +  uInt needbytes;                  /* for space calculations  */
  1.1131 +  decNumber bufa[D2N(DECBUFFER*2+1)];
  1.1132 +  decNumber *allocbufa=NULL;       /* -> allocated bufa, iff allocated  */
  1.1133 +  decNumber *acc;                  /* accumulator pointer  */
  1.1134 +  decNumber dzero;                 /* work  */
  1.1135 +
  1.1136 +  #if DECCHECK
  1.1137 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
  1.1138 +  if (decCheckOperands(res, fhs, DECUNUSED, set)) return res;
  1.1139 +  #endif
  1.1140 +
  1.1141 +  do {                                  /* protect allocated storage  */
  1.1142 +    #if DECSUBSET
  1.1143 +    if (!set->extended) {               /* [undefined if subset]  */
  1.1144 +      status|=DEC_Invalid_operation;
  1.1145 +      break;}
  1.1146 +    #endif
  1.1147 +    /* Check math restrictions [these ensure no overflow or underflow]  */
  1.1148 +    if ((!decNumberIsSpecial(lhs) && decCheckMath(lhs, set, &status))
  1.1149 +     || (!decNumberIsSpecial(rhs) && decCheckMath(rhs, set, &status))
  1.1150 +     || (!decNumberIsSpecial(fhs) && decCheckMath(fhs, set, &status))) break;
  1.1151 +    /* set up context for multiply  */
  1.1152 +    dcmul=*set;
  1.1153 +    dcmul.digits=lhs->digits+rhs->digits; /* just enough  */
  1.1154 +    /* [The above may be an over-estimate for subset arithmetic, but that's OK]  */
  1.1155 +    dcmul.emax=DEC_MAX_EMAX;            /* effectively unbounded ..  */
  1.1156 +    dcmul.emin=DEC_MIN_EMIN;            /* [thanks to Math restrictions]  */
  1.1157 +    /* set up decNumber space to receive the result of the multiply  */
  1.1158 +    acc=bufa;                           /* may fit  */
  1.1159 +    needbytes=sizeof(decNumber)+(D2U(dcmul.digits)-1)*sizeof(Unit);
  1.1160 +    if (needbytes>sizeof(bufa)) {       /* need malloc space  */
  1.1161 +      allocbufa=(decNumber *)malloc(needbytes);
  1.1162 +      if (allocbufa==NULL) {            /* hopeless -- abandon  */
  1.1163 +        status|=DEC_Insufficient_storage;
  1.1164 +        break;}
  1.1165 +      acc=allocbufa;                    /* use the allocated space  */
  1.1166 +      }
  1.1167 +    /* multiply with extended range and necessary precision  */
  1.1168 +    /*printf("emin=%ld\n", dcmul.emin);  */
  1.1169 +    decMultiplyOp(acc, lhs, rhs, &dcmul, &status);
  1.1170 +    /* Only Invalid operation (from sNaN or Inf * 0) is possible in  */
  1.1171 +    /* status; if either is seen than ignore fhs (in case it is  */
  1.1172 +    /* another sNaN) and set acc to NaN unless we had an sNaN  */
  1.1173 +    /* [decMultiplyOp leaves that to caller]  */
  1.1174 +    /* Note sNaN has to go through addOp to shorten payload if  */
  1.1175 +    /* necessary  */
  1.1176 +    if ((status&DEC_Invalid_operation)!=0) {
  1.1177 +      if (!(status&DEC_sNaN)) {         /* but be true invalid  */
  1.1178 +        uprv_decNumberZero(res);             /* acc not yet set  */
  1.1179 +        res->bits=DECNAN;
  1.1180 +        break;
  1.1181 +        }
  1.1182 +      uprv_decNumberZero(&dzero);            /* make 0 (any non-NaN would do)  */
  1.1183 +      fhs=&dzero;                       /* use that  */
  1.1184 +      }
  1.1185 +    #if DECCHECK
  1.1186 +     else { /* multiply was OK  */
  1.1187 +      if (status!=0) printf("Status=%08lx after FMA multiply\n", (LI)status);
  1.1188 +      }
  1.1189 +    #endif
  1.1190 +    /* add the third operand and result -> res, and all is done  */
  1.1191 +    decAddOp(res, acc, fhs, set, 0, &status);
  1.1192 +    } while(0);                         /* end protected  */
  1.1193 +
  1.1194 +  if (allocbufa!=NULL) free(allocbufa); /* drop any storage used  */
  1.1195 +  if (status!=0) decStatus(res, status, set);
  1.1196 +  #if DECCHECK
  1.1197 +  decCheckInexact(res, set);
  1.1198 +  #endif
  1.1199 +  return res;
  1.1200 +  } /* decNumberFMA  */
  1.1201 +
  1.1202 +/* ------------------------------------------------------------------ */
  1.1203 +/* decNumberInvert -- invert a Number, digitwise                      */
  1.1204 +/*                                                                    */
  1.1205 +/*   This computes C = ~A                                             */
  1.1206 +/*                                                                    */
  1.1207 +/*   res is C, the result.  C may be A (e.g., X=~X)                   */
  1.1208 +/*   rhs is A                                                         */
  1.1209 +/*   set is the context (used for result length and error report)     */
  1.1210 +/*                                                                    */
  1.1211 +/* C must have space for set->digits digits.                          */
  1.1212 +/*                                                                    */
  1.1213 +/* Logical function restrictions apply (see above); a NaN is          */
  1.1214 +/* returned with Invalid_operation if a restriction is violated.      */
  1.1215 +/* ------------------------------------------------------------------ */
  1.1216 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberInvert(decNumber *res, const decNumber *rhs,
  1.1217 +                            decContext *set) {
  1.1218 +  const Unit *ua, *msua;                /* -> operand and its msu  */
  1.1219 +  Unit  *uc, *msuc;                     /* -> result and its msu  */
  1.1220 +  Int   msudigs;                        /* digits in res msu  */
  1.1221 +  #if DECCHECK
  1.1222 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  1.1223 +  #endif
  1.1224 +
  1.1225 +  if (rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
  1.1226 +    decStatus(res, DEC_Invalid_operation, set);
  1.1227 +    return res;
  1.1228 +    }
  1.1229 +  /* operand is valid  */
  1.1230 +  ua=rhs->lsu;                          /* bottom-up  */
  1.1231 +  uc=res->lsu;                          /* ..  */
  1.1232 +  msua=ua+D2U(rhs->digits)-1;           /* -> msu of rhs  */
  1.1233 +  msuc=uc+D2U(set->digits)-1;           /* -> msu of result  */
  1.1234 +  msudigs=MSUDIGITS(set->digits);       /* [faster than remainder]  */
  1.1235 +  for (; uc<=msuc; ua++, uc++) {        /* Unit loop  */
  1.1236 +    Unit a;                             /* extract unit  */
  1.1237 +    Int  i, j;                          /* work  */
  1.1238 +    if (ua>msua) a=0;
  1.1239 +     else a=*ua;
  1.1240 +    *uc=0;                              /* can now write back  */
  1.1241 +    /* always need to examine all bits in rhs  */
  1.1242 +    /* This loop could be unrolled and/or use BIN2BCD tables  */
  1.1243 +    for (i=0; i<DECDPUN; i++) {
  1.1244 +      if ((~a)&1) *uc=*uc+(Unit)powers[i];   /* effect INVERT  */
  1.1245 +      j=a%10;
  1.1246 +      a=a/10;
  1.1247 +      if (j>1) {
  1.1248 +        decStatus(res, DEC_Invalid_operation, set);
  1.1249 +        return res;
  1.1250 +        }
  1.1251 +      if (uc==msuc && i==msudigs-1) break;   /* just did final digit  */
  1.1252 +      } /* each digit  */
  1.1253 +    } /* each unit  */
  1.1254 +  /* [here uc-1 is the msu of the result]  */
  1.1255 +  res->digits=decGetDigits(res->lsu, uc-res->lsu);
  1.1256 +  res->exponent=0;                      /* integer  */
  1.1257 +  res->bits=0;                          /* sign=0  */
  1.1258 +  return res;  /* [no status to set]  */
  1.1259 +  } /* decNumberInvert  */
  1.1260 +
  1.1261 +/* ------------------------------------------------------------------ */
  1.1262 +/* decNumberLn -- natural logarithm                                   */
  1.1263 +/*                                                                    */
  1.1264 +/*   This computes C = ln(A)                                          */
  1.1265 +/*                                                                    */
  1.1266 +/*   res is C, the result.  C may be A                                */
  1.1267 +/*   rhs is A                                                         */
  1.1268 +/*   set is the context; note that rounding mode has no effect        */
  1.1269 +/*                                                                    */
  1.1270 +/* C must have space for set->digits digits.                          */
  1.1271 +/*                                                                    */
  1.1272 +/* Notable cases:                                                     */
  1.1273 +/*   A<0 -> Invalid                                                   */
  1.1274 +/*   A=0 -> -Infinity (Exact)                                         */
  1.1275 +/*   A=+Infinity -> +Infinity (Exact)                                 */
  1.1276 +/*   A=1 exactly -> 0 (Exact)                                         */
  1.1277 +/*                                                                    */
  1.1278 +/* Mathematical function restrictions apply (see above); a NaN is     */
  1.1279 +/* returned with Invalid_operation if a restriction is violated.      */
  1.1280 +/*                                                                    */
  1.1281 +/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
  1.1282 +/* almost always be correctly rounded, but may be up to 1 ulp in      */
  1.1283 +/* error in rare cases.                                               */
  1.1284 +/* ------------------------------------------------------------------ */
  1.1285 +/* This is a wrapper for decLnOp which can handle the slightly wider  */
  1.1286 +/* (+11) range needed by Ln, Log10, etc. (which may have to be able   */
  1.1287 +/* to calculate at p+e+2).                                            */
  1.1288 +/* ------------------------------------------------------------------ */
  1.1289 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberLn(decNumber *res, const decNumber *rhs,
  1.1290 +                        decContext *set) {
  1.1291 +  uInt status=0;                   /* accumulator  */
  1.1292 +  #if DECSUBSET
  1.1293 +  decNumber *allocrhs=NULL;        /* non-NULL if rounded rhs allocated  */
  1.1294 +  #endif
  1.1295 +
  1.1296 +  #if DECCHECK
  1.1297 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  1.1298 +  #endif
  1.1299 +
  1.1300 +  /* Check restrictions; this is a math function; if not violated  */
  1.1301 +  /* then carry out the operation.  */
  1.1302 +  if (!decCheckMath(rhs, set, &status)) do { /* protect allocation  */
  1.1303 +    #if DECSUBSET
  1.1304 +    if (!set->extended) {
  1.1305 +      /* reduce operand and set lostDigits status, as needed  */
  1.1306 +      if (rhs->digits>set->digits) {
  1.1307 +        allocrhs=decRoundOperand(rhs, set, &status);
  1.1308 +        if (allocrhs==NULL) break;
  1.1309 +        rhs=allocrhs;
  1.1310 +        }
  1.1311 +      /* special check in subset for rhs=0  */
  1.1312 +      if (ISZERO(rhs)) {                /* +/- zeros -> error  */
  1.1313 +        status|=DEC_Invalid_operation;
  1.1314 +        break;}
  1.1315 +      } /* extended=0  */
  1.1316 +    #endif
  1.1317 +    decLnOp(res, rhs, set, &status);
  1.1318 +    } while(0);                         /* end protected  */
  1.1319 +
  1.1320 +  #if DECSUBSET
  1.1321 +  if (allocrhs !=NULL) free(allocrhs);  /* drop any storage used  */
  1.1322 +  #endif
  1.1323 +  /* apply significant status  */
  1.1324 +  if (status!=0) decStatus(res, status, set);
  1.1325 +  #if DECCHECK
  1.1326 +  decCheckInexact(res, set);
  1.1327 +  #endif
  1.1328 +  return res;
  1.1329 +  } /* decNumberLn  */
  1.1330 +
  1.1331 +/* ------------------------------------------------------------------ */
  1.1332 +/* decNumberLogB - get adjusted exponent, by 754 rules                */
  1.1333 +/*                                                                    */
  1.1334 +/*   This computes C = adjustedexponent(A)                            */
  1.1335 +/*                                                                    */
  1.1336 +/*   res is C, the result.  C may be A                                */
  1.1337 +/*   rhs is A                                                         */
  1.1338 +/*   set is the context, used only for digits and status              */
  1.1339 +/*                                                                    */
  1.1340 +/* C must have space for 10 digits (A might have 10**9 digits and     */
  1.1341 +/* an exponent of +999999999, or one digit and an exponent of         */
  1.1342 +/* -1999999999).                                                      */
  1.1343 +/*                                                                    */
  1.1344 +/* This returns the adjusted exponent of A after (in theory) padding  */
  1.1345 +/* with zeros on the right to set->digits digits while keeping the    */
  1.1346 +/* same value.  The exponent is not limited by emin/emax.             */
  1.1347 +/*                                                                    */
  1.1348 +/* Notable cases:                                                     */
  1.1349 +/*   A<0 -> Use |A|                                                   */
  1.1350 +/*   A=0 -> -Infinity (Division by zero)                              */
  1.1351 +/*   A=Infinite -> +Infinity (Exact)                                  */
  1.1352 +/*   A=1 exactly -> 0 (Exact)                                         */
  1.1353 +/*   NaNs are propagated as usual                                     */
  1.1354 +/* ------------------------------------------------------------------ */
  1.1355 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberLogB(decNumber *res, const decNumber *rhs,
  1.1356 +                          decContext *set) {
  1.1357 +  uInt status=0;                   /* accumulator  */
  1.1358 +
  1.1359 +  #if DECCHECK
  1.1360 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  1.1361 +  #endif
  1.1362 +
  1.1363 +  /* NaNs as usual; Infinities return +Infinity; 0->oops  */
  1.1364 +  if (decNumberIsNaN(rhs)) decNaNs(res, rhs, NULL, set, &status);
  1.1365 +   else if (decNumberIsInfinite(rhs)) uprv_decNumberCopyAbs(res, rhs);
  1.1366 +   else if (decNumberIsZero(rhs)) {
  1.1367 +    uprv_decNumberZero(res);                 /* prepare for Infinity  */
  1.1368 +    res->bits=DECNEG|DECINF;            /* -Infinity  */
  1.1369 +    status|=DEC_Division_by_zero;       /* as per 754  */
  1.1370 +    }
  1.1371 +   else { /* finite non-zero  */
  1.1372 +    Int ae=rhs->exponent+rhs->digits-1; /* adjusted exponent  */
  1.1373 +    uprv_decNumberFromInt32(res, ae);        /* lay it out  */
  1.1374 +    }
  1.1375 +
  1.1376 +  if (status!=0) decStatus(res, status, set);
  1.1377 +  return res;
  1.1378 +  } /* decNumberLogB  */
  1.1379 +
  1.1380 +/* ------------------------------------------------------------------ */
  1.1381 +/* decNumberLog10 -- logarithm in base 10                             */
  1.1382 +/*                                                                    */
  1.1383 +/*   This computes C = log10(A)                                       */
  1.1384 +/*                                                                    */
  1.1385 +/*   res is C, the result.  C may be A                                */
  1.1386 +/*   rhs is A                                                         */
  1.1387 +/*   set is the context; note that rounding mode has no effect        */
  1.1388 +/*                                                                    */
  1.1389 +/* C must have space for set->digits digits.                          */
  1.1390 +/*                                                                    */
  1.1391 +/* Notable cases:                                                     */
  1.1392 +/*   A<0 -> Invalid                                                   */
  1.1393 +/*   A=0 -> -Infinity (Exact)                                         */
  1.1394 +/*   A=+Infinity -> +Infinity (Exact)                                 */
  1.1395 +/*   A=10**n (if n is an integer) -> n (Exact)                        */
  1.1396 +/*                                                                    */
  1.1397 +/* Mathematical function restrictions apply (see above); a NaN is     */
  1.1398 +/* returned with Invalid_operation if a restriction is violated.      */
  1.1399 +/*                                                                    */
  1.1400 +/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
  1.1401 +/* almost always be correctly rounded, but may be up to 1 ulp in      */
  1.1402 +/* error in rare cases.                                               */
  1.1403 +/* ------------------------------------------------------------------ */
  1.1404 +/* This calculates ln(A)/ln(10) using appropriate precision.  For     */
  1.1405 +/* ln(A) this is the max(p, rhs->digits + t) + 3, where p is the      */
  1.1406 +/* requested digits and t is the number of digits in the exponent     */
  1.1407 +/* (maximum 6).  For ln(10) it is p + 3; this is often handled by the */
  1.1408 +/* fastpath in decLnOp.  The final division is done to the requested  */
  1.1409 +/* precision.                                                         */
  1.1410 +/* ------------------------------------------------------------------ */
  1.1411 +#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
  1.1412 +#pragma GCC diagnostic push
  1.1413 +#pragma GCC diagnostic ignored "-Warray-bounds"
  1.1414 +#endif
  1.1415 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberLog10(decNumber *res, const decNumber *rhs,
  1.1416 +                          decContext *set) {
  1.1417 +  uInt status=0, ignore=0;         /* status accumulators  */
  1.1418 +  uInt needbytes;                  /* for space calculations  */
  1.1419 +  Int p;                           /* working precision  */
  1.1420 +  Int t;                           /* digits in exponent of A  */
  1.1421 +
  1.1422 +  /* buffers for a and b working decimals  */
  1.1423 +  /* (adjustment calculator, same size)  */
  1.1424 +  decNumber bufa[D2N(DECBUFFER+2)];
  1.1425 +  decNumber *allocbufa=NULL;       /* -> allocated bufa, iff allocated  */
  1.1426 +  decNumber *a=bufa;               /* temporary a  */
  1.1427 +  decNumber bufb[D2N(DECBUFFER+2)];
  1.1428 +  decNumber *allocbufb=NULL;       /* -> allocated bufb, iff allocated  */
  1.1429 +  decNumber *b=bufb;               /* temporary b  */
  1.1430 +  decNumber bufw[D2N(10)];         /* working 2-10 digit number  */
  1.1431 +  decNumber *w=bufw;               /* ..  */
  1.1432 +  #if DECSUBSET
  1.1433 +  decNumber *allocrhs=NULL;        /* non-NULL if rounded rhs allocated  */
  1.1434 +  #endif
  1.1435 +
  1.1436 +  decContext aset;                 /* working context  */
  1.1437 +
  1.1438 +  #if DECCHECK
  1.1439 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  1.1440 +  #endif
  1.1441 +
  1.1442 +  /* Check restrictions; this is a math function; if not violated  */
  1.1443 +  /* then carry out the operation.  */
  1.1444 +  if (!decCheckMath(rhs, set, &status)) do { /* protect malloc  */
  1.1445 +    #if DECSUBSET
  1.1446 +    if (!set->extended) {
  1.1447 +      /* reduce operand and set lostDigits status, as needed  */
  1.1448 +      if (rhs->digits>set->digits) {
  1.1449 +        allocrhs=decRoundOperand(rhs, set, &status);
  1.1450 +        if (allocrhs==NULL) break;
  1.1451 +        rhs=allocrhs;
  1.1452 +        }
  1.1453 +      /* special check in subset for rhs=0  */
  1.1454 +      if (ISZERO(rhs)) {                /* +/- zeros -> error  */
  1.1455 +        status|=DEC_Invalid_operation;
  1.1456 +        break;}
  1.1457 +      } /* extended=0  */
  1.1458 +    #endif
  1.1459 +
  1.1460 +    uprv_decContextDefault(&aset, DEC_INIT_DECIMAL64); /* clean context  */
  1.1461 +
  1.1462 +    /* handle exact powers of 10; only check if +ve finite  */
  1.1463 +    if (!(rhs->bits&(DECNEG|DECSPECIAL)) && !ISZERO(rhs)) {
  1.1464 +      Int residue=0;               /* (no residue)  */
  1.1465 +      uInt copystat=0;             /* clean status  */
  1.1466 +
  1.1467 +      /* round to a single digit...  */
  1.1468 +      aset.digits=1;
  1.1469 +      decCopyFit(w, rhs, &aset, &residue, &copystat); /* copy & shorten  */
  1.1470 +      /* if exact and the digit is 1, rhs is a power of 10  */
  1.1471 +      if (!(copystat&DEC_Inexact) && w->lsu[0]==1) {
  1.1472 +        /* the exponent, conveniently, is the power of 10; making  */
  1.1473 +        /* this the result needs a little care as it might not fit,  */
  1.1474 +        /* so first convert it into the working number, and then move  */
  1.1475 +        /* to res  */
  1.1476 +        uprv_decNumberFromInt32(w, w->exponent);
  1.1477 +        residue=0;
  1.1478 +        decCopyFit(res, w, set, &residue, &status); /* copy & round  */
  1.1479 +        decFinish(res, set, &residue, &status);     /* cleanup/set flags  */
  1.1480 +        break;
  1.1481 +        } /* not a power of 10  */
  1.1482 +      } /* not a candidate for exact  */
  1.1483 +
  1.1484 +    /* simplify the information-content calculation to use 'total  */
  1.1485 +    /* number of digits in a, including exponent' as compared to the  */
  1.1486 +    /* requested digits, as increasing this will only rarely cost an  */
  1.1487 +    /* iteration in ln(a) anyway  */
  1.1488 +    t=6;                                /* it can never be >6  */
  1.1489 +
  1.1490 +    /* allocate space when needed...  */
  1.1491 +    p=(rhs->digits+t>set->digits?rhs->digits+t:set->digits)+3;
  1.1492 +    needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
  1.1493 +    if (needbytes>sizeof(bufa)) {       /* need malloc space  */
  1.1494 +      allocbufa=(decNumber *)malloc(needbytes);
  1.1495 +      if (allocbufa==NULL) {            /* hopeless -- abandon  */
  1.1496 +        status|=DEC_Insufficient_storage;
  1.1497 +        break;}
  1.1498 +      a=allocbufa;                      /* use the allocated space  */
  1.1499 +      }
  1.1500 +    aset.digits=p;                      /* as calculated  */
  1.1501 +    aset.emax=DEC_MAX_MATH;             /* usual bounds  */
  1.1502 +    aset.emin=-DEC_MAX_MATH;            /* ..  */
  1.1503 +    aset.clamp=0;                       /* and no concrete format  */
  1.1504 +    decLnOp(a, rhs, &aset, &status);    /* a=ln(rhs)  */
  1.1505 +
  1.1506 +    /* skip the division if the result so far is infinite, NaN, or  */
  1.1507 +    /* zero, or there was an error; note NaN from sNaN needs copy  */
  1.1508 +    if (status&DEC_NaNs && !(status&DEC_sNaN)) break;
  1.1509 +    if (a->bits&DECSPECIAL || ISZERO(a)) {
  1.1510 +      uprv_decNumberCopy(res, a);            /* [will fit]  */
  1.1511 +      break;}
  1.1512 +
  1.1513 +    /* for ln(10) an extra 3 digits of precision are needed  */
  1.1514 +    p=set->digits+3;
  1.1515 +    needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
  1.1516 +    if (needbytes>sizeof(bufb)) {       /* need malloc space  */
  1.1517 +      allocbufb=(decNumber *)malloc(needbytes);
  1.1518 +      if (allocbufb==NULL) {            /* hopeless -- abandon  */
  1.1519 +        status|=DEC_Insufficient_storage;
  1.1520 +        break;}
  1.1521 +      b=allocbufb;                      /* use the allocated space  */
  1.1522 +      }
  1.1523 +    uprv_decNumberZero(w);                   /* set up 10...  */
  1.1524 +    #if DECDPUN==1
  1.1525 +    w->lsu[1]=1; w->lsu[0]=0;           /* ..  */
  1.1526 +    #else
  1.1527 +    w->lsu[0]=10;                       /* ..  */
  1.1528 +    #endif
  1.1529 +    w->digits=2;                        /* ..  */
  1.1530 +
  1.1531 +    aset.digits=p;
  1.1532 +    decLnOp(b, w, &aset, &ignore);      /* b=ln(10)  */
  1.1533 +
  1.1534 +    aset.digits=set->digits;            /* for final divide  */
  1.1535 +    decDivideOp(res, a, b, &aset, DIVIDE, &status); /* into result  */
  1.1536 +    } while(0);                         /* [for break]  */
  1.1537 +
  1.1538 +  if (allocbufa!=NULL) free(allocbufa); /* drop any storage used  */
  1.1539 +  if (allocbufb!=NULL) free(allocbufb); /* ..  */
  1.1540 +  #if DECSUBSET
  1.1541 +  if (allocrhs !=NULL) free(allocrhs);  /* ..  */
  1.1542 +  #endif
  1.1543 +  /* apply significant status  */
  1.1544 +  if (status!=0) decStatus(res, status, set);
  1.1545 +  #if DECCHECK
  1.1546 +  decCheckInexact(res, set);
  1.1547 +  #endif
  1.1548 +  return res;
  1.1549 +  } /* decNumberLog10  */
  1.1550 +#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
  1.1551 +#pragma GCC diagnostic pop
  1.1552 +#endif
  1.1553 +
  1.1554 +/* ------------------------------------------------------------------ */
  1.1555 +/* decNumberMax -- compare two Numbers and return the maximum         */
  1.1556 +/*                                                                    */
  1.1557 +/*   This computes C = A ? B, returning the maximum by 754 rules      */
  1.1558 +/*                                                                    */
  1.1559 +/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
  1.1560 +/*   lhs is A                                                         */
  1.1561 +/*   rhs is B                                                         */
  1.1562 +/*   set is the context                                               */
  1.1563 +/*                                                                    */
  1.1564 +/* C must have space for set->digits digits.                          */
  1.1565 +/* ------------------------------------------------------------------ */
  1.1566 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberMax(decNumber *res, const decNumber *lhs,
  1.1567 +                         const decNumber *rhs, decContext *set) {
  1.1568 +  uInt status=0;                        /* accumulator  */
  1.1569 +  decCompareOp(res, lhs, rhs, set, COMPMAX, &status);
  1.1570 +  if (status!=0) decStatus(res, status, set);
  1.1571 +  #if DECCHECK
  1.1572 +  decCheckInexact(res, set);
  1.1573 +  #endif
  1.1574 +  return res;
  1.1575 +  } /* decNumberMax  */
  1.1576 +
  1.1577 +/* ------------------------------------------------------------------ */
  1.1578 +/* decNumberMaxMag -- compare and return the maximum by magnitude     */
  1.1579 +/*                                                                    */
  1.1580 +/*   This computes C = A ? B, returning the maximum by 754 rules      */
  1.1581 +/*                                                                    */
  1.1582 +/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
  1.1583 +/*   lhs is A                                                         */
  1.1584 +/*   rhs is B                                                         */
  1.1585 +/*   set is the context                                               */
  1.1586 +/*                                                                    */
  1.1587 +/* C must have space for set->digits digits.                          */
  1.1588 +/* ------------------------------------------------------------------ */
  1.1589 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberMaxMag(decNumber *res, const decNumber *lhs,
  1.1590 +                         const decNumber *rhs, decContext *set) {
  1.1591 +  uInt status=0;                        /* accumulator  */
  1.1592 +  decCompareOp(res, lhs, rhs, set, COMPMAXMAG, &status);
  1.1593 +  if (status!=0) decStatus(res, status, set);
  1.1594 +  #if DECCHECK
  1.1595 +  decCheckInexact(res, set);
  1.1596 +  #endif
  1.1597 +  return res;
  1.1598 +  } /* decNumberMaxMag  */
  1.1599 +
  1.1600 +/* ------------------------------------------------------------------ */
  1.1601 +/* decNumberMin -- compare two Numbers and return the minimum         */
  1.1602 +/*                                                                    */
  1.1603 +/*   This computes C = A ? B, returning the minimum by 754 rules      */
  1.1604 +/*                                                                    */
  1.1605 +/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
  1.1606 +/*   lhs is A                                                         */
  1.1607 +/*   rhs is B                                                         */
  1.1608 +/*   set is the context                                               */
  1.1609 +/*                                                                    */
  1.1610 +/* C must have space for set->digits digits.                          */
  1.1611 +/* ------------------------------------------------------------------ */
  1.1612 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberMin(decNumber *res, const decNumber *lhs,
  1.1613 +                         const decNumber *rhs, decContext *set) {
  1.1614 +  uInt status=0;                        /* accumulator  */
  1.1615 +  decCompareOp(res, lhs, rhs, set, COMPMIN, &status);
  1.1616 +  if (status!=0) decStatus(res, status, set);
  1.1617 +  #if DECCHECK
  1.1618 +  decCheckInexact(res, set);
  1.1619 +  #endif
  1.1620 +  return res;
  1.1621 +  } /* decNumberMin  */
  1.1622 +
  1.1623 +/* ------------------------------------------------------------------ */
  1.1624 +/* decNumberMinMag -- compare and return the minimum by magnitude     */
  1.1625 +/*                                                                    */
  1.1626 +/*   This computes C = A ? B, returning the minimum by 754 rules      */
  1.1627 +/*                                                                    */
  1.1628 +/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
  1.1629 +/*   lhs is A                                                         */
  1.1630 +/*   rhs is B                                                         */
  1.1631 +/*   set is the context                                               */
  1.1632 +/*                                                                    */
  1.1633 +/* C must have space for set->digits digits.                          */
  1.1634 +/* ------------------------------------------------------------------ */
  1.1635 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberMinMag(decNumber *res, const decNumber *lhs,
  1.1636 +                         const decNumber *rhs, decContext *set) {
  1.1637 +  uInt status=0;                        /* accumulator  */
  1.1638 +  decCompareOp(res, lhs, rhs, set, COMPMINMAG, &status);
  1.1639 +  if (status!=0) decStatus(res, status, set);
  1.1640 +  #if DECCHECK
  1.1641 +  decCheckInexact(res, set);
  1.1642 +  #endif
  1.1643 +  return res;
  1.1644 +  } /* decNumberMinMag  */
  1.1645 +
  1.1646 +/* ------------------------------------------------------------------ */
  1.1647 +/* decNumberMinus -- prefix minus operator                            */
  1.1648 +/*                                                                    */
  1.1649 +/*   This computes C = 0 - A                                          */
  1.1650 +/*                                                                    */
  1.1651 +/*   res is C, the result.  C may be A                                */
  1.1652 +/*   rhs is A                                                         */
  1.1653 +/*   set is the context                                               */
  1.1654 +/*                                                                    */
  1.1655 +/* See also decNumberCopyNegate for a quiet bitwise version of this.  */
  1.1656 +/* C must have space for set->digits digits.                          */
  1.1657 +/* ------------------------------------------------------------------ */
  1.1658 +/* Simply use AddOp for the subtract, which will do the necessary.    */
  1.1659 +/* ------------------------------------------------------------------ */
  1.1660 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberMinus(decNumber *res, const decNumber *rhs,
  1.1661 +                           decContext *set) {
  1.1662 +  decNumber dzero;
  1.1663 +  uInt status=0;                        /* accumulator  */
  1.1664 +
  1.1665 +  #if DECCHECK
  1.1666 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  1.1667 +  #endif
  1.1668 +
  1.1669 +  uprv_decNumberZero(&dzero);                /* make 0  */
  1.1670 +  dzero.exponent=rhs->exponent;         /* [no coefficient expansion]  */
  1.1671 +  decAddOp(res, &dzero, rhs, set, DECNEG, &status);
  1.1672 +  if (status!=0) decStatus(res, status, set);
  1.1673 +  #if DECCHECK
  1.1674 +  decCheckInexact(res, set);
  1.1675 +  #endif
  1.1676 +  return res;
  1.1677 +  } /* decNumberMinus  */
  1.1678 +
  1.1679 +/* ------------------------------------------------------------------ */
  1.1680 +/* decNumberNextMinus -- next towards -Infinity                       */
  1.1681 +/*                                                                    */
  1.1682 +/*   This computes C = A - infinitesimal, rounded towards -Infinity   */
  1.1683 +/*                                                                    */
  1.1684 +/*   res is C, the result.  C may be A                                */
  1.1685 +/*   rhs is A                                                         */
  1.1686 +/*   set is the context                                               */
  1.1687 +/*                                                                    */
  1.1688 +/* This is a generalization of 754 NextDown.                          */
  1.1689 +/* ------------------------------------------------------------------ */
  1.1690 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberNextMinus(decNumber *res, const decNumber *rhs,
  1.1691 +                               decContext *set) {
  1.1692 +  decNumber dtiny;                           /* constant  */
  1.1693 +  decContext workset=*set;                   /* work  */
  1.1694 +  uInt status=0;                             /* accumulator  */
  1.1695 +  #if DECCHECK
  1.1696 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  1.1697 +  #endif
  1.1698 +
  1.1699 +  /* +Infinity is the special case  */
  1.1700 +  if ((rhs->bits&(DECINF|DECNEG))==DECINF) {
  1.1701 +    decSetMaxValue(res, set);                /* is +ve  */
  1.1702 +    /* there is no status to set  */
  1.1703 +    return res;
  1.1704 +    }
  1.1705 +  uprv_decNumberZero(&dtiny);                     /* start with 0  */
  1.1706 +  dtiny.lsu[0]=1;                            /* make number that is ..  */
  1.1707 +  dtiny.exponent=DEC_MIN_EMIN-1;             /* .. smaller than tiniest  */
  1.1708 +  workset.round=DEC_ROUND_FLOOR;
  1.1709 +  decAddOp(res, rhs, &dtiny, &workset, DECNEG, &status);
  1.1710 +  status&=DEC_Invalid_operation|DEC_sNaN;    /* only sNaN Invalid please  */
  1.1711 +  if (status!=0) decStatus(res, status, set);
  1.1712 +  return res;
  1.1713 +  } /* decNumberNextMinus  */
  1.1714 +
  1.1715 +/* ------------------------------------------------------------------ */
  1.1716 +/* decNumberNextPlus -- next towards +Infinity                        */
  1.1717 +/*                                                                    */
  1.1718 +/*   This computes C = A + infinitesimal, rounded towards +Infinity   */
  1.1719 +/*                                                                    */
  1.1720 +/*   res is C, the result.  C may be A                                */
  1.1721 +/*   rhs is A                                                         */
  1.1722 +/*   set is the context                                               */
  1.1723 +/*                                                                    */
  1.1724 +/* This is a generalization of 754 NextUp.                            */
  1.1725 +/* ------------------------------------------------------------------ */
  1.1726 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberNextPlus(decNumber *res, const decNumber *rhs,
  1.1727 +                              decContext *set) {
  1.1728 +  decNumber dtiny;                           /* constant  */
  1.1729 +  decContext workset=*set;                   /* work  */
  1.1730 +  uInt status=0;                             /* accumulator  */
  1.1731 +  #if DECCHECK
  1.1732 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  1.1733 +  #endif
  1.1734 +
  1.1735 +  /* -Infinity is the special case  */
  1.1736 +  if ((rhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
  1.1737 +    decSetMaxValue(res, set);
  1.1738 +    res->bits=DECNEG;                        /* negative  */
  1.1739 +    /* there is no status to set  */
  1.1740 +    return res;
  1.1741 +    }
  1.1742 +  uprv_decNumberZero(&dtiny);                     /* start with 0  */
  1.1743 +  dtiny.lsu[0]=1;                            /* make number that is ..  */
  1.1744 +  dtiny.exponent=DEC_MIN_EMIN-1;             /* .. smaller than tiniest  */
  1.1745 +  workset.round=DEC_ROUND_CEILING;
  1.1746 +  decAddOp(res, rhs, &dtiny, &workset, 0, &status);
  1.1747 +  status&=DEC_Invalid_operation|DEC_sNaN;    /* only sNaN Invalid please  */
  1.1748 +  if (status!=0) decStatus(res, status, set);
  1.1749 +  return res;
  1.1750 +  } /* decNumberNextPlus  */
  1.1751 +
  1.1752 +/* ------------------------------------------------------------------ */
  1.1753 +/* decNumberNextToward -- next towards rhs                            */
  1.1754 +/*                                                                    */
  1.1755 +/*   This computes C = A +/- infinitesimal, rounded towards           */
  1.1756 +/*   +/-Infinity in the direction of B, as per 754-1985 nextafter     */
  1.1757 +/*   modified during revision but dropped from 754-2008.              */
  1.1758 +/*                                                                    */
  1.1759 +/*   res is C, the result.  C may be A or B.                          */
  1.1760 +/*   lhs is A                                                         */
  1.1761 +/*   rhs is B                                                         */
  1.1762 +/*   set is the context                                               */
  1.1763 +/*                                                                    */
  1.1764 +/* This is a generalization of 754-1985 NextAfter.                    */
  1.1765 +/* ------------------------------------------------------------------ */
  1.1766 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberNextToward(decNumber *res, const decNumber *lhs,
  1.1767 +                                const decNumber *rhs, decContext *set) {
  1.1768 +  decNumber dtiny;                           /* constant  */
  1.1769 +  decContext workset=*set;                   /* work  */
  1.1770 +  Int result;                                /* ..  */
  1.1771 +  uInt status=0;                             /* accumulator  */
  1.1772 +  #if DECCHECK
  1.1773 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
  1.1774 +  #endif
  1.1775 +
  1.1776 +  if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) {
  1.1777 +    decNaNs(res, lhs, rhs, set, &status);
  1.1778 +    }
  1.1779 +   else { /* Is numeric, so no chance of sNaN Invalid, etc.  */
  1.1780 +    result=decCompare(lhs, rhs, 0);     /* sign matters  */
  1.1781 +    if (result==BADINT) status|=DEC_Insufficient_storage; /* rare  */
  1.1782 +     else { /* valid compare  */
  1.1783 +      if (result==0) uprv_decNumberCopySign(res, lhs, rhs); /* easy  */
  1.1784 +       else { /* differ: need NextPlus or NextMinus  */
  1.1785 +        uByte sub;                      /* add or subtract  */
  1.1786 +        if (result<0) {                 /* lhs<rhs, do nextplus  */
  1.1787 +          /* -Infinity is the special case  */
  1.1788 +          if ((lhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
  1.1789 +            decSetMaxValue(res, set);
  1.1790 +            res->bits=DECNEG;           /* negative  */
  1.1791 +            return res;                 /* there is no status to set  */
  1.1792 +            }
  1.1793 +          workset.round=DEC_ROUND_CEILING;
  1.1794 +          sub=0;                        /* add, please  */
  1.1795 +          } /* plus  */
  1.1796 +         else {                         /* lhs>rhs, do nextminus  */
  1.1797 +          /* +Infinity is the special case  */
  1.1798 +          if ((lhs->bits&(DECINF|DECNEG))==DECINF) {
  1.1799 +            decSetMaxValue(res, set);
  1.1800 +            return res;                 /* there is no status to set  */
  1.1801 +            }
  1.1802 +          workset.round=DEC_ROUND_FLOOR;
  1.1803 +          sub=DECNEG;                   /* subtract, please  */
  1.1804 +          } /* minus  */
  1.1805 +        uprv_decNumberZero(&dtiny);          /* start with 0  */
  1.1806 +        dtiny.lsu[0]=1;                 /* make number that is ..  */
  1.1807 +        dtiny.exponent=DEC_MIN_EMIN-1;  /* .. smaller than tiniest  */
  1.1808 +        decAddOp(res, lhs, &dtiny, &workset, sub, &status); /* + or -  */
  1.1809 +        /* turn off exceptions if the result is a normal number  */
  1.1810 +        /* (including Nmin), otherwise let all status through  */
  1.1811 +        if (uprv_decNumberIsNormal(res, set)) status=0;
  1.1812 +        } /* unequal  */
  1.1813 +      } /* compare OK  */
  1.1814 +    } /* numeric  */
  1.1815 +  if (status!=0) decStatus(res, status, set);
  1.1816 +  return res;
  1.1817 +  } /* decNumberNextToward  */
  1.1818 +
  1.1819 +/* ------------------------------------------------------------------ */
  1.1820 +/* decNumberOr -- OR two Numbers, digitwise                           */
  1.1821 +/*                                                                    */
  1.1822 +/*   This computes C = A | B                                          */
  1.1823 +/*                                                                    */
  1.1824 +/*   res is C, the result.  C may be A and/or B (e.g., X=X|X)         */
  1.1825 +/*   lhs is A                                                         */
  1.1826 +/*   rhs is B                                                         */
  1.1827 +/*   set is the context (used for result length and error report)     */
  1.1828 +/*                                                                    */
  1.1829 +/* C must have space for set->digits digits.                          */
  1.1830 +/*                                                                    */
  1.1831 +/* Logical function restrictions apply (see above); a NaN is          */
  1.1832 +/* returned with Invalid_operation if a restriction is violated.      */
  1.1833 +/* ------------------------------------------------------------------ */
  1.1834 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberOr(decNumber *res, const decNumber *lhs,
  1.1835 +                        const decNumber *rhs, decContext *set) {
  1.1836 +  const Unit *ua, *ub;                  /* -> operands  */
  1.1837 +  const Unit *msua, *msub;              /* -> operand msus  */
  1.1838 +  Unit  *uc, *msuc;                     /* -> result and its msu  */
  1.1839 +  Int   msudigs;                        /* digits in res msu  */
  1.1840 +  #if DECCHECK
  1.1841 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
  1.1842 +  #endif
  1.1843 +
  1.1844 +  if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
  1.1845 +   || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
  1.1846 +    decStatus(res, DEC_Invalid_operation, set);
  1.1847 +    return res;
  1.1848 +    }
  1.1849 +  /* operands are valid  */
  1.1850 +  ua=lhs->lsu;                          /* bottom-up  */
  1.1851 +  ub=rhs->lsu;                          /* ..  */
  1.1852 +  uc=res->lsu;                          /* ..  */
  1.1853 +  msua=ua+D2U(lhs->digits)-1;           /* -> msu of lhs  */
  1.1854 +  msub=ub+D2U(rhs->digits)-1;           /* -> msu of rhs  */
  1.1855 +  msuc=uc+D2U(set->digits)-1;           /* -> msu of result  */
  1.1856 +  msudigs=MSUDIGITS(set->digits);       /* [faster than remainder]  */
  1.1857 +  for (; uc<=msuc; ua++, ub++, uc++) {  /* Unit loop  */
  1.1858 +    Unit a, b;                          /* extract units  */
  1.1859 +    if (ua>msua) a=0;
  1.1860 +     else a=*ua;
  1.1861 +    if (ub>msub) b=0;
  1.1862 +     else b=*ub;
  1.1863 +    *uc=0;                              /* can now write back  */
  1.1864 +    if (a|b) {                          /* maybe 1 bits to examine  */
  1.1865 +      Int i, j;
  1.1866 +      /* This loop could be unrolled and/or use BIN2BCD tables  */
  1.1867 +      for (i=0; i<DECDPUN; i++) {
  1.1868 +        if ((a|b)&1) *uc=*uc+(Unit)powers[i];     /* effect OR  */
  1.1869 +        j=a%10;
  1.1870 +        a=a/10;
  1.1871 +        j|=b%10;
  1.1872 +        b=b/10;
  1.1873 +        if (j>1) {
  1.1874 +          decStatus(res, DEC_Invalid_operation, set);
  1.1875 +          return res;
  1.1876 +          }
  1.1877 +        if (uc==msuc && i==msudigs-1) break;      /* just did final digit  */
  1.1878 +        } /* each digit  */
  1.1879 +      } /* non-zero  */
  1.1880 +    } /* each unit  */
  1.1881 +  /* [here uc-1 is the msu of the result]  */
  1.1882 +  res->digits=decGetDigits(res->lsu, uc-res->lsu);
  1.1883 +  res->exponent=0;                      /* integer  */
  1.1884 +  res->bits=0;                          /* sign=0  */
  1.1885 +  return res;  /* [no status to set]  */
  1.1886 +  } /* decNumberOr  */
  1.1887 +
  1.1888 +/* ------------------------------------------------------------------ */
  1.1889 +/* decNumberPlus -- prefix plus operator                              */
  1.1890 +/*                                                                    */
  1.1891 +/*   This computes C = 0 + A                                          */
  1.1892 +/*                                                                    */
  1.1893 +/*   res is C, the result.  C may be A                                */
  1.1894 +/*   rhs is A                                                         */
  1.1895 +/*   set is the context                                               */
  1.1896 +/*                                                                    */
  1.1897 +/* See also decNumberCopy for a quiet bitwise version of this.        */
  1.1898 +/* C must have space for set->digits digits.                          */
  1.1899 +/* ------------------------------------------------------------------ */
  1.1900 +/* This simply uses AddOp; Add will take fast path after preparing A. */
  1.1901 +/* Performance is a concern here, as this routine is often used to    */
  1.1902 +/* check operands and apply rounding and overflow/underflow testing.  */
  1.1903 +/* ------------------------------------------------------------------ */
  1.1904 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberPlus(decNumber *res, const decNumber *rhs,
  1.1905 +                          decContext *set) {
  1.1906 +  decNumber dzero;
  1.1907 +  uInt status=0;                        /* accumulator  */
  1.1908 +  #if DECCHECK
  1.1909 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  1.1910 +  #endif
  1.1911 +
  1.1912 +  uprv_decNumberZero(&dzero);                /* make 0  */
  1.1913 +  dzero.exponent=rhs->exponent;         /* [no coefficient expansion]  */
  1.1914 +  decAddOp(res, &dzero, rhs, set, 0, &status);
  1.1915 +  if (status!=0) decStatus(res, status, set);
  1.1916 +  #if DECCHECK
  1.1917 +  decCheckInexact(res, set);
  1.1918 +  #endif
  1.1919 +  return res;
  1.1920 +  } /* decNumberPlus  */
  1.1921 +
  1.1922 +/* ------------------------------------------------------------------ */
  1.1923 +/* decNumberMultiply -- multiply two Numbers                          */
  1.1924 +/*                                                                    */
  1.1925 +/*   This computes C = A x B                                          */
  1.1926 +/*                                                                    */
  1.1927 +/*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
  1.1928 +/*   lhs is A                                                         */
  1.1929 +/*   rhs is B                                                         */
  1.1930 +/*   set is the context                                               */
  1.1931 +/*                                                                    */
  1.1932 +/* C must have space for set->digits digits.                          */
  1.1933 +/* ------------------------------------------------------------------ */
  1.1934 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberMultiply(decNumber *res, const decNumber *lhs,
  1.1935 +                              const decNumber *rhs, decContext *set) {
  1.1936 +  uInt status=0;                   /* accumulator  */
  1.1937 +  decMultiplyOp(res, lhs, rhs, set, &status);
  1.1938 +  if (status!=0) decStatus(res, status, set);
  1.1939 +  #if DECCHECK
  1.1940 +  decCheckInexact(res, set);
  1.1941 +  #endif
  1.1942 +  return res;
  1.1943 +  } /* decNumberMultiply  */
  1.1944 +
  1.1945 +/* ------------------------------------------------------------------ */
  1.1946 +/* decNumberPower -- raise a number to a power                        */
  1.1947 +/*                                                                    */
  1.1948 +/*   This computes C = A ** B                                         */
  1.1949 +/*                                                                    */
  1.1950 +/*   res is C, the result.  C may be A and/or B (e.g., X=X**X)        */
  1.1951 +/*   lhs is A                                                         */
  1.1952 +/*   rhs is B                                                         */
  1.1953 +/*   set is the context                                               */
  1.1954 +/*                                                                    */
  1.1955 +/* C must have space for set->digits digits.                          */
  1.1956 +/*                                                                    */
  1.1957 +/* Mathematical function restrictions apply (see above); a NaN is     */
  1.1958 +/* returned with Invalid_operation if a restriction is violated.      */
  1.1959 +/*                                                                    */
  1.1960 +/* However, if 1999999997<=B<=999999999 and B is an integer then the  */
  1.1961 +/* restrictions on A and the context are relaxed to the usual bounds, */
  1.1962 +/* for compatibility with the earlier (integer power only) version    */
  1.1963 +/* of this function.                                                  */
  1.1964 +/*                                                                    */
  1.1965 +/* When B is an integer, the result may be exact, even if rounded.    */
  1.1966 +/*                                                                    */
  1.1967 +/* The final result is rounded according to the context; it will      */
  1.1968 +/* almost always be correctly rounded, but may be up to 1 ulp in      */
  1.1969 +/* error in rare cases.                                               */
  1.1970 +/* ------------------------------------------------------------------ */
  1.1971 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberPower(decNumber *res, const decNumber *lhs,
  1.1972 +                           const decNumber *rhs, decContext *set) {
  1.1973 +  #if DECSUBSET
  1.1974 +  decNumber *alloclhs=NULL;        /* non-NULL if rounded lhs allocated  */
  1.1975 +  decNumber *allocrhs=NULL;        /* .., rhs  */
  1.1976 +  #endif
  1.1977 +  decNumber *allocdac=NULL;        /* -> allocated acc buffer, iff used  */
  1.1978 +  decNumber *allocinv=NULL;        /* -> allocated 1/x buffer, iff used  */
  1.1979 +  Int   reqdigits=set->digits;     /* requested DIGITS  */
  1.1980 +  Int   n;                         /* rhs in binary  */
  1.1981 +  Flag  rhsint=0;                  /* 1 if rhs is an integer  */
  1.1982 +  Flag  useint=0;                  /* 1 if can use integer calculation  */
  1.1983 +  Flag  isoddint=0;                /* 1 if rhs is an integer and odd  */
  1.1984 +  Int   i;                         /* work  */
  1.1985 +  #if DECSUBSET
  1.1986 +  Int   dropped;                   /* ..  */
  1.1987 +  #endif
  1.1988 +  uInt  needbytes;                 /* buffer size needed  */
  1.1989 +  Flag  seenbit;                   /* seen a bit while powering  */
  1.1990 +  Int   residue=0;                 /* rounding residue  */
  1.1991 +  uInt  status=0;                  /* accumulators  */
  1.1992 +  uByte bits=0;                    /* result sign if errors  */
  1.1993 +  decContext aset;                 /* working context  */
  1.1994 +  decNumber dnOne;                 /* work value 1...  */
  1.1995 +  /* local accumulator buffer [a decNumber, with digits+elength+1 digits]  */
  1.1996 +  decNumber dacbuff[D2N(DECBUFFER+9)];
  1.1997 +  decNumber *dac=dacbuff;          /* -> result accumulator  */
  1.1998 +  /* same again for possible 1/lhs calculation  */
  1.1999 +  decNumber invbuff[D2N(DECBUFFER+9)];
  1.2000 +
  1.2001 +  #if DECCHECK
  1.2002 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
  1.2003 +  #endif
  1.2004 +
  1.2005 +  do {                             /* protect allocated storage  */
  1.2006 +    #if DECSUBSET
  1.2007 +    if (!set->extended) { /* reduce operands and set status, as needed  */
  1.2008 +      if (lhs->digits>reqdigits) {
  1.2009 +        alloclhs=decRoundOperand(lhs, set, &status);
  1.2010 +        if (alloclhs==NULL) break;
  1.2011 +        lhs=alloclhs;
  1.2012 +        }
  1.2013 +      if (rhs->digits>reqdigits) {
  1.2014 +        allocrhs=decRoundOperand(rhs, set, &status);
  1.2015 +        if (allocrhs==NULL) break;
  1.2016 +        rhs=allocrhs;
  1.2017 +        }
  1.2018 +      }
  1.2019 +    #endif
  1.2020 +    /* [following code does not require input rounding]  */
  1.2021 +
  1.2022 +    /* handle NaNs and rhs Infinity (lhs infinity is harder)  */
  1.2023 +    if (SPECIALARGS) {
  1.2024 +      if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) { /* NaNs  */
  1.2025 +        decNaNs(res, lhs, rhs, set, &status);
  1.2026 +        break;}
  1.2027 +      if (decNumberIsInfinite(rhs)) {   /* rhs Infinity  */
  1.2028 +        Flag rhsneg=rhs->bits&DECNEG;   /* save rhs sign  */
  1.2029 +        if (decNumberIsNegative(lhs)    /* lhs<0  */
  1.2030 +         && !decNumberIsZero(lhs))      /* ..  */
  1.2031 +          status|=DEC_Invalid_operation;
  1.2032 +         else {                         /* lhs >=0  */
  1.2033 +          uprv_decNumberZero(&dnOne);        /* set up 1  */
  1.2034 +          dnOne.lsu[0]=1;
  1.2035 +          uprv_decNumberCompare(dac, lhs, &dnOne, set); /* lhs ? 1  */
  1.2036 +          uprv_decNumberZero(res);           /* prepare for 0/1/Infinity  */
  1.2037 +          if (decNumberIsNegative(dac)) {    /* lhs<1  */
  1.2038 +            if (rhsneg) res->bits|=DECINF;   /* +Infinity [else is +0]  */
  1.2039 +            }
  1.2040 +           else if (dac->lsu[0]==0) {        /* lhs=1  */
  1.2041 +            /* 1**Infinity is inexact, so return fully-padded 1.0000  */
  1.2042 +            Int shift=set->digits-1;
  1.2043 +            *res->lsu=1;                     /* was 0, make int 1  */
  1.2044 +            res->digits=decShiftToMost(res->lsu, 1, shift);
  1.2045 +            res->exponent=-shift;            /* make 1.0000...  */
  1.2046 +            status|=DEC_Inexact|DEC_Rounded; /* deemed inexact  */
  1.2047 +            }
  1.2048 +           else {                            /* lhs>1  */
  1.2049 +            if (!rhsneg) res->bits|=DECINF;  /* +Infinity [else is +0]  */
  1.2050 +            }
  1.2051 +          } /* lhs>=0  */
  1.2052 +        break;}
  1.2053 +      /* [lhs infinity drops through]  */
  1.2054 +      } /* specials  */
  1.2055 +
  1.2056 +    /* Original rhs may be an integer that fits and is in range  */
  1.2057 +    n=decGetInt(rhs);
  1.2058 +    if (n!=BADINT) {                    /* it is an integer  */
  1.2059 +      rhsint=1;                         /* record the fact for 1**n  */
  1.2060 +      isoddint=(Flag)n&1;               /* [works even if big]  */
  1.2061 +      if (n!=BIGEVEN && n!=BIGODD)      /* can use integer path?  */
  1.2062 +        useint=1;                       /* looks good  */
  1.2063 +      }
  1.2064 +
  1.2065 +    if (decNumberIsNegative(lhs)        /* -x ..  */
  1.2066 +      && isoddint) bits=DECNEG;         /* .. to an odd power  */
  1.2067 +
  1.2068 +    /* handle LHS infinity  */
  1.2069 +    if (decNumberIsInfinite(lhs)) {     /* [NaNs already handled]  */
  1.2070 +      uByte rbits=rhs->bits;            /* save  */
  1.2071 +      uprv_decNumberZero(res);               /* prepare  */
  1.2072 +      if (n==0) *res->lsu=1;            /* [-]Inf**0 => 1  */
  1.2073 +       else {
  1.2074 +        /* -Inf**nonint -> error  */
  1.2075 +        if (!rhsint && decNumberIsNegative(lhs)) {
  1.2076 +          status|=DEC_Invalid_operation;     /* -Inf**nonint is error  */
  1.2077 +          break;}
  1.2078 +        if (!(rbits & DECNEG)) bits|=DECINF; /* was not a **-n  */
  1.2079 +        /* [otherwise will be 0 or -0]  */
  1.2080 +        res->bits=bits;
  1.2081 +        }
  1.2082 +      break;}
  1.2083 +
  1.2084 +    /* similarly handle LHS zero  */
  1.2085 +    if (decNumberIsZero(lhs)) {
  1.2086 +      if (n==0) {                            /* 0**0 => Error  */
  1.2087 +        #if DECSUBSET
  1.2088 +        if (!set->extended) {                /* [unless subset]  */
  1.2089 +          uprv_decNumberZero(res);
  1.2090 +          *res->lsu=1;                       /* return 1  */
  1.2091 +          break;}
  1.2092 +        #endif
  1.2093 +        status|=DEC_Invalid_operation;
  1.2094 +        }
  1.2095 +       else {                                /* 0**x  */
  1.2096 +        uByte rbits=rhs->bits;               /* save  */
  1.2097 +        if (rbits & DECNEG) {                /* was a 0**(-n)  */
  1.2098 +          #if DECSUBSET
  1.2099 +          if (!set->extended) {              /* [bad if subset]  */
  1.2100 +            status|=DEC_Invalid_operation;
  1.2101 +            break;}
  1.2102 +          #endif
  1.2103 +          bits|=DECINF;
  1.2104 +          }
  1.2105 +        uprv_decNumberZero(res);                  /* prepare  */
  1.2106 +        /* [otherwise will be 0 or -0]  */
  1.2107 +        res->bits=bits;
  1.2108 +        }
  1.2109 +      break;}
  1.2110 +
  1.2111 +    /* here both lhs and rhs are finite; rhs==0 is handled in the  */
  1.2112 +    /* integer path.  Next handle the non-integer cases  */
  1.2113 +    if (!useint) {                      /* non-integral rhs  */
  1.2114 +      /* any -ve lhs is bad, as is either operand or context out of  */
  1.2115 +      /* bounds  */
  1.2116 +      if (decNumberIsNegative(lhs)) {
  1.2117 +        status|=DEC_Invalid_operation;
  1.2118 +        break;}
  1.2119 +      if (decCheckMath(lhs, set, &status)
  1.2120 +       || decCheckMath(rhs, set, &status)) break; /* variable status  */
  1.2121 +
  1.2122 +      uprv_decContextDefault(&aset, DEC_INIT_DECIMAL64); /* clean context  */
  1.2123 +      aset.emax=DEC_MAX_MATH;           /* usual bounds  */
  1.2124 +      aset.emin=-DEC_MAX_MATH;          /* ..  */
  1.2125 +      aset.clamp=0;                     /* and no concrete format  */
  1.2126 +
  1.2127 +      /* calculate the result using exp(ln(lhs)*rhs), which can  */
  1.2128 +      /* all be done into the accumulator, dac.  The precision needed  */
  1.2129 +      /* is enough to contain the full information in the lhs (which  */
  1.2130 +      /* is the total digits, including exponent), or the requested  */
  1.2131 +      /* precision, if larger, + 4; 6 is used for the exponent  */
  1.2132 +      /* maximum length, and this is also used when it is shorter  */
  1.2133 +      /* than the requested digits as it greatly reduces the >0.5 ulp  */
  1.2134 +      /* cases at little cost (because Ln doubles digits each  */
  1.2135 +      /* iteration so a few extra digits rarely causes an extra  */
  1.2136 +      /* iteration)  */
  1.2137 +      aset.digits=MAXI(lhs->digits, set->digits)+6+4;
  1.2138 +      } /* non-integer rhs  */
  1.2139 +
  1.2140 +     else { /* rhs is in-range integer  */
  1.2141 +      if (n==0) {                       /* x**0 = 1  */
  1.2142 +        /* (0**0 was handled above)  */
  1.2143 +        uprv_decNumberZero(res);             /* result=1  */
  1.2144 +        *res->lsu=1;                    /* ..  */
  1.2145 +        break;}
  1.2146 +      /* rhs is a non-zero integer  */
  1.2147 +      if (n<0) n=-n;                    /* use abs(n)  */
  1.2148 +
  1.2149 +      aset=*set;                        /* clone the context  */
  1.2150 +      aset.round=DEC_ROUND_HALF_EVEN;   /* internally use balanced  */
  1.2151 +      /* calculate the working DIGITS  */
  1.2152 +      aset.digits=reqdigits+(rhs->digits+rhs->exponent)+2;
  1.2153 +      #if DECSUBSET
  1.2154 +      if (!set->extended) aset.digits--;     /* use classic precision  */
  1.2155 +      #endif
  1.2156 +      /* it's an error if this is more than can be handled  */
  1.2157 +      if (aset.digits>DECNUMMAXP) {status|=DEC_Invalid_operation; break;}
  1.2158 +      } /* integer path  */
  1.2159 +
  1.2160 +    /* aset.digits is the count of digits for the accumulator needed  */
  1.2161 +    /* if accumulator is too long for local storage, then allocate  */
  1.2162 +    needbytes=sizeof(decNumber)+(D2U(aset.digits)-1)*sizeof(Unit);
  1.2163 +    /* [needbytes also used below if 1/lhs needed]  */
  1.2164 +    if (needbytes>sizeof(dacbuff)) {
  1.2165 +      allocdac=(decNumber *)malloc(needbytes);
  1.2166 +      if (allocdac==NULL) {   /* hopeless -- abandon  */
  1.2167 +        status|=DEC_Insufficient_storage;
  1.2168 +        break;}
  1.2169 +      dac=allocdac;           /* use the allocated space  */
  1.2170 +      }
  1.2171 +    /* here, aset is set up and accumulator is ready for use  */
  1.2172 +
  1.2173 +    if (!useint) {                           /* non-integral rhs  */
  1.2174 +      /* x ** y; special-case x=1 here as it will otherwise always  */
  1.2175 +      /* reduce to integer 1; decLnOp has a fastpath which detects  */
  1.2176 +      /* the case of x=1  */
  1.2177 +      decLnOp(dac, lhs, &aset, &status);     /* dac=ln(lhs)  */
  1.2178 +      /* [no error possible, as lhs 0 already handled]  */
  1.2179 +      if (ISZERO(dac)) {                     /* x==1, 1.0, etc.  */
  1.2180 +        /* need to return fully-padded 1.0000 etc., but rhsint->1  */
  1.2181 +        *dac->lsu=1;                         /* was 0, make int 1  */
  1.2182 +        if (!rhsint) {                       /* add padding  */
  1.2183 +          Int shift=set->digits-1;
  1.2184 +          dac->digits=decShiftToMost(dac->lsu, 1, shift);
  1.2185 +          dac->exponent=-shift;              /* make 1.0000...  */
  1.2186 +          status|=DEC_Inexact|DEC_Rounded;   /* deemed inexact  */
  1.2187 +          }
  1.2188 +        }
  1.2189 +       else {
  1.2190 +        decMultiplyOp(dac, dac, rhs, &aset, &status);  /* dac=dac*rhs  */
  1.2191 +        decExpOp(dac, dac, &aset, &status);            /* dac=exp(dac)  */
  1.2192 +        }
  1.2193 +      /* and drop through for final rounding  */
  1.2194 +      } /* non-integer rhs  */
  1.2195 +
  1.2196 +     else {                             /* carry on with integer  */
  1.2197 +      uprv_decNumberZero(dac);               /* acc=1  */
  1.2198 +      *dac->lsu=1;                      /* ..  */
  1.2199 +
  1.2200 +      /* if a negative power the constant 1 is needed, and if not subset  */
  1.2201 +      /* invert the lhs now rather than inverting the result later  */
  1.2202 +      if (decNumberIsNegative(rhs)) {   /* was a **-n [hence digits>0]  */
  1.2203 +        decNumber *inv=invbuff;         /* asssume use fixed buffer  */
  1.2204 +        uprv_decNumberCopy(&dnOne, dac);     /* dnOne=1;  [needed now or later]  */
  1.2205 +        #if DECSUBSET
  1.2206 +        if (set->extended) {            /* need to calculate 1/lhs  */
  1.2207 +        #endif
  1.2208 +          /* divide lhs into 1, putting result in dac [dac=1/dac]  */
  1.2209 +          decDivideOp(dac, &dnOne, lhs, &aset, DIVIDE, &status);
  1.2210 +          /* now locate or allocate space for the inverted lhs  */
  1.2211 +          if (needbytes>sizeof(invbuff)) {
  1.2212 +            allocinv=(decNumber *)malloc(needbytes);
  1.2213 +            if (allocinv==NULL) {       /* hopeless -- abandon  */
  1.2214 +              status|=DEC_Insufficient_storage;
  1.2215 +              break;}
  1.2216 +            inv=allocinv;               /* use the allocated space  */
  1.2217 +            }
  1.2218 +          /* [inv now points to big-enough buffer or allocated storage]  */
  1.2219 +          uprv_decNumberCopy(inv, dac);      /* copy the 1/lhs  */
  1.2220 +          uprv_decNumberCopy(dac, &dnOne);   /* restore acc=1  */
  1.2221 +          lhs=inv;                      /* .. and go forward with new lhs  */
  1.2222 +        #if DECSUBSET
  1.2223 +          }
  1.2224 +        #endif
  1.2225 +        }
  1.2226 +
  1.2227 +      /* Raise-to-the-power loop...  */
  1.2228 +      seenbit=0;                   /* set once a 1-bit is encountered  */
  1.2229 +      for (i=1;;i++){              /* for each bit [top bit ignored]  */
  1.2230 +        /* abandon if had overflow or terminal underflow  */
  1.2231 +        if (status & (DEC_Overflow|DEC_Underflow)) { /* interesting?  */
  1.2232 +          if (status&DEC_Overflow || ISZERO(dac)) break;
  1.2233 +          }
  1.2234 +        /* [the following two lines revealed an optimizer bug in a C++  */
  1.2235 +        /* compiler, with symptom: 5**3 -> 25, when n=n+n was used]  */
  1.2236 +        n=n<<1;                    /* move next bit to testable position  */
  1.2237 +        if (n<0) {                 /* top bit is set  */
  1.2238 +          seenbit=1;               /* OK, significant bit seen  */
  1.2239 +          decMultiplyOp(dac, dac, lhs, &aset, &status); /* dac=dac*x  */
  1.2240 +          }
  1.2241 +        if (i==31) break;          /* that was the last bit  */
  1.2242 +        if (!seenbit) continue;    /* no need to square 1  */
  1.2243 +        decMultiplyOp(dac, dac, dac, &aset, &status); /* dac=dac*dac [square]  */
  1.2244 +        } /*i*/ /* 32 bits  */
  1.2245 +
  1.2246 +      /* complete internal overflow or underflow processing  */
  1.2247 +      if (status & (DEC_Overflow|DEC_Underflow)) {
  1.2248 +        #if DECSUBSET
  1.2249 +        /* If subset, and power was negative, reverse the kind of -erflow  */
  1.2250 +        /* [1/x not yet done]  */
  1.2251 +        if (!set->extended && decNumberIsNegative(rhs)) {
  1.2252 +          if (status & DEC_Overflow)
  1.2253 +            status^=DEC_Overflow | DEC_Underflow | DEC_Subnormal;
  1.2254 +           else { /* trickier -- Underflow may or may not be set  */
  1.2255 +            status&=~(DEC_Underflow | DEC_Subnormal); /* [one or both]  */
  1.2256 +            status|=DEC_Overflow;
  1.2257 +            }
  1.2258 +          }
  1.2259 +        #endif
  1.2260 +        dac->bits=(dac->bits & ~DECNEG) | bits; /* force correct sign  */
  1.2261 +        /* round subnormals [to set.digits rather than aset.digits]  */
  1.2262 +        /* or set overflow result similarly as required  */
  1.2263 +        decFinalize(dac, set, &residue, &status);
  1.2264 +        uprv_decNumberCopy(res, dac);   /* copy to result (is now OK length)  */
  1.2265 +        break;
  1.2266 +        }
  1.2267 +
  1.2268 +      #if DECSUBSET
  1.2269 +      if (!set->extended &&                  /* subset math  */
  1.2270 +          decNumberIsNegative(rhs)) {        /* was a **-n [hence digits>0]  */
  1.2271 +        /* so divide result into 1 [dac=1/dac]  */
  1.2272 +        decDivideOp(dac, &dnOne, dac, &aset, DIVIDE, &status);
  1.2273 +        }
  1.2274 +      #endif
  1.2275 +      } /* rhs integer path  */
  1.2276 +
  1.2277 +    /* reduce result to the requested length and copy to result  */
  1.2278 +    decCopyFit(res, dac, set, &residue, &status);
  1.2279 +    decFinish(res, set, &residue, &status);  /* final cleanup  */
  1.2280 +    #if DECSUBSET
  1.2281 +    if (!set->extended) decTrim(res, set, 0, 1, &dropped); /* trailing zeros  */
  1.2282 +    #endif
  1.2283 +    } while(0);                         /* end protected  */
  1.2284 +
  1.2285 +  if (allocdac!=NULL) free(allocdac);   /* drop any storage used  */
  1.2286 +  if (allocinv!=NULL) free(allocinv);   /* ..  */
  1.2287 +  #if DECSUBSET
  1.2288 +  if (alloclhs!=NULL) free(alloclhs);   /* ..  */
  1.2289 +  if (allocrhs!=NULL) free(allocrhs);   /* ..  */
  1.2290 +  #endif
  1.2291 +  if (status!=0) decStatus(res, status, set);
  1.2292 +  #if DECCHECK
  1.2293 +  decCheckInexact(res, set);
  1.2294 +  #endif
  1.2295 +  return res;
  1.2296 +  } /* decNumberPower  */
  1.2297 +
  1.2298 +/* ------------------------------------------------------------------ */
  1.2299 +/* decNumberQuantize -- force exponent to requested value             */
  1.2300 +/*                                                                    */
  1.2301 +/*   This computes C = op(A, B), where op adjusts the coefficient     */
  1.2302 +/*   of C (by rounding or shifting) such that the exponent (-scale)   */
  1.2303 +/*   of C has exponent of B.  The numerical value of C will equal A,  */
  1.2304 +/*   except for the effects of any rounding that occurred.            */
  1.2305 +/*                                                                    */
  1.2306 +/*   res is C, the result.  C may be A or B                           */
  1.2307 +/*   lhs is A, the number to adjust                                   */
  1.2308 +/*   rhs is B, the number with exponent to match                      */
  1.2309 +/*   set is the context                                               */
  1.2310 +/*                                                                    */
  1.2311 +/* C must have space for set->digits digits.                          */
  1.2312 +/*                                                                    */
  1.2313 +/* Unless there is an error or the result is infinite, the exponent   */
  1.2314 +/* after the operation is guaranteed to be equal to that of B.        */
  1.2315 +/* ------------------------------------------------------------------ */
  1.2316 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberQuantize(decNumber *res, const decNumber *lhs,
  1.2317 +                              const decNumber *rhs, decContext *set) {
  1.2318 +  uInt status=0;                        /* accumulator  */
  1.2319 +  decQuantizeOp(res, lhs, rhs, set, 1, &status);
  1.2320 +  if (status!=0) decStatus(res, status, set);
  1.2321 +  return res;
  1.2322 +  } /* decNumberQuantize  */
  1.2323 +
  1.2324 +/* ------------------------------------------------------------------ */
  1.2325 +/* decNumberReduce -- remove trailing zeros                           */
  1.2326 +/*                                                                    */
  1.2327 +/*   This computes C = 0 + A, and normalizes the result               */
  1.2328 +/*                                                                    */
  1.2329 +/*   res is C, the result.  C may be A                                */
  1.2330 +/*   rhs is A                                                         */
  1.2331 +/*   set is the context                                               */
  1.2332 +/*                                                                    */
  1.2333 +/* C must have space for set->digits digits.                          */
  1.2334 +/* ------------------------------------------------------------------ */
  1.2335 +/* Previously known as Normalize  */
  1.2336 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberNormalize(decNumber *res, const decNumber *rhs,
  1.2337 +                               decContext *set) {
  1.2338 +  return uprv_decNumberReduce(res, rhs, set);
  1.2339 +  } /* decNumberNormalize  */
  1.2340 +
  1.2341 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberReduce(decNumber *res, const decNumber *rhs,
  1.2342 +                            decContext *set) {
  1.2343 +  #if DECSUBSET
  1.2344 +  decNumber *allocrhs=NULL;        /* non-NULL if rounded rhs allocated  */
  1.2345 +  #endif
  1.2346 +  uInt status=0;                   /* as usual  */
  1.2347 +  Int  residue=0;                  /* as usual  */
  1.2348 +  Int  dropped;                    /* work  */
  1.2349 +
  1.2350 +  #if DECCHECK
  1.2351 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  1.2352 +  #endif
  1.2353 +
  1.2354 +  do {                             /* protect allocated storage  */
  1.2355 +    #if DECSUBSET
  1.2356 +    if (!set->extended) {
  1.2357 +      /* reduce operand and set lostDigits status, as needed  */
  1.2358 +      if (rhs->digits>set->digits) {
  1.2359 +        allocrhs=decRoundOperand(rhs, set, &status);
  1.2360 +        if (allocrhs==NULL) break;
  1.2361 +        rhs=allocrhs;
  1.2362 +        }
  1.2363 +      }
  1.2364 +    #endif
  1.2365 +    /* [following code does not require input rounding]  */
  1.2366 +
  1.2367 +    /* Infinities copy through; NaNs need usual treatment  */
  1.2368 +    if (decNumberIsNaN(rhs)) {
  1.2369 +      decNaNs(res, rhs, NULL, set, &status);
  1.2370 +      break;
  1.2371 +      }
  1.2372 +
  1.2373 +    /* reduce result to the requested length and copy to result  */
  1.2374 +    decCopyFit(res, rhs, set, &residue, &status); /* copy & round  */
  1.2375 +    decFinish(res, set, &residue, &status);       /* cleanup/set flags  */
  1.2376 +    decTrim(res, set, 1, 0, &dropped);            /* normalize in place  */
  1.2377 +                                                  /* [may clamp]  */
  1.2378 +    } while(0);                              /* end protected  */
  1.2379 +
  1.2380 +  #if DECSUBSET
  1.2381 +  if (allocrhs !=NULL) free(allocrhs);       /* ..  */
  1.2382 +  #endif
  1.2383 +  if (status!=0) decStatus(res, status, set);/* then report status  */
  1.2384 +  return res;
  1.2385 +  } /* decNumberReduce  */
  1.2386 +
  1.2387 +/* ------------------------------------------------------------------ */
  1.2388 +/* decNumberRescale -- force exponent to requested value              */
  1.2389 +/*                                                                    */
  1.2390 +/*   This computes C = op(A, B), where op adjusts the coefficient     */
  1.2391 +/*   of C (by rounding or shifting) such that the exponent (-scale)   */
  1.2392 +/*   of C has the value B.  The numerical value of C will equal A,    */
  1.2393 +/*   except for the effects of any rounding that occurred.            */
  1.2394 +/*                                                                    */
  1.2395 +/*   res is C, the result.  C may be A or B                           */
  1.2396 +/*   lhs is A, the number to adjust                                   */
  1.2397 +/*   rhs is B, the requested exponent                                 */
  1.2398 +/*   set is the context                                               */
  1.2399 +/*                                                                    */
  1.2400 +/* C must have space for set->digits digits.                          */
  1.2401 +/*                                                                    */
  1.2402 +/* Unless there is an error or the result is infinite, the exponent   */
  1.2403 +/* after the operation is guaranteed to be equal to B.                */
  1.2404 +/* ------------------------------------------------------------------ */
  1.2405 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberRescale(decNumber *res, const decNumber *lhs,
  1.2406 +                             const decNumber *rhs, decContext *set) {
  1.2407 +  uInt status=0;                        /* accumulator  */
  1.2408 +  decQuantizeOp(res, lhs, rhs, set, 0, &status);
  1.2409 +  if (status!=0) decStatus(res, status, set);
  1.2410 +  return res;
  1.2411 +  } /* decNumberRescale  */
  1.2412 +
  1.2413 +/* ------------------------------------------------------------------ */
  1.2414 +/* decNumberRemainder -- divide and return remainder                  */
  1.2415 +/*                                                                    */
  1.2416 +/*   This computes C = A % B                                          */
  1.2417 +/*                                                                    */
  1.2418 +/*   res is C, the result.  C may be A and/or B (e.g., X=X%X)         */
  1.2419 +/*   lhs is A                                                         */
  1.2420 +/*   rhs is B                                                         */
  1.2421 +/*   set is the context                                               */
  1.2422 +/*                                                                    */
  1.2423 +/* C must have space for set->digits digits.                          */
  1.2424 +/* ------------------------------------------------------------------ */
  1.2425 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberRemainder(decNumber *res, const decNumber *lhs,
  1.2426 +                               const decNumber *rhs, decContext *set) {
  1.2427 +  uInt status=0;                        /* accumulator  */
  1.2428 +  decDivideOp(res, lhs, rhs, set, REMAINDER, &status);
  1.2429 +  if (status!=0) decStatus(res, status, set);
  1.2430 +  #if DECCHECK
  1.2431 +  decCheckInexact(res, set);
  1.2432 +  #endif
  1.2433 +  return res;
  1.2434 +  } /* decNumberRemainder  */
  1.2435 +
  1.2436 +/* ------------------------------------------------------------------ */
  1.2437 +/* decNumberRemainderNear -- divide and return remainder from nearest */
  1.2438 +/*                                                                    */
  1.2439 +/*   This computes C = A % B, where % is the IEEE remainder operator  */
  1.2440 +/*                                                                    */
  1.2441 +/*   res is C, the result.  C may be A and/or B (e.g., X=X%X)         */
  1.2442 +/*   lhs is A                                                         */
  1.2443 +/*   rhs is B                                                         */
  1.2444 +/*   set is the context                                               */
  1.2445 +/*                                                                    */
  1.2446 +/* C must have space for set->digits digits.                          */
  1.2447 +/* ------------------------------------------------------------------ */
  1.2448 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberRemainderNear(decNumber *res, const decNumber *lhs,
  1.2449 +                                   const decNumber *rhs, decContext *set) {
  1.2450 +  uInt status=0;                        /* accumulator  */
  1.2451 +  decDivideOp(res, lhs, rhs, set, REMNEAR, &status);
  1.2452 +  if (status!=0) decStatus(res, status, set);
  1.2453 +  #if DECCHECK
  1.2454 +  decCheckInexact(res, set);
  1.2455 +  #endif
  1.2456 +  return res;
  1.2457 +  } /* decNumberRemainderNear  */
  1.2458 +
  1.2459 +/* ------------------------------------------------------------------ */
  1.2460 +/* decNumberRotate -- rotate the coefficient of a Number left/right   */
  1.2461 +/*                                                                    */
  1.2462 +/*   This computes C = A rot B  (in base ten and rotating set->digits */
  1.2463 +/*   digits).                                                         */
  1.2464 +/*                                                                    */
  1.2465 +/*   res is C, the result.  C may be A and/or B (e.g., X=XrotX)       */
  1.2466 +/*   lhs is A                                                         */
  1.2467 +/*   rhs is B, the number of digits to rotate (-ve to right)          */
  1.2468 +/*   set is the context                                               */
  1.2469 +/*                                                                    */
  1.2470 +/* The digits of the coefficient of A are rotated to the left (if B   */
  1.2471 +/* is positive) or to the right (if B is negative) without adjusting  */
  1.2472 +/* the exponent or the sign of A.  If lhs->digits is less than        */
  1.2473 +/* set->digits the coefficient is padded with zeros on the left       */
  1.2474 +/* before the rotate.  Any leading zeros in the result are removed    */
  1.2475 +/* as usual.                                                          */
  1.2476 +/*                                                                    */
  1.2477 +/* B must be an integer (q=0) and in the range -set->digits through   */
  1.2478 +/* +set->digits.                                                      */
  1.2479 +/* C must have space for set->digits digits.                          */
  1.2480 +/* NaNs are propagated as usual.  Infinities are unaffected (but      */
  1.2481 +/* B must be valid).  No status is set unless B is invalid or an      */
  1.2482 +/* operand is an sNaN.                                                */
  1.2483 +/* ------------------------------------------------------------------ */
  1.2484 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberRotate(decNumber *res, const decNumber *lhs,
  1.2485 +                           const decNumber *rhs, decContext *set) {
  1.2486 +  uInt status=0;              /* accumulator  */
  1.2487 +  Int  rotate;                /* rhs as an Int  */
  1.2488 +
  1.2489 +  #if DECCHECK
  1.2490 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
  1.2491 +  #endif
  1.2492 +
  1.2493 +  /* NaNs propagate as normal  */
  1.2494 +  if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
  1.2495 +    decNaNs(res, lhs, rhs, set, &status);
  1.2496 +   /* rhs must be an integer  */
  1.2497 +   else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
  1.2498 +    status=DEC_Invalid_operation;
  1.2499 +   else { /* both numeric, rhs is an integer  */
  1.2500 +    rotate=decGetInt(rhs);                   /* [cannot fail]  */
  1.2501 +    if (rotate==BADINT                       /* something bad ..  */
  1.2502 +     || rotate==BIGODD || rotate==BIGEVEN    /* .. very big ..  */
  1.2503 +     || abs(rotate)>set->digits)             /* .. or out of range  */
  1.2504 +      status=DEC_Invalid_operation;
  1.2505 +     else {                                  /* rhs is OK  */
  1.2506 +      uprv_decNumberCopy(res, lhs);
  1.2507 +      /* convert -ve rotate to equivalent positive rotation  */
  1.2508 +      if (rotate<0) rotate=set->digits+rotate;
  1.2509 +      if (rotate!=0 && rotate!=set->digits   /* zero or full rotation  */
  1.2510 +       && !decNumberIsInfinite(res)) {       /* lhs was infinite  */
  1.2511 +        /* left-rotate to do; 0 < rotate < set->digits  */
  1.2512 +        uInt units, shift;                   /* work  */
  1.2513 +        uInt msudigits;                      /* digits in result msu  */
  1.2514 +        Unit *msu=res->lsu+D2U(res->digits)-1;    /* current msu  */
  1.2515 +        Unit *msumax=res->lsu+D2U(set->digits)-1; /* rotation msu  */
  1.2516 +        for (msu++; msu<=msumax; msu++) *msu=0;   /* ensure high units=0  */
  1.2517 +        res->digits=set->digits;                  /* now full-length  */
  1.2518 +        msudigits=MSUDIGITS(res->digits);         /* actual digits in msu  */
  1.2519 +
  1.2520 +        /* rotation here is done in-place, in three steps  */
  1.2521 +        /* 1. shift all to least up to one unit to unit-align final  */
  1.2522 +        /*    lsd [any digits shifted out are rotated to the left,  */
  1.2523 +        /*    abutted to the original msd (which may require split)]  */
  1.2524 +        /*  */
  1.2525 +        /*    [if there are no whole units left to rotate, the  */
  1.2526 +        /*    rotation is now complete]  */
  1.2527 +        /*  */
  1.2528 +        /* 2. shift to least, from below the split point only, so that  */
  1.2529 +        /*    the final msd is in the right place in its Unit [any  */
  1.2530 +        /*    digits shifted out will fit exactly in the current msu,  */
  1.2531 +        /*    left aligned, no split required]  */
  1.2532 +        /*  */
  1.2533 +        /* 3. rotate all the units by reversing left part, right  */
  1.2534 +        /*    part, and then whole  */
  1.2535 +        /*  */
  1.2536 +        /* example: rotate right 8 digits (2 units + 2), DECDPUN=3.  */
  1.2537 +        /*  */
  1.2538 +        /*   start: 00a bcd efg hij klm npq  */
  1.2539 +        /*  */
  1.2540 +        /*      1a  000 0ab cde fgh|ijk lmn [pq saved]  */
  1.2541 +        /*      1b  00p qab cde fgh|ijk lmn  */
  1.2542 +        /*  */
  1.2543 +        /*      2a  00p qab cde fgh|00i jkl [mn saved]  */
  1.2544 +        /*      2b  mnp qab cde fgh|00i jkl  */
  1.2545 +        /*  */
  1.2546 +        /*      3a  fgh cde qab mnp|00i jkl  */
  1.2547 +        /*      3b  fgh cde qab mnp|jkl 00i  */
  1.2548 +        /*      3c  00i jkl mnp qab cde fgh  */
  1.2549 +
  1.2550 +        /* Step 1: amount to shift is the partial right-rotate count  */
  1.2551 +        rotate=set->digits-rotate;      /* make it right-rotate  */
  1.2552 +        units=rotate/DECDPUN;           /* whole units to rotate  */
  1.2553 +        shift=rotate%DECDPUN;           /* left-over digits count  */
  1.2554 +        if (shift>0) {                  /* not an exact number of units  */
  1.2555 +          uInt save=res->lsu[0]%powers[shift];    /* save low digit(s)  */
  1.2556 +          decShiftToLeast(res->lsu, D2U(res->digits), shift);
  1.2557 +          if (shift>msudigits) {        /* msumax-1 needs >0 digits  */
  1.2558 +            uInt rem=save%powers[shift-msudigits];/* split save  */
  1.2559 +            *msumax=(Unit)(save/powers[shift-msudigits]); /* and insert  */
  1.2560 +            *(msumax-1)=*(msumax-1)
  1.2561 +                       +(Unit)(rem*powers[DECDPUN-(shift-msudigits)]); /* ..  */
  1.2562 +            }
  1.2563 +           else { /* all fits in msumax  */
  1.2564 +            *msumax=*msumax+(Unit)(save*powers[msudigits-shift]); /* [maybe *1]  */
  1.2565 +            }
  1.2566 +          } /* digits shift needed  */
  1.2567 +
  1.2568 +        /* If whole units to rotate...  */
  1.2569 +        if (units>0) {                  /* some to do  */
  1.2570 +          /* Step 2: the units to touch are the whole ones in rotate,  */
  1.2571 +          /*   if any, and the shift is DECDPUN-msudigits (which may be  */
  1.2572 +          /*   0, again)  */
  1.2573 +          shift=DECDPUN-msudigits;
  1.2574 +          if (shift>0) {                /* not an exact number of units  */
  1.2575 +            uInt save=res->lsu[0]%powers[shift];  /* save low digit(s)  */
  1.2576 +            decShiftToLeast(res->lsu, units, shift);
  1.2577 +            *msumax=*msumax+(Unit)(save*powers[msudigits]);
  1.2578 +            } /* partial shift needed  */
  1.2579 +
  1.2580 +          /* Step 3: rotate the units array using triple reverse  */
  1.2581 +          /* (reversing is easy and fast)  */
  1.2582 +          decReverse(res->lsu+units, msumax);     /* left part  */
  1.2583 +          decReverse(res->lsu, res->lsu+units-1); /* right part  */
  1.2584 +          decReverse(res->lsu, msumax);           /* whole  */
  1.2585 +          } /* whole units to rotate  */
  1.2586 +        /* the rotation may have left an undetermined number of zeros  */
  1.2587 +        /* on the left, so true length needs to be calculated  */
  1.2588 +        res->digits=decGetDigits(res->lsu, msumax-res->lsu+1);
  1.2589 +        } /* rotate needed  */
  1.2590 +      } /* rhs OK  */
  1.2591 +    } /* numerics  */
  1.2592 +  if (status!=0) decStatus(res, status, set);
  1.2593 +  return res;
  1.2594 +  } /* decNumberRotate  */
  1.2595 +
  1.2596 +/* ------------------------------------------------------------------ */
  1.2597 +/* decNumberSameQuantum -- test for equal exponents                   */
  1.2598 +/*                                                                    */
  1.2599 +/*   res is the result number, which will contain either 0 or 1       */
  1.2600 +/*   lhs is a number to test                                          */
  1.2601 +/*   rhs is the second (usually a pattern)                            */
  1.2602 +/*                                                                    */
  1.2603 +/* No errors are possible and no context is needed.                   */
  1.2604 +/* ------------------------------------------------------------------ */
  1.2605 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberSameQuantum(decNumber *res, const decNumber *lhs,
  1.2606 +                                 const decNumber *rhs) {
  1.2607 +  Unit ret=0;                      /* return value  */
  1.2608 +
  1.2609 +  #if DECCHECK
  1.2610 +  if (decCheckOperands(res, lhs, rhs, DECUNCONT)) return res;
  1.2611 +  #endif
  1.2612 +
  1.2613 +  if (SPECIALARGS) {
  1.2614 +    if (decNumberIsNaN(lhs) && decNumberIsNaN(rhs)) ret=1;
  1.2615 +     else if (decNumberIsInfinite(lhs) && decNumberIsInfinite(rhs)) ret=1;
  1.2616 +     /* [anything else with a special gives 0]  */
  1.2617 +    }
  1.2618 +   else if (lhs->exponent==rhs->exponent) ret=1;
  1.2619 +
  1.2620 +  uprv_decNumberZero(res);              /* OK to overwrite an operand now  */
  1.2621 +  *res->lsu=ret;
  1.2622 +  return res;
  1.2623 +  } /* decNumberSameQuantum  */
  1.2624 +
  1.2625 +/* ------------------------------------------------------------------ */
  1.2626 +/* decNumberScaleB -- multiply by a power of 10                       */
  1.2627 +/*                                                                    */
  1.2628 +/* This computes C = A x 10**B where B is an integer (q=0) with       */
  1.2629 +/* maximum magnitude 2*(emax+digits)                                  */
  1.2630 +/*                                                                    */
  1.2631 +/*   res is C, the result.  C may be A or B                           */
  1.2632 +/*   lhs is A, the number to adjust                                   */
  1.2633 +/*   rhs is B, the requested power of ten to use                      */
  1.2634 +/*   set is the context                                               */
  1.2635 +/*                                                                    */
  1.2636 +/* C must have space for set->digits digits.                          */
  1.2637 +/*                                                                    */
  1.2638 +/* The result may underflow or overflow.                              */
  1.2639 +/* ------------------------------------------------------------------ */
  1.2640 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberScaleB(decNumber *res, const decNumber *lhs,
  1.2641 +                            const decNumber *rhs, decContext *set) {
  1.2642 +  Int  reqexp;                /* requested exponent change [B]  */
  1.2643 +  uInt status=0;              /* accumulator  */
  1.2644 +  Int  residue;               /* work  */
  1.2645 +
  1.2646 +  #if DECCHECK
  1.2647 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
  1.2648 +  #endif
  1.2649 +
  1.2650 +  /* Handle special values except lhs infinite  */
  1.2651 +  if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
  1.2652 +    decNaNs(res, lhs, rhs, set, &status);
  1.2653 +    /* rhs must be an integer  */
  1.2654 +   else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
  1.2655 +    status=DEC_Invalid_operation;
  1.2656 +   else {
  1.2657 +    /* lhs is a number; rhs is a finite with q==0  */
  1.2658 +    reqexp=decGetInt(rhs);                   /* [cannot fail]  */
  1.2659 +    if (reqexp==BADINT                       /* something bad ..  */
  1.2660 +     || reqexp==BIGODD || reqexp==BIGEVEN    /* .. very big ..  */
  1.2661 +     || abs(reqexp)>(2*(set->digits+set->emax))) /* .. or out of range  */
  1.2662 +      status=DEC_Invalid_operation;
  1.2663 +     else {                                  /* rhs is OK  */
  1.2664 +      uprv_decNumberCopy(res, lhs);               /* all done if infinite lhs  */
  1.2665 +      if (!decNumberIsInfinite(res)) {       /* prepare to scale  */
  1.2666 +        res->exponent+=reqexp;               /* adjust the exponent  */
  1.2667 +        residue=0;
  1.2668 +        decFinalize(res, set, &residue, &status); /* .. and check  */
  1.2669 +        } /* finite LHS  */
  1.2670 +      } /* rhs OK  */
  1.2671 +    } /* rhs finite  */
  1.2672 +  if (status!=0) decStatus(res, status, set);
  1.2673 +  return res;
  1.2674 +  } /* decNumberScaleB  */
  1.2675 +
  1.2676 +/* ------------------------------------------------------------------ */
  1.2677 +/* decNumberShift -- shift the coefficient of a Number left or right  */
  1.2678 +/*                                                                    */
  1.2679 +/*   This computes C = A << B or C = A >> -B  (in base ten).          */
  1.2680 +/*                                                                    */
  1.2681 +/*   res is C, the result.  C may be A and/or B (e.g., X=X<<X)        */
  1.2682 +/*   lhs is A                                                         */
  1.2683 +/*   rhs is B, the number of digits to shift (-ve to right)           */
  1.2684 +/*   set is the context                                               */
  1.2685 +/*                                                                    */
  1.2686 +/* The digits of the coefficient of A are shifted to the left (if B   */
  1.2687 +/* is positive) or to the right (if B is negative) without adjusting  */
  1.2688 +/* the exponent or the sign of A.                                     */
  1.2689 +/*                                                                    */
  1.2690 +/* B must be an integer (q=0) and in the range -set->digits through   */
  1.2691 +/* +set->digits.                                                      */
  1.2692 +/* C must have space for set->digits digits.                          */
  1.2693 +/* NaNs are propagated as usual.  Infinities are unaffected (but      */
  1.2694 +/* B must be valid).  No status is set unless B is invalid or an      */
  1.2695 +/* operand is an sNaN.                                                */
  1.2696 +/* ------------------------------------------------------------------ */
  1.2697 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberShift(decNumber *res, const decNumber *lhs,
  1.2698 +                           const decNumber *rhs, decContext *set) {
  1.2699 +  uInt status=0;              /* accumulator  */
  1.2700 +  Int  shift;                 /* rhs as an Int  */
  1.2701 +
  1.2702 +  #if DECCHECK
  1.2703 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
  1.2704 +  #endif
  1.2705 +
  1.2706 +  /* NaNs propagate as normal  */
  1.2707 +  if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
  1.2708 +    decNaNs(res, lhs, rhs, set, &status);
  1.2709 +   /* rhs must be an integer  */
  1.2710 +   else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
  1.2711 +    status=DEC_Invalid_operation;
  1.2712 +   else { /* both numeric, rhs is an integer  */
  1.2713 +    shift=decGetInt(rhs);                    /* [cannot fail]  */
  1.2714 +    if (shift==BADINT                        /* something bad ..  */
  1.2715 +     || shift==BIGODD || shift==BIGEVEN      /* .. very big ..  */
  1.2716 +     || abs(shift)>set->digits)              /* .. or out of range  */
  1.2717 +      status=DEC_Invalid_operation;
  1.2718 +     else {                                  /* rhs is OK  */
  1.2719 +      uprv_decNumberCopy(res, lhs);
  1.2720 +      if (shift!=0 && !decNumberIsInfinite(res)) { /* something to do  */
  1.2721 +        if (shift>0) {                       /* to left  */
  1.2722 +          if (shift==set->digits) {          /* removing all  */
  1.2723 +            *res->lsu=0;                     /* so place 0  */
  1.2724 +            res->digits=1;                   /* ..  */
  1.2725 +            }
  1.2726 +           else {                            /*  */
  1.2727 +            /* first remove leading digits if necessary  */
  1.2728 +            if (res->digits+shift>set->digits) {
  1.2729 +              decDecap(res, res->digits+shift-set->digits);
  1.2730 +              /* that updated res->digits; may have gone to 1 (for a  */
  1.2731 +              /* single digit or for zero  */
  1.2732 +              }
  1.2733 +            if (res->digits>1 || *res->lsu)  /* if non-zero..  */
  1.2734 +              res->digits=decShiftToMost(res->lsu, res->digits, shift);
  1.2735 +            } /* partial left  */
  1.2736 +          } /* left  */
  1.2737 +         else { /* to right  */
  1.2738 +          if (-shift>=res->digits) {         /* discarding all  */
  1.2739 +            *res->lsu=0;                     /* so place 0  */
  1.2740 +            res->digits=1;                   /* ..  */
  1.2741 +            }
  1.2742 +           else {
  1.2743 +            decShiftToLeast(res->lsu, D2U(res->digits), -shift);
  1.2744 +            res->digits-=(-shift);
  1.2745 +            }
  1.2746 +          } /* to right  */
  1.2747 +        } /* non-0 non-Inf shift  */
  1.2748 +      } /* rhs OK  */
  1.2749 +    } /* numerics  */
  1.2750 +  if (status!=0) decStatus(res, status, set);
  1.2751 +  return res;
  1.2752 +  } /* decNumberShift  */
  1.2753 +
  1.2754 +/* ------------------------------------------------------------------ */
  1.2755 +/* decNumberSquareRoot -- square root operator                        */
  1.2756 +/*                                                                    */
  1.2757 +/*   This computes C = squareroot(A)                                  */
  1.2758 +/*                                                                    */
  1.2759 +/*   res is C, the result.  C may be A                                */
  1.2760 +/*   rhs is A                                                         */
  1.2761 +/*   set is the context; note that rounding mode has no effect        */
  1.2762 +/*                                                                    */
  1.2763 +/* C must have space for set->digits digits.                          */
  1.2764 +/* ------------------------------------------------------------------ */
  1.2765 +/* This uses the following varying-precision algorithm in:            */
  1.2766 +/*                                                                    */
  1.2767 +/*   Properly Rounded Variable Precision Square Root, T. E. Hull and  */
  1.2768 +/*   A. Abrham, ACM Transactions on Mathematical Software, Vol 11 #3, */
  1.2769 +/*   pp229-237, ACM, September 1985.                                  */
  1.2770 +/*                                                                    */
  1.2771 +/* The square-root is calculated using Newton's method, after which   */
  1.2772 +/* a check is made to ensure the result is correctly rounded.         */
  1.2773 +/*                                                                    */
  1.2774 +/* % [Reformatted original Numerical Turing source code follows.]     */
  1.2775 +/* function sqrt(x : real) : real                                     */
  1.2776 +/* % sqrt(x) returns the properly rounded approximation to the square */
  1.2777 +/* % root of x, in the precision of the calling environment, or it    */
  1.2778 +/* % fails if x < 0.                                                  */
  1.2779 +/* % t e hull and a abrham, august, 1984                              */
  1.2780 +/* if x <= 0 then                                                     */
  1.2781 +/*   if x < 0 then                                                    */
  1.2782 +/*     assert false                                                   */
  1.2783 +/*   else                                                             */
  1.2784 +/*     result 0                                                       */
  1.2785 +/*   end if                                                           */
  1.2786 +/* end if                                                             */
  1.2787 +/* var f := setexp(x, 0)  % fraction part of x   [0.1 <= x < 1]       */
  1.2788 +/* var e := getexp(x)     % exponent part of x                        */
  1.2789 +/* var approx : real                                                  */
  1.2790 +/* if e mod 2 = 0  then                                               */
  1.2791 +/*   approx := .259 + .819 * f   % approx to root of f                */
  1.2792 +/* else                                                               */
  1.2793 +/*   f := f/l0                   % adjustments                        */
  1.2794 +/*   e := e + 1                  %   for odd                          */
  1.2795 +/*   approx := .0819 + 2.59 * f  %   exponent                         */
  1.2796 +/* end if                                                             */
  1.2797 +/*                                                                    */
  1.2798 +/* var p:= 3                                                          */
  1.2799 +/* const maxp := currentprecision + 2                                 */
  1.2800 +/* loop                                                               */
  1.2801 +/*   p := min(2*p - 2, maxp)     % p = 4,6,10, . . . , maxp           */
  1.2802 +/*   precision p                                                      */
  1.2803 +/*   approx := .5 * (approx + f/approx)                               */
  1.2804 +/*   exit when p = maxp                                               */
  1.2805 +/* end loop                                                           */
  1.2806 +/*                                                                    */
  1.2807 +/* % approx is now within 1 ulp of the properly rounded square root   */
  1.2808 +/* % of f; to ensure proper rounding, compare squares of (approx -    */
  1.2809 +/* % l/2 ulp) and (approx + l/2 ulp) with f.                          */
  1.2810 +/* p := currentprecision                                              */
  1.2811 +/* begin                                                              */
  1.2812 +/*   precision p + 2                                                  */
  1.2813 +/*   const approxsubhalf := approx - setexp(.5, -p)                   */
  1.2814 +/*   if mulru(approxsubhalf, approxsubhalf) > f then                  */
  1.2815 +/*     approx := approx - setexp(.l, -p + 1)                          */
  1.2816 +/*   else                                                             */
  1.2817 +/*     const approxaddhalf := approx + setexp(.5, -p)                 */
  1.2818 +/*     if mulrd(approxaddhalf, approxaddhalf) < f then                */
  1.2819 +/*       approx := approx + setexp(.l, -p + 1)                        */
  1.2820 +/*     end if                                                         */
  1.2821 +/*   end if                                                           */
  1.2822 +/* end                                                                */
  1.2823 +/* result setexp(approx, e div 2)  % fix exponent                     */
  1.2824 +/* end sqrt                                                           */
  1.2825 +/* ------------------------------------------------------------------ */
  1.2826 +#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
  1.2827 +#pragma GCC diagnostic push
  1.2828 +#pragma GCC diagnostic ignored "-Warray-bounds"
  1.2829 +#endif
  1.2830 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberSquareRoot(decNumber *res, const decNumber *rhs,
  1.2831 +                                decContext *set) {
  1.2832 +  decContext workset, approxset;   /* work contexts  */
  1.2833 +  decNumber dzero;                 /* used for constant zero  */
  1.2834 +  Int  maxp;                       /* largest working precision  */
  1.2835 +  Int  workp;                      /* working precision  */
  1.2836 +  Int  residue=0;                  /* rounding residue  */
  1.2837 +  uInt status=0, ignore=0;         /* status accumulators  */
  1.2838 +  uInt rstatus;                    /* ..  */
  1.2839 +  Int  exp;                        /* working exponent  */
  1.2840 +  Int  ideal;                      /* ideal (preferred) exponent  */
  1.2841 +  Int  needbytes;                  /* work  */
  1.2842 +  Int  dropped;                    /* ..  */
  1.2843 +
  1.2844 +  #if DECSUBSET
  1.2845 +  decNumber *allocrhs=NULL;        /* non-NULL if rounded rhs allocated  */
  1.2846 +  #endif
  1.2847 +  /* buffer for f [needs +1 in case DECBUFFER 0]  */
  1.2848 +  decNumber buff[D2N(DECBUFFER+1)];
  1.2849 +  /* buffer for a [needs +2 to match likely maxp]  */
  1.2850 +  decNumber bufa[D2N(DECBUFFER+2)];
  1.2851 +  /* buffer for temporary, b [must be same size as a]  */
  1.2852 +  decNumber bufb[D2N(DECBUFFER+2)];
  1.2853 +  decNumber *allocbuff=NULL;       /* -> allocated buff, iff allocated  */
  1.2854 +  decNumber *allocbufa=NULL;       /* -> allocated bufa, iff allocated  */
  1.2855 +  decNumber *allocbufb=NULL;       /* -> allocated bufb, iff allocated  */
  1.2856 +  decNumber *f=buff;               /* reduced fraction  */
  1.2857 +  decNumber *a=bufa;               /* approximation to result  */
  1.2858 +  decNumber *b=bufb;               /* intermediate result  */
  1.2859 +  /* buffer for temporary variable, up to 3 digits  */
  1.2860 +  decNumber buft[D2N(3)];
  1.2861 +  decNumber *t=buft;               /* up-to-3-digit constant or work  */
  1.2862 +
  1.2863 +  #if DECCHECK
  1.2864 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  1.2865 +  #endif
  1.2866 +
  1.2867 +  do {                             /* protect allocated storage  */
  1.2868 +    #if DECSUBSET
  1.2869 +    if (!set->extended) {
  1.2870 +      /* reduce operand and set lostDigits status, as needed  */
  1.2871 +      if (rhs->digits>set->digits) {
  1.2872 +        allocrhs=decRoundOperand(rhs, set, &status);
  1.2873 +        if (allocrhs==NULL) break;
  1.2874 +        /* [Note: 'f' allocation below could reuse this buffer if  */
  1.2875 +        /* used, but as this is rare they are kept separate for clarity.]  */
  1.2876 +        rhs=allocrhs;
  1.2877 +        }
  1.2878 +      }
  1.2879 +    #endif
  1.2880 +    /* [following code does not require input rounding]  */
  1.2881 +
  1.2882 +    /* handle infinities and NaNs  */
  1.2883 +    if (SPECIALARG) {
  1.2884 +      if (decNumberIsInfinite(rhs)) {         /* an infinity  */
  1.2885 +        if (decNumberIsNegative(rhs)) status|=DEC_Invalid_operation;
  1.2886 +         else uprv_decNumberCopy(res, rhs);        /* +Infinity  */
  1.2887 +        }
  1.2888 +       else decNaNs(res, rhs, NULL, set, &status); /* a NaN  */
  1.2889 +      break;
  1.2890 +      }
  1.2891 +
  1.2892 +    /* calculate the ideal (preferred) exponent [floor(exp/2)]  */
  1.2893 +    /* [It would be nicer to write: ideal=rhs->exponent>>1, but this  */
  1.2894 +    /* generates a compiler warning.  Generated code is the same.]  */
  1.2895 +    ideal=(rhs->exponent&~1)/2;         /* target  */
  1.2896 +
  1.2897 +    /* handle zeros  */
  1.2898 +    if (ISZERO(rhs)) {
  1.2899 +      uprv_decNumberCopy(res, rhs);          /* could be 0 or -0  */
  1.2900 +      res->exponent=ideal;              /* use the ideal [safe]  */
  1.2901 +      /* use decFinish to clamp any out-of-range exponent, etc.  */
  1.2902 +      decFinish(res, set, &residue, &status);
  1.2903 +      break;
  1.2904 +      }
  1.2905 +
  1.2906 +    /* any other -x is an oops  */
  1.2907 +    if (decNumberIsNegative(rhs)) {
  1.2908 +      status|=DEC_Invalid_operation;
  1.2909 +      break;
  1.2910 +      }
  1.2911 +
  1.2912 +    /* space is needed for three working variables  */
  1.2913 +    /*   f -- the same precision as the RHS, reduced to 0.01->0.99...  */
  1.2914 +    /*   a -- Hull's approximation -- precision, when assigned, is  */
  1.2915 +    /*        currentprecision+1 or the input argument precision,  */
  1.2916 +    /*        whichever is larger (+2 for use as temporary)  */
  1.2917 +    /*   b -- intermediate temporary result (same size as a)  */
  1.2918 +    /* if any is too long for local storage, then allocate  */
  1.2919 +    workp=MAXI(set->digits+1, rhs->digits);  /* actual rounding precision  */
  1.2920 +    workp=MAXI(workp, 7);                    /* at least 7 for low cases  */
  1.2921 +    maxp=workp+2;                            /* largest working precision  */
  1.2922 +
  1.2923 +    needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
  1.2924 +    if (needbytes>(Int)sizeof(buff)) {
  1.2925 +      allocbuff=(decNumber *)malloc(needbytes);
  1.2926 +      if (allocbuff==NULL) {  /* hopeless -- abandon  */
  1.2927 +        status|=DEC_Insufficient_storage;
  1.2928 +        break;}
  1.2929 +      f=allocbuff;            /* use the allocated space  */
  1.2930 +      }
  1.2931 +    /* a and b both need to be able to hold a maxp-length number  */
  1.2932 +    needbytes=sizeof(decNumber)+(D2U(maxp)-1)*sizeof(Unit);
  1.2933 +    if (needbytes>(Int)sizeof(bufa)) {            /* [same applies to b]  */
  1.2934 +      allocbufa=(decNumber *)malloc(needbytes);
  1.2935 +      allocbufb=(decNumber *)malloc(needbytes);
  1.2936 +      if (allocbufa==NULL || allocbufb==NULL) {   /* hopeless  */
  1.2937 +        status|=DEC_Insufficient_storage;
  1.2938 +        break;}
  1.2939 +      a=allocbufa;            /* use the allocated spaces  */
  1.2940 +      b=allocbufb;            /* ..  */
  1.2941 +      }
  1.2942 +
  1.2943 +    /* copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1  */
  1.2944 +    uprv_decNumberCopy(f, rhs);
  1.2945 +    exp=f->exponent+f->digits;               /* adjusted to Hull rules  */
  1.2946 +    f->exponent=-(f->digits);                /* to range  */
  1.2947 +
  1.2948 +    /* set up working context  */
  1.2949 +    uprv_decContextDefault(&workset, DEC_INIT_DECIMAL64);
  1.2950 +    workset.emax=DEC_MAX_EMAX;
  1.2951 +    workset.emin=DEC_MIN_EMIN;
  1.2952 +
  1.2953 +    /* [Until further notice, no error is possible and status bits  */
  1.2954 +    /* (Rounded, etc.) should be ignored, not accumulated.]  */
  1.2955 +
  1.2956 +    /* Calculate initial approximation, and allow for odd exponent  */
  1.2957 +    workset.digits=workp;                    /* p for initial calculation  */
  1.2958 +    t->bits=0; t->digits=3;
  1.2959 +    a->bits=0; a->digits=3;
  1.2960 +    if ((exp & 1)==0) {                      /* even exponent  */
  1.2961 +      /* Set t=0.259, a=0.819  */
  1.2962 +      t->exponent=-3;
  1.2963 +      a->exponent=-3;
  1.2964 +      #if DECDPUN>=3
  1.2965 +        t->lsu[0]=259;
  1.2966 +        a->lsu[0]=819;
  1.2967 +      #elif DECDPUN==2
  1.2968 +        t->lsu[0]=59; t->lsu[1]=2;
  1.2969 +        a->lsu[0]=19; a->lsu[1]=8;
  1.2970 +      #else
  1.2971 +        t->lsu[0]=9; t->lsu[1]=5; t->lsu[2]=2;
  1.2972 +        a->lsu[0]=9; a->lsu[1]=1; a->lsu[2]=8;
  1.2973 +      #endif
  1.2974 +      }
  1.2975 +     else {                                  /* odd exponent  */
  1.2976 +      /* Set t=0.0819, a=2.59  */
  1.2977 +      f->exponent--;                         /* f=f/10  */
  1.2978 +      exp++;                                 /* e=e+1  */
  1.2979 +      t->exponent=-4;
  1.2980 +      a->exponent=-2;
  1.2981 +      #if DECDPUN>=3
  1.2982 +        t->lsu[0]=819;
  1.2983 +        a->lsu[0]=259;
  1.2984 +      #elif DECDPUN==2
  1.2985 +        t->lsu[0]=19; t->lsu[1]=8;
  1.2986 +        a->lsu[0]=59; a->lsu[1]=2;
  1.2987 +      #else
  1.2988 +        t->lsu[0]=9; t->lsu[1]=1; t->lsu[2]=8;
  1.2989 +        a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;
  1.2990 +      #endif
  1.2991 +      }
  1.2992 +
  1.2993 +    decMultiplyOp(a, a, f, &workset, &ignore);    /* a=a*f  */
  1.2994 +    decAddOp(a, a, t, &workset, 0, &ignore);      /* ..+t  */
  1.2995 +    /* [a is now the initial approximation for sqrt(f), calculated with  */
  1.2996 +    /* currentprecision, which is also a's precision.]  */
  1.2997 +
  1.2998 +    /* the main calculation loop  */
  1.2999 +    uprv_decNumberZero(&dzero);                   /* make 0  */
  1.3000 +    uprv_decNumberZero(t);                        /* set t = 0.5  */
  1.3001 +    t->lsu[0]=5;                             /* ..  */
  1.3002 +    t->exponent=-1;                          /* ..  */
  1.3003 +    workset.digits=3;                        /* initial p  */
  1.3004 +    for (; workset.digits<maxp;) {
  1.3005 +      /* set p to min(2*p - 2, maxp)  [hence 3; or: 4, 6, 10, ... , maxp]  */
  1.3006 +      workset.digits=MINI(workset.digits*2-2, maxp);
  1.3007 +      /* a = 0.5 * (a + f/a)  */
  1.3008 +      /* [calculated at p then rounded to currentprecision]  */
  1.3009 +      decDivideOp(b, f, a, &workset, DIVIDE, &ignore); /* b=f/a  */
  1.3010 +      decAddOp(b, b, a, &workset, 0, &ignore);         /* b=b+a  */
  1.3011 +      decMultiplyOp(a, b, t, &workset, &ignore);       /* a=b*0.5  */
  1.3012 +      } /* loop  */
  1.3013 +
  1.3014 +    /* Here, 0.1 <= a < 1 [Hull], and a has maxp digits  */
  1.3015 +    /* now reduce to length, etc.; this needs to be done with a  */
  1.3016 +    /* having the correct exponent so as to handle subnormals  */
  1.3017 +    /* correctly  */
  1.3018 +    approxset=*set;                          /* get emin, emax, etc.  */
  1.3019 +    approxset.round=DEC_ROUND_HALF_EVEN;
  1.3020 +    a->exponent+=exp/2;                      /* set correct exponent  */
  1.3021 +    rstatus=0;                               /* clear status  */
  1.3022 +    residue=0;                               /* .. and accumulator  */
  1.3023 +    decCopyFit(a, a, &approxset, &residue, &rstatus);  /* reduce (if needed)  */
  1.3024 +    decFinish(a, &approxset, &residue, &rstatus);      /* clean and finalize  */
  1.3025 +
  1.3026 +    /* Overflow was possible if the input exponent was out-of-range,  */
  1.3027 +    /* in which case quit  */
  1.3028 +    if (rstatus&DEC_Overflow) {
  1.3029 +      status=rstatus;                        /* use the status as-is  */
  1.3030 +      uprv_decNumberCopy(res, a);                 /* copy to result  */
  1.3031 +      break;
  1.3032 +      }
  1.3033 +
  1.3034 +    /* Preserve status except Inexact/Rounded  */
  1.3035 +    status|=(rstatus & ~(DEC_Rounded|DEC_Inexact));
  1.3036 +
  1.3037 +    /* Carry out the Hull correction  */
  1.3038 +    a->exponent-=exp/2;                      /* back to 0.1->1  */
  1.3039 +
  1.3040 +    /* a is now at final precision and within 1 ulp of the properly  */
  1.3041 +    /* rounded square root of f; to ensure proper rounding, compare  */
  1.3042 +    /* squares of (a - l/2 ulp) and (a + l/2 ulp) with f.  */
  1.3043 +    /* Here workset.digits=maxp and t=0.5, and a->digits determines  */
  1.3044 +    /* the ulp  */
  1.3045 +    workset.digits--;                             /* maxp-1 is OK now  */
  1.3046 +    t->exponent=-a->digits-1;                     /* make 0.5 ulp  */
  1.3047 +    decAddOp(b, a, t, &workset, DECNEG, &ignore); /* b = a - 0.5 ulp  */
  1.3048 +    workset.round=DEC_ROUND_UP;
  1.3049 +    decMultiplyOp(b, b, b, &workset, &ignore);    /* b = mulru(b, b)  */
  1.3050 +    decCompareOp(b, f, b, &workset, COMPARE, &ignore); /* b ? f, reversed  */
  1.3051 +    if (decNumberIsNegative(b)) {                 /* f < b [i.e., b > f]  */
  1.3052 +      /* this is the more common adjustment, though both are rare  */
  1.3053 +      t->exponent++;                              /* make 1.0 ulp  */
  1.3054 +      t->lsu[0]=1;                                /* ..  */
  1.3055 +      decAddOp(a, a, t, &workset, DECNEG, &ignore); /* a = a - 1 ulp  */
  1.3056 +      /* assign to approx [round to length]  */
  1.3057 +      approxset.emin-=exp/2;                      /* adjust to match a  */
  1.3058 +      approxset.emax-=exp/2;
  1.3059 +      decAddOp(a, &dzero, a, &approxset, 0, &ignore);
  1.3060 +      }
  1.3061 +     else {
  1.3062 +      decAddOp(b, a, t, &workset, 0, &ignore);    /* b = a + 0.5 ulp  */
  1.3063 +      workset.round=DEC_ROUND_DOWN;
  1.3064 +      decMultiplyOp(b, b, b, &workset, &ignore);  /* b = mulrd(b, b)  */
  1.3065 +      decCompareOp(b, b, f, &workset, COMPARE, &ignore);   /* b ? f  */
  1.3066 +      if (decNumberIsNegative(b)) {               /* b < f  */
  1.3067 +        t->exponent++;                            /* make 1.0 ulp  */
  1.3068 +        t->lsu[0]=1;                              /* ..  */
  1.3069 +        decAddOp(a, a, t, &workset, 0, &ignore);  /* a = a + 1 ulp  */
  1.3070 +        /* assign to approx [round to length]  */
  1.3071 +        approxset.emin-=exp/2;                    /* adjust to match a  */
  1.3072 +        approxset.emax-=exp/2;
  1.3073 +        decAddOp(a, &dzero, a, &approxset, 0, &ignore);
  1.3074 +        }
  1.3075 +      }
  1.3076 +    /* [no errors are possible in the above, and rounding/inexact during  */
  1.3077 +    /* estimation are irrelevant, so status was not accumulated]  */
  1.3078 +
  1.3079 +    /* Here, 0.1 <= a < 1  (still), so adjust back  */
  1.3080 +    a->exponent+=exp/2;                      /* set correct exponent  */
  1.3081 +
  1.3082 +    /* count droppable zeros [after any subnormal rounding] by  */
  1.3083 +    /* trimming a copy  */
  1.3084 +    uprv_decNumberCopy(b, a);
  1.3085 +    decTrim(b, set, 1, 1, &dropped);         /* [drops trailing zeros]  */
  1.3086 +
  1.3087 +    /* Set Inexact and Rounded.  The answer can only be exact if  */
  1.3088 +    /* it is short enough so that squaring it could fit in workp  */
  1.3089 +    /* digits, so this is the only (relatively rare) condition that  */
  1.3090 +    /* a careful check is needed  */
  1.3091 +    if (b->digits*2-1 > workp) {             /* cannot fit  */
  1.3092 +      status|=DEC_Inexact|DEC_Rounded;
  1.3093 +      }
  1.3094 +     else {                                  /* could be exact/unrounded  */
  1.3095 +      uInt mstatus=0;                        /* local status  */
  1.3096 +      decMultiplyOp(b, b, b, &workset, &mstatus); /* try the multiply  */
  1.3097 +      if (mstatus&DEC_Overflow) {            /* result just won't fit  */
  1.3098 +        status|=DEC_Inexact|DEC_Rounded;
  1.3099 +        }
  1.3100 +       else {                                /* plausible  */
  1.3101 +        decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); /* b ? rhs  */
  1.3102 +        if (!ISZERO(t)) status|=DEC_Inexact|DEC_Rounded; /* not equal  */
  1.3103 +         else {                              /* is Exact  */
  1.3104 +          /* here, dropped is the count of trailing zeros in 'a'  */
  1.3105 +          /* use closest exponent to ideal...  */
  1.3106 +          Int todrop=ideal-a->exponent;      /* most that can be dropped  */
  1.3107 +          if (todrop<0) status|=DEC_Rounded; /* ideally would add 0s  */
  1.3108 +           else {                            /* unrounded  */
  1.3109 +            /* there are some to drop, but emax may not allow all  */
  1.3110 +            Int maxexp=set->emax-set->digits+1;
  1.3111 +            Int maxdrop=maxexp-a->exponent;
  1.3112 +            if (todrop>maxdrop && set->clamp) { /* apply clamping  */
  1.3113 +              todrop=maxdrop;
  1.3114 +              status|=DEC_Clamped;
  1.3115 +              }
  1.3116 +            if (dropped<todrop) {            /* clamp to those available  */
  1.3117 +              todrop=dropped;
  1.3118 +              status|=DEC_Clamped;
  1.3119 +              }
  1.3120 +            if (todrop>0) {                  /* have some to drop  */
  1.3121 +              decShiftToLeast(a->lsu, D2U(a->digits), todrop);
  1.3122 +              a->exponent+=todrop;           /* maintain numerical value  */
  1.3123 +              a->digits-=todrop;             /* new length  */
  1.3124 +              }
  1.3125 +            }
  1.3126 +          }
  1.3127 +        }
  1.3128 +      }
  1.3129 +
  1.3130 +    /* double-check Underflow, as perhaps the result could not have  */
  1.3131 +    /* been subnormal (initial argument too big), or it is now Exact  */
  1.3132 +    if (status&DEC_Underflow) {
  1.3133 +      Int ae=rhs->exponent+rhs->digits-1;    /* adjusted exponent  */
  1.3134 +      /* check if truly subnormal  */
  1.3135 +      #if DECEXTFLAG                         /* DEC_Subnormal too  */
  1.3136 +        if (ae>=set->emin*2) status&=~(DEC_Subnormal|DEC_Underflow);
  1.3137 +      #else
  1.3138 +        if (ae>=set->emin*2) status&=~DEC_Underflow;
  1.3139 +      #endif
  1.3140 +      /* check if truly inexact  */
  1.3141 +      if (!(status&DEC_Inexact)) status&=~DEC_Underflow;
  1.3142 +      }
  1.3143 +
  1.3144 +    uprv_decNumberCopy(res, a);                   /* a is now the result  */
  1.3145 +    } while(0);                              /* end protected  */
  1.3146 +
  1.3147 +  if (allocbuff!=NULL) free(allocbuff);      /* drop any storage used  */
  1.3148 +  if (allocbufa!=NULL) free(allocbufa);      /* ..  */
  1.3149 +  if (allocbufb!=NULL) free(allocbufb);      /* ..  */
  1.3150 +  #if DECSUBSET
  1.3151 +  if (allocrhs !=NULL) free(allocrhs);       /* ..  */
  1.3152 +  #endif
  1.3153 +  if (status!=0) decStatus(res, status, set);/* then report status  */
  1.3154 +  #if DECCHECK
  1.3155 +  decCheckInexact(res, set);
  1.3156 +  #endif
  1.3157 +  return res;
  1.3158 +  } /* decNumberSquareRoot  */
  1.3159 +#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
  1.3160 +#pragma GCC diagnostic pop
  1.3161 +#endif
  1.3162 +
  1.3163 +/* ------------------------------------------------------------------ */
  1.3164 +/* decNumberSubtract -- subtract two Numbers                          */
  1.3165 +/*                                                                    */
  1.3166 +/*   This computes C = A - B                                          */
  1.3167 +/*                                                                    */
  1.3168 +/*   res is C, the result.  C may be A and/or B (e.g., X=X-X)         */
  1.3169 +/*   lhs is A                                                         */
  1.3170 +/*   rhs is B                                                         */
  1.3171 +/*   set is the context                                               */
  1.3172 +/*                                                                    */
  1.3173 +/* C must have space for set->digits digits.                          */
  1.3174 +/* ------------------------------------------------------------------ */
  1.3175 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberSubtract(decNumber *res, const decNumber *lhs,
  1.3176 +                              const decNumber *rhs, decContext *set) {
  1.3177 +  uInt status=0;                        /* accumulator  */
  1.3178 +
  1.3179 +  decAddOp(res, lhs, rhs, set, DECNEG, &status);
  1.3180 +  if (status!=0) decStatus(res, status, set);
  1.3181 +  #if DECCHECK
  1.3182 +  decCheckInexact(res, set);
  1.3183 +  #endif
  1.3184 +  return res;
  1.3185 +  } /* decNumberSubtract  */
  1.3186 +
  1.3187 +/* ------------------------------------------------------------------ */
  1.3188 +/* decNumberToIntegralExact -- round-to-integral-value with InExact   */
  1.3189 +/* decNumberToIntegralValue -- round-to-integral-value                */
  1.3190 +/*                                                                    */
  1.3191 +/*   res is the result                                                */
  1.3192 +/*   rhs is input number                                              */
  1.3193 +/*   set is the context                                               */
  1.3194 +/*                                                                    */
  1.3195 +/* res must have space for any value of rhs.                          */
  1.3196 +/*                                                                    */
  1.3197 +/* This implements the IEEE special operators and therefore treats    */
  1.3198 +/* special values as valid.  For finite numbers it returns            */
  1.3199 +/* rescale(rhs, 0) if rhs->exponent is <0.                            */
  1.3200 +/* Otherwise the result is rhs (so no error is possible, except for   */
  1.3201 +/* sNaN).                                                             */
  1.3202 +/*                                                                    */
  1.3203 +/* The context is used for rounding mode and status after sNaN, but   */
  1.3204 +/* the digits setting is ignored.  The Exact version will signal      */
  1.3205 +/* Inexact if the result differs numerically from rhs; the other      */
  1.3206 +/* never signals Inexact.                                             */
  1.3207 +/* ------------------------------------------------------------------ */
  1.3208 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberToIntegralExact(decNumber *res, const decNumber *rhs,
  1.3209 +                                     decContext *set) {
  1.3210 +  decNumber dn;
  1.3211 +  decContext workset;              /* working context  */
  1.3212 +  uInt status=0;                   /* accumulator  */
  1.3213 +
  1.3214 +  #if DECCHECK
  1.3215 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  1.3216 +  #endif
  1.3217 +
  1.3218 +  /* handle infinities and NaNs  */
  1.3219 +  if (SPECIALARG) {
  1.3220 +    if (decNumberIsInfinite(rhs)) uprv_decNumberCopy(res, rhs); /* an Infinity  */
  1.3221 +     else decNaNs(res, rhs, NULL, set, &status); /* a NaN  */
  1.3222 +    }
  1.3223 +   else { /* finite  */
  1.3224 +    /* have a finite number; no error possible (res must be big enough)  */
  1.3225 +    if (rhs->exponent>=0) return uprv_decNumberCopy(res, rhs);
  1.3226 +    /* that was easy, but if negative exponent there is work to do...  */
  1.3227 +    workset=*set;                  /* clone rounding, etc.  */
  1.3228 +    workset.digits=rhs->digits;    /* no length rounding  */
  1.3229 +    workset.traps=0;               /* no traps  */
  1.3230 +    uprv_decNumberZero(&dn);            /* make a number with exponent 0  */
  1.3231 +    uprv_decNumberQuantize(res, rhs, &dn, &workset);
  1.3232 +    status|=workset.status;
  1.3233 +    }
  1.3234 +  if (status!=0) decStatus(res, status, set);
  1.3235 +  return res;
  1.3236 +  } /* decNumberToIntegralExact  */
  1.3237 +
  1.3238 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberToIntegralValue(decNumber *res, const decNumber *rhs,
  1.3239 +                                     decContext *set) {
  1.3240 +  decContext workset=*set;         /* working context  */
  1.3241 +  workset.traps=0;                 /* no traps  */
  1.3242 +  uprv_decNumberToIntegralExact(res, rhs, &workset);
  1.3243 +  /* this never affects set, except for sNaNs; NaN will have been set  */
  1.3244 +  /* or propagated already, so no need to call decStatus  */
  1.3245 +  set->status|=workset.status&DEC_Invalid_operation;
  1.3246 +  return res;
  1.3247 +  } /* decNumberToIntegralValue  */
  1.3248 +
  1.3249 +/* ------------------------------------------------------------------ */
  1.3250 +/* decNumberXor -- XOR two Numbers, digitwise                         */
  1.3251 +/*                                                                    */
  1.3252 +/*   This computes C = A ^ B                                          */
  1.3253 +/*                                                                    */
  1.3254 +/*   res is C, the result.  C may be A and/or B (e.g., X=X^X)         */
  1.3255 +/*   lhs is A                                                         */
  1.3256 +/*   rhs is B                                                         */
  1.3257 +/*   set is the context (used for result length and error report)     */
  1.3258 +/*                                                                    */
  1.3259 +/* C must have space for set->digits digits.                          */
  1.3260 +/*                                                                    */
  1.3261 +/* Logical function restrictions apply (see above); a NaN is          */
  1.3262 +/* returned with Invalid_operation if a restriction is violated.      */
  1.3263 +/* ------------------------------------------------------------------ */
  1.3264 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberXor(decNumber *res, const decNumber *lhs,
  1.3265 +                         const decNumber *rhs, decContext *set) {
  1.3266 +  const Unit *ua, *ub;                  /* -> operands  */
  1.3267 +  const Unit *msua, *msub;              /* -> operand msus  */
  1.3268 +  Unit  *uc, *msuc;                     /* -> result and its msu  */
  1.3269 +  Int   msudigs;                        /* digits in res msu  */
  1.3270 +  #if DECCHECK
  1.3271 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
  1.3272 +  #endif
  1.3273 +
  1.3274 +  if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
  1.3275 +   || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
  1.3276 +    decStatus(res, DEC_Invalid_operation, set);
  1.3277 +    return res;
  1.3278 +    }
  1.3279 +  /* operands are valid  */
  1.3280 +  ua=lhs->lsu;                          /* bottom-up  */
  1.3281 +  ub=rhs->lsu;                          /* ..  */
  1.3282 +  uc=res->lsu;                          /* ..  */
  1.3283 +  msua=ua+D2U(lhs->digits)-1;           /* -> msu of lhs  */
  1.3284 +  msub=ub+D2U(rhs->digits)-1;           /* -> msu of rhs  */
  1.3285 +  msuc=uc+D2U(set->digits)-1;           /* -> msu of result  */
  1.3286 +  msudigs=MSUDIGITS(set->digits);       /* [faster than remainder]  */
  1.3287 +  for (; uc<=msuc; ua++, ub++, uc++) {  /* Unit loop  */
  1.3288 +    Unit a, b;                          /* extract units  */
  1.3289 +    if (ua>msua) a=0;
  1.3290 +     else a=*ua;
  1.3291 +    if (ub>msub) b=0;
  1.3292 +     else b=*ub;
  1.3293 +    *uc=0;                              /* can now write back  */
  1.3294 +    if (a|b) {                          /* maybe 1 bits to examine  */
  1.3295 +      Int i, j;
  1.3296 +      /* This loop could be unrolled and/or use BIN2BCD tables  */
  1.3297 +      for (i=0; i<DECDPUN; i++) {
  1.3298 +        if ((a^b)&1) *uc=*uc+(Unit)powers[i];     /* effect XOR  */
  1.3299 +        j=a%10;
  1.3300 +        a=a/10;
  1.3301 +        j|=b%10;
  1.3302 +        b=b/10;
  1.3303 +        if (j>1) {
  1.3304 +          decStatus(res, DEC_Invalid_operation, set);
  1.3305 +          return res;
  1.3306 +          }
  1.3307 +        if (uc==msuc && i==msudigs-1) break;      /* just did final digit  */
  1.3308 +        } /* each digit  */
  1.3309 +      } /* non-zero  */
  1.3310 +    } /* each unit  */
  1.3311 +  /* [here uc-1 is the msu of the result]  */
  1.3312 +  res->digits=decGetDigits(res->lsu, uc-res->lsu);
  1.3313 +  res->exponent=0;                      /* integer  */
  1.3314 +  res->bits=0;                          /* sign=0  */
  1.3315 +  return res;  /* [no status to set]  */
  1.3316 +  } /* decNumberXor  */
  1.3317 +
  1.3318 +
  1.3319 +/* ================================================================== */
  1.3320 +/* Utility routines                                                   */
  1.3321 +/* ================================================================== */
  1.3322 +
  1.3323 +/* ------------------------------------------------------------------ */
  1.3324 +/* decNumberClass -- return the decClass of a decNumber               */
  1.3325 +/*   dn -- the decNumber to test                                      */
  1.3326 +/*   set -- the context to use for Emin                               */
  1.3327 +/*   returns the decClass enum                                        */
  1.3328 +/* ------------------------------------------------------------------ */
  1.3329 +enum decClass uprv_decNumberClass(const decNumber *dn, decContext *set) {
  1.3330 +  if (decNumberIsSpecial(dn)) {
  1.3331 +    if (decNumberIsQNaN(dn)) return DEC_CLASS_QNAN;
  1.3332 +    if (decNumberIsSNaN(dn)) return DEC_CLASS_SNAN;
  1.3333 +    /* must be an infinity  */
  1.3334 +    if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_INF;
  1.3335 +    return DEC_CLASS_POS_INF;
  1.3336 +    }
  1.3337 +  /* is finite  */
  1.3338 +  if (uprv_decNumberIsNormal(dn, set)) { /* most common  */
  1.3339 +    if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_NORMAL;
  1.3340 +    return DEC_CLASS_POS_NORMAL;
  1.3341 +    }
  1.3342 +  /* is subnormal or zero  */
  1.3343 +  if (decNumberIsZero(dn)) {    /* most common  */
  1.3344 +    if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_ZERO;
  1.3345 +    return DEC_CLASS_POS_ZERO;
  1.3346 +    }
  1.3347 +  if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_SUBNORMAL;
  1.3348 +  return DEC_CLASS_POS_SUBNORMAL;
  1.3349 +  } /* decNumberClass  */
  1.3350 +
  1.3351 +/* ------------------------------------------------------------------ */
  1.3352 +/* decNumberClassToString -- convert decClass to a string             */
  1.3353 +/*                                                                    */
  1.3354 +/*  eclass is a valid decClass                                        */
  1.3355 +/*  returns a constant string describing the class (max 13+1 chars)   */
  1.3356 +/* ------------------------------------------------------------------ */
  1.3357 +const char *uprv_decNumberClassToString(enum decClass eclass) {
  1.3358 +  if (eclass==DEC_CLASS_POS_NORMAL)    return DEC_ClassString_PN;
  1.3359 +  if (eclass==DEC_CLASS_NEG_NORMAL)    return DEC_ClassString_NN;
  1.3360 +  if (eclass==DEC_CLASS_POS_ZERO)      return DEC_ClassString_PZ;
  1.3361 +  if (eclass==DEC_CLASS_NEG_ZERO)      return DEC_ClassString_NZ;
  1.3362 +  if (eclass==DEC_CLASS_POS_SUBNORMAL) return DEC_ClassString_PS;
  1.3363 +  if (eclass==DEC_CLASS_NEG_SUBNORMAL) return DEC_ClassString_NS;
  1.3364 +  if (eclass==DEC_CLASS_POS_INF)       return DEC_ClassString_PI;
  1.3365 +  if (eclass==DEC_CLASS_NEG_INF)       return DEC_ClassString_NI;
  1.3366 +  if (eclass==DEC_CLASS_QNAN)          return DEC_ClassString_QN;
  1.3367 +  if (eclass==DEC_CLASS_SNAN)          return DEC_ClassString_SN;
  1.3368 +  return DEC_ClassString_UN;           /* Unknown  */
  1.3369 +  } /* decNumberClassToString  */
  1.3370 +
  1.3371 +/* ------------------------------------------------------------------ */
  1.3372 +/* decNumberCopy -- copy a number                                     */
  1.3373 +/*                                                                    */
  1.3374 +/*   dest is the target decNumber                                     */
  1.3375 +/*   src  is the source decNumber                                     */
  1.3376 +/*   returns dest                                                     */
  1.3377 +/*                                                                    */
  1.3378 +/* (dest==src is allowed and is a no-op)                              */
  1.3379 +/* All fields are updated as required.  This is a utility operation,  */
  1.3380 +/* so special values are unchanged and no error is possible.          */
  1.3381 +/* ------------------------------------------------------------------ */
  1.3382 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCopy(decNumber *dest, const decNumber *src) {
  1.3383 +
  1.3384 +  #if DECCHECK
  1.3385 +  if (src==NULL) return uprv_decNumberZero(dest);
  1.3386 +  #endif
  1.3387 +
  1.3388 +  if (dest==src) return dest;                /* no copy required  */
  1.3389 +
  1.3390 +  /* Use explicit assignments here as structure assignment could copy  */
  1.3391 +  /* more than just the lsu (for small DECDPUN).  This would not affect  */
  1.3392 +  /* the value of the results, but could disturb test harness spill  */
  1.3393 +  /* checking.  */
  1.3394 +  dest->bits=src->bits;
  1.3395 +  dest->exponent=src->exponent;
  1.3396 +  dest->digits=src->digits;
  1.3397 +  dest->lsu[0]=src->lsu[0];
  1.3398 +  if (src->digits>DECDPUN) {                 /* more Units to come  */
  1.3399 +    const Unit *smsup, *s;                   /* work  */
  1.3400 +    Unit  *d;                                /* ..  */
  1.3401 +    /* memcpy for the remaining Units would be safe as they cannot  */
  1.3402 +    /* overlap.  However, this explicit loop is faster in short cases.  */
  1.3403 +    d=dest->lsu+1;                           /* -> first destination  */
  1.3404 +    smsup=src->lsu+D2U(src->digits);         /* -> source msu+1  */
  1.3405 +    for (s=src->lsu+1; s<smsup; s++, d++) *d=*s;
  1.3406 +    }
  1.3407 +  return dest;
  1.3408 +  } /* decNumberCopy  */
  1.3409 +
  1.3410 +/* ------------------------------------------------------------------ */
  1.3411 +/* decNumberCopyAbs -- quiet absolute value operator                  */
  1.3412 +/*                                                                    */
  1.3413 +/*   This sets C = abs(A)                                             */
  1.3414 +/*                                                                    */
  1.3415 +/*   res is C, the result.  C may be A                                */
  1.3416 +/*   rhs is A                                                         */
  1.3417 +/*                                                                    */
  1.3418 +/* C must have space for set->digits digits.                          */
  1.3419 +/* No exception or error can occur; this is a quiet bitwise operation.*/
  1.3420 +/* See also decNumberAbs for a checking version of this.              */
  1.3421 +/* ------------------------------------------------------------------ */
  1.3422 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCopyAbs(decNumber *res, const decNumber *rhs) {
  1.3423 +  #if DECCHECK
  1.3424 +  if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
  1.3425 +  #endif
  1.3426 +  uprv_decNumberCopy(res, rhs);
  1.3427 +  res->bits&=~DECNEG;                   /* turn off sign  */
  1.3428 +  return res;
  1.3429 +  } /* decNumberCopyAbs  */
  1.3430 +
  1.3431 +/* ------------------------------------------------------------------ */
  1.3432 +/* decNumberCopyNegate -- quiet negate value operator                 */
  1.3433 +/*                                                                    */
  1.3434 +/*   This sets C = negate(A)                                          */
  1.3435 +/*                                                                    */
  1.3436 +/*   res is C, the result.  C may be A                                */
  1.3437 +/*   rhs is A                                                         */
  1.3438 +/*                                                                    */
  1.3439 +/* C must have space for set->digits digits.                          */
  1.3440 +/* No exception or error can occur; this is a quiet bitwise operation.*/
  1.3441 +/* See also decNumberMinus for a checking version of this.            */
  1.3442 +/* ------------------------------------------------------------------ */
  1.3443 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCopyNegate(decNumber *res, const decNumber *rhs) {
  1.3444 +  #if DECCHECK
  1.3445 +  if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
  1.3446 +  #endif
  1.3447 +  uprv_decNumberCopy(res, rhs);
  1.3448 +  res->bits^=DECNEG;                    /* invert the sign  */
  1.3449 +  return res;
  1.3450 +  } /* decNumberCopyNegate  */
  1.3451 +
  1.3452 +/* ------------------------------------------------------------------ */
  1.3453 +/* decNumberCopySign -- quiet copy and set sign operator              */
  1.3454 +/*                                                                    */
  1.3455 +/*   This sets C = A with the sign of B                               */
  1.3456 +/*                                                                    */
  1.3457 +/*   res is C, the result.  C may be A                                */
  1.3458 +/*   lhs is A                                                         */
  1.3459 +/*   rhs is B                                                         */
  1.3460 +/*                                                                    */
  1.3461 +/* C must have space for set->digits digits.                          */
  1.3462 +/* No exception or error can occur; this is a quiet bitwise operation.*/
  1.3463 +/* ------------------------------------------------------------------ */
  1.3464 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCopySign(decNumber *res, const decNumber *lhs,
  1.3465 +                              const decNumber *rhs) {
  1.3466 +  uByte sign;                           /* rhs sign  */
  1.3467 +  #if DECCHECK
  1.3468 +  if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
  1.3469 +  #endif
  1.3470 +  sign=rhs->bits & DECNEG;              /* save sign bit  */
  1.3471 +  uprv_decNumberCopy(res, lhs);
  1.3472 +  res->bits&=~DECNEG;                   /* clear the sign  */
  1.3473 +  res->bits|=sign;                      /* set from rhs  */
  1.3474 +  return res;
  1.3475 +  } /* decNumberCopySign  */
  1.3476 +
  1.3477 +/* ------------------------------------------------------------------ */
  1.3478 +/* decNumberGetBCD -- get the coefficient in BCD8                     */
  1.3479 +/*   dn is the source decNumber                                       */
  1.3480 +/*   bcd is the uInt array that will receive dn->digits BCD bytes,    */
  1.3481 +/*     most-significant at offset 0                                   */
  1.3482 +/*   returns bcd                                                      */
  1.3483 +/*                                                                    */
  1.3484 +/* bcd must have at least dn->digits bytes.  No error is possible; if */
  1.3485 +/* dn is a NaN or Infinite, digits must be 1 and the coefficient 0.   */
  1.3486 +/* ------------------------------------------------------------------ */
  1.3487 +U_CAPI uByte * U_EXPORT2 uprv_decNumberGetBCD(const decNumber *dn, uByte *bcd) {
  1.3488 +  uByte *ub=bcd+dn->digits-1;      /* -> lsd  */
  1.3489 +  const Unit *up=dn->lsu;          /* Unit pointer, -> lsu  */
  1.3490 +
  1.3491 +  #if DECDPUN==1                   /* trivial simple copy  */
  1.3492 +    for (; ub>=bcd; ub--, up++) *ub=*up;
  1.3493 +  #else                            /* chopping needed  */
  1.3494 +    uInt u=*up;                    /* work  */
  1.3495 +    uInt cut=DECDPUN;              /* downcounter through unit  */
  1.3496 +    for (; ub>=bcd; ub--) {
  1.3497 +      *ub=(uByte)(u%10);           /* [*6554 trick inhibits, here]  */
  1.3498 +      u=u/10;
  1.3499 +      cut--;
  1.3500 +      if (cut>0) continue;         /* more in this unit  */
  1.3501 +      up++;
  1.3502 +      u=*up;
  1.3503 +      cut=DECDPUN;
  1.3504 +      }
  1.3505 +  #endif
  1.3506 +  return bcd;
  1.3507 +  } /* decNumberGetBCD  */
  1.3508 +
  1.3509 +/* ------------------------------------------------------------------ */
  1.3510 +/* decNumberSetBCD -- set (replace) the coefficient from BCD8         */
  1.3511 +/*   dn is the target decNumber                                       */
  1.3512 +/*   bcd is the uInt array that will source n BCD bytes, most-        */
  1.3513 +/*     significant at offset 0                                        */
  1.3514 +/*   n is the number of digits in the source BCD array (bcd)          */
  1.3515 +/*   returns dn                                                       */
  1.3516 +/*                                                                    */
  1.3517 +/* dn must have space for at least n digits.  No error is possible;   */
  1.3518 +/* if dn is a NaN, or Infinite, or is to become a zero, n must be 1   */
  1.3519 +/* and bcd[0] zero.                                                   */
  1.3520 +/* ------------------------------------------------------------------ */
  1.3521 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberSetBCD(decNumber *dn, const uByte *bcd, uInt n) {
  1.3522 +  Unit *up=dn->lsu+D2U(dn->digits)-1;   /* -> msu [target pointer]  */
  1.3523 +  const uByte *ub=bcd;                  /* -> source msd  */
  1.3524 +
  1.3525 +  #if DECDPUN==1                        /* trivial simple copy  */
  1.3526 +    for (; ub<bcd+n; ub++, up--) *up=*ub;
  1.3527 +  #else                                 /* some assembly needed  */
  1.3528 +    /* calculate how many digits in msu, and hence first cut  */
  1.3529 +    Int cut=MSUDIGITS(n);               /* [faster than remainder]  */
  1.3530 +    for (;up>=dn->lsu; up--) {          /* each Unit from msu  */
  1.3531 +      *up=0;                            /* will take <=DECDPUN digits  */
  1.3532 +      for (; cut>0; ub++, cut--) *up=X10(*up)+*ub;
  1.3533 +      cut=DECDPUN;                      /* next Unit has all digits  */
  1.3534 +      }
  1.3535 +  #endif
  1.3536 +  dn->digits=n;                         /* set digit count  */
  1.3537 +  return dn;
  1.3538 +  } /* decNumberSetBCD  */
  1.3539 +
  1.3540 +/* ------------------------------------------------------------------ */
  1.3541 +/* decNumberIsNormal -- test normality of a decNumber                 */
  1.3542 +/*   dn is the decNumber to test                                      */
  1.3543 +/*   set is the context to use for Emin                               */
  1.3544 +/*   returns 1 if |dn| is finite and >=Nmin, 0 otherwise              */
  1.3545 +/* ------------------------------------------------------------------ */
  1.3546 +Int uprv_decNumberIsNormal(const decNumber *dn, decContext *set) {
  1.3547 +  Int ae;                               /* adjusted exponent  */
  1.3548 +  #if DECCHECK
  1.3549 +  if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
  1.3550 +  #endif
  1.3551 +
  1.3552 +  if (decNumberIsSpecial(dn)) return 0; /* not finite  */
  1.3553 +  if (decNumberIsZero(dn)) return 0;    /* not non-zero  */
  1.3554 +
  1.3555 +  ae=dn->exponent+dn->digits-1;         /* adjusted exponent  */
  1.3556 +  if (ae<set->emin) return 0;           /* is subnormal  */
  1.3557 +  return 1;
  1.3558 +  } /* decNumberIsNormal  */
  1.3559 +
  1.3560 +/* ------------------------------------------------------------------ */
  1.3561 +/* decNumberIsSubnormal -- test subnormality of a decNumber           */
  1.3562 +/*   dn is the decNumber to test                                      */
  1.3563 +/*   set is the context to use for Emin                               */
  1.3564 +/*   returns 1 if |dn| is finite, non-zero, and <Nmin, 0 otherwise    */
  1.3565 +/* ------------------------------------------------------------------ */
  1.3566 +Int uprv_decNumberIsSubnormal(const decNumber *dn, decContext *set) {
  1.3567 +  Int ae;                               /* adjusted exponent  */
  1.3568 +  #if DECCHECK
  1.3569 +  if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
  1.3570 +  #endif
  1.3571 +
  1.3572 +  if (decNumberIsSpecial(dn)) return 0; /* not finite  */
  1.3573 +  if (decNumberIsZero(dn)) return 0;    /* not non-zero  */
  1.3574 +
  1.3575 +  ae=dn->exponent+dn->digits-1;         /* adjusted exponent  */
  1.3576 +  if (ae<set->emin) return 1;           /* is subnormal  */
  1.3577 +  return 0;
  1.3578 +  } /* decNumberIsSubnormal  */
  1.3579 +
  1.3580 +/* ------------------------------------------------------------------ */
  1.3581 +/* decNumberTrim -- remove insignificant zeros                        */
  1.3582 +/*                                                                    */
  1.3583 +/*   dn is the number to trim                                         */
  1.3584 +/*   returns dn                                                       */
  1.3585 +/*                                                                    */
  1.3586 +/* All fields are updated as required.  This is a utility operation,  */
  1.3587 +/* so special values are unchanged and no error is possible.  The     */
  1.3588 +/* zeros are removed unconditionally.                                 */
  1.3589 +/* ------------------------------------------------------------------ */
  1.3590 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberTrim(decNumber *dn) {
  1.3591 +  Int  dropped;                    /* work  */
  1.3592 +  decContext set;                  /* ..  */
  1.3593 +  #if DECCHECK
  1.3594 +  if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn;
  1.3595 +  #endif
  1.3596 +  uprv_decContextDefault(&set, DEC_INIT_BASE);    /* clamp=0  */
  1.3597 +  return decTrim(dn, &set, 0, 1, &dropped);
  1.3598 +  } /* decNumberTrim  */
  1.3599 +
  1.3600 +/* ------------------------------------------------------------------ */
  1.3601 +/* decNumberVersion -- return the name and version of this module     */
  1.3602 +/*                                                                    */
  1.3603 +/* No error is possible.                                              */
  1.3604 +/* ------------------------------------------------------------------ */
  1.3605 +const char * uprv_decNumberVersion(void) {
  1.3606 +  return DECVERSION;
  1.3607 +  } /* decNumberVersion  */
  1.3608 +
  1.3609 +/* ------------------------------------------------------------------ */
  1.3610 +/* decNumberZero -- set a number to 0                                 */
  1.3611 +/*                                                                    */
  1.3612 +/*   dn is the number to set, with space for one digit                */
  1.3613 +/*   returns dn                                                       */
  1.3614 +/*                                                                    */
  1.3615 +/* No error is possible.                                              */
  1.3616 +/* ------------------------------------------------------------------ */
  1.3617 +/* Memset is not used as it is much slower in some environments.  */
  1.3618 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberZero(decNumber *dn) {
  1.3619 +
  1.3620 +  #if DECCHECK
  1.3621 +  if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
  1.3622 +  #endif
  1.3623 +
  1.3624 +  dn->bits=0;
  1.3625 +  dn->exponent=0;
  1.3626 +  dn->digits=1;
  1.3627 +  dn->lsu[0]=0;
  1.3628 +  return dn;
  1.3629 +  } /* decNumberZero  */
  1.3630 +
  1.3631 +/* ================================================================== */
  1.3632 +/* Local routines                                                     */
  1.3633 +/* ================================================================== */
  1.3634 +
  1.3635 +/* ------------------------------------------------------------------ */
  1.3636 +/* decToString -- lay out a number into a string                      */
  1.3637 +/*                                                                    */
  1.3638 +/*   dn     is the number to lay out                                  */
  1.3639 +/*   string is where to lay out the number                            */
  1.3640 +/*   eng    is 1 if Engineering, 0 if Scientific                      */
  1.3641 +/*                                                                    */
  1.3642 +/* string must be at least dn->digits+14 characters long              */
  1.3643 +/* No error is possible.                                              */
  1.3644 +/*                                                                    */
  1.3645 +/* Note that this routine can generate a -0 or 0.000.  These are      */
  1.3646 +/* never generated in subset to-number or arithmetic, but can occur   */
  1.3647 +/* in non-subset arithmetic (e.g., -1*0 or 1.234-1.234).              */
  1.3648 +/* ------------------------------------------------------------------ */
  1.3649 +/* If DECCHECK is enabled the string "?" is returned if a number is  */
  1.3650 +/* invalid.  */
  1.3651 +static void decToString(const decNumber *dn, char *string, Flag eng) {
  1.3652 +  Int exp=dn->exponent;       /* local copy  */
  1.3653 +  Int e;                      /* E-part value  */
  1.3654 +  Int pre;                    /* digits before the '.'  */
  1.3655 +  Int cut;                    /* for counting digits in a Unit  */
  1.3656 +  char *c=string;             /* work [output pointer]  */
  1.3657 +  const Unit *up=dn->lsu+D2U(dn->digits)-1; /* -> msu [input pointer]  */
  1.3658 +  uInt u, pow;                /* work  */
  1.3659 +
  1.3660 +  #if DECCHECK
  1.3661 +  if (decCheckOperands(DECUNRESU, dn, DECUNUSED, DECUNCONT)) {
  1.3662 +    strcpy(string, "?");
  1.3663 +    return;}
  1.3664 +  #endif
  1.3665 +
  1.3666 +  if (decNumberIsNegative(dn)) {   /* Negatives get a minus  */
  1.3667 +    *c='-';
  1.3668 +    c++;
  1.3669 +    }
  1.3670 +  if (dn->bits&DECSPECIAL) {       /* Is a special value  */
  1.3671 +    if (decNumberIsInfinite(dn)) {
  1.3672 +      strcpy(c,   "Inf");
  1.3673 +      strcpy(c+3, "inity");
  1.3674 +      return;}
  1.3675 +    /* a NaN  */
  1.3676 +    if (dn->bits&DECSNAN) {        /* signalling NaN  */
  1.3677 +      *c='s';
  1.3678 +      c++;
  1.3679 +      }
  1.3680 +    strcpy(c, "NaN");
  1.3681 +    c+=3;                          /* step past  */
  1.3682 +    /* if not a clean non-zero coefficient, that's all there is in a  */
  1.3683 +    /* NaN string  */
  1.3684 +    if (exp!=0 || (*dn->lsu==0 && dn->digits==1)) return;
  1.3685 +    /* [drop through to add integer]  */
  1.3686 +    }
  1.3687 +
  1.3688 +  /* calculate how many digits in msu, and hence first cut  */
  1.3689 +  cut=MSUDIGITS(dn->digits);       /* [faster than remainder]  */
  1.3690 +  cut--;                           /* power of ten for digit  */
  1.3691 +
  1.3692 +  if (exp==0) {                    /* simple integer [common fastpath]  */
  1.3693 +    for (;up>=dn->lsu; up--) {     /* each Unit from msu  */
  1.3694 +      u=*up;                       /* contains DECDPUN digits to lay out  */
  1.3695 +      for (; cut>=0; c++, cut--) TODIGIT(u, cut, c, pow);
  1.3696 +      cut=DECDPUN-1;               /* next Unit has all digits  */
  1.3697 +      }
  1.3698 +    *c='\0';                       /* terminate the string  */
  1.3699 +    return;}
  1.3700 +
  1.3701 +  /* non-0 exponent -- assume plain form */
  1.3702 +  pre=dn->digits+exp;              /* digits before '.'  */
  1.3703 +  e=0;                             /* no E  */
  1.3704 +  if ((exp>0) || (pre<-5)) {       /* need exponential form  */
  1.3705 +    e=exp+dn->digits-1;            /* calculate E value  */
  1.3706 +    pre=1;                         /* assume one digit before '.'  */
  1.3707 +    if (eng && (e!=0)) {           /* engineering: may need to adjust  */
  1.3708 +      Int adj;                     /* adjustment  */
  1.3709 +      /* The C remainder operator is undefined for negative numbers, so  */
  1.3710 +      /* a positive remainder calculation must be used here  */
  1.3711 +      if (e<0) {
  1.3712 +        adj=(-e)%3;
  1.3713 +        if (adj!=0) adj=3-adj;
  1.3714 +        }
  1.3715 +       else { /* e>0  */
  1.3716 +        adj=e%3;
  1.3717 +        }
  1.3718 +      e=e-adj;
  1.3719 +      /* if dealing with zero still produce an exponent which is a  */
  1.3720 +      /* multiple of three, as expected, but there will only be the  */
  1.3721 +      /* one zero before the E, still.  Otherwise note the padding.  */
  1.3722 +      if (!ISZERO(dn)) pre+=adj;
  1.3723 +       else {  /* is zero  */
  1.3724 +        if (adj!=0) {              /* 0.00Esnn needed  */
  1.3725 +          e=e+3;
  1.3726 +          pre=-(2-adj);
  1.3727 +          }
  1.3728 +        } /* zero  */
  1.3729 +      } /* eng  */
  1.3730 +    } /* need exponent  */
  1.3731 +
  1.3732 +  /* lay out the digits of the coefficient, adding 0s and . as needed */
  1.3733 +  u=*up;
  1.3734 +  if (pre>0) {                     /* xxx.xxx or xx00 (engineering) form  */
  1.3735 +    Int n=pre;
  1.3736 +    for (; pre>0; pre--, c++, cut--) {
  1.3737 +      if (cut<0) {                 /* need new Unit  */
  1.3738 +        if (up==dn->lsu) break;    /* out of input digits (pre>digits)  */
  1.3739 +        up--;
  1.3740 +        cut=DECDPUN-1;
  1.3741 +        u=*up;
  1.3742 +        }
  1.3743 +      TODIGIT(u, cut, c, pow);
  1.3744 +      }
  1.3745 +    if (n<dn->digits) {            /* more to come, after '.'  */
  1.3746 +      *c='.'; c++;
  1.3747 +      for (;; c++, cut--) {
  1.3748 +        if (cut<0) {               /* need new Unit  */
  1.3749 +          if (up==dn->lsu) break;  /* out of input digits  */
  1.3750 +          up--;
  1.3751 +          cut=DECDPUN-1;
  1.3752 +          u=*up;
  1.3753 +          }
  1.3754 +        TODIGIT(u, cut, c, pow);
  1.3755 +        }
  1.3756 +      }
  1.3757 +     else for (; pre>0; pre--, c++) *c='0'; /* 0 padding (for engineering) needed  */
  1.3758 +    }
  1.3759 +   else {                          /* 0.xxx or 0.000xxx form  */
  1.3760 +    *c='0'; c++;
  1.3761 +    *c='.'; c++;
  1.3762 +    for (; pre<0; pre++, c++) *c='0';   /* add any 0's after '.'  */
  1.3763 +    for (; ; c++, cut--) {
  1.3764 +      if (cut<0) {                 /* need new Unit  */
  1.3765 +        if (up==dn->lsu) break;    /* out of input digits  */
  1.3766 +        up--;
  1.3767 +        cut=DECDPUN-1;
  1.3768 +        u=*up;
  1.3769 +        }
  1.3770 +      TODIGIT(u, cut, c, pow);
  1.3771 +      }
  1.3772 +    }
  1.3773 +
  1.3774 +  /* Finally add the E-part, if needed.  It will never be 0, has a
  1.3775 +     base maximum and minimum of +999999999 through -999999999, but
  1.3776 +     could range down to -1999999998 for anormal numbers */
  1.3777 +  if (e!=0) {
  1.3778 +    Flag had=0;               /* 1=had non-zero  */
  1.3779 +    *c='E'; c++;
  1.3780 +    *c='+'; c++;              /* assume positive  */
  1.3781 +    u=e;                      /* ..  */
  1.3782 +    if (e<0) {
  1.3783 +      *(c-1)='-';             /* oops, need -  */
  1.3784 +      u=-e;                   /* uInt, please  */
  1.3785 +      }
  1.3786 +    /* lay out the exponent [_itoa or equivalent is not ANSI C]  */
  1.3787 +    for (cut=9; cut>=0; cut--) {
  1.3788 +      TODIGIT(u, cut, c, pow);
  1.3789 +      if (*c=='0' && !had) continue;    /* skip leading zeros  */
  1.3790 +      had=1;                            /* had non-0  */
  1.3791 +      c++;                              /* step for next  */
  1.3792 +      } /* cut  */
  1.3793 +    }
  1.3794 +  *c='\0';          /* terminate the string (all paths)  */
  1.3795 +  return;
  1.3796 +  } /* decToString  */
  1.3797 +
  1.3798 +/* ------------------------------------------------------------------ */
  1.3799 +/* decAddOp -- add/subtract operation                                 */
  1.3800 +/*                                                                    */
  1.3801 +/*   This computes C = A + B                                          */
  1.3802 +/*                                                                    */
  1.3803 +/*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
  1.3804 +/*   lhs is A                                                         */
  1.3805 +/*   rhs is B                                                         */
  1.3806 +/*   set is the context                                               */
  1.3807 +/*   negate is DECNEG if rhs should be negated, or 0 otherwise        */
  1.3808 +/*   status accumulates status for the caller                         */
  1.3809 +/*                                                                    */
  1.3810 +/* C must have space for set->digits digits.                          */
  1.3811 +/* Inexact in status must be 0 for correct Exact zero sign in result  */
  1.3812 +/* ------------------------------------------------------------------ */
  1.3813 +/* If possible, the coefficient is calculated directly into C.        */
  1.3814 +/* However, if:                                                       */
  1.3815 +/*   -- a digits+1 calculation is needed because the numbers are      */
  1.3816 +/*      unaligned and span more than set->digits digits               */
  1.3817 +/*   -- a carry to digits+1 digits looks possible                     */
  1.3818 +/*   -- C is the same as A or B, and the result would destructively   */
  1.3819 +/*      overlap the A or B coefficient                                */
  1.3820 +/* then the result must be calculated into a temporary buffer.  In    */
  1.3821 +/* this case a local (stack) buffer is used if possible, and only if  */
  1.3822 +/* too long for that does malloc become the final resort.             */
  1.3823 +/*                                                                    */
  1.3824 +/* Misalignment is handled as follows:                                */
  1.3825 +/*   Apad: (AExp>BExp) Swap operands and proceed as for BExp>AExp.    */
  1.3826 +/*   BPad: Apply the padding by a combination of shifting (whole      */
  1.3827 +/*         units) and multiplication (part units).                    */
  1.3828 +/*                                                                    */
  1.3829 +/* Addition, especially x=x+1, is speed-critical.                     */
  1.3830 +/* The static buffer is larger than might be expected to allow for    */
  1.3831 +/* calls from higher-level funtions (notable exp).                    */
  1.3832 +/* ------------------------------------------------------------------ */
  1.3833 +static decNumber * decAddOp(decNumber *res, const decNumber *lhs,
  1.3834 +                            const decNumber *rhs, decContext *set,
  1.3835 +                            uByte negate, uInt *status) {
  1.3836 +  #if DECSUBSET
  1.3837 +  decNumber *alloclhs=NULL;        /* non-NULL if rounded lhs allocated  */
  1.3838 +  decNumber *allocrhs=NULL;        /* .., rhs  */
  1.3839 +  #endif
  1.3840 +  Int   rhsshift;                  /* working shift (in Units)  */
  1.3841 +  Int   maxdigits;                 /* longest logical length  */
  1.3842 +  Int   mult;                      /* multiplier  */
  1.3843 +  Int   residue;                   /* rounding accumulator  */
  1.3844 +  uByte bits;                      /* result bits  */
  1.3845 +  Flag  diffsign;                  /* non-0 if arguments have different sign  */
  1.3846 +  Unit  *acc;                      /* accumulator for result  */
  1.3847 +  Unit  accbuff[SD2U(DECBUFFER*2+20)]; /* local buffer [*2+20 reduces many  */
  1.3848 +                                   /* allocations when called from  */
  1.3849 +                                   /* other operations, notable exp]  */
  1.3850 +  Unit  *allocacc=NULL;            /* -> allocated acc buffer, iff allocated  */
  1.3851 +  Int   reqdigits=set->digits;     /* local copy; requested DIGITS  */
  1.3852 +  Int   padding;                   /* work  */
  1.3853 +
  1.3854 +  #if DECCHECK
  1.3855 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
  1.3856 +  #endif
  1.3857 +
  1.3858 +  do {                             /* protect allocated storage  */
  1.3859 +    #if DECSUBSET
  1.3860 +    if (!set->extended) {
  1.3861 +      /* reduce operands and set lostDigits status, as needed  */
  1.3862 +      if (lhs->digits>reqdigits) {
  1.3863 +        alloclhs=decRoundOperand(lhs, set, status);
  1.3864 +        if (alloclhs==NULL) break;
  1.3865 +        lhs=alloclhs;
  1.3866 +        }
  1.3867 +      if (rhs->digits>reqdigits) {
  1.3868 +        allocrhs=decRoundOperand(rhs, set, status);
  1.3869 +        if (allocrhs==NULL) break;
  1.3870 +        rhs=allocrhs;
  1.3871 +        }
  1.3872 +      }
  1.3873 +    #endif
  1.3874 +    /* [following code does not require input rounding]  */
  1.3875 +
  1.3876 +    /* note whether signs differ [used all paths]  */
  1.3877 +    diffsign=(Flag)((lhs->bits^rhs->bits^negate)&DECNEG);
  1.3878 +
  1.3879 +    /* handle infinities and NaNs  */
  1.3880 +    if (SPECIALARGS) {                  /* a special bit set  */
  1.3881 +      if (SPECIALARGS & (DECSNAN | DECNAN))  /* a NaN  */
  1.3882 +        decNaNs(res, lhs, rhs, set, status);
  1.3883 +       else { /* one or two infinities  */
  1.3884 +        if (decNumberIsInfinite(lhs)) { /* LHS is infinity  */
  1.3885 +          /* two infinities with different signs is invalid  */
  1.3886 +          if (decNumberIsInfinite(rhs) && diffsign) {
  1.3887 +            *status|=DEC_Invalid_operation;
  1.3888 +            break;
  1.3889 +            }
  1.3890 +          bits=lhs->bits & DECNEG;      /* get sign from LHS  */
  1.3891 +          }
  1.3892 +         else bits=(rhs->bits^negate) & DECNEG;/* RHS must be Infinity  */
  1.3893 +        bits|=DECINF;
  1.3894 +        uprv_decNumberZero(res);
  1.3895 +        res->bits=bits;                 /* set +/- infinity  */
  1.3896 +        } /* an infinity  */
  1.3897 +      break;
  1.3898 +      }
  1.3899 +
  1.3900 +    /* Quick exit for add 0s; return the non-0, modified as need be  */
  1.3901 +    if (ISZERO(lhs)) {
  1.3902 +      Int adjust;                       /* work  */
  1.3903 +      Int lexp=lhs->exponent;           /* save in case LHS==RES  */
  1.3904 +      bits=lhs->bits;                   /* ..  */
  1.3905 +      residue=0;                        /* clear accumulator  */
  1.3906 +      decCopyFit(res, rhs, set, &residue, status); /* copy (as needed)  */
  1.3907 +      res->bits^=negate;                /* flip if rhs was negated  */
  1.3908 +      #if DECSUBSET
  1.3909 +      if (set->extended) {              /* exponents on zeros count  */
  1.3910 +      #endif
  1.3911 +        /* exponent will be the lower of the two  */
  1.3912 +        adjust=lexp-res->exponent;      /* adjustment needed [if -ve]  */
  1.3913 +        if (ISZERO(res)) {              /* both 0: special IEEE 754 rules  */
  1.3914 +          if (adjust<0) res->exponent=lexp;  /* set exponent  */
  1.3915 +          /* 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0  */
  1.3916 +          if (diffsign) {
  1.3917 +            if (set->round!=DEC_ROUND_FLOOR) res->bits=0;
  1.3918 +             else res->bits=DECNEG;     /* preserve 0 sign  */
  1.3919 +            }
  1.3920 +          }
  1.3921 +         else { /* non-0 res  */
  1.3922 +          if (adjust<0) {     /* 0-padding needed  */
  1.3923 +            if ((res->digits-adjust)>set->digits) {
  1.3924 +              adjust=res->digits-set->digits;     /* to fit exactly  */
  1.3925 +              *status|=DEC_Rounded;               /* [but exact]  */
  1.3926 +              }
  1.3927 +            res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
  1.3928 +            res->exponent+=adjust;                /* set the exponent.  */
  1.3929 +            }
  1.3930 +          } /* non-0 res  */
  1.3931 +      #if DECSUBSET
  1.3932 +        } /* extended  */
  1.3933 +      #endif
  1.3934 +      decFinish(res, set, &residue, status);      /* clean and finalize  */
  1.3935 +      break;}
  1.3936 +
  1.3937 +    if (ISZERO(rhs)) {                  /* [lhs is non-zero]  */
  1.3938 +      Int adjust;                       /* work  */
  1.3939 +      Int rexp=rhs->exponent;           /* save in case RHS==RES  */
  1.3940 +      bits=rhs->bits;                   /* be clean  */
  1.3941 +      residue=0;                        /* clear accumulator  */
  1.3942 +      decCopyFit(res, lhs, set, &residue, status); /* copy (as needed)  */
  1.3943 +      #if DECSUBSET
  1.3944 +      if (set->extended) {              /* exponents on zeros count  */
  1.3945 +      #endif
  1.3946 +        /* exponent will be the lower of the two  */
  1.3947 +        /* [0-0 case handled above]  */
  1.3948 +        adjust=rexp-res->exponent;      /* adjustment needed [if -ve]  */
  1.3949 +        if (adjust<0) {     /* 0-padding needed  */
  1.3950 +          if ((res->digits-adjust)>set->digits) {
  1.3951 +            adjust=res->digits-set->digits;     /* to fit exactly  */
  1.3952 +            *status|=DEC_Rounded;               /* [but exact]  */
  1.3953 +            }
  1.3954 +          res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
  1.3955 +          res->exponent+=adjust;                /* set the exponent.  */
  1.3956 +          }
  1.3957 +      #if DECSUBSET
  1.3958 +        } /* extended  */
  1.3959 +      #endif
  1.3960 +      decFinish(res, set, &residue, status);      /* clean and finalize  */
  1.3961 +      break;}
  1.3962 +
  1.3963 +    /* [NB: both fastpath and mainpath code below assume these cases  */
  1.3964 +    /* (notably 0-0) have already been handled]  */
  1.3965 +
  1.3966 +    /* calculate the padding needed to align the operands  */
  1.3967 +    padding=rhs->exponent-lhs->exponent;
  1.3968 +
  1.3969 +    /* Fastpath cases where the numbers are aligned and normal, the RHS  */
  1.3970 +    /* is all in one unit, no operand rounding is needed, and no carry,  */
  1.3971 +    /* lengthening, or borrow is needed  */
  1.3972 +    if (padding==0
  1.3973 +        && rhs->digits<=DECDPUN
  1.3974 +        && rhs->exponent>=set->emin     /* [some normals drop through]  */
  1.3975 +        && rhs->exponent<=set->emax-set->digits+1 /* [could clamp]  */
  1.3976 +        && rhs->digits<=reqdigits
  1.3977 +        && lhs->digits<=reqdigits) {
  1.3978 +      Int partial=*lhs->lsu;
  1.3979 +      if (!diffsign) {                  /* adding  */
  1.3980 +        partial+=*rhs->lsu;
  1.3981 +        if ((partial<=DECDPUNMAX)       /* result fits in unit  */
  1.3982 +         && (lhs->digits>=DECDPUN ||    /* .. and no digits-count change  */
  1.3983 +             partial<(Int)powers[lhs->digits])) { /* ..  */
  1.3984 +          if (res!=lhs) uprv_decNumberCopy(res, lhs);  /* not in place  */
  1.3985 +          *res->lsu=(Unit)partial;      /* [copy could have overwritten RHS]  */
  1.3986 +          break;
  1.3987 +          }
  1.3988 +        /* else drop out for careful add  */
  1.3989 +        }
  1.3990 +       else {                           /* signs differ  */
  1.3991 +        partial-=*rhs->lsu;
  1.3992 +        if (partial>0) { /* no borrow needed, and non-0 result  */
  1.3993 +          if (res!=lhs) uprv_decNumberCopy(res, lhs);  /* not in place  */
  1.3994 +          *res->lsu=(Unit)partial;
  1.3995 +          /* this could have reduced digits [but result>0]  */
  1.3996 +          res->digits=decGetDigits(res->lsu, D2U(res->digits));
  1.3997 +          break;
  1.3998 +          }
  1.3999 +        /* else drop out for careful subtract  */
  1.4000 +        }
  1.4001 +      }
  1.4002 +
  1.4003 +    /* Now align (pad) the lhs or rhs so they can be added or  */
  1.4004 +    /* subtracted, as necessary.  If one number is much larger than  */
  1.4005 +    /* the other (that is, if in plain form there is a least one  */
  1.4006 +    /* digit between the lowest digit of one and the highest of the  */
  1.4007 +    /* other) padding with up to DIGITS-1 trailing zeros may be  */
  1.4008 +    /* needed; then apply rounding (as exotic rounding modes may be  */
  1.4009 +    /* affected by the residue).  */
  1.4010 +    rhsshift=0;               /* rhs shift to left (padding) in Units  */
  1.4011 +    bits=lhs->bits;           /* assume sign is that of LHS  */
  1.4012 +    mult=1;                   /* likely multiplier  */
  1.4013 +
  1.4014 +    /* [if padding==0 the operands are aligned; no padding is needed]  */
  1.4015 +    if (padding!=0) {
  1.4016 +      /* some padding needed; always pad the RHS, as any required  */
  1.4017 +      /* padding can then be effected by a simple combination of  */
  1.4018 +      /* shifts and a multiply  */
  1.4019 +      Flag swapped=0;
  1.4020 +      if (padding<0) {                  /* LHS needs the padding  */
  1.4021 +        const decNumber *t;
  1.4022 +        padding=-padding;               /* will be +ve  */
  1.4023 +        bits=(uByte)(rhs->bits^negate); /* assumed sign is now that of RHS  */
  1.4024 +        t=lhs; lhs=rhs; rhs=t;
  1.4025 +        swapped=1;
  1.4026 +        }
  1.4027 +
  1.4028 +      /* If, after pad, rhs would be longer than lhs by digits+1 or  */
  1.4029 +      /* more then lhs cannot affect the answer, except as a residue,  */
  1.4030 +      /* so only need to pad up to a length of DIGITS+1.  */
  1.4031 +      if (rhs->digits+padding > lhs->digits+reqdigits+1) {
  1.4032 +        /* The RHS is sufficient  */
  1.4033 +        /* for residue use the relative sign indication...  */
  1.4034 +        Int shift=reqdigits-rhs->digits;     /* left shift needed  */
  1.4035 +        residue=1;                           /* residue for rounding  */
  1.4036 +        if (diffsign) residue=-residue;      /* signs differ  */
  1.4037 +        /* copy, shortening if necessary  */
  1.4038 +        decCopyFit(res, rhs, set, &residue, status);
  1.4039 +        /* if it was already shorter, then need to pad with zeros  */
  1.4040 +        if (shift>0) {
  1.4041 +          res->digits=decShiftToMost(res->lsu, res->digits, shift);
  1.4042 +          res->exponent-=shift;              /* adjust the exponent.  */
  1.4043 +          }
  1.4044 +        /* flip the result sign if unswapped and rhs was negated  */
  1.4045 +        if (!swapped) res->bits^=negate;
  1.4046 +        decFinish(res, set, &residue, status);    /* done  */
  1.4047 +        break;}
  1.4048 +
  1.4049 +      /* LHS digits may affect result  */
  1.4050 +      rhsshift=D2U(padding+1)-1;        /* this much by Unit shift ..  */
  1.4051 +      mult=powers[padding-(rhsshift*DECDPUN)]; /* .. this by multiplication  */
  1.4052 +      } /* padding needed  */
  1.4053 +
  1.4054 +    if (diffsign) mult=-mult;           /* signs differ  */
  1.4055 +
  1.4056 +    /* determine the longer operand  */
  1.4057 +    maxdigits=rhs->digits+padding;      /* virtual length of RHS  */
  1.4058 +    if (lhs->digits>maxdigits) maxdigits=lhs->digits;
  1.4059 +
  1.4060 +    /* Decide on the result buffer to use; if possible place directly  */
  1.4061 +    /* into result.  */
  1.4062 +    acc=res->lsu;                       /* assume add direct to result  */
  1.4063 +    /* If destructive overlap, or the number is too long, or a carry or  */
  1.4064 +    /* borrow to DIGITS+1 might be possible, a buffer must be used.  */
  1.4065 +    /* [Might be worth more sophisticated tests when maxdigits==reqdigits]  */
  1.4066 +    if ((maxdigits>=reqdigits)          /* is, or could be, too large  */
  1.4067 +     || (res==rhs && rhsshift>0)) {     /* destructive overlap  */
  1.4068 +      /* buffer needed, choose it; units for maxdigits digits will be  */
  1.4069 +      /* needed, +1 Unit for carry or borrow  */
  1.4070 +      Int need=D2U(maxdigits)+1;
  1.4071 +      acc=accbuff;                      /* assume use local buffer  */
  1.4072 +      if (need*sizeof(Unit)>sizeof(accbuff)) {
  1.4073 +        /* printf("malloc add %ld %ld\n", need, sizeof(accbuff));  */
  1.4074 +        allocacc=(Unit *)malloc(need*sizeof(Unit));
  1.4075 +        if (allocacc==NULL) {           /* hopeless -- abandon  */
  1.4076 +          *status|=DEC_Insufficient_storage;
  1.4077 +          break;}
  1.4078 +        acc=allocacc;
  1.4079 +        }
  1.4080 +      }
  1.4081 +
  1.4082 +    res->bits=(uByte)(bits&DECNEG);     /* it's now safe to overwrite..  */
  1.4083 +    res->exponent=lhs->exponent;        /* .. operands (even if aliased)  */
  1.4084 +
  1.4085 +    #if DECTRACE
  1.4086 +      decDumpAr('A', lhs->lsu, D2U(lhs->digits));
  1.4087 +      decDumpAr('B', rhs->lsu, D2U(rhs->digits));
  1.4088 +      printf("  :h: %ld %ld\n", rhsshift, mult);
  1.4089 +    #endif
  1.4090 +
  1.4091 +    /* add [A+B*m] or subtract [A+B*(-m)]  */
  1.4092 +    U_ASSERT(rhs->digits > 0);
  1.4093 +    U_ASSERT(lhs->digits > 0);
  1.4094 +    res->digits=decUnitAddSub(lhs->lsu, D2U(lhs->digits),
  1.4095 +                              rhs->lsu, D2U(rhs->digits),
  1.4096 +                              rhsshift, acc, mult)
  1.4097 +               *DECDPUN;           /* [units -> digits]  */
  1.4098 +    if (res->digits<0) {           /* borrowed...  */
  1.4099 +      res->digits=-res->digits;
  1.4100 +      res->bits^=DECNEG;           /* flip the sign  */
  1.4101 +      }
  1.4102 +    #if DECTRACE
  1.4103 +      decDumpAr('+', acc, D2U(res->digits));
  1.4104 +    #endif
  1.4105 +
  1.4106 +    /* If a buffer was used the result must be copied back, possibly  */
  1.4107 +    /* shortening.  (If no buffer was used then the result must have  */
  1.4108 +    /* fit, so can't need rounding and residue must be 0.)  */
  1.4109 +    residue=0;                     /* clear accumulator  */
  1.4110 +    if (acc!=res->lsu) {
  1.4111 +      #if DECSUBSET
  1.4112 +      if (set->extended) {         /* round from first significant digit  */
  1.4113 +      #endif
  1.4114 +        /* remove leading zeros that were added due to rounding up to  */
  1.4115 +        /* integral Units -- before the test for rounding.  */
  1.4116 +        if (res->digits>reqdigits)
  1.4117 +          res->digits=decGetDigits(acc, D2U(res->digits));
  1.4118 +        decSetCoeff(res, set, acc, res->digits, &residue, status);
  1.4119 +      #if DECSUBSET
  1.4120 +        }
  1.4121 +       else { /* subset arithmetic rounds from original significant digit  */
  1.4122 +        /* May have an underestimate.  This only occurs when both  */
  1.4123 +        /* numbers fit in DECDPUN digits and are padding with a  */
  1.4124 +        /* negative multiple (-10, -100...) and the top digit(s) become  */
  1.4125 +        /* 0.  (This only matters when using X3.274 rules where the  */
  1.4126 +        /* leading zero could be included in the rounding.)  */
  1.4127 +        if (res->digits<maxdigits) {
  1.4128 +          *(acc+D2U(res->digits))=0; /* ensure leading 0 is there  */
  1.4129 +          res->digits=maxdigits;
  1.4130 +          }
  1.4131 +         else {
  1.4132 +          /* remove leading zeros that added due to rounding up to  */
  1.4133 +          /* integral Units (but only those in excess of the original  */
  1.4134 +          /* maxdigits length, unless extended) before test for rounding.  */
  1.4135 +          if (res->digits>reqdigits) {
  1.4136 +            res->digits=decGetDigits(acc, D2U(res->digits));
  1.4137 +            if (res->digits<maxdigits) res->digits=maxdigits;
  1.4138 +            }
  1.4139 +          }
  1.4140 +        decSetCoeff(res, set, acc, res->digits, &residue, status);
  1.4141 +        /* Now apply rounding if needed before removing leading zeros.  */
  1.4142 +        /* This is safe because subnormals are not a possibility  */
  1.4143 +        if (residue!=0) {
  1.4144 +          decApplyRound(res, set, residue, status);
  1.4145 +          residue=0;                 /* did what needed to be done  */
  1.4146 +          }
  1.4147 +        } /* subset  */
  1.4148 +      #endif
  1.4149 +      } /* used buffer  */
  1.4150 +
  1.4151 +    /* strip leading zeros [these were left on in case of subset subtract]  */
  1.4152 +    res->digits=decGetDigits(res->lsu, D2U(res->digits));
  1.4153 +
  1.4154 +    /* apply checks and rounding  */
  1.4155 +    decFinish(res, set, &residue, status);
  1.4156 +
  1.4157 +    /* "When the sum of two operands with opposite signs is exactly  */
  1.4158 +    /* zero, the sign of that sum shall be '+' in all rounding modes  */
  1.4159 +    /* except round toward -Infinity, in which mode that sign shall be  */
  1.4160 +    /* '-'."  [Subset zeros also never have '-', set by decFinish.]  */
  1.4161 +    if (ISZERO(res) && diffsign
  1.4162 +     #if DECSUBSET
  1.4163 +     && set->extended
  1.4164 +     #endif
  1.4165 +     && (*status&DEC_Inexact)==0) {
  1.4166 +      if (set->round==DEC_ROUND_FLOOR) res->bits|=DECNEG;   /* sign -  */
  1.4167 +                                  else res->bits&=~DECNEG;  /* sign +  */
  1.4168 +      }
  1.4169 +    } while(0);                              /* end protected  */
  1.4170 +
  1.4171 +  if (allocacc!=NULL) free(allocacc);        /* drop any storage used  */
  1.4172 +  #if DECSUBSET
  1.4173 +  if (allocrhs!=NULL) free(allocrhs);        /* ..  */
  1.4174 +  if (alloclhs!=NULL) free(alloclhs);        /* ..  */
  1.4175 +  #endif
  1.4176 +  return res;
  1.4177 +  } /* decAddOp  */
  1.4178 +
  1.4179 +/* ------------------------------------------------------------------ */
  1.4180 +/* decDivideOp -- division operation                                  */
  1.4181 +/*                                                                    */
  1.4182 +/*  This routine performs the calculations for all four division      */
  1.4183 +/*  operators (divide, divideInteger, remainder, remainderNear).      */
  1.4184 +/*                                                                    */
  1.4185 +/*  C=A op B                                                          */
  1.4186 +/*                                                                    */
  1.4187 +/*   res is C, the result.  C may be A and/or B (e.g., X=X/X)         */
  1.4188 +/*   lhs is A                                                         */
  1.4189 +/*   rhs is B                                                         */
  1.4190 +/*   set is the context                                               */
  1.4191 +/*   op  is DIVIDE, DIVIDEINT, REMAINDER, or REMNEAR respectively.    */
  1.4192 +/*   status is the usual accumulator                                  */
  1.4193 +/*                                                                    */
  1.4194 +/* C must have space for set->digits digits.                          */
  1.4195 +/*                                                                    */
  1.4196 +/* ------------------------------------------------------------------ */
  1.4197 +/*   The underlying algorithm of this routine is the same as in the   */
  1.4198 +/*   1981 S/370 implementation, that is, non-restoring long division  */
  1.4199 +/*   with bi-unit (rather than bi-digit) estimation for each unit     */
  1.4200 +/*   multiplier.  In this pseudocode overview, complications for the  */
  1.4201 +/*   Remainder operators and division residues for exact rounding are */
  1.4202 +/*   omitted for clarity.                                             */
  1.4203 +/*                                                                    */
  1.4204 +/*     Prepare operands and handle special values                     */
  1.4205 +/*     Test for x/0 and then 0/x                                      */
  1.4206 +/*     Exp =Exp1 - Exp2                                               */
  1.4207 +/*     Exp =Exp +len(var1) -len(var2)                                 */
  1.4208 +/*     Sign=Sign1 * Sign2                                             */
  1.4209 +/*     Pad accumulator (Var1) to double-length with 0's (pad1)        */
  1.4210 +/*     Pad Var2 to same length as Var1                                */
  1.4211 +/*     msu2pair/plus=1st 2 or 1 units of var2, +1 to allow for round  */
  1.4212 +/*     have=0                                                         */
  1.4213 +/*     Do until (have=digits+1 OR residue=0)                          */
  1.4214 +/*       if exp<0 then if integer divide/residue then leave           */
  1.4215 +/*       this_unit=0                                                  */
  1.4216 +/*       Do forever                                                   */
  1.4217 +/*          compare numbers                                           */
  1.4218 +/*          if <0 then leave inner_loop                               */
  1.4219 +/*          if =0 then (* quick exit without subtract *) do           */
  1.4220 +/*             this_unit=this_unit+1; output this_unit                */
  1.4221 +/*             leave outer_loop; end                                  */
  1.4222 +/*          Compare lengths of numbers (mantissae):                   */
  1.4223 +/*          If same then tops2=msu2pair -- {units 1&2 of var2}        */
  1.4224 +/*                  else tops2=msu2plus -- {0, unit 1 of var2}        */
  1.4225 +/*          tops1=first_unit_of_Var1*10**DECDPUN +second_unit_of_var1 */
  1.4226 +/*          mult=tops1/tops2  -- Good and safe guess at divisor       */
  1.4227 +/*          if mult=0 then mult=1                                     */
  1.4228 +/*          this_unit=this_unit+mult                                  */
  1.4229 +/*          subtract                                                  */
  1.4230 +/*          end inner_loop                                            */
  1.4231 +/*        if have\=0 | this_unit\=0 then do                           */
  1.4232 +/*          output this_unit                                          */
  1.4233 +/*          have=have+1; end                                          */
  1.4234 +/*        var2=var2/10                                                */
  1.4235 +/*        exp=exp-1                                                   */
  1.4236 +/*        end outer_loop                                              */
  1.4237 +/*     exp=exp+1   -- set the proper exponent                         */
  1.4238 +/*     if have=0 then generate answer=0                               */
  1.4239 +/*     Return (Result is defined by Var1)                             */
  1.4240 +/*                                                                    */
  1.4241 +/* ------------------------------------------------------------------ */
  1.4242 +/* Two working buffers are needed during the division; one (digits+   */
  1.4243 +/* 1) to accumulate the result, and the other (up to 2*digits+1) for  */
  1.4244 +/* long subtractions.  These are acc and var1 respectively.           */
  1.4245 +/* var1 is a copy of the lhs coefficient, var2 is the rhs coefficient.*/
  1.4246 +/* The static buffers may be larger than might be expected to allow   */
  1.4247 +/* for calls from higher-level funtions (notable exp).                */
  1.4248 +/* ------------------------------------------------------------------ */
  1.4249 +static decNumber * decDivideOp(decNumber *res,
  1.4250 +                               const decNumber *lhs, const decNumber *rhs,
  1.4251 +                               decContext *set, Flag op, uInt *status) {
  1.4252 +  #if DECSUBSET
  1.4253 +  decNumber *alloclhs=NULL;        /* non-NULL if rounded lhs allocated  */
  1.4254 +  decNumber *allocrhs=NULL;        /* .., rhs  */
  1.4255 +  #endif
  1.4256 +  Unit  accbuff[SD2U(DECBUFFER+DECDPUN+10)]; /* local buffer  */
  1.4257 +  Unit  *acc=accbuff;              /* -> accumulator array for result  */
  1.4258 +  Unit  *allocacc=NULL;            /* -> allocated buffer, iff allocated  */
  1.4259 +  Unit  *accnext;                  /* -> where next digit will go  */
  1.4260 +  Int   acclength;                 /* length of acc needed [Units]  */
  1.4261 +  Int   accunits;                  /* count of units accumulated  */
  1.4262 +  Int   accdigits;                 /* count of digits accumulated  */
  1.4263 +
  1.4264 +  Unit  varbuff[SD2U(DECBUFFER*2+DECDPUN)];  /* buffer for var1  */
  1.4265 +  Unit  *var1=varbuff;             /* -> var1 array for long subtraction  */
  1.4266 +  Unit  *varalloc=NULL;            /* -> allocated buffer, iff used  */
  1.4267 +  Unit  *msu1;                     /* -> msu of var1  */
  1.4268 +
  1.4269 +  const Unit *var2;                /* -> var2 array  */
  1.4270 +  const Unit *msu2;                /* -> msu of var2  */
  1.4271 +  Int   msu2plus;                  /* msu2 plus one [does not vary]  */
  1.4272 +  eInt  msu2pair;                  /* msu2 pair plus one [does not vary]  */
  1.4273 +
  1.4274 +  Int   var1units, var2units;      /* actual lengths  */
  1.4275 +  Int   var2ulen;                  /* logical length (units)  */
  1.4276 +  Int   var1initpad=0;             /* var1 initial padding (digits)  */
  1.4277 +  Int   maxdigits;                 /* longest LHS or required acc length  */
  1.4278 +  Int   mult;                      /* multiplier for subtraction  */
  1.4279 +  Unit  thisunit;                  /* current unit being accumulated  */
  1.4280 +  Int   residue;                   /* for rounding  */
  1.4281 +  Int   reqdigits=set->digits;     /* requested DIGITS  */
  1.4282 +  Int   exponent;                  /* working exponent  */
  1.4283 +  Int   maxexponent=0;             /* DIVIDE maximum exponent if unrounded  */
  1.4284 +  uByte bits;                      /* working sign  */
  1.4285 +  Unit  *target;                   /* work  */
  1.4286 +  const Unit *source;              /* ..  */
  1.4287 +  uInt  const *pow;                /* ..  */
  1.4288 +  Int   shift, cut;                /* ..  */
  1.4289 +  #if DECSUBSET
  1.4290 +  Int   dropped;                   /* work  */
  1.4291 +  #endif
  1.4292 +
  1.4293 +  #if DECCHECK
  1.4294 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
  1.4295 +  #endif
  1.4296 +
  1.4297 +  do {                             /* protect allocated storage  */
  1.4298 +    #if DECSUBSET
  1.4299 +    if (!set->extended) {
  1.4300 +      /* reduce operands and set lostDigits status, as needed  */
  1.4301 +      if (lhs->digits>reqdigits) {
  1.4302 +        alloclhs=decRoundOperand(lhs, set, status);
  1.4303 +        if (alloclhs==NULL) break;
  1.4304 +        lhs=alloclhs;
  1.4305 +        }
  1.4306 +      if (rhs->digits>reqdigits) {
  1.4307 +        allocrhs=decRoundOperand(rhs, set, status);
  1.4308 +        if (allocrhs==NULL) break;
  1.4309 +        rhs=allocrhs;
  1.4310 +        }
  1.4311 +      }
  1.4312 +    #endif
  1.4313 +    /* [following code does not require input rounding]  */
  1.4314 +
  1.4315 +    bits=(lhs->bits^rhs->bits)&DECNEG;  /* assumed sign for divisions  */
  1.4316 +
  1.4317 +    /* handle infinities and NaNs  */
  1.4318 +    if (SPECIALARGS) {                  /* a special bit set  */
  1.4319 +      if (SPECIALARGS & (DECSNAN | DECNAN)) { /* one or two NaNs  */
  1.4320 +        decNaNs(res, lhs, rhs, set, status);
  1.4321 +        break;
  1.4322 +        }
  1.4323 +      /* one or two infinities  */
  1.4324 +      if (decNumberIsInfinite(lhs)) {   /* LHS (dividend) is infinite  */
  1.4325 +        if (decNumberIsInfinite(rhs) || /* two infinities are invalid ..  */
  1.4326 +            op & (REMAINDER | REMNEAR)) { /* as is remainder of infinity  */
  1.4327 +          *status|=DEC_Invalid_operation;
  1.4328 +          break;
  1.4329 +          }
  1.4330 +        /* [Note that infinity/0 raises no exceptions]  */
  1.4331 +        uprv_decNumberZero(res);
  1.4332 +        res->bits=bits|DECINF;          /* set +/- infinity  */
  1.4333 +        break;
  1.4334 +        }
  1.4335 +       else {                           /* RHS (divisor) is infinite  */
  1.4336 +        residue=0;
  1.4337 +        if (op&(REMAINDER|REMNEAR)) {
  1.4338 +          /* result is [finished clone of] lhs  */
  1.4339 +          decCopyFit(res, lhs, set, &residue, status);
  1.4340 +          }
  1.4341 +         else {  /* a division  */
  1.4342 +          uprv_decNumberZero(res);
  1.4343 +          res->bits=bits;               /* set +/- zero  */
  1.4344 +          /* for DIVIDEINT the exponent is always 0.  For DIVIDE, result  */
  1.4345 +          /* is a 0 with infinitely negative exponent, clamped to minimum  */
  1.4346 +          if (op&DIVIDE) {
  1.4347 +            res->exponent=set->emin-set->digits+1;
  1.4348 +            *status|=DEC_Clamped;
  1.4349 +            }
  1.4350 +          }
  1.4351 +        decFinish(res, set, &residue, status);
  1.4352 +        break;
  1.4353 +        }
  1.4354 +      }
  1.4355 +
  1.4356 +    /* handle 0 rhs (x/0)  */
  1.4357 +    if (ISZERO(rhs)) {                  /* x/0 is always exceptional  */
  1.4358 +      if (ISZERO(lhs)) {
  1.4359 +        uprv_decNumberZero(res);             /* [after lhs test]  */
  1.4360 +        *status|=DEC_Division_undefined;/* 0/0 will become NaN  */
  1.4361 +        }
  1.4362 +       else {
  1.4363 +        uprv_decNumberZero(res);
  1.4364 +        if (op&(REMAINDER|REMNEAR)) *status|=DEC_Invalid_operation;
  1.4365 +         else {
  1.4366 +          *status|=DEC_Division_by_zero; /* x/0  */
  1.4367 +          res->bits=bits|DECINF;         /* .. is +/- Infinity  */
  1.4368 +          }
  1.4369 +        }
  1.4370 +      break;}
  1.4371 +
  1.4372 +    /* handle 0 lhs (0/x)  */
  1.4373 +    if (ISZERO(lhs)) {                  /* 0/x [x!=0]  */
  1.4374 +      #if DECSUBSET
  1.4375 +      if (!set->extended) uprv_decNumberZero(res);
  1.4376 +       else {
  1.4377 +      #endif
  1.4378 +        if (op&DIVIDE) {
  1.4379 +          residue=0;
  1.4380 +          exponent=lhs->exponent-rhs->exponent; /* ideal exponent  */
  1.4381 +          uprv_decNumberCopy(res, lhs);      /* [zeros always fit]  */
  1.4382 +          res->bits=bits;               /* sign as computed  */
  1.4383 +          res->exponent=exponent;       /* exponent, too  */
  1.4384 +          decFinalize(res, set, &residue, status);   /* check exponent  */
  1.4385 +          }
  1.4386 +         else if (op&DIVIDEINT) {
  1.4387 +          uprv_decNumberZero(res);           /* integer 0  */
  1.4388 +          res->bits=bits;               /* sign as computed  */
  1.4389 +          }
  1.4390 +         else {                         /* a remainder  */
  1.4391 +          exponent=rhs->exponent;       /* [save in case overwrite]  */
  1.4392 +          uprv_decNumberCopy(res, lhs);      /* [zeros always fit]  */
  1.4393 +          if (exponent<res->exponent) res->exponent=exponent; /* use lower  */
  1.4394 +          }
  1.4395 +      #if DECSUBSET
  1.4396 +        }
  1.4397 +      #endif
  1.4398 +      break;}
  1.4399 +
  1.4400 +    /* Precalculate exponent.  This starts off adjusted (and hence fits  */
  1.4401 +    /* in 31 bits) and becomes the usual unadjusted exponent as the  */
  1.4402 +    /* division proceeds.  The order of evaluation is important, here,  */
  1.4403 +    /* to avoid wrap.  */
  1.4404 +    exponent=(lhs->exponent+lhs->digits)-(rhs->exponent+rhs->digits);
  1.4405 +
  1.4406 +    /* If the working exponent is -ve, then some quick exits are  */
  1.4407 +    /* possible because the quotient is known to be <1  */
  1.4408 +    /* [for REMNEAR, it needs to be < -1, as -0.5 could need work]  */
  1.4409 +    if (exponent<0 && !(op==DIVIDE)) {
  1.4410 +      if (op&DIVIDEINT) {
  1.4411 +        uprv_decNumberZero(res);                  /* integer part is 0  */
  1.4412 +        #if DECSUBSET
  1.4413 +        if (set->extended)
  1.4414 +        #endif
  1.4415 +          res->bits=bits;                    /* set +/- zero  */
  1.4416 +        break;}
  1.4417 +      /* fastpath remainders so long as the lhs has the smaller  */
  1.4418 +      /* (or equal) exponent  */
  1.4419 +      if (lhs->exponent<=rhs->exponent) {
  1.4420 +        if (op&REMAINDER || exponent<-1) {
  1.4421 +          /* It is REMAINDER or safe REMNEAR; result is [finished  */
  1.4422 +          /* clone of] lhs  (r = x - 0*y)  */
  1.4423 +          residue=0;
  1.4424 +          decCopyFit(res, lhs, set, &residue, status);
  1.4425 +          decFinish(res, set, &residue, status);
  1.4426 +          break;
  1.4427 +          }
  1.4428 +        /* [unsafe REMNEAR drops through]  */
  1.4429 +        }
  1.4430 +      } /* fastpaths  */
  1.4431 +
  1.4432 +    /* Long (slow) division is needed; roll up the sleeves... */
  1.4433 +
  1.4434 +    /* The accumulator will hold the quotient of the division.  */
  1.4435 +    /* If it needs to be too long for stack storage, then allocate.  */
  1.4436 +    acclength=D2U(reqdigits+DECDPUN);   /* in Units  */
  1.4437 +    if (acclength*sizeof(Unit)>sizeof(accbuff)) {
  1.4438 +      /* printf("malloc dvacc %ld units\n", acclength);  */
  1.4439 +      allocacc=(Unit *)malloc(acclength*sizeof(Unit));
  1.4440 +      if (allocacc==NULL) {             /* hopeless -- abandon  */
  1.4441 +        *status|=DEC_Insufficient_storage;
  1.4442 +        break;}
  1.4443 +      acc=allocacc;                     /* use the allocated space  */
  1.4444 +      }
  1.4445 +
  1.4446 +    /* var1 is the padded LHS ready for subtractions.  */
  1.4447 +    /* If it needs to be too long for stack storage, then allocate.  */
  1.4448 +    /* The maximum units needed for var1 (long subtraction) is:  */
  1.4449 +    /* Enough for  */
  1.4450 +    /*     (rhs->digits+reqdigits-1) -- to allow full slide to right  */
  1.4451 +    /* or  (lhs->digits)             -- to allow for long lhs  */
  1.4452 +    /* whichever is larger  */
  1.4453 +    /*   +1                -- for rounding of slide to right  */
  1.4454 +    /*   +1                -- for leading 0s  */
  1.4455 +    /*   +1                -- for pre-adjust if a remainder or DIVIDEINT  */
  1.4456 +    /* [Note: unused units do not participate in decUnitAddSub data]  */
  1.4457 +    maxdigits=rhs->digits+reqdigits-1;
  1.4458 +    if (lhs->digits>maxdigits) maxdigits=lhs->digits;
  1.4459 +    var1units=D2U(maxdigits)+2;
  1.4460 +    /* allocate a guard unit above msu1 for REMAINDERNEAR  */
  1.4461 +    if (!(op&DIVIDE)) var1units++;
  1.4462 +    if ((var1units+1)*sizeof(Unit)>sizeof(varbuff)) {
  1.4463 +      /* printf("malloc dvvar %ld units\n", var1units+1);  */
  1.4464 +      varalloc=(Unit *)malloc((var1units+1)*sizeof(Unit));
  1.4465 +      if (varalloc==NULL) {             /* hopeless -- abandon  */
  1.4466 +        *status|=DEC_Insufficient_storage;
  1.4467 +        break;}
  1.4468 +      var1=varalloc;                    /* use the allocated space  */
  1.4469 +      }
  1.4470 +
  1.4471 +    /* Extend the lhs and rhs to full long subtraction length.  The lhs  */
  1.4472 +    /* is truly extended into the var1 buffer, with 0 padding, so a  */
  1.4473 +    /* subtract in place is always possible.  The rhs (var2) has  */
  1.4474 +    /* virtual padding (implemented by decUnitAddSub).  */
  1.4475 +    /* One guard unit was allocated above msu1 for rem=rem+rem in  */
  1.4476 +    /* REMAINDERNEAR.  */
  1.4477 +    msu1=var1+var1units-1;              /* msu of var1  */
  1.4478 +    source=lhs->lsu+D2U(lhs->digits)-1; /* msu of input array  */
  1.4479 +    for (target=msu1; source>=lhs->lsu; source--, target--) *target=*source;
  1.4480 +    for (; target>=var1; target--) *target=0;
  1.4481 +
  1.4482 +    /* rhs (var2) is left-aligned with var1 at the start  */
  1.4483 +    var2ulen=var1units;                 /* rhs logical length (units)  */
  1.4484 +    var2units=D2U(rhs->digits);         /* rhs actual length (units)  */
  1.4485 +    var2=rhs->lsu;                      /* -> rhs array  */
  1.4486 +    msu2=var2+var2units-1;              /* -> msu of var2 [never changes]  */
  1.4487 +    /* now set up the variables which will be used for estimating the  */
  1.4488 +    /* multiplication factor.  If these variables are not exact, add  */
  1.4489 +    /* 1 to make sure that the multiplier is never overestimated.  */
  1.4490 +    msu2plus=*msu2;                     /* it's value ..  */
  1.4491 +    if (var2units>1) msu2plus++;        /* .. +1 if any more  */
  1.4492 +    msu2pair=(eInt)*msu2*(DECDPUNMAX+1);/* top two pair ..  */
  1.4493 +    if (var2units>1) {                  /* .. [else treat 2nd as 0]  */
  1.4494 +      msu2pair+=*(msu2-1);              /* ..  */
  1.4495 +      if (var2units>2) msu2pair++;      /* .. +1 if any more  */
  1.4496 +      }
  1.4497 +
  1.4498 +    /* The calculation is working in units, which may have leading zeros,  */
  1.4499 +    /* but the exponent was calculated on the assumption that they are  */
  1.4500 +    /* both left-aligned.  Adjust the exponent to compensate: add the  */
  1.4501 +    /* number of leading zeros in var1 msu and subtract those in var2 msu.  */
  1.4502 +    /* [This is actually done by counting the digits and negating, as  */
  1.4503 +    /* lead1=DECDPUN-digits1, and similarly for lead2.]  */
  1.4504 +    for (pow=&powers[1]; *msu1>=*pow; pow++) exponent--;
  1.4505 +    for (pow=&powers[1]; *msu2>=*pow; pow++) exponent++;
  1.4506 +
  1.4507 +    /* Now, if doing an integer divide or remainder, ensure that  */
  1.4508 +    /* the result will be Unit-aligned.  To do this, shift the var1  */
  1.4509 +    /* accumulator towards least if need be.  (It's much easier to  */
  1.4510 +    /* do this now than to reassemble the residue afterwards, if  */
  1.4511 +    /* doing a remainder.)  Also ensure the exponent is not negative.  */
  1.4512 +    if (!(op&DIVIDE)) {
  1.4513 +      Unit *u;                          /* work  */
  1.4514 +      /* save the initial 'false' padding of var1, in digits  */
  1.4515 +      var1initpad=(var1units-D2U(lhs->digits))*DECDPUN;
  1.4516 +      /* Determine the shift to do.  */
  1.4517 +      if (exponent<0) cut=-exponent;
  1.4518 +       else cut=DECDPUN-exponent%DECDPUN;
  1.4519 +      decShiftToLeast(var1, var1units, cut);
  1.4520 +      exponent+=cut;                    /* maintain numerical value  */
  1.4521 +      var1initpad-=cut;                 /* .. and reduce padding  */
  1.4522 +      /* clean any most-significant units which were just emptied  */
  1.4523 +      for (u=msu1; cut>=DECDPUN; cut-=DECDPUN, u--) *u=0;
  1.4524 +      } /* align  */
  1.4525 +     else { /* is DIVIDE  */
  1.4526 +      maxexponent=lhs->exponent-rhs->exponent;    /* save  */
  1.4527 +      /* optimization: if the first iteration will just produce 0,  */
  1.4528 +      /* preadjust to skip it [valid for DIVIDE only]  */
  1.4529 +      if (*msu1<*msu2) {
  1.4530 +        var2ulen--;                     /* shift down  */
  1.4531 +        exponent-=DECDPUN;              /* update the exponent  */
  1.4532 +        }
  1.4533 +      }
  1.4534 +
  1.4535 +    /* ---- start the long-division loops ------------------------------  */
  1.4536 +    accunits=0;                         /* no units accumulated yet  */
  1.4537 +    accdigits=0;                        /* .. or digits  */
  1.4538 +    accnext=acc+acclength-1;            /* -> msu of acc [NB: allows digits+1]  */
  1.4539 +    for (;;) {                          /* outer forever loop  */
  1.4540 +      thisunit=0;                       /* current unit assumed 0  */
  1.4541 +      /* find the next unit  */
  1.4542 +      for (;;) {                        /* inner forever loop  */
  1.4543 +        /* strip leading zero units [from either pre-adjust or from  */
  1.4544 +        /* subtract last time around].  Leave at least one unit.  */
  1.4545 +        for (; *msu1==0 && msu1>var1; msu1--) var1units--;
  1.4546 +
  1.4547 +        if (var1units<var2ulen) break;       /* var1 too low for subtract  */
  1.4548 +        if (var1units==var2ulen) {           /* unit-by-unit compare needed  */
  1.4549 +          /* compare the two numbers, from msu  */
  1.4550 +          const Unit *pv1, *pv2;
  1.4551 +          Unit v2;                           /* units to compare  */
  1.4552 +          pv2=msu2;                          /* -> msu  */
  1.4553 +          for (pv1=msu1; ; pv1--, pv2--) {
  1.4554 +            /* v1=*pv1 -- always OK  */
  1.4555 +            v2=0;                            /* assume in padding  */
  1.4556 +            if (pv2>=var2) v2=*pv2;          /* in range  */
  1.4557 +            if (*pv1!=v2) break;             /* no longer the same  */
  1.4558 +            if (pv1==var1) break;            /* done; leave pv1 as is  */
  1.4559 +            }
  1.4560 +          /* here when all inspected or a difference seen  */
  1.4561 +          if (*pv1<v2) break;                /* var1 too low to subtract  */
  1.4562 +          if (*pv1==v2) {                    /* var1 == var2  */
  1.4563 +            /* reach here if var1 and var2 are identical; subtraction  */
  1.4564 +            /* would increase digit by one, and the residue will be 0 so  */
  1.4565 +            /* the calculation is done; leave the loop with residue=0.  */
  1.4566 +            thisunit++;                      /* as though subtracted  */
  1.4567 +            *var1=0;                         /* set var1 to 0  */
  1.4568 +            var1units=1;                     /* ..  */
  1.4569 +            break;  /* from inner  */
  1.4570 +            } /* var1 == var2  */
  1.4571 +          /* *pv1>v2.  Prepare for real subtraction; the lengths are equal  */
  1.4572 +          /* Estimate the multiplier (there's always a msu1-1)...  */
  1.4573 +          /* Bring in two units of var2 to provide a good estimate.  */
  1.4574 +          mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2pair);
  1.4575 +          } /* lengths the same  */
  1.4576 +         else { /* var1units > var2ulen, so subtraction is safe  */
  1.4577 +          /* The var2 msu is one unit towards the lsu of the var1 msu,  */
  1.4578 +          /* so only one unit for var2 can be used.  */
  1.4579 +          mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2plus);
  1.4580 +          }
  1.4581 +        if (mult==0) mult=1;                 /* must always be at least 1  */
  1.4582 +        /* subtraction needed; var1 is > var2  */
  1.4583 +        thisunit=(Unit)(thisunit+mult);      /* accumulate  */
  1.4584 +        /* subtract var1-var2, into var1; only the overlap needs  */
  1.4585 +        /* processing, as this is an in-place calculation  */
  1.4586 +        shift=var2ulen-var2units;
  1.4587 +        #if DECTRACE
  1.4588 +          decDumpAr('1', &var1[shift], var1units-shift);
  1.4589 +          decDumpAr('2', var2, var2units);
  1.4590 +          printf("m=%ld\n", -mult);
  1.4591 +        #endif
  1.4592 +        decUnitAddSub(&var1[shift], var1units-shift,
  1.4593 +                      var2, var2units, 0,
  1.4594 +                      &var1[shift], -mult);
  1.4595 +        #if DECTRACE
  1.4596 +          decDumpAr('#', &var1[shift], var1units-shift);
  1.4597 +        #endif
  1.4598 +        /* var1 now probably has leading zeros; these are removed at the  */
  1.4599 +        /* top of the inner loop.  */
  1.4600 +        } /* inner loop  */
  1.4601 +
  1.4602 +      /* The next unit has been calculated in full; unless it's a  */
  1.4603 +      /* leading zero, add to acc  */
  1.4604 +      if (accunits!=0 || thisunit!=0) {      /* is first or non-zero  */
  1.4605 +        *accnext=thisunit;                   /* store in accumulator  */
  1.4606 +        /* account exactly for the new digits  */
  1.4607 +        if (accunits==0) {
  1.4608 +          accdigits++;                       /* at least one  */
  1.4609 +          for (pow=&powers[1]; thisunit>=*pow; pow++) accdigits++;
  1.4610 +          }
  1.4611 +         else accdigits+=DECDPUN;
  1.4612 +        accunits++;                          /* update count  */
  1.4613 +        accnext--;                           /* ready for next  */
  1.4614 +        if (accdigits>reqdigits) break;      /* have enough digits  */
  1.4615 +        }
  1.4616 +
  1.4617 +      /* if the residue is zero, the operation is done (unless divide  */
  1.4618 +      /* or divideInteger and still not enough digits yet)  */
  1.4619 +      if (*var1==0 && var1units==1) {        /* residue is 0  */
  1.4620 +        if (op&(REMAINDER|REMNEAR)) break;
  1.4621 +        if ((op&DIVIDE) && (exponent<=maxexponent)) break;
  1.4622 +        /* [drop through if divideInteger]  */
  1.4623 +        }
  1.4624 +      /* also done enough if calculating remainder or integer  */
  1.4625 +      /* divide and just did the last ('units') unit  */
  1.4626 +      if (exponent==0 && !(op&DIVIDE)) break;
  1.4627 +
  1.4628 +      /* to get here, var1 is less than var2, so divide var2 by the per-  */
  1.4629 +      /* Unit power of ten and go for the next digit  */
  1.4630 +      var2ulen--;                            /* shift down  */
  1.4631 +      exponent-=DECDPUN;                     /* update the exponent  */
  1.4632 +      } /* outer loop  */
  1.4633 +
  1.4634 +    /* ---- division is complete ---------------------------------------  */
  1.4635 +    /* here: acc      has at least reqdigits+1 of good results (or fewer  */
  1.4636 +    /*                if early stop), starting at accnext+1 (its lsu)  */
  1.4637 +    /*       var1     has any residue at the stopping point  */
  1.4638 +    /*       accunits is the number of digits collected in acc  */
  1.4639 +    if (accunits==0) {             /* acc is 0  */
  1.4640 +      accunits=1;                  /* show have a unit ..  */
  1.4641 +      accdigits=1;                 /* ..  */
  1.4642 +      *accnext=0;                  /* .. whose value is 0  */
  1.4643 +      }
  1.4644 +     else accnext++;               /* back to last placed  */
  1.4645 +    /* accnext now -> lowest unit of result  */
  1.4646 +
  1.4647 +    residue=0;                     /* assume no residue  */
  1.4648 +    if (op&DIVIDE) {
  1.4649 +      /* record the presence of any residue, for rounding  */
  1.4650 +      if (*var1!=0 || var1units>1) residue=1;
  1.4651 +       else { /* no residue  */
  1.4652 +        /* Had an exact division; clean up spurious trailing 0s.  */
  1.4653 +        /* There will be at most DECDPUN-1, from the final multiply,  */
  1.4654 +        /* and then only if the result is non-0 (and even) and the  */
  1.4655 +        /* exponent is 'loose'.  */
  1.4656 +        #if DECDPUN>1
  1.4657 +        Unit lsu=*accnext;
  1.4658 +        if (!(lsu&0x01) && (lsu!=0)) {
  1.4659 +          /* count the trailing zeros  */
  1.4660 +          Int drop=0;
  1.4661 +          for (;; drop++) {    /* [will terminate because lsu!=0]  */
  1.4662 +            if (exponent>=maxexponent) break;     /* don't chop real 0s  */
  1.4663 +            #if DECDPUN<=4
  1.4664 +              if ((lsu-QUOT10(lsu, drop+1)
  1.4665 +                  *powers[drop+1])!=0) break;     /* found non-0 digit  */
  1.4666 +            #else
  1.4667 +              if (lsu%powers[drop+1]!=0) break;   /* found non-0 digit  */
  1.4668 +            #endif
  1.4669 +            exponent++;
  1.4670 +            }
  1.4671 +          if (drop>0) {
  1.4672 +            accunits=decShiftToLeast(accnext, accunits, drop);
  1.4673 +            accdigits=decGetDigits(accnext, accunits);
  1.4674 +            accunits=D2U(accdigits);
  1.4675 +            /* [exponent was adjusted in the loop]  */
  1.4676 +            }
  1.4677 +          } /* neither odd nor 0  */
  1.4678 +        #endif
  1.4679 +        } /* exact divide  */
  1.4680 +      } /* divide  */
  1.4681 +     else /* op!=DIVIDE */ {
  1.4682 +      /* check for coefficient overflow  */
  1.4683 +      if (accdigits+exponent>reqdigits) {
  1.4684 +        *status|=DEC_Division_impossible;
  1.4685 +        break;
  1.4686 +        }
  1.4687 +      if (op & (REMAINDER|REMNEAR)) {
  1.4688 +        /* [Here, the exponent will be 0, because var1 was adjusted  */
  1.4689 +        /* appropriately.]  */
  1.4690 +        Int postshift;                       /* work  */
  1.4691 +        Flag wasodd=0;                       /* integer was odd  */
  1.4692 +        Unit *quotlsu;                       /* for save  */
  1.4693 +        Int  quotdigits;                     /* ..  */
  1.4694 +
  1.4695 +        bits=lhs->bits;                      /* remainder sign is always as lhs  */
  1.4696 +
  1.4697 +        /* Fastpath when residue is truly 0 is worthwhile [and  */
  1.4698 +        /* simplifies the code below]  */
  1.4699 +        if (*var1==0 && var1units==1) {      /* residue is 0  */
  1.4700 +          Int exp=lhs->exponent;             /* save min(exponents)  */
  1.4701 +          if (rhs->exponent<exp) exp=rhs->exponent;
  1.4702 +          uprv_decNumberZero(res);                /* 0 coefficient  */
  1.4703 +          #if DECSUBSET
  1.4704 +          if (set->extended)
  1.4705 +          #endif
  1.4706 +          res->exponent=exp;                 /* .. with proper exponent  */
  1.4707 +          res->bits=(uByte)(bits&DECNEG);          /* [cleaned]  */
  1.4708 +          decFinish(res, set, &residue, status);   /* might clamp  */
  1.4709 +          break;
  1.4710 +          }
  1.4711 +        /* note if the quotient was odd  */
  1.4712 +        if (*accnext & 0x01) wasodd=1;       /* acc is odd  */
  1.4713 +        quotlsu=accnext;                     /* save in case need to reinspect  */
  1.4714 +        quotdigits=accdigits;                /* ..  */
  1.4715 +
  1.4716 +        /* treat the residue, in var1, as the value to return, via acc  */
  1.4717 +        /* calculate the unused zero digits.  This is the smaller of:  */
  1.4718 +        /*   var1 initial padding (saved above)  */
  1.4719 +        /*   var2 residual padding, which happens to be given by:  */
  1.4720 +        postshift=var1initpad+exponent-lhs->exponent+rhs->exponent;
  1.4721 +        /* [the 'exponent' term accounts for the shifts during divide]  */
  1.4722 +        if (var1initpad<postshift) postshift=var1initpad;
  1.4723 +
  1.4724 +        /* shift var1 the requested amount, and adjust its digits  */
  1.4725 +        var1units=decShiftToLeast(var1, var1units, postshift);
  1.4726 +        accnext=var1;
  1.4727 +        accdigits=decGetDigits(var1, var1units);
  1.4728 +        accunits=D2U(accdigits);
  1.4729 +
  1.4730 +        exponent=lhs->exponent;         /* exponent is smaller of lhs & rhs  */
  1.4731 +        if (rhs->exponent<exponent) exponent=rhs->exponent;
  1.4732 +
  1.4733 +        /* Now correct the result if doing remainderNear; if it  */
  1.4734 +        /* (looking just at coefficients) is > rhs/2, or == rhs/2 and  */
  1.4735 +        /* the integer was odd then the result should be rem-rhs.  */
  1.4736 +        if (op&REMNEAR) {
  1.4737 +          Int compare, tarunits;        /* work  */
  1.4738 +          Unit *up;                     /* ..  */
  1.4739 +          /* calculate remainder*2 into the var1 buffer (which has  */
  1.4740 +          /* 'headroom' of an extra unit and hence enough space)  */
  1.4741 +          /* [a dedicated 'double' loop would be faster, here]  */
  1.4742 +          tarunits=decUnitAddSub(accnext, accunits, accnext, accunits,
  1.4743 +                                 0, accnext, 1);
  1.4744 +          /* decDumpAr('r', accnext, tarunits);  */
  1.4745 +
  1.4746 +          /* Here, accnext (var1) holds tarunits Units with twice the  */
  1.4747 +          /* remainder's coefficient, which must now be compared to the  */
  1.4748 +          /* RHS.  The remainder's exponent may be smaller than the RHS's.  */
  1.4749 +          compare=decUnitCompare(accnext, tarunits, rhs->lsu, D2U(rhs->digits),
  1.4750 +                                 rhs->exponent-exponent);
  1.4751 +          if (compare==BADINT) {             /* deep trouble  */
  1.4752 +            *status|=DEC_Insufficient_storage;
  1.4753 +            break;}
  1.4754 +
  1.4755 +          /* now restore the remainder by dividing by two; the lsu  */
  1.4756 +          /* is known to be even.  */
  1.4757 +          for (up=accnext; up<accnext+tarunits; up++) {
  1.4758 +            Int half;              /* half to add to lower unit  */
  1.4759 +            half=*up & 0x01;
  1.4760 +            *up/=2;                /* [shift]  */
  1.4761 +            if (!half) continue;
  1.4762 +            *(up-1)+=(DECDPUNMAX+1)/2;
  1.4763 +            }
  1.4764 +          /* [accunits still describes the original remainder length]  */
  1.4765 +
  1.4766 +          if (compare>0 || (compare==0 && wasodd)) { /* adjustment needed  */
  1.4767 +            Int exp, expunits, exprem;       /* work  */
  1.4768 +            /* This is effectively causing round-up of the quotient,  */
  1.4769 +            /* so if it was the rare case where it was full and all  */
  1.4770 +            /* nines, it would overflow and hence division-impossible  */
  1.4771 +            /* should be raised  */
  1.4772 +            Flag allnines=0;                 /* 1 if quotient all nines  */
  1.4773 +            if (quotdigits==reqdigits) {     /* could be borderline  */
  1.4774 +              for (up=quotlsu; ; up++) {
  1.4775 +                if (quotdigits>DECDPUN) {
  1.4776 +                  if (*up!=DECDPUNMAX) break;/* non-nines  */
  1.4777 +                  }
  1.4778 +                 else {                      /* this is the last Unit  */
  1.4779 +                  if (*up==powers[quotdigits]-1) allnines=1;
  1.4780 +                  break;
  1.4781 +                  }
  1.4782 +                quotdigits-=DECDPUN;         /* checked those digits  */
  1.4783 +                } /* up  */
  1.4784 +              } /* borderline check  */
  1.4785 +            if (allnines) {
  1.4786 +              *status|=DEC_Division_impossible;
  1.4787 +              break;}
  1.4788 +
  1.4789 +            /* rem-rhs is needed; the sign will invert.  Again, var1  */
  1.4790 +            /* can safely be used for the working Units array.  */
  1.4791 +            exp=rhs->exponent-exponent;      /* RHS padding needed  */
  1.4792 +            /* Calculate units and remainder from exponent.  */
  1.4793 +            expunits=exp/DECDPUN;
  1.4794 +            exprem=exp%DECDPUN;
  1.4795 +            /* subtract [A+B*(-m)]; the result will always be negative  */
  1.4796 +            accunits=-decUnitAddSub(accnext, accunits,
  1.4797 +                                    rhs->lsu, D2U(rhs->digits),
  1.4798 +                                    expunits, accnext, -(Int)powers[exprem]);
  1.4799 +            accdigits=decGetDigits(accnext, accunits); /* count digits exactly  */
  1.4800 +            accunits=D2U(accdigits);    /* and recalculate the units for copy  */
  1.4801 +            /* [exponent is as for original remainder]  */
  1.4802 +            bits^=DECNEG;               /* flip the sign  */
  1.4803 +            }
  1.4804 +          } /* REMNEAR  */
  1.4805 +        } /* REMAINDER or REMNEAR  */
  1.4806 +      } /* not DIVIDE  */
  1.4807 +
  1.4808 +    /* Set exponent and bits  */
  1.4809 +    res->exponent=exponent;
  1.4810 +    res->bits=(uByte)(bits&DECNEG);          /* [cleaned]  */
  1.4811 +
  1.4812 +    /* Now the coefficient.  */
  1.4813 +    decSetCoeff(res, set, accnext, accdigits, &residue, status);
  1.4814 +
  1.4815 +    decFinish(res, set, &residue, status);   /* final cleanup  */
  1.4816 +
  1.4817 +    #if DECSUBSET
  1.4818 +    /* If a divide then strip trailing zeros if subset [after round]  */
  1.4819 +    if (!set->extended && (op==DIVIDE)) decTrim(res, set, 0, 1, &dropped);
  1.4820 +    #endif
  1.4821 +    } while(0);                              /* end protected  */
  1.4822 +
  1.4823 +  if (varalloc!=NULL) free(varalloc);   /* drop any storage used  */
  1.4824 +  if (allocacc!=NULL) free(allocacc);   /* ..  */
  1.4825 +  #if DECSUBSET
  1.4826 +  if (allocrhs!=NULL) free(allocrhs);   /* ..  */
  1.4827 +  if (alloclhs!=NULL) free(alloclhs);   /* ..  */
  1.4828 +  #endif
  1.4829 +  return res;
  1.4830 +  } /* decDivideOp  */
  1.4831 +
  1.4832 +/* ------------------------------------------------------------------ */
  1.4833 +/* decMultiplyOp -- multiplication operation                          */
  1.4834 +/*                                                                    */
  1.4835 +/*  This routine performs the multiplication C=A x B.                 */
  1.4836 +/*                                                                    */
  1.4837 +/*   res is C, the result.  C may be A and/or B (e.g., X=X*X)         */
  1.4838 +/*   lhs is A                                                         */
  1.4839 +/*   rhs is B                                                         */
  1.4840 +/*   set is the context                                               */
  1.4841 +/*   status is the usual accumulator                                  */
  1.4842 +/*                                                                    */
  1.4843 +/* C must have space for set->digits digits.                          */
  1.4844 +/*                                                                    */
  1.4845 +/* ------------------------------------------------------------------ */
  1.4846 +/* 'Classic' multiplication is used rather than Karatsuba, as the     */
  1.4847 +/* latter would give only a minor improvement for the short numbers   */
  1.4848 +/* expected to be handled most (and uses much more memory).           */
  1.4849 +/*                                                                    */
  1.4850 +/* There are two major paths here: the general-purpose ('old code')   */
  1.4851 +/* path which handles all DECDPUN values, and a fastpath version      */
  1.4852 +/* which is used if 64-bit ints are available, DECDPUN<=4, and more   */
  1.4853 +/* than two calls to decUnitAddSub would be made.                     */
  1.4854 +/*                                                                    */
  1.4855 +/* The fastpath version lumps units together into 8-digit or 9-digit  */
  1.4856 +/* chunks, and also uses a lazy carry strategy to minimise expensive  */
  1.4857 +/* 64-bit divisions.  The chunks are then broken apart again into     */
  1.4858 +/* units for continuing processing.  Despite this overhead, the       */
  1.4859 +/* fastpath can speed up some 16-digit operations by 10x (and much    */
  1.4860 +/* more for higher-precision calculations).                           */
  1.4861 +/*                                                                    */
  1.4862 +/* A buffer always has to be used for the accumulator; in the         */
  1.4863 +/* fastpath, buffers are also always needed for the chunked copies of */
  1.4864 +/* of the operand coefficients.                                       */
  1.4865 +/* Static buffers are larger than needed just for multiply, to allow  */
  1.4866 +/* for calls from other operations (notably exp).                     */
  1.4867 +/* ------------------------------------------------------------------ */
  1.4868 +#define FASTMUL (DECUSE64 && DECDPUN<5)
  1.4869 +static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs,
  1.4870 +                                 const decNumber *rhs, decContext *set,
  1.4871 +                                 uInt *status) {
  1.4872 +  Int    accunits;                 /* Units of accumulator in use  */
  1.4873 +  Int    exponent;                 /* work  */
  1.4874 +  Int    residue=0;                /* rounding residue  */
  1.4875 +  uByte  bits;                     /* result sign  */
  1.4876 +  Unit  *acc;                      /* -> accumulator Unit array  */
  1.4877 +  Int    needbytes;                /* size calculator  */
  1.4878 +  void  *allocacc=NULL;            /* -> allocated accumulator, iff allocated  */
  1.4879 +  Unit  accbuff[SD2U(DECBUFFER*4+1)]; /* buffer (+1 for DECBUFFER==0,  */
  1.4880 +                                   /* *4 for calls from other operations)  */
  1.4881 +  const Unit *mer, *mermsup;       /* work  */
  1.4882 +  Int   madlength;                 /* Units in multiplicand  */
  1.4883 +  Int   shift;                     /* Units to shift multiplicand by  */
  1.4884 +
  1.4885 +  #if FASTMUL
  1.4886 +    /* if DECDPUN is 1 or 3 work in base 10**9, otherwise  */
  1.4887 +    /* (DECDPUN is 2 or 4) then work in base 10**8  */
  1.4888 +    #if DECDPUN & 1                /* odd  */
  1.4889 +      #define FASTBASE 1000000000  /* base  */
  1.4890 +      #define FASTDIGS          9  /* digits in base  */
  1.4891 +      #define FASTLAZY         18  /* carry resolution point [1->18]  */
  1.4892 +    #else
  1.4893 +      #define FASTBASE  100000000
  1.4894 +      #define FASTDIGS          8
  1.4895 +      #define FASTLAZY       1844  /* carry resolution point [1->1844]  */
  1.4896 +    #endif
  1.4897 +    /* three buffers are used, two for chunked copies of the operands  */
  1.4898 +    /* (base 10**8 or base 10**9) and one base 2**64 accumulator with  */
  1.4899 +    /* lazy carry evaluation  */
  1.4900 +    uInt   zlhibuff[(DECBUFFER*2+1)/8+1]; /* buffer (+1 for DECBUFFER==0)  */
  1.4901 +    uInt  *zlhi=zlhibuff;                 /* -> lhs array  */
  1.4902 +    uInt  *alloclhi=NULL;                 /* -> allocated buffer, iff allocated  */
  1.4903 +    uInt   zrhibuff[(DECBUFFER*2+1)/8+1]; /* buffer (+1 for DECBUFFER==0)  */
  1.4904 +    uInt  *zrhi=zrhibuff;                 /* -> rhs array  */
  1.4905 +    uInt  *allocrhi=NULL;                 /* -> allocated buffer, iff allocated  */
  1.4906 +    uLong  zaccbuff[(DECBUFFER*2+1)/4+2]; /* buffer (+1 for DECBUFFER==0)  */
  1.4907 +    /* [allocacc is shared for both paths, as only one will run]  */
  1.4908 +    uLong *zacc=zaccbuff;          /* -> accumulator array for exact result  */
  1.4909 +    #if DECDPUN==1
  1.4910 +    Int    zoff;                   /* accumulator offset  */
  1.4911 +    #endif
  1.4912 +    uInt  *lip, *rip;              /* item pointers  */
  1.4913 +    uInt  *lmsi, *rmsi;            /* most significant items  */
  1.4914 +    Int    ilhs, irhs, iacc;       /* item counts in the arrays  */
  1.4915 +    Int    lazy;                   /* lazy carry counter  */
  1.4916 +    uLong  lcarry;                 /* uLong carry  */
  1.4917 +    uInt   carry;                  /* carry (NB not uLong)  */
  1.4918 +    Int    count;                  /* work  */
  1.4919 +    const  Unit *cup;              /* ..  */
  1.4920 +    Unit  *up;                     /* ..  */
  1.4921 +    uLong *lp;                     /* ..  */
  1.4922 +    Int    p;                      /* ..  */
  1.4923 +  #endif
  1.4924 +
  1.4925 +  #if DECSUBSET
  1.4926 +    decNumber *alloclhs=NULL;      /* -> allocated buffer, iff allocated  */
  1.4927 +    decNumber *allocrhs=NULL;      /* -> allocated buffer, iff allocated  */
  1.4928 +  #endif
  1.4929 +
  1.4930 +  #if DECCHECK
  1.4931 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
  1.4932 +  #endif
  1.4933 +
  1.4934 +  /* precalculate result sign  */
  1.4935 +  bits=(uByte)((lhs->bits^rhs->bits)&DECNEG);
  1.4936 +
  1.4937 +  /* handle infinities and NaNs  */
  1.4938 +  if (SPECIALARGS) {               /* a special bit set  */
  1.4939 +    if (SPECIALARGS & (DECSNAN | DECNAN)) { /* one or two NaNs  */
  1.4940 +      decNaNs(res, lhs, rhs, set, status);
  1.4941 +      return res;}
  1.4942 +    /* one or two infinities; Infinity * 0 is invalid  */
  1.4943 +    if (((lhs->bits & DECINF)==0 && ISZERO(lhs))
  1.4944 +      ||((rhs->bits & DECINF)==0 && ISZERO(rhs))) {
  1.4945 +      *status|=DEC_Invalid_operation;
  1.4946 +      return res;}
  1.4947 +    uprv_decNumberZero(res);
  1.4948 +    res->bits=bits|DECINF;         /* infinity  */
  1.4949 +    return res;}
  1.4950 +
  1.4951 +  /* For best speed, as in DMSRCN [the original Rexx numerics  */
  1.4952 +  /* module], use the shorter number as the multiplier (rhs) and  */
  1.4953 +  /* the longer as the multiplicand (lhs) to minimise the number of  */
  1.4954 +  /* adds (partial products)  */
  1.4955 +  if (lhs->digits<rhs->digits) {   /* swap...  */
  1.4956 +    const decNumber *hold=lhs;
  1.4957 +    lhs=rhs;
  1.4958 +    rhs=hold;
  1.4959 +    }
  1.4960 +
  1.4961 +  do {                             /* protect allocated storage  */
  1.4962 +    #if DECSUBSET
  1.4963 +    if (!set->extended) {
  1.4964 +      /* reduce operands and set lostDigits status, as needed  */
  1.4965 +      if (lhs->digits>set->digits) {
  1.4966 +        alloclhs=decRoundOperand(lhs, set, status);
  1.4967 +        if (alloclhs==NULL) break;
  1.4968 +        lhs=alloclhs;
  1.4969 +        }
  1.4970 +      if (rhs->digits>set->digits) {
  1.4971 +        allocrhs=decRoundOperand(rhs, set, status);
  1.4972 +        if (allocrhs==NULL) break;
  1.4973 +        rhs=allocrhs;
  1.4974 +        }
  1.4975 +      }
  1.4976 +    #endif
  1.4977 +    /* [following code does not require input rounding]  */
  1.4978 +
  1.4979 +    #if FASTMUL                    /* fastpath can be used  */
  1.4980 +    /* use the fast path if there are enough digits in the shorter  */
  1.4981 +    /* operand to make the setup and takedown worthwhile  */
  1.4982 +    #define NEEDTWO (DECDPUN*2)    /* within two decUnitAddSub calls  */
  1.4983 +    if (rhs->digits>NEEDTWO) {     /* use fastpath...  */
  1.4984 +      /* calculate the number of elements in each array  */
  1.4985 +      ilhs=(lhs->digits+FASTDIGS-1)/FASTDIGS; /* [ceiling]  */
  1.4986 +      irhs=(rhs->digits+FASTDIGS-1)/FASTDIGS; /* ..  */
  1.4987 +      iacc=ilhs+irhs;
  1.4988 +
  1.4989 +      /* allocate buffers if required, as usual  */
  1.4990 +      needbytes=ilhs*sizeof(uInt);
  1.4991 +      if (needbytes>(Int)sizeof(zlhibuff)) {
  1.4992 +        alloclhi=(uInt *)malloc(needbytes);
  1.4993 +        zlhi=alloclhi;}
  1.4994 +      needbytes=irhs*sizeof(uInt);
  1.4995 +      if (needbytes>(Int)sizeof(zrhibuff)) {
  1.4996 +        allocrhi=(uInt *)malloc(needbytes);
  1.4997 +        zrhi=allocrhi;}
  1.4998 +
  1.4999 +      /* Allocating the accumulator space needs a special case when  */
  1.5000 +      /* DECDPUN=1 because when converting the accumulator to Units  */
  1.5001 +      /* after the multiplication each 8-byte item becomes 9 1-byte  */
  1.5002 +      /* units.  Therefore iacc extra bytes are needed at the front  */
  1.5003 +      /* (rounded up to a multiple of 8 bytes), and the uLong  */
  1.5004 +      /* accumulator starts offset the appropriate number of units  */
  1.5005 +      /* to the right to avoid overwrite during the unchunking.  */
  1.5006 +
  1.5007 +      /* Make sure no signed int overflow below. This is always true */
  1.5008 +      /* if the given numbers have less digits than DEC_MAX_DIGITS. */
  1.5009 +      U_ASSERT(iacc <= INT32_MAX/sizeof(uLong));
  1.5010 +      needbytes=iacc*sizeof(uLong);
  1.5011 +      #if DECDPUN==1
  1.5012 +      zoff=(iacc+7)/8;        /* items to offset by  */
  1.5013 +      needbytes+=zoff*8;
  1.5014 +      #endif
  1.5015 +      if (needbytes>(Int)sizeof(zaccbuff)) {
  1.5016 +        allocacc=(uLong *)malloc(needbytes);
  1.5017 +        zacc=(uLong *)allocacc;}
  1.5018 +      if (zlhi==NULL||zrhi==NULL||zacc==NULL) {
  1.5019 +        *status|=DEC_Insufficient_storage;
  1.5020 +        break;}
  1.5021 +
  1.5022 +      acc=(Unit *)zacc;       /* -> target Unit array  */
  1.5023 +      #if DECDPUN==1
  1.5024 +      zacc+=zoff;             /* start uLong accumulator to right  */
  1.5025 +      #endif
  1.5026 +
  1.5027 +      /* assemble the chunked copies of the left and right sides  */
  1.5028 +      for (count=lhs->digits, cup=lhs->lsu, lip=zlhi; count>0; lip++)
  1.5029 +        for (p=0, *lip=0; p<FASTDIGS && count>0;
  1.5030 +             p+=DECDPUN, cup++, count-=DECDPUN)
  1.5031 +          *lip+=*cup*powers[p];
  1.5032 +      lmsi=lip-1;     /* save -> msi  */
  1.5033 +      for (count=rhs->digits, cup=rhs->lsu, rip=zrhi; count>0; rip++)
  1.5034 +        for (p=0, *rip=0; p<FASTDIGS && count>0;
  1.5035 +             p+=DECDPUN, cup++, count-=DECDPUN)
  1.5036 +          *rip+=*cup*powers[p];
  1.5037 +      rmsi=rip-1;     /* save -> msi  */
  1.5038 +
  1.5039 +      /* zero the accumulator  */
  1.5040 +      for (lp=zacc; lp<zacc+iacc; lp++) *lp=0;
  1.5041 +
  1.5042 +      /* Start the multiplication */
  1.5043 +      /* Resolving carries can dominate the cost of accumulating the  */
  1.5044 +      /* partial products, so this is only done when necessary.  */
  1.5045 +      /* Each uLong item in the accumulator can hold values up to  */
  1.5046 +      /* 2**64-1, and each partial product can be as large as  */
  1.5047 +      /* (10**FASTDIGS-1)**2.  When FASTDIGS=9, this can be added to  */
  1.5048 +      /* itself 18.4 times in a uLong without overflowing, so during  */
  1.5049 +      /* the main calculation resolution is carried out every 18th  */
  1.5050 +      /* add -- every 162 digits.  Similarly, when FASTDIGS=8, the  */
  1.5051 +      /* partial products can be added to themselves 1844.6 times in  */
  1.5052 +      /* a uLong without overflowing, so intermediate carry  */
  1.5053 +      /* resolution occurs only every 14752 digits.  Hence for common  */
  1.5054 +      /* short numbers usually only the one final carry resolution  */
  1.5055 +      /* occurs.  */
  1.5056 +      /* (The count is set via FASTLAZY to simplify experiments to  */
  1.5057 +      /* measure the value of this approach: a 35% improvement on a  */
  1.5058 +      /* [34x34] multiply.)  */
  1.5059 +      lazy=FASTLAZY;                         /* carry delay count  */
  1.5060 +      for (rip=zrhi; rip<=rmsi; rip++) {     /* over each item in rhs  */
  1.5061 +        lp=zacc+(rip-zrhi);                  /* where to add the lhs  */
  1.5062 +        for (lip=zlhi; lip<=lmsi; lip++, lp++) { /* over each item in lhs  */
  1.5063 +          *lp+=(uLong)(*lip)*(*rip);         /* [this should in-line]  */
  1.5064 +          } /* lip loop  */
  1.5065 +        lazy--;
  1.5066 +        if (lazy>0 && rip!=rmsi) continue;
  1.5067 +        lazy=FASTLAZY;                       /* reset delay count  */
  1.5068 +        /* spin up the accumulator resolving overflows  */
  1.5069 +        for (lp=zacc; lp<zacc+iacc; lp++) {
  1.5070 +          if (*lp<FASTBASE) continue;        /* it fits  */
  1.5071 +          lcarry=*lp/FASTBASE;               /* top part [slow divide]  */
  1.5072 +          /* lcarry can exceed 2**32-1, so check again; this check  */
  1.5073 +          /* and occasional extra divide (slow) is well worth it, as  */
  1.5074 +          /* it allows FASTLAZY to be increased to 18 rather than 4  */
  1.5075 +          /* in the FASTDIGS=9 case  */
  1.5076 +          if (lcarry<FASTBASE) carry=(uInt)lcarry;  /* [usual]  */
  1.5077 +           else { /* two-place carry [fairly rare]  */
  1.5078 +            uInt carry2=(uInt)(lcarry/FASTBASE);    /* top top part  */
  1.5079 +            *(lp+2)+=carry2;                        /* add to item+2  */
  1.5080 +            *lp-=((uLong)FASTBASE*FASTBASE*carry2); /* [slow]  */
  1.5081 +            carry=(uInt)(lcarry-((uLong)FASTBASE*carry2)); /* [inline]  */
  1.5082 +            }
  1.5083 +          *(lp+1)+=carry;                    /* add to item above [inline]  */
  1.5084 +          *lp-=((uLong)FASTBASE*carry);      /* [inline]  */
  1.5085 +          } /* carry resolution  */
  1.5086 +        } /* rip loop  */
  1.5087 +
  1.5088 +      /* The multiplication is complete; time to convert back into  */
  1.5089 +      /* units.  This can be done in-place in the accumulator and in  */
  1.5090 +      /* 32-bit operations, because carries were resolved after the  */
  1.5091 +      /* final add.  This needs N-1 divides and multiplies for  */
  1.5092 +      /* each item in the accumulator (which will become up to N  */
  1.5093 +      /* units, where 2<=N<=9).  */
  1.5094 +      for (lp=zacc, up=acc; lp<zacc+iacc; lp++) {
  1.5095 +        uInt item=(uInt)*lp;                 /* decapitate to uInt  */
  1.5096 +        for (p=0; p<FASTDIGS-DECDPUN; p+=DECDPUN, up++) {
  1.5097 +          uInt part=item/(DECDPUNMAX+1);
  1.5098 +          *up=(Unit)(item-(part*(DECDPUNMAX+1)));
  1.5099 +          item=part;
  1.5100 +          } /* p  */
  1.5101 +        *up=(Unit)item; up++;                /* [final needs no division]  */
  1.5102 +        } /* lp  */
  1.5103 +      accunits=up-acc;                       /* count of units  */
  1.5104 +      }
  1.5105 +     else { /* here to use units directly, without chunking ['old code']  */
  1.5106 +    #endif
  1.5107 +
  1.5108 +      /* if accumulator will be too long for local storage, then allocate  */
  1.5109 +      acc=accbuff;                 /* -> assume buffer for accumulator  */
  1.5110 +      needbytes=(D2U(lhs->digits)+D2U(rhs->digits))*sizeof(Unit);
  1.5111 +      if (needbytes>(Int)sizeof(accbuff)) {
  1.5112 +        allocacc=(Unit *)malloc(needbytes);
  1.5113 +        if (allocacc==NULL) {*status|=DEC_Insufficient_storage; break;}
  1.5114 +        acc=(Unit *)allocacc;                /* use the allocated space  */
  1.5115 +        }
  1.5116 +
  1.5117 +      /* Now the main long multiplication loop */
  1.5118 +      /* Unlike the equivalent in the IBM Java implementation, there  */
  1.5119 +      /* is no advantage in calculating from msu to lsu.  So, do it  */
  1.5120 +      /* by the book, as it were.  */
  1.5121 +      /* Each iteration calculates ACC=ACC+MULTAND*MULT  */
  1.5122 +      accunits=1;                  /* accumulator starts at '0'  */
  1.5123 +      *acc=0;                      /* .. (lsu=0)  */
  1.5124 +      shift=0;                     /* no multiplicand shift at first  */
  1.5125 +      madlength=D2U(lhs->digits);  /* this won't change  */
  1.5126 +      mermsup=rhs->lsu+D2U(rhs->digits); /* -> msu+1 of multiplier  */
  1.5127 +
  1.5128 +      for (mer=rhs->lsu; mer<mermsup; mer++) {
  1.5129 +        /* Here, *mer is the next Unit in the multiplier to use  */
  1.5130 +        /* If non-zero [optimization] add it...  */
  1.5131 +        if (*mer!=0) accunits=decUnitAddSub(&acc[shift], accunits-shift,
  1.5132 +                                            lhs->lsu, madlength, 0,
  1.5133 +                                            &acc[shift], *mer)
  1.5134 +                                            + shift;
  1.5135 +         else { /* extend acc with a 0; it will be used shortly  */
  1.5136 +          *(acc+accunits)=0;       /* [this avoids length of <=0 later]  */
  1.5137 +          accunits++;
  1.5138 +          }
  1.5139 +        /* multiply multiplicand by 10**DECDPUN for next Unit to left  */
  1.5140 +        shift++;                   /* add this for 'logical length'  */
  1.5141 +        } /* n  */
  1.5142 +    #if FASTMUL
  1.5143 +      } /* unchunked units  */
  1.5144 +    #endif
  1.5145 +    /* common end-path  */
  1.5146 +    #if DECTRACE
  1.5147 +      decDumpAr('*', acc, accunits);         /* Show exact result  */
  1.5148 +    #endif
  1.5149 +
  1.5150 +    /* acc now contains the exact result of the multiplication,  */
  1.5151 +    /* possibly with a leading zero unit; build the decNumber from  */
  1.5152 +    /* it, noting if any residue  */
  1.5153 +    res->bits=bits;                          /* set sign  */
  1.5154 +    res->digits=decGetDigits(acc, accunits); /* count digits exactly  */
  1.5155 +
  1.5156 +    /* There can be a 31-bit wrap in calculating the exponent.  */
  1.5157 +    /* This can only happen if both input exponents are negative and  */
  1.5158 +    /* both their magnitudes are large.  If there was a wrap, set a  */
  1.5159 +    /* safe very negative exponent, from which decFinalize() will  */
  1.5160 +    /* raise a hard underflow shortly.  */
  1.5161 +    exponent=lhs->exponent+rhs->exponent;    /* calculate exponent  */
  1.5162 +    if (lhs->exponent<0 && rhs->exponent<0 && exponent>0)
  1.5163 +      exponent=-2*DECNUMMAXE;                /* force underflow  */
  1.5164 +    res->exponent=exponent;                  /* OK to overwrite now  */
  1.5165 +
  1.5166 +
  1.5167 +    /* Set the coefficient.  If any rounding, residue records  */
  1.5168 +    decSetCoeff(res, set, acc, res->digits, &residue, status);
  1.5169 +    decFinish(res, set, &residue, status);   /* final cleanup  */
  1.5170 +    } while(0);                         /* end protected  */
  1.5171 +
  1.5172 +  if (allocacc!=NULL) free(allocacc);   /* drop any storage used  */
  1.5173 +  #if DECSUBSET
  1.5174 +  if (allocrhs!=NULL) free(allocrhs);   /* ..  */
  1.5175 +  if (alloclhs!=NULL) free(alloclhs);   /* ..  */
  1.5176 +  #endif
  1.5177 +  #if FASTMUL
  1.5178 +  if (allocrhi!=NULL) free(allocrhi);   /* ..  */
  1.5179 +  if (alloclhi!=NULL) free(alloclhi);   /* ..  */
  1.5180 +  #endif
  1.5181 +  return res;
  1.5182 +  } /* decMultiplyOp  */
  1.5183 +
  1.5184 +/* ------------------------------------------------------------------ */
  1.5185 +/* decExpOp -- effect exponentiation                                  */
  1.5186 +/*                                                                    */
  1.5187 +/*   This computes C = exp(A)                                         */
  1.5188 +/*                                                                    */
  1.5189 +/*   res is C, the result.  C may be A                                */
  1.5190 +/*   rhs is A                                                         */
  1.5191 +/*   set is the context; note that rounding mode has no effect        */
  1.5192 +/*                                                                    */
  1.5193 +/* C must have space for set->digits digits. status is updated but    */
  1.5194 +/* not set.                                                           */
  1.5195 +/*                                                                    */
  1.5196 +/* Restrictions:                                                      */
  1.5197 +/*                                                                    */
  1.5198 +/*   digits, emax, and -emin in the context must be less than         */
  1.5199 +/*   2*DEC_MAX_MATH (1999998), and the rhs must be within these       */
  1.5200 +/*   bounds or a zero.  This is an internal routine, so these         */
  1.5201 +/*   restrictions are contractual and not enforced.                   */
  1.5202 +/*                                                                    */
  1.5203 +/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will      */
  1.5204 +/* almost always be correctly rounded, but may be up to 1 ulp in      */
  1.5205 +/* error in rare cases.                                               */
  1.5206 +/*                                                                    */
  1.5207 +/* Finite results will always be full precision and Inexact, except   */
  1.5208 +/* when A is a zero or -Infinity (giving 1 or 0 respectively).        */
  1.5209 +/* ------------------------------------------------------------------ */
  1.5210 +/* This approach used here is similar to the algorithm described in   */
  1.5211 +/*                                                                    */
  1.5212 +/*   Variable Precision Exponential Function, T. E. Hull and          */
  1.5213 +/*   A. Abrham, ACM Transactions on Mathematical Software, Vol 12 #2, */
  1.5214 +/*   pp79-91, ACM, June 1986.                                         */
  1.5215 +/*                                                                    */
  1.5216 +/* with the main difference being that the iterations in the series   */
  1.5217 +/* evaluation are terminated dynamically (which does not require the  */
  1.5218 +/* extra variable-precision variables which are expensive in this     */
  1.5219 +/* context).                                                          */
  1.5220 +/*                                                                    */
  1.5221 +/* The error analysis in Hull & Abrham's paper applies except for the */
  1.5222 +/* round-off error accumulation during the series evaluation.  This   */
  1.5223 +/* code does not precalculate the number of iterations and so cannot  */
  1.5224 +/* use Horner's scheme.  Instead, the accumulation is done at double- */
  1.5225 +/* precision, which ensures that the additions of the terms are exact */
  1.5226 +/* and do not accumulate round-off (and any round-off errors in the   */
  1.5227 +/* terms themselves move 'to the right' faster than they can          */
  1.5228 +/* accumulate).  This code also extends the calculation by allowing,  */
  1.5229 +/* in the spirit of other decNumber operators, the input to be more   */
  1.5230 +/* precise than the result (the precision used is based on the more   */
  1.5231 +/* precise of the input or requested result).                         */
  1.5232 +/*                                                                    */
  1.5233 +/* Implementation notes:                                              */
  1.5234 +/*                                                                    */
  1.5235 +/* 1. This is separated out as decExpOp so it can be called from      */
  1.5236 +/*    other Mathematical functions (notably Ln) with a wider range    */
  1.5237 +/*    than normal.  In particular, it can handle the slightly wider   */
  1.5238 +/*    (double) range needed by Ln (which has to be able to calculate  */
  1.5239 +/*    exp(-x) where x can be the tiniest number (Ntiny).              */
  1.5240 +/*                                                                    */
  1.5241 +/* 2. Normalizing x to be <=0.1 (instead of <=1) reduces loop         */
  1.5242 +/*    iterations by appoximately a third with additional (although    */
  1.5243 +/*    diminishing) returns as the range is reduced to even smaller    */
  1.5244 +/*    fractions.  However, h (the power of 10 used to correct the     */
  1.5245 +/*    result at the end, see below) must be kept <=8 as otherwise     */
  1.5246 +/*    the final result cannot be computed.  Hence the leverage is a   */
  1.5247 +/*    sliding value (8-h), where potentially the range is reduced     */
  1.5248 +/*    more for smaller values.                                        */
  1.5249 +/*                                                                    */
  1.5250 +/*    The leverage that can be applied in this way is severely        */
  1.5251 +/*    limited by the cost of the raise-to-the power at the end,       */
  1.5252 +/*    which dominates when the number of iterations is small (less    */
  1.5253 +/*    than ten) or when rhs is short.  As an example, the adjustment  */
  1.5254 +/*    x**10,000,000 needs 31 multiplications, all but one full-width. */
  1.5255 +/*                                                                    */
  1.5256 +/* 3. The restrictions (especially precision) could be raised with    */
  1.5257 +/*    care, but the full decNumber range seems very hard within the   */
  1.5258 +/*    32-bit limits.                                                  */
  1.5259 +/*                                                                    */
  1.5260 +/* 4. The working precisions for the static buffers are twice the     */
  1.5261 +/*    obvious size to allow for calls from decNumberPower.            */
  1.5262 +/* ------------------------------------------------------------------ */
  1.5263 +decNumber * decExpOp(decNumber *res, const decNumber *rhs,
  1.5264 +                         decContext *set, uInt *status) {
  1.5265 +  uInt ignore=0;                   /* working status  */
  1.5266 +  Int h;                           /* adjusted exponent for 0.xxxx  */
  1.5267 +  Int p;                           /* working precision  */
  1.5268 +  Int residue;                     /* rounding residue  */
  1.5269 +  uInt needbytes;                  /* for space calculations  */
  1.5270 +  const decNumber *x=rhs;          /* (may point to safe copy later)  */
  1.5271 +  decContext aset, tset, dset;     /* working contexts  */
  1.5272 +  Int comp;                        /* work  */
  1.5273 +
  1.5274 +  /* the argument is often copied to normalize it, so (unusually) it  */
  1.5275 +  /* is treated like other buffers, using DECBUFFER, +1 in case  */
  1.5276 +  /* DECBUFFER is 0  */
  1.5277 +  decNumber bufr[D2N(DECBUFFER*2+1)];
  1.5278 +  decNumber *allocrhs=NULL;        /* non-NULL if rhs buffer allocated  */
  1.5279 +
  1.5280 +  /* the working precision will be no more than set->digits+8+1  */
  1.5281 +  /* so for on-stack buffers DECBUFFER+9 is used, +1 in case DECBUFFER  */
  1.5282 +  /* is 0 (and twice that for the accumulator)  */
  1.5283 +
  1.5284 +  /* buffer for t, term (working precision plus)  */
  1.5285 +  decNumber buft[D2N(DECBUFFER*2+9+1)];
  1.5286 +  decNumber *allocbuft=NULL;       /* -> allocated buft, iff allocated  */
  1.5287 +  decNumber *t=buft;               /* term  */
  1.5288 +  /* buffer for a, accumulator (working precision * 2), at least 9  */
  1.5289 +  decNumber bufa[D2N(DECBUFFER*4+18+1)];
  1.5290 +  decNumber *allocbufa=NULL;       /* -> allocated bufa, iff allocated  */
  1.5291 +  decNumber *a=bufa;               /* accumulator  */
  1.5292 +  /* decNumber for the divisor term; this needs at most 9 digits  */
  1.5293 +  /* and so can be fixed size [16 so can use standard context]  */
  1.5294 +  decNumber bufd[D2N(16)];
  1.5295 +  decNumber *d=bufd;               /* divisor  */
  1.5296 +  decNumber numone;                /* constant 1  */
  1.5297 +
  1.5298 +  #if DECCHECK
  1.5299 +  Int iterations=0;                /* for later sanity check  */
  1.5300 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  1.5301 +  #endif
  1.5302 +
  1.5303 +  do {                                  /* protect allocated storage  */
  1.5304 +    if (SPECIALARG) {                   /* handle infinities and NaNs  */
  1.5305 +      if (decNumberIsInfinite(rhs)) {   /* an infinity  */
  1.5306 +        if (decNumberIsNegative(rhs))   /* -Infinity -> +0  */
  1.5307 +          uprv_decNumberZero(res);
  1.5308 +         else uprv_decNumberCopy(res, rhs);  /* +Infinity -> self  */
  1.5309 +        }
  1.5310 +       else decNaNs(res, rhs, NULL, set, status); /* a NaN  */
  1.5311 +      break;}
  1.5312 +
  1.5313 +    if (ISZERO(rhs)) {                  /* zeros -> exact 1  */
  1.5314 +      uprv_decNumberZero(res);               /* make clean 1  */
  1.5315 +      *res->lsu=1;                      /* ..  */
  1.5316 +      break;}                           /* [no status to set]  */
  1.5317 +
  1.5318 +    /* e**x when 0 < x < 0.66 is < 1+3x/2, hence can fast-path  */
  1.5319 +    /* positive and negative tiny cases which will result in inexact  */
  1.5320 +    /* 1.  This also allows the later add-accumulate to always be  */
  1.5321 +    /* exact (because its length will never be more than twice the  */
  1.5322 +    /* working precision).  */
  1.5323 +    /* The comparator (tiny) needs just one digit, so use the  */
  1.5324 +    /* decNumber d for it (reused as the divisor, etc., below); its  */
  1.5325 +    /* exponent is such that if x is positive it will have  */
  1.5326 +    /* set->digits-1 zeros between the decimal point and the digit,  */
  1.5327 +    /* which is 4, and if x is negative one more zero there as the  */
  1.5328 +    /* more precise result will be of the form 0.9999999 rather than  */
  1.5329 +    /* 1.0000001.  Hence, tiny will be 0.0000004  if digits=7 and x>0  */
  1.5330 +    /* or 0.00000004 if digits=7 and x<0.  If RHS not larger than  */
  1.5331 +    /* this then the result will be 1.000000  */
  1.5332 +    uprv_decNumberZero(d);                   /* clean  */
  1.5333 +    *d->lsu=4;                          /* set 4 ..  */
  1.5334 +    d->exponent=-set->digits;           /* * 10**(-d)  */
  1.5335 +    if (decNumberIsNegative(rhs)) d->exponent--;  /* negative case  */
  1.5336 +    comp=decCompare(d, rhs, 1);         /* signless compare  */
  1.5337 +    if (comp==BADINT) {
  1.5338 +      *status|=DEC_Insufficient_storage;
  1.5339 +      break;}
  1.5340 +    if (comp>=0) {                      /* rhs < d  */
  1.5341 +      Int shift=set->digits-1;
  1.5342 +      uprv_decNumberZero(res);               /* set 1  */
  1.5343 +      *res->lsu=1;                      /* ..  */
  1.5344 +      res->digits=decShiftToMost(res->lsu, 1, shift);
  1.5345 +      res->exponent=-shift;                  /* make 1.0000...  */
  1.5346 +      *status|=DEC_Inexact | DEC_Rounded;    /* .. inexactly  */
  1.5347 +      break;} /* tiny  */
  1.5348 +
  1.5349 +    /* set up the context to be used for calculating a, as this is  */
  1.5350 +    /* used on both paths below  */
  1.5351 +    uprv_decContextDefault(&aset, DEC_INIT_DECIMAL64);
  1.5352 +    /* accumulator bounds are as requested (could underflow)  */
  1.5353 +    aset.emax=set->emax;                /* usual bounds  */
  1.5354 +    aset.emin=set->emin;                /* ..  */
  1.5355 +    aset.clamp=0;                       /* and no concrete format  */
  1.5356 +
  1.5357 +    /* calculate the adjusted (Hull & Abrham) exponent (where the  */
  1.5358 +    /* decimal point is just to the left of the coefficient msd)  */
  1.5359 +    h=rhs->exponent+rhs->digits;
  1.5360 +    /* if h>8 then 10**h cannot be calculated safely; however, when  */
  1.5361 +    /* h=8 then exp(|rhs|) will be at least exp(1E+7) which is at  */
  1.5362 +    /* least 6.59E+4342944, so (due to the restriction on Emax/Emin)  */
  1.5363 +    /* overflow (or underflow to 0) is guaranteed -- so this case can  */
  1.5364 +    /* be handled by simply forcing the appropriate excess  */
  1.5365 +    if (h>8) {                          /* overflow/underflow  */
  1.5366 +      /* set up here so Power call below will over or underflow to  */
  1.5367 +      /* zero; set accumulator to either 2 or 0.02  */
  1.5368 +      /* [stack buffer for a is always big enough for this]  */
  1.5369 +      uprv_decNumberZero(a);
  1.5370 +      *a->lsu=2;                        /* not 1 but < exp(1)  */
  1.5371 +      if (decNumberIsNegative(rhs)) a->exponent=-2; /* make 0.02  */
  1.5372 +      h=8;                              /* clamp so 10**h computable  */
  1.5373 +      p=9;                              /* set a working precision  */
  1.5374 +      }
  1.5375 +     else {                             /* h<=8  */
  1.5376 +      Int maxlever=(rhs->digits>8?1:0);
  1.5377 +      /* [could/should increase this for precisions >40 or so, too]  */
  1.5378 +
  1.5379 +      /* if h is 8, cannot normalize to a lower upper limit because  */
  1.5380 +      /* the final result will not be computable (see notes above),  */
  1.5381 +      /* but leverage can be applied whenever h is less than 8.  */
  1.5382 +      /* Apply as much as possible, up to a MAXLEVER digits, which  */
  1.5383 +      /* sets the tradeoff against the cost of the later a**(10**h).  */
  1.5384 +      /* As h is increased, the working precision below also  */
  1.5385 +      /* increases to compensate for the "constant digits at the  */
  1.5386 +      /* front" effect.  */
  1.5387 +      Int lever=MINI(8-h, maxlever);    /* leverage attainable  */
  1.5388 +      Int use=-rhs->digits-lever;       /* exponent to use for RHS  */
  1.5389 +      h+=lever;                         /* apply leverage selected  */
  1.5390 +      if (h<0) {                        /* clamp  */
  1.5391 +        use+=h;                         /* [may end up subnormal]  */
  1.5392 +        h=0;
  1.5393 +        }
  1.5394 +      /* Take a copy of RHS if it needs normalization (true whenever x>=1)  */
  1.5395 +      if (rhs->exponent!=use) {
  1.5396 +        decNumber *newrhs=bufr;         /* assume will fit on stack  */
  1.5397 +        needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
  1.5398 +        if (needbytes>sizeof(bufr)) {   /* need malloc space  */
  1.5399 +          allocrhs=(decNumber *)malloc(needbytes);
  1.5400 +          if (allocrhs==NULL) {         /* hopeless -- abandon  */
  1.5401 +            *status|=DEC_Insufficient_storage;
  1.5402 +            break;}
  1.5403 +          newrhs=allocrhs;              /* use the allocated space  */
  1.5404 +          }
  1.5405 +        uprv_decNumberCopy(newrhs, rhs);     /* copy to safe space  */
  1.5406 +        newrhs->exponent=use;           /* normalize; now <1  */
  1.5407 +        x=newrhs;                       /* ready for use  */
  1.5408 +        /* decNumberShow(x);  */
  1.5409 +        }
  1.5410 +
  1.5411 +      /* Now use the usual power series to evaluate exp(x).  The  */
  1.5412 +      /* series starts as 1 + x + x^2/2 ... so prime ready for the  */
  1.5413 +      /* third term by setting the term variable t=x, the accumulator  */
  1.5414 +      /* a=1, and the divisor d=2.  */
  1.5415 +
  1.5416 +      /* First determine the working precision.  From Hull & Abrham  */
  1.5417 +      /* this is set->digits+h+2.  However, if x is 'over-precise' we  */
  1.5418 +      /* need to allow for all its digits to potentially participate  */
  1.5419 +      /* (consider an x where all the excess digits are 9s) so in  */
  1.5420 +      /* this case use x->digits+h+2  */
  1.5421 +      p=MAXI(x->digits, set->digits)+h+2;    /* [h<=8]  */
  1.5422 +
  1.5423 +      /* a and t are variable precision, and depend on p, so space  */
  1.5424 +      /* must be allocated for them if necessary  */
  1.5425 +
  1.5426 +      /* the accumulator needs to be able to hold 2p digits so that  */
  1.5427 +      /* the additions on the second and subsequent iterations are  */
  1.5428 +      /* sufficiently exact.  */
  1.5429 +      needbytes=sizeof(decNumber)+(D2U(p*2)-1)*sizeof(Unit);
  1.5430 +      if (needbytes>sizeof(bufa)) {     /* need malloc space  */
  1.5431 +        allocbufa=(decNumber *)malloc(needbytes);
  1.5432 +        if (allocbufa==NULL) {          /* hopeless -- abandon  */
  1.5433 +          *status|=DEC_Insufficient_storage;
  1.5434 +          break;}
  1.5435 +        a=allocbufa;                    /* use the allocated space  */
  1.5436 +        }
  1.5437 +      /* the term needs to be able to hold p digits (which is  */
  1.5438 +      /* guaranteed to be larger than x->digits, so the initial copy  */
  1.5439 +      /* is safe); it may also be used for the raise-to-power  */
  1.5440 +      /* calculation below, which needs an extra two digits  */
  1.5441 +      needbytes=sizeof(decNumber)+(D2U(p+2)-1)*sizeof(Unit);
  1.5442 +      if (needbytes>sizeof(buft)) {     /* need malloc space  */
  1.5443 +        allocbuft=(decNumber *)malloc(needbytes);
  1.5444 +        if (allocbuft==NULL) {          /* hopeless -- abandon  */
  1.5445 +          *status|=DEC_Insufficient_storage;
  1.5446 +          break;}
  1.5447 +        t=allocbuft;                    /* use the allocated space  */
  1.5448 +        }
  1.5449 +
  1.5450 +      uprv_decNumberCopy(t, x);              /* term=x  */
  1.5451 +      uprv_decNumberZero(a); *a->lsu=1;      /* accumulator=1  */
  1.5452 +      uprv_decNumberZero(d); *d->lsu=2;      /* divisor=2  */
  1.5453 +      uprv_decNumberZero(&numone); *numone.lsu=1; /* constant 1 for increment  */
  1.5454 +
  1.5455 +      /* set up the contexts for calculating a, t, and d  */
  1.5456 +      uprv_decContextDefault(&tset, DEC_INIT_DECIMAL64);
  1.5457 +      dset=tset;
  1.5458 +      /* accumulator bounds are set above, set precision now  */
  1.5459 +      aset.digits=p*2;                  /* double  */
  1.5460 +      /* term bounds avoid any underflow or overflow  */
  1.5461 +      tset.digits=p;
  1.5462 +      tset.emin=DEC_MIN_EMIN;           /* [emax is plenty]  */
  1.5463 +      /* [dset.digits=16, etc., are sufficient]  */
  1.5464 +
  1.5465 +      /* finally ready to roll  */
  1.5466 +      for (;;) {
  1.5467 +        #if DECCHECK
  1.5468 +        iterations++;
  1.5469 +        #endif
  1.5470 +        /* only the status from the accumulation is interesting  */
  1.5471 +        /* [but it should remain unchanged after first add]  */
  1.5472 +        decAddOp(a, a, t, &aset, 0, status);           /* a=a+t  */
  1.5473 +        decMultiplyOp(t, t, x, &tset, &ignore);        /* t=t*x  */
  1.5474 +        decDivideOp(t, t, d, &tset, DIVIDE, &ignore);  /* t=t/d  */
  1.5475 +        /* the iteration ends when the term cannot affect the result,  */
  1.5476 +        /* if rounded to p digits, which is when its value is smaller  */
  1.5477 +        /* than the accumulator by p+1 digits.  There must also be  */
  1.5478 +        /* full precision in a.  */
  1.5479 +        if (((a->digits+a->exponent)>=(t->digits+t->exponent+p+1))
  1.5480 +            && (a->digits>=p)) break;
  1.5481 +        decAddOp(d, d, &numone, &dset, 0, &ignore);    /* d=d+1  */
  1.5482 +        } /* iterate  */
  1.5483 +
  1.5484 +      #if DECCHECK
  1.5485 +      /* just a sanity check; comment out test to show always  */
  1.5486 +      if (iterations>p+3)
  1.5487 +        printf("Exp iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
  1.5488 +               (LI)iterations, (LI)*status, (LI)p, (LI)x->digits);
  1.5489 +      #endif
  1.5490 +      } /* h<=8  */
  1.5491 +
  1.5492 +    /* apply postconditioning: a=a**(10**h) -- this is calculated  */
  1.5493 +    /* at a slightly higher precision than Hull & Abrham suggest  */
  1.5494 +    if (h>0) {
  1.5495 +      Int seenbit=0;               /* set once a 1-bit is seen  */
  1.5496 +      Int i;                       /* counter  */
  1.5497 +      Int n=powers[h];             /* always positive  */
  1.5498 +      aset.digits=p+2;             /* sufficient precision  */
  1.5499 +      /* avoid the overhead and many extra digits of decNumberPower  */
  1.5500 +      /* as all that is needed is the short 'multipliers' loop; here  */
  1.5501 +      /* accumulate the answer into t  */
  1.5502 +      uprv_decNumberZero(t); *t->lsu=1; /* acc=1  */
  1.5503 +      for (i=1;;i++){              /* for each bit [top bit ignored]  */
  1.5504 +        /* abandon if have had overflow or terminal underflow  */
  1.5505 +        if (*status & (DEC_Overflow|DEC_Underflow)) { /* interesting?  */
  1.5506 +          if (*status&DEC_Overflow || ISZERO(t)) break;}
  1.5507 +        n=n<<1;                    /* move next bit to testable position  */
  1.5508 +        if (n<0) {                 /* top bit is set  */
  1.5509 +          seenbit=1;               /* OK, have a significant bit  */
  1.5510 +          decMultiplyOp(t, t, a, &aset, status); /* acc=acc*x  */
  1.5511 +          }
  1.5512 +        if (i==31) break;          /* that was the last bit  */
  1.5513 +        if (!seenbit) continue;    /* no need to square 1  */
  1.5514 +        decMultiplyOp(t, t, t, &aset, status); /* acc=acc*acc [square]  */
  1.5515 +        } /*i*/ /* 32 bits  */
  1.5516 +      /* decNumberShow(t);  */
  1.5517 +      a=t;                         /* and carry on using t instead of a  */
  1.5518 +      }
  1.5519 +
  1.5520 +    /* Copy and round the result to res  */
  1.5521 +    residue=1;                          /* indicate dirt to right ..  */
  1.5522 +    if (ISZERO(a)) residue=0;           /* .. unless underflowed to 0  */
  1.5523 +    aset.digits=set->digits;            /* [use default rounding]  */
  1.5524 +    decCopyFit(res, a, &aset, &residue, status); /* copy & shorten  */
  1.5525 +    decFinish(res, set, &residue, status);       /* cleanup/set flags  */
  1.5526 +    } while(0);                         /* end protected  */
  1.5527 +
  1.5528 +  if (allocrhs !=NULL) free(allocrhs);  /* drop any storage used  */
  1.5529 +  if (allocbufa!=NULL) free(allocbufa); /* ..  */
  1.5530 +  if (allocbuft!=NULL) free(allocbuft); /* ..  */
  1.5531 +  /* [status is handled by caller]  */
  1.5532 +  return res;
  1.5533 +  } /* decExpOp  */
  1.5534 +
  1.5535 +/* ------------------------------------------------------------------ */
  1.5536 +/* Initial-estimate natural logarithm table                           */
  1.5537 +/*                                                                    */
  1.5538 +/*   LNnn -- 90-entry 16-bit table for values from .10 through .99.   */
  1.5539 +/*           The result is a 4-digit encode of the coefficient (c=the */
  1.5540 +/*           top 14 bits encoding 0-9999) and a 2-digit encode of the */
  1.5541 +/*           exponent (e=the bottom 2 bits encoding 0-3)              */
  1.5542 +/*                                                                    */
  1.5543 +/*           The resulting value is given by:                         */
  1.5544 +/*                                                                    */
  1.5545 +/*             v = -c * 10**(-e-3)                                    */
  1.5546 +/*                                                                    */
  1.5547 +/*           where e and c are extracted from entry k = LNnn[x-10]    */
  1.5548 +/*           where x is truncated (NB) into the range 10 through 99,  */
  1.5549 +/*           and then c = k>>2 and e = k&3.                           */
  1.5550 +/* ------------------------------------------------------------------ */
  1.5551 +static const uShort LNnn[90]={9016,  8652,  8316,  8008,  7724,  7456,  7208,
  1.5552 +  6972,  6748,  6540,  6340,  6148,  5968,  5792,  5628,  5464,  5312,
  1.5553 +  5164,  5020,  4884,  4748,  4620,  4496,  4376,  4256,  4144,  4032,
  1.5554 + 39233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629,
  1.5555 + 29777, 28945, 28129, 27329, 26545, 25777, 25021, 24281, 23553, 22837,
  1.5556 + 22137, 21445, 20769, 20101, 19445, 18801, 18165, 17541, 16925, 16321,
  1.5557 + 15721, 15133, 14553, 13985, 13421, 12865, 12317, 11777, 11241, 10717,
  1.5558 + 10197,  9685,  9177,  8677,  8185,  7697,  7213,  6737,  6269,  5801,
  1.5559 +  5341,  4889,  4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254,
  1.5560 + 10130,  6046, 20055};
  1.5561 +
  1.5562 +/* ------------------------------------------------------------------ */
  1.5563 +/* decLnOp -- effect natural logarithm                                */
  1.5564 +/*                                                                    */
  1.5565 +/*   This computes C = ln(A)                                          */
  1.5566 +/*                                                                    */
  1.5567 +/*   res is C, the result.  C may be A                                */
  1.5568 +/*   rhs is A                                                         */
  1.5569 +/*   set is the context; note that rounding mode has no effect        */
  1.5570 +/*                                                                    */
  1.5571 +/* C must have space for set->digits digits.                          */
  1.5572 +/*                                                                    */
  1.5573 +/* Notable cases:                                                     */
  1.5574 +/*   A<0 -> Invalid                                                   */
  1.5575 +/*   A=0 -> -Infinity (Exact)                                         */
  1.5576 +/*   A=+Infinity -> +Infinity (Exact)                                 */
  1.5577 +/*   A=1 exactly -> 0 (Exact)                                         */
  1.5578 +/*                                                                    */
  1.5579 +/* Restrictions (as for Exp):                                         */
  1.5580 +/*                                                                    */
  1.5581 +/*   digits, emax, and -emin in the context must be less than         */
  1.5582 +/*   DEC_MAX_MATH+11 (1000010), and the rhs must be within these      */
  1.5583 +/*   bounds or a zero.  This is an internal routine, so these         */
  1.5584 +/*   restrictions are contractual and not enforced.                   */
  1.5585 +/*                                                                    */
  1.5586 +/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will      */
  1.5587 +/* almost always be correctly rounded, but may be up to 1 ulp in      */
  1.5588 +/* error in rare cases.                                               */
  1.5589 +/* ------------------------------------------------------------------ */
  1.5590 +/* The result is calculated using Newton's method, with each          */
  1.5591 +/* iteration calculating a' = a + x * exp(-a) - 1.  See, for example, */
  1.5592 +/* Epperson 1989.                                                     */
  1.5593 +/*                                                                    */
  1.5594 +/* The iteration ends when the adjustment x*exp(-a)-1 is tiny enough. */
  1.5595 +/* This has to be calculated at the sum of the precision of x and the */
  1.5596 +/* working precision.                                                 */
  1.5597 +/*                                                                    */
  1.5598 +/* Implementation notes:                                              */
  1.5599 +/*                                                                    */
  1.5600 +/* 1. This is separated out as decLnOp so it can be called from       */
  1.5601 +/*    other Mathematical functions (e.g., Log 10) with a wider range  */
  1.5602 +/*    than normal.  In particular, it can handle the slightly wider   */
  1.5603 +/*    (+9+2) range needed by a power function.                        */
  1.5604 +/*                                                                    */
  1.5605 +/* 2. The speed of this function is about 10x slower than exp, as     */
  1.5606 +/*    it typically needs 4-6 iterations for short numbers, and the    */
  1.5607 +/*    extra precision needed adds a squaring effect, twice.           */
  1.5608 +/*                                                                    */
  1.5609 +/* 3. Fastpaths are included for ln(10) and ln(2), up to length 40,   */
  1.5610 +/*    as these are common requests.  ln(10) is used by log10(x).      */
  1.5611 +/*                                                                    */
  1.5612 +/* 4. An iteration might be saved by widening the LNnn table, and     */
  1.5613 +/*    would certainly save at least one if it were made ten times     */
  1.5614 +/*    bigger, too (for truncated fractions 0.100 through 0.999).      */
  1.5615 +/*    However, for most practical evaluations, at least four or five  */
  1.5616 +/*    iterations will be neede -- so this would only speed up by      */
  1.5617 +/*    20-25% and that probably does not justify increasing the table  */
  1.5618 +/*    size.                                                           */
  1.5619 +/*                                                                    */
  1.5620 +/* 5. The static buffers are larger than might be expected to allow   */
  1.5621 +/*    for calls from decNumberPower.                                  */
  1.5622 +/* ------------------------------------------------------------------ */
  1.5623 +#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
  1.5624 +#pragma GCC diagnostic push
  1.5625 +#pragma GCC diagnostic ignored "-Warray-bounds"
  1.5626 +#endif
  1.5627 +decNumber * decLnOp(decNumber *res, const decNumber *rhs,
  1.5628 +                    decContext *set, uInt *status) {
  1.5629 +  uInt ignore=0;                   /* working status accumulator  */
  1.5630 +  uInt needbytes;                  /* for space calculations  */
  1.5631 +  Int residue;                     /* rounding residue  */
  1.5632 +  Int r;                           /* rhs=f*10**r [see below]  */
  1.5633 +  Int p;                           /* working precision  */
  1.5634 +  Int pp;                          /* precision for iteration  */
  1.5635 +  Int t;                           /* work  */
  1.5636 +
  1.5637 +  /* buffers for a (accumulator, typically precision+2) and b  */
  1.5638 +  /* (adjustment calculator, same size)  */
  1.5639 +  decNumber bufa[D2N(DECBUFFER+12)];
  1.5640 +  decNumber *allocbufa=NULL;       /* -> allocated bufa, iff allocated  */
  1.5641 +  decNumber *a=bufa;               /* accumulator/work  */
  1.5642 +  decNumber bufb[D2N(DECBUFFER*2+2)];
  1.5643 +  decNumber *allocbufb=NULL;       /* -> allocated bufa, iff allocated  */
  1.5644 +  decNumber *b=bufb;               /* adjustment/work  */
  1.5645 +
  1.5646 +  decNumber  numone;               /* constant 1  */
  1.5647 +  decNumber  cmp;                  /* work  */
  1.5648 +  decContext aset, bset;           /* working contexts  */
  1.5649 +
  1.5650 +  #if DECCHECK
  1.5651 +  Int iterations=0;                /* for later sanity check  */
  1.5652 +  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
  1.5653 +  #endif
  1.5654 +
  1.5655 +  do {                                  /* protect allocated storage  */
  1.5656 +    if (SPECIALARG) {                   /* handle infinities and NaNs  */
  1.5657 +      if (decNumberIsInfinite(rhs)) {   /* an infinity  */
  1.5658 +        if (decNumberIsNegative(rhs))   /* -Infinity -> error  */
  1.5659 +          *status|=DEC_Invalid_operation;
  1.5660 +         else uprv_decNumberCopy(res, rhs);  /* +Infinity -> self  */
  1.5661 +        }
  1.5662 +       else decNaNs(res, rhs, NULL, set, status); /* a NaN  */
  1.5663 +      break;}
  1.5664 +
  1.5665 +    if (ISZERO(rhs)) {                  /* +/- zeros -> -Infinity  */
  1.5666 +      uprv_decNumberZero(res);               /* make clean  */
  1.5667 +      res->bits=DECINF|DECNEG;          /* set - infinity  */
  1.5668 +      break;}                           /* [no status to set]  */
  1.5669 +
  1.5670 +    /* Non-zero negatives are bad...  */
  1.5671 +    if (decNumberIsNegative(rhs)) {     /* -x -> error  */
  1.5672 +      *status|=DEC_Invalid_operation;
  1.5673 +      break;}
  1.5674 +
  1.5675 +    /* Here, rhs is positive, finite, and in range  */
  1.5676 +
  1.5677 +    /* lookaside fastpath code for ln(2) and ln(10) at common lengths  */
  1.5678 +    if (rhs->exponent==0 && set->digits<=40) {
  1.5679 +      #if DECDPUN==1
  1.5680 +      if (rhs->lsu[0]==0 && rhs->lsu[1]==1 && rhs->digits==2) { /* ln(10)  */
  1.5681 +      #else
  1.5682 +      if (rhs->lsu[0]==10 && rhs->digits==2) {                  /* ln(10)  */
  1.5683 +      #endif
  1.5684 +        aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
  1.5685 +        #define LN10 "2.302585092994045684017991454684364207601"
  1.5686 +        uprv_decNumberFromString(res, LN10, &aset);
  1.5687 +        *status|=(DEC_Inexact | DEC_Rounded); /* is inexact  */
  1.5688 +        break;}
  1.5689 +      if (rhs->lsu[0]==2 && rhs->digits==1) { /* ln(2)  */
  1.5690 +        aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
  1.5691 +        #define LN2 "0.6931471805599453094172321214581765680755"
  1.5692 +        uprv_decNumberFromString(res, LN2, &aset);
  1.5693 +        *status|=(DEC_Inexact | DEC_Rounded);
  1.5694 +        break;}
  1.5695 +      } /* integer and short  */
  1.5696 +
  1.5697 +    /* Determine the working precision.  This is normally the  */
  1.5698 +    /* requested precision + 2, with a minimum of 9.  However, if  */
  1.5699 +    /* the rhs is 'over-precise' then allow for all its digits to  */
  1.5700 +    /* potentially participate (consider an rhs where all the excess  */
  1.5701 +    /* digits are 9s) so in this case use rhs->digits+2.  */
  1.5702 +    p=MAXI(rhs->digits, MAXI(set->digits, 7))+2;
  1.5703 +
  1.5704 +    /* Allocate space for the accumulator and the high-precision  */
  1.5705 +    /* adjustment calculator, if necessary.  The accumulator must  */
  1.5706 +    /* be able to hold p digits, and the adjustment up to  */
  1.5707 +    /* rhs->digits+p digits.  They are also made big enough for 16  */
  1.5708 +    /* digits so that they can be used for calculating the initial  */
  1.5709 +    /* estimate.  */
  1.5710 +    needbytes=sizeof(decNumber)+(D2U(MAXI(p,16))-1)*sizeof(Unit);
  1.5711 +    if (needbytes>sizeof(bufa)) {     /* need malloc space  */
  1.5712 +      allocbufa=(decNumber *)malloc(needbytes);
  1.5713 +      if (allocbufa==NULL) {          /* hopeless -- abandon  */
  1.5714 +        *status|=DEC_Insufficient_storage;
  1.5715 +        break;}
  1.5716 +      a=allocbufa;                    /* use the allocated space  */
  1.5717 +      }
  1.5718 +    pp=p+rhs->digits;
  1.5719 +    needbytes=sizeof(decNumber)+(D2U(MAXI(pp,16))-1)*sizeof(Unit);
  1.5720 +    if (needbytes>sizeof(bufb)) {     /* need malloc space  */
  1.5721 +      allocbufb=(decNumber *)malloc(needbytes);
  1.5722 +      if (allocbufb==NULL) {          /* hopeless -- abandon  */
  1.5723 +        *status|=DEC_Insufficient_storage;
  1.5724 +        break;}
  1.5725 +      b=allocbufb;                    /* use the allocated space  */
  1.5726 +      }
  1.5727 +
  1.5728 +    /* Prepare an initial estimate in acc. Calculate this by  */
  1.5729 +    /* considering the coefficient of x to be a normalized fraction,  */
  1.5730 +    /* f, with the decimal point at far left and multiplied by  */
  1.5731 +    /* 10**r.  Then, rhs=f*10**r and 0.1<=f<1, and  */
  1.5732 +    /*   ln(x) = ln(f) + ln(10)*r  */
  1.5733 +    /* Get the initial estimate for ln(f) from a small lookup  */
  1.5734 +    /* table (see above) indexed by the first two digits of f,  */
  1.5735 +    /* truncated.  */
  1.5736 +
  1.5737 +    uprv_decContextDefault(&aset, DEC_INIT_DECIMAL64); /* 16-digit extended  */
  1.5738 +    r=rhs->exponent+rhs->digits;        /* 'normalised' exponent  */
  1.5739 +    uprv_decNumberFromInt32(a, r);           /* a=r  */
  1.5740 +    uprv_decNumberFromInt32(b, 2302585);     /* b=ln(10) (2.302585)  */
  1.5741 +    b->exponent=-6;                     /*  ..  */
  1.5742 +    decMultiplyOp(a, a, b, &aset, &ignore);  /* a=a*b  */
  1.5743 +    /* now get top two digits of rhs into b by simple truncate and  */
  1.5744 +    /* force to integer  */
  1.5745 +    residue=0;                          /* (no residue)  */
  1.5746 +    aset.digits=2; aset.round=DEC_ROUND_DOWN;
  1.5747 +    decCopyFit(b, rhs, &aset, &residue, &ignore); /* copy & shorten  */
  1.5748 +    b->exponent=0;                      /* make integer  */
  1.5749 +    t=decGetInt(b);                     /* [cannot fail]  */
  1.5750 +    if (t<10) t=X10(t);                 /* adjust single-digit b  */
  1.5751 +    t=LNnn[t-10];                       /* look up ln(b)  */
  1.5752 +    uprv_decNumberFromInt32(b, t>>2);        /* b=ln(b) coefficient  */
  1.5753 +    b->exponent=-(t&3)-3;               /* set exponent  */
  1.5754 +    b->bits=DECNEG;                     /* ln(0.10)->ln(0.99) always -ve  */
  1.5755 +    aset.digits=16; aset.round=DEC_ROUND_HALF_EVEN; /* restore  */
  1.5756 +    decAddOp(a, a, b, &aset, 0, &ignore); /* acc=a+b  */
  1.5757 +    /* the initial estimate is now in a, with up to 4 digits correct.  */
  1.5758 +    /* When rhs is at or near Nmax the estimate will be low, so we  */
  1.5759 +    /* will approach it from below, avoiding overflow when calling exp.  */
  1.5760 +
  1.5761 +    uprv_decNumberZero(&numone); *numone.lsu=1;   /* constant 1 for adjustment  */
  1.5762 +
  1.5763 +    /* accumulator bounds are as requested (could underflow, but  */
  1.5764 +    /* cannot overflow)  */
  1.5765 +    aset.emax=set->emax;
  1.5766 +    aset.emin=set->emin;
  1.5767 +    aset.clamp=0;                       /* no concrete format  */
  1.5768 +    /* set up a context to be used for the multiply and subtract  */
  1.5769 +    bset=aset;
  1.5770 +    bset.emax=DEC_MAX_MATH*2;           /* use double bounds for the  */
  1.5771 +    bset.emin=-DEC_MAX_MATH*2;          /* adjustment calculation  */
  1.5772 +                                        /* [see decExpOp call below]  */
  1.5773 +    /* for each iteration double the number of digits to calculate,  */
  1.5774 +    /* up to a maximum of p  */
  1.5775 +    pp=9;                               /* initial precision  */
  1.5776 +    /* [initially 9 as then the sequence starts 7+2, 16+2, and  */
  1.5777 +    /* 34+2, which is ideal for standard-sized numbers]  */
  1.5778 +    aset.digits=pp;                     /* working context  */
  1.5779 +    bset.digits=pp+rhs->digits;         /* wider context  */
  1.5780 +    for (;;) {                          /* iterate  */
  1.5781 +      #if DECCHECK
  1.5782 +      iterations++;
  1.5783 +      if (iterations>24) break;         /* consider 9 * 2**24  */
  1.5784 +      #endif
  1.5785 +      /* calculate the adjustment (exp(-a)*x-1) into b.  This is a  */
  1.5786 +      /* catastrophic subtraction but it really is the difference  */
  1.5787 +      /* from 1 that is of interest.  */
  1.5788 +      /* Use the internal entry point to Exp as it allows the double  */
  1.5789 +      /* range for calculating exp(-a) when a is the tiniest subnormal.  */
  1.5790 +      a->bits^=DECNEG;                  /* make -a  */
  1.5791 +      decExpOp(b, a, &bset, &ignore);   /* b=exp(-a)  */
  1.5792 +      a->bits^=DECNEG;                  /* restore sign of a  */
  1.5793 +      /* now multiply by rhs and subtract 1, at the wider precision  */
  1.5794 +      decMultiplyOp(b, b, rhs, &bset, &ignore);        /* b=b*rhs  */
  1.5795 +      decAddOp(b, b, &numone, &bset, DECNEG, &ignore); /* b=b-1  */
  1.5796 +
  1.5797 +      /* the iteration ends when the adjustment cannot affect the  */
  1.5798 +      /* result by >=0.5 ulp (at the requested digits), which  */
  1.5799 +      /* is when its value is smaller than the accumulator by  */
  1.5800 +      /* set->digits+1 digits (or it is zero) -- this is a looser  */
  1.5801 +      /* requirement than for Exp because all that happens to the  */
  1.5802 +      /* accumulator after this is the final rounding (but note that  */
  1.5803 +      /* there must also be full precision in a, or a=0).  */
  1.5804 +
  1.5805 +      if (decNumberIsZero(b) ||
  1.5806 +          (a->digits+a->exponent)>=(b->digits+b->exponent+set->digits+1)) {
  1.5807 +        if (a->digits==p) break;
  1.5808 +        if (decNumberIsZero(a)) {
  1.5809 +          decCompareOp(&cmp, rhs, &numone, &aset, COMPARE, &ignore); /* rhs=1 ?  */
  1.5810 +          if (cmp.lsu[0]==0) a->exponent=0;            /* yes, exact 0  */
  1.5811 +           else *status|=(DEC_Inexact | DEC_Rounded);  /* no, inexact  */
  1.5812 +          break;
  1.5813 +          }
  1.5814 +        /* force padding if adjustment has gone to 0 before full length  */
  1.5815 +        if (decNumberIsZero(b)) b->exponent=a->exponent-p;
  1.5816 +        }
  1.5817 +
  1.5818 +      /* not done yet ...  */
  1.5819 +      decAddOp(a, a, b, &aset, 0, &ignore);  /* a=a+b for next estimate  */
  1.5820 +      if (pp==p) continue;                   /* precision is at maximum  */
  1.5821 +      /* lengthen the next calculation  */
  1.5822 +      pp=pp*2;                               /* double precision  */
  1.5823 +      if (pp>p) pp=p;                        /* clamp to maximum  */
  1.5824 +      aset.digits=pp;                        /* working context  */
  1.5825 +      bset.digits=pp+rhs->digits;            /* wider context  */
  1.5826 +      } /* Newton's iteration  */
  1.5827 +
  1.5828 +    #if DECCHECK
  1.5829 +    /* just a sanity check; remove the test to show always  */
  1.5830 +    if (iterations>24)
  1.5831 +      printf("Ln iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
  1.5832 +            (LI)iterations, (LI)*status, (LI)p, (LI)rhs->digits);
  1.5833 +    #endif
  1.5834 +
  1.5835 +    /* Copy and round the result to res  */
  1.5836 +    residue=1;                          /* indicate dirt to right  */
  1.5837 +    if (ISZERO(a)) residue=0;           /* .. unless underflowed to 0  */
  1.5838 +    aset.digits=set->digits;            /* [use default rounding]  */
  1.5839 +    decCopyFit(res, a, &aset, &residue, status); /* copy & shorten  */
  1.5840 +    decFinish(res, set, &residue, status);       /* cleanup/set flags  */
  1.5841 +    } while(0);                         /* end protected  */
  1.5842 +
  1.5843 +  if (allocbufa!=NULL) free(allocbufa); /* drop any storage used  */
  1.5844 +  if (allocbufb!=NULL) free(allocbufb); /* ..  */
  1.5845 +  /* [status is handled by caller]  */
  1.5846 +  return res;
  1.5847 +  } /* decLnOp  */
  1.5848 +#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
  1.5849 +#pragma GCC diagnostic pop
  1.5850 +#endif
  1.5851 +
  1.5852 +/* ------------------------------------------------------------------ */
  1.5853 +/* decQuantizeOp  -- force exponent to requested value                */
  1.5854 +/*                                                                    */
  1.5855 +/*   This computes C = op(A, B), where op adjusts the coefficient     */
  1.5856 +/*   of C (by rounding or shifting) such that the exponent (-scale)   */
  1.5857 +/*   of C has the value B or matches the exponent of B.               */
  1.5858 +/*   The numerical value of C will equal A, except for the effects of */
  1.5859 +/*   any rounding that occurred.                                      */
  1.5860 +/*                                                                    */
  1.5861 +/*   res is C, the result.  C may be A or B                           */
  1.5862 +/*   lhs is A, the number to adjust                                   */
  1.5863 +/*   rhs is B, the requested exponent                                 */
  1.5864 +/*   set is the context                                               */
  1.5865 +/*   quant is 1 for quantize or 0 for rescale                         */
  1.5866 +/*   status is the status accumulator (this can be called without     */
  1.5867 +/*          risk of control loss)                                     */
  1.5868 +/*                                                                    */
  1.5869 +/* C must have space for set->digits digits.                          */
  1.5870 +/*                                                                    */
  1.5871 +/* Unless there is an error or the result is infinite, the exponent   */
  1.5872 +/* after the operation is guaranteed to be that requested.            */
  1.5873 +/* ------------------------------------------------------------------ */
  1.5874 +static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs,
  1.5875 +                                 const decNumber *rhs, decContext *set,
  1.5876 +                                 Flag quant, uInt *status) {
  1.5877 +  #if DECSUBSET
  1.5878 +  decNumber *alloclhs=NULL;        /* non-NULL if rounded lhs allocated  */
  1.5879 +  decNumber *allocrhs=NULL;        /* .., rhs  */
  1.5880 +  #endif
  1.5881 +  const decNumber *inrhs=rhs;      /* save original rhs  */
  1.5882 +  Int   reqdigits=set->digits;     /* requested DIGITS  */
  1.5883 +  Int   reqexp;                    /* requested exponent [-scale]  */
  1.5884 +  Int   residue=0;                 /* rounding residue  */
  1.5885 +  Int   etiny=set->emin-(reqdigits-1);
  1.5886 +
  1.5887 +  #if DECCHECK
  1.5888 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
  1.5889 +  #endif
  1.5890 +
  1.5891 +  do {                             /* protect allocated storage  */
  1.5892 +    #if DECSUBSET
  1.5893 +    if (!set->extended) {
  1.5894 +      /* reduce operands and set lostDigits status, as needed  */
  1.5895 +      if (lhs->digits>reqdigits) {
  1.5896 +        alloclhs=decRoundOperand(lhs, set, status);
  1.5897 +        if (alloclhs==NULL) break;
  1.5898 +        lhs=alloclhs;
  1.5899 +        }
  1.5900 +      if (rhs->digits>reqdigits) { /* [this only checks lostDigits]  */
  1.5901 +        allocrhs=decRoundOperand(rhs, set, status);
  1.5902 +        if (allocrhs==NULL) break;
  1.5903 +        rhs=allocrhs;
  1.5904 +        }
  1.5905 +      }
  1.5906 +    #endif
  1.5907 +    /* [following code does not require input rounding]  */
  1.5908 +
  1.5909 +    /* Handle special values  */
  1.5910 +    if (SPECIALARGS) {
  1.5911 +      /* NaNs get usual processing  */
  1.5912 +      if (SPECIALARGS & (DECSNAN | DECNAN))
  1.5913 +        decNaNs(res, lhs, rhs, set, status);
  1.5914 +      /* one infinity but not both is bad  */
  1.5915 +      else if ((lhs->bits ^ rhs->bits) & DECINF)
  1.5916 +        *status|=DEC_Invalid_operation;
  1.5917 +      /* both infinity: return lhs  */
  1.5918 +      else uprv_decNumberCopy(res, lhs);          /* [nop if in place]  */
  1.5919 +      break;
  1.5920 +      }
  1.5921 +
  1.5922 +    /* set requested exponent  */
  1.5923 +    if (quant) reqexp=inrhs->exponent;  /* quantize -- match exponents  */
  1.5924 +     else {                             /* rescale -- use value of rhs  */
  1.5925 +      /* Original rhs must be an integer that fits and is in range,  */
  1.5926 +      /* which could be from -1999999997 to +999999999, thanks to  */
  1.5927 +      /* subnormals  */
  1.5928 +      reqexp=decGetInt(inrhs);               /* [cannot fail]  */
  1.5929 +      }
  1.5930 +
  1.5931 +    #if DECSUBSET
  1.5932 +    if (!set->extended) etiny=set->emin;     /* no subnormals  */
  1.5933 +    #endif
  1.5934 +
  1.5935 +    if (reqexp==BADINT                       /* bad (rescale only) or ..  */
  1.5936 +     || reqexp==BIGODD || reqexp==BIGEVEN    /* very big (ditto) or ..  */
  1.5937 +     || (reqexp<etiny)                       /* < lowest  */
  1.5938 +     || (reqexp>set->emax)) {                /* > emax  */
  1.5939 +      *status|=DEC_Invalid_operation;
  1.5940 +      break;}
  1.5941 +
  1.5942 +    /* the RHS has been processed, so it can be overwritten now if necessary  */
  1.5943 +    if (ISZERO(lhs)) {                       /* zero coefficient unchanged  */
  1.5944 +      uprv_decNumberCopy(res, lhs);               /* [nop if in place]  */
  1.5945 +      res->exponent=reqexp;                  /* .. just set exponent  */
  1.5946 +      #if DECSUBSET
  1.5947 +      if (!set->extended) res->bits=0;       /* subset specification; no -0  */
  1.5948 +      #endif
  1.5949 +      }
  1.5950 +     else {                                  /* non-zero lhs  */
  1.5951 +      Int adjust=reqexp-lhs->exponent;       /* digit adjustment needed  */
  1.5952 +      /* if adjusted coefficient will definitely not fit, give up now  */
  1.5953 +      if ((lhs->digits-adjust)>reqdigits) {
  1.5954 +        *status|=DEC_Invalid_operation;
  1.5955 +        break;
  1.5956 +        }
  1.5957 +
  1.5958 +      if (adjust>0) {                        /* increasing exponent  */
  1.5959 +        /* this will decrease the length of the coefficient by adjust  */
  1.5960 +        /* digits, and must round as it does so  */
  1.5961 +        decContext workset;                  /* work  */
  1.5962 +        workset=*set;                        /* clone rounding, etc.  */
  1.5963 +        workset.digits=lhs->digits-adjust;   /* set requested length  */
  1.5964 +        /* [note that the latter can be <1, here]  */
  1.5965 +        decCopyFit(res, lhs, &workset, &residue, status); /* fit to result  */
  1.5966 +        decApplyRound(res, &workset, residue, status);    /* .. and round  */
  1.5967 +        residue=0;                                        /* [used]  */
  1.5968 +        /* If just rounded a 999s case, exponent will be off by one;  */
  1.5969 +        /* adjust back (after checking space), if so.  */
  1.5970 +        if (res->exponent>reqexp) {
  1.5971 +          /* re-check needed, e.g., for quantize(0.9999, 0.001) under  */
  1.5972 +          /* set->digits==3  */
  1.5973 +          if (res->digits==reqdigits) {      /* cannot shift by 1  */
  1.5974 +            *status&=~(DEC_Inexact | DEC_Rounded); /* [clean these]  */
  1.5975 +            *status|=DEC_Invalid_operation;
  1.5976 +            break;
  1.5977 +            }
  1.5978 +          res->digits=decShiftToMost(res->lsu, res->digits, 1); /* shift  */
  1.5979 +          res->exponent--;                   /* (re)adjust the exponent.  */
  1.5980 +          }
  1.5981 +        #if DECSUBSET
  1.5982 +        if (ISZERO(res) && !set->extended) res->bits=0; /* subset; no -0  */
  1.5983 +        #endif
  1.5984 +        } /* increase  */
  1.5985 +       else /* adjust<=0 */ {                /* decreasing or = exponent  */
  1.5986 +        /* this will increase the length of the coefficient by -adjust  */
  1.5987 +        /* digits, by adding zero or more trailing zeros; this is  */
  1.5988 +        /* already checked for fit, above  */
  1.5989 +        uprv_decNumberCopy(res, lhs);             /* [it will fit]  */
  1.5990 +        /* if padding needed (adjust<0), add it now...  */
  1.5991 +        if (adjust<0) {
  1.5992 +          res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
  1.5993 +          res->exponent+=adjust;             /* adjust the exponent  */
  1.5994 +          }
  1.5995 +        } /* decrease  */
  1.5996 +      } /* non-zero  */
  1.5997 +
  1.5998 +    /* Check for overflow [do not use Finalize in this case, as an  */
  1.5999 +    /* overflow here is a "don't fit" situation]  */
  1.6000 +    if (res->exponent>set->emax-res->digits+1) {  /* too big  */
  1.6001 +      *status|=DEC_Invalid_operation;
  1.6002 +      break;
  1.6003 +      }
  1.6004 +     else {
  1.6005 +      decFinalize(res, set, &residue, status);    /* set subnormal flags  */
  1.6006 +      *status&=~DEC_Underflow;          /* suppress Underflow [as per 754]  */
  1.6007 +      }
  1.6008 +    } while(0);                         /* end protected  */
  1.6009 +
  1.6010 +  #if DECSUBSET
  1.6011 +  if (allocrhs!=NULL) free(allocrhs);   /* drop any storage used  */
  1.6012 +  if (alloclhs!=NULL) free(alloclhs);   /* ..  */
  1.6013 +  #endif
  1.6014 +  return res;
  1.6015 +  } /* decQuantizeOp  */
  1.6016 +
  1.6017 +/* ------------------------------------------------------------------ */
  1.6018 +/* decCompareOp -- compare, min, or max two Numbers                   */
  1.6019 +/*                                                                    */
  1.6020 +/*   This computes C = A ? B and carries out one of four operations:  */
  1.6021 +/*     COMPARE    -- returns the signum (as a number) giving the      */
  1.6022 +/*                   result of a comparison unless one or both        */
  1.6023 +/*                   operands is a NaN (in which case a NaN results)  */
  1.6024 +/*     COMPSIG    -- as COMPARE except that a quiet NaN raises        */
  1.6025 +/*                   Invalid operation.                               */
  1.6026 +/*     COMPMAX    -- returns the larger of the operands, using the    */
  1.6027 +/*                   754 maxnum operation                             */
  1.6028 +/*     COMPMAXMAG -- ditto, comparing absolute values                 */
  1.6029 +/*     COMPMIN    -- the 754 minnum operation                         */
  1.6030 +/*     COMPMINMAG -- ditto, comparing absolute values                 */
  1.6031 +/*     COMTOTAL   -- returns the signum (as a number) giving the      */
  1.6032 +/*                   result of a comparison using 754 total ordering  */
  1.6033 +/*                                                                    */
  1.6034 +/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
  1.6035 +/*   lhs is A                                                         */
  1.6036 +/*   rhs is B                                                         */
  1.6037 +/*   set is the context                                               */
  1.6038 +/*   op  is the operation flag                                        */
  1.6039 +/*   status is the usual accumulator                                  */
  1.6040 +/*                                                                    */
  1.6041 +/* C must have space for one digit for COMPARE or set->digits for     */
  1.6042 +/* COMPMAX, COMPMIN, COMPMAXMAG, or COMPMINMAG.                       */
  1.6043 +/* ------------------------------------------------------------------ */
  1.6044 +/* The emphasis here is on speed for common cases, and avoiding       */
  1.6045 +/* coefficient comparison if possible.                                */
  1.6046 +/* ------------------------------------------------------------------ */
  1.6047 +static decNumber * decCompareOp(decNumber *res, const decNumber *lhs,
  1.6048 +                         const decNumber *rhs, decContext *set,
  1.6049 +                         Flag op, uInt *status) {
  1.6050 +  #if DECSUBSET
  1.6051 +  decNumber *alloclhs=NULL;        /* non-NULL if rounded lhs allocated  */
  1.6052 +  decNumber *allocrhs=NULL;        /* .., rhs  */
  1.6053 +  #endif
  1.6054 +  Int   result=0;                  /* default result value  */
  1.6055 +  uByte merged;                    /* work  */
  1.6056 +
  1.6057 +  #if DECCHECK
  1.6058 +  if (decCheckOperands(res, lhs, rhs, set)) return res;
  1.6059 +  #endif
  1.6060 +
  1.6061 +  do {                             /* protect allocated storage  */
  1.6062 +    #if DECSUBSET
  1.6063 +    if (!set->extended) {
  1.6064 +      /* reduce operands and set lostDigits status, as needed  */
  1.6065 +      if (lhs->digits>set->digits) {
  1.6066 +        alloclhs=decRoundOperand(lhs, set, status);
  1.6067 +        if (alloclhs==NULL) {result=BADINT; break;}
  1.6068 +        lhs=alloclhs;
  1.6069 +        }
  1.6070 +      if (rhs->digits>set->digits) {
  1.6071 +        allocrhs=decRoundOperand(rhs, set, status);
  1.6072 +        if (allocrhs==NULL) {result=BADINT; break;}
  1.6073 +        rhs=allocrhs;
  1.6074 +        }
  1.6075 +      }
  1.6076 +    #endif
  1.6077 +    /* [following code does not require input rounding]  */
  1.6078 +
  1.6079 +    /* If total ordering then handle differing signs 'up front'  */
  1.6080 +    if (op==COMPTOTAL) {                /* total ordering  */
  1.6081 +      if (decNumberIsNegative(lhs) && !decNumberIsNegative(rhs)) {
  1.6082 +        result=-1;
  1.6083 +        break;
  1.6084 +        }
  1.6085 +      if (!decNumberIsNegative(lhs) && decNumberIsNegative(rhs)) {
  1.6086 +        result=+1;
  1.6087 +        break;
  1.6088 +        }
  1.6089 +      }
  1.6090 +
  1.6091 +    /* handle NaNs specially; let infinities drop through  */
  1.6092 +    /* This assumes sNaN (even just one) leads to NaN.  */
  1.6093 +    merged=(lhs->bits | rhs->bits) & (DECSNAN | DECNAN);
  1.6094 +    if (merged) {                       /* a NaN bit set  */
  1.6095 +      if (op==COMPARE);                 /* result will be NaN  */
  1.6096 +       else if (op==COMPSIG)            /* treat qNaN as sNaN  */
  1.6097 +        *status|=DEC_Invalid_operation | DEC_sNaN;
  1.6098 +       else if (op==COMPTOTAL) {        /* total ordering, always finite  */
  1.6099 +        /* signs are known to be the same; compute the ordering here  */
  1.6100 +        /* as if the signs are both positive, then invert for negatives  */
  1.6101 +        if (!decNumberIsNaN(lhs)) result=-1;
  1.6102 +         else if (!decNumberIsNaN(rhs)) result=+1;
  1.6103 +         /* here if both NaNs  */
  1.6104 +         else if (decNumberIsSNaN(lhs) && decNumberIsQNaN(rhs)) result=-1;
  1.6105 +         else if (decNumberIsQNaN(lhs) && decNumberIsSNaN(rhs)) result=+1;
  1.6106 +         else { /* both NaN or both sNaN  */
  1.6107 +          /* now it just depends on the payload  */
  1.6108 +          result=decUnitCompare(lhs->lsu, D2U(lhs->digits),
  1.6109 +                                rhs->lsu, D2U(rhs->digits), 0);
  1.6110 +          /* [Error not possible, as these are 'aligned']  */
  1.6111 +          } /* both same NaNs  */
  1.6112 +        if (decNumberIsNegative(lhs)) result=-result;
  1.6113 +        break;
  1.6114 +        } /* total order  */
  1.6115 +
  1.6116 +       else if (merged & DECSNAN);           /* sNaN -> qNaN  */
  1.6117 +       else { /* here if MIN or MAX and one or two quiet NaNs  */
  1.6118 +        /* min or max -- 754 rules ignore single NaN  */
  1.6119 +        if (!decNumberIsNaN(lhs) || !decNumberIsNaN(rhs)) {
  1.6120 +          /* just one NaN; force choice to be the non-NaN operand  */
  1.6121 +          op=COMPMAX;
  1.6122 +          if (lhs->bits & DECNAN) result=-1; /* pick rhs  */
  1.6123 +                             else result=+1; /* pick lhs  */
  1.6124 +          break;
  1.6125 +          }
  1.6126 +        } /* max or min  */
  1.6127 +      op=COMPNAN;                            /* use special path  */
  1.6128 +      decNaNs(res, lhs, rhs, set, status);   /* propagate NaN  */
  1.6129 +      break;
  1.6130 +      }
  1.6131 +    /* have numbers  */
  1.6132 +    if (op==COMPMAXMAG || op==COMPMINMAG) result=decCompare(lhs, rhs, 1);
  1.6133 +     else result=decCompare(lhs, rhs, 0);    /* sign matters  */
  1.6134 +    } while(0);                              /* end protected  */
  1.6135 +
  1.6136 +  if (result==BADINT) *status|=DEC_Insufficient_storage; /* rare  */
  1.6137 +   else {
  1.6138 +    if (op==COMPARE || op==COMPSIG ||op==COMPTOTAL) { /* returning signum  */
  1.6139 +      if (op==COMPTOTAL && result==0) {
  1.6140 +        /* operands are numerically equal or same NaN (and same sign,  */
  1.6141 +        /* tested first); if identical, leave result 0  */
  1.6142 +        if (lhs->exponent!=rhs->exponent) {
  1.6143 +          if (lhs->exponent<rhs->exponent) result=-1;
  1.6144 +           else result=+1;
  1.6145 +          if (decNumberIsNegative(lhs)) result=-result;
  1.6146 +          } /* lexp!=rexp  */
  1.6147 +        } /* total-order by exponent  */
  1.6148 +      uprv_decNumberZero(res);               /* [always a valid result]  */
  1.6149 +      if (result!=0) {                  /* must be -1 or +1  */
  1.6150 +        *res->lsu=1;
  1.6151 +        if (result<0) res->bits=DECNEG;
  1.6152 +        }
  1.6153 +      }
  1.6154 +     else if (op==COMPNAN);             /* special, drop through  */
  1.6155 +     else {                             /* MAX or MIN, non-NaN result  */
  1.6156 +      Int residue=0;                    /* rounding accumulator  */
  1.6157 +      /* choose the operand for the result  */
  1.6158 +      const decNumber *choice;
  1.6159 +      if (result==0) { /* operands are numerically equal  */
  1.6160 +        /* choose according to sign then exponent (see 754)  */
  1.6161 +        uByte slhs=(lhs->bits & DECNEG);
  1.6162 +        uByte srhs=(rhs->bits & DECNEG);
  1.6163 +        #if DECSUBSET
  1.6164 +        if (!set->extended) {           /* subset: force left-hand  */
  1.6165 +          op=COMPMAX;
  1.6166 +          result=+1;
  1.6167 +          }
  1.6168 +        else
  1.6169 +        #endif
  1.6170 +        if (slhs!=srhs) {          /* signs differ  */
  1.6171 +          if (slhs) result=-1;     /* rhs is max  */
  1.6172 +               else result=+1;     /* lhs is max  */
  1.6173 +          }
  1.6174 +         else if (slhs && srhs) {  /* both negative  */
  1.6175 +          if (lhs->exponent<rhs->exponent) result=+1;
  1.6176 +                                      else result=-1;
  1.6177 +          /* [if equal, use lhs, technically identical]  */
  1.6178 +          }
  1.6179 +         else {                    /* both positive  */
  1.6180 +          if (lhs->exponent>rhs->exponent) result=+1;
  1.6181 +                                      else result=-1;
  1.6182 +          /* [ditto]  */
  1.6183 +          }
  1.6184 +        } /* numerically equal  */
  1.6185 +      /* here result will be non-0; reverse if looking for MIN  */
  1.6186 +      if (op==COMPMIN || op==COMPMINMAG) result=-result;
  1.6187 +      choice=(result>0 ? lhs : rhs);    /* choose  */
  1.6188 +      /* copy chosen to result, rounding if need be  */
  1.6189 +      decCopyFit(res, choice, set, &residue, status);
  1.6190 +      decFinish(res, set, &residue, status);
  1.6191 +      }
  1.6192 +    }
  1.6193 +  #if DECSUBSET
  1.6194 +  if (allocrhs!=NULL) free(allocrhs);   /* free any storage used  */
  1.6195 +  if (alloclhs!=NULL) free(alloclhs);   /* ..  */
  1.6196 +  #endif
  1.6197 +  return res;
  1.6198 +  } /* decCompareOp  */
  1.6199 +
  1.6200 +/* ------------------------------------------------------------------ */
  1.6201 +/* decCompare -- compare two decNumbers by numerical value            */
  1.6202 +/*                                                                    */
  1.6203 +/*  This routine compares A ? B without altering them.                */
  1.6204 +/*                                                                    */
  1.6205 +/*  Arg1 is A, a decNumber which is not a NaN                         */
  1.6206 +/*  Arg2 is B, a decNumber which is not a NaN                         */
  1.6207 +/*  Arg3 is 1 for a sign-independent compare, 0 otherwise             */
  1.6208 +/*                                                                    */
  1.6209 +/*  returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure   */
  1.6210 +/*  (the only possible failure is an allocation error)                */
  1.6211 +/* ------------------------------------------------------------------ */
  1.6212 +static Int decCompare(const decNumber *lhs, const decNumber *rhs,
  1.6213 +                      Flag abs_c) {
  1.6214 +  Int   result;                    /* result value  */
  1.6215 +  Int   sigr;                      /* rhs signum  */
  1.6216 +  Int   compare;                   /* work  */
  1.6217 +
  1.6218 +  result=1;                                  /* assume signum(lhs)  */
  1.6219 +  if (ISZERO(lhs)) result=0;
  1.6220 +  if (abs_c) {
  1.6221 +    if (ISZERO(rhs)) return result;          /* LHS wins or both 0  */
  1.6222 +    /* RHS is non-zero  */
  1.6223 +    if (result==0) return -1;                /* LHS is 0; RHS wins  */
  1.6224 +    /* [here, both non-zero, result=1]  */
  1.6225 +    }
  1.6226 +   else {                                    /* signs matter  */
  1.6227 +    if (result && decNumberIsNegative(lhs)) result=-1;
  1.6228 +    sigr=1;                                  /* compute signum(rhs)  */
  1.6229 +    if (ISZERO(rhs)) sigr=0;
  1.6230 +     else if (decNumberIsNegative(rhs)) sigr=-1;
  1.6231 +    if (result > sigr) return +1;            /* L > R, return 1  */
  1.6232 +    if (result < sigr) return -1;            /* L < R, return -1  */
  1.6233 +    if (result==0) return 0;                   /* both 0  */
  1.6234 +    }
  1.6235 +
  1.6236 +  /* signums are the same; both are non-zero  */
  1.6237 +  if ((lhs->bits | rhs->bits) & DECINF) {    /* one or more infinities  */
  1.6238 +    if (decNumberIsInfinite(rhs)) {
  1.6239 +      if (decNumberIsInfinite(lhs)) result=0;/* both infinite  */
  1.6240 +       else result=-result;                  /* only rhs infinite  */
  1.6241 +      }
  1.6242 +    return result;
  1.6243 +    }
  1.6244 +  /* must compare the coefficients, allowing for exponents  */
  1.6245 +  if (lhs->exponent>rhs->exponent) {         /* LHS exponent larger  */
  1.6246 +    /* swap sides, and sign  */
  1.6247 +    const decNumber *temp=lhs;
  1.6248 +    lhs=rhs;
  1.6249 +    rhs=temp;
  1.6250 +    result=-result;
  1.6251 +    }
  1.6252 +  compare=decUnitCompare(lhs->lsu, D2U(lhs->digits),
  1.6253 +                         rhs->lsu, D2U(rhs->digits),
  1.6254 +                         rhs->exponent-lhs->exponent);
  1.6255 +  if (compare!=BADINT) compare*=result;      /* comparison succeeded  */
  1.6256 +  return compare;
  1.6257 +  } /* decCompare  */
  1.6258 +
  1.6259 +/* ------------------------------------------------------------------ */
  1.6260 +/* decUnitCompare -- compare two >=0 integers in Unit arrays          */
  1.6261 +/*                                                                    */
  1.6262 +/*  This routine compares A ? B*10**E where A and B are unit arrays   */
  1.6263 +/*  A is a plain integer                                              */
  1.6264 +/*  B has an exponent of E (which must be non-negative)               */
  1.6265 +/*                                                                    */
  1.6266 +/*  Arg1 is A first Unit (lsu)                                        */
  1.6267 +/*  Arg2 is A length in Units                                         */
  1.6268 +/*  Arg3 is B first Unit (lsu)                                        */
  1.6269 +/*  Arg4 is B length in Units                                         */
  1.6270 +/*  Arg5 is E (0 if the units are aligned)                            */
  1.6271 +/*                                                                    */
  1.6272 +/*  returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure   */
  1.6273 +/*  (the only possible failure is an allocation error, which can      */
  1.6274 +/*  only occur if E!=0)                                               */
  1.6275 +/* ------------------------------------------------------------------ */
  1.6276 +static Int decUnitCompare(const Unit *a, Int alength,
  1.6277 +                          const Unit *b, Int blength, Int exp) {
  1.6278 +  Unit  *acc;                      /* accumulator for result  */
  1.6279 +  Unit  accbuff[SD2U(DECBUFFER*2+1)]; /* local buffer  */
  1.6280 +  Unit  *allocacc=NULL;            /* -> allocated acc buffer, iff allocated  */
  1.6281 +  Int   accunits, need;            /* units in use or needed for acc  */
  1.6282 +  const Unit *l, *r, *u;           /* work  */
  1.6283 +  Int   expunits, exprem, result;  /* ..  */
  1.6284 +
  1.6285 +  if (exp==0) {                    /* aligned; fastpath  */
  1.6286 +    if (alength>blength) return 1;
  1.6287 +    if (alength<blength) return -1;
  1.6288 +    /* same number of units in both -- need unit-by-unit compare  */
  1.6289 +    l=a+alength-1;
  1.6290 +    r=b+alength-1;
  1.6291 +    for (;l>=a; l--, r--) {
  1.6292 +      if (*l>*r) return 1;
  1.6293 +      if (*l<*r) return -1;
  1.6294 +      }
  1.6295 +    return 0;                      /* all units match  */
  1.6296 +    } /* aligned  */
  1.6297 +
  1.6298 +  /* Unaligned.  If one is >1 unit longer than the other, padded  */
  1.6299 +  /* approximately, then can return easily  */
  1.6300 +  if (alength>blength+(Int)D2U(exp)) return 1;
  1.6301 +  if (alength+1<blength+(Int)D2U(exp)) return -1;
  1.6302 +
  1.6303 +  /* Need to do a real subtract.  For this, a result buffer is needed  */
  1.6304 +  /* even though only the sign is of interest.  Its length needs  */
  1.6305 +  /* to be the larger of alength and padded blength, +2  */
  1.6306 +  need=blength+D2U(exp);                /* maximum real length of B  */
  1.6307 +  if (need<alength) need=alength;
  1.6308 +  need+=2;
  1.6309 +  acc=accbuff;                          /* assume use local buffer  */
  1.6310 +  if (need*sizeof(Unit)>sizeof(accbuff)) {
  1.6311 +    allocacc=(Unit *)malloc(need*sizeof(Unit));
  1.6312 +    if (allocacc==NULL) return BADINT;  /* hopeless -- abandon  */
  1.6313 +    acc=allocacc;
  1.6314 +    }
  1.6315 +  /* Calculate units and remainder from exponent.  */
  1.6316 +  expunits=exp/DECDPUN;
  1.6317 +  exprem=exp%DECDPUN;
  1.6318 +  /* subtract [A+B*(-m)]  */
  1.6319 +  accunits=decUnitAddSub(a, alength, b, blength, expunits, acc,
  1.6320 +                         -(Int)powers[exprem]);
  1.6321 +  /* [UnitAddSub result may have leading zeros, even on zero]  */
  1.6322 +  if (accunits<0) result=-1;            /* negative result  */
  1.6323 +   else {                               /* non-negative result  */
  1.6324 +    /* check units of the result before freeing any storage  */
  1.6325 +    for (u=acc; u<acc+accunits-1 && *u==0;) u++;
  1.6326 +    result=(*u==0 ? 0 : +1);
  1.6327 +    }
  1.6328 +  /* clean up and return the result  */
  1.6329 +  if (allocacc!=NULL) free(allocacc);   /* drop any storage used  */
  1.6330 +  return result;
  1.6331 +  } /* decUnitCompare  */
  1.6332 +
  1.6333 +/* ------------------------------------------------------------------ */
  1.6334 +/* decUnitAddSub -- add or subtract two >=0 integers in Unit arrays   */
  1.6335 +/*                                                                    */
  1.6336 +/*  This routine performs the calculation:                            */
  1.6337 +/*                                                                    */
  1.6338 +/*  C=A+(B*M)                                                         */
  1.6339 +/*                                                                    */
  1.6340 +/*  Where M is in the range -DECDPUNMAX through +DECDPUNMAX.          */
  1.6341 +/*                                                                    */
  1.6342 +/*  A may be shorter or longer than B.                                */
  1.6343 +/*                                                                    */
  1.6344 +/*  Leading zeros are not removed after a calculation.  The result is */
  1.6345 +/*  either the same length as the longer of A and B (adding any       */
  1.6346 +/*  shift), or one Unit longer than that (if a Unit carry occurred).  */
  1.6347 +/*                                                                    */
  1.6348 +/*  A and B content are not altered unless C is also A or B.          */
  1.6349 +/*  C may be the same array as A or B, but only if no zero padding is */
  1.6350 +/*  requested (that is, C may be B only if bshift==0).                */
  1.6351 +/*  C is filled from the lsu; only those units necessary to complete  */
  1.6352 +/*  the calculation are referenced.                                   */
  1.6353 +/*                                                                    */
  1.6354 +/*  Arg1 is A first Unit (lsu)                                        */
  1.6355 +/*  Arg2 is A length in Units                                         */
  1.6356 +/*  Arg3 is B first Unit (lsu)                                        */
  1.6357 +/*  Arg4 is B length in Units                                         */
  1.6358 +/*  Arg5 is B shift in Units  (>=0; pads with 0 units if positive)    */
  1.6359 +/*  Arg6 is C first Unit (lsu)                                        */
  1.6360 +/*  Arg7 is M, the multiplier                                         */
  1.6361 +/*                                                                    */
  1.6362 +/*  returns the count of Units written to C, which will be non-zero   */
  1.6363 +/*  and negated if the result is negative.  That is, the sign of the  */
  1.6364 +/*  returned Int is the sign of the result (positive for zero) and    */
  1.6365 +/*  the absolute value of the Int is the count of Units.              */
  1.6366 +/*                                                                    */
  1.6367 +/*  It is the caller's responsibility to make sure that C size is     */
  1.6368 +/*  safe, allowing space if necessary for a one-Unit carry.           */
  1.6369 +/*                                                                    */
  1.6370 +/*  This routine is severely performance-critical; *any* change here  */
  1.6371 +/*  must be measured (timed) to assure no performance degradation.    */
  1.6372 +/*  In particular, trickery here tends to be counter-productive, as   */
  1.6373 +/*  increased complexity of code hurts register optimizations on      */
  1.6374 +/*  register-poor architectures.  Avoiding divisions is nearly        */
  1.6375 +/*  always a Good Idea, however.                                      */
  1.6376 +/*                                                                    */
  1.6377 +/* Special thanks to Rick McGuire (IBM Cambridge, MA) and Dave Clark  */
  1.6378 +/* (IBM Warwick, UK) for some of the ideas used in this routine.      */
  1.6379 +/* ------------------------------------------------------------------ */
  1.6380 +static Int decUnitAddSub(const Unit *a, Int alength,
  1.6381 +                         const Unit *b, Int blength, Int bshift,
  1.6382 +                         Unit *c, Int m) {
  1.6383 +  const Unit *alsu=a;              /* A lsu [need to remember it]  */
  1.6384 +  Unit *clsu=c;                    /* C ditto  */
  1.6385 +  Unit *minC;                      /* low water mark for C  */
  1.6386 +  Unit *maxC;                      /* high water mark for C  */
  1.6387 +  eInt carry=0;                    /* carry integer (could be Long)  */
  1.6388 +  Int  add;                        /* work  */
  1.6389 +  #if DECDPUN<=4                   /* myriadal, millenary, etc.  */
  1.6390 +  Int  est;                        /* estimated quotient  */
  1.6391 +  #endif
  1.6392 +
  1.6393 +  #if DECTRACE
  1.6394 +  if (alength<1 || blength<1)
  1.6395 +    printf("decUnitAddSub: alen blen m %ld %ld [%ld]\n", alength, blength, m);
  1.6396 +  #endif
  1.6397 +
  1.6398 +  maxC=c+alength;                  /* A is usually the longer  */
  1.6399 +  minC=c+blength;                  /* .. and B the shorter  */
  1.6400 +  if (bshift!=0) {                 /* B is shifted; low As copy across  */
  1.6401 +    minC+=bshift;
  1.6402 +    /* if in place [common], skip copy unless there's a gap [rare]  */
  1.6403 +    if (a==c && bshift<=alength) {
  1.6404 +      c+=bshift;
  1.6405 +      a+=bshift;
  1.6406 +      }
  1.6407 +     else for (; c<clsu+bshift; a++, c++) {  /* copy needed  */
  1.6408 +      if (a<alsu+alength) *c=*a;
  1.6409 +       else *c=0;
  1.6410 +      }
  1.6411 +    }
  1.6412 +  if (minC>maxC) { /* swap  */
  1.6413 +    Unit *hold=minC;
  1.6414 +    minC=maxC;
  1.6415 +    maxC=hold;
  1.6416 +    }
  1.6417 +
  1.6418 +  /* For speed, do the addition as two loops; the first where both A  */
  1.6419 +  /* and B contribute, and the second (if necessary) where only one or  */
  1.6420 +  /* other of the numbers contribute.  */
  1.6421 +  /* Carry handling is the same (i.e., duplicated) in each case.  */
  1.6422 +  for (; c<minC; c++) {
  1.6423 +    carry+=*a;
  1.6424 +    a++;
  1.6425 +    carry+=((eInt)*b)*m;                /* [special-casing m=1/-1  */
  1.6426 +    b++;                                /* here is not a win]  */
  1.6427 +    /* here carry is new Unit of digits; it could be +ve or -ve  */
  1.6428 +    if ((ueInt)carry<=DECDPUNMAX) {     /* fastpath 0-DECDPUNMAX  */
  1.6429 +      *c=(Unit)carry;
  1.6430 +      carry=0;
  1.6431 +      continue;
  1.6432 +      }
  1.6433 +    #if DECDPUN==4                           /* use divide-by-multiply  */
  1.6434 +      if (carry>=0) {
  1.6435 +        est=(((ueInt)carry>>11)*53687)>>18;
  1.6436 +        *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder  */
  1.6437 +        carry=est;                           /* likely quotient [89%]  */
  1.6438 +        if (*c<DECDPUNMAX+1) continue;       /* estimate was correct  */
  1.6439 +        carry++;
  1.6440 +        *c-=DECDPUNMAX+1;
  1.6441 +        continue;
  1.6442 +        }
  1.6443 +      /* negative case  */
  1.6444 +      carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive  */
  1.6445 +      est=(((ueInt)carry>>11)*53687)>>18;
  1.6446 +      *c=(Unit)(carry-est*(DECDPUNMAX+1));
  1.6447 +      carry=est-(DECDPUNMAX+1);              /* correctly negative  */
  1.6448 +      if (*c<DECDPUNMAX+1) continue;         /* was OK  */
  1.6449 +      carry++;
  1.6450 +      *c-=DECDPUNMAX+1;
  1.6451 +    #elif DECDPUN==3
  1.6452 +      if (carry>=0) {
  1.6453 +        est=(((ueInt)carry>>3)*16777)>>21;
  1.6454 +        *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder  */
  1.6455 +        carry=est;                           /* likely quotient [99%]  */
  1.6456 +        if (*c<DECDPUNMAX+1) continue;       /* estimate was correct  */
  1.6457 +        carry++;
  1.6458 +        *c-=DECDPUNMAX+1;
  1.6459 +        continue;
  1.6460 +        }
  1.6461 +      /* negative case  */
  1.6462 +      carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive  */
  1.6463 +      est=(((ueInt)carry>>3)*16777)>>21;
  1.6464 +      *c=(Unit)(carry-est*(DECDPUNMAX+1));
  1.6465 +      carry=est-(DECDPUNMAX+1);              /* correctly negative  */
  1.6466 +      if (*c<DECDPUNMAX+1) continue;         /* was OK  */
  1.6467 +      carry++;
  1.6468 +      *c-=DECDPUNMAX+1;
  1.6469 +    #elif DECDPUN<=2
  1.6470 +      /* Can use QUOT10 as carry <= 4 digits  */
  1.6471 +      if (carry>=0) {
  1.6472 +        est=QUOT10(carry, DECDPUN);
  1.6473 +        *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder  */
  1.6474 +        carry=est;                           /* quotient  */
  1.6475 +        continue;
  1.6476 +        }
  1.6477 +      /* negative case  */
  1.6478 +      carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive  */
  1.6479 +      est=QUOT10(carry, DECDPUN);
  1.6480 +      *c=(Unit)(carry-est*(DECDPUNMAX+1));
  1.6481 +      carry=est-(DECDPUNMAX+1);              /* correctly negative  */
  1.6482 +    #else
  1.6483 +      /* remainder operator is undefined if negative, so must test  */
  1.6484 +      if ((ueInt)carry<(DECDPUNMAX+1)*2) {   /* fastpath carry +1  */
  1.6485 +        *c=(Unit)(carry-(DECDPUNMAX+1));     /* [helps additions]  */
  1.6486 +        carry=1;
  1.6487 +        continue;
  1.6488 +        }
  1.6489 +      if (carry>=0) {
  1.6490 +        *c=(Unit)(carry%(DECDPUNMAX+1));
  1.6491 +        carry=carry/(DECDPUNMAX+1);
  1.6492 +        continue;
  1.6493 +        }
  1.6494 +      /* negative case  */
  1.6495 +      carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive  */
  1.6496 +      *c=(Unit)(carry%(DECDPUNMAX+1));
  1.6497 +      carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);
  1.6498 +    #endif
  1.6499 +    } /* c  */
  1.6500 +
  1.6501 +  /* now may have one or other to complete  */
  1.6502 +  /* [pretest to avoid loop setup/shutdown]  */
  1.6503 +  if (c<maxC) for (; c<maxC; c++) {
  1.6504 +    if (a<alsu+alength) {               /* still in A  */
  1.6505 +      carry+=*a;
  1.6506 +      a++;
  1.6507 +      }
  1.6508 +     else {                             /* inside B  */
  1.6509 +      carry+=((eInt)*b)*m;
  1.6510 +      b++;
  1.6511 +      }
  1.6512 +    /* here carry is new Unit of digits; it could be +ve or -ve and  */
  1.6513 +    /* magnitude up to DECDPUNMAX squared  */
  1.6514 +    if ((ueInt)carry<=DECDPUNMAX) {     /* fastpath 0-DECDPUNMAX  */
  1.6515 +      *c=(Unit)carry;
  1.6516 +      carry=0;
  1.6517 +      continue;
  1.6518 +      }
  1.6519 +    /* result for this unit is negative or >DECDPUNMAX  */
  1.6520 +    #if DECDPUN==4                           /* use divide-by-multiply  */
  1.6521 +      if (carry>=0) {
  1.6522 +        est=(((ueInt)carry>>11)*53687)>>18;
  1.6523 +        *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder  */
  1.6524 +        carry=est;                           /* likely quotient [79.7%]  */
  1.6525 +        if (*c<DECDPUNMAX+1) continue;       /* estimate was correct  */
  1.6526 +        carry++;
  1.6527 +        *c-=DECDPUNMAX+1;
  1.6528 +        continue;
  1.6529 +        }
  1.6530 +      /* negative case  */
  1.6531 +      carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive  */
  1.6532 +      est=(((ueInt)carry>>11)*53687)>>18;
  1.6533 +      *c=(Unit)(carry-est*(DECDPUNMAX+1));
  1.6534 +      carry=est-(DECDPUNMAX+1);              /* correctly negative  */
  1.6535 +      if (*c<DECDPUNMAX+1) continue;         /* was OK  */
  1.6536 +      carry++;
  1.6537 +      *c-=DECDPUNMAX+1;
  1.6538 +    #elif DECDPUN==3
  1.6539 +      if (carry>=0) {
  1.6540 +        est=(((ueInt)carry>>3)*16777)>>21;
  1.6541 +        *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder  */
  1.6542 +        carry=est;                           /* likely quotient [99%]  */
  1.6543 +        if (*c<DECDPUNMAX+1) continue;       /* estimate was correct  */
  1.6544 +        carry++;
  1.6545 +        *c-=DECDPUNMAX+1;
  1.6546 +        continue;
  1.6547 +        }
  1.6548 +      /* negative case  */
  1.6549 +      carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive  */
  1.6550 +      est=(((ueInt)carry>>3)*16777)>>21;
  1.6551 +      *c=(Unit)(carry-est*(DECDPUNMAX+1));
  1.6552 +      carry=est-(DECDPUNMAX+1);              /* correctly negative  */
  1.6553 +      if (*c<DECDPUNMAX+1) continue;         /* was OK  */
  1.6554 +      carry++;
  1.6555 +      *c-=DECDPUNMAX+1;
  1.6556 +    #elif DECDPUN<=2
  1.6557 +      if (carry>=0) {
  1.6558 +        est=QUOT10(carry, DECDPUN);
  1.6559 +        *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder  */
  1.6560 +        carry=est;                           /* quotient  */
  1.6561 +        continue;
  1.6562 +        }
  1.6563 +      /* negative case  */
  1.6564 +      carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive  */
  1.6565 +      est=QUOT10(carry, DECDPUN);
  1.6566 +      *c=(Unit)(carry-est*(DECDPUNMAX+1));
  1.6567 +      carry=est-(DECDPUNMAX+1);              /* correctly negative  */
  1.6568 +    #else
  1.6569 +      if ((ueInt)carry<(DECDPUNMAX+1)*2){    /* fastpath carry 1  */
  1.6570 +        *c=(Unit)(carry-(DECDPUNMAX+1));
  1.6571 +        carry=1;
  1.6572 +        continue;
  1.6573 +        }
  1.6574 +      /* remainder operator is undefined if negative, so must test  */
  1.6575 +      if (carry>=0) {
  1.6576 +        *c=(Unit)(carry%(DECDPUNMAX+1));
  1.6577 +        carry=carry/(DECDPUNMAX+1);
  1.6578 +        continue;
  1.6579 +        }
  1.6580 +      /* negative case  */
  1.6581 +      carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive  */
  1.6582 +      *c=(Unit)(carry%(DECDPUNMAX+1));
  1.6583 +      carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);
  1.6584 +    #endif
  1.6585 +    } /* c  */
  1.6586 +
  1.6587 +  /* OK, all A and B processed; might still have carry or borrow  */
  1.6588 +  /* return number of Units in the result, negated if a borrow  */
  1.6589 +  if (carry==0) return c-clsu;     /* no carry, so no more to do  */
  1.6590 +  if (carry>0) {                   /* positive carry  */
  1.6591 +    *c=(Unit)carry;                /* place as new unit  */
  1.6592 +    c++;                           /* ..  */
  1.6593 +    return c-clsu;
  1.6594 +    }
  1.6595 +  /* -ve carry: it's a borrow; complement needed  */
  1.6596 +  add=1;                           /* temporary carry...  */
  1.6597 +  for (c=clsu; c<maxC; c++) {
  1.6598 +    add=DECDPUNMAX+add-*c;
  1.6599 +    if (add<=DECDPUNMAX) {
  1.6600 +      *c=(Unit)add;
  1.6601 +      add=0;
  1.6602 +      }
  1.6603 +     else {
  1.6604 +      *c=0;
  1.6605 +      add=1;
  1.6606 +      }
  1.6607 +    }
  1.6608 +  /* add an extra unit iff it would be non-zero  */
  1.6609 +  #if DECTRACE
  1.6610 +    printf("UAS borrow: add %ld, carry %ld\n", add, carry);
  1.6611 +  #endif
  1.6612 +  if ((add-carry-1)!=0) {
  1.6613 +    *c=(Unit)(add-carry-1);
  1.6614 +    c++;                      /* interesting, include it  */
  1.6615 +    }
  1.6616 +  return clsu-c;              /* -ve result indicates borrowed  */
  1.6617 +  } /* decUnitAddSub  */
  1.6618 +
  1.6619 +/* ------------------------------------------------------------------ */
  1.6620 +/* decTrim -- trim trailing zeros or normalize                        */
  1.6621 +/*                                                                    */
  1.6622 +/*   dn is the number to trim or normalize                            */
  1.6623 +/*   set is the context to use to check for clamp                     */
  1.6624 +/*   all is 1 to remove all trailing zeros, 0 for just fraction ones  */
  1.6625 +/*   noclamp is 1 to unconditional (unclamped) trim                   */
  1.6626 +/*   dropped returns the number of discarded trailing zeros           */
  1.6627 +/*   returns dn                                                       */
  1.6628 +/*                                                                    */
  1.6629 +/* If clamp is set in the context then the number of zeros trimmed    */
  1.6630 +/* may be limited if the exponent is high.                            */
  1.6631 +/* All fields are updated as required.  This is a utility operation,  */
  1.6632 +/* so special values are unchanged and no error is possible.          */
  1.6633 +/* ------------------------------------------------------------------ */
  1.6634 +static decNumber * decTrim(decNumber *dn, decContext *set, Flag all,
  1.6635 +                           Flag noclamp, Int *dropped) {
  1.6636 +  Int   d, exp;                    /* work  */
  1.6637 +  uInt  cut;                       /* ..  */
  1.6638 +  Unit  *up;                       /* -> current Unit  */
  1.6639 +
  1.6640 +  #if DECCHECK
  1.6641 +  if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
  1.6642 +  #endif
  1.6643 +
  1.6644 +  *dropped=0;                           /* assume no zeros dropped  */
  1.6645 +  if ((dn->bits & DECSPECIAL)           /* fast exit if special ..  */
  1.6646 +    || (*dn->lsu & 0x01)) return dn;    /* .. or odd  */
  1.6647 +  if (ISZERO(dn)) {                     /* .. or 0  */
  1.6648 +    dn->exponent=0;                     /* (sign is preserved)  */
  1.6649 +    return dn;
  1.6650 +    }
  1.6651 +
  1.6652 +  /* have a finite number which is even  */
  1.6653 +  exp=dn->exponent;
  1.6654 +  cut=1;                           /* digit (1-DECDPUN) in Unit  */
  1.6655 +  up=dn->lsu;                      /* -> current Unit  */
  1.6656 +  for (d=0; d<dn->digits-1; d++) { /* [don't strip the final digit]  */
  1.6657 +    /* slice by powers  */
  1.6658 +    #if DECDPUN<=4
  1.6659 +      uInt quot=QUOT10(*up, cut);
  1.6660 +      if ((*up-quot*powers[cut])!=0) break;  /* found non-0 digit  */
  1.6661 +    #else
  1.6662 +      if (*up%powers[cut]!=0) break;         /* found non-0 digit  */
  1.6663 +    #endif
  1.6664 +    /* have a trailing 0  */
  1.6665 +    if (!all) {                    /* trimming  */
  1.6666 +      /* [if exp>0 then all trailing 0s are significant for trim]  */
  1.6667 +      if (exp<=0) {                /* if digit might be significant  */
  1.6668 +        if (exp==0) break;         /* then quit  */
  1.6669 +        exp++;                     /* next digit might be significant  */
  1.6670 +        }
  1.6671 +      }
  1.6672 +    cut++;                         /* next power  */
  1.6673 +    if (cut>DECDPUN) {             /* need new Unit  */
  1.6674 +      up++;
  1.6675 +      cut=1;
  1.6676 +      }
  1.6677 +    } /* d  */
  1.6678 +  if (d==0) return dn;             /* none to drop  */
  1.6679 +
  1.6680 +  /* may need to limit drop if clamping  */
  1.6681 +  if (set->clamp && !noclamp) {
  1.6682 +    Int maxd=set->emax-set->digits+1-dn->exponent;
  1.6683 +    if (maxd<=0) return dn;        /* nothing possible  */
  1.6684 +    if (d>maxd) d=maxd;
  1.6685 +    }
  1.6686 +
  1.6687 +  /* effect the drop  */
  1.6688 +  decShiftToLeast(dn->lsu, D2U(dn->digits), d);
  1.6689 +  dn->exponent+=d;                 /* maintain numerical value  */
  1.6690 +  dn->digits-=d;                   /* new length  */
  1.6691 +  *dropped=d;                      /* report the count  */
  1.6692 +  return dn;
  1.6693 +  } /* decTrim  */
  1.6694 +
  1.6695 +/* ------------------------------------------------------------------ */
  1.6696 +/* decReverse -- reverse a Unit array in place                        */
  1.6697 +/*                                                                    */
  1.6698 +/*   ulo    is the start of the array                                 */
  1.6699 +/*   uhi    is the end of the array (highest Unit to include)         */
  1.6700 +/*                                                                    */
  1.6701 +/* The units ulo through uhi are reversed in place (if the number     */
  1.6702 +/* of units is odd, the middle one is untouched).  Note that the      */
  1.6703 +/* digit(s) in each unit are unaffected.                              */
  1.6704 +/* ------------------------------------------------------------------ */
  1.6705 +static void decReverse(Unit *ulo, Unit *uhi) {
  1.6706 +  Unit temp;
  1.6707 +  for (; ulo<uhi; ulo++, uhi--) {
  1.6708 +    temp=*ulo;
  1.6709 +    *ulo=*uhi;
  1.6710 +    *uhi=temp;
  1.6711 +    }
  1.6712 +  return;
  1.6713 +  } /* decReverse  */
  1.6714 +
  1.6715 +/* ------------------------------------------------------------------ */
  1.6716 +/* decShiftToMost -- shift digits in array towards most significant   */
  1.6717 +/*                                                                    */
  1.6718 +/*   uar    is the array                                              */
  1.6719 +/*   digits is the count of digits in use in the array                */
  1.6720 +/*   shift  is the number of zeros to pad with (least significant);   */
  1.6721 +/*     it must be zero or positive                                    */
  1.6722 +/*                                                                    */
  1.6723 +/*   returns the new length of the integer in the array, in digits    */
  1.6724 +/*                                                                    */
  1.6725 +/* No overflow is permitted (that is, the uar array must be known to  */
  1.6726 +/* be large enough to hold the result, after shifting).               */
  1.6727 +/* ------------------------------------------------------------------ */
  1.6728 +static Int decShiftToMost(Unit *uar, Int digits, Int shift) {
  1.6729 +  Unit  *target, *source, *first;  /* work  */
  1.6730 +  Int   cut;                       /* odd 0's to add  */
  1.6731 +  uInt  next;                      /* work  */
  1.6732 +
  1.6733 +  if (shift==0) return digits;     /* [fastpath] nothing to do  */
  1.6734 +  if ((digits+shift)<=DECDPUN) {   /* [fastpath] single-unit case  */
  1.6735 +    *uar=(Unit)(*uar*powers[shift]);
  1.6736 +    return digits+shift;
  1.6737 +    }
  1.6738 +
  1.6739 +  next=0;                          /* all paths  */
  1.6740 +  source=uar+D2U(digits)-1;        /* where msu comes from  */
  1.6741 +  target=source+D2U(shift);        /* where upper part of first cut goes  */
  1.6742 +  cut=DECDPUN-MSUDIGITS(shift);    /* where to slice  */
  1.6743 +  if (cut==0) {                    /* unit-boundary case  */
  1.6744 +    for (; source>=uar; source--, target--) *target=*source;
  1.6745 +    }
  1.6746 +   else {
  1.6747 +    first=uar+D2U(digits+shift)-1; /* where msu of source will end up  */
  1.6748 +    for (; source>=uar; source--, target--) {
  1.6749 +      /* split the source Unit and accumulate remainder for next  */
  1.6750 +      #if DECDPUN<=4
  1.6751 +        uInt quot=QUOT10(*source, cut);
  1.6752 +        uInt rem=*source-quot*powers[cut];
  1.6753 +        next+=quot;
  1.6754 +      #else
  1.6755 +        uInt rem=*source%powers[cut];
  1.6756 +        next+=*source/powers[cut];
  1.6757 +      #endif
  1.6758 +      if (target<=first) *target=(Unit)next;   /* write to target iff valid  */
  1.6759 +      next=rem*powers[DECDPUN-cut];            /* save remainder for next Unit  */
  1.6760 +      }
  1.6761 +    } /* shift-move  */
  1.6762 +
  1.6763 +  /* propagate any partial unit to one below and clear the rest  */
  1.6764 +  for (; target>=uar; target--) {
  1.6765 +    *target=(Unit)next;
  1.6766 +    next=0;
  1.6767 +    }
  1.6768 +  return digits+shift;
  1.6769 +  } /* decShiftToMost  */
  1.6770 +
  1.6771 +/* ------------------------------------------------------------------ */
  1.6772 +/* decShiftToLeast -- shift digits in array towards least significant */
  1.6773 +/*                                                                    */
  1.6774 +/*   uar   is the array                                               */
  1.6775 +/*   units is length of the array, in units                           */
  1.6776 +/*   shift is the number of digits to remove from the lsu end; it     */
  1.6777 +/*     must be zero or positive and <= than units*DECDPUN.            */
  1.6778 +/*                                                                    */
  1.6779 +/*   returns the new length of the integer in the array, in units     */
  1.6780 +/*                                                                    */
  1.6781 +/* Removed digits are discarded (lost).  Units not required to hold   */
  1.6782 +/* the final result are unchanged.                                    */
  1.6783 +/* ------------------------------------------------------------------ */
  1.6784 +static Int decShiftToLeast(Unit *uar, Int units, Int shift) {
  1.6785 +  Unit  *target, *up;              /* work  */
  1.6786 +  Int   cut, count;                /* work  */
  1.6787 +  Int   quot, rem;                 /* for division  */
  1.6788 +
  1.6789 +  if (shift==0) return units;      /* [fastpath] nothing to do  */
  1.6790 +  if (shift==units*DECDPUN) {      /* [fastpath] little to do  */
  1.6791 +    *uar=0;                        /* all digits cleared gives zero  */
  1.6792 +    return 1;                      /* leaves just the one  */
  1.6793 +    }
  1.6794 +
  1.6795 +  target=uar;                      /* both paths  */
  1.6796 +  cut=MSUDIGITS(shift);
  1.6797 +  if (cut==DECDPUN) {              /* unit-boundary case; easy  */
  1.6798 +    up=uar+D2U(shift);
  1.6799 +    for (; up<uar+units; target++, up++) *target=*up;
  1.6800 +    return target-uar;
  1.6801 +    }
  1.6802 +
  1.6803 +  /* messier  */
  1.6804 +  up=uar+D2U(shift-cut);           /* source; correct to whole Units  */
  1.6805 +  count=units*DECDPUN-shift;       /* the maximum new length  */
  1.6806 +  #if DECDPUN<=4
  1.6807 +    quot=QUOT10(*up, cut);
  1.6808 +  #else
  1.6809 +    quot=*up/powers[cut];
  1.6810 +  #endif
  1.6811 +  for (; ; target++) {
  1.6812 +    *target=(Unit)quot;
  1.6813 +    count-=(DECDPUN-cut);
  1.6814 +    if (count<=0) break;
  1.6815 +    up++;
  1.6816 +    quot=*up;
  1.6817 +    #if DECDPUN<=4
  1.6818 +      quot=QUOT10(quot, cut);
  1.6819 +      rem=*up-quot*powers[cut];
  1.6820 +    #else
  1.6821 +      rem=quot%powers[cut];
  1.6822 +      quot=quot/powers[cut];
  1.6823 +    #endif
  1.6824 +    *target=(Unit)(*target+rem*powers[DECDPUN-cut]);
  1.6825 +    count-=cut;
  1.6826 +    if (count<=0) break;
  1.6827 +    }
  1.6828 +  return target-uar+1;
  1.6829 +  } /* decShiftToLeast  */
  1.6830 +
  1.6831 +#if DECSUBSET
  1.6832 +/* ------------------------------------------------------------------ */
  1.6833 +/* decRoundOperand -- round an operand  [used for subset only]        */
  1.6834 +/*                                                                    */
  1.6835 +/*   dn is the number to round (dn->digits is > set->digits)          */
  1.6836 +/*   set is the relevant context                                      */
  1.6837 +/*   status is the status accumulator                                 */
  1.6838 +/*                                                                    */
  1.6839 +/*   returns an allocated decNumber with the rounded result.          */
  1.6840 +/*                                                                    */
  1.6841 +/* lostDigits and other status may be set by this.                    */
  1.6842 +/*                                                                    */
  1.6843 +/* Since the input is an operand, it must not be modified.            */
  1.6844 +/* Instead, return an allocated decNumber, rounded as required.       */
  1.6845 +/* It is the caller's responsibility to free the allocated storage.   */
  1.6846 +/*                                                                    */
  1.6847 +/* If no storage is available then the result cannot be used, so NULL */
  1.6848 +/* is returned.                                                       */
  1.6849 +/* ------------------------------------------------------------------ */
  1.6850 +static decNumber *decRoundOperand(const decNumber *dn, decContext *set,
  1.6851 +                                  uInt *status) {
  1.6852 +  decNumber *res;                       /* result structure  */
  1.6853 +  uInt newstatus=0;                     /* status from round  */
  1.6854 +  Int  residue=0;                       /* rounding accumulator  */
  1.6855 +
  1.6856 +  /* Allocate storage for the returned decNumber, big enough for the  */
  1.6857 +  /* length specified by the context  */
  1.6858 +  res=(decNumber *)malloc(sizeof(decNumber)
  1.6859 +                          +(D2U(set->digits)-1)*sizeof(Unit));
  1.6860 +  if (res==NULL) {
  1.6861 +    *status|=DEC_Insufficient_storage;
  1.6862 +    return NULL;
  1.6863 +    }
  1.6864 +  decCopyFit(res, dn, set, &residue, &newstatus);
  1.6865 +  decApplyRound(res, set, residue, &newstatus);
  1.6866 +
  1.6867 +  /* If that set Inexact then "lost digits" is raised...  */
  1.6868 +  if (newstatus & DEC_Inexact) newstatus|=DEC_Lost_digits;
  1.6869 +  *status|=newstatus;
  1.6870 +  return res;
  1.6871 +  } /* decRoundOperand  */
  1.6872 +#endif
  1.6873 +
  1.6874 +/* ------------------------------------------------------------------ */
  1.6875 +/* decCopyFit -- copy a number, truncating the coefficient if needed  */
  1.6876 +/*                                                                    */
  1.6877 +/*   dest is the target decNumber                                     */
  1.6878 +/*   src  is the source decNumber                                     */
  1.6879 +/*   set is the context [used for length (digits) and rounding mode]  */
  1.6880 +/*   residue is the residue accumulator                               */
  1.6881 +/*   status contains the current status to be updated                 */
  1.6882 +/*                                                                    */
  1.6883 +/* (dest==src is allowed and will be a no-op if fits)                 */
  1.6884 +/* All fields are updated as required.                                */
  1.6885 +/* ------------------------------------------------------------------ */
  1.6886 +static void decCopyFit(decNumber *dest, const decNumber *src,
  1.6887 +                       decContext *set, Int *residue, uInt *status) {
  1.6888 +  dest->bits=src->bits;
  1.6889 +  dest->exponent=src->exponent;
  1.6890 +  decSetCoeff(dest, set, src->lsu, src->digits, residue, status);
  1.6891 +  } /* decCopyFit  */
  1.6892 +
  1.6893 +/* ------------------------------------------------------------------ */
  1.6894 +/* decSetCoeff -- set the coefficient of a number                     */
  1.6895 +/*                                                                    */
  1.6896 +/*   dn    is the number whose coefficient array is to be set.        */
  1.6897 +/*         It must have space for set->digits digits                  */
  1.6898 +/*   set   is the context [for size]                                  */
  1.6899 +/*   lsu   -> lsu of the source coefficient [may be dn->lsu]          */
  1.6900 +/*   len   is digits in the source coefficient [may be dn->digits]    */
  1.6901 +/*   residue is the residue accumulator.  This has values as in       */
  1.6902 +/*         decApplyRound, and will be unchanged unless the            */
  1.6903 +/*         target size is less than len.  In this case, the           */
  1.6904 +/*         coefficient is truncated and the residue is updated to     */
  1.6905 +/*         reflect the previous residue and the dropped digits.       */
  1.6906 +/*   status is the status accumulator, as usual                       */
  1.6907 +/*                                                                    */
  1.6908 +/* The coefficient may already be in the number, or it can be an      */
  1.6909 +/* external intermediate array.  If it is in the number, lsu must ==  */
  1.6910 +/* dn->lsu and len must == dn->digits.                                */
  1.6911 +/*                                                                    */
  1.6912 +/* Note that the coefficient length (len) may be < set->digits, and   */
  1.6913 +/* in this case this merely copies the coefficient (or is a no-op     */
  1.6914 +/* if dn->lsu==lsu).                                                  */
  1.6915 +/*                                                                    */
  1.6916 +/* Note also that (only internally, from decQuantizeOp and            */
  1.6917 +/* decSetSubnormal) the value of set->digits may be less than one,    */
  1.6918 +/* indicating a round to left.  This routine handles that case        */
  1.6919 +/* correctly; caller ensures space.                                   */
  1.6920 +/*                                                                    */
  1.6921 +/* dn->digits, dn->lsu (and as required), and dn->exponent are        */
  1.6922 +/* updated as necessary.   dn->bits (sign) is unchanged.              */
  1.6923 +/*                                                                    */
  1.6924 +/* DEC_Rounded status is set if any digits are discarded.             */
  1.6925 +/* DEC_Inexact status is set if any non-zero digits are discarded, or */
  1.6926 +/*                       incoming residue was non-0 (implies rounded) */
  1.6927 +/* ------------------------------------------------------------------ */
  1.6928 +/* mapping array: maps 0-9 to canonical residues, so that a residue  */
  1.6929 +/* can be adjusted in the range [-1, +1] and achieve correct rounding  */
  1.6930 +/*                             0  1  2  3  4  5  6  7  8  9  */
  1.6931 +static const uByte resmap[10]={0, 3, 3, 3, 3, 5, 7, 7, 7, 7};
  1.6932 +static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu,
  1.6933 +                        Int len, Int *residue, uInt *status) {
  1.6934 +  Int   discard;              /* number of digits to discard  */
  1.6935 +  uInt  cut;                  /* cut point in Unit  */
  1.6936 +  const Unit *up;             /* work  */
  1.6937 +  Unit  *target;              /* ..  */
  1.6938 +  Int   count;                /* ..  */
  1.6939 +  #if DECDPUN<=4
  1.6940 +  uInt  temp;                 /* ..  */
  1.6941 +  #endif
  1.6942 +
  1.6943 +  discard=len-set->digits;    /* digits to discard  */
  1.6944 +  if (discard<=0) {           /* no digits are being discarded  */
  1.6945 +    if (dn->lsu!=lsu) {       /* copy needed  */
  1.6946 +      /* copy the coefficient array to the result number; no shift needed  */
  1.6947 +      count=len;              /* avoids D2U  */
  1.6948 +      up=lsu;
  1.6949 +      for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
  1.6950 +        *target=*up;
  1.6951 +      dn->digits=len;         /* set the new length  */
  1.6952 +      }
  1.6953 +    /* dn->exponent and residue are unchanged, record any inexactitude  */
  1.6954 +    if (*residue!=0) *status|=(DEC_Inexact | DEC_Rounded);
  1.6955 +    return;
  1.6956 +    }
  1.6957 +
  1.6958 +  /* some digits must be discarded ...  */
  1.6959 +  dn->exponent+=discard;      /* maintain numerical value  */
  1.6960 +  *status|=DEC_Rounded;       /* accumulate Rounded status  */
  1.6961 +  if (*residue>1) *residue=1; /* previous residue now to right, so reduce  */
  1.6962 +
  1.6963 +  if (discard>len) {          /* everything, +1, is being discarded  */
  1.6964 +    /* guard digit is 0  */
  1.6965 +    /* residue is all the number [NB could be all 0s]  */
  1.6966 +    if (*residue<=0) {        /* not already positive  */
  1.6967 +      count=len;              /* avoids D2U  */
  1.6968 +      for (up=lsu; count>0; up++, count-=DECDPUN) if (*up!=0) { /* found non-0  */
  1.6969 +        *residue=1;
  1.6970 +        break;                /* no need to check any others  */
  1.6971 +        }
  1.6972 +      }
  1.6973 +    if (*residue!=0) *status|=DEC_Inexact; /* record inexactitude  */
  1.6974 +    *dn->lsu=0;               /* coefficient will now be 0  */
  1.6975 +    dn->digits=1;             /* ..  */
  1.6976 +    return;
  1.6977 +    } /* total discard  */
  1.6978 +
  1.6979 +  /* partial discard [most common case]  */
  1.6980 +  /* here, at least the first (most significant) discarded digit exists  */
  1.6981 +
  1.6982 +  /* spin up the number, noting residue during the spin, until get to  */
  1.6983 +  /* the Unit with the first discarded digit.  When reach it, extract  */
  1.6984 +  /* it and remember its position  */
  1.6985 +  count=0;
  1.6986 +  for (up=lsu;; up++) {
  1.6987 +    count+=DECDPUN;
  1.6988 +    if (count>=discard) break; /* full ones all checked  */
  1.6989 +    if (*up!=0) *residue=1;
  1.6990 +    } /* up  */
  1.6991 +
  1.6992 +  /* here up -> Unit with first discarded digit  */
  1.6993 +  cut=discard-(count-DECDPUN)-1;
  1.6994 +  if (cut==DECDPUN-1) {       /* unit-boundary case (fast)  */
  1.6995 +    Unit half=(Unit)powers[DECDPUN]>>1;
  1.6996 +    /* set residue directly  */
  1.6997 +    if (*up>=half) {
  1.6998 +      if (*up>half) *residue=7;
  1.6999 +      else *residue+=5;       /* add sticky bit  */
  1.7000 +      }
  1.7001 +     else { /* <half  */
  1.7002 +      if (*up!=0) *residue=3; /* [else is 0, leave as sticky bit]  */
  1.7003 +      }
  1.7004 +    if (set->digits<=0) {     /* special for Quantize/Subnormal :-(  */
  1.7005 +      *dn->lsu=0;             /* .. result is 0  */
  1.7006 +      dn->digits=1;           /* ..  */
  1.7007 +      }
  1.7008 +     else {                   /* shift to least  */
  1.7009 +      count=set->digits;      /* now digits to end up with  */
  1.7010 +      dn->digits=count;       /* set the new length  */
  1.7011 +      up++;                   /* move to next  */
  1.7012 +      /* on unit boundary, so shift-down copy loop is simple  */
  1.7013 +      for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
  1.7014 +        *target=*up;
  1.7015 +      }
  1.7016 +    } /* unit-boundary case  */
  1.7017 +
  1.7018 +   else { /* discard digit is in low digit(s), and not top digit  */
  1.7019 +    uInt  discard1;                /* first discarded digit  */
  1.7020 +    uInt  quot, rem;               /* for divisions  */
  1.7021 +    if (cut==0) quot=*up;          /* is at bottom of unit  */
  1.7022 +     else /* cut>0 */ {            /* it's not at bottom of unit  */
  1.7023 +      #if DECDPUN<=4
  1.7024 +        U_ASSERT(/* cut >= 0 &&*/ cut <= 4);
  1.7025 +        quot=QUOT10(*up, cut);
  1.7026 +        rem=*up-quot*powers[cut];
  1.7027 +      #else
  1.7028 +        rem=*up%powers[cut];
  1.7029 +        quot=*up/powers[cut];
  1.7030 +      #endif
  1.7031 +      if (rem!=0) *residue=1;
  1.7032 +      }
  1.7033 +    /* discard digit is now at bottom of quot  */
  1.7034 +    #if DECDPUN<=4
  1.7035 +      temp=(quot*6554)>>16;        /* fast /10  */
  1.7036 +      /* Vowels algorithm here not a win (9 instructions)  */
  1.7037 +      discard1=quot-X10(temp);
  1.7038 +      quot=temp;
  1.7039 +    #else
  1.7040 +      discard1=quot%10;
  1.7041 +      quot=quot/10;
  1.7042 +    #endif
  1.7043 +    /* here, discard1 is the guard digit, and residue is everything  */
  1.7044 +    /* else [use mapping array to accumulate residue safely]  */
  1.7045 +    *residue+=resmap[discard1];
  1.7046 +    cut++;                         /* update cut  */
  1.7047 +    /* here: up -> Unit of the array with bottom digit  */
  1.7048 +    /*       cut is the division point for each Unit  */
  1.7049 +    /*       quot holds the uncut high-order digits for the current unit  */
  1.7050 +    if (set->digits<=0) {          /* special for Quantize/Subnormal :-(  */
  1.7051 +      *dn->lsu=0;                  /* .. result is 0  */
  1.7052 +      dn->digits=1;                /* ..  */
  1.7053 +      }
  1.7054 +     else {                        /* shift to least needed  */
  1.7055 +      count=set->digits;           /* now digits to end up with  */
  1.7056 +      dn->digits=count;            /* set the new length  */
  1.7057 +      /* shift-copy the coefficient array to the result number  */
  1.7058 +      for (target=dn->lsu; ; target++) {
  1.7059 +        *target=(Unit)quot;
  1.7060 +        count-=(DECDPUN-cut);
  1.7061 +        if (count<=0) break;
  1.7062 +        up++;
  1.7063 +        quot=*up;
  1.7064 +        #if DECDPUN<=4
  1.7065 +          quot=QUOT10(quot, cut);
  1.7066 +          rem=*up-quot*powers[cut];
  1.7067 +        #else
  1.7068 +          rem=quot%powers[cut];
  1.7069 +          quot=quot/powers[cut];
  1.7070 +        #endif
  1.7071 +        *target=(Unit)(*target+rem*powers[DECDPUN-cut]);
  1.7072 +        count-=cut;
  1.7073 +        if (count<=0) break;
  1.7074 +        } /* shift-copy loop  */
  1.7075 +      } /* shift to least  */
  1.7076 +    } /* not unit boundary  */
  1.7077 +
  1.7078 +  if (*residue!=0) *status|=DEC_Inexact; /* record inexactitude  */
  1.7079 +  return;
  1.7080 +  } /* decSetCoeff  */
  1.7081 +
  1.7082 +/* ------------------------------------------------------------------ */
  1.7083 +/* decApplyRound -- apply pending rounding to a number                */
  1.7084 +/*                                                                    */
  1.7085 +/*   dn    is the number, with space for set->digits digits           */
  1.7086 +/*   set   is the context [for size and rounding mode]                */
  1.7087 +/*   residue indicates pending rounding, being any accumulated        */
  1.7088 +/*         guard and sticky information.  It may be:                  */
  1.7089 +/*         6-9: rounding digit is >5                                  */
  1.7090 +/*         5:   rounding digit is exactly half-way                    */
  1.7091 +/*         1-4: rounding digit is <5 and >0                           */
  1.7092 +/*         0:   the coefficient is exact                              */
  1.7093 +/*        -1:   as 1, but the hidden digits are subtractive, that     */
  1.7094 +/*              is, of the opposite sign to dn.  In this case the     */
  1.7095 +/*              coefficient must be non-0.  This case occurs when     */
  1.7096 +/*              subtracting a small number (which can be reduced to   */
  1.7097 +/*              a sticky bit); see decAddOp.                          */
  1.7098 +/*   status is the status accumulator, as usual                       */
  1.7099 +/*                                                                    */
  1.7100 +/* This routine applies rounding while keeping the length of the      */
  1.7101 +/* coefficient constant.  The exponent and status are unchanged       */
  1.7102 +/* except if:                                                         */
  1.7103 +/*                                                                    */
  1.7104 +/*   -- the coefficient was increased and is all nines (in which      */
  1.7105 +/*      case Overflow could occur, and is handled directly here so    */
  1.7106 +/*      the caller does not need to re-test for overflow)             */
  1.7107 +/*                                                                    */
  1.7108 +/*   -- the coefficient was decreased and becomes all nines (in which */
  1.7109 +/*      case Underflow could occur, and is also handled directly).    */
  1.7110 +/*                                                                    */
  1.7111 +/* All fields in dn are updated as required.                          */
  1.7112 +/*                                                                    */
  1.7113 +/* ------------------------------------------------------------------ */
  1.7114 +static void decApplyRound(decNumber *dn, decContext *set, Int residue,
  1.7115 +                          uInt *status) {
  1.7116 +  Int  bump;                  /* 1 if coefficient needs to be incremented  */
  1.7117 +                              /* -1 if coefficient needs to be decremented  */
  1.7118 +
  1.7119 +  if (residue==0) return;     /* nothing to apply  */
  1.7120 +
  1.7121 +  bump=0;                     /* assume a smooth ride  */
  1.7122 +
  1.7123 +  /* now decide whether, and how, to round, depending on mode  */
  1.7124 +  switch (set->round) {
  1.7125 +    case DEC_ROUND_05UP: {    /* round zero or five up (for reround)  */
  1.7126 +      /* This is the same as DEC_ROUND_DOWN unless there is a  */
  1.7127 +      /* positive residue and the lsd of dn is 0 or 5, in which case  */
  1.7128 +      /* it is bumped; when residue is <0, the number is therefore  */
  1.7129 +      /* bumped down unless the final digit was 1 or 6 (in which  */
  1.7130 +      /* case it is bumped down and then up -- a no-op)  */
  1.7131 +      Int lsd5=*dn->lsu%5;     /* get lsd and quintate  */
  1.7132 +      if (residue<0 && lsd5!=1) bump=-1;
  1.7133 +       else if (residue>0 && lsd5==0) bump=1;
  1.7134 +      /* [bump==1 could be applied directly; use common path for clarity]  */
  1.7135 +      break;} /* r-05  */
  1.7136 +
  1.7137 +    case DEC_ROUND_DOWN: {
  1.7138 +      /* no change, except if negative residue  */
  1.7139 +      if (residue<0) bump=-1;
  1.7140 +      break;} /* r-d  */
  1.7141 +
  1.7142 +    case DEC_ROUND_HALF_DOWN: {
  1.7143 +      if (residue>5) bump=1;
  1.7144 +      break;} /* r-h-d  */
  1.7145 +
  1.7146 +    case DEC_ROUND_HALF_EVEN: {
  1.7147 +      if (residue>5) bump=1;            /* >0.5 goes up  */
  1.7148 +       else if (residue==5) {           /* exactly 0.5000...  */
  1.7149 +        /* 0.5 goes up iff [new] lsd is odd  */
  1.7150 +        if (*dn->lsu & 0x01) bump=1;
  1.7151 +        }
  1.7152 +      break;} /* r-h-e  */
  1.7153 +
  1.7154 +    case DEC_ROUND_HALF_UP: {
  1.7155 +      if (residue>=5) bump=1;
  1.7156 +      break;} /* r-h-u  */
  1.7157 +
  1.7158 +    case DEC_ROUND_UP: {
  1.7159 +      if (residue>0) bump=1;
  1.7160 +      break;} /* r-u  */
  1.7161 +
  1.7162 +    case DEC_ROUND_CEILING: {
  1.7163 +      /* same as _UP for positive numbers, and as _DOWN for negatives  */
  1.7164 +      /* [negative residue cannot occur on 0]  */
  1.7165 +      if (decNumberIsNegative(dn)) {
  1.7166 +        if (residue<0) bump=-1;
  1.7167 +        }
  1.7168 +       else {
  1.7169 +        if (residue>0) bump=1;
  1.7170 +        }
  1.7171 +      break;} /* r-c  */
  1.7172 +
  1.7173 +    case DEC_ROUND_FLOOR: {
  1.7174 +      /* same as _UP for negative numbers, and as _DOWN for positive  */
  1.7175 +      /* [negative residue cannot occur on 0]  */
  1.7176 +      if (!decNumberIsNegative(dn)) {
  1.7177 +        if (residue<0) bump=-1;
  1.7178 +        }
  1.7179 +       else {
  1.7180 +        if (residue>0) bump=1;
  1.7181 +        }
  1.7182 +      break;} /* r-f  */
  1.7183 +
  1.7184 +    default: {      /* e.g., DEC_ROUND_MAX  */
  1.7185 +      *status|=DEC_Invalid_context;
  1.7186 +      #if DECTRACE || (DECCHECK && DECVERB)
  1.7187 +      printf("Unknown rounding mode: %d\n", set->round);
  1.7188 +      #endif
  1.7189 +      break;}
  1.7190 +    } /* switch  */
  1.7191 +
  1.7192 +  /* now bump the number, up or down, if need be  */
  1.7193 +  if (bump==0) return;                       /* no action required  */
  1.7194 +
  1.7195 +  /* Simply use decUnitAddSub unless bumping up and the number is  */
  1.7196 +  /* all nines.  In this special case set to 100... explicitly  */
  1.7197 +  /* and adjust the exponent by one (as otherwise could overflow  */
  1.7198 +  /* the array)  */
  1.7199 +  /* Similarly handle all-nines result if bumping down.  */
  1.7200 +  if (bump>0) {
  1.7201 +    Unit *up;                                /* work  */
  1.7202 +    uInt count=dn->digits;                   /* digits to be checked  */
  1.7203 +    for (up=dn->lsu; ; up++) {
  1.7204 +      if (count<=DECDPUN) {
  1.7205 +        /* this is the last Unit (the msu)  */
  1.7206 +        if (*up!=powers[count]-1) break;     /* not still 9s  */
  1.7207 +        /* here if it, too, is all nines  */
  1.7208 +        *up=(Unit)powers[count-1];           /* here 999 -> 100 etc.  */
  1.7209 +        for (up=up-1; up>=dn->lsu; up--) *up=0; /* others all to 0  */
  1.7210 +        dn->exponent++;                      /* and bump exponent  */
  1.7211 +        /* [which, very rarely, could cause Overflow...]  */
  1.7212 +        if ((dn->exponent+dn->digits)>set->emax+1) {
  1.7213 +          decSetOverflow(dn, set, status);
  1.7214 +          }
  1.7215 +        return;                              /* done  */
  1.7216 +        }
  1.7217 +      /* a full unit to check, with more to come  */
  1.7218 +      if (*up!=DECDPUNMAX) break;            /* not still 9s  */
  1.7219 +      count-=DECDPUN;
  1.7220 +      } /* up  */
  1.7221 +    } /* bump>0  */
  1.7222 +   else {                                    /* -1  */
  1.7223 +    /* here checking for a pre-bump of 1000... (leading 1, all  */
  1.7224 +    /* other digits zero)  */
  1.7225 +    Unit *up, *sup;                          /* work  */
  1.7226 +    uInt count=dn->digits;                   /* digits to be checked  */
  1.7227 +    for (up=dn->lsu; ; up++) {
  1.7228 +      if (count<=DECDPUN) {
  1.7229 +        /* this is the last Unit (the msu)  */
  1.7230 +        if (*up!=powers[count-1]) break;     /* not 100..  */
  1.7231 +        /* here if have the 1000... case  */
  1.7232 +        sup=up;                              /* save msu pointer  */
  1.7233 +        *up=(Unit)powers[count]-1;           /* here 100 in msu -> 999  */
  1.7234 +        /* others all to all-nines, too  */
  1.7235 +        for (up=up-1; up>=dn->lsu; up--) *up=(Unit)powers[DECDPUN]-1;
  1.7236 +        dn->exponent--;                      /* and bump exponent  */
  1.7237 +
  1.7238 +        /* iff the number was at the subnormal boundary (exponent=etiny)  */
  1.7239 +        /* then the exponent is now out of range, so it will in fact get  */
  1.7240 +        /* clamped to etiny and the final 9 dropped.  */
  1.7241 +        /* printf(">> emin=%d exp=%d sdig=%d\n", set->emin,  */
  1.7242 +        /*        dn->exponent, set->digits);  */
  1.7243 +        if (dn->exponent+1==set->emin-set->digits+1) {
  1.7244 +          if (count==1 && dn->digits==1) *sup=0;  /* here 9 -> 0[.9]  */
  1.7245 +           else {
  1.7246 +            *sup=(Unit)powers[count-1]-1;    /* here 999.. in msu -> 99..  */
  1.7247 +            dn->digits--;
  1.7248 +            }
  1.7249 +          dn->exponent++;
  1.7250 +          *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
  1.7251 +          }
  1.7252 +        return;                              /* done  */
  1.7253 +        }
  1.7254 +
  1.7255 +      /* a full unit to check, with more to come  */
  1.7256 +      if (*up!=0) break;                     /* not still 0s  */
  1.7257 +      count-=DECDPUN;
  1.7258 +      } /* up  */
  1.7259 +
  1.7260 +    } /* bump<0  */
  1.7261 +
  1.7262 +  /* Actual bump needed.  Do it.  */
  1.7263 +  decUnitAddSub(dn->lsu, D2U(dn->digits), uarrone, 1, 0, dn->lsu, bump);
  1.7264 +  } /* decApplyRound  */
  1.7265 +
  1.7266 +#if DECSUBSET
  1.7267 +/* ------------------------------------------------------------------ */
  1.7268 +/* decFinish -- finish processing a number                            */
  1.7269 +/*                                                                    */
  1.7270 +/*   dn is the number                                                 */
  1.7271 +/*   set is the context                                               */
  1.7272 +/*   residue is the rounding accumulator (as in decApplyRound)        */
  1.7273 +/*   status is the accumulator                                        */
  1.7274 +/*                                                                    */
  1.7275 +/* This finishes off the current number by:                           */
  1.7276 +/*    1. If not extended:                                             */
  1.7277 +/*       a. Converting a zero result to clean '0'                     */
  1.7278 +/*       b. Reducing positive exponents to 0, if would fit in digits  */
  1.7279 +/*    2. Checking for overflow and subnormals (always)                */
  1.7280 +/* Note this is just Finalize when no subset arithmetic.              */
  1.7281 +/* All fields are updated as required.                                */
  1.7282 +/* ------------------------------------------------------------------ */
  1.7283 +static void decFinish(decNumber *dn, decContext *set, Int *residue,
  1.7284 +                      uInt *status) {
  1.7285 +  if (!set->extended) {
  1.7286 +    if ISZERO(dn) {                /* value is zero  */
  1.7287 +      dn->exponent=0;              /* clean exponent ..  */
  1.7288 +      dn->bits=0;                  /* .. and sign  */
  1.7289 +      return;                      /* no error possible  */
  1.7290 +      }
  1.7291 +    if (dn->exponent>=0) {         /* non-negative exponent  */
  1.7292 +      /* >0; reduce to integer if possible  */
  1.7293 +      if (set->digits >= (dn->exponent+dn->digits)) {
  1.7294 +        dn->digits=decShiftToMost(dn->lsu, dn->digits, dn->exponent);
  1.7295 +        dn->exponent=0;
  1.7296 +        }
  1.7297 +      }
  1.7298 +    } /* !extended  */
  1.7299 +
  1.7300 +  decFinalize(dn, set, residue, status);
  1.7301 +  } /* decFinish  */
  1.7302 +#endif
  1.7303 +
  1.7304 +/* ------------------------------------------------------------------ */
  1.7305 +/* decFinalize -- final check, clamp, and round of a number           */
  1.7306 +/*                                                                    */
  1.7307 +/*   dn is the number                                                 */
  1.7308 +/*   set is the context                                               */
  1.7309 +/*   residue is the rounding accumulator (as in decApplyRound)        */
  1.7310 +/*   status is the status accumulator                                 */
  1.7311 +/*                                                                    */
  1.7312 +/* This finishes off the current number by checking for subnormal     */
  1.7313 +/* results, applying any pending rounding, checking for overflow,     */
  1.7314 +/* and applying any clamping.                                         */
  1.7315 +/* Underflow and overflow conditions are raised as appropriate.       */
  1.7316 +/* All fields are updated as required.                                */
  1.7317 +/* ------------------------------------------------------------------ */
  1.7318 +static void decFinalize(decNumber *dn, decContext *set, Int *residue,
  1.7319 +                        uInt *status) {
  1.7320 +  Int shift;                            /* shift needed if clamping  */
  1.7321 +  Int tinyexp=set->emin-dn->digits+1;   /* precalculate subnormal boundary  */
  1.7322 +
  1.7323 +  /* Must be careful, here, when checking the exponent as the  */
  1.7324 +  /* adjusted exponent could overflow 31 bits [because it may already  */
  1.7325 +  /* be up to twice the expected].  */
  1.7326 +
  1.7327 +  /* First test for subnormal.  This must be done before any final  */
  1.7328 +  /* round as the result could be rounded to Nmin or 0.  */
  1.7329 +  if (dn->exponent<=tinyexp) {          /* prefilter  */
  1.7330 +    Int comp;
  1.7331 +    decNumber nmin;
  1.7332 +    /* A very nasty case here is dn == Nmin and residue<0  */
  1.7333 +    if (dn->exponent<tinyexp) {
  1.7334 +      /* Go handle subnormals; this will apply round if needed.  */
  1.7335 +      decSetSubnormal(dn, set, residue, status);
  1.7336 +      return;
  1.7337 +      }
  1.7338 +    /* Equals case: only subnormal if dn=Nmin and negative residue  */
  1.7339 +    uprv_decNumberZero(&nmin);
  1.7340 +    nmin.lsu[0]=1;
  1.7341 +    nmin.exponent=set->emin;
  1.7342 +    comp=decCompare(dn, &nmin, 1);                /* (signless compare)  */
  1.7343 +    if (comp==BADINT) {                           /* oops  */
  1.7344 +      *status|=DEC_Insufficient_storage;          /* abandon...  */
  1.7345 +      return;
  1.7346 +      }
  1.7347 +    if (*residue<0 && comp==0) {                  /* neg residue and dn==Nmin  */
  1.7348 +      decApplyRound(dn, set, *residue, status);   /* might force down  */
  1.7349 +      decSetSubnormal(dn, set, residue, status);
  1.7350 +      return;
  1.7351 +      }
  1.7352 +    }
  1.7353 +
  1.7354 +  /* now apply any pending round (this could raise overflow).  */
  1.7355 +  if (*residue!=0) decApplyRound(dn, set, *residue, status);
  1.7356 +
  1.7357 +  /* Check for overflow [redundant in the 'rare' case] or clamp  */
  1.7358 +  if (dn->exponent<=set->emax-set->digits+1) return;   /* neither needed  */
  1.7359 +
  1.7360 +
  1.7361 +  /* here when might have an overflow or clamp to do  */
  1.7362 +  if (dn->exponent>set->emax-dn->digits+1) {           /* too big  */
  1.7363 +    decSetOverflow(dn, set, status);
  1.7364 +    return;
  1.7365 +    }
  1.7366 +  /* here when the result is normal but in clamp range  */
  1.7367 +  if (!set->clamp) return;
  1.7368 +
  1.7369 +  /* here when need to apply the IEEE exponent clamp (fold-down)  */
  1.7370 +  shift=dn->exponent-(set->emax-set->digits+1);
  1.7371 +
  1.7372 +  /* shift coefficient (if non-zero)  */
  1.7373 +  if (!ISZERO(dn)) {
  1.7374 +    dn->digits=decShiftToMost(dn->lsu, dn->digits, shift);
  1.7375 +    }
  1.7376 +  dn->exponent-=shift;   /* adjust the exponent to match  */
  1.7377 +  *status|=DEC_Clamped;  /* and record the dirty deed  */
  1.7378 +  return;
  1.7379 +  } /* decFinalize  */
  1.7380 +
  1.7381 +/* ------------------------------------------------------------------ */
  1.7382 +/* decSetOverflow -- set number to proper overflow value              */
  1.7383 +/*                                                                    */
  1.7384 +/*   dn is the number (used for sign [only] and result)               */
  1.7385 +/*   set is the context [used for the rounding mode, etc.]            */
  1.7386 +/*   status contains the current status to be updated                 */
  1.7387 +/*                                                                    */
  1.7388 +/* This sets the sign of a number and sets its value to either        */
  1.7389 +/* Infinity or the maximum finite value, depending on the sign of     */
  1.7390 +/* dn and the rounding mode, following IEEE 754 rules.                */
  1.7391 +/* ------------------------------------------------------------------ */
  1.7392 +static void decSetOverflow(decNumber *dn, decContext *set, uInt *status) {
  1.7393 +  Flag needmax=0;                  /* result is maximum finite value  */
  1.7394 +  uByte sign=dn->bits&DECNEG;      /* clean and save sign bit  */
  1.7395 +
  1.7396 +  if (ISZERO(dn)) {                /* zero does not overflow magnitude  */
  1.7397 +    Int emax=set->emax;                      /* limit value  */
  1.7398 +    if (set->clamp) emax-=set->digits-1;     /* lower if clamping  */
  1.7399 +    if (dn->exponent>emax) {                 /* clamp required  */
  1.7400 +      dn->exponent=emax;
  1.7401 +      *status|=DEC_Clamped;
  1.7402 +      }
  1.7403 +    return;
  1.7404 +    }
  1.7405 +
  1.7406 +  uprv_decNumberZero(dn);
  1.7407 +  switch (set->round) {
  1.7408 +    case DEC_ROUND_DOWN: {
  1.7409 +      needmax=1;                   /* never Infinity  */
  1.7410 +      break;} /* r-d  */
  1.7411 +    case DEC_ROUND_05UP: {
  1.7412 +      needmax=1;                   /* never Infinity  */
  1.7413 +      break;} /* r-05  */
  1.7414 +    case DEC_ROUND_CEILING: {
  1.7415 +      if (sign) needmax=1;         /* Infinity if non-negative  */
  1.7416 +      break;} /* r-c  */
  1.7417 +    case DEC_ROUND_FLOOR: {
  1.7418 +      if (!sign) needmax=1;        /* Infinity if negative  */
  1.7419 +      break;} /* r-f  */
  1.7420 +    default: break;                /* Infinity in all other cases  */
  1.7421 +    }
  1.7422 +  if (needmax) {
  1.7423 +    decSetMaxValue(dn, set);
  1.7424 +    dn->bits=sign;                 /* set sign  */
  1.7425 +    }
  1.7426 +   else dn->bits=sign|DECINF;      /* Value is +/-Infinity  */
  1.7427 +  *status|=DEC_Overflow | DEC_Inexact | DEC_Rounded;
  1.7428 +  } /* decSetOverflow  */
  1.7429 +
  1.7430 +/* ------------------------------------------------------------------ */
  1.7431 +/* decSetMaxValue -- set number to +Nmax (maximum normal value)       */
  1.7432 +/*                                                                    */
  1.7433 +/*   dn is the number to set                                          */
  1.7434 +/*   set is the context [used for digits and emax]                    */
  1.7435 +/*                                                                    */
  1.7436 +/* This sets the number to the maximum positive value.                */
  1.7437 +/* ------------------------------------------------------------------ */
  1.7438 +static void decSetMaxValue(decNumber *dn, decContext *set) {
  1.7439 +  Unit *up;                        /* work  */
  1.7440 +  Int count=set->digits;           /* nines to add  */
  1.7441 +  dn->digits=count;
  1.7442 +  /* fill in all nines to set maximum value  */
  1.7443 +  for (up=dn->lsu; ; up++) {
  1.7444 +    if (count>DECDPUN) *up=DECDPUNMAX;  /* unit full o'nines  */
  1.7445 +     else {                             /* this is the msu  */
  1.7446 +      *up=(Unit)(powers[count]-1);
  1.7447 +      break;
  1.7448 +      }
  1.7449 +    count-=DECDPUN;                /* filled those digits  */
  1.7450 +    } /* up  */
  1.7451 +  dn->bits=0;                      /* + sign  */
  1.7452 +  dn->exponent=set->emax-set->digits+1;
  1.7453 +  } /* decSetMaxValue  */
  1.7454 +
  1.7455 +/* ------------------------------------------------------------------ */
  1.7456 +/* decSetSubnormal -- process value whose exponent is <Emin           */
  1.7457 +/*                                                                    */
  1.7458 +/*   dn is the number (used as input as well as output; it may have   */
  1.7459 +/*         an allowed subnormal value, which may need to be rounded)  */
  1.7460 +/*   set is the context [used for the rounding mode]                  */
  1.7461 +/*   residue is any pending residue                                   */
  1.7462 +/*   status contains the current status to be updated                 */
  1.7463 +/*                                                                    */
  1.7464 +/* If subset mode, set result to zero and set Underflow flags.        */
  1.7465 +/*                                                                    */
  1.7466 +/* Value may be zero with a low exponent; this does not set Subnormal */
  1.7467 +/* but the exponent will be clamped to Etiny.                         */
  1.7468 +/*                                                                    */
  1.7469 +/* Otherwise ensure exponent is not out of range, and round as        */
  1.7470 +/* necessary.  Underflow is set if the result is Inexact.             */
  1.7471 +/* ------------------------------------------------------------------ */
  1.7472 +static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
  1.7473 +                            uInt *status) {
  1.7474 +  decContext workset;         /* work  */
  1.7475 +  Int        etiny, adjust;   /* ..  */
  1.7476 +
  1.7477 +  #if DECSUBSET
  1.7478 +  /* simple set to zero and 'hard underflow' for subset  */
  1.7479 +  if (!set->extended) {
  1.7480 +    uprv_decNumberZero(dn);
  1.7481 +    /* always full overflow  */
  1.7482 +    *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
  1.7483 +    return;
  1.7484 +    }
  1.7485 +  #endif
  1.7486 +
  1.7487 +  /* Full arithmetic -- allow subnormals, rounded to minimum exponent  */
  1.7488 +  /* (Etiny) if needed  */
  1.7489 +  etiny=set->emin-(set->digits-1);      /* smallest allowed exponent  */
  1.7490 +
  1.7491 +  if ISZERO(dn) {                       /* value is zero  */
  1.7492 +    /* residue can never be non-zero here  */
  1.7493 +    #if DECCHECK
  1.7494 +      if (*residue!=0) {
  1.7495 +        printf("++ Subnormal 0 residue %ld\n", (LI)*residue);
  1.7496 +        *status|=DEC_Invalid_operation;
  1.7497 +        }
  1.7498 +    #endif
  1.7499 +    if (dn->exponent<etiny) {           /* clamp required  */
  1.7500 +      dn->exponent=etiny;
  1.7501 +      *status|=DEC_Clamped;
  1.7502 +      }
  1.7503 +    return;
  1.7504 +    }
  1.7505 +
  1.7506 +  *status|=DEC_Subnormal;               /* have a non-zero subnormal  */
  1.7507 +  adjust=etiny-dn->exponent;            /* calculate digits to remove  */
  1.7508 +  if (adjust<=0) {                      /* not out of range; unrounded  */
  1.7509 +    /* residue can never be non-zero here, except in the Nmin-residue  */
  1.7510 +    /* case (which is a subnormal result), so can take fast-path here  */
  1.7511 +    /* it may already be inexact (from setting the coefficient)  */
  1.7512 +    if (*status&DEC_Inexact) *status|=DEC_Underflow;
  1.7513 +    return;
  1.7514 +    }
  1.7515 +
  1.7516 +  /* adjust>0, so need to rescale the result so exponent becomes Etiny  */
  1.7517 +  /* [this code is similar to that in rescale]  */
  1.7518 +  workset=*set;                         /* clone rounding, etc.  */
  1.7519 +  workset.digits=dn->digits-adjust;     /* set requested length  */
  1.7520 +  workset.emin-=adjust;                 /* and adjust emin to match  */
  1.7521 +  /* [note that the latter can be <1, here, similar to Rescale case]  */
  1.7522 +  decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);
  1.7523 +  decApplyRound(dn, &workset, *residue, status);
  1.7524 +
  1.7525 +  /* Use 754 default rule: Underflow is set iff Inexact  */
  1.7526 +  /* [independent of whether trapped]  */
  1.7527 +  if (*status&DEC_Inexact) *status|=DEC_Underflow;
  1.7528 +
  1.7529 +  /* if rounded up a 999s case, exponent will be off by one; adjust  */
  1.7530 +  /* back if so [it will fit, because it was shortened earlier]  */
  1.7531 +  if (dn->exponent>etiny) {
  1.7532 +    dn->digits=decShiftToMost(dn->lsu, dn->digits, 1);
  1.7533 +    dn->exponent--;                     /* (re)adjust the exponent.  */
  1.7534 +    }
  1.7535 +
  1.7536 +  /* if rounded to zero, it is by definition clamped...  */
  1.7537 +  if (ISZERO(dn)) *status|=DEC_Clamped;
  1.7538 +  } /* decSetSubnormal  */
  1.7539 +
  1.7540 +/* ------------------------------------------------------------------ */
  1.7541 +/* decCheckMath - check entry conditions for a math function          */
  1.7542 +/*                                                                    */
  1.7543 +/*   This checks the context and the operand                          */
  1.7544 +/*                                                                    */
  1.7545 +/*   rhs is the operand to check                                      */
  1.7546 +/*   set is the context to check                                      */
  1.7547 +/*   status is unchanged if both are good                             */
  1.7548 +/*                                                                    */
  1.7549 +/* returns non-zero if status is changed, 0 otherwise                 */
  1.7550 +/*                                                                    */
  1.7551 +/* Restrictions enforced:                                             */
  1.7552 +/*                                                                    */
  1.7553 +/*   digits, emax, and -emin in the context must be less than         */
  1.7554 +/*   DEC_MAX_MATH (999999), and A must be within these bounds if      */
  1.7555 +/*   non-zero.  Invalid_operation is set in the status if a           */
  1.7556 +/*   restriction is violated.                                         */
  1.7557 +/* ------------------------------------------------------------------ */
  1.7558 +static uInt decCheckMath(const decNumber *rhs, decContext *set,
  1.7559 +                         uInt *status) {
  1.7560 +  uInt save=*status;                         /* record  */
  1.7561 +  if (set->digits>DEC_MAX_MATH
  1.7562 +   || set->emax>DEC_MAX_MATH
  1.7563 +   || -set->emin>DEC_MAX_MATH) *status|=DEC_Invalid_context;
  1.7564 +   else if ((rhs->digits>DEC_MAX_MATH
  1.7565 +     || rhs->exponent+rhs->digits>DEC_MAX_MATH+1
  1.7566 +     || rhs->exponent+rhs->digits<2*(1-DEC_MAX_MATH))
  1.7567 +     && !ISZERO(rhs)) *status|=DEC_Invalid_operation;
  1.7568 +  return (*status!=save);
  1.7569 +  } /* decCheckMath  */
  1.7570 +
  1.7571 +/* ------------------------------------------------------------------ */
  1.7572 +/* decGetInt -- get integer from a number                             */
  1.7573 +/*                                                                    */
  1.7574 +/*   dn is the number [which will not be altered]                     */
  1.7575 +/*                                                                    */
  1.7576 +/*   returns one of:                                                  */
  1.7577 +/*     BADINT if there is a non-zero fraction                         */
  1.7578 +/*     the converted integer                                          */
  1.7579 +/*     BIGEVEN if the integer is even and magnitude > 2*10**9         */
  1.7580 +/*     BIGODD  if the integer is odd  and magnitude > 2*10**9         */
  1.7581 +/*                                                                    */
  1.7582 +/* This checks and gets a whole number from the input decNumber.      */
  1.7583 +/* The sign can be determined from dn by the caller when BIGEVEN or   */
  1.7584 +/* BIGODD is returned.                                                */
  1.7585 +/* ------------------------------------------------------------------ */
  1.7586 +static Int decGetInt(const decNumber *dn) {
  1.7587 +  Int  theInt;                          /* result accumulator  */
  1.7588 +  const Unit *up;                       /* work  */
  1.7589 +  Int  got;                             /* digits (real or not) processed  */
  1.7590 +  Int  ilength=dn->digits+dn->exponent; /* integral length  */
  1.7591 +  Flag neg=decNumberIsNegative(dn);     /* 1 if -ve  */
  1.7592 +
  1.7593 +  /* The number must be an integer that fits in 10 digits  */
  1.7594 +  /* Assert, here, that 10 is enough for any rescale Etiny  */
  1.7595 +  #if DEC_MAX_EMAX > 999999999
  1.7596 +    #error GetInt may need updating [for Emax]
  1.7597 +  #endif
  1.7598 +  #if DEC_MIN_EMIN < -999999999
  1.7599 +    #error GetInt may need updating [for Emin]
  1.7600 +  #endif
  1.7601 +  if (ISZERO(dn)) return 0;             /* zeros are OK, with any exponent  */
  1.7602 +
  1.7603 +  up=dn->lsu;                           /* ready for lsu  */
  1.7604 +  theInt=0;                             /* ready to accumulate  */
  1.7605 +  if (dn->exponent>=0) {                /* relatively easy  */
  1.7606 +    /* no fractional part [usual]; allow for positive exponent  */
  1.7607 +    got=dn->exponent;
  1.7608 +    }
  1.7609 +   else { /* -ve exponent; some fractional part to check and discard  */
  1.7610 +    Int count=-dn->exponent;            /* digits to discard  */
  1.7611 +    /* spin up whole units until reach the Unit with the unit digit  */
  1.7612 +    for (; count>=DECDPUN; up++) {
  1.7613 +      if (*up!=0) return BADINT;        /* non-zero Unit to discard  */
  1.7614 +      count-=DECDPUN;
  1.7615 +      }
  1.7616 +    if (count==0) got=0;                /* [a multiple of DECDPUN]  */
  1.7617 +     else {                             /* [not multiple of DECDPUN]  */
  1.7618 +      Int rem;                          /* work  */
  1.7619 +      /* slice off fraction digits and check for non-zero  */
  1.7620 +      #if DECDPUN<=4
  1.7621 +        theInt=QUOT10(*up, count);
  1.7622 +        rem=*up-theInt*powers[count];
  1.7623 +      #else
  1.7624 +        rem=*up%powers[count];          /* slice off discards  */
  1.7625 +        theInt=*up/powers[count];
  1.7626 +      #endif
  1.7627 +      if (rem!=0) return BADINT;        /* non-zero fraction  */
  1.7628 +      /* it looks good  */
  1.7629 +      got=DECDPUN-count;                /* number of digits so far  */
  1.7630 +      up++;                             /* ready for next  */
  1.7631 +      }
  1.7632 +    }
  1.7633 +  /* now it's known there's no fractional part  */
  1.7634 +
  1.7635 +  /* tricky code now, to accumulate up to 9.3 digits  */
  1.7636 +  if (got==0) {theInt=*up; got+=DECDPUN; up++;} /* ensure lsu is there  */
  1.7637 +
  1.7638 +  if (ilength<11) {
  1.7639 +    Int save=theInt;
  1.7640 +    /* collect any remaining unit(s)  */
  1.7641 +    for (; got<ilength; up++) {
  1.7642 +      theInt+=*up*powers[got];
  1.7643 +      got+=DECDPUN;
  1.7644 +      }
  1.7645 +    if (ilength==10) {                  /* need to check for wrap  */
  1.7646 +      if (theInt/(Int)powers[got-DECDPUN]!=(Int)*(up-1)) ilength=11;
  1.7647 +         /* [that test also disallows the BADINT result case]  */
  1.7648 +       else if (neg && theInt>1999999997) ilength=11;
  1.7649 +       else if (!neg && theInt>999999999) ilength=11;
  1.7650 +      if (ilength==11) theInt=save;     /* restore correct low bit  */
  1.7651 +      }
  1.7652 +    }
  1.7653 +
  1.7654 +  if (ilength>10) {                     /* too big  */
  1.7655 +    if (theInt&1) return BIGODD;        /* bottom bit 1  */
  1.7656 +    return BIGEVEN;                     /* bottom bit 0  */
  1.7657 +    }
  1.7658 +
  1.7659 +  if (neg) theInt=-theInt;              /* apply sign  */
  1.7660 +  return theInt;
  1.7661 +  } /* decGetInt  */
  1.7662 +
  1.7663 +/* ------------------------------------------------------------------ */
  1.7664 +/* decDecap -- decapitate the coefficient of a number                 */
  1.7665 +/*                                                                    */
  1.7666 +/*   dn   is the number to be decapitated                             */
  1.7667 +/*   drop is the number of digits to be removed from the left of dn;  */
  1.7668 +/*     this must be <= dn->digits (if equal, the coefficient is       */
  1.7669 +/*     set to 0)                                                      */
  1.7670 +/*                                                                    */
  1.7671 +/* Returns dn; dn->digits will be <= the initial digits less drop     */
  1.7672 +/* (after removing drop digits there may be leading zero digits       */
  1.7673 +/* which will also be removed).  Only dn->lsu and dn->digits change.  */
  1.7674 +/* ------------------------------------------------------------------ */
  1.7675 +static decNumber *decDecap(decNumber *dn, Int drop) {
  1.7676 +  Unit *msu;                            /* -> target cut point  */
  1.7677 +  Int cut;                              /* work  */
  1.7678 +  if (drop>=dn->digits) {               /* losing the whole thing  */
  1.7679 +    #if DECCHECK
  1.7680 +    if (drop>dn->digits)
  1.7681 +      printf("decDecap called with drop>digits [%ld>%ld]\n",
  1.7682 +             (LI)drop, (LI)dn->digits);
  1.7683 +    #endif
  1.7684 +    dn->lsu[0]=0;
  1.7685 +    dn->digits=1;
  1.7686 +    return dn;
  1.7687 +    }
  1.7688 +  msu=dn->lsu+D2U(dn->digits-drop)-1;   /* -> likely msu  */
  1.7689 +  cut=MSUDIGITS(dn->digits-drop);       /* digits to be in use in msu  */
  1.7690 +  if (cut!=DECDPUN) *msu%=powers[cut];  /* clear left digits  */
  1.7691 +  /* that may have left leading zero digits, so do a proper count...  */
  1.7692 +  dn->digits=decGetDigits(dn->lsu, msu-dn->lsu+1);
  1.7693 +  return dn;
  1.7694 +  } /* decDecap  */
  1.7695 +
  1.7696 +/* ------------------------------------------------------------------ */
  1.7697 +/* decBiStr -- compare string with pairwise options                   */
  1.7698 +/*                                                                    */
  1.7699 +/*   targ is the string to compare                                    */
  1.7700 +/*   str1 is one of the strings to compare against (length may be 0)  */
  1.7701 +/*   str2 is the other; it must be the same length as str1            */
  1.7702 +/*                                                                    */
  1.7703 +/*   returns 1 if strings compare equal, (that is, it is the same     */
  1.7704 +/*   length as str1 and str2, and each character of targ is in either */
  1.7705 +/*   str1 or str2 in the corresponding position), or 0 otherwise      */
  1.7706 +/*                                                                    */
  1.7707 +/* This is used for generic caseless compare, including the awkward   */
  1.7708 +/* case of the Turkish dotted and dotless Is.  Use as (for example):  */
  1.7709 +/*   if (decBiStr(test, "mike", "MIKE")) ...                          */
  1.7710 +/* ------------------------------------------------------------------ */
  1.7711 +static Flag decBiStr(const char *targ, const char *str1, const char *str2) {
  1.7712 +  for (;;targ++, str1++, str2++) {
  1.7713 +    if (*targ!=*str1 && *targ!=*str2) return 0;
  1.7714 +    /* *targ has a match in one (or both, if terminator)  */
  1.7715 +    if (*targ=='\0') break;
  1.7716 +    } /* forever  */
  1.7717 +  return 1;
  1.7718 +  } /* decBiStr  */
  1.7719 +
  1.7720 +/* ------------------------------------------------------------------ */
  1.7721 +/* decNaNs -- handle NaN operand or operands                          */
  1.7722 +/*                                                                    */
  1.7723 +/*   res     is the result number                                     */
  1.7724 +/*   lhs     is the first operand                                     */
  1.7725 +/*   rhs     is the second operand, or NULL if none                   */
  1.7726 +/*   context is used to limit payload length                          */
  1.7727 +/*   status  contains the current status                              */
  1.7728 +/*   returns res in case convenient                                   */
  1.7729 +/*                                                                    */
  1.7730 +/* Called when one or both operands is a NaN, and propagates the      */
  1.7731 +/* appropriate result to res.  When an sNaN is found, it is changed   */
  1.7732 +/* to a qNaN and Invalid operation is set.                            */
  1.7733 +/* ------------------------------------------------------------------ */
  1.7734 +static decNumber * decNaNs(decNumber *res, const decNumber *lhs,
  1.7735 +                           const decNumber *rhs, decContext *set,
  1.7736 +                           uInt *status) {
  1.7737 +  /* This decision tree ends up with LHS being the source pointer,  */
  1.7738 +  /* and status updated if need be  */
  1.7739 +  if (lhs->bits & DECSNAN)
  1.7740 +    *status|=DEC_Invalid_operation | DEC_sNaN;
  1.7741 +   else if (rhs==NULL);
  1.7742 +   else if (rhs->bits & DECSNAN) {
  1.7743 +    lhs=rhs;
  1.7744 +    *status|=DEC_Invalid_operation | DEC_sNaN;
  1.7745 +    }
  1.7746 +   else if (lhs->bits & DECNAN);
  1.7747 +   else lhs=rhs;
  1.7748 +
  1.7749 +  /* propagate the payload  */
  1.7750 +  if (lhs->digits<=set->digits) uprv_decNumberCopy(res, lhs); /* easy  */
  1.7751 +   else { /* too long  */
  1.7752 +    const Unit *ul;
  1.7753 +    Unit *ur, *uresp1;
  1.7754 +    /* copy safe number of units, then decapitate  */
  1.7755 +    res->bits=lhs->bits;                /* need sign etc.  */
  1.7756 +    uresp1=res->lsu+D2U(set->digits);
  1.7757 +    for (ur=res->lsu, ul=lhs->lsu; ur<uresp1; ur++, ul++) *ur=*ul;
  1.7758 +    res->digits=D2U(set->digits)*DECDPUN;
  1.7759 +    /* maybe still too long  */
  1.7760 +    if (res->digits>set->digits) decDecap(res, res->digits-set->digits);
  1.7761 +    }
  1.7762 +
  1.7763 +  res->bits&=~DECSNAN;        /* convert any sNaN to NaN, while  */
  1.7764 +  res->bits|=DECNAN;          /* .. preserving sign  */
  1.7765 +  res->exponent=0;            /* clean exponent  */
  1.7766 +                              /* [coefficient was copied/decapitated]  */
  1.7767 +  return res;
  1.7768 +  } /* decNaNs  */
  1.7769 +
  1.7770 +/* ------------------------------------------------------------------ */
  1.7771 +/* decStatus -- apply non-zero status                                 */
  1.7772 +/*                                                                    */
  1.7773 +/*   dn     is the number to set if error                             */
  1.7774 +/*   status contains the current status (not yet in context)          */
  1.7775 +/*   set    is the context                                            */
  1.7776 +/*                                                                    */
  1.7777 +/* If the status is an error status, the number is set to a NaN,      */
  1.7778 +/* unless the error was an overflow, divide-by-zero, or underflow,    */
  1.7779 +/* in which case the number will have already been set.               */
  1.7780 +/*                                                                    */
  1.7781 +/* The context status is then updated with the new status.  Note that */
  1.7782 +/* this may raise a signal, so control may never return from this     */
  1.7783 +/* routine (hence resources must be recovered before it is called).   */
  1.7784 +/* ------------------------------------------------------------------ */
  1.7785 +static void decStatus(decNumber *dn, uInt status, decContext *set) {
  1.7786 +  if (status & DEC_NaNs) {              /* error status -> NaN  */
  1.7787 +    /* if cause was an sNaN, clear and propagate [NaN is already set up]  */
  1.7788 +    if (status & DEC_sNaN) status&=~DEC_sNaN;
  1.7789 +     else {
  1.7790 +      uprv_decNumberZero(dn);                /* other error: clean throughout  */
  1.7791 +      dn->bits=DECNAN;                  /* and make a quiet NaN  */
  1.7792 +      }
  1.7793 +    }
  1.7794 +  uprv_decContextSetStatus(set, status);     /* [may not return]  */
  1.7795 +  return;
  1.7796 +  } /* decStatus  */
  1.7797 +
  1.7798 +/* ------------------------------------------------------------------ */
  1.7799 +/* decGetDigits -- count digits in a Units array                      */
  1.7800 +/*                                                                    */
  1.7801 +/*   uar is the Unit array holding the number (this is often an       */
  1.7802 +/*          accumulator of some sort)                                 */
  1.7803 +/*   len is the length of the array in units [>=1]                    */
  1.7804 +/*                                                                    */
  1.7805 +/*   returns the number of (significant) digits in the array          */
  1.7806 +/*                                                                    */
  1.7807 +/* All leading zeros are excluded, except the last if the array has   */
  1.7808 +/* only zero Units.                                                   */
  1.7809 +/* ------------------------------------------------------------------ */
  1.7810 +/* This may be called twice during some operations.  */
  1.7811 +static Int decGetDigits(Unit *uar, Int len) {
  1.7812 +  Unit *up=uar+(len-1);            /* -> msu  */
  1.7813 +  Int  digits=(len-1)*DECDPUN+1;   /* possible digits excluding msu  */
  1.7814 +  #if DECDPUN>4
  1.7815 +  uInt const *pow;                 /* work  */
  1.7816 +  #endif
  1.7817 +                                   /* (at least 1 in final msu)  */
  1.7818 +  #if DECCHECK
  1.7819 +  if (len<1) printf("decGetDigits called with len<1 [%ld]\n", (LI)len);
  1.7820 +  #endif
  1.7821 +
  1.7822 +  for (; up>=uar; up--) {
  1.7823 +    if (*up==0) {                  /* unit is all 0s  */
  1.7824 +      if (digits==1) break;        /* a zero has one digit  */
  1.7825 +      digits-=DECDPUN;             /* adjust for 0 unit  */
  1.7826 +      continue;}
  1.7827 +    /* found the first (most significant) non-zero Unit  */
  1.7828 +    #if DECDPUN>1                  /* not done yet  */
  1.7829 +    if (*up<10) break;             /* is 1-9  */
  1.7830 +    digits++;
  1.7831 +    #if DECDPUN>2                  /* not done yet  */
  1.7832 +    if (*up<100) break;            /* is 10-99  */
  1.7833 +    digits++;
  1.7834 +    #if DECDPUN>3                  /* not done yet  */
  1.7835 +    if (*up<1000) break;           /* is 100-999  */
  1.7836 +    digits++;
  1.7837 +    #if DECDPUN>4                  /* count the rest ...  */
  1.7838 +    for (pow=&powers[4]; *up>=*pow; pow++) digits++;
  1.7839 +    #endif
  1.7840 +    #endif
  1.7841 +    #endif
  1.7842 +    #endif
  1.7843 +    break;
  1.7844 +    } /* up  */
  1.7845 +  return digits;
  1.7846 +  } /* decGetDigits  */
  1.7847 +
  1.7848 +#if DECTRACE | DECCHECK
  1.7849 +/* ------------------------------------------------------------------ */
  1.7850 +/* decNumberShow -- display a number [debug aid]                      */
  1.7851 +/*   dn is the number to show                                         */
  1.7852 +/*                                                                    */
  1.7853 +/* Shows: sign, exponent, coefficient (msu first), digits             */
  1.7854 +/*    or: sign, special-value                                         */
  1.7855 +/* ------------------------------------------------------------------ */
  1.7856 +/* this is public so other modules can use it  */
  1.7857 +void uprv_decNumberShow(const decNumber *dn) {
  1.7858 +  const Unit *up;                  /* work  */
  1.7859 +  uInt u, d;                       /* ..  */
  1.7860 +  Int cut;                         /* ..  */
  1.7861 +  char isign='+';                  /* main sign  */
  1.7862 +  if (dn==NULL) {
  1.7863 +    printf("NULL\n");
  1.7864 +    return;}
  1.7865 +  if (decNumberIsNegative(dn)) isign='-';
  1.7866 +  printf(" >> %c ", isign);
  1.7867 +  if (dn->bits&DECSPECIAL) {       /* Is a special value  */
  1.7868 +    if (decNumberIsInfinite(dn)) printf("Infinity");
  1.7869 +     else {                                  /* a NaN  */
  1.7870 +      if (dn->bits&DECSNAN) printf("sNaN");  /* signalling NaN  */
  1.7871 +       else printf("NaN");
  1.7872 +      }
  1.7873 +    /* if coefficient and exponent are 0, no more to do  */
  1.7874 +    if (dn->exponent==0 && dn->digits==1 && *dn->lsu==0) {
  1.7875 +      printf("\n");
  1.7876 +      return;}
  1.7877 +    /* drop through to report other information  */
  1.7878 +    printf(" ");
  1.7879 +    }
  1.7880 +
  1.7881 +  /* now carefully display the coefficient  */
  1.7882 +  up=dn->lsu+D2U(dn->digits)-1;         /* msu  */
  1.7883 +  printf("%ld", (LI)*up);
  1.7884 +  for (up=up-1; up>=dn->lsu; up--) {
  1.7885 +    u=*up;
  1.7886 +    printf(":");
  1.7887 +    for (cut=DECDPUN-1; cut>=0; cut--) {
  1.7888 +      d=u/powers[cut];
  1.7889 +      u-=d*powers[cut];
  1.7890 +      printf("%ld", (LI)d);
  1.7891 +      } /* cut  */
  1.7892 +    } /* up  */
  1.7893 +  if (dn->exponent!=0) {
  1.7894 +    char esign='+';
  1.7895 +    if (dn->exponent<0) esign='-';
  1.7896 +    printf(" E%c%ld", esign, (LI)abs(dn->exponent));
  1.7897 +    }
  1.7898 +  printf(" [%ld]\n", (LI)dn->digits);
  1.7899 +  } /* decNumberShow  */
  1.7900 +#endif
  1.7901 +
  1.7902 +#if DECTRACE || DECCHECK
  1.7903 +/* ------------------------------------------------------------------ */
  1.7904 +/* decDumpAr -- display a unit array [debug/check aid]                */
  1.7905 +/*   name is a single-character tag name                              */
  1.7906 +/*   ar   is the array to display                                     */
  1.7907 +/*   len  is the length of the array in Units                         */
  1.7908 +/* ------------------------------------------------------------------ */
  1.7909 +static void decDumpAr(char name, const Unit *ar, Int len) {
  1.7910 +  Int i;
  1.7911 +  const char *spec;
  1.7912 +  #if DECDPUN==9
  1.7913 +    spec="%09d ";
  1.7914 +  #elif DECDPUN==8
  1.7915 +    spec="%08d ";
  1.7916 +  #elif DECDPUN==7
  1.7917 +    spec="%07d ";
  1.7918 +  #elif DECDPUN==6
  1.7919 +    spec="%06d ";
  1.7920 +  #elif DECDPUN==5
  1.7921 +    spec="%05d ";
  1.7922 +  #elif DECDPUN==4
  1.7923 +    spec="%04d ";
  1.7924 +  #elif DECDPUN==3
  1.7925 +    spec="%03d ";
  1.7926 +  #elif DECDPUN==2
  1.7927 +    spec="%02d ";
  1.7928 +  #else
  1.7929 +    spec="%d ";
  1.7930 +  #endif
  1.7931 +  printf("  :%c: ", name);
  1.7932 +  for (i=len-1; i>=0; i--) {
  1.7933 +    if (i==len-1) printf("%ld ", (LI)ar[i]);
  1.7934 +     else printf(spec, ar[i]);
  1.7935 +    }
  1.7936 +  printf("\n");
  1.7937 +  return;}
  1.7938 +#endif
  1.7939 +
  1.7940 +#if DECCHECK
  1.7941 +/* ------------------------------------------------------------------ */
  1.7942 +/* decCheckOperands -- check operand(s) to a routine                  */
  1.7943 +/*   res is the result structure (not checked; it will be set to      */
  1.7944 +/*          quiet NaN if error found (and it is not NULL))            */
  1.7945 +/*   lhs is the first operand (may be DECUNRESU)                      */
  1.7946 +/*   rhs is the second (may be DECUNUSED)                             */
  1.7947 +/*   set is the context (may be DECUNCONT)                            */
  1.7948 +/*   returns 0 if both operands, and the context are clean, or 1      */
  1.7949 +/*     otherwise (in which case the context will show an error,       */
  1.7950 +/*     unless NULL).  Note that res is not cleaned; caller should     */
  1.7951 +/*     handle this so res=NULL case is safe.                          */
  1.7952 +/* The caller is expected to abandon immediately if 1 is returned.    */
  1.7953 +/* ------------------------------------------------------------------ */
  1.7954 +static Flag decCheckOperands(decNumber *res, const decNumber *lhs,
  1.7955 +                             const decNumber *rhs, decContext *set) {
  1.7956 +  Flag bad=0;
  1.7957 +  if (set==NULL) {                 /* oops; hopeless  */
  1.7958 +    #if DECTRACE || DECVERB
  1.7959 +    printf("Reference to context is NULL.\n");
  1.7960 +    #endif
  1.7961 +    bad=1;
  1.7962 +    return 1;}
  1.7963 +   else if (set!=DECUNCONT
  1.7964 +     && (set->digits<1 || set->round>=DEC_ROUND_MAX)) {
  1.7965 +    bad=1;
  1.7966 +    #if DECTRACE || DECVERB
  1.7967 +    printf("Bad context [digits=%ld round=%ld].\n",
  1.7968 +           (LI)set->digits, (LI)set->round);
  1.7969 +    #endif
  1.7970 +    }
  1.7971 +   else {
  1.7972 +    if (res==NULL) {
  1.7973 +      bad=1;
  1.7974 +      #if DECTRACE
  1.7975 +      /* this one not DECVERB as standard tests include NULL  */
  1.7976 +      printf("Reference to result is NULL.\n");
  1.7977 +      #endif
  1.7978 +      }
  1.7979 +    if (!bad && lhs!=DECUNUSED) bad=(decCheckNumber(lhs));
  1.7980 +    if (!bad && rhs!=DECUNUSED) bad=(decCheckNumber(rhs));
  1.7981 +    }
  1.7982 +  if (bad) {
  1.7983 +    if (set!=DECUNCONT) uprv_decContextSetStatus(set, DEC_Invalid_operation);
  1.7984 +    if (res!=DECUNRESU && res!=NULL) {
  1.7985 +      uprv_decNumberZero(res);
  1.7986 +      res->bits=DECNAN;       /* qNaN  */
  1.7987 +      }
  1.7988 +    }
  1.7989 +  return bad;
  1.7990 +  } /* decCheckOperands  */
  1.7991 +
  1.7992 +/* ------------------------------------------------------------------ */
  1.7993 +/* decCheckNumber -- check a number                                   */
  1.7994 +/*   dn is the number to check                                        */
  1.7995 +/*   returns 0 if the number is clean, or 1 otherwise                 */
  1.7996 +/*                                                                    */
  1.7997 +/* The number is considered valid if it could be a result from some   */
  1.7998 +/* operation in some valid context.                                   */
  1.7999 +/* ------------------------------------------------------------------ */
  1.8000 +static Flag decCheckNumber(const decNumber *dn) {
  1.8001 +  const Unit *up;             /* work  */
  1.8002 +  uInt maxuint;               /* ..  */
  1.8003 +  Int ae, d, digits;          /* ..  */
  1.8004 +  Int emin, emax;             /* ..  */
  1.8005 +
  1.8006 +  if (dn==NULL) {             /* hopeless  */
  1.8007 +    #if DECTRACE
  1.8008 +    /* this one not DECVERB as standard tests include NULL  */
  1.8009 +    printf("Reference to decNumber is NULL.\n");
  1.8010 +    #endif
  1.8011 +    return 1;}
  1.8012 +
  1.8013 +  /* check special values  */
  1.8014 +  if (dn->bits & DECSPECIAL) {
  1.8015 +    if (dn->exponent!=0) {
  1.8016 +      #if DECTRACE || DECVERB
  1.8017 +      printf("Exponent %ld (not 0) for a special value [%02x].\n",
  1.8018 +             (LI)dn->exponent, dn->bits);
  1.8019 +      #endif
  1.8020 +      return 1;}
  1.8021 +
  1.8022 +    /* 2003.09.08: NaNs may now have coefficients, so next tests Inf only  */
  1.8023 +    if (decNumberIsInfinite(dn)) {
  1.8024 +      if (dn->digits!=1) {
  1.8025 +        #if DECTRACE || DECVERB
  1.8026 +        printf("Digits %ld (not 1) for an infinity.\n", (LI)dn->digits);
  1.8027 +        #endif
  1.8028 +        return 1;}
  1.8029 +      if (*dn->lsu!=0) {
  1.8030 +        #if DECTRACE || DECVERB
  1.8031 +        printf("LSU %ld (not 0) for an infinity.\n", (LI)*dn->lsu);
  1.8032 +        #endif
  1.8033 +        decDumpAr('I', dn->lsu, D2U(dn->digits));
  1.8034 +        return 1;}
  1.8035 +      } /* Inf  */
  1.8036 +    /* 2002.12.26: negative NaNs can now appear through proposed IEEE  */
  1.8037 +    /*             concrete formats (decimal64, etc.).  */
  1.8038 +    return 0;
  1.8039 +    }
  1.8040 +
  1.8041 +  /* check the coefficient  */
  1.8042 +  if (dn->digits<1 || dn->digits>DECNUMMAXP) {
  1.8043 +    #if DECTRACE || DECVERB
  1.8044 +    printf("Digits %ld in number.\n", (LI)dn->digits);
  1.8045 +    #endif
  1.8046 +    return 1;}
  1.8047 +
  1.8048 +  d=dn->digits;
  1.8049 +
  1.8050 +  for (up=dn->lsu; d>0; up++) {
  1.8051 +    if (d>DECDPUN) maxuint=DECDPUNMAX;
  1.8052 +     else {                   /* reached the msu  */
  1.8053 +      maxuint=powers[d]-1;
  1.8054 +      if (dn->digits>1 && *up<powers[d-1]) {
  1.8055 +        #if DECTRACE || DECVERB
  1.8056 +        printf("Leading 0 in number.\n");
  1.8057 +        uprv_decNumberShow(dn);
  1.8058 +        #endif
  1.8059 +        return 1;}
  1.8060 +      }
  1.8061 +    if (*up>maxuint) {
  1.8062 +      #if DECTRACE || DECVERB
  1.8063 +      printf("Bad Unit [%08lx] in %ld-digit number at offset %ld [maxuint %ld].\n",
  1.8064 +              (LI)*up, (LI)dn->digits, (LI)(up-dn->lsu), (LI)maxuint);
  1.8065 +      #endif
  1.8066 +      return 1;}
  1.8067 +    d-=DECDPUN;
  1.8068 +    }
  1.8069 +
  1.8070 +  /* check the exponent.  Note that input operands can have exponents  */
  1.8071 +  /* which are out of the set->emin/set->emax and set->digits range  */
  1.8072 +  /* (just as they can have more digits than set->digits).  */
  1.8073 +  ae=dn->exponent+dn->digits-1;    /* adjusted exponent  */
  1.8074 +  emax=DECNUMMAXE;
  1.8075 +  emin=DECNUMMINE;
  1.8076 +  digits=DECNUMMAXP;
  1.8077 +  if (ae<emin-(digits-1)) {
  1.8078 +    #if DECTRACE || DECVERB
  1.8079 +    printf("Adjusted exponent underflow [%ld].\n", (LI)ae);
  1.8080 +    uprv_decNumberShow(dn);
  1.8081 +    #endif
  1.8082 +    return 1;}
  1.8083 +  if (ae>+emax) {
  1.8084 +    #if DECTRACE || DECVERB
  1.8085 +    printf("Adjusted exponent overflow [%ld].\n", (LI)ae);
  1.8086 +    uprv_decNumberShow(dn);
  1.8087 +    #endif
  1.8088 +    return 1;}
  1.8089 +
  1.8090 +  return 0;              /* it's OK  */
  1.8091 +  } /* decCheckNumber  */
  1.8092 +
  1.8093 +/* ------------------------------------------------------------------ */
  1.8094 +/* decCheckInexact -- check a normal finite inexact result has digits */
  1.8095 +/*   dn is the number to check                                        */
  1.8096 +/*   set is the context (for status and precision)                    */
  1.8097 +/*   sets Invalid operation, etc., if some digits are missing         */
  1.8098 +/* [this check is not made for DECSUBSET compilation or when          */
  1.8099 +/* subnormal is not set]                                              */
  1.8100 +/* ------------------------------------------------------------------ */
  1.8101 +static void decCheckInexact(const decNumber *dn, decContext *set) {
  1.8102 +  #if !DECSUBSET && DECEXTFLAG
  1.8103 +    if ((set->status & (DEC_Inexact|DEC_Subnormal))==DEC_Inexact
  1.8104 +     && (set->digits!=dn->digits) && !(dn->bits & DECSPECIAL)) {
  1.8105 +      #if DECTRACE || DECVERB
  1.8106 +      printf("Insufficient digits [%ld] on normal Inexact result.\n",
  1.8107 +             (LI)dn->digits);
  1.8108 +      uprv_decNumberShow(dn);
  1.8109 +      #endif
  1.8110 +      uprv_decContextSetStatus(set, DEC_Invalid_operation);
  1.8111 +      }
  1.8112 +  #else
  1.8113 +    /* next is a noop for quiet compiler  */
  1.8114 +    if (dn!=NULL && dn->digits==0) set->status|=DEC_Invalid_operation;
  1.8115 +  #endif
  1.8116 +  return;
  1.8117 +  } /* decCheckInexact  */
  1.8118 +#endif
  1.8119 +
  1.8120 +#if DECALLOC
  1.8121 +#undef malloc
  1.8122 +#undef free
  1.8123 +/* ------------------------------------------------------------------ */
  1.8124 +/* decMalloc -- accountable allocation routine                        */
  1.8125 +/*   n is the number of bytes to allocate                             */
  1.8126 +/*                                                                    */
  1.8127 +/* Semantics is the same as the stdlib malloc routine, but bytes      */
  1.8128 +/* allocated are accounted for globally, and corruption fences are    */
  1.8129 +/* added before and after the 'actual' storage.                       */
  1.8130 +/* ------------------------------------------------------------------ */
  1.8131 +/* This routine allocates storage with an extra twelve bytes; 8 are   */
  1.8132 +/* at the start and hold:                                             */
  1.8133 +/*   0-3 the original length requested                                */
  1.8134 +/*   4-7 buffer corruption detection fence (DECFENCE, x4)             */
  1.8135 +/* The 4 bytes at the end also hold a corruption fence (DECFENCE, x4) */
  1.8136 +/* ------------------------------------------------------------------ */
  1.8137 +static void *decMalloc(size_t n) {
  1.8138 +  uInt  size=n+12;                 /* true size  */
  1.8139 +  void  *alloc;                    /* -> allocated storage  */
  1.8140 +  uByte *b, *b0;                   /* work  */
  1.8141 +  uInt  uiwork;                    /* for macros  */
  1.8142 +
  1.8143 +  alloc=malloc(size);              /* -> allocated storage  */
  1.8144 +  if (alloc==NULL) return NULL;    /* out of strorage  */
  1.8145 +  b0=(uByte *)alloc;               /* as bytes  */
  1.8146 +  decAllocBytes+=n;                /* account for storage  */
  1.8147 +  UBFROMUI(alloc, n);              /* save n  */
  1.8148 +  /* printf(" alloc ++ dAB: %ld (%ld)\n", (LI)decAllocBytes, (LI)n);  */
  1.8149 +  for (b=b0+4; b<b0+8; b++) *b=DECFENCE;
  1.8150 +  for (b=b0+n+8; b<b0+n+12; b++) *b=DECFENCE;
  1.8151 +  return b0+8;                     /* -> play area  */
  1.8152 +  } /* decMalloc  */
  1.8153 +
  1.8154 +/* ------------------------------------------------------------------ */
  1.8155 +/* decFree -- accountable free routine                                */
  1.8156 +/*   alloc is the storage to free                                     */
  1.8157 +/*                                                                    */
  1.8158 +/* Semantics is the same as the stdlib malloc routine, except that    */
  1.8159 +/* the global storage accounting is updated and the fences are        */
  1.8160 +/* checked to ensure that no routine has written 'out of bounds'.     */
  1.8161 +/* ------------------------------------------------------------------ */
  1.8162 +/* This routine first checks that the fences have not been corrupted. */
  1.8163 +/* It then frees the storage using the 'truw' storage address (that   */
  1.8164 +/* is, offset by 8).                                                  */
  1.8165 +/* ------------------------------------------------------------------ */
  1.8166 +static void decFree(void *alloc) {
  1.8167 +  uInt  n;                         /* original length  */
  1.8168 +  uByte *b, *b0;                   /* work  */
  1.8169 +  uInt  uiwork;                    /* for macros  */
  1.8170 +
  1.8171 +  if (alloc==NULL) return;         /* allowed; it's a nop  */
  1.8172 +  b0=(uByte *)alloc;               /* as bytes  */
  1.8173 +  b0-=8;                           /* -> true start of storage  */
  1.8174 +  n=UBTOUI(b0);                    /* lift length  */
  1.8175 +  for (b=b0+4; b<b0+8; b++) if (*b!=DECFENCE)
  1.8176 +    printf("=== Corrupt byte [%02x] at offset %d from %ld ===\n", *b,
  1.8177 +           b-b0-8, (LI)b0);
  1.8178 +  for (b=b0+n+8; b<b0+n+12; b++) if (*b!=DECFENCE)
  1.8179 +    printf("=== Corrupt byte [%02x] at offset +%d from %ld, n=%ld ===\n", *b,
  1.8180 +           b-b0-8, (LI)b0, (LI)n);
  1.8181 +  free(b0);                        /* drop the storage  */
  1.8182 +  decAllocBytes-=n;                /* account for storage  */
  1.8183 +  /* printf(" free -- dAB: %d (%d)\n", decAllocBytes, -n);  */
  1.8184 +  } /* decFree  */
  1.8185 +#define malloc(a) decMalloc(a)
  1.8186 +#define free(a) decFree(a)
  1.8187 +#endif

mercurial