Coverage Report

Created: 2026-06-07 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/icu/icu4c/source/i18n/decNumber.cpp
Line
Count
Source
1
// © 2016 and later: Unicode, Inc. and others.
2
// License & terms of use: http://www.unicode.org/copyright.html
3
/* ------------------------------------------------------------------ */
4
/* Decimal Number arithmetic module                                   */
5
/* ------------------------------------------------------------------ */
6
/* Copyright (c) IBM Corporation, 2000-2014.  All rights reserved.    */
7
/*                                                                    */
8
/* This software is made available under the terms of the             */
9
/* ICU License -- ICU 1.8.1 and later.                                */
10
/*                                                                    */
11
/* The description and User's Guide ("The decNumber C Library") for   */
12
/* this software is called decNumber.pdf.  This document is           */
13
/* available, together with arithmetic and format specifications,     */
14
/* testcases, and Web links, on the General Decimal Arithmetic page.  */
15
/*                                                                    */
16
/* Please send comments, suggestions, and corrections to the author:  */
17
/*   mfc@uk.ibm.com                                                   */
18
/*   Mike Cowlishaw, IBM Fellow                                       */
19
/*   IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK         */
20
/* ------------------------------------------------------------------ */
21
22
/* Modified version, for use from within ICU.
23
 *    Renamed public functions, to avoid an unwanted export of the 
24
 *    standard names from the ICU library.
25
 *
26
 *    Use ICU's uprv_malloc() and uprv_free()
27
 *
28
 *    Revert comment syntax to plain C
29
 *
30
 *    Remove a few compiler warnings.
31
 */
32
33
/* This module comprises the routines for arbitrary-precision General */
34
/* Decimal Arithmetic as defined in the specification which may be    */
35
/* found on the General Decimal Arithmetic pages.  It implements both */
36
/* the full ('extended') arithmetic and the simpler ('subset')        */
37
/* arithmetic.                                                        */
38
/*                                                                    */
39
/* Usage notes:                                                       */
40
/*                                                                    */
41
/* 1. This code is ANSI C89 except:                                   */
42
/*                                                                    */
43
/*    a) C99 line comments (double forward slash) are used.  (Most C  */
44
/*       compilers accept these.  If yours does not, a simple script  */
45
/*       can be used to convert them to ANSI C comments.)             */
46
/*                                                                    */
47
/*    b) Types from C99 stdint.h are used.  If you do not have this   */
48
/*       header file, see the User's Guide section of the decNumber   */
49
/*       documentation; this lists the necessary definitions.         */
50
/*                                                                    */
51
/*    c) If DECDPUN>4 or DECUSE64=1, the C99 64-bit int64_t and       */
52
/*       uint64_t types may be used.  To avoid these, set DECUSE64=0  */
53
/*       and DECDPUN<=4 (see documentation).                          */
54
/*                                                                    */
55
/*    The code also conforms to C99 restrictions; in particular,      */
56
/*    strict aliasing rules are observed.                             */
57
/*                                                                    */
58
/* 2. The decNumber format which this library uses is optimized for   */
59
/*    efficient processing of relatively short numbers; in particular */
60
/*    it allows the use of fixed sized structures and minimizes copy  */
61
/*    and move operations.  It does, however, support arbitrary       */
62
/*    precision (up to 999,999,999 digits) and arbitrary exponent     */
63
/*    range (Emax in the range 0 through 999,999,999 and Emin in the  */
64
/*    range -999,999,999 through 0).  Mathematical functions (for     */
65
/*    example decNumberExp) as identified below are restricted more   */
66
/*    tightly: digits, emax, and -emin in the context must be <=      */
67
/*    DEC_MAX_MATH (999999), and their operand(s) must be within      */
68
/*    these bounds.                                                   */
69
/*                                                                    */
70
/* 3. Logical functions are further restricted; their operands must   */
71
/*    be finite, positive, have an exponent of zero, and all digits   */
72
/*    must be either 0 or 1.  The result will only contain digits     */
73
/*    which are 0 or 1 (and will have exponent=0 and a sign of 0).    */
74
/*                                                                    */
75
/* 4. Operands to operator functions are never modified unless they   */
76
/*    are also specified to be the result number (which is always     */
77
/*    permitted).  Other than that case, operands must not overlap.   */
78
/*                                                                    */
79
/* 5. Error handling: the type of the error is ORed into the status   */
80
/*    flags in the current context (decContext structure).  The       */
81
/*    SIGFPE signal is then raised if the corresponding trap-enabler  */
82
/*    flag in the decContext is set (is 1).                           */
83
/*                                                                    */
84
/*    It is the responsibility of the caller to clear the status      */
85
/*    flags as required.                                              */
86
/*                                                                    */
87
/*    The result of any routine which returns a number will always    */
88
/*    be a valid number (which may be a special value, such as an     */
89
/*    Infinity or NaN).                                               */
90
/*                                                                    */
91
/* 6. The decNumber format is not an exchangeable concrete            */
92
/*    representation as it comprises fields which may be machine-     */
93
/*    dependent (packed or unpacked, or special length, for example). */
94
/*    Canonical conversions to and from strings are provided; other   */
95
/*    conversions are available in separate modules.                  */
96
/*                                                                    */
97
/* 7. Normally, input operands are assumed to be valid.  Set DECCHECK */
98
/*    to 1 for extended operand checking (including nullptr operands).   */
99
/*    Results are undefined if a badly-formed structure (or a nullptr    */
100
/*    pointer to a structure) is provided, though with DECCHECK       */
101
/*    enabled the operator routines are protected against exceptions. */
102
/*    (Except if the result pointer is nullptr, which is unrecoverable.) */
103
/*                                                                    */
104
/*    However, the routines will never cause exceptions if they are   */
105
/*    given well-formed operands, even if the value of the operands   */
106
/*    is inappropriate for the operation and DECCHECK is not set.     */
107
/*    (Except for SIGFPE, as and where documented.)                   */
108
/*                                                                    */
109
/* 8. Subset arithmetic is available only if DECSUBSET is set to 1.   */
110
/* ------------------------------------------------------------------ */
111
/* Implementation notes for maintenance of this module:               */
112
/*                                                                    */
113
/* 1. Storage leak protection:  Routines which use malloc are not     */
114
/*    permitted to use return for fastpath or error exits (i.e.,      */
115
/*    they follow strict structured programming conventions).         */
116
/*    Instead they have a do{}while(0); construct surrounding the     */
117
/*    code which is protected -- break may be used to exit this.      */
118
/*    Other routines can safely use the return statement inline.      */
119
/*                                                                    */
120
/*    Storage leak accounting can be enabled using DECALLOC.          */
121
/*                                                                    */
122
/* 2. All loops use the for(;;) construct.  Any do construct does     */
123
/*    not loop; it is for allocation protection as just described.    */
124
/*                                                                    */
125
/* 3. Setting status in the context must always be the very last      */
126
/*    action in a routine, as non-0 status may raise a trap and hence */
127
/*    the call to set status may not return (if the handler uses long */
128
/*    jump).  Therefore all cleanup must be done first.  In general,  */
129
/*    to achieve this status is accumulated and is only applied just  */
130
/*    before return by calling decContextSetStatus (via decStatus).   */
131
/*                                                                    */
132
/*    Routines which allocate storage cannot, in general, use the     */
133
/*    'top level' routines which could cause a non-returning          */
134
/*    transfer of control.  The decXxxxOp routines are safe (do not   */
135
/*    call decStatus even if traps are set in the context) and should */
136
/*    be used instead (they are also a little faster).                */
137
/*                                                                    */
138
/* 4. Exponent checking is minimized by allowing the exponent to      */
139
/*    grow outside its limits during calculations, provided that      */
140
/*    the decFinalize function is called later.  Multiplication and   */
141
/*    division, and intermediate calculations in exponentiation,      */
142
/*    require more careful checks because of the risk of 31-bit       */
143
/*    overflow (the most negative valid exponent is -1999999997, for  */
144
/*    a 999999999-digit number with adjusted exponent of -999999999). */
145
/*                                                                    */
146
/* 5. Rounding is deferred until finalization of results, with any    */
147
/*    'off to the right' data being represented as a single digit     */
148
/*    residue (in the range -1 through 9).  This avoids any double-   */
149
/*    rounding when more than one shortening takes place (for         */
150
/*    example, when a result is subnormal).                           */
151
/*                                                                    */
152
/* 6. The digits count is allowed to rise to a multiple of DECDPUN    */
153
/*    during many operations, so whole Units are handled and exact    */
154
/*    accounting of digits is not needed.  The correct digits value   */
155
/*    is found by decGetDigits, which accounts for leading zeros.     */
156
/*    This must be called before any rounding if the number of digits */
157
/*    is not known exactly.                                           */
158
/*                                                                    */
159
/* 7. The multiply-by-reciprocal 'trick' is used for partitioning     */
160
/*    numbers up to four digits, using appropriate constants.  This   */
161
/*    is not useful for longer numbers because overflow of 32 bits    */
162
/*    would lead to 4 multiplies, which is almost as expensive as     */
163
/*    a divide (unless a floating-point or 64-bit multiply is         */
164
/*    assumed to be available).                                       */
165
/*                                                                    */
166
/* 8. Unusual abbreviations that may be used in the commentary:       */
167
/*      lhs -- left hand side (operand, of an operation)              */
168
/*      lsd -- least significant digit (of coefficient)               */
169
/*      lsu -- least significant Unit (of coefficient)                */
170
/*      msd -- most significant digit (of coefficient)                */
171
/*      msi -- most significant item (in an array)                    */
172
/*      msu -- most significant Unit (of coefficient)                 */
173
/*      rhs -- right hand side (operand, of an operation)             */
174
/*      +ve -- positive                                               */
175
/*      -ve -- negative                                               */
176
/*      **  -- raise to the power                                     */
177
/* ------------------------------------------------------------------ */
178
179
#include <stdlib.h>                /* for malloc, free, etc.  */
180
/*  #include <stdio.h>   */        /* for printf [if needed]  */
181
#include <string.h>                /* for strcpy  */
182
#include <ctype.h>                 /* for lower  */
183
#include "cmemory.h"               /* for uprv_malloc, etc., in ICU */
184
#include "decNumber.h"             /* base number library  */
185
#include "decNumberLocal.h"        /* decNumber local types, etc.  */
186
#include "uassert.h"
187
188
/* Constants */
189
/* Public lookup table used by the D2U macro  */
190
static const uByte d2utable[DECMAXD2U+1]=D2UTABLE;
191
192
#define DECVERB     1              /* set to 1 for verbose DECCHECK  */
193
0
#define powers      DECPOWERS      /* old internal name  */
194
195
/* Local constants  */
196
0
#define DIVIDE      0x80           /* Divide operators  */
197
0
#define REMAINDER   0x40           /* ..  */
198
0
#define DIVIDEINT   0x20           /* ..  */
199
0
#define REMNEAR     0x10           /* ..  */
200
0
#define COMPARE     0x01           /* Compare operators  */
201
0
#define COMPMAX     0x02           /* ..  */
202
0
#define COMPMIN     0x03           /* ..  */
203
0
#define COMPTOTAL   0x04           /* ..  */
204
0
#define COMPNAN     0x05           /* .. [NaN processing]  */
205
0
#define COMPSIG     0x06           /* .. [signaling COMPARE]  */
206
0
#define COMPMAXMAG  0x07           /* ..  */
207
0
#define COMPMINMAG  0x08           /* ..  */
208
209
0
#define DEC_sNaN     0x40000000    /* local status: sNaN signal  */
210
0
#define BADINT  (Int)0x80000000    /* most-negative Int; error indicator  */
211
/* Next two indicate an integer >= 10**6, and its parity (bottom bit)  */
212
0
#define BIGEVEN (Int)0x80000002
213
0
#define BIGODD  (Int)0x80000003
214
215
static const Unit uarrone[1]={1};   /* Unit array of 1, used for incrementing  */
216
217
/* ------------------------------------------------------------------ */
218
/* round-for-reround digits                                           */
219
/* ------------------------------------------------------------------ */
220
#if 0
221
static const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
222
#endif
223
224
/* ------------------------------------------------------------------ */
225
/* Powers of ten (powers[n]==10**n, 0<=n<=9)                          */
226
/* ------------------------------------------------------------------ */
227
static const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
228
                          10000000, 100000000, 1000000000};
229
230
231
/* Granularity-dependent code */
232
#if DECDPUN<=4
233
0
  #define eInt  Int           /* extended integer  */
234
  #define ueInt uInt          /* unsigned extended integer  */
235
  /* Constant multipliers for divide-by-power-of five using reciprocal  */
236
  /* multiply, after removing powers of 2 by shifting, and final shift  */
237
  /* of 17 [we only need up to **4]  */
238
  static const uInt multies[]={131073, 26215, 5243, 1049, 210};
239
  /* QUOT10 -- macro to return the quotient of unit u divided by 10**n  */
240
0
  #define QUOT10(u, n) ((((uInt)(u)>>(n))*multies[n])>>17)
241
#else
242
  /* For DECDPUN>4 non-ANSI-89 64-bit types are needed.  */
243
  #if !DECUSE64
244
    #error decNumber.c: DECUSE64 must be 1 when DECDPUN>4
245
  #endif
246
  #define eInt  Long          /* extended integer  */
247
  #define ueInt uLong         /* unsigned extended integer  */
248
#endif
249
250
/* Local routines */
251
static decNumber * decAddOp(decNumber *, const decNumber *, const decNumber *,
252
                              decContext *, uByte, uInt *);
253
static Flag        decBiStr(const char *, const char *, const char *);
254
static uInt        decCheckMath(const decNumber *, decContext *, uInt *);
255
static void        decApplyRound(decNumber *, decContext *, Int, uInt *);
256
static Int         decCompare(const decNumber *lhs, const decNumber *rhs, Flag);
257
static decNumber * decCompareOp(decNumber *, const decNumber *,
258
                              const decNumber *, decContext *,
259
                              Flag, uInt *);
260
static void        decCopyFit(decNumber *, const decNumber *, decContext *,
261
                              Int *, uInt *);
262
static decNumber * decDecap(decNumber *, Int);
263
static decNumber * decDivideOp(decNumber *, const decNumber *,
264
                              const decNumber *, decContext *, Flag, uInt *);
265
static decNumber * decExpOp(decNumber *, const decNumber *,
266
                              decContext *, uInt *);
267
static void        decFinalize(decNumber *, decContext *, Int *, uInt *);
268
static Int         decGetDigits(Unit *, Int);
269
static Int         decGetInt(const decNumber *);
270
static decNumber * decLnOp(decNumber *, const decNumber *,
271
                              decContext *, uInt *);
272
static decNumber * decMultiplyOp(decNumber *, const decNumber *,
273
                              const decNumber *, decContext *,
274
                              uInt *);
275
static decNumber * decNaNs(decNumber *, const decNumber *,
276
                              const decNumber *, decContext *, uInt *);
277
static decNumber * decQuantizeOp(decNumber *, const decNumber *,
278
                              const decNumber *, decContext *, Flag,
279
                              uInt *);
280
static void        decReverse(Unit *, Unit *);
281
static void        decSetCoeff(decNumber *, decContext *, const Unit *,
282
                              Int, Int *, uInt *);
283
static void        decSetMaxValue(decNumber *, decContext *);
284
static void        decSetOverflow(decNumber *, decContext *, uInt *);
285
static void        decSetSubnormal(decNumber *, decContext *, Int *, uInt *);
286
static Int         decShiftToLeast(Unit *, Int, Int);
287
static Int         decShiftToMost(Unit *, Int, Int);
288
static void        decStatus(decNumber *, uInt, decContext *);
289
static void        decToString(const decNumber *, char[], Flag);
290
static decNumber * decTrim(decNumber *, decContext *, Flag, Flag, Int *);
291
static Int         decUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
292
                              Unit *, Int);
293
static Int         decUnitCompare(const Unit *, Int, const Unit *, Int, Int);
294
295
#if !DECSUBSET
296
/* decFinish == decFinalize when no subset arithmetic needed */
297
0
#define decFinish(a,b,c,d) decFinalize(a,b,c,d)
298
#else
299
static void        decFinish(decNumber *, decContext *, Int *, uInt *);
300
static decNumber * decRoundOperand(const decNumber *, decContext *, uInt *);
301
#endif
302
303
/* Local macros */
304
/* masked special-values bits  */
305
0
#define SPECIALARG  (rhs->bits & DECSPECIAL)
306
0
#define SPECIALARGS ((lhs->bits | rhs->bits) & DECSPECIAL)
307
308
/* For use in ICU */
309
0
#define malloc(a) uprv_malloc(a)
310
0
#define free(a) uprv_free(a)
311
312
/* Diagnostic macros, etc. */
313
#if DECALLOC
314
/* Handle malloc/free accounting.  If enabled, our accountable routines  */
315
/* are used; otherwise the code just goes straight to the system malloc  */
316
/* and free routines.  */
317
#define malloc(a) decMalloc(a)
318
#define free(a) decFree(a)
319
#define DECFENCE 0x5a              /* corruption detector  */
320
/* 'Our' malloc and free:  */
321
static void *decMalloc(size_t);
322
static void  decFree(void *);
323
uInt decAllocBytes=0;              /* count of bytes allocated  */
324
/* Note that DECALLOC code only checks for storage buffer overflow.  */
325
/* To check for memory leaks, the decAllocBytes variable must be  */
326
/* checked to be 0 at appropriate times (e.g., after the test  */
327
/* harness completes a set of tests).  This checking may be unreliable  */
328
/* if the testing is done in a multi-thread environment.  */
329
#endif
330
331
#if DECCHECK
332
/* Optional checking routines.  Enabling these means that decNumber  */
333
/* and decContext operands to operator routines are checked for  */
334
/* correctness.  This roughly doubles the execution time of the  */
335
/* fastest routines (and adds 600+ bytes), so should not normally be  */
336
/* used in 'production'.  */
337
/* decCheckInexact is used to check that inexact results have a full  */
338
/* complement of digits (where appropriate -- this is not the case  */
339
/* for Quantize, for example)  */
340
#define DECUNRESU ((decNumber *)(void *)0xffffffff)
341
#define DECUNUSED ((const decNumber *)(void *)0xffffffff)
342
#define DECUNCONT ((decContext *)(void *)(0xffffffff))
343
static Flag decCheckOperands(decNumber *, const decNumber *,
344
                             const decNumber *, decContext *);
345
static Flag decCheckNumber(const decNumber *);
346
static void decCheckInexact(const decNumber *, decContext *);
347
#endif
348
349
#if DECTRACE || DECCHECK
350
/* Optional trace/debugging routines (may or may not be used)  */
351
void decNumberShow(const decNumber *);  /* displays the components of a number  */
352
static void decDumpAr(char, const Unit *, Int);
353
#endif
354
355
/* ================================================================== */
356
/* Conversions                                                        */
357
/* ================================================================== */
358
359
/* ------------------------------------------------------------------ */
360
/* from-int32 -- conversion from Int or uInt                          */
361
/*                                                                    */
362
/*  dn is the decNumber to receive the integer                        */
363
/*  in or uin is the integer to be converted                          */
364
/*  returns dn                                                        */
365
/*                                                                    */
366
/* No error is possible.                                              */
367
/* ------------------------------------------------------------------ */
368
0
U_CAPI decNumber * U_EXPORT2 uprv_decNumberFromInt32(decNumber *dn, Int in) {
369
0
  uInt unsig;
370
0
  if (in>=0) unsig=in;
371
0
   else {                               /* negative (possibly BADINT)  */
372
0
    if (in==BADINT) unsig=(uInt)1073741824*2; /* special case  */
373
0
     else unsig=-in;                    /* invert  */
374
0
    }
375
  /* in is now positive  */
376
0
  uprv_decNumberFromUInt32(dn, unsig);
377
0
  if (in<0) dn->bits=DECNEG;            /* sign needed  */
378
0
  return dn;
379
0
  } /* decNumberFromInt32  */
380
381
0
U_CAPI decNumber * U_EXPORT2 uprv_decNumberFromUInt32(decNumber *dn, uInt uin) {
382
0
  Unit *up;                             /* work pointer  */
383
0
  uprv_decNumberZero(dn);                    /* clean  */
384
0
  if (uin==0) return dn;                /* [or decGetDigits bad call]  */
385
0
  for (up=dn->lsu; uin>0; up++) {
386
0
    *up=(Unit)(uin%(DECDPUNMAX+1));
387
0
    uin=uin/(DECDPUNMAX+1);
388
0
    }
389
0
  dn->digits=decGetDigits(dn->lsu, static_cast<int32_t>(up - dn->lsu));
390
0
  return dn;
391
0
  } /* decNumberFromUInt32  */
392
393
/* ------------------------------------------------------------------ */
394
/* to-int32 -- conversion to Int or uInt                              */
395
/*                                                                    */
396
/*  dn is the decNumber to convert                                    */
397
/*  set is the context for reporting errors                           */
398
/*  returns the converted decNumber, or 0 if Invalid is set           */
399
/*                                                                    */
400
/* Invalid is set if the decNumber does not have exponent==0 or if    */
401
/* it is a NaN, Infinite, or out-of-range.                            */
402
/* ------------------------------------------------------------------ */
403
0
U_CAPI Int U_EXPORT2 uprv_decNumberToInt32(const decNumber *dn, decContext *set) {
404
  #if DECCHECK
405
  if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
406
  #endif
407
408
  /* special or too many digits, or bad exponent  */
409
0
  if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0) ; /* bad  */
410
0
   else { /* is a finite integer with 10 or fewer digits  */
411
0
    Int d;                         /* work  */
412
0
    const Unit *up;                /* ..  */
413
0
    uInt hi=0, lo;                 /* ..  */
414
0
    up=dn->lsu;                    /* -> lsu  */
415
0
    lo=*up;                        /* get 1 to 9 digits  */
416
    #if DECDPUN>1                  /* split to higher  */
417
      hi=lo/10;
418
      lo=lo%10;
419
    #endif
420
0
    up++;
421
    /* collect remaining Units, if any, into hi  */
422
0
    for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];
423
    /* now low has the lsd, hi the remainder  */
424
0
    if (hi>214748364 || (hi==214748364 && lo>7)) { /* out of range?  */
425
      /* most-negative is a reprieve  */
426
0
      if (dn->bits&DECNEG && hi==214748364 && lo==8) return 0x80000000;
427
      /* bad -- drop through  */
428
0
      }
429
0
     else { /* in-range always  */
430
0
      Int i=X10(hi)+lo;
431
0
      if (dn->bits&DECNEG) return -i;
432
0
      return i;
433
0
      }
434
0
    } /* integer  */
435
0
  uprv_decContextSetStatus(set, DEC_Invalid_operation); /* [may not return]  */
436
0
  return 0;
437
0
  } /* decNumberToInt32  */
438
439
0
U_CAPI uInt U_EXPORT2 uprv_decNumberToUInt32(const decNumber *dn, decContext *set) {
440
  #if DECCHECK
441
  if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
442
  #endif
443
  /* special or too many digits, or bad exponent, or negative (<0)  */
444
0
  if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0
445
0
    || (dn->bits&DECNEG && !ISZERO(dn)));                   /* bad  */
446
0
   else { /* is a finite integer with 10 or fewer digits  */
447
0
    Int d;                         /* work  */
448
0
    const Unit *up;                /* ..  */
449
0
    uInt hi=0, lo;                 /* ..  */
450
0
    up=dn->lsu;                    /* -> lsu  */
451
0
    lo=*up;                        /* get 1 to 9 digits  */
452
    #if DECDPUN>1                  /* split to higher  */
453
      hi=lo/10;
454
      lo=lo%10;
455
    #endif
456
0
    up++;
457
    /* collect remaining Units, if any, into hi  */
458
0
    for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];
459
460
    /* now low has the lsd, hi the remainder  */
461
0
    if (hi>429496729 || (hi==429496729 && lo>5)) ; /* no reprieve possible  */
462
0
     else return X10(hi)+lo;
463
0
    } /* integer  */
464
0
  uprv_decContextSetStatus(set, DEC_Invalid_operation); /* [may not return]  */
465
0
  return 0;
466
0
  } /* decNumberToUInt32  */
467
468
/* ------------------------------------------------------------------ */
469
/* to-scientific-string -- conversion to numeric string               */
470
/* to-engineering-string -- conversion to numeric string              */
471
/*                                                                    */
472
/*   decNumberToString(dn, string);                                   */
473
/*   decNumberToEngString(dn, string);                                */
474
/*                                                                    */
475
/*  dn is the decNumber to convert                                    */
476
/*  string is the string where the result will be laid out            */
477
/*                                                                    */
478
/*  string must be at least dn->digits+14 characters long             */
479
/*                                                                    */
480
/*  No error is possible, and no status can be set.                   */
481
/* ------------------------------------------------------------------ */
482
0
U_CAPI char * U_EXPORT2 uprv_decNumberToString(const decNumber *dn, char *string){
483
0
  decToString(dn, string, 0);
484
0
  return string;
485
0
  } /* DecNumberToString  */
486
487
0
U_CAPI char * U_EXPORT2 uprv_decNumberToEngString(const decNumber *dn, char *string){
488
0
  decToString(dn, string, 1);
489
0
  return string;
490
0
  } /* DecNumberToEngString  */
491
492
/* ------------------------------------------------------------------ */
493
/* to-number -- conversion from numeric string                        */
494
/*                                                                    */
495
/* decNumberFromString -- convert string to decNumber                 */
496
/*   dn        -- the number structure to fill                        */
497
/*   chars[]   -- the string to convert ('\0' terminated)             */
498
/*   set       -- the context used for processing any error,          */
499
/*                determining the maximum precision available         */
500
/*                (set.digits), determining the maximum and minimum   */
501
/*                exponent (set.emax and set.emin), determining if    */
502
/*                extended values are allowed, and checking the       */
503
/*                rounding mode if overflow occurs or rounding is     */
504
/*                needed.                                             */
505
/*                                                                    */
506
/* The length of the coefficient and the size of the exponent are     */
507
/* checked by this routine, so the correct error (Underflow or        */
508
/* Overflow) can be reported or rounding applied, as necessary.       */
509
/*                                                                    */
510
/* If bad syntax is detected, the result will be a quiet NaN.         */
511
/* ------------------------------------------------------------------ */
512
U_CAPI decNumber * U_EXPORT2 uprv_decNumberFromString(decNumber *dn, const char chars[],
513
0
                                decContext *set) {
514
0
  Int   exponent=0;                /* working exponent [assume 0]  */
515
0
  uByte bits=0;                    /* working flags [assume +ve]  */
516
0
  Unit  *res;                      /* where result will be built  */
517
0
  Unit  resbuff[SD2U(DECBUFFER+9)];/* local buffer in case need temporary  */
518
                                   /* [+9 allows for ln() constants]  */
519
0
  Unit  *allocres=nullptr;            /* -> allocated result, iff allocated  */
520
0
  Int   d=0;                       /* count of digits found in decimal part  */
521
0
  const char *dotchar=nullptr;        /* where dot was found  */
522
0
  const char *cfirst=chars;        /* -> first character of decimal part  */
523
0
  const char *last=nullptr;           /* -> last digit of decimal part  */
524
0
  const char *c;                   /* work  */
525
0
  Unit  *up;                       /* ..  */
526
  #if DECDPUN>1
527
  Int   cut, out;                  /* ..  */
528
  #endif
529
0
  Int   residue;                   /* rounding residue  */
530
0
  uInt  status=0;                  /* error code  */
531
532
  #if DECCHECK
533
  if (decCheckOperands(DECUNRESU, DECUNUSED, DECUNUSED, set))
534
    return uprv_decNumberZero(dn);
535
  #endif
536
537
0
  do {                             /* status & malloc protection  */
538
0
    for (c=chars;; c++) {          /* -> input character  */
539
0
      if (*c>='0' && *c<='9') {    /* test for Arabic digit  */
540
0
        last=c;
541
0
        d++;                       /* count of real digits  */
542
0
        continue;                  /* still in decimal part  */
543
0
        }
544
0
      if (*c=='.' && dotchar==nullptr) { /* first '.'  */
545
0
        dotchar=c;                 /* record offset into decimal part  */
546
0
        if (c==cfirst) cfirst++;   /* first digit must follow  */
547
0
        continue;}
548
0
      if (c==chars) {              /* first in string...  */
549
0
        if (*c=='-') {             /* valid - sign  */
550
0
          cfirst++;
551
0
          bits=DECNEG;
552
0
          continue;}
553
0
        if (*c=='+') {             /* valid + sign  */
554
0
          cfirst++;
555
0
          continue;}
556
0
        }
557
      /* *c is not a digit, or a valid +, -, or '.'  */
558
0
      break;
559
0
      } /* c  */
560
561
0
    if (last==nullptr) {              /* no digits yet  */
562
0
      status=DEC_Conversion_syntax;/* assume the worst  */
563
0
      if (*c=='\0') break;         /* and no more to come...  */
564
      #if DECSUBSET
565
      /* if subset then infinities and NaNs are not allowed  */
566
      if (!set->extended) break;   /* hopeless  */
567
      #endif
568
      /* Infinities and NaNs are possible, here  */
569
0
      if (dotchar!=nullptr) break;    /* .. unless had a dot  */
570
0
      uprv_decNumberZero(dn);           /* be optimistic  */
571
0
      if (decBiStr(c, "infinity", "INFINITY")
572
0
       || decBiStr(c, "inf", "INF")) {
573
0
        dn->bits=bits | DECINF;
574
0
        status=0;                  /* is OK  */
575
0
        break; /* all done  */
576
0
        }
577
      /* a NaN expected  */
578
      /* 2003.09.10 NaNs are now permitted to have a sign  */
579
0
      dn->bits=bits | DECNAN;      /* assume simple NaN  */
580
0
      if (*c=='s' || *c=='S') {    /* looks like an sNaN  */
581
0
        c++;
582
0
        dn->bits=bits | DECSNAN;
583
0
        }
584
0
      if (*c!='n' && *c!='N') break;    /* check caseless "NaN"  */
585
0
      c++;
586
0
      if (*c!='a' && *c!='A') break;    /* ..  */
587
0
      c++;
588
0
      if (*c!='n' && *c!='N') break;    /* ..  */
589
0
      c++;
590
      /* now either nothing, or nnnn payload, expected  */
591
      /* -> start of integer and skip leading 0s [including plain 0]  */
592
0
      for (cfirst=c; *cfirst=='0';) cfirst++;
593
0
      if (*cfirst=='\0') {         /* "NaN" or "sNaN", maybe with all 0s  */
594
0
        status=0;                  /* it's good  */
595
0
        break;                     /* ..  */
596
0
        }
597
      /* something other than 0s; setup last and d as usual [no dots]  */
598
0
      for (c=cfirst;; c++, d++) {
599
0
        if (*c<'0' || *c>'9') break; /* test for Arabic digit  */
600
0
        last=c;
601
0
        }
602
0
      if (*c!='\0') break;         /* not all digits  */
603
0
      if (d>set->digits-1) {
604
        /* [NB: payload in a decNumber can be full length unless  */
605
        /* clamped, in which case can only be digits-1]  */
606
0
        if (set->clamp) break;
607
0
        if (d>set->digits) break;
608
0
        } /* too many digits?  */
609
      /* good; drop through to convert the integer to coefficient  */
610
0
      status=0;                    /* syntax is OK  */
611
0
      bits=dn->bits;               /* for copy-back  */
612
0
      } /* last==nullptr  */
613
614
0
     else if (*c!='\0') {          /* more to process...  */
615
      /* had some digits; exponent is only valid sequence now  */
616
0
      Flag nege;                   /* 1=negative exponent  */
617
0
      const char *firstexp;        /* -> first significant exponent digit  */
618
0
      status=DEC_Conversion_syntax;/* assume the worst  */
619
0
      if (*c!='e' && *c!='E') break;
620
      /* Found 'e' or 'E' -- now process explicit exponent */
621
      /* 1998.07.11: sign no longer required  */
622
0
      nege=0;
623
0
      c++;                         /* to (possible) sign  */
624
0
      if (*c=='-') {nege=1; c++;}
625
0
       else if (*c=='+') c++;
626
0
      if (*c=='\0') break;
627
628
0
      for (; *c=='0' && *(c+1)!='\0';) c++;  /* strip insignificant zeros  */
629
0
      firstexp=c;                            /* save exponent digit place  */
630
0
      uInt uexponent = 0;   /* Avoid undefined behavior on signed int overflow */
631
0
      for (; ;c++) {
632
0
        if (*c<'0' || *c>'9') break;         /* not a digit  */
633
0
        uexponent=X10(uexponent)+(uInt)*c-(uInt)'0';
634
0
        } /* c  */
635
0
      exponent = (Int)uexponent;
636
      /* if not now on a '\0', *c must not be a digit  */
637
0
      if (*c!='\0') break;
638
639
      /* (this next test must be after the syntax checks)  */
640
      /* if it was too long the exponent may have wrapped, so check  */
641
      /* carefully and set it to a certain overflow if wrap possible  */
642
0
      if (c>=firstexp+9+1) {
643
0
        if (c>firstexp+9+1 || *firstexp>'1') exponent=DECNUMMAXE*2;
644
        /* [up to 1999999999 is OK, for example 1E-1000000998]  */
645
0
        }
646
0
      if (nege) exponent=-exponent;     /* was negative  */
647
0
      status=0;                         /* is OK  */
648
0
      } /* stuff after digits  */
649
650
    /* Here when whole string has been inspected; syntax is good  */
651
    /* cfirst->first digit (never dot), last->last digit (ditto)  */
652
653
    /* strip leading zeros/dot [leave final 0 if all 0's]  */
654
0
    if (*cfirst=='0') {                 /* [cfirst has stepped over .]  */
655
0
      for (c=cfirst; c<last; c++, cfirst++) {
656
0
        if (*c=='.') continue;          /* ignore dots  */
657
0
        if (*c!='0') break;             /* non-zero found  */
658
0
        d--;                            /* 0 stripped  */
659
0
        } /* c  */
660
      #if DECSUBSET
661
      /* make a rapid exit for easy zeros if !extended  */
662
      if (*cfirst=='0' && !set->extended) {
663
        uprv_decNumberZero(dn);              /* clean result  */
664
        break;                          /* [could be return]  */
665
        }
666
      #endif
667
0
      } /* at least one leading 0  */
668
669
    /* Handle decimal point...  */
670
0
    if (dotchar!=nullptr && dotchar<last)  /* non-trailing '.' found?  */
671
0
      exponent -= static_cast<int32_t>(last-dotchar);         /* adjust exponent  */
672
    /* [we can now ignore the .]  */
673
674
    /* OK, the digits string is good.  Assemble in the decNumber, or in  */
675
    /* a temporary units array if rounding is needed  */
676
0
    if (d<=set->digits) res=dn->lsu;    /* fits into supplied decNumber  */
677
0
     else {                             /* rounding needed  */
678
0
      Int needbytes=D2U(d)*sizeof(Unit);/* bytes needed  */
679
0
      res=resbuff;                      /* assume use local buffer  */
680
0
      if (needbytes>(Int)sizeof(resbuff)) { /* too big for local  */
681
0
        allocres=(Unit *)malloc(needbytes);
682
0
        if (allocres==nullptr) {status|=DEC_Insufficient_storage; break;}
683
0
        res=allocres;
684
0
        }
685
0
      }
686
    /* res now -> number lsu, buffer, or allocated storage for Unit array  */
687
688
    /* Place the coefficient into the selected Unit array  */
689
    /* [this is often 70% of the cost of this function when DECDPUN>1]  */
690
    #if DECDPUN>1
691
    out=0;                         /* accumulator  */
692
    up=res+D2U(d)-1;               /* -> msu  */
693
    cut=d-(up-res)*DECDPUN;        /* digits in top unit  */
694
    for (c=cfirst;; c++) {         /* along the digits  */
695
      if (*c=='.') continue;       /* ignore '.' [don't decrement cut]  */
696
      out=X10(out)+(Int)*c-(Int)'0';
697
      if (c==last) break;          /* done [never get to trailing '.']  */
698
      cut--;
699
      if (cut>0) continue;         /* more for this unit  */
700
      *up=(Unit)out;               /* write unit  */
701
      up--;                        /* prepare for unit below..  */
702
      cut=DECDPUN;                 /* ..  */
703
      out=0;                       /* ..  */
704
      } /* c  */
705
    *up=(Unit)out;                 /* write lsu  */
706
707
    #else
708
    /* DECDPUN==1  */
709
0
    up=res;                        /* -> lsu  */
710
0
    for (c=last; c>=cfirst; c--) { /* over each character, from least  */
711
0
      if (*c=='.') continue;       /* ignore . [don't step up]  */
712
0
      *up=(Unit)((Int)*c-(Int)'0');
713
0
      up++;
714
0
      } /* c  */
715
0
    #endif
716
717
0
    dn->bits=bits;
718
0
    dn->exponent=exponent;
719
0
    dn->digits=d;
720
721
    /* if not in number (too long) shorten into the number  */
722
0
    if (d>set->digits) {
723
0
      residue=0;
724
0
      decSetCoeff(dn, set, res, d, &residue, &status);
725
      /* always check for overflow or subnormal and round as needed  */
726
0
      decFinalize(dn, set, &residue, &status);
727
0
      }
728
0
     else { /* no rounding, but may still have overflow or subnormal  */
729
      /* [these tests are just for performance; finalize repeats them]  */
730
0
      if ((dn->exponent-1<set->emin-dn->digits)
731
0
       || (dn->exponent-1>set->emax-set->digits)) {
732
0
        residue=0;
733
0
        decFinalize(dn, set, &residue, &status);
734
0
        }
735
0
      }
736
    /* decNumberShow(dn);  */
737
0
    } while(0);                         /* [for break]  */
738
739
0
  if (allocres!=nullptr) free(allocres);   /* drop any storage used  */
740
0
  if (status!=0) decStatus(dn, status, set);
741
0
  return dn;
742
0
  } /* decNumberFromString */
743
744
/* ================================================================== */
745
/* Operators                                                          */
746
/* ================================================================== */
747
748
/* ------------------------------------------------------------------ */
749
/* decNumberAbs -- absolute value operator                            */
750
/*                                                                    */
751
/*   This computes C = abs(A)                                         */
752
/*                                                                    */
753
/*   res is C, the result.  C may be A                                */
754
/*   rhs is A                                                         */
755
/*   set is the context                                               */
756
/*                                                                    */
757
/* See also decNumberCopyAbs for a quiet bitwise version of this.     */
758
/* C must have space for set->digits digits.                          */
759
/* ------------------------------------------------------------------ */
760
/* This has the same effect as decNumberPlus unless A is negative,    */
761
/* in which case it has the same effect as decNumberMinus.            */
762
/* ------------------------------------------------------------------ */
763
U_CAPI decNumber * U_EXPORT2 uprv_decNumberAbs(decNumber *res, const decNumber *rhs,
764
0
                         decContext *set) {
765
0
  decNumber dzero;                      /* for 0  */
766
0
  uInt status=0;                        /* accumulator  */
767
768
  #if DECCHECK
769
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
770
  #endif
771
772
0
  uprv_decNumberZero(&dzero);                /* set 0  */
773
0
  dzero.exponent=rhs->exponent;         /* [no coefficient expansion]  */
774
0
  decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status);
775
0
  if (status!=0) decStatus(res, status, set);
776
  #if DECCHECK
777
  decCheckInexact(res, set);
778
  #endif
779
0
  return res;
780
0
  } /* decNumberAbs  */
781
782
/* ------------------------------------------------------------------ */
783
/* decNumberAdd -- add two Numbers                                    */
784
/*                                                                    */
785
/*   This computes C = A + B                                          */
786
/*                                                                    */
787
/*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
788
/*   lhs is A                                                         */
789
/*   rhs is B                                                         */
790
/*   set is the context                                               */
791
/*                                                                    */
792
/* C must have space for set->digits digits.                          */
793
/* ------------------------------------------------------------------ */
794
/* This just calls the routine shared with Subtract                   */
795
U_CAPI decNumber * U_EXPORT2 uprv_decNumberAdd(decNumber *res, const decNumber *lhs,
796
0
                         const decNumber *rhs, decContext *set) {
797
0
  uInt status=0;                        /* accumulator  */
798
0
  decAddOp(res, lhs, rhs, set, 0, &status);
799
0
  if (status!=0) decStatus(res, status, set);
800
  #if DECCHECK
801
  decCheckInexact(res, set);
802
  #endif
803
0
  return res;
804
0
  } /* decNumberAdd  */
805
806
/* ------------------------------------------------------------------ */
807
/* decNumberAnd -- AND two Numbers, digitwise                         */
808
/*                                                                    */
809
/*   This computes C = A & B                                          */
810
/*                                                                    */
811
/*   res is C, the result.  C may be A and/or B (e.g., X=X&X)         */
812
/*   lhs is A                                                         */
813
/*   rhs is B                                                         */
814
/*   set is the context (used for result length and error report)     */
815
/*                                                                    */
816
/* C must have space for set->digits digits.                          */
817
/*                                                                    */
818
/* Logical function restrictions apply (see above); a NaN is          */
819
/* returned with Invalid_operation if a restriction is violated.      */
820
/* ------------------------------------------------------------------ */
821
U_CAPI decNumber * U_EXPORT2 uprv_decNumberAnd(decNumber *res, const decNumber *lhs,
822
0
                         const decNumber *rhs, decContext *set) {
823
0
  const Unit *ua, *ub;                  /* -> operands  */
824
0
  const Unit *msua, *msub;              /* -> operand msus  */
825
0
  Unit *uc,  *msuc;                     /* -> result and its msu  */
826
0
  Int   msudigs;                        /* digits in res msu  */
827
  #if DECCHECK
828
  if (decCheckOperands(res, lhs, rhs, set)) return res;
829
  #endif
830
831
0
  if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
832
0
   || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
833
0
    decStatus(res, DEC_Invalid_operation, set);
834
0
    return res;
835
0
    }
836
837
  /* operands are valid  */
838
0
  ua=lhs->lsu;                          /* bottom-up  */
839
0
  ub=rhs->lsu;                          /* ..  */
840
0
  uc=res->lsu;                          /* ..  */
841
0
  msua=ua+D2U(lhs->digits)-1;           /* -> msu of lhs  */
842
0
  msub=ub+D2U(rhs->digits)-1;           /* -> msu of rhs  */
843
0
  msuc=uc+D2U(set->digits)-1;           /* -> msu of result  */
844
0
  msudigs=MSUDIGITS(set->digits);       /* [faster than remainder]  */
845
0
  for (; uc<=msuc; ua++, ub++, uc++) {  /* Unit loop  */
846
0
    Unit a, b;                          /* extract units  */
847
0
    if (ua>msua) a=0;
848
0
     else a=*ua;
849
0
    if (ub>msub) b=0;
850
0
     else b=*ub;
851
0
    *uc=0;                              /* can now write back  */
852
0
    if (a|b) {                          /* maybe 1 bits to examine  */
853
0
      Int i, j;
854
0
      *uc=0;                            /* can now write back  */
855
      /* This loop could be unrolled and/or use BIN2BCD tables  */
856
0
      for (i=0; i<DECDPUN; i++) {
857
0
        if (a&b&1) *uc=*uc+(Unit)powers[i];  /* effect AND  */
858
0
        j=a%10;
859
0
        a=a/10;
860
0
        j|=b%10;
861
0
        b=b/10;
862
0
        if (j>1) {
863
0
          decStatus(res, DEC_Invalid_operation, set);
864
0
          return res;
865
0
          }
866
0
        if (uc==msuc && i==msudigs-1) break; /* just did final digit  */
867
0
        } /* each digit  */
868
0
      } /* both OK  */
869
0
    } /* each unit  */
870
  /* [here uc-1 is the msu of the result]  */
871
0
  res->digits=decGetDigits(res->lsu, static_cast<int32_t>(uc - res->lsu));
872
0
  res->exponent=0;                      /* integer  */
873
0
  res->bits=0;                          /* sign=0  */
874
0
  return res;  /* [no status to set]  */
875
0
  } /* decNumberAnd  */
876
877
/* ------------------------------------------------------------------ */
878
/* decNumberCompare -- compare two Numbers                            */
879
/*                                                                    */
880
/*   This computes C = A ? B                                          */
881
/*                                                                    */
882
/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
883
/*   lhs is A                                                         */
884
/*   rhs is B                                                         */
885
/*   set is the context                                               */
886
/*                                                                    */
887
/* C must have space for one digit (or NaN).                          */
888
/* ------------------------------------------------------------------ */
889
U_CAPI decNumber * U_EXPORT2 uprv_decNumberCompare(decNumber *res, const decNumber *lhs,
890
0
                             const decNumber *rhs, decContext *set) {
891
0
  uInt status=0;                        /* accumulator  */
892
0
  decCompareOp(res, lhs, rhs, set, COMPARE, &status);
893
0
  if (status!=0) decStatus(res, status, set);
894
0
  return res;
895
0
  } /* decNumberCompare  */
896
897
/* ------------------------------------------------------------------ */
898
/* decNumberCompareSignal -- compare, signalling on all NaNs          */
899
/*                                                                    */
900
/*   This computes C = A ? B                                          */
901
/*                                                                    */
902
/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
903
/*   lhs is A                                                         */
904
/*   rhs is B                                                         */
905
/*   set is the context                                               */
906
/*                                                                    */
907
/* C must have space for one digit (or NaN).                          */
908
/* ------------------------------------------------------------------ */
909
U_CAPI decNumber * U_EXPORT2 uprv_decNumberCompareSignal(decNumber *res, const decNumber *lhs,
910
0
                                   const decNumber *rhs, decContext *set) {
911
0
  uInt status=0;                        /* accumulator  */
912
0
  decCompareOp(res, lhs, rhs, set, COMPSIG, &status);
913
0
  if (status!=0) decStatus(res, status, set);
914
0
  return res;
915
0
  } /* decNumberCompareSignal  */
916
917
/* ------------------------------------------------------------------ */
918
/* decNumberCompareTotal -- compare two Numbers, using total ordering */
919
/*                                                                    */
920
/*   This computes C = A ? B, under total ordering                    */
921
/*                                                                    */
922
/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
923
/*   lhs is A                                                         */
924
/*   rhs is B                                                         */
925
/*   set is the context                                               */
926
/*                                                                    */
927
/* C must have space for one digit; the result will always be one of  */
928
/* -1, 0, or 1.                                                       */
929
/* ------------------------------------------------------------------ */
930
U_CAPI decNumber * U_EXPORT2 uprv_decNumberCompareTotal(decNumber *res, const decNumber *lhs,
931
0
                                  const decNumber *rhs, decContext *set) {
932
0
  uInt status=0;                        /* accumulator  */
933
0
  decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
934
0
  if (status!=0) decStatus(res, status, set);
935
0
  return res;
936
0
  } /* decNumberCompareTotal  */
937
938
/* ------------------------------------------------------------------ */
939
/* decNumberCompareTotalMag -- compare, total ordering of magnitudes  */
940
/*                                                                    */
941
/*   This computes C = |A| ? |B|, under total ordering                */
942
/*                                                                    */
943
/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
944
/*   lhs is A                                                         */
945
/*   rhs is B                                                         */
946
/*   set is the context                                               */
947
/*                                                                    */
948
/* C must have space for one digit; the result will always be one of  */
949
/* -1, 0, or 1.                                                       */
950
/* ------------------------------------------------------------------ */
951
U_CAPI decNumber * U_EXPORT2 uprv_decNumberCompareTotalMag(decNumber *res, const decNumber *lhs,
952
0
                                     const decNumber *rhs, decContext *set) {
953
0
  uInt status=0;                   /* accumulator  */
954
0
  uInt needbytes;                  /* for space calculations  */
955
0
  decNumber bufa[D2N(DECBUFFER+1)];/* +1 in case DECBUFFER=0  */
956
0
  decNumber *allocbufa=nullptr;       /* -> allocated bufa, iff allocated  */
957
0
  decNumber bufb[D2N(DECBUFFER+1)];
958
0
  decNumber *allocbufb=nullptr;       /* -> allocated bufb, iff allocated  */
959
0
  decNumber *a, *b;                /* temporary pointers  */
960
961
  #if DECCHECK
962
  if (decCheckOperands(res, lhs, rhs, set)) return res;
963
  #endif
964
965
0
  do {                                  /* protect allocated storage  */
966
    /* if either is negative, take a copy and absolute  */
967
0
    if (decNumberIsNegative(lhs)) {     /* lhs<0  */
968
0
      a=bufa;
969
0
      needbytes=sizeof(decNumber)+(D2U(lhs->digits)-1)*sizeof(Unit);
970
0
      if (needbytes>sizeof(bufa)) {     /* need malloc space  */
971
0
        allocbufa=(decNumber *)malloc(needbytes);
972
0
        if (allocbufa==nullptr) {          /* hopeless -- abandon  */
973
0
          status|=DEC_Insufficient_storage;
974
0
          break;}
975
0
        a=allocbufa;                    /* use the allocated space  */
976
0
        }
977
0
      uprv_decNumberCopy(a, lhs);            /* copy content  */
978
0
      a->bits&=~DECNEG;                 /* .. and clear the sign  */
979
0
      lhs=a;                            /* use copy from here on  */
980
0
      }
981
0
    if (decNumberIsNegative(rhs)) {     /* rhs<0  */
982
0
      b=bufb;
983
0
      needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
984
0
      if (needbytes>sizeof(bufb)) {     /* need malloc space  */
985
0
        allocbufb=(decNumber *)malloc(needbytes);
986
0
        if (allocbufb==nullptr) {          /* hopeless -- abandon  */
987
0
          status|=DEC_Insufficient_storage;
988
0
          break;}
989
0
        b=allocbufb;                    /* use the allocated space  */
990
0
        }
991
0
      uprv_decNumberCopy(b, rhs);            /* copy content  */
992
0
      b->bits&=~DECNEG;                 /* .. and clear the sign  */
993
0
      rhs=b;                            /* use copy from here on  */
994
0
      }
995
0
    decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
996
0
    } while(0);                         /* end protected  */
997
998
0
  if (allocbufa!=nullptr) free(allocbufa); /* drop any storage used  */
999
0
  if (allocbufb!=nullptr) free(allocbufb); /* ..  */
1000
0
  if (status!=0) decStatus(res, status, set);
1001
0
  return res;
1002
0
  } /* decNumberCompareTotalMag  */
1003
1004
/* ------------------------------------------------------------------ */
1005
/* decNumberDivide -- divide one number by another                    */
1006
/*                                                                    */
1007
/*   This computes C = A / B                                          */
1008
/*                                                                    */
1009
/*   res is C, the result.  C may be A and/or B (e.g., X=X/X)         */
1010
/*   lhs is A                                                         */
1011
/*   rhs is B                                                         */
1012
/*   set is the context                                               */
1013
/*                                                                    */
1014
/* C must have space for set->digits digits.                          */
1015
/* ------------------------------------------------------------------ */
1016
U_CAPI decNumber * U_EXPORT2 uprv_decNumberDivide(decNumber *res, const decNumber *lhs,
1017
0
                            const decNumber *rhs, decContext *set) {
1018
0
  uInt status=0;                        /* accumulator  */
1019
0
  decDivideOp(res, lhs, rhs, set, DIVIDE, &status);
1020
0
  if (status!=0) decStatus(res, status, set);
1021
  #if DECCHECK
1022
  decCheckInexact(res, set);
1023
  #endif
1024
0
  return res;
1025
0
  } /* decNumberDivide  */
1026
1027
/* ------------------------------------------------------------------ */
1028
/* decNumberDivideInteger -- divide and return integer quotient       */
1029
/*                                                                    */
1030
/*   This computes C = A # B, where # is the integer divide operator  */
1031
/*                                                                    */
1032
/*   res is C, the result.  C may be A and/or B (e.g., X=X#X)         */
1033
/*   lhs is A                                                         */
1034
/*   rhs is B                                                         */
1035
/*   set is the context                                               */
1036
/*                                                                    */
1037
/* C must have space for set->digits digits.                          */
1038
/* ------------------------------------------------------------------ */
1039
U_CAPI decNumber * U_EXPORT2 uprv_decNumberDivideInteger(decNumber *res, const decNumber *lhs,
1040
0
                                   const decNumber *rhs, decContext *set) {
1041
0
  uInt status=0;                        /* accumulator  */
1042
0
  decDivideOp(res, lhs, rhs, set, DIVIDEINT, &status);
1043
0
  if (status!=0) decStatus(res, status, set);
1044
0
  return res;
1045
0
  } /* decNumberDivideInteger  */
1046
1047
/* ------------------------------------------------------------------ */
1048
/* decNumberExp -- exponentiation                                     */
1049
/*                                                                    */
1050
/*   This computes C = exp(A)                                         */
1051
/*                                                                    */
1052
/*   res is C, the result.  C may be A                                */
1053
/*   rhs is A                                                         */
1054
/*   set is the context; note that rounding mode has no effect        */
1055
/*                                                                    */
1056
/* C must have space for set->digits digits.                          */
1057
/*                                                                    */
1058
/* Mathematical function restrictions apply (see above); a NaN is     */
1059
/* returned with Invalid_operation if a restriction is violated.      */
1060
/*                                                                    */
1061
/* Finite results will always be full precision and Inexact, except   */
1062
/* when A is a zero or -Infinity (giving 1 or 0 respectively).        */
1063
/*                                                                    */
1064
/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
1065
/* almost always be correctly rounded, but may be up to 1 ulp in      */
1066
/* error in rare cases.                                               */
1067
/* ------------------------------------------------------------------ */
1068
/* This is a wrapper for decExpOp which can handle the slightly wider */
1069
/* (double) range needed by Ln (which has to be able to calculate     */
1070
/* exp(-a) where a can be the tiniest number (Ntiny).                 */
1071
/* ------------------------------------------------------------------ */
1072
U_CAPI decNumber * U_EXPORT2 uprv_decNumberExp(decNumber *res, const decNumber *rhs,
1073
0
                         decContext *set) {
1074
0
  uInt status=0;                        /* accumulator  */
1075
  #if DECSUBSET
1076
  decNumber *allocrhs=nullptr;        /* non-nullptr if rounded rhs allocated  */
1077
  #endif
1078
1079
  #if DECCHECK
1080
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1081
  #endif
1082
1083
  /* Check restrictions; these restrictions ensure that if h=8 (see  */
1084
  /* decExpOp) then the result will either overflow or underflow to 0.  */
1085
  /* Other math functions restrict the input range, too, for inverses.  */
1086
  /* If not violated then carry out the operation.  */
1087
0
  if (!decCheckMath(rhs, set, &status)) do { /* protect allocation  */
1088
    #if DECSUBSET
1089
    if (!set->extended) {
1090
      /* reduce operand and set lostDigits status, as needed  */
1091
      if (rhs->digits>set->digits) {
1092
        allocrhs=decRoundOperand(rhs, set, &status);
1093
        if (allocrhs==nullptr) break;
1094
        rhs=allocrhs;
1095
        }
1096
      }
1097
    #endif
1098
0
    decExpOp(res, rhs, set, &status);
1099
0
    } while(0);                         /* end protected  */
1100
1101
  #if DECSUBSET
1102
  if (allocrhs !=nullptr) free(allocrhs);  /* drop any storage used  */
1103
  #endif
1104
  /* apply significant status  */
1105
0
  if (status!=0) decStatus(res, status, set);
1106
  #if DECCHECK
1107
  decCheckInexact(res, set);
1108
  #endif
1109
0
  return res;
1110
0
  } /* decNumberExp  */
1111
1112
/* ------------------------------------------------------------------ */
1113
/* decNumberFMA -- fused multiply add                                 */
1114
/*                                                                    */
1115
/*   This computes D = (A * B) + C with only one rounding             */
1116
/*                                                                    */
1117
/*   res is D, the result.  D may be A or B or C (e.g., X=FMA(X,X,X)) */
1118
/*   lhs is A                                                         */
1119
/*   rhs is B                                                         */
1120
/*   fhs is C [far hand side]                                         */
1121
/*   set is the context                                               */
1122
/*                                                                    */
1123
/* Mathematical function restrictions apply (see above); a NaN is     */
1124
/* returned with Invalid_operation if a restriction is violated.      */
1125
/*                                                                    */
1126
/* C must have space for set->digits digits.                          */
1127
/* ------------------------------------------------------------------ */
1128
U_CAPI decNumber * U_EXPORT2 uprv_decNumberFMA(decNumber *res, const decNumber *lhs,
1129
                         const decNumber *rhs, const decNumber *fhs,
1130
0
                         decContext *set) {
1131
0
  uInt status=0;                   /* accumulator  */
1132
0
  decContext dcmul;                /* context for the multiplication  */
1133
0
  uInt needbytes;                  /* for space calculations  */
1134
0
  decNumber bufa[D2N(DECBUFFER*2+1)];
1135
0
  decNumber *allocbufa=nullptr;       /* -> allocated bufa, iff allocated  */
1136
0
  decNumber *acc;                  /* accumulator pointer  */
1137
0
  decNumber dzero;                 /* work  */
1138
1139
  #if DECCHECK
1140
  if (decCheckOperands(res, lhs, rhs, set)) return res;
1141
  if (decCheckOperands(res, fhs, DECUNUSED, set)) return res;
1142
  #endif
1143
1144
0
  do {                                  /* protect allocated storage  */
1145
    #if DECSUBSET
1146
    if (!set->extended) {               /* [undefined if subset]  */
1147
      status|=DEC_Invalid_operation;
1148
      break;}
1149
    #endif
1150
    /* Check math restrictions [these ensure no overflow or underflow]  */
1151
0
    if ((!decNumberIsSpecial(lhs) && decCheckMath(lhs, set, &status))
1152
0
     || (!decNumberIsSpecial(rhs) && decCheckMath(rhs, set, &status))
1153
0
     || (!decNumberIsSpecial(fhs) && decCheckMath(fhs, set, &status))) break;
1154
    /* set up context for multiply  */
1155
0
    dcmul=*set;
1156
0
    dcmul.digits=lhs->digits+rhs->digits; /* just enough  */
1157
    /* [The above may be an over-estimate for subset arithmetic, but that's OK]  */
1158
0
    dcmul.emax=DEC_MAX_EMAX;            /* effectively unbounded ..  */
1159
0
    dcmul.emin=DEC_MIN_EMIN;            /* [thanks to Math restrictions]  */
1160
    /* set up decNumber space to receive the result of the multiply  */
1161
0
    acc=bufa;                           /* may fit  */
1162
0
    needbytes=sizeof(decNumber)+(D2U(dcmul.digits)-1)*sizeof(Unit);
1163
0
    if (needbytes>sizeof(bufa)) {       /* need malloc space  */
1164
0
      allocbufa=(decNumber *)malloc(needbytes);
1165
0
      if (allocbufa==nullptr) {            /* hopeless -- abandon  */
1166
0
        status|=DEC_Insufficient_storage;
1167
0
        break;}
1168
0
      acc=allocbufa;                    /* use the allocated space  */
1169
0
      }
1170
    /* multiply with extended range and necessary precision  */
1171
    /*printf("emin=%ld\n", dcmul.emin);  */
1172
0
    decMultiplyOp(acc, lhs, rhs, &dcmul, &status);
1173
    /* Only Invalid operation (from sNaN or Inf * 0) is possible in  */
1174
    /* status; if either is seen than ignore fhs (in case it is  */
1175
    /* another sNaN) and set acc to NaN unless we had an sNaN  */
1176
    /* [decMultiplyOp leaves that to caller]  */
1177
    /* Note sNaN has to go through addOp to shorten payload if  */
1178
    /* necessary  */
1179
0
    if ((status&DEC_Invalid_operation)!=0) {
1180
0
      if (!(status&DEC_sNaN)) {         /* but be true invalid  */
1181
0
        uprv_decNumberZero(res);             /* acc not yet set  */
1182
0
        res->bits=DECNAN;
1183
0
        break;
1184
0
        }
1185
0
      uprv_decNumberZero(&dzero);            /* make 0 (any non-NaN would do)  */
1186
0
      fhs=&dzero;                       /* use that  */
1187
0
      }
1188
    #if DECCHECK
1189
     else { /* multiply was OK  */
1190
      if (status!=0) printf("Status=%08lx after FMA multiply\n", (LI)status);
1191
      }
1192
    #endif
1193
    /* add the third operand and result -> res, and all is done  */
1194
0
    decAddOp(res, acc, fhs, set, 0, &status);
1195
0
    } while(0);                         /* end protected  */
1196
1197
0
  if (allocbufa!=nullptr) free(allocbufa); /* drop any storage used  */
1198
0
  if (status!=0) decStatus(res, status, set);
1199
  #if DECCHECK
1200
  decCheckInexact(res, set);
1201
  #endif
1202
0
  return res;
1203
0
  } /* decNumberFMA  */
1204
1205
/* ------------------------------------------------------------------ */
1206
/* decNumberInvert -- invert a Number, digitwise                      */
1207
/*                                                                    */
1208
/*   This computes C = ~A                                             */
1209
/*                                                                    */
1210
/*   res is C, the result.  C may be A (e.g., X=~X)                   */
1211
/*   rhs is A                                                         */
1212
/*   set is the context (used for result length and error report)     */
1213
/*                                                                    */
1214
/* C must have space for set->digits digits.                          */
1215
/*                                                                    */
1216
/* Logical function restrictions apply (see above); a NaN is          */
1217
/* returned with Invalid_operation if a restriction is violated.      */
1218
/* ------------------------------------------------------------------ */
1219
U_CAPI decNumber * U_EXPORT2 uprv_decNumberInvert(decNumber *res, const decNumber *rhs,
1220
0
                            decContext *set) {
1221
0
  const Unit *ua, *msua;                /* -> operand and its msu  */
1222
0
  Unit  *uc, *msuc;                     /* -> result and its msu  */
1223
0
  Int   msudigs;                        /* digits in res msu  */
1224
  #if DECCHECK
1225
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1226
  #endif
1227
1228
0
  if (rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
1229
0
    decStatus(res, DEC_Invalid_operation, set);
1230
0
    return res;
1231
0
    }
1232
  /* operand is valid  */
1233
0
  ua=rhs->lsu;                          /* bottom-up  */
1234
0
  uc=res->lsu;                          /* ..  */
1235
0
  msua=ua+D2U(rhs->digits)-1;           /* -> msu of rhs  */
1236
0
  msuc=uc+D2U(set->digits)-1;           /* -> msu of result  */
1237
0
  msudigs=MSUDIGITS(set->digits);       /* [faster than remainder]  */
1238
0
  for (; uc<=msuc; ua++, uc++) {        /* Unit loop  */
1239
0
    Unit a;                             /* extract unit  */
1240
0
    Int  i, j;                          /* work  */
1241
0
    if (ua>msua) a=0;
1242
0
     else a=*ua;
1243
0
    *uc=0;                              /* can now write back  */
1244
    /* always need to examine all bits in rhs  */
1245
    /* This loop could be unrolled and/or use BIN2BCD tables  */
1246
0
    for (i=0; i<DECDPUN; i++) {
1247
0
      if ((~a)&1) *uc=*uc+(Unit)powers[i];   /* effect INVERT  */
1248
0
      j=a%10;
1249
0
      a=a/10;
1250
0
      if (j>1) {
1251
0
        decStatus(res, DEC_Invalid_operation, set);
1252
0
        return res;
1253
0
        }
1254
0
      if (uc==msuc && i==msudigs-1) break;   /* just did final digit  */
1255
0
      } /* each digit  */
1256
0
    } /* each unit  */
1257
  /* [here uc-1 is the msu of the result]  */
1258
0
  res->digits=decGetDigits(res->lsu, static_cast<int32_t>(uc - res->lsu));
1259
0
  res->exponent=0;                      /* integer  */
1260
0
  res->bits=0;                          /* sign=0  */
1261
0
  return res;  /* [no status to set]  */
1262
0
  } /* decNumberInvert  */
1263
1264
/* ------------------------------------------------------------------ */
1265
/* decNumberLn -- natural logarithm                                   */
1266
/*                                                                    */
1267
/*   This computes C = ln(A)                                          */
1268
/*                                                                    */
1269
/*   res is C, the result.  C may be A                                */
1270
/*   rhs is A                                                         */
1271
/*   set is the context; note that rounding mode has no effect        */
1272
/*                                                                    */
1273
/* C must have space for set->digits digits.                          */
1274
/*                                                                    */
1275
/* Notable cases:                                                     */
1276
/*   A<0 -> Invalid                                                   */
1277
/*   A=0 -> -Infinity (Exact)                                         */
1278
/*   A=+Infinity -> +Infinity (Exact)                                 */
1279
/*   A=1 exactly -> 0 (Exact)                                         */
1280
/*                                                                    */
1281
/* Mathematical function restrictions apply (see above); a NaN is     */
1282
/* returned with Invalid_operation if a restriction is violated.      */
1283
/*                                                                    */
1284
/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
1285
/* almost always be correctly rounded, but may be up to 1 ulp in      */
1286
/* error in rare cases.                                               */
1287
/* ------------------------------------------------------------------ */
1288
/* This is a wrapper for decLnOp which can handle the slightly wider  */
1289
/* (+11) range needed by Ln, Log10, etc. (which may have to be able   */
1290
/* to calculate at p+e+2).                                            */
1291
/* ------------------------------------------------------------------ */
1292
U_CAPI decNumber * U_EXPORT2 uprv_decNumberLn(decNumber *res, const decNumber *rhs,
1293
0
                        decContext *set) {
1294
0
  uInt status=0;                   /* accumulator  */
1295
  #if DECSUBSET
1296
  decNumber *allocrhs=nullptr;        /* non-nullptr if rounded rhs allocated  */
1297
  #endif
1298
1299
  #if DECCHECK
1300
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1301
  #endif
1302
1303
  /* Check restrictions; this is a math function; if not violated  */
1304
  /* then carry out the operation.  */
1305
0
  if (!decCheckMath(rhs, set, &status)) do { /* protect allocation  */
1306
    #if DECSUBSET
1307
    if (!set->extended) {
1308
      /* reduce operand and set lostDigits status, as needed  */
1309
      if (rhs->digits>set->digits) {
1310
        allocrhs=decRoundOperand(rhs, set, &status);
1311
        if (allocrhs==nullptr) break;
1312
        rhs=allocrhs;
1313
        }
1314
      /* special check in subset for rhs=0  */
1315
      if (ISZERO(rhs)) {                /* +/- zeros -> error  */
1316
        status|=DEC_Invalid_operation;
1317
        break;}
1318
      } /* extended=0  */
1319
    #endif
1320
0
    decLnOp(res, rhs, set, &status);
1321
0
    } while(0);                         /* end protected  */
1322
1323
  #if DECSUBSET
1324
  if (allocrhs !=nullptr) free(allocrhs);  /* drop any storage used  */
1325
  #endif
1326
  /* apply significant status  */
1327
0
  if (status!=0) decStatus(res, status, set);
1328
  #if DECCHECK
1329
  decCheckInexact(res, set);
1330
  #endif
1331
0
  return res;
1332
0
  } /* decNumberLn  */
1333
1334
/* ------------------------------------------------------------------ */
1335
/* decNumberLogB - get adjusted exponent, by 754 rules                */
1336
/*                                                                    */
1337
/*   This computes C = adjustedexponent(A)                            */
1338
/*                                                                    */
1339
/*   res is C, the result.  C may be A                                */
1340
/*   rhs is A                                                         */
1341
/*   set is the context, used only for digits and status              */
1342
/*                                                                    */
1343
/* C must have space for 10 digits (A might have 10**9 digits and     */
1344
/* an exponent of +999999999, or one digit and an exponent of         */
1345
/* -1999999999).                                                      */
1346
/*                                                                    */
1347
/* This returns the adjusted exponent of A after (in theory) padding  */
1348
/* with zeros on the right to set->digits digits while keeping the    */
1349
/* same value.  The exponent is not limited by emin/emax.             */
1350
/*                                                                    */
1351
/* Notable cases:                                                     */
1352
/*   A<0 -> Use |A|                                                   */
1353
/*   A=0 -> -Infinity (Division by zero)                              */
1354
/*   A=Infinite -> +Infinity (Exact)                                  */
1355
/*   A=1 exactly -> 0 (Exact)                                         */
1356
/*   NaNs are propagated as usual                                     */
1357
/* ------------------------------------------------------------------ */
1358
U_CAPI decNumber * U_EXPORT2 uprv_decNumberLogB(decNumber *res, const decNumber *rhs,
1359
0
                          decContext *set) {
1360
0
  uInt status=0;                   /* accumulator  */
1361
1362
  #if DECCHECK
1363
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1364
  #endif
1365
1366
  /* NaNs as usual; Infinities return +Infinity; 0->oops  */
1367
0
  if (decNumberIsNaN(rhs)) decNaNs(res, rhs, nullptr, set, &status);
1368
0
   else if (decNumberIsInfinite(rhs)) uprv_decNumberCopyAbs(res, rhs);
1369
0
   else if (decNumberIsZero(rhs)) {
1370
0
    uprv_decNumberZero(res);                 /* prepare for Infinity  */
1371
0
    res->bits=DECNEG|DECINF;            /* -Infinity  */
1372
0
    status|=DEC_Division_by_zero;       /* as per 754  */
1373
0
    }
1374
0
   else { /* finite non-zero  */
1375
0
    Int ae=rhs->exponent+rhs->digits-1; /* adjusted exponent  */
1376
0
    uprv_decNumberFromInt32(res, ae);        /* lay it out  */
1377
0
    }
1378
1379
0
  if (status!=0) decStatus(res, status, set);
1380
0
  return res;
1381
0
  } /* decNumberLogB  */
1382
1383
/* ------------------------------------------------------------------ */
1384
/* decNumberLog10 -- logarithm in base 10                             */
1385
/*                                                                    */
1386
/*   This computes C = log10(A)                                       */
1387
/*                                                                    */
1388
/*   res is C, the result.  C may be A                                */
1389
/*   rhs is A                                                         */
1390
/*   set is the context; note that rounding mode has no effect        */
1391
/*                                                                    */
1392
/* C must have space for set->digits digits.                          */
1393
/*                                                                    */
1394
/* Notable cases:                                                     */
1395
/*   A<0 -> Invalid                                                   */
1396
/*   A=0 -> -Infinity (Exact)                                         */
1397
/*   A=+Infinity -> +Infinity (Exact)                                 */
1398
/*   A=10**n (if n is an integer) -> n (Exact)                        */
1399
/*                                                                    */
1400
/* Mathematical function restrictions apply (see above); a NaN is     */
1401
/* returned with Invalid_operation if a restriction is violated.      */
1402
/*                                                                    */
1403
/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will    */
1404
/* almost always be correctly rounded, but may be up to 1 ulp in      */
1405
/* error in rare cases.                                               */
1406
/* ------------------------------------------------------------------ */
1407
/* This calculates ln(A)/ln(10) using appropriate precision.  For     */
1408
/* ln(A) this is the max(p, rhs->digits + t) + 3, where p is the      */
1409
/* requested digits and t is the number of digits in the exponent     */
1410
/* (maximum 6).  For ln(10) it is p + 3; this is often handled by the */
1411
/* fastpath in decLnOp.  The final division is done to the requested  */
1412
/* precision.                                                         */
1413
/* ------------------------------------------------------------------ */
1414
#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
1415
#pragma GCC diagnostic push
1416
#pragma GCC diagnostic ignored "-Warray-bounds"
1417
#endif
1418
U_CAPI decNumber * U_EXPORT2 uprv_decNumberLog10(decNumber *res, const decNumber *rhs,
1419
0
                          decContext *set) {
1420
0
  uInt status=0, ignore=0;         /* status accumulators  */
1421
0
  uInt needbytes;                  /* for space calculations  */
1422
0
  Int p;                           /* working precision  */
1423
0
  Int t;                           /* digits in exponent of A  */
1424
1425
  /* buffers for a and b working decimals  */
1426
  /* (adjustment calculator, same size)  */
1427
0
  decNumber bufa[D2N(DECBUFFER+2)];
1428
0
  decNumber *allocbufa=nullptr;       /* -> allocated bufa, iff allocated  */
1429
0
  decNumber *a=bufa;               /* temporary a  */
1430
0
  decNumber bufb[D2N(DECBUFFER+2)];
1431
0
  decNumber *allocbufb=nullptr;       /* -> allocated bufb, iff allocated  */
1432
0
  decNumber *b=bufb;               /* temporary b  */
1433
0
  decNumber bufw[D2N(10)];         /* working 2-10 digit number  */
1434
0
  decNumber *w=bufw;               /* ..  */
1435
  #if DECSUBSET
1436
  decNumber *allocrhs=nullptr;        /* non-nullptr if rounded rhs allocated  */
1437
  #endif
1438
1439
0
  decContext aset;                 /* working context  */
1440
1441
  #if DECCHECK
1442
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1443
  #endif
1444
1445
  /* Check restrictions; this is a math function; if not violated  */
1446
  /* then carry out the operation.  */
1447
0
  if (!decCheckMath(rhs, set, &status)) do { /* protect malloc  */
1448
    #if DECSUBSET
1449
    if (!set->extended) {
1450
      /* reduce operand and set lostDigits status, as needed  */
1451
      if (rhs->digits>set->digits) {
1452
        allocrhs=decRoundOperand(rhs, set, &status);
1453
        if (allocrhs==nullptr) break;
1454
        rhs=allocrhs;
1455
        }
1456
      /* special check in subset for rhs=0  */
1457
      if (ISZERO(rhs)) {                /* +/- zeros -> error  */
1458
        status|=DEC_Invalid_operation;
1459
        break;}
1460
      } /* extended=0  */
1461
    #endif
1462
1463
0
    uprv_decContextDefault(&aset, DEC_INIT_DECIMAL64); /* clean context  */
1464
1465
    /* handle exact powers of 10; only check if +ve finite  */
1466
0
    if (!(rhs->bits&(DECNEG|DECSPECIAL)) && !ISZERO(rhs)) {
1467
0
      Int residue=0;               /* (no residue)  */
1468
0
      uInt copystat=0;             /* clean status  */
1469
1470
      /* round to a single digit...  */
1471
0
      aset.digits=1;
1472
0
      decCopyFit(w, rhs, &aset, &residue, &copystat); /* copy & shorten  */
1473
      /* if exact and the digit is 1, rhs is a power of 10  */
1474
0
      if (!(copystat&DEC_Inexact) && w->lsu[0]==1) {
1475
        /* the exponent, conveniently, is the power of 10; making  */
1476
        /* this the result needs a little care as it might not fit,  */
1477
        /* so first convert it into the working number, and then move  */
1478
        /* to res  */
1479
0
        uprv_decNumberFromInt32(w, w->exponent);
1480
0
        residue=0;
1481
0
        decCopyFit(res, w, set, &residue, &status); /* copy & round  */
1482
0
        decFinish(res, set, &residue, &status);     /* cleanup/set flags  */
1483
0
        break;
1484
0
        } /* not a power of 10  */
1485
0
      } /* not a candidate for exact  */
1486
1487
    /* simplify the information-content calculation to use 'total  */
1488
    /* number of digits in a, including exponent' as compared to the  */
1489
    /* requested digits, as increasing this will only rarely cost an  */
1490
    /* iteration in ln(a) anyway  */
1491
0
    t=6;                                /* it can never be >6  */
1492
1493
    /* allocate space when needed...  */
1494
0
    p=(rhs->digits+t>set->digits?rhs->digits+t:set->digits)+3;
1495
0
    needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
1496
0
    if (needbytes>sizeof(bufa)) {       /* need malloc space  */
1497
0
      allocbufa=(decNumber *)malloc(needbytes);
1498
0
      if (allocbufa==nullptr) {            /* hopeless -- abandon  */
1499
0
        status|=DEC_Insufficient_storage;
1500
0
        break;}
1501
0
      a=allocbufa;                      /* use the allocated space  */
1502
0
      }
1503
0
    aset.digits=p;                      /* as calculated  */
1504
0
    aset.emax=DEC_MAX_MATH;             /* usual bounds  */
1505
0
    aset.emin=-DEC_MAX_MATH;            /* ..  */
1506
0
    aset.clamp=0;                       /* and no concrete format  */
1507
0
    decLnOp(a, rhs, &aset, &status);    /* a=ln(rhs)  */
1508
1509
    /* skip the division if the result so far is infinite, NaN, or  */
1510
    /* zero, or there was an error; note NaN from sNaN needs copy  */
1511
0
    if (status&DEC_NaNs && !(status&DEC_sNaN)) break;
1512
0
    if (a->bits&DECSPECIAL || ISZERO(a)) {
1513
0
      uprv_decNumberCopy(res, a);            /* [will fit]  */
1514
0
      break;}
1515
1516
    /* for ln(10) an extra 3 digits of precision are needed  */
1517
0
    p=set->digits+3;
1518
0
    needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
1519
0
    if (needbytes>sizeof(bufb)) {       /* need malloc space  */
1520
0
      allocbufb=(decNumber *)malloc(needbytes);
1521
0
      if (allocbufb==nullptr) {            /* hopeless -- abandon  */
1522
0
        status|=DEC_Insufficient_storage;
1523
0
        break;}
1524
0
      b=allocbufb;                      /* use the allocated space  */
1525
0
      }
1526
0
    uprv_decNumberZero(w);                   /* set up 10...  */
1527
0
    #if DECDPUN==1
1528
0
    w->lsu[1]=1; w->lsu[0]=0;           /* ..  */
1529
    #else
1530
    w->lsu[0]=10;                       /* ..  */
1531
    #endif
1532
0
    w->digits=2;                        /* ..  */
1533
1534
0
    aset.digits=p;
1535
0
    decLnOp(b, w, &aset, &ignore);      /* b=ln(10)  */
1536
1537
0
    aset.digits=set->digits;            /* for final divide  */
1538
0
    decDivideOp(res, a, b, &aset, DIVIDE, &status); /* into result  */
1539
0
    } while(0);                         /* [for break]  */
1540
1541
0
  if (allocbufa!=nullptr) free(allocbufa); /* drop any storage used  */
1542
0
  if (allocbufb!=nullptr) free(allocbufb); /* ..  */
1543
  #if DECSUBSET
1544
  if (allocrhs !=nullptr) free(allocrhs);  /* ..  */
1545
  #endif
1546
  /* apply significant status  */
1547
0
  if (status!=0) decStatus(res, status, set);
1548
  #if DECCHECK
1549
  decCheckInexact(res, set);
1550
  #endif
1551
0
  return res;
1552
0
  } /* decNumberLog10  */
1553
#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
1554
#pragma GCC diagnostic pop
1555
#endif
1556
1557
/* ------------------------------------------------------------------ */
1558
/* decNumberMax -- compare two Numbers and return the maximum         */
1559
/*                                                                    */
1560
/*   This computes C = A ? B, returning the maximum by 754 rules      */
1561
/*                                                                    */
1562
/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
1563
/*   lhs is A                                                         */
1564
/*   rhs is B                                                         */
1565
/*   set is the context                                               */
1566
/*                                                                    */
1567
/* C must have space for set->digits digits.                          */
1568
/* ------------------------------------------------------------------ */
1569
U_CAPI decNumber * U_EXPORT2 uprv_decNumberMax(decNumber *res, const decNumber *lhs,
1570
0
                         const decNumber *rhs, decContext *set) {
1571
0
  uInt status=0;                        /* accumulator  */
1572
0
  decCompareOp(res, lhs, rhs, set, COMPMAX, &status);
1573
0
  if (status!=0) decStatus(res, status, set);
1574
  #if DECCHECK
1575
  decCheckInexact(res, set);
1576
  #endif
1577
0
  return res;
1578
0
  } /* decNumberMax  */
1579
1580
/* ------------------------------------------------------------------ */
1581
/* decNumberMaxMag -- compare and return the maximum by magnitude     */
1582
/*                                                                    */
1583
/*   This computes C = A ? B, returning the maximum by 754 rules      */
1584
/*                                                                    */
1585
/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
1586
/*   lhs is A                                                         */
1587
/*   rhs is B                                                         */
1588
/*   set is the context                                               */
1589
/*                                                                    */
1590
/* C must have space for set->digits digits.                          */
1591
/* ------------------------------------------------------------------ */
1592
U_CAPI decNumber * U_EXPORT2 uprv_decNumberMaxMag(decNumber *res, const decNumber *lhs,
1593
0
                         const decNumber *rhs, decContext *set) {
1594
0
  uInt status=0;                        /* accumulator  */
1595
0
  decCompareOp(res, lhs, rhs, set, COMPMAXMAG, &status);
1596
0
  if (status!=0) decStatus(res, status, set);
1597
  #if DECCHECK
1598
  decCheckInexact(res, set);
1599
  #endif
1600
0
  return res;
1601
0
  } /* decNumberMaxMag  */
1602
1603
/* ------------------------------------------------------------------ */
1604
/* decNumberMin -- compare two Numbers and return the minimum         */
1605
/*                                                                    */
1606
/*   This computes C = A ? B, returning the minimum by 754 rules      */
1607
/*                                                                    */
1608
/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
1609
/*   lhs is A                                                         */
1610
/*   rhs is B                                                         */
1611
/*   set is the context                                               */
1612
/*                                                                    */
1613
/* C must have space for set->digits digits.                          */
1614
/* ------------------------------------------------------------------ */
1615
U_CAPI decNumber * U_EXPORT2 uprv_decNumberMin(decNumber *res, const decNumber *lhs,
1616
0
                         const decNumber *rhs, decContext *set) {
1617
0
  uInt status=0;                        /* accumulator  */
1618
0
  decCompareOp(res, lhs, rhs, set, COMPMIN, &status);
1619
0
  if (status!=0) decStatus(res, status, set);
1620
  #if DECCHECK
1621
  decCheckInexact(res, set);
1622
  #endif
1623
0
  return res;
1624
0
  } /* decNumberMin  */
1625
1626
/* ------------------------------------------------------------------ */
1627
/* decNumberMinMag -- compare and return the minimum by magnitude     */
1628
/*                                                                    */
1629
/*   This computes C = A ? B, returning the minimum by 754 rules      */
1630
/*                                                                    */
1631
/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
1632
/*   lhs is A                                                         */
1633
/*   rhs is B                                                         */
1634
/*   set is the context                                               */
1635
/*                                                                    */
1636
/* C must have space for set->digits digits.                          */
1637
/* ------------------------------------------------------------------ */
1638
U_CAPI decNumber * U_EXPORT2 uprv_decNumberMinMag(decNumber *res, const decNumber *lhs,
1639
0
                         const decNumber *rhs, decContext *set) {
1640
0
  uInt status=0;                        /* accumulator  */
1641
0
  decCompareOp(res, lhs, rhs, set, COMPMINMAG, &status);
1642
0
  if (status!=0) decStatus(res, status, set);
1643
  #if DECCHECK
1644
  decCheckInexact(res, set);
1645
  #endif
1646
0
  return res;
1647
0
  } /* decNumberMinMag  */
1648
1649
/* ------------------------------------------------------------------ */
1650
/* decNumberMinus -- prefix minus operator                            */
1651
/*                                                                    */
1652
/*   This computes C = 0 - A                                          */
1653
/*                                                                    */
1654
/*   res is C, the result.  C may be A                                */
1655
/*   rhs is A                                                         */
1656
/*   set is the context                                               */
1657
/*                                                                    */
1658
/* See also decNumberCopyNegate for a quiet bitwise version of this.  */
1659
/* C must have space for set->digits digits.                          */
1660
/* ------------------------------------------------------------------ */
1661
/* Simply use AddOp for the subtract, which will do the necessary.    */
1662
/* ------------------------------------------------------------------ */
1663
U_CAPI decNumber * U_EXPORT2 uprv_decNumberMinus(decNumber *res, const decNumber *rhs,
1664
0
                           decContext *set) {
1665
0
  decNumber dzero;
1666
0
  uInt status=0;                        /* accumulator  */
1667
1668
  #if DECCHECK
1669
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1670
  #endif
1671
1672
0
  uprv_decNumberZero(&dzero);                /* make 0  */
1673
0
  dzero.exponent=rhs->exponent;         /* [no coefficient expansion]  */
1674
0
  decAddOp(res, &dzero, rhs, set, DECNEG, &status);
1675
0
  if (status!=0) decStatus(res, status, set);
1676
  #if DECCHECK
1677
  decCheckInexact(res, set);
1678
  #endif
1679
0
  return res;
1680
0
  } /* decNumberMinus  */
1681
1682
/* ------------------------------------------------------------------ */
1683
/* decNumberNextMinus -- next towards -Infinity                       */
1684
/*                                                                    */
1685
/*   This computes C = A - infinitesimal, rounded towards -Infinity   */
1686
/*                                                                    */
1687
/*   res is C, the result.  C may be A                                */
1688
/*   rhs is A                                                         */
1689
/*   set is the context                                               */
1690
/*                                                                    */
1691
/* This is a generalization of 754 NextDown.                          */
1692
/* ------------------------------------------------------------------ */
1693
U_CAPI decNumber * U_EXPORT2 uprv_decNumberNextMinus(decNumber *res, const decNumber *rhs,
1694
0
                               decContext *set) {
1695
0
  decNumber dtiny;                           /* constant  */
1696
0
  decContext workset=*set;                   /* work  */
1697
0
  uInt status=0;                             /* accumulator  */
1698
  #if DECCHECK
1699
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1700
  #endif
1701
1702
  /* +Infinity is the special case  */
1703
0
  if ((rhs->bits&(DECINF|DECNEG))==DECINF) {
1704
0
    decSetMaxValue(res, set);                /* is +ve  */
1705
    /* there is no status to set  */
1706
0
    return res;
1707
0
    }
1708
0
  uprv_decNumberZero(&dtiny);                     /* start with 0  */
1709
0
  dtiny.lsu[0]=1;                            /* make number that is ..  */
1710
0
  dtiny.exponent=DEC_MIN_EMIN-1;             /* .. smaller than tiniest  */
1711
0
  workset.round=DEC_ROUND_FLOOR;
1712
0
  decAddOp(res, rhs, &dtiny, &workset, DECNEG, &status);
1713
0
  status&=DEC_Invalid_operation|DEC_sNaN;    /* only sNaN Invalid please  */
1714
0
  if (status!=0) decStatus(res, status, set);
1715
0
  return res;
1716
0
  } /* decNumberNextMinus  */
1717
1718
/* ------------------------------------------------------------------ */
1719
/* decNumberNextPlus -- next towards +Infinity                        */
1720
/*                                                                    */
1721
/*   This computes C = A + infinitesimal, rounded towards +Infinity   */
1722
/*                                                                    */
1723
/*   res is C, the result.  C may be A                                */
1724
/*   rhs is A                                                         */
1725
/*   set is the context                                               */
1726
/*                                                                    */
1727
/* This is a generalization of 754 NextUp.                            */
1728
/* ------------------------------------------------------------------ */
1729
U_CAPI decNumber * U_EXPORT2 uprv_decNumberNextPlus(decNumber *res, const decNumber *rhs,
1730
0
                              decContext *set) {
1731
0
  decNumber dtiny;                           /* constant  */
1732
0
  decContext workset=*set;                   /* work  */
1733
0
  uInt status=0;                             /* accumulator  */
1734
  #if DECCHECK
1735
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1736
  #endif
1737
1738
  /* -Infinity is the special case  */
1739
0
  if ((rhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
1740
0
    decSetMaxValue(res, set);
1741
0
    res->bits=DECNEG;                        /* negative  */
1742
    /* there is no status to set  */
1743
0
    return res;
1744
0
    }
1745
0
  uprv_decNumberZero(&dtiny);                     /* start with 0  */
1746
0
  dtiny.lsu[0]=1;                            /* make number that is ..  */
1747
0
  dtiny.exponent=DEC_MIN_EMIN-1;             /* .. smaller than tiniest  */
1748
0
  workset.round=DEC_ROUND_CEILING;
1749
0
  decAddOp(res, rhs, &dtiny, &workset, 0, &status);
1750
0
  status&=DEC_Invalid_operation|DEC_sNaN;    /* only sNaN Invalid please  */
1751
0
  if (status!=0) decStatus(res, status, set);
1752
0
  return res;
1753
0
  } /* decNumberNextPlus  */
1754
1755
/* ------------------------------------------------------------------ */
1756
/* decNumberNextToward -- next towards rhs                            */
1757
/*                                                                    */
1758
/*   This computes C = A +/- infinitesimal, rounded towards           */
1759
/*   +/-Infinity in the direction of B, as per 754-1985 nextafter     */
1760
/*   modified during revision but dropped from 754-2008.              */
1761
/*                                                                    */
1762
/*   res is C, the result.  C may be A or B.                          */
1763
/*   lhs is A                                                         */
1764
/*   rhs is B                                                         */
1765
/*   set is the context                                               */
1766
/*                                                                    */
1767
/* This is a generalization of 754-1985 NextAfter.                    */
1768
/* ------------------------------------------------------------------ */
1769
U_CAPI decNumber * U_EXPORT2 uprv_decNumberNextToward(decNumber *res, const decNumber *lhs,
1770
0
                                const decNumber *rhs, decContext *set) {
1771
0
  decNumber dtiny;                           /* constant  */
1772
0
  decContext workset=*set;                   /* work  */
1773
0
  Int result;                                /* ..  */
1774
0
  uInt status=0;                             /* accumulator  */
1775
  #if DECCHECK
1776
  if (decCheckOperands(res, lhs, rhs, set)) return res;
1777
  #endif
1778
1779
0
  if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) {
1780
0
    decNaNs(res, lhs, rhs, set, &status);
1781
0
    }
1782
0
   else { /* Is numeric, so no chance of sNaN Invalid, etc.  */
1783
0
    result=decCompare(lhs, rhs, 0);     /* sign matters  */
1784
0
    if (result==BADINT) status|=DEC_Insufficient_storage; /* rare  */
1785
0
     else { /* valid compare  */
1786
0
      if (result==0) uprv_decNumberCopySign(res, lhs, rhs); /* easy  */
1787
0
       else { /* differ: need NextPlus or NextMinus  */
1788
0
        uByte sub;                      /* add or subtract  */
1789
0
        if (result<0) {                 /* lhs<rhs, do nextplus  */
1790
          /* -Infinity is the special case  */
1791
0
          if ((lhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
1792
0
            decSetMaxValue(res, set);
1793
0
            res->bits=DECNEG;           /* negative  */
1794
0
            return res;                 /* there is no status to set  */
1795
0
            }
1796
0
          workset.round=DEC_ROUND_CEILING;
1797
0
          sub=0;                        /* add, please  */
1798
0
          } /* plus  */
1799
0
         else {                         /* lhs>rhs, do nextminus  */
1800
          /* +Infinity is the special case  */
1801
0
          if ((lhs->bits&(DECINF|DECNEG))==DECINF) {
1802
0
            decSetMaxValue(res, set);
1803
0
            return res;                 /* there is no status to set  */
1804
0
            }
1805
0
          workset.round=DEC_ROUND_FLOOR;
1806
0
          sub=DECNEG;                   /* subtract, please  */
1807
0
          } /* minus  */
1808
0
        uprv_decNumberZero(&dtiny);          /* start with 0  */
1809
0
        dtiny.lsu[0]=1;                 /* make number that is ..  */
1810
0
        dtiny.exponent=DEC_MIN_EMIN-1;  /* .. smaller than tiniest  */
1811
0
        decAddOp(res, lhs, &dtiny, &workset, sub, &status); /* + or -  */
1812
        /* turn off exceptions if the result is a normal number  */
1813
        /* (including Nmin), otherwise let all status through  */
1814
0
        if (uprv_decNumberIsNormal(res, set)) status=0;
1815
0
        } /* unequal  */
1816
0
      } /* compare OK  */
1817
0
    } /* numeric  */
1818
0
  if (status!=0) decStatus(res, status, set);
1819
0
  return res;
1820
0
  } /* decNumberNextToward  */
1821
1822
/* ------------------------------------------------------------------ */
1823
/* decNumberOr -- OR two Numbers, digitwise                           */
1824
/*                                                                    */
1825
/*   This computes C = A | B                                          */
1826
/*                                                                    */
1827
/*   res is C, the result.  C may be A and/or B (e.g., X=X|X)         */
1828
/*   lhs is A                                                         */
1829
/*   rhs is B                                                         */
1830
/*   set is the context (used for result length and error report)     */
1831
/*                                                                    */
1832
/* C must have space for set->digits digits.                          */
1833
/*                                                                    */
1834
/* Logical function restrictions apply (see above); a NaN is          */
1835
/* returned with Invalid_operation if a restriction is violated.      */
1836
/* ------------------------------------------------------------------ */
1837
U_CAPI decNumber * U_EXPORT2 uprv_decNumberOr(decNumber *res, const decNumber *lhs,
1838
0
                        const decNumber *rhs, decContext *set) {
1839
0
  const Unit *ua, *ub;                  /* -> operands  */
1840
0
  const Unit *msua, *msub;              /* -> operand msus  */
1841
0
  Unit  *uc, *msuc;                     /* -> result and its msu  */
1842
0
  Int   msudigs;                        /* digits in res msu  */
1843
  #if DECCHECK
1844
  if (decCheckOperands(res, lhs, rhs, set)) return res;
1845
  #endif
1846
1847
0
  if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
1848
0
   || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
1849
0
    decStatus(res, DEC_Invalid_operation, set);
1850
0
    return res;
1851
0
    }
1852
  /* operands are valid  */
1853
0
  ua=lhs->lsu;                          /* bottom-up  */
1854
0
  ub=rhs->lsu;                          /* ..  */
1855
0
  uc=res->lsu;                          /* ..  */
1856
0
  msua=ua+D2U(lhs->digits)-1;           /* -> msu of lhs  */
1857
0
  msub=ub+D2U(rhs->digits)-1;           /* -> msu of rhs  */
1858
0
  msuc=uc+D2U(set->digits)-1;           /* -> msu of result  */
1859
0
  msudigs=MSUDIGITS(set->digits);       /* [faster than remainder]  */
1860
0
  for (; uc<=msuc; ua++, ub++, uc++) {  /* Unit loop  */
1861
0
    Unit a, b;                          /* extract units  */
1862
0
    if (ua>msua) a=0;
1863
0
     else a=*ua;
1864
0
    if (ub>msub) b=0;
1865
0
     else b=*ub;
1866
0
    *uc=0;                              /* can now write back  */
1867
0
    if (a|b) {                          /* maybe 1 bits to examine  */
1868
0
      Int i, j;
1869
      /* This loop could be unrolled and/or use BIN2BCD tables  */
1870
0
      for (i=0; i<DECDPUN; i++) {
1871
0
        if ((a|b)&1) *uc=*uc+(Unit)powers[i];     /* effect OR  */
1872
0
        j=a%10;
1873
0
        a=a/10;
1874
0
        j|=b%10;
1875
0
        b=b/10;
1876
0
        if (j>1) {
1877
0
          decStatus(res, DEC_Invalid_operation, set);
1878
0
          return res;
1879
0
          }
1880
0
        if (uc==msuc && i==msudigs-1) break;      /* just did final digit  */
1881
0
        } /* each digit  */
1882
0
      } /* non-zero  */
1883
0
    } /* each unit  */
1884
  /* [here uc-1 is the msu of the result]  */
1885
0
  res->digits=decGetDigits(res->lsu, static_cast<int32_t>(uc-res->lsu));
1886
0
  res->exponent=0;                      /* integer  */
1887
0
  res->bits=0;                          /* sign=0  */
1888
0
  return res;  /* [no status to set]  */
1889
0
  } /* decNumberOr  */
1890
1891
/* ------------------------------------------------------------------ */
1892
/* decNumberPlus -- prefix plus operator                              */
1893
/*                                                                    */
1894
/*   This computes C = 0 + A                                          */
1895
/*                                                                    */
1896
/*   res is C, the result.  C may be A                                */
1897
/*   rhs is A                                                         */
1898
/*   set is the context                                               */
1899
/*                                                                    */
1900
/* See also decNumberCopy for a quiet bitwise version of this.        */
1901
/* C must have space for set->digits digits.                          */
1902
/* ------------------------------------------------------------------ */
1903
/* This simply uses AddOp; Add will take fast path after preparing A. */
1904
/* Performance is a concern here, as this routine is often used to    */
1905
/* check operands and apply rounding and overflow/underflow testing.  */
1906
/* ------------------------------------------------------------------ */
1907
U_CAPI decNumber * U_EXPORT2 uprv_decNumberPlus(decNumber *res, const decNumber *rhs,
1908
0
                          decContext *set) {
1909
0
  decNumber dzero;
1910
0
  uInt status=0;                        /* accumulator  */
1911
  #if DECCHECK
1912
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1913
  #endif
1914
1915
0
  uprv_decNumberZero(&dzero);                /* make 0  */
1916
0
  dzero.exponent=rhs->exponent;         /* [no coefficient expansion]  */
1917
0
  decAddOp(res, &dzero, rhs, set, 0, &status);
1918
0
  if (status!=0) decStatus(res, status, set);
1919
  #if DECCHECK
1920
  decCheckInexact(res, set);
1921
  #endif
1922
0
  return res;
1923
0
  } /* decNumberPlus  */
1924
1925
/* ------------------------------------------------------------------ */
1926
/* decNumberMultiply -- multiply two Numbers                          */
1927
/*                                                                    */
1928
/*   This computes C = A x B                                          */
1929
/*                                                                    */
1930
/*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
1931
/*   lhs is A                                                         */
1932
/*   rhs is B                                                         */
1933
/*   set is the context                                               */
1934
/*                                                                    */
1935
/* C must have space for set->digits digits.                          */
1936
/* ------------------------------------------------------------------ */
1937
U_CAPI decNumber * U_EXPORT2 uprv_decNumberMultiply(decNumber *res, const decNumber *lhs,
1938
0
                              const decNumber *rhs, decContext *set) {
1939
0
  uInt status=0;                   /* accumulator  */
1940
0
  decMultiplyOp(res, lhs, rhs, set, &status);
1941
0
  if (status!=0) decStatus(res, status, set);
1942
  #if DECCHECK
1943
  decCheckInexact(res, set);
1944
  #endif
1945
0
  return res;
1946
0
  } /* decNumberMultiply  */
1947
1948
/* ------------------------------------------------------------------ */
1949
/* decNumberPower -- raise a number to a power                        */
1950
/*                                                                    */
1951
/*   This computes C = A ** B                                         */
1952
/*                                                                    */
1953
/*   res is C, the result.  C may be A and/or B (e.g., X=X**X)        */
1954
/*   lhs is A                                                         */
1955
/*   rhs is B                                                         */
1956
/*   set is the context                                               */
1957
/*                                                                    */
1958
/* C must have space for set->digits digits.                          */
1959
/*                                                                    */
1960
/* Mathematical function restrictions apply (see above); a NaN is     */
1961
/* returned with Invalid_operation if a restriction is violated.      */
1962
/*                                                                    */
1963
/* However, if 1999999997<=B<=999999999 and B is an integer then the  */
1964
/* restrictions on A and the context are relaxed to the usual bounds, */
1965
/* for compatibility with the earlier (integer power only) version    */
1966
/* of this function.                                                  */
1967
/*                                                                    */
1968
/* When B is an integer, the result may be exact, even if rounded.    */
1969
/*                                                                    */
1970
/* The final result is rounded according to the context; it will      */
1971
/* almost always be correctly rounded, but may be up to 1 ulp in      */
1972
/* error in rare cases.                                               */
1973
/* ------------------------------------------------------------------ */
1974
U_CAPI decNumber * U_EXPORT2 uprv_decNumberPower(decNumber *res, const decNumber *lhs,
1975
0
                           const decNumber *rhs, decContext *set) {
1976
  #if DECSUBSET
1977
  decNumber *alloclhs=nullptr;        /* non-nullptr if rounded lhs allocated  */
1978
  decNumber *allocrhs=nullptr;        /* .., rhs  */
1979
  #endif
1980
0
  decNumber *allocdac=nullptr;        /* -> allocated acc buffer, iff used  */
1981
0
  decNumber *allocinv=nullptr;        /* -> allocated 1/x buffer, iff used  */
1982
0
  Int   reqdigits=set->digits;     /* requested DIGITS  */
1983
0
  Int   n;                         /* rhs in binary  */
1984
0
  Flag  rhsint=0;                  /* 1 if rhs is an integer  */
1985
0
  Flag  useint=0;                  /* 1 if can use integer calculation  */
1986
0
  Flag  isoddint=0;                /* 1 if rhs is an integer and odd  */
1987
0
  Int   i;                         /* work  */
1988
  #if DECSUBSET
1989
  Int   dropped;                   /* ..  */
1990
  #endif
1991
0
  uInt  needbytes;                 /* buffer size needed  */
1992
0
  Flag  seenbit;                   /* seen a bit while powering  */
1993
0
  Int   residue=0;                 /* rounding residue  */
1994
0
  uInt  status=0;                  /* accumulators  */
1995
0
  uByte bits=0;                    /* result sign if errors  */
1996
0
  decContext aset;                 /* working context  */
1997
0
  decNumber dnOne;                 /* work value 1...  */
1998
  /* local accumulator buffer [a decNumber, with digits+elength+1 digits]  */
1999
0
  decNumber dacbuff[D2N(DECBUFFER+9)];
2000
0
  decNumber *dac=dacbuff;          /* -> result accumulator  */
2001
  /* same again for possible 1/lhs calculation  */
2002
0
  decNumber invbuff[D2N(DECBUFFER+9)];
2003
2004
  #if DECCHECK
2005
  if (decCheckOperands(res, lhs, rhs, set)) return res;
2006
  #endif
2007
2008
0
  do {                             /* protect allocated storage  */
2009
    #if DECSUBSET
2010
    if (!set->extended) { /* reduce operands and set status, as needed  */
2011
      if (lhs->digits>reqdigits) {
2012
        alloclhs=decRoundOperand(lhs, set, &status);
2013
        if (alloclhs==nullptr) break;
2014
        lhs=alloclhs;
2015
        }
2016
      if (rhs->digits>reqdigits) {
2017
        allocrhs=decRoundOperand(rhs, set, &status);
2018
        if (allocrhs==nullptr) break;
2019
        rhs=allocrhs;
2020
        }
2021
      }
2022
    #endif
2023
    /* [following code does not require input rounding]  */
2024
2025
    /* handle NaNs and rhs Infinity (lhs infinity is harder)  */
2026
0
    if (SPECIALARGS) {
2027
0
      if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) { /* NaNs  */
2028
0
        decNaNs(res, lhs, rhs, set, &status);
2029
0
        break;}
2030
0
      if (decNumberIsInfinite(rhs)) {   /* rhs Infinity  */
2031
0
        Flag rhsneg=rhs->bits&DECNEG;   /* save rhs sign  */
2032
0
        if (decNumberIsNegative(lhs)    /* lhs<0  */
2033
0
         && !decNumberIsZero(lhs))      /* ..  */
2034
0
          status|=DEC_Invalid_operation;
2035
0
         else {                         /* lhs >=0  */
2036
0
          uprv_decNumberZero(&dnOne);        /* set up 1  */
2037
0
          dnOne.lsu[0]=1;
2038
0
          uprv_decNumberCompare(dac, lhs, &dnOne, set); /* lhs ? 1  */
2039
0
          uprv_decNumberZero(res);           /* prepare for 0/1/Infinity  */
2040
0
          if (decNumberIsNegative(dac)) {    /* lhs<1  */
2041
0
            if (rhsneg) res->bits|=DECINF;   /* +Infinity [else is +0]  */
2042
0
            }
2043
0
           else if (dac->lsu[0]==0) {        /* lhs=1  */
2044
            /* 1**Infinity is inexact, so return fully-padded 1.0000  */
2045
0
            Int shift=set->digits-1;
2046
0
            *res->lsu=1;                     /* was 0, make int 1  */
2047
0
            res->digits=decShiftToMost(res->lsu, 1, shift);
2048
0
            res->exponent=-shift;            /* make 1.0000...  */
2049
0
            status|=DEC_Inexact|DEC_Rounded; /* deemed inexact  */
2050
0
            }
2051
0
           else {                            /* lhs>1  */
2052
0
            if (!rhsneg) res->bits|=DECINF;  /* +Infinity [else is +0]  */
2053
0
            }
2054
0
          } /* lhs>=0  */
2055
0
        break;}
2056
      /* [lhs infinity drops through]  */
2057
0
      } /* specials  */
2058
2059
    /* Original rhs may be an integer that fits and is in range  */
2060
0
    n=decGetInt(rhs);
2061
0
    if (n!=BADINT) {                    /* it is an integer  */
2062
0
      rhsint=1;                         /* record the fact for 1**n  */
2063
0
      isoddint=(Flag)n&1;               /* [works even if big]  */
2064
0
      if (n!=BIGEVEN && n!=BIGODD)      /* can use integer path?  */
2065
0
        useint=1;                       /* looks good  */
2066
0
      }
2067
2068
0
    if (decNumberIsNegative(lhs)        /* -x ..  */
2069
0
      && isoddint) bits=DECNEG;         /* .. to an odd power  */
2070
2071
    /* handle LHS infinity  */
2072
0
    if (decNumberIsInfinite(lhs)) {     /* [NaNs already handled]  */
2073
0
      uByte rbits=rhs->bits;            /* save  */
2074
0
      uprv_decNumberZero(res);               /* prepare  */
2075
0
      if (n==0) *res->lsu=1;            /* [-]Inf**0 => 1  */
2076
0
       else {
2077
        /* -Inf**nonint -> error  */
2078
0
        if (!rhsint && decNumberIsNegative(lhs)) {
2079
0
          status|=DEC_Invalid_operation;     /* -Inf**nonint is error  */
2080
0
          break;}
2081
0
        if (!(rbits & DECNEG)) bits|=DECINF; /* was not a **-n  */
2082
        /* [otherwise will be 0 or -0]  */
2083
0
        res->bits=bits;
2084
0
        }
2085
0
      break;}
2086
2087
    /* similarly handle LHS zero  */
2088
0
    if (decNumberIsZero(lhs)) {
2089
0
      if (n==0) {                            /* 0**0 => Error  */
2090
        #if DECSUBSET
2091
        if (!set->extended) {                /* [unless subset]  */
2092
          uprv_decNumberZero(res);
2093
          *res->lsu=1;                       /* return 1  */
2094
          break;}
2095
        #endif
2096
0
        status|=DEC_Invalid_operation;
2097
0
        }
2098
0
       else {                                /* 0**x  */
2099
0
        uByte rbits=rhs->bits;               /* save  */
2100
0
        if (rbits & DECNEG) {                /* was a 0**(-n)  */
2101
          #if DECSUBSET
2102
          if (!set->extended) {              /* [bad if subset]  */
2103
            status|=DEC_Invalid_operation;
2104
            break;}
2105
          #endif
2106
0
          bits|=DECINF;
2107
0
          }
2108
0
        uprv_decNumberZero(res);                  /* prepare  */
2109
        /* [otherwise will be 0 or -0]  */
2110
0
        res->bits=bits;
2111
0
        }
2112
0
      break;}
2113
2114
    /* here both lhs and rhs are finite; rhs==0 is handled in the  */
2115
    /* integer path.  Next handle the non-integer cases  */
2116
0
    if (!useint) {                      /* non-integral rhs  */
2117
      /* any -ve lhs is bad, as is either operand or context out of  */
2118
      /* bounds  */
2119
0
      if (decNumberIsNegative(lhs)) {
2120
0
        status|=DEC_Invalid_operation;
2121
0
        break;}
2122
0
      if (decCheckMath(lhs, set, &status)
2123
0
       || decCheckMath(rhs, set, &status)) break; /* variable status  */
2124
2125
0
      uprv_decContextDefault(&aset, DEC_INIT_DECIMAL64); /* clean context  */
2126
0
      aset.emax=DEC_MAX_MATH;           /* usual bounds  */
2127
0
      aset.emin=-DEC_MAX_MATH;          /* ..  */
2128
0
      aset.clamp=0;                     /* and no concrete format  */
2129
2130
      /* calculate the result using exp(ln(lhs)*rhs), which can  */
2131
      /* all be done into the accumulator, dac.  The precision needed  */
2132
      /* is enough to contain the full information in the lhs (which  */
2133
      /* is the total digits, including exponent), or the requested  */
2134
      /* precision, if larger, + 4; 6 is used for the exponent  */
2135
      /* maximum length, and this is also used when it is shorter  */
2136
      /* than the requested digits as it greatly reduces the >0.5 ulp  */
2137
      /* cases at little cost (because Ln doubles digits each  */
2138
      /* iteration so a few extra digits rarely causes an extra  */
2139
      /* iteration)  */
2140
0
      aset.digits=MAXI(lhs->digits, set->digits)+6+4;
2141
0
      } /* non-integer rhs  */
2142
2143
0
     else { /* rhs is in-range integer  */
2144
0
      if (n==0) {                       /* x**0 = 1  */
2145
        /* (0**0 was handled above)  */
2146
0
        uprv_decNumberZero(res);             /* result=1  */
2147
0
        *res->lsu=1;                    /* ..  */
2148
0
        break;}
2149
      /* rhs is a non-zero integer  */
2150
0
      if (n<0) n=-n;                    /* use abs(n)  */
2151
2152
0
      aset=*set;                        /* clone the context  */
2153
0
      aset.round=DEC_ROUND_HALF_EVEN;   /* internally use balanced  */
2154
      /* calculate the working DIGITS  */
2155
0
      aset.digits=reqdigits+(rhs->digits+rhs->exponent)+2;
2156
      #if DECSUBSET
2157
      if (!set->extended) aset.digits--;     /* use classic precision  */
2158
      #endif
2159
      /* it's an error if this is more than can be handled  */
2160
0
      if (aset.digits>DECNUMMAXP) {status|=DEC_Invalid_operation; break;}
2161
0
      } /* integer path  */
2162
2163
    /* aset.digits is the count of digits for the accumulator needed  */
2164
    /* if accumulator is too long for local storage, then allocate  */
2165
0
    needbytes=sizeof(decNumber)+(D2U(aset.digits)-1)*sizeof(Unit);
2166
    /* [needbytes also used below if 1/lhs needed]  */
2167
0
    if (needbytes>sizeof(dacbuff)) {
2168
0
      allocdac=(decNumber *)malloc(needbytes);
2169
0
      if (allocdac==nullptr) {   /* hopeless -- abandon  */
2170
0
        status|=DEC_Insufficient_storage;
2171
0
        break;}
2172
0
      dac=allocdac;           /* use the allocated space  */
2173
0
      }
2174
    /* here, aset is set up and accumulator is ready for use  */
2175
2176
0
    if (!useint) {                           /* non-integral rhs  */
2177
      /* x ** y; special-case x=1 here as it will otherwise always  */
2178
      /* reduce to integer 1; decLnOp has a fastpath which detects  */
2179
      /* the case of x=1  */
2180
0
      decLnOp(dac, lhs, &aset, &status);     /* dac=ln(lhs)  */
2181
      /* [no error possible, as lhs 0 already handled]  */
2182
0
      if (ISZERO(dac)) {                     /* x==1, 1.0, etc.  */
2183
        /* need to return fully-padded 1.0000 etc., but rhsint->1  */
2184
0
        *dac->lsu=1;                         /* was 0, make int 1  */
2185
0
        if (!rhsint) {                       /* add padding  */
2186
0
          Int shift=set->digits-1;
2187
0
          dac->digits=decShiftToMost(dac->lsu, 1, shift);
2188
0
          dac->exponent=-shift;              /* make 1.0000...  */
2189
0
          status|=DEC_Inexact|DEC_Rounded;   /* deemed inexact  */
2190
0
          }
2191
0
        }
2192
0
       else {
2193
0
        decMultiplyOp(dac, dac, rhs, &aset, &status);  /* dac=dac*rhs  */
2194
0
        decExpOp(dac, dac, &aset, &status);            /* dac=exp(dac)  */
2195
0
        }
2196
      /* and drop through for final rounding  */
2197
0
      } /* non-integer rhs  */
2198
2199
0
     else {                             /* carry on with integer  */
2200
0
      uprv_decNumberZero(dac);               /* acc=1  */
2201
0
      *dac->lsu=1;                      /* ..  */
2202
2203
      /* if a negative power the constant 1 is needed, and if not subset  */
2204
      /* invert the lhs now rather than inverting the result later  */
2205
0
      if (decNumberIsNegative(rhs)) {   /* was a **-n [hence digits>0]  */
2206
0
        decNumber *inv=invbuff;         /* assume use fixed buffer  */
2207
0
        uprv_decNumberCopy(&dnOne, dac);     /* dnOne=1;  [needed now or later]  */
2208
        #if DECSUBSET
2209
        if (set->extended) {            /* need to calculate 1/lhs  */
2210
        #endif
2211
          /* divide lhs into 1, putting result in dac [dac=1/dac]  */
2212
0
          decDivideOp(dac, &dnOne, lhs, &aset, DIVIDE, &status);
2213
          /* now locate or allocate space for the inverted lhs  */
2214
0
          if (needbytes>sizeof(invbuff)) {
2215
0
            allocinv=(decNumber *)malloc(needbytes);
2216
0
            if (allocinv==nullptr) {       /* hopeless -- abandon  */
2217
0
              status|=DEC_Insufficient_storage;
2218
0
              break;}
2219
0
            inv=allocinv;               /* use the allocated space  */
2220
0
            }
2221
          /* [inv now points to big-enough buffer or allocated storage]  */
2222
0
          uprv_decNumberCopy(inv, dac);      /* copy the 1/lhs  */
2223
0
          uprv_decNumberCopy(dac, &dnOne);   /* restore acc=1  */
2224
0
          lhs=inv;                      /* .. and go forward with new lhs  */
2225
        #if DECSUBSET
2226
          }
2227
        #endif
2228
0
        }
2229
2230
      /* Raise-to-the-power loop...  */
2231
0
      seenbit=0;                   /* set once a 1-bit is encountered  */
2232
0
      for (i=1;;i++){              /* for each bit [top bit ignored]  */
2233
        /* abandon if had overflow or terminal underflow  */
2234
0
        if (status & (DEC_Overflow|DEC_Underflow)) { /* interesting?  */
2235
0
          if (status&DEC_Overflow || ISZERO(dac)) break;
2236
0
          }
2237
        /* [the following two lines revealed an optimizer bug in a C++  */
2238
        /* compiler, with symptom: 5**3 -> 25, when n=n+n was used]  */
2239
0
        n=n<<1;                    /* move next bit to testable position  */
2240
0
        if (n<0) {                 /* top bit is set  */
2241
0
          seenbit=1;               /* OK, significant bit seen  */
2242
0
          decMultiplyOp(dac, dac, lhs, &aset, &status); /* dac=dac*x  */
2243
0
          }
2244
0
        if (i==31) break;          /* that was the last bit  */
2245
0
        if (!seenbit) continue;    /* no need to square 1  */
2246
0
        decMultiplyOp(dac, dac, dac, &aset, &status); /* dac=dac*dac [square]  */
2247
0
        } /*i*/ /* 32 bits  */
2248
2249
      /* complete internal overflow or underflow processing  */
2250
0
      if (status & (DEC_Overflow|DEC_Underflow)) {
2251
        #if DECSUBSET
2252
        /* If subset, and power was negative, reverse the kind of -erflow  */
2253
        /* [1/x not yet done]  */
2254
        if (!set->extended && decNumberIsNegative(rhs)) {
2255
          if (status & DEC_Overflow)
2256
            status^=DEC_Overflow | DEC_Underflow | DEC_Subnormal;
2257
           else { /* trickier -- Underflow may or may not be set  */
2258
            status&=~(DEC_Underflow | DEC_Subnormal); /* [one or both]  */
2259
            status|=DEC_Overflow;
2260
            }
2261
          }
2262
        #endif
2263
0
        dac->bits=(dac->bits & ~DECNEG) | bits; /* force correct sign  */
2264
        /* round subnormals [to set.digits rather than aset.digits]  */
2265
        /* or set overflow result similarly as required  */
2266
0
        decFinalize(dac, set, &residue, &status);
2267
0
        uprv_decNumberCopy(res, dac);   /* copy to result (is now OK length)  */
2268
0
        break;
2269
0
        }
2270
2271
      #if DECSUBSET
2272
      if (!set->extended &&                  /* subset math  */
2273
          decNumberIsNegative(rhs)) {        /* was a **-n [hence digits>0]  */
2274
        /* so divide result into 1 [dac=1/dac]  */
2275
        decDivideOp(dac, &dnOne, dac, &aset, DIVIDE, &status);
2276
        }
2277
      #endif
2278
0
      } /* rhs integer path  */
2279
2280
    /* reduce result to the requested length and copy to result  */
2281
0
    decCopyFit(res, dac, set, &residue, &status);
2282
0
    decFinish(res, set, &residue, &status);  /* final cleanup  */
2283
    #if DECSUBSET
2284
    if (!set->extended) decTrim(res, set, 0, 1, &dropped); /* trailing zeros  */
2285
    #endif
2286
0
    } while(0);                         /* end protected  */
2287
2288
0
  if (allocdac!=nullptr) free(allocdac);   /* drop any storage used  */
2289
0
  if (allocinv!=nullptr) free(allocinv);   /* ..  */
2290
  #if DECSUBSET
2291
  if (alloclhs!=nullptr) free(alloclhs);   /* ..  */
2292
  if (allocrhs!=nullptr) free(allocrhs);   /* ..  */
2293
  #endif
2294
0
  if (status!=0) decStatus(res, status, set);
2295
  #if DECCHECK
2296
  decCheckInexact(res, set);
2297
  #endif
2298
0
  return res;
2299
0
  } /* decNumberPower  */
2300
2301
/* ------------------------------------------------------------------ */
2302
/* decNumberQuantize -- force exponent to requested value             */
2303
/*                                                                    */
2304
/*   This computes C = op(A, B), where op adjusts the coefficient     */
2305
/*   of C (by rounding or shifting) such that the exponent (-scale)   */
2306
/*   of C has exponent of B.  The numerical value of C will equal A,  */
2307
/*   except for the effects of any rounding that occurred.            */
2308
/*                                                                    */
2309
/*   res is C, the result.  C may be A or B                           */
2310
/*   lhs is A, the number to adjust                                   */
2311
/*   rhs is B, the number with exponent to match                      */
2312
/*   set is the context                                               */
2313
/*                                                                    */
2314
/* C must have space for set->digits digits.                          */
2315
/*                                                                    */
2316
/* Unless there is an error or the result is infinite, the exponent   */
2317
/* after the operation is guaranteed to be equal to that of B.        */
2318
/* ------------------------------------------------------------------ */
2319
U_CAPI decNumber * U_EXPORT2 uprv_decNumberQuantize(decNumber *res, const decNumber *lhs,
2320
0
                              const decNumber *rhs, decContext *set) {
2321
0
  uInt status=0;                        /* accumulator  */
2322
0
  decQuantizeOp(res, lhs, rhs, set, 1, &status);
2323
0
  if (status!=0) decStatus(res, status, set);
2324
0
  return res;
2325
0
  } /* decNumberQuantize  */
2326
2327
/* ------------------------------------------------------------------ */
2328
/* decNumberReduce -- remove trailing zeros                           */
2329
/*                                                                    */
2330
/*   This computes C = 0 + A, and normalizes the result               */
2331
/*                                                                    */
2332
/*   res is C, the result.  C may be A                                */
2333
/*   rhs is A                                                         */
2334
/*   set is the context                                               */
2335
/*                                                                    */
2336
/* C must have space for set->digits digits.                          */
2337
/* ------------------------------------------------------------------ */
2338
/* Previously known as Normalize  */
2339
U_CAPI decNumber * U_EXPORT2 uprv_decNumberNormalize(decNumber *res, const decNumber *rhs,
2340
0
                               decContext *set) {
2341
0
  return uprv_decNumberReduce(res, rhs, set);
2342
0
  } /* decNumberNormalize  */
2343
2344
U_CAPI decNumber * U_EXPORT2 uprv_decNumberReduce(decNumber *res, const decNumber *rhs,
2345
0
                            decContext *set) {
2346
  #if DECSUBSET
2347
  decNumber *allocrhs=nullptr;        /* non-nullptr if rounded rhs allocated  */
2348
  #endif
2349
0
  uInt status=0;                   /* as usual  */
2350
0
  Int  residue=0;                  /* as usual  */
2351
0
  Int  dropped;                    /* work  */
2352
2353
  #if DECCHECK
2354
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
2355
  #endif
2356
2357
0
  do {                             /* protect allocated storage  */
2358
    #if DECSUBSET
2359
    if (!set->extended) {
2360
      /* reduce operand and set lostDigits status, as needed  */
2361
      if (rhs->digits>set->digits) {
2362
        allocrhs=decRoundOperand(rhs, set, &status);
2363
        if (allocrhs==nullptr) break;
2364
        rhs=allocrhs;
2365
        }
2366
      }
2367
    #endif
2368
    /* [following code does not require input rounding]  */
2369
2370
    /* Infinities copy through; NaNs need usual treatment  */
2371
0
    if (decNumberIsNaN(rhs)) {
2372
0
      decNaNs(res, rhs, nullptr, set, &status);
2373
0
      break;
2374
0
      }
2375
2376
    /* reduce result to the requested length and copy to result  */
2377
0
    decCopyFit(res, rhs, set, &residue, &status); /* copy & round  */
2378
0
    decFinish(res, set, &residue, &status);       /* cleanup/set flags  */
2379
0
    decTrim(res, set, 1, 0, &dropped);            /* normalize in place  */
2380
                                                  /* [may clamp]  */
2381
0
    } while(0);                              /* end protected  */
2382
2383
  #if DECSUBSET
2384
  if (allocrhs !=nullptr) free(allocrhs);       /* ..  */
2385
  #endif
2386
0
  if (status!=0) decStatus(res, status, set);/* then report status  */
2387
0
  return res;
2388
0
  } /* decNumberReduce  */
2389
2390
/* ------------------------------------------------------------------ */
2391
/* decNumberRescale -- force exponent to requested value              */
2392
/*                                                                    */
2393
/*   This computes C = op(A, B), where op adjusts the coefficient     */
2394
/*   of C (by rounding or shifting) such that the exponent (-scale)   */
2395
/*   of C has the value B.  The numerical value of C will equal A,    */
2396
/*   except for the effects of any rounding that occurred.            */
2397
/*                                                                    */
2398
/*   res is C, the result.  C may be A or B                           */
2399
/*   lhs is A, the number to adjust                                   */
2400
/*   rhs is B, the requested exponent                                 */
2401
/*   set is the context                                               */
2402
/*                                                                    */
2403
/* C must have space for set->digits digits.                          */
2404
/*                                                                    */
2405
/* Unless there is an error or the result is infinite, the exponent   */
2406
/* after the operation is guaranteed to be equal to B.                */
2407
/* ------------------------------------------------------------------ */
2408
U_CAPI decNumber * U_EXPORT2 uprv_decNumberRescale(decNumber *res, const decNumber *lhs,
2409
0
                             const decNumber *rhs, decContext *set) {
2410
0
  uInt status=0;                        /* accumulator  */
2411
0
  decQuantizeOp(res, lhs, rhs, set, 0, &status);
2412
0
  if (status!=0) decStatus(res, status, set);
2413
0
  return res;
2414
0
  } /* decNumberRescale  */
2415
2416
/* ------------------------------------------------------------------ */
2417
/* decNumberRemainder -- divide and return remainder                  */
2418
/*                                                                    */
2419
/*   This computes C = A % B                                          */
2420
/*                                                                    */
2421
/*   res is C, the result.  C may be A and/or B (e.g., X=X%X)         */
2422
/*   lhs is A                                                         */
2423
/*   rhs is B                                                         */
2424
/*   set is the context                                               */
2425
/*                                                                    */
2426
/* C must have space for set->digits digits.                          */
2427
/* ------------------------------------------------------------------ */
2428
U_CAPI decNumber * U_EXPORT2 uprv_decNumberRemainder(decNumber *res, const decNumber *lhs,
2429
0
                               const decNumber *rhs, decContext *set) {
2430
0
  uInt status=0;                        /* accumulator  */
2431
0
  decDivideOp(res, lhs, rhs, set, REMAINDER, &status);
2432
0
  if (status!=0) decStatus(res, status, set);
2433
  #if DECCHECK
2434
  decCheckInexact(res, set);
2435
  #endif
2436
0
  return res;
2437
0
  } /* decNumberRemainder  */
2438
2439
/* ------------------------------------------------------------------ */
2440
/* decNumberRemainderNear -- divide and return remainder from nearest */
2441
/*                                                                    */
2442
/*   This computes C = A % B, where % is the IEEE remainder operator  */
2443
/*                                                                    */
2444
/*   res is C, the result.  C may be A and/or B (e.g., X=X%X)         */
2445
/*   lhs is A                                                         */
2446
/*   rhs is B                                                         */
2447
/*   set is the context                                               */
2448
/*                                                                    */
2449
/* C must have space for set->digits digits.                          */
2450
/* ------------------------------------------------------------------ */
2451
U_CAPI decNumber * U_EXPORT2 uprv_decNumberRemainderNear(decNumber *res, const decNumber *lhs,
2452
0
                                   const decNumber *rhs, decContext *set) {
2453
0
  uInt status=0;                        /* accumulator  */
2454
0
  decDivideOp(res, lhs, rhs, set, REMNEAR, &status);
2455
0
  if (status!=0) decStatus(res, status, set);
2456
  #if DECCHECK
2457
  decCheckInexact(res, set);
2458
  #endif
2459
0
  return res;
2460
0
  } /* decNumberRemainderNear  */
2461
2462
/* ------------------------------------------------------------------ */
2463
/* decNumberRotate -- rotate the coefficient of a Number left/right   */
2464
/*                                                                    */
2465
/*   This computes C = A rot B  (in base ten and rotating set->digits */
2466
/*   digits).                                                         */
2467
/*                                                                    */
2468
/*   res is C, the result.  C may be A and/or B (e.g., X=XrotX)       */
2469
/*   lhs is A                                                         */
2470
/*   rhs is B, the number of digits to rotate (-ve to right)          */
2471
/*   set is the context                                               */
2472
/*                                                                    */
2473
/* The digits of the coefficient of A are rotated to the left (if B   */
2474
/* is positive) or to the right (if B is negative) without adjusting  */
2475
/* the exponent or the sign of A.  If lhs->digits is less than        */
2476
/* set->digits the coefficient is padded with zeros on the left       */
2477
/* before the rotate.  Any leading zeros in the result are removed    */
2478
/* as usual.                                                          */
2479
/*                                                                    */
2480
/* B must be an integer (q=0) and in the range -set->digits through   */
2481
/* +set->digits.                                                      */
2482
/* C must have space for set->digits digits.                          */
2483
/* NaNs are propagated as usual.  Infinities are unaffected (but      */
2484
/* B must be valid).  No status is set unless B is invalid or an      */
2485
/* operand is an sNaN.                                                */
2486
/* ------------------------------------------------------------------ */
2487
U_CAPI decNumber * U_EXPORT2 uprv_decNumberRotate(decNumber *res, const decNumber *lhs,
2488
0
                           const decNumber *rhs, decContext *set) {
2489
0
  uInt status=0;              /* accumulator  */
2490
0
  Int  rotate;                /* rhs as an Int  */
2491
2492
  #if DECCHECK
2493
  if (decCheckOperands(res, lhs, rhs, set)) return res;
2494
  #endif
2495
2496
  /* NaNs propagate as normal  */
2497
0
  if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
2498
0
    decNaNs(res, lhs, rhs, set, &status);
2499
   /* rhs must be an integer  */
2500
0
   else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
2501
0
    status=DEC_Invalid_operation;
2502
0
   else { /* both numeric, rhs is an integer  */
2503
0
    rotate=decGetInt(rhs);                   /* [cannot fail]  */
2504
0
    if (rotate==BADINT                       /* something bad ..  */
2505
0
     || rotate==BIGODD || rotate==BIGEVEN    /* .. very big ..  */
2506
0
     || abs(rotate)>set->digits)             /* .. or out of range  */
2507
0
      status=DEC_Invalid_operation;
2508
0
     else {                                  /* rhs is OK  */
2509
0
      uprv_decNumberCopy(res, lhs);
2510
      /* convert -ve rotate to equivalent positive rotation  */
2511
0
      if (rotate<0) rotate=set->digits+rotate;
2512
0
      if (rotate!=0 && rotate!=set->digits   /* zero or full rotation  */
2513
0
       && !decNumberIsInfinite(res)) {       /* lhs was infinite  */
2514
        /* left-rotate to do; 0 < rotate < set->digits  */
2515
0
        uInt units, shift;                   /* work  */
2516
0
        uInt msudigits;                      /* digits in result msu  */
2517
0
        Unit *msu=res->lsu+D2U(res->digits)-1;    /* current msu  */
2518
0
        Unit *msumax=res->lsu+D2U(set->digits)-1; /* rotation msu  */
2519
0
        for (msu++; msu<=msumax; msu++) *msu=0;   /* ensure high units=0  */
2520
0
        res->digits=set->digits;                  /* now full-length  */
2521
0
        msudigits=MSUDIGITS(res->digits);         /* actual digits in msu  */
2522
2523
        /* rotation here is done in-place, in three steps  */
2524
        /* 1. shift all to least up to one unit to unit-align final  */
2525
        /*    lsd [any digits shifted out are rotated to the left,  */
2526
        /*    abutted to the original msd (which may require split)]  */
2527
        /*  */
2528
        /*    [if there are no whole units left to rotate, the  */
2529
        /*    rotation is now complete]  */
2530
        /*  */
2531
        /* 2. shift to least, from below the split point only, so that  */
2532
        /*    the final msd is in the right place in its Unit [any  */
2533
        /*    digits shifted out will fit exactly in the current msu,  */
2534
        /*    left aligned, no split required]  */
2535
        /*  */
2536
        /* 3. rotate all the units by reversing left part, right  */
2537
        /*    part, and then whole  */
2538
        /*  */
2539
        /* example: rotate right 8 digits (2 units + 2), DECDPUN=3.  */
2540
        /*  */
2541
        /*   start: 00a bcd efg hij klm npq  */
2542
        /*  */
2543
        /*      1a  000 0ab cde fgh|ijk lmn [pq saved]  */
2544
        /*      1b  00p qab cde fgh|ijk lmn  */
2545
        /*  */
2546
        /*      2a  00p qab cde fgh|00i jkl [mn saved]  */
2547
        /*      2b  mnp qab cde fgh|00i jkl  */
2548
        /*  */
2549
        /*      3a  fgh cde qab mnp|00i jkl  */
2550
        /*      3b  fgh cde qab mnp|jkl 00i  */
2551
        /*      3c  00i jkl mnp qab cde fgh  */
2552
2553
        /* Step 1: amount to shift is the partial right-rotate count  */
2554
0
        rotate=set->digits-rotate;      /* make it right-rotate  */
2555
0
        units=rotate/DECDPUN;           /* whole units to rotate  */
2556
0
        shift=rotate%DECDPUN;           /* left-over digits count  */
2557
0
        if (shift>0) {                  /* not an exact number of units  */
2558
0
          uInt save=res->lsu[0]%powers[shift];    /* save low digit(s)  */
2559
0
          decShiftToLeast(res->lsu, D2U(res->digits), shift);
2560
0
          if (shift>msudigits) {        /* msumax-1 needs >0 digits  */
2561
0
            uInt rem=save%powers[shift-msudigits];/* split save  */
2562
0
            *msumax=(Unit)(save/powers[shift-msudigits]); /* and insert  */
2563
0
            *(msumax-1)=*(msumax-1)
2564
0
                       +(Unit)(rem*powers[DECDPUN-(shift-msudigits)]); /* ..  */
2565
0
            }
2566
0
           else { /* all fits in msumax  */
2567
0
            *msumax=*msumax+(Unit)(save*powers[msudigits-shift]); /* [maybe *1]  */
2568
0
            }
2569
0
          } /* digits shift needed  */
2570
2571
        /* If whole units to rotate...  */
2572
0
        if (units>0) {                  /* some to do  */
2573
          /* Step 2: the units to touch are the whole ones in rotate,  */
2574
          /*   if any, and the shift is DECDPUN-msudigits (which may be  */
2575
          /*   0, again)  */
2576
0
          shift=DECDPUN-msudigits;
2577
0
          if (shift>0) {                /* not an exact number of units  */
2578
0
            uInt save=res->lsu[0]%powers[shift];  /* save low digit(s)  */
2579
0
            decShiftToLeast(res->lsu, units, shift);
2580
0
            *msumax=*msumax+(Unit)(save*powers[msudigits]);
2581
0
            } /* partial shift needed  */
2582
2583
          /* Step 3: rotate the units array using triple reverse  */
2584
          /* (reversing is easy and fast)  */
2585
0
          decReverse(res->lsu+units, msumax);     /* left part  */
2586
0
          decReverse(res->lsu, res->lsu+units-1); /* right part  */
2587
0
          decReverse(res->lsu, msumax);           /* whole  */
2588
0
          } /* whole units to rotate  */
2589
        /* the rotation may have left an undetermined number of zeros  */
2590
        /* on the left, so true length needs to be calculated  */
2591
0
        res->digits=decGetDigits(res->lsu, static_cast<int32_t>(msumax-res->lsu+1));
2592
0
        } /* rotate needed  */
2593
0
      } /* rhs OK  */
2594
0
    } /* numerics  */
2595
0
  if (status!=0) decStatus(res, status, set);
2596
0
  return res;
2597
0
  } /* decNumberRotate  */
2598
2599
/* ------------------------------------------------------------------ */
2600
/* decNumberSameQuantum -- test for equal exponents                   */
2601
/*                                                                    */
2602
/*   res is the result number, which will contain either 0 or 1       */
2603
/*   lhs is a number to test                                          */
2604
/*   rhs is the second (usually a pattern)                            */
2605
/*                                                                    */
2606
/* No errors are possible and no context is needed.                   */
2607
/* ------------------------------------------------------------------ */
2608
U_CAPI decNumber * U_EXPORT2 uprv_decNumberSameQuantum(decNumber *res, const decNumber *lhs,
2609
0
                                 const decNumber *rhs) {
2610
0
  Unit ret=0;                      /* return value  */
2611
2612
  #if DECCHECK
2613
  if (decCheckOperands(res, lhs, rhs, DECUNCONT)) return res;
2614
  #endif
2615
2616
0
  if (SPECIALARGS) {
2617
0
    if (decNumberIsNaN(lhs) && decNumberIsNaN(rhs)) ret=1;
2618
0
     else if (decNumberIsInfinite(lhs) && decNumberIsInfinite(rhs)) ret=1;
2619
     /* [anything else with a special gives 0]  */
2620
0
    }
2621
0
   else if (lhs->exponent==rhs->exponent) ret=1;
2622
2623
0
  uprv_decNumberZero(res);              /* OK to overwrite an operand now  */
2624
0
  *res->lsu=ret;
2625
0
  return res;
2626
0
  } /* decNumberSameQuantum  */
2627
2628
/* ------------------------------------------------------------------ */
2629
/* decNumberScaleB -- multiply by a power of 10                       */
2630
/*                                                                    */
2631
/* This computes C = A x 10**B where B is an integer (q=0) with       */
2632
/* maximum magnitude 2*(emax+digits)                                  */
2633
/*                                                                    */
2634
/*   res is C, the result.  C may be A or B                           */
2635
/*   lhs is A, the number to adjust                                   */
2636
/*   rhs is B, the requested power of ten to use                      */
2637
/*   set is the context                                               */
2638
/*                                                                    */
2639
/* C must have space for set->digits digits.                          */
2640
/*                                                                    */
2641
/* The result may underflow or overflow.                              */
2642
/* ------------------------------------------------------------------ */
2643
U_CAPI decNumber * U_EXPORT2 uprv_decNumberScaleB(decNumber *res, const decNumber *lhs,
2644
0
                            const decNumber *rhs, decContext *set) {
2645
0
  Int  reqexp;                /* requested exponent change [B]  */
2646
0
  uInt status=0;              /* accumulator  */
2647
0
  Int  residue;               /* work  */
2648
2649
  #if DECCHECK
2650
  if (decCheckOperands(res, lhs, rhs, set)) return res;
2651
  #endif
2652
2653
  /* Handle special values except lhs infinite  */
2654
0
  if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
2655
0
    decNaNs(res, lhs, rhs, set, &status);
2656
    /* rhs must be an integer  */
2657
0
   else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
2658
0
    status=DEC_Invalid_operation;
2659
0
   else {
2660
    /* lhs is a number; rhs is a finite with q==0  */
2661
0
    reqexp=decGetInt(rhs);                   /* [cannot fail]  */
2662
0
    if (reqexp==BADINT                       /* something bad ..  */
2663
0
     || reqexp==BIGODD || reqexp==BIGEVEN    /* .. very big ..  */
2664
0
     || abs(reqexp)>(2*(set->digits+set->emax))) /* .. or out of range  */
2665
0
      status=DEC_Invalid_operation;
2666
0
     else {                                  /* rhs is OK  */
2667
0
      uprv_decNumberCopy(res, lhs);               /* all done if infinite lhs  */
2668
0
      if (!decNumberIsInfinite(res)) {       /* prepare to scale  */
2669
0
        res->exponent+=reqexp;               /* adjust the exponent  */
2670
0
        residue=0;
2671
0
        decFinalize(res, set, &residue, &status); /* .. and check  */
2672
0
        } /* finite LHS  */
2673
0
      } /* rhs OK  */
2674
0
    } /* rhs finite  */
2675
0
  if (status!=0) decStatus(res, status, set);
2676
0
  return res;
2677
0
  } /* decNumberScaleB  */
2678
2679
/* ------------------------------------------------------------------ */
2680
/* decNumberShift -- shift the coefficient of a Number left or right  */
2681
/*                                                                    */
2682
/*   This computes C = A << B or C = A >> -B  (in base ten).          */
2683
/*                                                                    */
2684
/*   res is C, the result.  C may be A and/or B (e.g., X=X<<X)        */
2685
/*   lhs is A                                                         */
2686
/*   rhs is B, the number of digits to shift (-ve to right)           */
2687
/*   set is the context                                               */
2688
/*                                                                    */
2689
/* The digits of the coefficient of A are shifted to the left (if B   */
2690
/* is positive) or to the right (if B is negative) without adjusting  */
2691
/* the exponent or the sign of A.                                     */
2692
/*                                                                    */
2693
/* B must be an integer (q=0) and in the range -set->digits through   */
2694
/* +set->digits.                                                      */
2695
/* C must have space for set->digits digits.                          */
2696
/* NaNs are propagated as usual.  Infinities are unaffected (but      */
2697
/* B must be valid).  No status is set unless B is invalid or an      */
2698
/* operand is an sNaN.                                                */
2699
/* ------------------------------------------------------------------ */
2700
U_CAPI decNumber * U_EXPORT2 uprv_decNumberShift(decNumber *res, const decNumber *lhs,
2701
0
                           const decNumber *rhs, decContext *set) {
2702
0
  uInt status=0;              /* accumulator  */
2703
0
  Int  shift;                 /* rhs as an Int  */
2704
2705
  #if DECCHECK
2706
  if (decCheckOperands(res, lhs, rhs, set)) return res;
2707
  #endif
2708
2709
  /* NaNs propagate as normal  */
2710
0
  if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
2711
0
    decNaNs(res, lhs, rhs, set, &status);
2712
   /* rhs must be an integer  */
2713
0
   else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
2714
0
    status=DEC_Invalid_operation;
2715
0
   else { /* both numeric, rhs is an integer  */
2716
0
    shift=decGetInt(rhs);                    /* [cannot fail]  */
2717
0
    if (shift==BADINT                        /* something bad ..  */
2718
0
     || shift==BIGODD || shift==BIGEVEN      /* .. very big ..  */
2719
0
     || abs(shift)>set->digits)              /* .. or out of range  */
2720
0
      status=DEC_Invalid_operation;
2721
0
     else {                                  /* rhs is OK  */
2722
0
      uprv_decNumberCopy(res, lhs);
2723
0
      if (shift!=0 && !decNumberIsInfinite(res)) { /* something to do  */
2724
0
        if (shift>0) {                       /* to left  */
2725
0
          if (shift==set->digits) {          /* removing all  */
2726
0
            *res->lsu=0;                     /* so place 0  */
2727
0
            res->digits=1;                   /* ..  */
2728
0
            }
2729
0
           else {                            /*  */
2730
            /* first remove leading digits if necessary  */
2731
0
            if (res->digits+shift>set->digits) {
2732
0
              decDecap(res, res->digits+shift-set->digits);
2733
              /* that updated res->digits; may have gone to 1 (for a  */
2734
              /* single digit or for zero  */
2735
0
              }
2736
0
            if (res->digits>1 || *res->lsu)  /* if non-zero..  */
2737
0
              res->digits=decShiftToMost(res->lsu, res->digits, shift);
2738
0
            } /* partial left  */
2739
0
          } /* left  */
2740
0
         else { /* to right  */
2741
0
          if (-shift>=res->digits) {         /* discarding all  */
2742
0
            *res->lsu=0;                     /* so place 0  */
2743
0
            res->digits=1;                   /* ..  */
2744
0
            }
2745
0
           else {
2746
0
            decShiftToLeast(res->lsu, D2U(res->digits), -shift);
2747
0
            res->digits-=(-shift);
2748
0
            }
2749
0
          } /* to right  */
2750
0
        } /* non-0 non-Inf shift  */
2751
0
      } /* rhs OK  */
2752
0
    } /* numerics  */
2753
0
  if (status!=0) decStatus(res, status, set);
2754
0
  return res;
2755
0
  } /* decNumberShift  */
2756
2757
/* ------------------------------------------------------------------ */
2758
/* decNumberSquareRoot -- square root operator                        */
2759
/*                                                                    */
2760
/*   This computes C = squareroot(A)                                  */
2761
/*                                                                    */
2762
/*   res is C, the result.  C may be A                                */
2763
/*   rhs is A                                                         */
2764
/*   set is the context; note that rounding mode has no effect        */
2765
/*                                                                    */
2766
/* C must have space for set->digits digits.                          */
2767
/* ------------------------------------------------------------------ */
2768
/* This uses the following varying-precision algorithm in:            */
2769
/*                                                                    */
2770
/*   Properly Rounded Variable Precision Square Root, T. E. Hull and  */
2771
/*   A. Abrham, ACM Transactions on Mathematical Software, Vol 11 #3, */
2772
/*   pp229-237, ACM, September 1985.                                  */
2773
/*                                                                    */
2774
/* The square-root is calculated using Newton's method, after which   */
2775
/* a check is made to ensure the result is correctly rounded.         */
2776
/*                                                                    */
2777
/* % [Reformatted original Numerical Turing source code follows.]     */
2778
/* function sqrt(x : real) : real                                     */
2779
/* % sqrt(x) returns the properly rounded approximation to the square */
2780
/* % root of x, in the precision of the calling environment, or it    */
2781
/* % fails if x < 0.                                                  */
2782
/* % t e hull and a abrham, august, 1984                              */
2783
/* if x <= 0 then                                                     */
2784
/*   if x < 0 then                                                    */
2785
/*     assert false                                                   */
2786
/*   else                                                             */
2787
/*     result 0                                                       */
2788
/*   end if                                                           */
2789
/* end if                                                             */
2790
/* var f := setexp(x, 0)  % fraction part of x   [0.1 <= x < 1]       */
2791
/* var e := getexp(x)     % exponent part of x                        */
2792
/* var approx : real                                                  */
2793
/* if e mod 2 = 0  then                                               */
2794
/*   approx := .259 + .819 * f   % approx to root of f                */
2795
/* else                                                               */
2796
/*   f := f/l0                   % adjustments                        */
2797
/*   e := e + 1                  %   for odd                          */
2798
/*   approx := .0819 + 2.59 * f  %   exponent                         */
2799
/* end if                                                             */
2800
/*                                                                    */
2801
/* var p:= 3                                                          */
2802
/* const maxp := currentprecision + 2                                 */
2803
/* loop                                                               */
2804
/*   p := min(2*p - 2, maxp)     % p = 4,6,10, . . . , maxp           */
2805
/*   precision p                                                      */
2806
/*   approx := .5 * (approx + f/approx)                               */
2807
/*   exit when p = maxp                                               */
2808
/* end loop                                                           */
2809
/*                                                                    */
2810
/* % approx is now within 1 ulp of the properly rounded square root   */
2811
/* % of f; to ensure proper rounding, compare squares of (approx -    */
2812
/* % l/2 ulp) and (approx + l/2 ulp) with f.                          */
2813
/* p := currentprecision                                              */
2814
/* begin                                                              */
2815
/*   precision p + 2                                                  */
2816
/*   const approxsubhalf := approx - setexp(.5, -p)                   */
2817
/*   if mulru(approxsubhalf, approxsubhalf) > f then                  */
2818
/*     approx := approx - setexp(.l, -p + 1)                          */
2819
/*   else                                                             */
2820
/*     const approxaddhalf := approx + setexp(.5, -p)                 */
2821
/*     if mulrd(approxaddhalf, approxaddhalf) < f then                */
2822
/*       approx := approx + setexp(.l, -p + 1)                        */
2823
/*     end if                                                         */
2824
/*   end if                                                           */
2825
/* end                                                                */
2826
/* result setexp(approx, e div 2)  % fix exponent                     */
2827
/* end sqrt                                                           */
2828
/* ------------------------------------------------------------------ */
2829
#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
2830
#pragma GCC diagnostic push
2831
#pragma GCC diagnostic ignored "-Warray-bounds"
2832
#endif
2833
U_CAPI decNumber * U_EXPORT2 uprv_decNumberSquareRoot(decNumber *res, const decNumber *rhs,
2834
0
                                decContext *set) {
2835
0
  decContext workset, approxset;   /* work contexts  */
2836
0
  decNumber dzero;                 /* used for constant zero  */
2837
0
  Int  maxp;                       /* largest working precision  */
2838
0
  Int  workp;                      /* working precision  */
2839
0
  Int  residue=0;                  /* rounding residue  */
2840
0
  uInt status=0, ignore=0;         /* status accumulators  */
2841
0
  uInt rstatus;                    /* ..  */
2842
0
  Int  exp;                        /* working exponent  */
2843
0
  Int  ideal;                      /* ideal (preferred) exponent  */
2844
0
  Int  needbytes;                  /* work  */
2845
0
  Int  dropped;                    /* ..  */
2846
2847
  #if DECSUBSET
2848
  decNumber *allocrhs=nullptr;        /* non-nullptr if rounded rhs allocated  */
2849
  #endif
2850
  /* buffer for f [needs +1 in case DECBUFFER 0]  */
2851
0
  decNumber buff[D2N(DECBUFFER+1)];
2852
  /* buffer for a [needs +2 to match likely maxp]  */
2853
0
  decNumber bufa[D2N(DECBUFFER+2)];
2854
  /* buffer for temporary, b [must be same size as a]  */
2855
0
  decNumber bufb[D2N(DECBUFFER+2)];
2856
0
  decNumber *allocbuff=nullptr;       /* -> allocated buff, iff allocated  */
2857
0
  decNumber *allocbufa=nullptr;       /* -> allocated bufa, iff allocated  */
2858
0
  decNumber *allocbufb=nullptr;       /* -> allocated bufb, iff allocated  */
2859
0
  decNumber *f=buff;               /* reduced fraction  */
2860
0
  decNumber *a=bufa;               /* approximation to result  */
2861
0
  decNumber *b=bufb;               /* intermediate result  */
2862
  /* buffer for temporary variable, up to 3 digits  */
2863
0
  decNumber buft[D2N(3)];
2864
0
  decNumber *t=buft;               /* up-to-3-digit constant or work  */
2865
2866
  #if DECCHECK
2867
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
2868
  #endif
2869
2870
0
  do {                             /* protect allocated storage  */
2871
    #if DECSUBSET
2872
    if (!set->extended) {
2873
      /* reduce operand and set lostDigits status, as needed  */
2874
      if (rhs->digits>set->digits) {
2875
        allocrhs=decRoundOperand(rhs, set, &status);
2876
        if (allocrhs==nullptr) break;
2877
        /* [Note: 'f' allocation below could reuse this buffer if  */
2878
        /* used, but as this is rare they are kept separate for clarity.]  */
2879
        rhs=allocrhs;
2880
        }
2881
      }
2882
    #endif
2883
    /* [following code does not require input rounding]  */
2884
2885
    /* handle infinities and NaNs  */
2886
0
    if (SPECIALARG) {
2887
0
      if (decNumberIsInfinite(rhs)) {         /* an infinity  */
2888
0
        if (decNumberIsNegative(rhs)) status|=DEC_Invalid_operation;
2889
0
         else uprv_decNumberCopy(res, rhs);        /* +Infinity  */
2890
0
        }
2891
0
       else decNaNs(res, rhs, nullptr, set, &status); /* a NaN  */
2892
0
      break;
2893
0
      }
2894
2895
    /* calculate the ideal (preferred) exponent [floor(exp/2)]  */
2896
    /* [It would be nicer to write: ideal=rhs->exponent>>1, but this  */
2897
    /* generates a compiler warning.  Generated code is the same.]  */
2898
0
    ideal=(rhs->exponent&~1)/2;         /* target  */
2899
2900
    /* handle zeros  */
2901
0
    if (ISZERO(rhs)) {
2902
0
      uprv_decNumberCopy(res, rhs);          /* could be 0 or -0  */
2903
0
      res->exponent=ideal;              /* use the ideal [safe]  */
2904
      /* use decFinish to clamp any out-of-range exponent, etc.  */
2905
0
      decFinish(res, set, &residue, &status);
2906
0
      break;
2907
0
      }
2908
2909
    /* any other -x is an oops  */
2910
0
    if (decNumberIsNegative(rhs)) {
2911
0
      status|=DEC_Invalid_operation;
2912
0
      break;
2913
0
      }
2914
2915
    /* space is needed for three working variables  */
2916
    /*   f -- the same precision as the RHS, reduced to 0.01->0.99...  */
2917
    /*   a -- Hull's approximation -- precision, when assigned, is  */
2918
    /*        currentprecision+1 or the input argument precision,  */
2919
    /*        whichever is larger (+2 for use as temporary)  */
2920
    /*   b -- intermediate temporary result (same size as a)  */
2921
    /* if any is too long for local storage, then allocate  */
2922
0
    workp=MAXI(set->digits+1, rhs->digits);  /* actual rounding precision  */
2923
0
    workp=MAXI(workp, 7);                    /* at least 7 for low cases  */
2924
0
    maxp=workp+2;                            /* largest working precision  */
2925
2926
0
    needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
2927
0
    if (needbytes>(Int)sizeof(buff)) {
2928
0
      allocbuff=(decNumber *)malloc(needbytes);
2929
0
      if (allocbuff==nullptr) {  /* hopeless -- abandon  */
2930
0
        status|=DEC_Insufficient_storage;
2931
0
        break;}
2932
0
      f=allocbuff;            /* use the allocated space  */
2933
0
      }
2934
    /* a and b both need to be able to hold a maxp-length number  */
2935
0
    needbytes=sizeof(decNumber)+(D2U(maxp)-1)*sizeof(Unit);
2936
0
    if (needbytes>(Int)sizeof(bufa)) {            /* [same applies to b]  */
2937
0
      allocbufa=(decNumber *)malloc(needbytes);
2938
0
      allocbufb=(decNumber *)malloc(needbytes);
2939
0
      if (allocbufa==nullptr || allocbufb==nullptr) {   /* hopeless  */
2940
0
        status|=DEC_Insufficient_storage;
2941
0
        break;}
2942
0
      a=allocbufa;            /* use the allocated spaces  */
2943
0
      b=allocbufb;            /* ..  */
2944
0
      }
2945
2946
    /* copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1  */
2947
0
    uprv_decNumberCopy(f, rhs);
2948
0
    exp=f->exponent+f->digits;               /* adjusted to Hull rules  */
2949
0
    f->exponent=-(f->digits);                /* to range  */
2950
2951
    /* set up working context  */
2952
0
    uprv_decContextDefault(&workset, DEC_INIT_DECIMAL64);
2953
0
    workset.emax=DEC_MAX_EMAX;
2954
0
    workset.emin=DEC_MIN_EMIN;
2955
2956
    /* [Until further notice, no error is possible and status bits  */
2957
    /* (Rounded, etc.) should be ignored, not accumulated.]  */
2958
2959
    /* Calculate initial approximation, and allow for odd exponent  */
2960
0
    workset.digits=workp;                    /* p for initial calculation  */
2961
0
    t->bits=0; t->digits=3;
2962
0
    a->bits=0; a->digits=3;
2963
0
    if ((exp & 1)==0) {                      /* even exponent  */
2964
      /* Set t=0.259, a=0.819  */
2965
0
      t->exponent=-3;
2966
0
      a->exponent=-3;
2967
      #if DECDPUN>=3
2968
        t->lsu[0]=259;
2969
        a->lsu[0]=819;
2970
      #elif DECDPUN==2
2971
        t->lsu[0]=59; t->lsu[1]=2;
2972
        a->lsu[0]=19; a->lsu[1]=8;
2973
      #else
2974
0
        t->lsu[0]=9; t->lsu[1]=5; t->lsu[2]=2;
2975
0
        a->lsu[0]=9; a->lsu[1]=1; a->lsu[2]=8;
2976
0
      #endif
2977
0
      }
2978
0
     else {                                  /* odd exponent  */
2979
      /* Set t=0.0819, a=2.59  */
2980
0
      f->exponent--;                         /* f=f/10  */
2981
0
      exp++;                                 /* e=e+1  */
2982
0
      t->exponent=-4;
2983
0
      a->exponent=-2;
2984
      #if DECDPUN>=3
2985
        t->lsu[0]=819;
2986
        a->lsu[0]=259;
2987
      #elif DECDPUN==2
2988
        t->lsu[0]=19; t->lsu[1]=8;
2989
        a->lsu[0]=59; a->lsu[1]=2;
2990
      #else
2991
0
        t->lsu[0]=9; t->lsu[1]=1; t->lsu[2]=8;
2992
0
        a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;
2993
0
      #endif
2994
0
      }
2995
2996
0
    decMultiplyOp(a, a, f, &workset, &ignore);    /* a=a*f  */
2997
0
    decAddOp(a, a, t, &workset, 0, &ignore);      /* ..+t  */
2998
    /* [a is now the initial approximation for sqrt(f), calculated with  */
2999
    /* currentprecision, which is also a's precision.]  */
3000
3001
    /* the main calculation loop  */
3002
0
    uprv_decNumberZero(&dzero);                   /* make 0  */
3003
0
    uprv_decNumberZero(t);                        /* set t = 0.5  */
3004
0
    t->lsu[0]=5;                             /* ..  */
3005
0
    t->exponent=-1;                          /* ..  */
3006
0
    workset.digits=3;                        /* initial p  */
3007
0
    for (; workset.digits<maxp;) {
3008
      /* set p to min(2*p - 2, maxp)  [hence 3; or: 4, 6, 10, ... , maxp]  */
3009
0
      workset.digits=MINI(workset.digits*2-2, maxp);
3010
      /* a = 0.5 * (a + f/a)  */
3011
      /* [calculated at p then rounded to currentprecision]  */
3012
0
      decDivideOp(b, f, a, &workset, DIVIDE, &ignore); /* b=f/a  */
3013
0
      decAddOp(b, b, a, &workset, 0, &ignore);         /* b=b+a  */
3014
0
      decMultiplyOp(a, b, t, &workset, &ignore);       /* a=b*0.5  */
3015
0
      } /* loop  */
3016
3017
    /* Here, 0.1 <= a < 1 [Hull], and a has maxp digits  */
3018
    /* now reduce to length, etc.; this needs to be done with a  */
3019
    /* having the correct exponent so as to handle subnormals  */
3020
    /* correctly  */
3021
0
    approxset=*set;                          /* get emin, emax, etc.  */
3022
0
    approxset.round=DEC_ROUND_HALF_EVEN;
3023
0
    a->exponent+=exp/2;                      /* set correct exponent  */
3024
0
    rstatus=0;                               /* clear status  */
3025
0
    residue=0;                               /* .. and accumulator  */
3026
0
    decCopyFit(a, a, &approxset, &residue, &rstatus);  /* reduce (if needed)  */
3027
0
    decFinish(a, &approxset, &residue, &rstatus);      /* clean and finalize  */
3028
3029
    /* Overflow was possible if the input exponent was out-of-range,  */
3030
    /* in which case quit  */
3031
0
    if (rstatus&DEC_Overflow) {
3032
0
      status=rstatus;                        /* use the status as-is  */
3033
0
      uprv_decNumberCopy(res, a);                 /* copy to result  */
3034
0
      break;
3035
0
      }
3036
3037
    /* Preserve status except Inexact/Rounded  */
3038
0
    status|=(rstatus & ~(DEC_Rounded|DEC_Inexact));
3039
3040
    /* Carry out the Hull correction  */
3041
0
    a->exponent-=exp/2;                      /* back to 0.1->1  */
3042
3043
    /* a is now at final precision and within 1 ulp of the properly  */
3044
    /* rounded square root of f; to ensure proper rounding, compare  */
3045
    /* squares of (a - l/2 ulp) and (a + l/2 ulp) with f.  */
3046
    /* Here workset.digits=maxp and t=0.5, and a->digits determines  */
3047
    /* the ulp  */
3048
0
    workset.digits--;                             /* maxp-1 is OK now  */
3049
0
    t->exponent=-a->digits-1;                     /* make 0.5 ulp  */
3050
0
    decAddOp(b, a, t, &workset, DECNEG, &ignore); /* b = a - 0.5 ulp  */
3051
0
    workset.round=DEC_ROUND_UP;
3052
0
    decMultiplyOp(b, b, b, &workset, &ignore);    /* b = mulru(b, b)  */
3053
0
    decCompareOp(b, f, b, &workset, COMPARE, &ignore); /* b ? f, reversed  */
3054
0
    if (decNumberIsNegative(b)) {                 /* f < b [i.e., b > f]  */
3055
      /* this is the more common adjustment, though both are rare  */
3056
0
      t->exponent++;                              /* make 1.0 ulp  */
3057
0
      t->lsu[0]=1;                                /* ..  */
3058
0
      decAddOp(a, a, t, &workset, DECNEG, &ignore); /* a = a - 1 ulp  */
3059
      /* assign to approx [round to length]  */
3060
0
      approxset.emin-=exp/2;                      /* adjust to match a  */
3061
0
      approxset.emax-=exp/2;
3062
0
      decAddOp(a, &dzero, a, &approxset, 0, &ignore);
3063
0
      }
3064
0
     else {
3065
0
      decAddOp(b, a, t, &workset, 0, &ignore);    /* b = a + 0.5 ulp  */
3066
0
      workset.round=DEC_ROUND_DOWN;
3067
0
      decMultiplyOp(b, b, b, &workset, &ignore);  /* b = mulrd(b, b)  */
3068
0
      decCompareOp(b, b, f, &workset, COMPARE, &ignore);   /* b ? f  */
3069
0
      if (decNumberIsNegative(b)) {               /* b < f  */
3070
0
        t->exponent++;                            /* make 1.0 ulp  */
3071
0
        t->lsu[0]=1;                              /* ..  */
3072
0
        decAddOp(a, a, t, &workset, 0, &ignore);  /* a = a + 1 ulp  */
3073
        /* assign to approx [round to length]  */
3074
0
        approxset.emin-=exp/2;                    /* adjust to match a  */
3075
0
        approxset.emax-=exp/2;
3076
0
        decAddOp(a, &dzero, a, &approxset, 0, &ignore);
3077
0
        }
3078
0
      }
3079
    /* [no errors are possible in the above, and rounding/inexact during  */
3080
    /* estimation are irrelevant, so status was not accumulated]  */
3081
3082
    /* Here, 0.1 <= a < 1  (still), so adjust back  */
3083
0
    a->exponent+=exp/2;                      /* set correct exponent  */
3084
3085
    /* count droppable zeros [after any subnormal rounding] by  */
3086
    /* trimming a copy  */
3087
0
    uprv_decNumberCopy(b, a);
3088
0
    decTrim(b, set, 1, 1, &dropped);         /* [drops trailing zeros]  */
3089
3090
    /* Set Inexact and Rounded.  The answer can only be exact if  */
3091
    /* it is short enough so that squaring it could fit in workp  */
3092
    /* digits, so this is the only (relatively rare) condition that  */
3093
    /* a careful check is needed  */
3094
0
    if (b->digits*2-1 > workp) {             /* cannot fit  */
3095
0
      status|=DEC_Inexact|DEC_Rounded;
3096
0
      }
3097
0
     else {                                  /* could be exact/unrounded  */
3098
0
      uInt mstatus=0;                        /* local status  */
3099
0
      decMultiplyOp(b, b, b, &workset, &mstatus); /* try the multiply  */
3100
0
      if (mstatus&DEC_Overflow) {            /* result just won't fit  */
3101
0
        status|=DEC_Inexact|DEC_Rounded;
3102
0
        }
3103
0
       else {                                /* plausible  */
3104
0
        decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); /* b ? rhs  */
3105
0
        if (!ISZERO(t)) status|=DEC_Inexact|DEC_Rounded; /* not equal  */
3106
0
         else {                              /* is Exact  */
3107
          /* here, dropped is the count of trailing zeros in 'a'  */
3108
          /* use closest exponent to ideal...  */
3109
0
          Int todrop=ideal-a->exponent;      /* most that can be dropped  */
3110
0
          if (todrop<0) status|=DEC_Rounded; /* ideally would add 0s  */
3111
0
           else {                            /* unrounded  */
3112
            /* there are some to drop, but emax may not allow all  */
3113
0
            Int maxexp=set->emax-set->digits+1;
3114
0
            Int maxdrop=maxexp-a->exponent;
3115
0
            if (todrop>maxdrop && set->clamp) { /* apply clamping  */
3116
0
              todrop=maxdrop;
3117
0
              status|=DEC_Clamped;
3118
0
              }
3119
0
            if (dropped<todrop) {            /* clamp to those available  */
3120
0
              todrop=dropped;
3121
0
              status|=DEC_Clamped;
3122
0
              }
3123
0
            if (todrop>0) {                  /* have some to drop  */
3124
0
              decShiftToLeast(a->lsu, D2U(a->digits), todrop);
3125
0
              a->exponent+=todrop;           /* maintain numerical value  */
3126
0
              a->digits-=todrop;             /* new length  */
3127
0
              }
3128
0
            }
3129
0
          }
3130
0
        }
3131
0
      }
3132
3133
    /* double-check Underflow, as perhaps the result could not have  */
3134
    /* been subnormal (initial argument too big), or it is now Exact  */
3135
0
    if (status&DEC_Underflow) {
3136
0
      Int ae=rhs->exponent+rhs->digits-1;    /* adjusted exponent  */
3137
      /* check if truly subnormal  */
3138
      #if DECEXTFLAG                         /* DEC_Subnormal too  */
3139
0
        if (ae>=set->emin*2) status&=~(DEC_Subnormal|DEC_Underflow);
3140
      #else
3141
        if (ae>=set->emin*2) status&=~DEC_Underflow;
3142
      #endif
3143
      /* check if truly inexact  */
3144
0
      if (!(status&DEC_Inexact)) status&=~DEC_Underflow;
3145
0
      }
3146
3147
0
    uprv_decNumberCopy(res, a);                   /* a is now the result  */
3148
0
    } while(0);                              /* end protected  */
3149
3150
0
  if (allocbuff!=nullptr) free(allocbuff);      /* drop any storage used  */
3151
0
  if (allocbufa!=nullptr) free(allocbufa);      /* ..  */
3152
0
  if (allocbufb!=nullptr) free(allocbufb);      /* ..  */
3153
  #if DECSUBSET
3154
  if (allocrhs !=nullptr) free(allocrhs);       /* ..  */
3155
  #endif
3156
0
  if (status!=0) decStatus(res, status, set);/* then report status  */
3157
  #if DECCHECK
3158
  decCheckInexact(res, set);
3159
  #endif
3160
0
  return res;
3161
0
  } /* decNumberSquareRoot  */
3162
#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
3163
#pragma GCC diagnostic pop
3164
#endif
3165
3166
/* ------------------------------------------------------------------ */
3167
/* decNumberSubtract -- subtract two Numbers                          */
3168
/*                                                                    */
3169
/*   This computes C = A - B                                          */
3170
/*                                                                    */
3171
/*   res is C, the result.  C may be A and/or B (e.g., X=X-X)         */
3172
/*   lhs is A                                                         */
3173
/*   rhs is B                                                         */
3174
/*   set is the context                                               */
3175
/*                                                                    */
3176
/* C must have space for set->digits digits.                          */
3177
/* ------------------------------------------------------------------ */
3178
U_CAPI decNumber * U_EXPORT2 uprv_decNumberSubtract(decNumber *res, const decNumber *lhs,
3179
0
                              const decNumber *rhs, decContext *set) {
3180
0
  uInt status=0;                        /* accumulator  */
3181
3182
0
  decAddOp(res, lhs, rhs, set, DECNEG, &status);
3183
0
  if (status!=0) decStatus(res, status, set);
3184
  #if DECCHECK
3185
  decCheckInexact(res, set);
3186
  #endif
3187
0
  return res;
3188
0
  } /* decNumberSubtract  */
3189
3190
/* ------------------------------------------------------------------ */
3191
/* decNumberToIntegralExact -- round-to-integral-value with InExact   */
3192
/* decNumberToIntegralValue -- round-to-integral-value                */
3193
/*                                                                    */
3194
/*   res is the result                                                */
3195
/*   rhs is input number                                              */
3196
/*   set is the context                                               */
3197
/*                                                                    */
3198
/* res must have space for any value of rhs.                          */
3199
/*                                                                    */
3200
/* This implements the IEEE special operators and therefore treats    */
3201
/* special values as valid.  For finite numbers it returns            */
3202
/* rescale(rhs, 0) if rhs->exponent is <0.                            */
3203
/* Otherwise the result is rhs (so no error is possible, except for   */
3204
/* sNaN).                                                             */
3205
/*                                                                    */
3206
/* The context is used for rounding mode and status after sNaN, but   */
3207
/* the digits setting is ignored.  The Exact version will signal      */
3208
/* Inexact if the result differs numerically from rhs; the other      */
3209
/* never signals Inexact.                                             */
3210
/* ------------------------------------------------------------------ */
3211
U_CAPI decNumber * U_EXPORT2 uprv_decNumberToIntegralExact(decNumber *res, const decNumber *rhs,
3212
0
                                     decContext *set) {
3213
0
  decNumber dn;
3214
0
  decContext workset;              /* working context  */
3215
0
  uInt status=0;                   /* accumulator  */
3216
3217
  #if DECCHECK
3218
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
3219
  #endif
3220
3221
  /* handle infinities and NaNs  */
3222
0
  if (SPECIALARG) {
3223
0
    if (decNumberIsInfinite(rhs)) uprv_decNumberCopy(res, rhs); /* an Infinity  */
3224
0
     else decNaNs(res, rhs, nullptr, set, &status); /* a NaN  */
3225
0
    }
3226
0
   else { /* finite  */
3227
    /* have a finite number; no error possible (res must be big enough)  */
3228
0
    if (rhs->exponent>=0) return uprv_decNumberCopy(res, rhs);
3229
    /* that was easy, but if negative exponent there is work to do...  */
3230
0
    workset=*set;                  /* clone rounding, etc.  */
3231
0
    workset.digits=rhs->digits;    /* no length rounding  */
3232
0
    workset.traps=0;               /* no traps  */
3233
0
    uprv_decNumberZero(&dn);            /* make a number with exponent 0  */
3234
0
    uprv_decNumberQuantize(res, rhs, &dn, &workset);
3235
0
    status|=workset.status;
3236
0
    }
3237
0
  if (status!=0) decStatus(res, status, set);
3238
0
  return res;
3239
0
  } /* decNumberToIntegralExact  */
3240
3241
U_CAPI decNumber * U_EXPORT2 uprv_decNumberToIntegralValue(decNumber *res, const decNumber *rhs,
3242
0
                                     decContext *set) {
3243
0
  decContext workset=*set;         /* working context  */
3244
0
  workset.traps=0;                 /* no traps  */
3245
0
  uprv_decNumberToIntegralExact(res, rhs, &workset);
3246
  /* this never affects set, except for sNaNs; NaN will have been set  */
3247
  /* or propagated already, so no need to call decStatus  */
3248
0
  set->status|=workset.status&DEC_Invalid_operation;
3249
0
  return res;
3250
0
  } /* decNumberToIntegralValue  */
3251
3252
/* ------------------------------------------------------------------ */
3253
/* decNumberXor -- XOR two Numbers, digitwise                         */
3254
/*                                                                    */
3255
/*   This computes C = A ^ B                                          */
3256
/*                                                                    */
3257
/*   res is C, the result.  C may be A and/or B (e.g., X=X^X)         */
3258
/*   lhs is A                                                         */
3259
/*   rhs is B                                                         */
3260
/*   set is the context (used for result length and error report)     */
3261
/*                                                                    */
3262
/* C must have space for set->digits digits.                          */
3263
/*                                                                    */
3264
/* Logical function restrictions apply (see above); a NaN is          */
3265
/* returned with Invalid_operation if a restriction is violated.      */
3266
/* ------------------------------------------------------------------ */
3267
U_CAPI decNumber * U_EXPORT2 uprv_decNumberXor(decNumber *res, const decNumber *lhs,
3268
0
                         const decNumber *rhs, decContext *set) {
3269
0
  const Unit *ua, *ub;                  /* -> operands  */
3270
0
  const Unit *msua, *msub;              /* -> operand msus  */
3271
0
  Unit  *uc, *msuc;                     /* -> result and its msu  */
3272
0
  Int   msudigs;                        /* digits in res msu  */
3273
  #if DECCHECK
3274
  if (decCheckOperands(res, lhs, rhs, set)) return res;
3275
  #endif
3276
3277
0
  if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
3278
0
   || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
3279
0
    decStatus(res, DEC_Invalid_operation, set);
3280
0
    return res;
3281
0
    }
3282
  /* operands are valid  */
3283
0
  ua=lhs->lsu;                          /* bottom-up  */
3284
0
  ub=rhs->lsu;                          /* ..  */
3285
0
  uc=res->lsu;                          /* ..  */
3286
0
  msua=ua+D2U(lhs->digits)-1;           /* -> msu of lhs  */
3287
0
  msub=ub+D2U(rhs->digits)-1;           /* -> msu of rhs  */
3288
0
  msuc=uc+D2U(set->digits)-1;           /* -> msu of result  */
3289
0
  msudigs=MSUDIGITS(set->digits);       /* [faster than remainder]  */
3290
0
  for (; uc<=msuc; ua++, ub++, uc++) {  /* Unit loop  */
3291
0
    Unit a, b;                          /* extract units  */
3292
0
    if (ua>msua) a=0;
3293
0
     else a=*ua;
3294
0
    if (ub>msub) b=0;
3295
0
     else b=*ub;
3296
0
    *uc=0;                              /* can now write back  */
3297
0
    if (a|b) {                          /* maybe 1 bits to examine  */
3298
0
      Int i, j;
3299
      /* This loop could be unrolled and/or use BIN2BCD tables  */
3300
0
      for (i=0; i<DECDPUN; i++) {
3301
0
        if ((a^b)&1) *uc=*uc+(Unit)powers[i];     /* effect XOR  */
3302
0
        j=a%10;
3303
0
        a=a/10;
3304
0
        j|=b%10;
3305
0
        b=b/10;
3306
0
        if (j>1) {
3307
0
          decStatus(res, DEC_Invalid_operation, set);
3308
0
          return res;
3309
0
          }
3310
0
        if (uc==msuc && i==msudigs-1) break;      /* just did final digit  */
3311
0
        } /* each digit  */
3312
0
      } /* non-zero  */
3313
0
    } /* each unit  */
3314
  /* [here uc-1 is the msu of the result]  */
3315
0
  res->digits=decGetDigits(res->lsu, static_cast<int32_t>(uc-res->lsu));
3316
0
  res->exponent=0;                      /* integer  */
3317
0
  res->bits=0;                          /* sign=0  */
3318
0
  return res;  /* [no status to set]  */
3319
0
  } /* decNumberXor  */
3320
3321
3322
/* ================================================================== */
3323
/* Utility routines                                                   */
3324
/* ================================================================== */
3325
3326
/* ------------------------------------------------------------------ */
3327
/* decNumberClass -- return the decClass of a decNumber               */
3328
/*   dn -- the decNumber to test                                      */
3329
/*   set -- the context to use for Emin                               */
3330
/*   returns the decClass enum                                        */
3331
/* ------------------------------------------------------------------ */
3332
0
enum decClass uprv_decNumberClass(const decNumber *dn, decContext *set) {
3333
0
  if (decNumberIsSpecial(dn)) {
3334
0
    if (decNumberIsQNaN(dn)) return DEC_CLASS_QNAN;
3335
0
    if (decNumberIsSNaN(dn)) return DEC_CLASS_SNAN;
3336
    /* must be an infinity  */
3337
0
    if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_INF;
3338
0
    return DEC_CLASS_POS_INF;
3339
0
    }
3340
  /* is finite  */
3341
0
  if (uprv_decNumberIsNormal(dn, set)) { /* most common  */
3342
0
    if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_NORMAL;
3343
0
    return DEC_CLASS_POS_NORMAL;
3344
0
    }
3345
  /* is subnormal or zero  */
3346
0
  if (decNumberIsZero(dn)) {    /* most common  */
3347
0
    if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_ZERO;
3348
0
    return DEC_CLASS_POS_ZERO;
3349
0
    }
3350
0
  if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_SUBNORMAL;
3351
0
  return DEC_CLASS_POS_SUBNORMAL;
3352
0
  } /* decNumberClass  */
3353
3354
/* ------------------------------------------------------------------ */
3355
/* decNumberClassToString -- convert decClass to a string             */
3356
/*                                                                    */
3357
/*  eclass is a valid decClass                                        */
3358
/*  returns a constant string describing the class (max 13+1 chars)   */
3359
/* ------------------------------------------------------------------ */
3360
0
const char *uprv_decNumberClassToString(enum decClass eclass) {
3361
0
  if (eclass==DEC_CLASS_POS_NORMAL)    return DEC_ClassString_PN;
3362
0
  if (eclass==DEC_CLASS_NEG_NORMAL)    return DEC_ClassString_NN;
3363
0
  if (eclass==DEC_CLASS_POS_ZERO)      return DEC_ClassString_PZ;
3364
0
  if (eclass==DEC_CLASS_NEG_ZERO)      return DEC_ClassString_NZ;
3365
0
  if (eclass==DEC_CLASS_POS_SUBNORMAL) return DEC_ClassString_PS;
3366
0
  if (eclass==DEC_CLASS_NEG_SUBNORMAL) return DEC_ClassString_NS;
3367
0
  if (eclass==DEC_CLASS_POS_INF)       return DEC_ClassString_PI;
3368
0
  if (eclass==DEC_CLASS_NEG_INF)       return DEC_ClassString_NI;
3369
0
  if (eclass==DEC_CLASS_QNAN)          return DEC_ClassString_QN;
3370
0
  if (eclass==DEC_CLASS_SNAN)          return DEC_ClassString_SN;
3371
0
  return DEC_ClassString_UN;           /* Unknown  */
3372
0
  } /* decNumberClassToString  */
3373
3374
/* ------------------------------------------------------------------ */
3375
/* decNumberCopy -- copy a number                                     */
3376
/*                                                                    */
3377
/*   dest is the target decNumber                                     */
3378
/*   src  is the source decNumber                                     */
3379
/*   returns dest                                                     */
3380
/*                                                                    */
3381
/* (dest==src is allowed and is a no-op)                              */
3382
/* All fields are updated as required.  This is a utility operation,  */
3383
/* so special values are unchanged and no error is possible.          */
3384
/* ------------------------------------------------------------------ */
3385
0
U_CAPI decNumber * U_EXPORT2 uprv_decNumberCopy(decNumber *dest, const decNumber *src) {
3386
3387
  #if DECCHECK
3388
  if (src==nullptr) return uprv_decNumberZero(dest);
3389
  #endif
3390
3391
0
  if (dest==src) return dest;                /* no copy required  */
3392
3393
  /* Use explicit assignments here as structure assignment could copy  */
3394
  /* more than just the lsu (for small DECDPUN).  This would not affect  */
3395
  /* the value of the results, but could disturb test harness spill  */
3396
  /* checking.  */
3397
0
  dest->bits=src->bits;
3398
0
  dest->exponent=src->exponent;
3399
0
  dest->digits=src->digits;
3400
0
  dest->lsu[0]=src->lsu[0];
3401
0
  if (src->digits>DECDPUN) {                 /* more Units to come  */
3402
0
    const Unit *smsup, *s;                   /* work  */
3403
0
    Unit  *d;                                /* ..  */
3404
    /* memcpy for the remaining Units would be safe as they cannot  */
3405
    /* overlap.  However, this explicit loop is faster in short cases.  */
3406
0
    d=dest->lsu+1;                           /* -> first destination  */
3407
0
    smsup=src->lsu+D2U(src->digits);         /* -> source msu+1  */
3408
0
    for (s=src->lsu+1; s<smsup; s++, d++) *d=*s;
3409
0
    }
3410
0
  return dest;
3411
0
  } /* decNumberCopy  */
3412
3413
/* ------------------------------------------------------------------ */
3414
/* decNumberCopyAbs -- quiet absolute value operator                  */
3415
/*                                                                    */
3416
/*   This sets C = abs(A)                                             */
3417
/*                                                                    */
3418
/*   res is C, the result.  C may be A                                */
3419
/*   rhs is A                                                         */
3420
/*                                                                    */
3421
/* C must have space for set->digits digits.                          */
3422
/* No exception or error can occur; this is a quiet bitwise operation.*/
3423
/* See also decNumberAbs for a checking version of this.              */
3424
/* ------------------------------------------------------------------ */
3425
0
U_CAPI decNumber * U_EXPORT2 uprv_decNumberCopyAbs(decNumber *res, const decNumber *rhs) {
3426
  #if DECCHECK
3427
  if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
3428
  #endif
3429
0
  uprv_decNumberCopy(res, rhs);
3430
0
  res->bits&=~DECNEG;                   /* turn off sign  */
3431
0
  return res;
3432
0
  } /* decNumberCopyAbs  */
3433
3434
/* ------------------------------------------------------------------ */
3435
/* decNumberCopyNegate -- quiet negate value operator                 */
3436
/*                                                                    */
3437
/*   This sets C = negate(A)                                          */
3438
/*                                                                    */
3439
/*   res is C, the result.  C may be A                                */
3440
/*   rhs is A                                                         */
3441
/*                                                                    */
3442
/* C must have space for set->digits digits.                          */
3443
/* No exception or error can occur; this is a quiet bitwise operation.*/
3444
/* See also decNumberMinus for a checking version of this.            */
3445
/* ------------------------------------------------------------------ */
3446
0
U_CAPI decNumber * U_EXPORT2 uprv_decNumberCopyNegate(decNumber *res, const decNumber *rhs) {
3447
  #if DECCHECK
3448
  if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
3449
  #endif
3450
0
  uprv_decNumberCopy(res, rhs);
3451
0
  res->bits^=DECNEG;                    /* invert the sign  */
3452
0
  return res;
3453
0
  } /* decNumberCopyNegate  */
3454
3455
/* ------------------------------------------------------------------ */
3456
/* decNumberCopySign -- quiet copy and set sign operator              */
3457
/*                                                                    */
3458
/*   This sets C = A with the sign of B                               */
3459
/*                                                                    */
3460
/*   res is C, the result.  C may be A                                */
3461
/*   lhs is A                                                         */
3462
/*   rhs is B                                                         */
3463
/*                                                                    */
3464
/* C must have space for set->digits digits.                          */
3465
/* No exception or error can occur; this is a quiet bitwise operation.*/
3466
/* ------------------------------------------------------------------ */
3467
U_CAPI decNumber * U_EXPORT2 uprv_decNumberCopySign(decNumber *res, const decNumber *lhs,
3468
0
                              const decNumber *rhs) {
3469
0
  uByte sign;                           /* rhs sign  */
3470
  #if DECCHECK
3471
  if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
3472
  #endif
3473
0
  sign=rhs->bits & DECNEG;              /* save sign bit  */
3474
0
  uprv_decNumberCopy(res, lhs);
3475
0
  res->bits&=~DECNEG;                   /* clear the sign  */
3476
0
  res->bits|=sign;                      /* set from rhs  */
3477
0
  return res;
3478
0
  } /* decNumberCopySign  */
3479
3480
/* ------------------------------------------------------------------ */
3481
/* decNumberGetBCD -- get the coefficient in BCD8                     */
3482
/*   dn is the source decNumber                                       */
3483
/*   bcd is the uInt array that will receive dn->digits BCD bytes,    */
3484
/*     most-significant at offset 0                                   */
3485
/*   returns bcd                                                      */
3486
/*                                                                    */
3487
/* bcd must have at least dn->digits bytes.  No error is possible; if */
3488
/* dn is a NaN or Infinite, digits must be 1 and the coefficient 0.   */
3489
/* ------------------------------------------------------------------ */
3490
0
U_CAPI uByte * U_EXPORT2 uprv_decNumberGetBCD(const decNumber *dn, uByte *bcd) {
3491
0
  uByte *ub=bcd+dn->digits-1;      /* -> lsd  */
3492
0
  const Unit *up=dn->lsu;          /* Unit pointer, -> lsu  */
3493
3494
0
  #if DECDPUN==1                   /* trivial simple copy  */
3495
0
    for (; ub>=bcd; ub--, up++) *ub=*up;
3496
  #else                            /* chopping needed  */
3497
    uInt u=*up;                    /* work  */
3498
    uInt cut=DECDPUN;              /* downcounter through unit  */
3499
    for (; ub>=bcd; ub--) {
3500
      *ub=(uByte)(u%10);           /* [*6554 trick inhibits, here]  */
3501
      u=u/10;
3502
      cut--;
3503
      if (cut>0) continue;         /* more in this unit  */
3504
      up++;
3505
      u=*up;
3506
      cut=DECDPUN;
3507
      }
3508
  #endif
3509
0
  return bcd;
3510
0
  } /* decNumberGetBCD  */
3511
3512
/* ------------------------------------------------------------------ */
3513
/* decNumberSetBCD -- set (replace) the coefficient from BCD8         */
3514
/*   dn is the target decNumber                                       */
3515
/*   bcd is the uInt array that will source n BCD bytes, most-        */
3516
/*     significant at offset 0                                        */
3517
/*   n is the number of digits in the source BCD array (bcd)          */
3518
/*   returns dn                                                       */
3519
/*                                                                    */
3520
/* dn must have space for at least n digits.  No error is possible;   */
3521
/* if dn is a NaN, or Infinite, or is to become a zero, n must be 1   */
3522
/* and bcd[0] zero.                                                   */
3523
/* ------------------------------------------------------------------ */
3524
0
U_CAPI decNumber * U_EXPORT2 uprv_decNumberSetBCD(decNumber *dn, const uByte *bcd, uInt n) {
3525
0
  Unit *up=dn->lsu+D2U(dn->digits)-1;   /* -> msu [target pointer]  */
3526
0
  const uByte *ub=bcd;                  /* -> source msd  */
3527
3528
0
  #if DECDPUN==1                        /* trivial simple copy  */
3529
0
    for (; ub<bcd+n; ub++, up--) *up=*ub;
3530
  #else                                 /* some assembly needed  */
3531
    /* calculate how many digits in msu, and hence first cut  */
3532
    Int cut=MSUDIGITS(n);               /* [faster than remainder]  */
3533
    for (;up>=dn->lsu; up--) {          /* each Unit from msu  */
3534
      *up=0;                            /* will take <=DECDPUN digits  */
3535
      for (; cut>0; ub++, cut--) *up=X10(*up)+*ub;
3536
      cut=DECDPUN;                      /* next Unit has all digits  */
3537
      }
3538
  #endif
3539
0
  dn->digits=n;                         /* set digit count  */
3540
0
  return dn;
3541
0
  } /* decNumberSetBCD  */
3542
3543
/* ------------------------------------------------------------------ */
3544
/* decNumberIsNormal -- test normality of a decNumber                 */
3545
/*   dn is the decNumber to test                                      */
3546
/*   set is the context to use for Emin                               */
3547
/*   returns 1 if |dn| is finite and >=Nmin, 0 otherwise              */
3548
/* ------------------------------------------------------------------ */
3549
0
Int uprv_decNumberIsNormal(const decNumber *dn, decContext *set) {
3550
0
  Int ae;                               /* adjusted exponent  */
3551
  #if DECCHECK
3552
  if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
3553
  #endif
3554
3555
0
  if (decNumberIsSpecial(dn)) return 0; /* not finite  */
3556
0
  if (decNumberIsZero(dn)) return 0;    /* not non-zero  */
3557
3558
0
  ae=dn->exponent+dn->digits-1;         /* adjusted exponent  */
3559
0
  if (ae<set->emin) return 0;           /* is subnormal  */
3560
0
  return 1;
3561
0
  } /* decNumberIsNormal  */
3562
3563
/* ------------------------------------------------------------------ */
3564
/* decNumberIsSubnormal -- test subnormality of a decNumber           */
3565
/*   dn is the decNumber to test                                      */
3566
/*   set is the context to use for Emin                               */
3567
/*   returns 1 if |dn| is finite, non-zero, and <Nmin, 0 otherwise    */
3568
/* ------------------------------------------------------------------ */
3569
0
Int uprv_decNumberIsSubnormal(const decNumber *dn, decContext *set) {
3570
0
  Int ae;                               /* adjusted exponent  */
3571
  #if DECCHECK
3572
  if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
3573
  #endif
3574
3575
0
  if (decNumberIsSpecial(dn)) return 0; /* not finite  */
3576
0
  if (decNumberIsZero(dn)) return 0;    /* not non-zero  */
3577
3578
0
  ae=dn->exponent+dn->digits-1;         /* adjusted exponent  */
3579
0
  if (ae<set->emin) return 1;           /* is subnormal  */
3580
0
  return 0;
3581
0
  } /* decNumberIsSubnormal  */
3582
3583
/* ------------------------------------------------------------------ */
3584
/* decNumberTrim -- remove insignificant zeros                        */
3585
/*                                                                    */
3586
/*   dn is the number to trim                                         */
3587
/*   returns dn                                                       */
3588
/*                                                                    */
3589
/* All fields are updated as required.  This is a utility operation,  */
3590
/* so special values are unchanged and no error is possible.  The     */
3591
/* zeros are removed unconditionally.                                 */
3592
/* ------------------------------------------------------------------ */
3593
0
U_CAPI decNumber * U_EXPORT2 uprv_decNumberTrim(decNumber *dn) {
3594
0
  Int  dropped;                    /* work  */
3595
0
  decContext set;                  /* ..  */
3596
  #if DECCHECK
3597
  if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn;
3598
  #endif
3599
0
  uprv_decContextDefault(&set, DEC_INIT_BASE);    /* clamp=0  */
3600
0
  return decTrim(dn, &set, 0, 1, &dropped);
3601
0
  } /* decNumberTrim  */
3602
3603
/* ------------------------------------------------------------------ */
3604
/* decNumberVersion -- return the name and version of this module     */
3605
/*                                                                    */
3606
/* No error is possible.                                              */
3607
/* ------------------------------------------------------------------ */
3608
0
const char * uprv_decNumberVersion() {
3609
0
  return DECVERSION;
3610
0
  } /* decNumberVersion  */
3611
3612
/* ------------------------------------------------------------------ */
3613
/* decNumberZero -- set a number to 0                                 */
3614
/*                                                                    */
3615
/*   dn is the number to set, with space for one digit                */
3616
/*   returns dn                                                       */
3617
/*                                                                    */
3618
/* No error is possible.                                              */
3619
/* ------------------------------------------------------------------ */
3620
/* Memset is not used as it is much slower in some environments.  */
3621
0
U_CAPI decNumber * U_EXPORT2 uprv_decNumberZero(decNumber *dn) {
3622
3623
  #if DECCHECK
3624
  if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
3625
  #endif
3626
3627
0
  dn->bits=0;
3628
0
  dn->exponent=0;
3629
0
  dn->digits=1;
3630
0
  dn->lsu[0]=0;
3631
0
  return dn;
3632
0
  } /* decNumberZero  */
3633
3634
/* ================================================================== */
3635
/* Local routines                                                     */
3636
/* ================================================================== */
3637
3638
/* ------------------------------------------------------------------ */
3639
/* decToString -- lay out a number into a string                      */
3640
/*                                                                    */
3641
/*   dn     is the number to lay out                                  */
3642
/*   string is where to lay out the number                            */
3643
/*   eng    is 1 if Engineering, 0 if Scientific                      */
3644
/*                                                                    */
3645
/* string must be at least dn->digits+14 characters long              */
3646
/* No error is possible.                                              */
3647
/*                                                                    */
3648
/* Note that this routine can generate a -0 or 0.000.  These are      */
3649
/* never generated in subset to-number or arithmetic, but can occur   */
3650
/* in non-subset arithmetic (e.g., -1*0 or 1.234-1.234).              */
3651
/* ------------------------------------------------------------------ */
3652
/* If DECCHECK is enabled the string "?" is returned if a number is  */
3653
/* invalid.  */
3654
0
static void decToString(const decNumber *dn, char *string, Flag eng) {
3655
0
  Int exp=dn->exponent;       /* local copy  */
3656
0
  Int e;                      /* E-part value  */
3657
0
  Int pre;                    /* digits before the '.'  */
3658
0
  Int cut;                    /* for counting digits in a Unit  */
3659
0
  char *c=string;             /* work [output pointer]  */
3660
0
  const Unit *up=dn->lsu+D2U(dn->digits)-1; /* -> msu [input pointer]  */
3661
0
  uInt u, pow;                /* work  */
3662
3663
  #if DECCHECK
3664
  if (decCheckOperands(DECUNRESU, dn, DECUNUSED, DECUNCONT)) {
3665
    strcpy(string, "?");
3666
    return;}
3667
  #endif
3668
3669
0
  if (decNumberIsNegative(dn)) {   /* Negatives get a minus  */
3670
0
    *c='-';
3671
0
    c++;
3672
0
    }
3673
0
  if (dn->bits&DECSPECIAL) {       /* Is a special value  */
3674
0
    if (decNumberIsInfinite(dn)) {
3675
0
      strcpy(c,   "Inf");
3676
0
      strcpy(c+3, "inity");
3677
0
      return;}
3678
    /* a NaN  */
3679
0
    if (dn->bits&DECSNAN) {        /* signalling NaN  */
3680
0
      *c='s';
3681
0
      c++;
3682
0
      }
3683
0
    strcpy(c, "NaN");
3684
0
    c+=3;                          /* step past  */
3685
    /* if not a clean non-zero coefficient, that's all there is in a  */
3686
    /* NaN string  */
3687
0
    if (exp!=0 || (*dn->lsu==0 && dn->digits==1)) return;
3688
    /* [drop through to add integer]  */
3689
0
    }
3690
3691
  /* calculate how many digits in msu, and hence first cut  */
3692
0
  cut=MSUDIGITS(dn->digits);       /* [faster than remainder]  */
3693
0
  cut--;                           /* power of ten for digit  */
3694
3695
0
  if (exp==0) {                    /* simple integer [common fastpath]  */
3696
0
    for (;up>=dn->lsu; up--) {     /* each Unit from msu  */
3697
0
      u=*up;                       /* contains DECDPUN digits to lay out  */
3698
0
      for (; cut>=0; c++, cut--) TODIGIT(u, cut, c, pow);
3699
0
      cut=DECDPUN-1;               /* next Unit has all digits  */
3700
0
      }
3701
0
    *c='\0';                       /* terminate the string  */
3702
0
    return;}
3703
3704
  /* non-0 exponent -- assume plain form */
3705
0
  pre=dn->digits+exp;              /* digits before '.'  */
3706
0
  e=0;                             /* no E  */
3707
0
  if ((exp>0) || (pre<-5)) {       /* need exponential form  */
3708
0
    e=exp+dn->digits-1;            /* calculate E value  */
3709
0
    pre=1;                         /* assume one digit before '.'  */
3710
0
    if (eng && (e!=0)) {           /* engineering: may need to adjust  */
3711
0
      Int adj;                     /* adjustment  */
3712
      /* The C remainder operator is undefined for negative numbers, so  */
3713
      /* a positive remainder calculation must be used here  */
3714
0
      if (e<0) {
3715
0
        adj=(-e)%3;
3716
0
        if (adj!=0) adj=3-adj;
3717
0
        }
3718
0
       else { /* e>0  */
3719
0
        adj=e%3;
3720
0
        }
3721
0
      e=e-adj;
3722
      /* if dealing with zero still produce an exponent which is a  */
3723
      /* multiple of three, as expected, but there will only be the  */
3724
      /* one zero before the E, still.  Otherwise note the padding.  */
3725
0
      if (!ISZERO(dn)) pre+=adj;
3726
0
       else {  /* is zero  */
3727
0
        if (adj!=0) {              /* 0.00Esnn needed  */
3728
0
          e=e+3;
3729
0
          pre=-(2-adj);
3730
0
          }
3731
0
        } /* zero  */
3732
0
      } /* eng  */
3733
0
    } /* need exponent  */
3734
3735
  /* lay out the digits of the coefficient, adding 0s and . as needed */
3736
0
  u=*up;
3737
0
  if (pre>0) {                     /* xxx.xxx or xx00 (engineering) form  */
3738
0
    Int n=pre;
3739
0
    for (; pre>0; pre--, c++, cut--) {
3740
0
      if (cut<0) {                 /* need new Unit  */
3741
0
        if (up==dn->lsu) break;    /* out of input digits (pre>digits)  */
3742
0
        up--;
3743
0
        cut=DECDPUN-1;
3744
0
        u=*up;
3745
0
        }
3746
0
      TODIGIT(u, cut, c, pow);
3747
0
      }
3748
0
    if (n<dn->digits) {            /* more to come, after '.'  */
3749
0
      *c='.'; c++;
3750
0
      for (;; c++, cut--) {
3751
0
        if (cut<0) {               /* need new Unit  */
3752
0
          if (up==dn->lsu) break;  /* out of input digits  */
3753
0
          up--;
3754
0
          cut=DECDPUN-1;
3755
0
          u=*up;
3756
0
          }
3757
0
        TODIGIT(u, cut, c, pow);
3758
0
        }
3759
0
      }
3760
0
     else for (; pre>0; pre--, c++) *c='0'; /* 0 padding (for engineering) needed  */
3761
0
    }
3762
0
   else {                          /* 0.xxx or 0.000xxx form  */
3763
0
    *c='0'; c++;
3764
0
    *c='.'; c++;
3765
0
    for (; pre<0; pre++, c++) *c='0';   /* add any 0's after '.'  */
3766
0
    for (; ; c++, cut--) {
3767
0
      if (cut<0) {                 /* need new Unit  */
3768
0
        if (up==dn->lsu) break;    /* out of input digits  */
3769
0
        up--;
3770
0
        cut=DECDPUN-1;
3771
0
        u=*up;
3772
0
        }
3773
0
      TODIGIT(u, cut, c, pow);
3774
0
      }
3775
0
    }
3776
3777
  /* Finally add the E-part, if needed.  It will never be 0, has a
3778
     base maximum and minimum of +999999999 through -999999999, but
3779
     could range down to -1999999998 for abnormal numbers */
3780
0
  if (e!=0) {
3781
0
    Flag had=0;               /* 1=had non-zero  */
3782
0
    *c='E'; c++;
3783
0
    *c='+'; c++;              /* assume positive  */
3784
0
    u=e;                      /* ..  */
3785
0
    if (e<0) {
3786
0
      *(c-1)='-';             /* oops, need -  */
3787
0
      u=-e;                   /* uInt, please  */
3788
0
      }
3789
    /* lay out the exponent [_itoa or equivalent is not ANSI C]  */
3790
0
    for (cut=9; cut>=0; cut--) {
3791
0
      TODIGIT(u, cut, c, pow);
3792
0
      if (*c=='0' && !had) continue;    /* skip leading zeros  */
3793
0
      had=1;                            /* had non-0  */
3794
0
      c++;                              /* step for next  */
3795
0
      } /* cut  */
3796
0
    }
3797
0
  *c='\0';          /* terminate the string (all paths)  */
3798
0
  } /* decToString  */
3799
3800
/* ------------------------------------------------------------------ */
3801
/* decAddOp -- add/subtract operation                                 */
3802
/*                                                                    */
3803
/*   This computes C = A + B                                          */
3804
/*                                                                    */
3805
/*   res is C, the result.  C may be A and/or B (e.g., X=X+X)         */
3806
/*   lhs is A                                                         */
3807
/*   rhs is B                                                         */
3808
/*   set is the context                                               */
3809
/*   negate is DECNEG if rhs should be negated, or 0 otherwise        */
3810
/*   status accumulates status for the caller                         */
3811
/*                                                                    */
3812
/* C must have space for set->digits digits.                          */
3813
/* Inexact in status must be 0 for correct Exact zero sign in result  */
3814
/* ------------------------------------------------------------------ */
3815
/* If possible, the coefficient is calculated directly into C.        */
3816
/* However, if:                                                       */
3817
/*   -- a digits+1 calculation is needed because the numbers are      */
3818
/*      unaligned and span more than set->digits digits               */
3819
/*   -- a carry to digits+1 digits looks possible                     */
3820
/*   -- C is the same as A or B, and the result would destructively   */
3821
/*      overlap the A or B coefficient                                */
3822
/* then the result must be calculated into a temporary buffer.  In    */
3823
/* this case a local (stack) buffer is used if possible, and only if  */
3824
/* too long for that does malloc become the final resort.             */
3825
/*                                                                    */
3826
/* Misalignment is handled as follows:                                */
3827
/*   Apad: (AExp>BExp) Swap operands and proceed as for BExp>AExp.    */
3828
/*   BPad: Apply the padding by a combination of shifting (whole      */
3829
/*         units) and multiplication (part units).                    */
3830
/*                                                                    */
3831
/* Addition, especially x=x+1, is speed-critical.                     */
3832
/* The static buffer is larger than might be expected to allow for    */
3833
/* calls from higher-level functions (notable exp).                    */
3834
/* ------------------------------------------------------------------ */
3835
static decNumber * decAddOp(decNumber *res, const decNumber *lhs,
3836
                            const decNumber *rhs, decContext *set,
3837
0
                            uByte negate, uInt *status) {
3838
  #if DECSUBSET
3839
  decNumber *alloclhs=nullptr;        /* non-nullptr if rounded lhs allocated  */
3840
  decNumber *allocrhs=nullptr;        /* .., rhs  */
3841
  #endif
3842
0
  Int   rhsshift;                  /* working shift (in Units)  */
3843
0
  Int   maxdigits;                 /* longest logical length  */
3844
0
  Int   mult;                      /* multiplier  */
3845
0
  Int   residue;                   /* rounding accumulator  */
3846
0
  uByte bits;                      /* result bits  */
3847
0
  Flag  diffsign;                  /* non-0 if arguments have different sign  */
3848
0
  Unit  *acc;                      /* accumulator for result  */
3849
0
  Unit  accbuff[SD2U(DECBUFFER*2+20)]; /* local buffer [*2+20 reduces many  */
3850
                                   /* allocations when called from  */
3851
                                   /* other operations, notable exp]  */
3852
0
  Unit  *allocacc=nullptr;            /* -> allocated acc buffer, iff allocated  */
3853
0
  Int   reqdigits=set->digits;     /* local copy; requested DIGITS  */
3854
0
  Int   padding;                   /* work  */
3855
3856
  #if DECCHECK
3857
  if (decCheckOperands(res, lhs, rhs, set)) return res;
3858
  #endif
3859
3860
0
  do {                             /* protect allocated storage  */
3861
    #if DECSUBSET
3862
    if (!set->extended) {
3863
      /* reduce operands and set lostDigits status, as needed  */
3864
      if (lhs->digits>reqdigits) {
3865
        alloclhs=decRoundOperand(lhs, set, status);
3866
        if (alloclhs==nullptr) break;
3867
        lhs=alloclhs;
3868
        }
3869
      if (rhs->digits>reqdigits) {
3870
        allocrhs=decRoundOperand(rhs, set, status);
3871
        if (allocrhs==nullptr) break;
3872
        rhs=allocrhs;
3873
        }
3874
      }
3875
    #endif
3876
    /* [following code does not require input rounding]  */
3877
3878
    /* note whether signs differ [used all paths]  */
3879
0
    diffsign = static_cast<Flag>((lhs->bits ^ rhs->bits ^ negate) & DECNEG);
3880
3881
    /* handle infinities and NaNs  */
3882
0
    if (SPECIALARGS) {                  /* a special bit set  */
3883
0
      if (SPECIALARGS & (DECSNAN | DECNAN))  /* a NaN  */
3884
0
        decNaNs(res, lhs, rhs, set, status);
3885
0
       else { /* one or two infinities  */
3886
0
        if (decNumberIsInfinite(lhs)) { /* LHS is infinity  */
3887
          /* two infinities with different signs is invalid  */
3888
0
          if (decNumberIsInfinite(rhs) && diffsign) {
3889
0
            *status|=DEC_Invalid_operation;
3890
0
            break;
3891
0
            }
3892
0
          bits=lhs->bits & DECNEG;      /* get sign from LHS  */
3893
0
          }
3894
0
         else bits=(rhs->bits^negate) & DECNEG;/* RHS must be Infinity  */
3895
0
        bits|=DECINF;
3896
0
        uprv_decNumberZero(res);
3897
0
        res->bits=bits;                 /* set +/- infinity  */
3898
0
        } /* an infinity  */
3899
0
      break;
3900
0
      }
3901
3902
    /* Quick exit for add 0s; return the non-0, modified as need be  */
3903
0
    if (ISZERO(lhs)) {
3904
0
      Int adjust;                       /* work  */
3905
0
      Int lexp=lhs->exponent;           /* save in case LHS==RES  */
3906
0
      bits=lhs->bits;                   /* ..  */
3907
0
      residue=0;                        /* clear accumulator  */
3908
0
      decCopyFit(res, rhs, set, &residue, status); /* copy (as needed)  */
3909
0
      res->bits^=negate;                /* flip if rhs was negated  */
3910
      #if DECSUBSET
3911
      if (set->extended) {              /* exponents on zeros count  */
3912
      #endif
3913
        /* exponent will be the lower of the two  */
3914
0
        adjust=lexp-res->exponent;      /* adjustment needed [if -ve]  */
3915
0
        if (ISZERO(res)) {              /* both 0: special IEEE 754 rules  */
3916
0
          if (adjust<0) res->exponent=lexp;  /* set exponent  */
3917
          /* 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0  */
3918
0
          if (diffsign) {
3919
0
            if (set->round!=DEC_ROUND_FLOOR) res->bits=0;
3920
0
             else res->bits=DECNEG;     /* preserve 0 sign  */
3921
0
            }
3922
0
          }
3923
0
         else { /* non-0 res  */
3924
0
          if (adjust<0) {     /* 0-padding needed  */
3925
0
            if ((res->digits-adjust)>set->digits) {
3926
0
              adjust=res->digits-set->digits;     /* to fit exactly  */
3927
0
              *status|=DEC_Rounded;               /* [but exact]  */
3928
0
              }
3929
0
            res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
3930
0
            res->exponent+=adjust;                /* set the exponent.  */
3931
0
            }
3932
0
          } /* non-0 res  */
3933
      #if DECSUBSET
3934
        } /* extended  */
3935
      #endif
3936
0
      decFinish(res, set, &residue, status);      /* clean and finalize  */
3937
0
      break;}
3938
3939
0
    if (ISZERO(rhs)) {                  /* [lhs is non-zero]  */
3940
0
      Int adjust;                       /* work  */
3941
0
      Int rexp=rhs->exponent;           /* save in case RHS==RES  */
3942
0
      bits=rhs->bits;                   /* be clean  */
3943
0
      residue=0;                        /* clear accumulator  */
3944
0
      decCopyFit(res, lhs, set, &residue, status); /* copy (as needed)  */
3945
      #if DECSUBSET
3946
      if (set->extended) {              /* exponents on zeros count  */
3947
      #endif
3948
        /* exponent will be the lower of the two  */
3949
        /* [0-0 case handled above]  */
3950
0
        adjust=rexp-res->exponent;      /* adjustment needed [if -ve]  */
3951
0
        if (adjust<0) {     /* 0-padding needed  */
3952
0
          if ((res->digits-adjust)>set->digits) {
3953
0
            adjust=res->digits-set->digits;     /* to fit exactly  */
3954
0
            *status|=DEC_Rounded;               /* [but exact]  */
3955
0
            }
3956
0
          res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
3957
0
          res->exponent+=adjust;                /* set the exponent.  */
3958
0
          }
3959
      #if DECSUBSET
3960
        } /* extended  */
3961
      #endif
3962
0
      decFinish(res, set, &residue, status);      /* clean and finalize  */
3963
0
      break;}
3964
3965
    /* [NB: both fastpath and mainpath code below assume these cases  */
3966
    /* (notably 0-0) have already been handled]  */
3967
3968
    /* calculate the padding needed to align the operands  */
3969
0
    padding=rhs->exponent-lhs->exponent;
3970
3971
    /* Fastpath cases where the numbers are aligned and normal, the RHS  */
3972
    /* is all in one unit, no operand rounding is needed, and no carry,  */
3973
    /* lengthening, or borrow is needed  */
3974
0
    if (padding==0
3975
0
        && rhs->digits<=DECDPUN
3976
0
        && rhs->exponent>=set->emin     /* [some normals drop through]  */
3977
0
        && rhs->exponent<=set->emax-set->digits+1 /* [could clamp]  */
3978
0
        && rhs->digits<=reqdigits
3979
0
        && lhs->digits<=reqdigits) {
3980
0
      Int partial=*lhs->lsu;
3981
0
      if (!diffsign) {                  /* adding  */
3982
0
        partial+=*rhs->lsu;
3983
0
        if ((partial<=DECDPUNMAX)       /* result fits in unit  */
3984
0
         && (lhs->digits>=DECDPUN ||    /* .. and no digits-count change  */
3985
0
             partial < static_cast<Int>(powers[lhs->digits]))) { /* ..  */
3986
0
          if (res!=lhs) uprv_decNumberCopy(res, lhs);  /* not in place  */
3987
0
          *res->lsu = static_cast<Unit>(partial); /* [copy could have overwritten RHS]  */
3988
0
          break;
3989
0
          }
3990
        /* else drop out for careful add  */
3991
0
        }
3992
0
       else {                           /* signs differ  */
3993
0
        partial-=*rhs->lsu;
3994
0
        if (partial>0) { /* no borrow needed, and non-0 result  */
3995
0
          if (res!=lhs) uprv_decNumberCopy(res, lhs);  /* not in place  */
3996
0
          *res->lsu = static_cast<Unit>(partial);
3997
          /* this could have reduced digits [but result>0]  */
3998
0
          res->digits=decGetDigits(res->lsu, D2U(res->digits));
3999
0
          break;
4000
0
          }
4001
        /* else drop out for careful subtract  */
4002
0
        }
4003
0
      }
4004
4005
    /* Now align (pad) the lhs or rhs so they can be added or  */
4006
    /* subtracted, as necessary.  If one number is much larger than  */
4007
    /* the other (that is, if in plain form there is a least one  */
4008
    /* digit between the lowest digit of one and the highest of the  */
4009
    /* other) padding with up to DIGITS-1 trailing zeros may be  */
4010
    /* needed; then apply rounding (as exotic rounding modes may be  */
4011
    /* affected by the residue).  */
4012
0
    rhsshift=0;               /* rhs shift to left (padding) in Units  */
4013
0
    bits=lhs->bits;           /* assume sign is that of LHS  */
4014
0
    mult=1;                   /* likely multiplier  */
4015
4016
    /* [if padding==0 the operands are aligned; no padding is needed]  */
4017
0
    if (padding!=0) {
4018
      /* some padding needed; always pad the RHS, as any required  */
4019
      /* padding can then be effected by a simple combination of  */
4020
      /* shifts and a multiply  */
4021
0
      Flag swapped=0;
4022
0
      if (padding<0) {                  /* LHS needs the padding  */
4023
0
        const decNumber *t;
4024
0
        padding=-padding;               /* will be +ve  */
4025
0
        bits = static_cast<uByte>(rhs->bits ^ negate); /* assumed sign is now that of RHS  */
4026
0
        t=lhs; lhs=rhs; rhs=t;
4027
0
        swapped=1;
4028
0
        }
4029
4030
      /* If, after pad, rhs would be longer than lhs by digits+1 or  */
4031
      /* more then lhs cannot affect the answer, except as a residue,  */
4032
      /* so only need to pad up to a length of DIGITS+1.  */
4033
0
      if (rhs->digits+padding > lhs->digits+reqdigits+1) {
4034
        /* The RHS is sufficient  */
4035
        /* for residue use the relative sign indication...  */
4036
0
        Int shift=reqdigits-rhs->digits;     /* left shift needed  */
4037
0
        residue=1;                           /* residue for rounding  */
4038
0
        if (diffsign) residue=-residue;      /* signs differ  */
4039
        /* copy, shortening if necessary  */
4040
0
        decCopyFit(res, rhs, set, &residue, status);
4041
        /* if it was already shorter, then need to pad with zeros  */
4042
0
        if (shift>0) {
4043
0
          res->digits=decShiftToMost(res->lsu, res->digits, shift);
4044
0
          res->exponent-=shift;              /* adjust the exponent.  */
4045
0
          }
4046
        /* flip the result sign if unswapped and rhs was negated  */
4047
0
        if (!swapped) res->bits^=negate;
4048
0
        decFinish(res, set, &residue, status);    /* done  */
4049
0
        break;}
4050
4051
      /* LHS digits may affect result  */
4052
0
      rhsshift=D2U(padding+1)-1;        /* this much by Unit shift ..  */
4053
0
      mult=powers[padding-(rhsshift*DECDPUN)]; /* .. this by multiplication  */
4054
0
      } /* padding needed  */
4055
4056
0
    if (diffsign) mult=-mult;           /* signs differ  */
4057
4058
    /* determine the longer operand  */
4059
0
    maxdigits=rhs->digits+padding;      /* virtual length of RHS  */
4060
0
    if (lhs->digits>maxdigits) maxdigits=lhs->digits;
4061
4062
    /* Decide on the result buffer to use; if possible place directly  */
4063
    /* into result.  */
4064
0
    acc=res->lsu;                       /* assume add direct to result  */
4065
    /* If destructive overlap, or the number is too long, or a carry or  */
4066
    /* borrow to DIGITS+1 might be possible, a buffer must be used.  */
4067
    /* [Might be worth more sophisticated tests when maxdigits==reqdigits]  */
4068
0
    if ((maxdigits>=reqdigits)          /* is, or could be, too large  */
4069
0
     || (res==rhs && rhsshift>0)) {     /* destructive overlap  */
4070
      /* buffer needed, choose it; units for maxdigits digits will be  */
4071
      /* needed, +1 Unit for carry or borrow  */
4072
0
      Int need=D2U(maxdigits)+1;
4073
0
      acc=accbuff;                      /* assume use local buffer  */
4074
0
      if (need*sizeof(Unit)>sizeof(accbuff)) {
4075
        /* printf("malloc add %ld %ld\n", need, sizeof(accbuff));  */
4076
0
        allocacc = static_cast<Unit*>(malloc(need * sizeof(Unit)));
4077
0
        if (allocacc==nullptr) {           /* hopeless -- abandon  */
4078
0
          *status|=DEC_Insufficient_storage;
4079
0
          break;}
4080
0
        acc=allocacc;
4081
0
        }
4082
0
      }
4083
4084
0
    res->bits = static_cast<uByte>(bits & DECNEG); /* it's now safe to overwrite..  */
4085
0
    res->exponent=lhs->exponent;        /* .. operands (even if aliased)  */
4086
4087
    #if DECTRACE
4088
      decDumpAr('A', lhs->lsu, D2U(lhs->digits));
4089
      decDumpAr('B', rhs->lsu, D2U(rhs->digits));
4090
      printf("  :h: %ld %ld\n", rhsshift, mult);
4091
    #endif
4092
4093
    /* add [A+B*m] or subtract [A+B*(-m)]  */
4094
0
    U_ASSERT(rhs->digits > 0);
4095
0
    U_ASSERT(lhs->digits > 0);
4096
0
    res->digits=decUnitAddSub(lhs->lsu, D2U(lhs->digits),
4097
0
                              rhs->lsu, D2U(rhs->digits),
4098
0
                              rhsshift, acc, mult)
4099
0
               *DECDPUN;           /* [units -> digits]  */
4100
0
    if (res->digits<0) {           /* borrowed...  */
4101
0
      res->digits=-res->digits;
4102
0
      res->bits^=DECNEG;           /* flip the sign  */
4103
0
      }
4104
    #if DECTRACE
4105
      decDumpAr('+', acc, D2U(res->digits));
4106
    #endif
4107
4108
    /* If a buffer was used the result must be copied back, possibly  */
4109
    /* shortening.  (If no buffer was used then the result must have  */
4110
    /* fit, so can't need rounding and residue must be 0.)  */
4111
0
    residue=0;                     /* clear accumulator  */
4112
0
    if (acc!=res->lsu) {
4113
      #if DECSUBSET
4114
      if (set->extended) {         /* round from first significant digit  */
4115
      #endif
4116
        /* remove leading zeros that were added due to rounding up to  */
4117
        /* integral Units -- before the test for rounding.  */
4118
0
        if (res->digits>reqdigits)
4119
0
          res->digits=decGetDigits(acc, D2U(res->digits));
4120
0
        decSetCoeff(res, set, acc, res->digits, &residue, status);
4121
      #if DECSUBSET
4122
        }
4123
       else { /* subset arithmetic rounds from original significant digit  */
4124
        /* May have an underestimate.  This only occurs when both  */
4125
        /* numbers fit in DECDPUN digits and are padding with a  */
4126
        /* negative multiple (-10, -100...) and the top digit(s) become  */
4127
        /* 0.  (This only matters when using X3.274 rules where the  */
4128
        /* leading zero could be included in the rounding.)  */
4129
        if (res->digits<maxdigits) {
4130
          *(acc+D2U(res->digits))=0; /* ensure leading 0 is there  */
4131
          res->digits=maxdigits;
4132
          }
4133
         else {
4134
          /* remove leading zeros that added due to rounding up to  */
4135
          /* integral Units (but only those in excess of the original  */
4136
          /* maxdigits length, unless extended) before test for rounding.  */
4137
          if (res->digits>reqdigits) {
4138
            res->digits=decGetDigits(acc, D2U(res->digits));
4139
            if (res->digits<maxdigits) res->digits=maxdigits;
4140
            }
4141
          }
4142
        decSetCoeff(res, set, acc, res->digits, &residue, status);
4143
        /* Now apply rounding if needed before removing leading zeros.  */
4144
        /* This is safe because subnormals are not a possibility  */
4145
        if (residue!=0) {
4146
          decApplyRound(res, set, residue, status);
4147
          residue=0;                 /* did what needed to be done  */
4148
          }
4149
        } /* subset  */
4150
      #endif
4151
0
      } /* used buffer  */
4152
4153
    /* strip leading zeros [these were left on in case of subset subtract]  */
4154
0
    res->digits=decGetDigits(res->lsu, D2U(res->digits));
4155
4156
    /* apply checks and rounding  */
4157
0
    decFinish(res, set, &residue, status);
4158
4159
    /* "When the sum of two operands with opposite signs is exactly  */
4160
    /* zero, the sign of that sum shall be '+' in all rounding modes  */
4161
    /* except round toward -Infinity, in which mode that sign shall be  */
4162
    /* '-'."  [Subset zeros also never have '-', set by decFinish.]  */
4163
0
    if (ISZERO(res) && diffsign
4164
     #if DECSUBSET
4165
     && set->extended
4166
     #endif
4167
0
     && (*status&DEC_Inexact)==0) {
4168
0
      if (set->round==DEC_ROUND_FLOOR) res->bits|=DECNEG;   /* sign -  */
4169
0
                                  else res->bits&=~DECNEG;  /* sign +  */
4170
0
      }
4171
0
    } while(0);                              /* end protected  */
4172
4173
0
  if (allocacc!=nullptr) free(allocacc);        /* drop any storage used  */
4174
  #if DECSUBSET
4175
  if (allocrhs!=nullptr) free(allocrhs);        /* ..  */
4176
  if (alloclhs!=nullptr) free(alloclhs);        /* ..  */
4177
  #endif
4178
0
  return res;
4179
0
  } /* decAddOp  */
4180
4181
/* ------------------------------------------------------------------ */
4182
/* decDivideOp -- division operation                                  */
4183
/*                                                                    */
4184
/*  This routine performs the calculations for all four division      */
4185
/*  operators (divide, divideInteger, remainder, remainderNear).      */
4186
/*                                                                    */
4187
/*  C=A op B                                                          */
4188
/*                                                                    */
4189
/*   res is C, the result.  C may be A and/or B (e.g., X=X/X)         */
4190
/*   lhs is A                                                         */
4191
/*   rhs is B                                                         */
4192
/*   set is the context                                               */
4193
/*   op  is DIVIDE, DIVIDEINT, REMAINDER, or REMNEAR respectively.    */
4194
/*   status is the usual accumulator                                  */
4195
/*                                                                    */
4196
/* C must have space for set->digits digits.                          */
4197
/*                                                                    */
4198
/* ------------------------------------------------------------------ */
4199
/*   The underlying algorithm of this routine is the same as in the   */
4200
/*   1981 S/370 implementation, that is, non-restoring long division  */
4201
/*   with bi-unit (rather than bi-digit) estimation for each unit     */
4202
/*   multiplier.  In this pseudocode overview, complications for the  */
4203
/*   Remainder operators and division residues for exact rounding are */
4204
/*   omitted for clarity.                                             */
4205
/*                                                                    */
4206
/*     Prepare operands and handle special values                     */
4207
/*     Test for x/0 and then 0/x                                      */
4208
/*     Exp =Exp1 - Exp2                                               */
4209
/*     Exp =Exp +len(var1) -len(var2)                                 */
4210
/*     Sign=Sign1 * Sign2                                             */
4211
/*     Pad accumulator (Var1) to double-length with 0's (pad1)        */
4212
/*     Pad Var2 to same length as Var1                                */
4213
/*     msu2pair/plus=1st 2 or 1 units of var2, +1 to allow for round  */
4214
/*     have=0                                                         */
4215
/*     Do until (have=digits+1 OR residue=0)                          */
4216
/*       if exp<0 then if integer divide/residue then leave           */
4217
/*       this_unit=0                                                  */
4218
/*       Do forever                                                   */
4219
/*          compare numbers                                           */
4220
/*          if <0 then leave inner_loop                               */
4221
/*          if =0 then (* quick exit without subtract *) do           */
4222
/*             this_unit=this_unit+1; output this_unit                */
4223
/*             leave outer_loop; end                                  */
4224
/*          Compare lengths of numbers (mantissae):                   */
4225
/*          If same then tops2=msu2pair -- {units 1&2 of var2}        */
4226
/*                  else tops2=msu2plus -- {0, unit 1 of var2}        */
4227
/*          tops1=first_unit_of_Var1*10**DECDPUN +second_unit_of_var1 */
4228
/*          mult=tops1/tops2  -- Good and safe guess at divisor       */
4229
/*          if mult=0 then mult=1                                     */
4230
/*          this_unit=this_unit+mult                                  */
4231
/*          subtract                                                  */
4232
/*          end inner_loop                                            */
4233
/*        if have\=0 | this_unit\=0 then do                           */
4234
/*          output this_unit                                          */
4235
/*          have=have+1; end                                          */
4236
/*        var2=var2/10                                                */
4237
/*        exp=exp-1                                                   */
4238
/*        end outer_loop                                              */
4239
/*     exp=exp+1   -- set the proper exponent                         */
4240
/*     if have=0 then generate answer=0                               */
4241
/*     Return (Result is defined by Var1)                             */
4242
/*                                                                    */
4243
/* ------------------------------------------------------------------ */
4244
/* Two working buffers are needed during the division; one (digits+   */
4245
/* 1) to accumulate the result, and the other (up to 2*digits+1) for  */
4246
/* long subtractions.  These are acc and var1 respectively.           */
4247
/* var1 is a copy of the lhs coefficient, var2 is the rhs coefficient.*/
4248
/* The static buffers may be larger than might be expected to allow   */
4249
/* for calls from higher-level functions (notable exp).                */
4250
/* ------------------------------------------------------------------ */
4251
static decNumber * decDivideOp(decNumber *res,
4252
                               const decNumber *lhs, const decNumber *rhs,
4253
0
                               decContext *set, Flag op, uInt *status) {
4254
  #if DECSUBSET
4255
  decNumber *alloclhs=nullptr;        /* non-nullptr if rounded lhs allocated  */
4256
  decNumber *allocrhs=nullptr;        /* .., rhs  */
4257
  #endif
4258
0
  Unit  accbuff[SD2U(DECBUFFER+DECDPUN+10)]; /* local buffer  */
4259
0
  Unit  *acc=accbuff;              /* -> accumulator array for result  */
4260
0
  Unit  *allocacc=nullptr;            /* -> allocated buffer, iff allocated  */
4261
0
  Unit  *accnext;                  /* -> where next digit will go  */
4262
0
  Int   acclength;                 /* length of acc needed [Units]  */
4263
0
  Int   accunits;                  /* count of units accumulated  */
4264
0
  Int   accdigits;                 /* count of digits accumulated  */
4265
4266
0
  Unit  varbuff[SD2U(DECBUFFER*2+DECDPUN)];  /* buffer for var1  */
4267
0
  Unit  *var1=varbuff;             /* -> var1 array for long subtraction  */
4268
0
  Unit  *varalloc=nullptr;            /* -> allocated buffer, iff used  */
4269
0
  Unit  *msu1;                     /* -> msu of var1  */
4270
4271
0
  const Unit *var2;                /* -> var2 array  */
4272
0
  const Unit *msu2;                /* -> msu of var2  */
4273
0
  Int   msu2plus;                  /* msu2 plus one [does not vary]  */
4274
0
  eInt  msu2pair;                  /* msu2 pair plus one [does not vary]  */
4275
4276
0
  Int   var1units, var2units;      /* actual lengths  */
4277
0
  Int   var2ulen;                  /* logical length (units)  */
4278
0
  Int   var1initpad=0;             /* var1 initial padding (digits)  */
4279
0
  Int   maxdigits;                 /* longest LHS or required acc length  */
4280
0
  Int   mult;                      /* multiplier for subtraction  */
4281
0
  Unit  thisunit;                  /* current unit being accumulated  */
4282
0
  Int   residue;                   /* for rounding  */
4283
0
  Int   reqdigits=set->digits;     /* requested DIGITS  */
4284
0
  Int   exponent;                  /* working exponent  */
4285
0
  Int   maxexponent=0;             /* DIVIDE maximum exponent if unrounded  */
4286
0
  uByte bits;                      /* working sign  */
4287
0
  Unit  *target;                   /* work  */
4288
0
  const Unit *source;              /* ..  */
4289
0
  uInt  const *pow;                /* ..  */
4290
0
  Int   shift, cut;                /* ..  */
4291
  #if DECSUBSET
4292
  Int   dropped;                   /* work  */
4293
  #endif
4294
4295
  #if DECCHECK
4296
  if (decCheckOperands(res, lhs, rhs, set)) return res;
4297
  #endif
4298
4299
0
  do {                             /* protect allocated storage  */
4300
    #if DECSUBSET
4301
    if (!set->extended) {
4302
      /* reduce operands and set lostDigits status, as needed  */
4303
      if (lhs->digits>reqdigits) {
4304
        alloclhs=decRoundOperand(lhs, set, status);
4305
        if (alloclhs==nullptr) break;
4306
        lhs=alloclhs;
4307
        }
4308
      if (rhs->digits>reqdigits) {
4309
        allocrhs=decRoundOperand(rhs, set, status);
4310
        if (allocrhs==nullptr) break;
4311
        rhs=allocrhs;
4312
        }
4313
      }
4314
    #endif
4315
    /* [following code does not require input rounding]  */
4316
4317
0
    bits=(lhs->bits^rhs->bits)&DECNEG;  /* assumed sign for divisions  */
4318
4319
    /* handle infinities and NaNs  */
4320
0
    if (SPECIALARGS) {                  /* a special bit set  */
4321
0
      if (SPECIALARGS & (DECSNAN | DECNAN)) { /* one or two NaNs  */
4322
0
        decNaNs(res, lhs, rhs, set, status);
4323
0
        break;
4324
0
        }
4325
      /* one or two infinities  */
4326
0
      if (decNumberIsInfinite(lhs)) {   /* LHS (dividend) is infinite  */
4327
0
        if (decNumberIsInfinite(rhs) || /* two infinities are invalid ..  */
4328
0
            op & (REMAINDER | REMNEAR)) { /* as is remainder of infinity  */
4329
0
          *status|=DEC_Invalid_operation;
4330
0
          break;
4331
0
          }
4332
        /* [Note that infinity/0 raises no exceptions]  */
4333
0
        uprv_decNumberZero(res);
4334
0
        res->bits=bits|DECINF;          /* set +/- infinity  */
4335
0
        break;
4336
0
        }
4337
0
       else {                           /* RHS (divisor) is infinite  */
4338
0
        residue=0;
4339
0
        if (op&(REMAINDER|REMNEAR)) {
4340
          /* result is [finished clone of] lhs  */
4341
0
          decCopyFit(res, lhs, set, &residue, status);
4342
0
          }
4343
0
         else {  /* a division  */
4344
0
          uprv_decNumberZero(res);
4345
0
          res->bits=bits;               /* set +/- zero  */
4346
          /* for DIVIDEINT the exponent is always 0.  For DIVIDE, result  */
4347
          /* is a 0 with infinitely negative exponent, clamped to minimum  */
4348
0
          if (op&DIVIDE) {
4349
0
            res->exponent=set->emin-set->digits+1;
4350
0
            *status|=DEC_Clamped;
4351
0
            }
4352
0
          }
4353
0
        decFinish(res, set, &residue, status);
4354
0
        break;
4355
0
        }
4356
0
      }
4357
4358
    /* handle 0 rhs (x/0)  */
4359
0
    if (ISZERO(rhs)) {                  /* x/0 is always exceptional  */
4360
0
      if (ISZERO(lhs)) {
4361
0
        uprv_decNumberZero(res);             /* [after lhs test]  */
4362
0
        *status|=DEC_Division_undefined;/* 0/0 will become NaN  */
4363
0
        }
4364
0
       else {
4365
0
        uprv_decNumberZero(res);
4366
0
        if (op&(REMAINDER|REMNEAR)) *status|=DEC_Invalid_operation;
4367
0
         else {
4368
0
          *status|=DEC_Division_by_zero; /* x/0  */
4369
0
          res->bits=bits|DECINF;         /* .. is +/- Infinity  */
4370
0
          }
4371
0
        }
4372
0
      break;}
4373
4374
    /* handle 0 lhs (0/x)  */
4375
0
    if (ISZERO(lhs)) {                  /* 0/x [x!=0]  */
4376
      #if DECSUBSET
4377
      if (!set->extended) uprv_decNumberZero(res);
4378
       else {
4379
      #endif
4380
0
        if (op&DIVIDE) {
4381
0
          residue=0;
4382
0
          exponent=lhs->exponent-rhs->exponent; /* ideal exponent  */
4383
0
          uprv_decNumberCopy(res, lhs);      /* [zeros always fit]  */
4384
0
          res->bits=bits;               /* sign as computed  */
4385
0
          res->exponent=exponent;       /* exponent, too  */
4386
0
          decFinalize(res, set, &residue, status);   /* check exponent  */
4387
0
          }
4388
0
         else if (op&DIVIDEINT) {
4389
0
          uprv_decNumberZero(res);           /* integer 0  */
4390
0
          res->bits=bits;               /* sign as computed  */
4391
0
          }
4392
0
         else {                         /* a remainder  */
4393
0
          exponent=rhs->exponent;       /* [save in case overwrite]  */
4394
0
          uprv_decNumberCopy(res, lhs);      /* [zeros always fit]  */
4395
0
          if (exponent<res->exponent) res->exponent=exponent; /* use lower  */
4396
0
          }
4397
      #if DECSUBSET
4398
        }
4399
      #endif
4400
0
      break;}
4401
4402
    /* Precalculate exponent.  This starts off adjusted (and hence fits  */
4403
    /* in 31 bits) and becomes the usual unadjusted exponent as the  */
4404
    /* division proceeds.  The order of evaluation is important, here,  */
4405
    /* to avoid wrap.  */
4406
0
    exponent=(lhs->exponent+lhs->digits)-(rhs->exponent+rhs->digits);
4407
4408
    /* If the working exponent is -ve, then some quick exits are  */
4409
    /* possible because the quotient is known to be <1  */
4410
    /* [for REMNEAR, it needs to be < -1, as -0.5 could need work]  */
4411
0
    if (exponent<0 && !(op==DIVIDE)) {
4412
0
      if (op&DIVIDEINT) {
4413
0
        uprv_decNumberZero(res);                  /* integer part is 0  */
4414
        #if DECSUBSET
4415
        if (set->extended)
4416
        #endif
4417
0
          res->bits=bits;                    /* set +/- zero  */
4418
0
        break;}
4419
      /* fastpath remainders so long as the lhs has the smaller  */
4420
      /* (or equal) exponent  */
4421
0
      if (lhs->exponent<=rhs->exponent) {
4422
0
        if (op&REMAINDER || exponent<-1) {
4423
          /* It is REMAINDER or safe REMNEAR; result is [finished  */
4424
          /* clone of] lhs  (r = x - 0*y)  */
4425
0
          residue=0;
4426
0
          decCopyFit(res, lhs, set, &residue, status);
4427
0
          decFinish(res, set, &residue, status);
4428
0
          break;
4429
0
          }
4430
        /* [unsafe REMNEAR drops through]  */
4431
0
        }
4432
0
      } /* fastpaths  */
4433
4434
    /* Long (slow) division is needed; roll up the sleeves... */
4435
4436
    /* The accumulator will hold the quotient of the division.  */
4437
    /* If it needs to be too long for stack storage, then allocate.  */
4438
0
    acclength=D2U(reqdigits+DECDPUN);   /* in Units  */
4439
0
    if (acclength*sizeof(Unit)>sizeof(accbuff)) {
4440
      /* printf("malloc dvacc %ld units\n", acclength);  */
4441
0
      allocacc = static_cast<Unit*>(malloc(acclength * sizeof(Unit)));
4442
0
      if (allocacc==nullptr) {             /* hopeless -- abandon  */
4443
0
        *status|=DEC_Insufficient_storage;
4444
0
        break;}
4445
0
      acc=allocacc;                     /* use the allocated space  */
4446
0
      }
4447
4448
    /* var1 is the padded LHS ready for subtractions.  */
4449
    /* If it needs to be too long for stack storage, then allocate.  */
4450
    /* The maximum units needed for var1 (long subtraction) is:  */
4451
    /* Enough for  */
4452
    /*     (rhs->digits+reqdigits-1) -- to allow full slide to right  */
4453
    /* or  (lhs->digits)             -- to allow for long lhs  */
4454
    /* whichever is larger  */
4455
    /*   +1                -- for rounding of slide to right  */
4456
    /*   +1                -- for leading 0s  */
4457
    /*   +1                -- for pre-adjust if a remainder or DIVIDEINT  */
4458
    /* [Note: unused units do not participate in decUnitAddSub data]  */
4459
0
    maxdigits=rhs->digits+reqdigits-1;
4460
0
    if (lhs->digits>maxdigits) maxdigits=lhs->digits;
4461
0
    var1units=D2U(maxdigits)+2;
4462
    /* allocate a guard unit above msu1 for REMAINDERNEAR  */
4463
0
    if (!(op&DIVIDE)) var1units++;
4464
0
    if ((var1units+1)*sizeof(Unit)>sizeof(varbuff)) {
4465
      /* printf("malloc dvvar %ld units\n", var1units+1);  */
4466
0
      varalloc = static_cast<Unit*>(malloc((var1units + 1) * sizeof(Unit)));
4467
0
      if (varalloc==nullptr) {             /* hopeless -- abandon  */
4468
0
        *status|=DEC_Insufficient_storage;
4469
0
        break;}
4470
0
      var1=varalloc;                    /* use the allocated space  */
4471
0
      }
4472
4473
    /* Extend the lhs and rhs to full long subtraction length.  The lhs  */
4474
    /* is truly extended into the var1 buffer, with 0 padding, so a  */
4475
    /* subtract in place is always possible.  The rhs (var2) has  */
4476
    /* virtual padding (implemented by decUnitAddSub).  */
4477
    /* One guard unit was allocated above msu1 for rem=rem+rem in  */
4478
    /* REMAINDERNEAR.  */
4479
0
    msu1=var1+var1units-1;              /* msu of var1  */
4480
0
    source=lhs->lsu+D2U(lhs->digits)-1; /* msu of input array  */
4481
0
    for (target=msu1; source>=lhs->lsu; source--, target--) *target=*source;
4482
0
    for (; target>=var1; target--) *target=0;
4483
4484
    /* rhs (var2) is left-aligned with var1 at the start  */
4485
0
    var2ulen=var1units;                 /* rhs logical length (units)  */
4486
0
    var2units=D2U(rhs->digits);         /* rhs actual length (units)  */
4487
0
    var2=rhs->lsu;                      /* -> rhs array  */
4488
0
    msu2=var2+var2units-1;              /* -> msu of var2 [never changes]  */
4489
    /* now set up the variables which will be used for estimating the  */
4490
    /* multiplication factor.  If these variables are not exact, add  */
4491
    /* 1 to make sure that the multiplier is never overestimated.  */
4492
0
    msu2plus=*msu2;                     /* it's value ..  */
4493
0
    if (var2units>1) msu2plus++;        /* .. +1 if any more  */
4494
0
    msu2pair = static_cast<eInt>(*msu2) * (DECDPUNMAX + 1); /* top two pair ..  */
4495
0
    if (var2units>1) {                  /* .. [else treat 2nd as 0]  */
4496
0
      msu2pair+=*(msu2-1);              /* ..  */
4497
0
      if (var2units>2) msu2pair++;      /* .. +1 if any more  */
4498
0
      }
4499
4500
    /* The calculation is working in units, which may have leading zeros,  */
4501
    /* but the exponent was calculated on the assumption that they are  */
4502
    /* both left-aligned.  Adjust the exponent to compensate: add the  */
4503
    /* number of leading zeros in var1 msu and subtract those in var2 msu.  */
4504
    /* [This is actually done by counting the digits and negating, as  */
4505
    /* lead1=DECDPUN-digits1, and similarly for lead2.]  */
4506
0
    for (pow=&powers[1]; *msu1>=*pow; pow++) exponent--;
4507
0
    for (pow=&powers[1]; *msu2>=*pow; pow++) exponent++;
4508
4509
    /* Now, if doing an integer divide or remainder, ensure that  */
4510
    /* the result will be Unit-aligned.  To do this, shift the var1  */
4511
    /* accumulator towards least if need be.  (It's much easier to  */
4512
    /* do this now than to reassemble the residue afterwards, if  */
4513
    /* doing a remainder.)  Also ensure the exponent is not negative.  */
4514
0
    if (!(op&DIVIDE)) {
4515
0
      Unit *u;                          /* work  */
4516
      /* save the initial 'false' padding of var1, in digits  */
4517
0
      var1initpad=(var1units-D2U(lhs->digits))*DECDPUN;
4518
      /* Determine the shift to do.  */
4519
0
      if (exponent<0) cut=-exponent;
4520
0
       else cut=DECDPUN-exponent%DECDPUN;
4521
0
      decShiftToLeast(var1, var1units, cut);
4522
0
      exponent+=cut;                    /* maintain numerical value  */
4523
0
      var1initpad-=cut;                 /* .. and reduce padding  */
4524
      /* clean any most-significant units which were just emptied  */
4525
0
      for (u=msu1; cut>=DECDPUN; cut-=DECDPUN, u--) *u=0;
4526
0
      } /* align  */
4527
0
     else { /* is DIVIDE  */
4528
0
      maxexponent=lhs->exponent-rhs->exponent;    /* save  */
4529
      /* optimization: if the first iteration will just produce 0,  */
4530
      /* preadjust to skip it [valid for DIVIDE only]  */
4531
0
      if (*msu1<*msu2) {
4532
0
        var2ulen--;                     /* shift down  */
4533
0
        exponent-=DECDPUN;              /* update the exponent  */
4534
0
        }
4535
0
      }
4536
4537
    /* ---- start the long-division loops ------------------------------  */
4538
0
    accunits=0;                         /* no units accumulated yet  */
4539
0
    accdigits=0;                        /* .. or digits  */
4540
0
    accnext=acc+acclength-1;            /* -> msu of acc [NB: allows digits+1]  */
4541
0
    for (;;) {                          /* outer forever loop  */
4542
0
      thisunit=0;                       /* current unit assumed 0  */
4543
      /* find the next unit  */
4544
0
      for (;;) {                        /* inner forever loop  */
4545
        /* strip leading zero units [from either pre-adjust or from  */
4546
        /* subtract last time around].  Leave at least one unit.  */
4547
0
        for (; *msu1==0 && msu1>var1; msu1--) var1units--;
4548
4549
0
        if (var1units<var2ulen) break;       /* var1 too low for subtract  */
4550
0
        if (var1units==var2ulen) {           /* unit-by-unit compare needed  */
4551
          /* compare the two numbers, from msu  */
4552
0
          const Unit *pv1, *pv2;
4553
0
          Unit v2;                           /* units to compare  */
4554
0
          pv2=msu2;                          /* -> msu  */
4555
0
          for (pv1=msu1; ; pv1--, pv2--) {
4556
            /* v1=*pv1 -- always OK  */
4557
0
            v2=0;                            /* assume in padding  */
4558
0
            if (pv2>=var2) v2=*pv2;          /* in range  */
4559
0
            if (*pv1!=v2) break;             /* no longer the same  */
4560
0
            if (pv1==var1) break;            /* done; leave pv1 as is  */
4561
0
            }
4562
          /* here when all inspected or a difference seen  */
4563
0
          if (*pv1<v2) break;                /* var1 too low to subtract  */
4564
0
          if (*pv1==v2) {                    /* var1 == var2  */
4565
            /* reach here if var1 and var2 are identical; subtraction  */
4566
            /* would increase digit by one, and the residue will be 0 so  */
4567
            /* the calculation is done; leave the loop with residue=0.  */
4568
0
            thisunit++;                      /* as though subtracted  */
4569
0
            *var1=0;                         /* set var1 to 0  */
4570
0
            var1units=1;                     /* ..  */
4571
0
            break;  /* from inner  */
4572
0
            } /* var1 == var2  */
4573
          /* *pv1>v2.  Prepare for real subtraction; the lengths are equal  */
4574
          /* Estimate the multiplier (there's always a msu1-1)...  */
4575
          /* Bring in two units of var2 to provide a good estimate.  */
4576
0
            mult = static_cast<Int>((static_cast<eInt>(*msu1) * (DECDPUNMAX + 1) + *(msu1 - 1)) / msu2pair);
4577
0
          } /* lengths the same  */
4578
0
         else { /* var1units > var2ulen, so subtraction is safe  */
4579
          /* The var2 msu is one unit towards the lsu of the var1 msu,  */
4580
          /* so only one unit for var2 can be used.  */
4581
0
          mult = static_cast<Int>((static_cast<eInt>(*msu1) * (DECDPUNMAX + 1) + *(msu1 - 1)) / msu2plus);
4582
0
          }
4583
0
        if (mult==0) mult=1;                 /* must always be at least 1  */
4584
        /* subtraction needed; var1 is > var2  */
4585
0
        thisunit = static_cast<Unit>(thisunit + mult); /* accumulate  */
4586
        /* subtract var1-var2, into var1; only the overlap needs  */
4587
        /* processing, as this is an in-place calculation  */
4588
0
        shift=var2ulen-var2units;
4589
        #if DECTRACE
4590
          decDumpAr('1', &var1[shift], var1units-shift);
4591
          decDumpAr('2', var2, var2units);
4592
          printf("m=%ld\n", -mult);
4593
        #endif
4594
0
        decUnitAddSub(&var1[shift], var1units-shift,
4595
0
                      var2, var2units, 0,
4596
0
                      &var1[shift], -mult);
4597
        #if DECTRACE
4598
          decDumpAr('#', &var1[shift], var1units-shift);
4599
        #endif
4600
        /* var1 now probably has leading zeros; these are removed at the  */
4601
        /* top of the inner loop.  */
4602
0
        } /* inner loop  */
4603
4604
      /* The next unit has been calculated in full; unless it's a  */
4605
      /* leading zero, add to acc  */
4606
0
      if (accunits!=0 || thisunit!=0) {      /* is first or non-zero  */
4607
0
        *accnext=thisunit;                   /* store in accumulator  */
4608
        /* account exactly for the new digits  */
4609
0
        if (accunits==0) {
4610
0
          accdigits++;                       /* at least one  */
4611
0
          for (pow=&powers[1]; thisunit>=*pow; pow++) accdigits++;
4612
0
          }
4613
0
         else accdigits+=DECDPUN;
4614
0
        accunits++;                          /* update count  */
4615
0
        accnext--;                           /* ready for next  */
4616
0
        if (accdigits>reqdigits) break;      /* have enough digits  */
4617
0
        }
4618
4619
      /* if the residue is zero, the operation is done (unless divide  */
4620
      /* or divideInteger and still not enough digits yet)  */
4621
0
      if (*var1==0 && var1units==1) {        /* residue is 0  */
4622
0
        if (op&(REMAINDER|REMNEAR)) break;
4623
0
        if ((op&DIVIDE) && (exponent<=maxexponent)) break;
4624
        /* [drop through if divideInteger]  */
4625
0
        }
4626
      /* also done enough if calculating remainder or integer  */
4627
      /* divide and just did the last ('units') unit  */
4628
0
      if (exponent==0 && !(op&DIVIDE)) break;
4629
4630
      /* to get here, var1 is less than var2, so divide var2 by the per-  */
4631
      /* Unit power of ten and go for the next digit  */
4632
0
      var2ulen--;                            /* shift down  */
4633
0
      exponent-=DECDPUN;                     /* update the exponent  */
4634
0
      } /* outer loop  */
4635
4636
    /* ---- division is complete ---------------------------------------  */
4637
    /* here: acc      has at least reqdigits+1 of good results (or fewer  */
4638
    /*                if early stop), starting at accnext+1 (its lsu)  */
4639
    /*       var1     has any residue at the stopping point  */
4640
    /*       accunits is the number of digits collected in acc  */
4641
0
    if (accunits==0) {             /* acc is 0  */
4642
0
      accunits=1;                  /* show have a unit ..  */
4643
0
      accdigits=1;                 /* ..  */
4644
0
      *accnext=0;                  /* .. whose value is 0  */
4645
0
      }
4646
0
     else accnext++;               /* back to last placed  */
4647
    /* accnext now -> lowest unit of result  */
4648
4649
0
    residue=0;                     /* assume no residue  */
4650
0
    if (op&DIVIDE) {
4651
      /* record the presence of any residue, for rounding  */
4652
0
      if (*var1!=0 || var1units>1) residue=1;
4653
0
       else { /* no residue  */
4654
        /* Had an exact division; clean up spurious trailing 0s.  */
4655
        /* There will be at most DECDPUN-1, from the final multiply,  */
4656
        /* and then only if the result is non-0 (and even) and the  */
4657
        /* exponent is 'loose'.  */
4658
        #if DECDPUN>1
4659
        Unit lsu=*accnext;
4660
        if (!(lsu&0x01) && (lsu!=0)) {
4661
          /* count the trailing zeros  */
4662
          Int drop=0;
4663
          for (;; drop++) {    /* [will terminate because lsu!=0]  */
4664
            if (exponent>=maxexponent) break;     /* don't chop real 0s  */
4665
            #if DECDPUN<=4
4666
              if ((lsu-QUOT10(lsu, drop+1)
4667
                  *powers[drop+1])!=0) break;     /* found non-0 digit  */
4668
            #else
4669
              if (lsu%powers[drop+1]!=0) break;   /* found non-0 digit  */
4670
            #endif
4671
            exponent++;
4672
            }
4673
          if (drop>0) {
4674
            accunits=decShiftToLeast(accnext, accunits, drop);
4675
            accdigits=decGetDigits(accnext, accunits);
4676
            accunits=D2U(accdigits);
4677
            /* [exponent was adjusted in the loop]  */
4678
            }
4679
          } /* neither odd nor 0  */
4680
        #endif
4681
0
        } /* exact divide  */
4682
0
      } /* divide  */
4683
0
     else /* op!=DIVIDE */ {
4684
      /* check for coefficient overflow  */
4685
0
      if (accdigits+exponent>reqdigits) {
4686
0
        *status|=DEC_Division_impossible;
4687
0
        break;
4688
0
        }
4689
0
      if (op & (REMAINDER|REMNEAR)) {
4690
        /* [Here, the exponent will be 0, because var1 was adjusted  */
4691
        /* appropriately.]  */
4692
0
        Int postshift;                       /* work  */
4693
0
        Flag wasodd=0;                       /* integer was odd  */
4694
0
        Unit *quotlsu;                       /* for save  */
4695
0
        Int  quotdigits;                     /* ..  */
4696
4697
0
        bits=lhs->bits;                      /* remainder sign is always as lhs  */
4698
4699
        /* Fastpath when residue is truly 0 is worthwhile [and  */
4700
        /* simplifies the code below]  */
4701
0
        if (*var1==0 && var1units==1) {      /* residue is 0  */
4702
0
          Int exp=lhs->exponent;             /* save min(exponents)  */
4703
0
          if (rhs->exponent<exp) exp=rhs->exponent;
4704
0
          uprv_decNumberZero(res);                /* 0 coefficient  */
4705
          #if DECSUBSET
4706
          if (set->extended)
4707
          #endif
4708
0
          res->exponent=exp;                 /* .. with proper exponent  */
4709
0
          res->bits = static_cast<uByte>(bits & DECNEG); /* [cleaned]  */
4710
0
          decFinish(res, set, &residue, status);   /* might clamp  */
4711
0
          break;
4712
0
          }
4713
        /* note if the quotient was odd  */
4714
0
        if (*accnext & 0x01) wasodd=1;       /* acc is odd  */
4715
0
        quotlsu=accnext;                     /* save in case need to reinspect  */
4716
0
        quotdigits=accdigits;                /* ..  */
4717
4718
        /* treat the residue, in var1, as the value to return, via acc  */
4719
        /* calculate the unused zero digits.  This is the smaller of:  */
4720
        /*   var1 initial padding (saved above)  */
4721
        /*   var2 residual padding, which happens to be given by:  */
4722
0
        postshift=var1initpad+exponent-lhs->exponent+rhs->exponent;
4723
        /* [the 'exponent' term accounts for the shifts during divide]  */
4724
0
        if (var1initpad<postshift) postshift=var1initpad;
4725
4726
        /* shift var1 the requested amount, and adjust its digits  */
4727
0
        var1units=decShiftToLeast(var1, var1units, postshift);
4728
0
        accnext=var1;
4729
0
        accdigits=decGetDigits(var1, var1units);
4730
0
        accunits=D2U(accdigits);
4731
4732
0
        exponent=lhs->exponent;         /* exponent is smaller of lhs & rhs  */
4733
0
        if (rhs->exponent<exponent) exponent=rhs->exponent;
4734
4735
        /* Now correct the result if doing remainderNear; if it  */
4736
        /* (looking just at coefficients) is > rhs/2, or == rhs/2 and  */
4737
        /* the integer was odd then the result should be rem-rhs.  */
4738
0
        if (op&REMNEAR) {
4739
0
          Int compare, tarunits;        /* work  */
4740
0
          Unit *up;                     /* ..  */
4741
          /* calculate remainder*2 into the var1 buffer (which has  */
4742
          /* 'headroom' of an extra unit and hence enough space)  */
4743
          /* [a dedicated 'double' loop would be faster, here]  */
4744
0
          tarunits=decUnitAddSub(accnext, accunits, accnext, accunits,
4745
0
                                 0, accnext, 1);
4746
          /* decDumpAr('r', accnext, tarunits);  */
4747
4748
          /* Here, accnext (var1) holds tarunits Units with twice the  */
4749
          /* remainder's coefficient, which must now be compared to the  */
4750
          /* RHS.  The remainder's exponent may be smaller than the RHS's.  */
4751
0
          compare=decUnitCompare(accnext, tarunits, rhs->lsu, D2U(rhs->digits),
4752
0
                                 rhs->exponent-exponent);
4753
0
          if (compare==BADINT) {             /* deep trouble  */
4754
0
            *status|=DEC_Insufficient_storage;
4755
0
            break;}
4756
4757
          /* now restore the remainder by dividing by two; the lsu  */
4758
          /* is known to be even.  */
4759
0
          for (up=accnext; up<accnext+tarunits; up++) {
4760
0
            Int half;              /* half to add to lower unit  */
4761
0
            half=*up & 0x01;
4762
0
            *up/=2;                /* [shift]  */
4763
0
            if (!half) continue;
4764
0
            *(up-1)+=(DECDPUNMAX+1)/2;
4765
0
            }
4766
          /* [accunits still describes the original remainder length]  */
4767
4768
0
          if (compare>0 || (compare==0 && wasodd)) { /* adjustment needed  */
4769
0
            Int exp, expunits, exprem;       /* work  */
4770
            /* This is effectively causing round-up of the quotient,  */
4771
            /* so if it was the rare case where it was full and all  */
4772
            /* nines, it would overflow and hence division-impossible  */
4773
            /* should be raised  */
4774
0
            Flag allnines=0;                 /* 1 if quotient all nines  */
4775
0
            if (quotdigits==reqdigits) {     /* could be borderline  */
4776
0
              for (up=quotlsu; ; up++) {
4777
0
                if (quotdigits>DECDPUN) {
4778
0
                  if (*up!=DECDPUNMAX) break;/* non-nines  */
4779
0
                  }
4780
0
                 else {                      /* this is the last Unit  */
4781
0
                  if (*up==powers[quotdigits]-1) allnines=1;
4782
0
                  break;
4783
0
                  }
4784
0
                quotdigits-=DECDPUN;         /* checked those digits  */
4785
0
                } /* up  */
4786
0
              } /* borderline check  */
4787
0
            if (allnines) {
4788
0
              *status|=DEC_Division_impossible;
4789
0
              break;}
4790
4791
            /* rem-rhs is needed; the sign will invert.  Again, var1  */
4792
            /* can safely be used for the working Units array.  */
4793
0
            exp=rhs->exponent-exponent;      /* RHS padding needed  */
4794
            /* Calculate units and remainder from exponent.  */
4795
0
            expunits=exp/DECDPUN;
4796
0
            exprem=exp%DECDPUN;
4797
            /* subtract [A+B*(-m)]; the result will always be negative  */
4798
0
            accunits=-decUnitAddSub(accnext, accunits,
4799
0
                                    rhs->lsu, D2U(rhs->digits),
4800
0
                                    expunits, accnext, -static_cast<Int>(powers[exprem]));
4801
0
            accdigits=decGetDigits(accnext, accunits); /* count digits exactly  */
4802
0
            accunits=D2U(accdigits);    /* and recalculate the units for copy  */
4803
            /* [exponent is as for original remainder]  */
4804
0
            bits^=DECNEG;               /* flip the sign  */
4805
0
            }
4806
0
          } /* REMNEAR  */
4807
0
        } /* REMAINDER or REMNEAR  */
4808
0
      } /* not DIVIDE  */
4809
4810
    /* Set exponent and bits  */
4811
0
    res->exponent=exponent;
4812
0
    res->bits = static_cast<uByte>(bits & DECNEG); /* [cleaned]  */
4813
4814
    /* Now the coefficient.  */
4815
0
    decSetCoeff(res, set, accnext, accdigits, &residue, status);
4816
4817
0
    decFinish(res, set, &residue, status);   /* final cleanup  */
4818
4819
    #if DECSUBSET
4820
    /* If a divide then strip trailing zeros if subset [after round]  */
4821
    if (!set->extended && (op==DIVIDE)) decTrim(res, set, 0, 1, &dropped);
4822
    #endif
4823
0
    } while(0);                              /* end protected  */
4824
4825
0
  if (varalloc!=nullptr) free(varalloc);   /* drop any storage used  */
4826
0
  if (allocacc!=nullptr) free(allocacc);   /* ..  */
4827
  #if DECSUBSET
4828
  if (allocrhs!=nullptr) free(allocrhs);   /* ..  */
4829
  if (alloclhs!=nullptr) free(alloclhs);   /* ..  */
4830
  #endif
4831
0
  return res;
4832
0
  } /* decDivideOp  */
4833
4834
/* ------------------------------------------------------------------ */
4835
/* decMultiplyOp -- multiplication operation                          */
4836
/*                                                                    */
4837
/*  This routine performs the multiplication C=A x B.                 */
4838
/*                                                                    */
4839
/*   res is C, the result.  C may be A and/or B (e.g., X=X*X)         */
4840
/*   lhs is A                                                         */
4841
/*   rhs is B                                                         */
4842
/*   set is the context                                               */
4843
/*   status is the usual accumulator                                  */
4844
/*                                                                    */
4845
/* C must have space for set->digits digits.                          */
4846
/*                                                                    */
4847
/* ------------------------------------------------------------------ */
4848
/* 'Classic' multiplication is used rather than Karatsuba, as the     */
4849
/* latter would give only a minor improvement for the short numbers   */
4850
/* expected to be handled most (and uses much more memory).           */
4851
/*                                                                    */
4852
/* There are two major paths here: the general-purpose ('old code')   */
4853
/* path which handles all DECDPUN values, and a fastpath version      */
4854
/* which is used if 64-bit ints are available, DECDPUN<=4, and more   */
4855
/* than two calls to decUnitAddSub would be made.                     */
4856
/*                                                                    */
4857
/* The fastpath version lumps units together into 8-digit or 9-digit  */
4858
/* chunks, and also uses a lazy carry strategy to minimise expensive  */
4859
/* 64-bit divisions.  The chunks are then broken apart again into     */
4860
/* units for continuing processing.  Despite this overhead, the       */
4861
/* fastpath can speed up some 16-digit operations by 10x (and much    */
4862
/* more for higher-precision calculations).                           */
4863
/*                                                                    */
4864
/* A buffer always has to be used for the accumulator; in the         */
4865
/* fastpath, buffers are also always needed for the chunked copies of */
4866
/* of the operand coefficients.                                       */
4867
/* Static buffers are larger than needed just for multiply, to allow  */
4868
/* for calls from other operations (notably exp).                     */
4869
/* ------------------------------------------------------------------ */
4870
#define FASTMUL (DECUSE64 && DECDPUN<5)
4871
static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs,
4872
                                 const decNumber *rhs, decContext *set,
4873
0
                                 uInt *status) {
4874
0
  Int    accunits;                 /* Units of accumulator in use  */
4875
0
  Int    exponent;                 /* work  */
4876
0
  Int    residue=0;                /* rounding residue  */
4877
0
  uByte  bits;                     /* result sign  */
4878
0
  Unit  *acc;                      /* -> accumulator Unit array  */
4879
0
  Int    needbytes;                /* size calculator  */
4880
0
  void  *allocacc=nullptr;            /* -> allocated accumulator, iff allocated  */
4881
0
  Unit  accbuff[SD2U(DECBUFFER*4+1)]; /* buffer (+1 for DECBUFFER==0,  */
4882
                                   /* *4 for calls from other operations)  */
4883
0
  const Unit *mer, *mermsup;       /* work  */
4884
0
  Int   madlength;                 /* Units in multiplicand  */
4885
0
  Int   shift;                     /* Units to shift multiplicand by  */
4886
4887
0
  #if FASTMUL
4888
    /* if DECDPUN is 1 or 3 work in base 10**9, otherwise  */
4889
    /* (DECDPUN is 2 or 4) then work in base 10**8  */
4890
0
    #if DECDPUN & 1                /* odd  */
4891
0
      #define FASTBASE 1000000000  /* base  */
4892
0
      #define FASTDIGS          9  /* digits in base  */
4893
0
      #define FASTLAZY         18  /* carry resolution point [1->18]  */
4894
    #else
4895
      #define FASTBASE  100000000
4896
      #define FASTDIGS          8
4897
      #define FASTLAZY       1844  /* carry resolution point [1->1844]  */
4898
    #endif
4899
    /* three buffers are used, two for chunked copies of the operands  */
4900
    /* (base 10**8 or base 10**9) and one base 2**64 accumulator with  */
4901
    /* lazy carry evaluation  */
4902
0
    uInt   zlhibuff[(DECBUFFER*2+1)/8+1]; /* buffer (+1 for DECBUFFER==0)  */
4903
0
    uInt  *zlhi=zlhibuff;                 /* -> lhs array  */
4904
0
    uInt  *alloclhi=nullptr;                 /* -> allocated buffer, iff allocated  */
4905
0
    uInt   zrhibuff[(DECBUFFER*2+1)/8+1]; /* buffer (+1 for DECBUFFER==0)  */
4906
0
    uInt  *zrhi=zrhibuff;                 /* -> rhs array  */
4907
0
    uInt  *allocrhi=nullptr;                 /* -> allocated buffer, iff allocated  */
4908
0
    uLong  zaccbuff[(DECBUFFER*2+1)/4+2]; /* buffer (+1 for DECBUFFER==0)  */
4909
    /* [allocacc is shared for both paths, as only one will run]  */
4910
0
    uLong *zacc=zaccbuff;          /* -> accumulator array for exact result  */
4911
0
    #if DECDPUN==1
4912
0
    Int    zoff;                   /* accumulator offset  */
4913
0
    #endif
4914
0
    uInt  *lip, *rip;              /* item pointers  */
4915
0
    uInt  *lmsi, *rmsi;            /* most significant items  */
4916
0
    Int    ilhs, irhs, iacc;       /* item counts in the arrays  */
4917
0
    Int    lazy;                   /* lazy carry counter  */
4918
0
    uLong  lcarry;                 /* uLong carry  */
4919
0
    uInt   carry;                  /* carry (NB not uLong)  */
4920
0
    Int    count;                  /* work  */
4921
0
    const  Unit *cup;              /* ..  */
4922
0
    Unit  *up;                     /* ..  */
4923
0
    uLong *lp;                     /* ..  */
4924
0
    Int    p;                      /* ..  */
4925
0
  #endif
4926
4927
  #if DECSUBSET
4928
    decNumber *alloclhs=nullptr;      /* -> allocated buffer, iff allocated  */
4929
    decNumber *allocrhs=nullptr;      /* -> allocated buffer, iff allocated  */
4930
  #endif
4931
4932
  #if DECCHECK
4933
  if (decCheckOperands(res, lhs, rhs, set)) return res;
4934
  #endif
4935
4936
  /* precalculate result sign  */
4937
0
  bits = static_cast<uByte>((lhs->bits ^ rhs->bits) & DECNEG);
4938
4939
  /* handle infinities and NaNs  */
4940
0
  if (SPECIALARGS) {               /* a special bit set  */
4941
0
    if (SPECIALARGS & (DECSNAN | DECNAN)) { /* one or two NaNs  */
4942
0
      decNaNs(res, lhs, rhs, set, status);
4943
0
      return res;}
4944
    /* one or two infinities; Infinity * 0 is invalid  */
4945
0
    if (((lhs->bits & DECINF)==0 && ISZERO(lhs))
4946
0
      ||((rhs->bits & DECINF)==0 && ISZERO(rhs))) {
4947
0
      *status|=DEC_Invalid_operation;
4948
0
      return res;}
4949
0
    uprv_decNumberZero(res);
4950
0
    res->bits=bits|DECINF;         /* infinity  */
4951
0
    return res;}
4952
4953
  /* For best speed, as in DMSRCN [the original Rexx numerics  */
4954
  /* module], use the shorter number as the multiplier (rhs) and  */
4955
  /* the longer as the multiplicand (lhs) to minimise the number of  */
4956
  /* adds (partial products)  */
4957
0
  if (lhs->digits<rhs->digits) {   /* swap...  */
4958
0
    const decNumber *hold=lhs;
4959
0
    lhs=rhs;
4960
0
    rhs=hold;
4961
0
    }
4962
4963
0
  do {                             /* protect allocated storage  */
4964
    #if DECSUBSET
4965
    if (!set->extended) {
4966
      /* reduce operands and set lostDigits status, as needed  */
4967
      if (lhs->digits>set->digits) {
4968
        alloclhs=decRoundOperand(lhs, set, status);
4969
        if (alloclhs==nullptr) break;
4970
        lhs=alloclhs;
4971
        }
4972
      if (rhs->digits>set->digits) {
4973
        allocrhs=decRoundOperand(rhs, set, status);
4974
        if (allocrhs==nullptr) break;
4975
        rhs=allocrhs;
4976
        }
4977
      }
4978
    #endif
4979
    /* [following code does not require input rounding]  */
4980
4981
    #if FASTMUL                    /* fastpath can be used  */
4982
    /* use the fast path if there are enough digits in the shorter  */
4983
    /* operand to make the setup and takedown worthwhile  */
4984
0
    #define NEEDTWO (DECDPUN*2)    /* within two decUnitAddSub calls  */
4985
0
    if (rhs->digits>NEEDTWO) {     /* use fastpath...  */
4986
      /* calculate the number of elements in each array  */
4987
0
      ilhs=(lhs->digits+FASTDIGS-1)/FASTDIGS; /* [ceiling]  */
4988
0
      irhs=(rhs->digits+FASTDIGS-1)/FASTDIGS; /* ..  */
4989
0
      iacc=ilhs+irhs;
4990
4991
      /* allocate buffers if required, as usual  */
4992
0
      needbytes=ilhs*sizeof(uInt);
4993
0
      if (needbytes > static_cast<Int>(sizeof(zlhibuff))) {
4994
0
        alloclhi = static_cast<uInt*>(malloc(needbytes));
4995
0
        zlhi=alloclhi;}
4996
0
      needbytes=irhs*sizeof(uInt);
4997
0
      if (needbytes > static_cast<Int>(sizeof(zrhibuff))) {
4998
0
        allocrhi = static_cast<uInt*>(malloc(needbytes));
4999
0
        zrhi=allocrhi;}
5000
5001
      /* Allocating the accumulator space needs a special case when  */
5002
      /* DECDPUN=1 because when converting the accumulator to Units  */
5003
      /* after the multiplication each 8-byte item becomes 9 1-byte  */
5004
      /* units.  Therefore iacc extra bytes are needed at the front  */
5005
      /* (rounded up to a multiple of 8 bytes), and the uLong  */
5006
      /* accumulator starts offset the appropriate number of units  */
5007
      /* to the right to avoid overwrite during the unchunking.  */
5008
5009
      /* Make sure no signed int overflow below. This is always true */
5010
      /* if the given numbers have less digits than DEC_MAX_DIGITS. */
5011
0
      U_ASSERT((uint32_t)iacc <= INT32_MAX/sizeof(uLong));
5012
0
      needbytes=iacc*sizeof(uLong);
5013
0
      #if DECDPUN==1
5014
0
      zoff=(iacc+7)/8;        /* items to offset by  */
5015
0
      needbytes+=zoff*8;
5016
0
      #endif
5017
0
      if (needbytes > static_cast<Int>(sizeof(zaccbuff))) {
5018
0
        allocacc = static_cast<uLong*>(malloc(needbytes));
5019
0
        zacc = static_cast<uLong*>(allocacc);}
5020
0
      if (zlhi==nullptr||zrhi==nullptr||zacc==nullptr) {
5021
0
        *status|=DEC_Insufficient_storage;
5022
0
        break;}
5023
5024
0
      acc = reinterpret_cast<Unit*>(zacc); /* -> target Unit array  */
5025
0
      #if DECDPUN==1
5026
0
      zacc+=zoff;             /* start uLong accumulator to right  */
5027
0
      #endif
5028
5029
      /* assemble the chunked copies of the left and right sides  */
5030
0
      for (count=lhs->digits, cup=lhs->lsu, lip=zlhi; count>0; lip++)
5031
0
        for (p=0, *lip=0; p<FASTDIGS && count>0;
5032
0
             p+=DECDPUN, cup++, count-=DECDPUN)
5033
0
          *lip+=*cup*powers[p];
5034
0
      lmsi=lip-1;     /* save -> msi  */
5035
0
      for (count=rhs->digits, cup=rhs->lsu, rip=zrhi; count>0; rip++)
5036
0
        for (p=0, *rip=0; p<FASTDIGS && count>0;
5037
0
             p+=DECDPUN, cup++, count-=DECDPUN)
5038
0
          *rip+=*cup*powers[p];
5039
0
      rmsi=rip-1;     /* save -> msi  */
5040
5041
      /* zero the accumulator  */
5042
0
      for (lp=zacc; lp<zacc+iacc; lp++) *lp=0;
5043
5044
      /* Start the multiplication */
5045
      /* Resolving carries can dominate the cost of accumulating the  */
5046
      /* partial products, so this is only done when necessary.  */
5047
      /* Each uLong item in the accumulator can hold values up to  */
5048
      /* 2**64-1, and each partial product can be as large as  */
5049
      /* (10**FASTDIGS-1)**2.  When FASTDIGS=9, this can be added to  */
5050
      /* itself 18.4 times in a uLong without overflowing, so during  */
5051
      /* the main calculation resolution is carried out every 18th  */
5052
      /* add -- every 162 digits.  Similarly, when FASTDIGS=8, the  */
5053
      /* partial products can be added to themselves 1844.6 times in  */
5054
      /* a uLong without overflowing, so intermediate carry  */
5055
      /* resolution occurs only every 14752 digits.  Hence for common  */
5056
      /* short numbers usually only the one final carry resolution  */
5057
      /* occurs.  */
5058
      /* (The count is set via FASTLAZY to simplify experiments to  */
5059
      /* measure the value of this approach: a 35% improvement on a  */
5060
      /* [34x34] multiply.)  */
5061
0
      lazy=FASTLAZY;                         /* carry delay count  */
5062
0
      for (rip=zrhi; rip<=rmsi; rip++) {     /* over each item in rhs  */
5063
0
        lp=zacc+(rip-zrhi);                  /* where to add the lhs  */
5064
0
        for (lip=zlhi; lip<=lmsi; lip++, lp++) { /* over each item in lhs  */
5065
0
          *lp += static_cast<uLong>(*lip) * (*rip); /* [this should in-line]  */
5066
0
          } /* lip loop  */
5067
0
        lazy--;
5068
0
        if (lazy>0 && rip!=rmsi) continue;
5069
0
        lazy=FASTLAZY;                       /* reset delay count  */
5070
        /* spin up the accumulator resolving overflows  */
5071
0
        for (lp=zacc; lp<zacc+iacc; lp++) {
5072
0
          if (*lp<FASTBASE) continue;        /* it fits  */
5073
0
          lcarry=*lp/FASTBASE;               /* top part [slow divide]  */
5074
          /* lcarry can exceed 2**32-1, so check again; this check  */
5075
          /* and occasional extra divide (slow) is well worth it, as  */
5076
          /* it allows FASTLAZY to be increased to 18 rather than 4  */
5077
          /* in the FASTDIGS=9 case  */
5078
0
          if (lcarry<FASTBASE) carry = static_cast<uInt>(lcarry); /* [usual]  */
5079
0
           else { /* two-place carry [fairly rare]  */
5080
0
            uInt carry2 = static_cast<uInt>(lcarry / FASTBASE);        /* top top part  */
5081
0
            *(lp+2)+=carry2;                        /* add to item+2  */
5082
0
            *lp -= (static_cast<uLong>(FASTBASE) * FASTBASE * carry2); /* [slow]  */
5083
0
            carry = static_cast<uInt>(lcarry - (static_cast<uLong>(FASTBASE) * carry2)); /* [inline]  */
5084
0
            }
5085
0
          *(lp+1)+=carry;                    /* add to item above [inline]  */
5086
0
          *lp -= (static_cast<uLong>(FASTBASE) * carry); /* [inline]  */
5087
0
          } /* carry resolution  */
5088
0
        } /* rip loop  */
5089
5090
      /* The multiplication is complete; time to convert back into  */
5091
      /* units.  This can be done in-place in the accumulator and in  */
5092
      /* 32-bit operations, because carries were resolved after the  */
5093
      /* final add.  This needs N-1 divides and multiplies for  */
5094
      /* each item in the accumulator (which will become up to N  */
5095
      /* units, where 2<=N<=9).  */
5096
0
      for (lp=zacc, up=acc; lp<zacc+iacc; lp++) {
5097
0
        uInt item = static_cast<uInt>(*lp); /* decapitate to uInt  */
5098
0
        for (p=0; p<FASTDIGS-DECDPUN; p+=DECDPUN, up++) {
5099
0
          uInt part=item/(DECDPUNMAX+1);
5100
0
          *up = static_cast<Unit>(item - (part * (DECDPUNMAX + 1)));
5101
0
          item=part;
5102
0
          } /* p  */
5103
0
        *up = static_cast<Unit>(item); up++; /* [final needs no division]  */
5104
0
        } /* lp  */
5105
0
      accunits = static_cast<int32_t>(up-acc);                       /* count of units  */
5106
0
      }
5107
0
     else { /* here to use units directly, without chunking ['old code']  */
5108
0
    #endif
5109
5110
      /* if accumulator will be too long for local storage, then allocate  */
5111
0
      acc=accbuff;                 /* -> assume buffer for accumulator  */
5112
0
      needbytes=(D2U(lhs->digits)+D2U(rhs->digits))*sizeof(Unit);
5113
0
      if (needbytes > static_cast<Int>(sizeof(accbuff))) {
5114
0
        allocacc = static_cast<Unit*>(malloc(needbytes));
5115
0
        if (allocacc==nullptr) {*status|=DEC_Insufficient_storage; break;}
5116
0
        acc = static_cast<Unit*>(allocacc); /* use the allocated space  */
5117
0
        }
5118
5119
      /* Now the main long multiplication loop */
5120
      /* Unlike the equivalent in the IBM Java implementation, there  */
5121
      /* is no advantage in calculating from msu to lsu.  So, do it  */
5122
      /* by the book, as it were.  */
5123
      /* Each iteration calculates ACC=ACC+MULTAND*MULT  */
5124
0
      accunits=1;                  /* accumulator starts at '0'  */
5125
0
      *acc=0;                      /* .. (lsu=0)  */
5126
0
      shift=0;                     /* no multiplicand shift at first  */
5127
0
      madlength=D2U(lhs->digits);  /* this won't change  */
5128
0
      mermsup=rhs->lsu+D2U(rhs->digits); /* -> msu+1 of multiplier  */
5129
5130
0
      for (mer=rhs->lsu; mer<mermsup; mer++) {
5131
        /* Here, *mer is the next Unit in the multiplier to use  */
5132
        /* If non-zero [optimization] add it...  */
5133
0
        if (*mer!=0) accunits=decUnitAddSub(&acc[shift], accunits-shift,
5134
0
                                            lhs->lsu, madlength, 0,
5135
0
                                            &acc[shift], *mer)
5136
0
                                            + shift;
5137
0
         else { /* extend acc with a 0; it will be used shortly  */
5138
0
          *(acc+accunits)=0;       /* [this avoids length of <=0 later]  */
5139
0
          accunits++;
5140
0
          }
5141
        /* multiply multiplicand by 10**DECDPUN for next Unit to left  */
5142
0
        shift++;                   /* add this for 'logical length'  */
5143
0
        } /* n  */
5144
0
    #if FASTMUL
5145
0
      } /* unchunked units  */
5146
0
    #endif
5147
    /* common end-path  */
5148
    #if DECTRACE
5149
      decDumpAr('*', acc, accunits);         /* Show exact result  */
5150
    #endif
5151
5152
    /* acc now contains the exact result of the multiplication,  */
5153
    /* possibly with a leading zero unit; build the decNumber from  */
5154
    /* it, noting if any residue  */
5155
0
    res->bits=bits;                          /* set sign  */
5156
0
    res->digits=decGetDigits(acc, accunits); /* count digits exactly  */
5157
5158
    /* There can be a 31-bit wrap in calculating the exponent.  */
5159
    /* This can only happen if both input exponents are negative and  */
5160
    /* both their magnitudes are large.  If there was a wrap, set a  */
5161
    /* safe very negative exponent, from which decFinalize() will  */
5162
    /* raise a hard underflow shortly.  */
5163
0
    exponent=lhs->exponent+rhs->exponent;    /* calculate exponent  */
5164
0
    if (lhs->exponent<0 && rhs->exponent<0 && exponent>0)
5165
0
      exponent=-2*DECNUMMAXE;                /* force underflow  */
5166
0
    res->exponent=exponent;                  /* OK to overwrite now  */
5167
5168
5169
    /* Set the coefficient.  If any rounding, residue records  */
5170
0
    decSetCoeff(res, set, acc, res->digits, &residue, status);
5171
0
    decFinish(res, set, &residue, status);   /* final cleanup  */
5172
0
    } while(0);                         /* end protected  */
5173
5174
0
  if (allocacc!=nullptr) free(allocacc);   /* drop any storage used  */
5175
  #if DECSUBSET
5176
  if (allocrhs!=nullptr) free(allocrhs);   /* ..  */
5177
  if (alloclhs!=nullptr) free(alloclhs);   /* ..  */
5178
  #endif
5179
0
  #if FASTMUL
5180
0
  if (allocrhi!=nullptr) free(allocrhi);   /* ..  */
5181
0
  if (alloclhi!=nullptr) free(alloclhi);   /* ..  */
5182
0
  #endif
5183
0
  return res;
5184
0
  } /* decMultiplyOp  */
5185
5186
/* ------------------------------------------------------------------ */
5187
/* decExpOp -- effect exponentiation                                  */
5188
/*                                                                    */
5189
/*   This computes C = exp(A)                                         */
5190
/*                                                                    */
5191
/*   res is C, the result.  C may be A                                */
5192
/*   rhs is A                                                         */
5193
/*   set is the context; note that rounding mode has no effect        */
5194
/*                                                                    */
5195
/* C must have space for set->digits digits. status is updated but    */
5196
/* not set.                                                           */
5197
/*                                                                    */
5198
/* Restrictions:                                                      */
5199
/*                                                                    */
5200
/*   digits, emax, and -emin in the context must be less than         */
5201
/*   2*DEC_MAX_MATH (1999998), and the rhs must be within these       */
5202
/*   bounds or a zero.  This is an internal routine, so these         */
5203
/*   restrictions are contractual and not enforced.                   */
5204
/*                                                                    */
5205
/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will      */
5206
/* almost always be correctly rounded, but may be up to 1 ulp in      */
5207
/* error in rare cases.                                               */
5208
/*                                                                    */
5209
/* Finite results will always be full precision and Inexact, except   */
5210
/* when A is a zero or -Infinity (giving 1 or 0 respectively).        */
5211
/* ------------------------------------------------------------------ */
5212
/* This approach used here is similar to the algorithm described in   */
5213
/*                                                                    */
5214
/*   Variable Precision Exponential Function, T. E. Hull and          */
5215
/*   A. Abrham, ACM Transactions on Mathematical Software, Vol 12 #2, */
5216
/*   pp79-91, ACM, June 1986.                                         */
5217
/*                                                                    */
5218
/* with the main difference being that the iterations in the series   */
5219
/* evaluation are terminated dynamically (which does not require the  */
5220
/* extra variable-precision variables which are expensive in this     */
5221
/* context).                                                          */
5222
/*                                                                    */
5223
/* The error analysis in Hull & Abrham's paper applies except for the */
5224
/* round-off error accumulation during the series evaluation.  This   */
5225
/* code does not precalculate the number of iterations and so cannot  */
5226
/* use Horner's scheme.  Instead, the accumulation is done at double- */
5227
/* precision, which ensures that the additions of the terms are exact */
5228
/* and do not accumulate round-off (and any round-off errors in the   */
5229
/* terms themselves move 'to the right' faster than they can          */
5230
/* accumulate).  This code also extends the calculation by allowing,  */
5231
/* in the spirit of other decNumber operators, the input to be more   */
5232
/* precise than the result (the precision used is based on the more   */
5233
/* precise of the input or requested result).                         */
5234
/*                                                                    */
5235
/* Implementation notes:                                              */
5236
/*                                                                    */
5237
/* 1. This is separated out as decExpOp so it can be called from      */
5238
/*    other Mathematical functions (notably Ln) with a wider range    */
5239
/*    than normal.  In particular, it can handle the slightly wider   */
5240
/*    (double) range needed by Ln (which has to be able to calculate  */
5241
/*    exp(-x) where x can be the tiniest number (Ntiny).              */
5242
/*                                                                    */
5243
/* 2. Normalizing x to be <=0.1 (instead of <=1) reduces loop         */
5244
/*    iterations by approximately a third with additional (although    */
5245
/*    diminishing) returns as the range is reduced to even smaller    */
5246
/*    fractions.  However, h (the power of 10 used to correct the     */
5247
/*    result at the end, see below) must be kept <=8 as otherwise     */
5248
/*    the final result cannot be computed.  Hence the leverage is a   */
5249
/*    sliding value (8-h), where potentially the range is reduced     */
5250
/*    more for smaller values.                                        */
5251
/*                                                                    */
5252
/*    The leverage that can be applied in this way is severely        */
5253
/*    limited by the cost of the raise-to-the power at the end,       */
5254
/*    which dominates when the number of iterations is small (less    */
5255
/*    than ten) or when rhs is short.  As an example, the adjustment  */
5256
/*    x**10,000,000 needs 31 multiplications, all but one full-width. */
5257
/*                                                                    */
5258
/* 3. The restrictions (especially precision) could be raised with    */
5259
/*    care, but the full decNumber range seems very hard within the   */
5260
/*    32-bit limits.                                                  */
5261
/*                                                                    */
5262
/* 4. The working precisions for the static buffers are twice the     */
5263
/*    obvious size to allow for calls from decNumberPower.            */
5264
/* ------------------------------------------------------------------ */
5265
decNumber * decExpOp(decNumber *res, const decNumber *rhs,
5266
0
                         decContext *set, uInt *status) {
5267
0
  uInt ignore=0;                   /* working status  */
5268
0
  Int h;                           /* adjusted exponent for 0.xxxx  */
5269
0
  Int p;                           /* working precision  */
5270
0
  Int residue;                     /* rounding residue  */
5271
0
  uInt needbytes;                  /* for space calculations  */
5272
0
  const decNumber *x=rhs;          /* (may point to safe copy later)  */
5273
0
  decContext aset, tset, dset;     /* working contexts  */
5274
0
  Int comp;                        /* work  */
5275
5276
  /* the argument is often copied to normalize it, so (unusually) it  */
5277
  /* is treated like other buffers, using DECBUFFER, +1 in case  */
5278
  /* DECBUFFER is 0  */
5279
0
  decNumber bufr[D2N(DECBUFFER*2+1)];
5280
0
  decNumber *allocrhs=nullptr;        /* non-nullptr if rhs buffer allocated  */
5281
5282
  /* the working precision will be no more than set->digits+8+1  */
5283
  /* so for on-stack buffers DECBUFFER+9 is used, +1 in case DECBUFFER  */
5284
  /* is 0 (and twice that for the accumulator)  */
5285
5286
  /* buffer for t, term (working precision plus)  */
5287
0
  decNumber buft[D2N(DECBUFFER*2+9+1)];
5288
0
  decNumber *allocbuft=nullptr;       /* -> allocated buft, iff allocated  */
5289
0
  decNumber *t=buft;               /* term  */
5290
  /* buffer for a, accumulator (working precision * 2), at least 9  */
5291
0
  decNumber bufa[D2N(DECBUFFER*4+18+1)];
5292
0
  decNumber *allocbufa=nullptr;       /* -> allocated bufa, iff allocated  */
5293
0
  decNumber *a=bufa;               /* accumulator  */
5294
  /* decNumber for the divisor term; this needs at most 9 digits  */
5295
  /* and so can be fixed size [16 so can use standard context]  */
5296
0
  decNumber bufd[D2N(16)];
5297
0
  decNumber *d=bufd;               /* divisor  */
5298
0
  decNumber numone;                /* constant 1  */
5299
5300
  #if DECCHECK
5301
  Int iterations=0;                /* for later sanity check  */
5302
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
5303
  #endif
5304
5305
0
  do {                                  /* protect allocated storage  */
5306
0
    if (SPECIALARG) {                   /* handle infinities and NaNs  */
5307
0
      if (decNumberIsInfinite(rhs)) {   /* an infinity  */
5308
0
        if (decNumberIsNegative(rhs))   /* -Infinity -> +0  */
5309
0
          uprv_decNumberZero(res);
5310
0
         else uprv_decNumberCopy(res, rhs);  /* +Infinity -> self  */
5311
0
        }
5312
0
       else decNaNs(res, rhs, nullptr, set, status); /* a NaN  */
5313
0
      break;}
5314
5315
0
    if (ISZERO(rhs)) {                  /* zeros -> exact 1  */
5316
0
      uprv_decNumberZero(res);               /* make clean 1  */
5317
0
      *res->lsu=1;                      /* ..  */
5318
0
      break;}                           /* [no status to set]  */
5319
5320
    /* e**x when 0 < x < 0.66 is < 1+3x/2, hence can fast-path  */
5321
    /* positive and negative tiny cases which will result in inexact  */
5322
    /* 1.  This also allows the later add-accumulate to always be  */
5323
    /* exact (because its length will never be more than twice the  */
5324
    /* working precision).  */
5325
    /* The comparator (tiny) needs just one digit, so use the  */
5326
    /* decNumber d for it (reused as the divisor, etc., below); its  */
5327
    /* exponent is such that if x is positive it will have  */
5328
    /* set->digits-1 zeros between the decimal point and the digit,  */
5329
    /* which is 4, and if x is negative one more zero there as the  */
5330
    /* more precise result will be of the form 0.9999999 rather than  */
5331
    /* 1.0000001.  Hence, tiny will be 0.0000004  if digits=7 and x>0  */
5332
    /* or 0.00000004 if digits=7 and x<0.  If RHS not larger than  */
5333
    /* this then the result will be 1.000000  */
5334
0
    uprv_decNumberZero(d);                   /* clean  */
5335
0
    *d->lsu=4;                          /* set 4 ..  */
5336
0
    d->exponent=-set->digits;           /* * 10**(-d)  */
5337
0
    if (decNumberIsNegative(rhs)) d->exponent--;  /* negative case  */
5338
0
    comp=decCompare(d, rhs, 1);         /* signless compare  */
5339
0
    if (comp==BADINT) {
5340
0
      *status|=DEC_Insufficient_storage;
5341
0
      break;}
5342
0
    if (comp>=0) {                      /* rhs < d  */
5343
0
      Int shift=set->digits-1;
5344
0
      uprv_decNumberZero(res);               /* set 1  */
5345
0
      *res->lsu=1;                      /* ..  */
5346
0
      res->digits=decShiftToMost(res->lsu, 1, shift);
5347
0
      res->exponent=-shift;                  /* make 1.0000...  */
5348
0
      *status|=DEC_Inexact | DEC_Rounded;    /* .. inexactly  */
5349
0
      break;} /* tiny  */
5350
5351
    /* set up the context to be used for calculating a, as this is  */
5352
    /* used on both paths below  */
5353
0
    uprv_decContextDefault(&aset, DEC_INIT_DECIMAL64);
5354
    /* accumulator bounds are as requested (could underflow)  */
5355
0
    aset.emax=set->emax;                /* usual bounds  */
5356
0
    aset.emin=set->emin;                /* ..  */
5357
0
    aset.clamp=0;                       /* and no concrete format  */
5358
5359
    /* calculate the adjusted (Hull & Abrham) exponent (where the  */
5360
    /* decimal point is just to the left of the coefficient msd)  */
5361
0
    h=rhs->exponent+rhs->digits;
5362
    /* if h>8 then 10**h cannot be calculated safely; however, when  */
5363
    /* h=8 then exp(|rhs|) will be at least exp(1E+7) which is at  */
5364
    /* least 6.59E+4342944, so (due to the restriction on Emax/Emin)  */
5365
    /* overflow (or underflow to 0) is guaranteed -- so this case can  */
5366
    /* be handled by simply forcing the appropriate excess  */
5367
0
    if (h>8) {                          /* overflow/underflow  */
5368
      /* set up here so Power call below will over or underflow to  */
5369
      /* zero; set accumulator to either 2 or 0.02  */
5370
      /* [stack buffer for a is always big enough for this]  */
5371
0
      uprv_decNumberZero(a);
5372
0
      *a->lsu=2;                        /* not 1 but < exp(1)  */
5373
0
      if (decNumberIsNegative(rhs)) a->exponent=-2; /* make 0.02  */
5374
0
      h=8;                              /* clamp so 10**h computable  */
5375
0
      p=9;                              /* set a working precision  */
5376
0
      }
5377
0
     else {                             /* h<=8  */
5378
0
      Int maxlever=(rhs->digits>8?1:0);
5379
      /* [could/should increase this for precisions >40 or so, too]  */
5380
5381
      /* if h is 8, cannot normalize to a lower upper limit because  */
5382
      /* the final result will not be computable (see notes above),  */
5383
      /* but leverage can be applied whenever h is less than 8.  */
5384
      /* Apply as much as possible, up to a MAXLEVER digits, which  */
5385
      /* sets the tradeoff against the cost of the later a**(10**h).  */
5386
      /* As h is increased, the working precision below also  */
5387
      /* increases to compensate for the "constant digits at the  */
5388
      /* front" effect.  */
5389
0
      Int lever=MINI(8-h, maxlever);    /* leverage attainable  */
5390
0
      Int use=-rhs->digits-lever;       /* exponent to use for RHS  */
5391
0
      h+=lever;                         /* apply leverage selected  */
5392
0
      if (h<0) {                        /* clamp  */
5393
0
        use+=h;                         /* [may end up subnormal]  */
5394
0
        h=0;
5395
0
        }
5396
      /* Take a copy of RHS if it needs normalization (true whenever x>=1)  */
5397
0
      if (rhs->exponent!=use) {
5398
0
        decNumber *newrhs=bufr;         /* assume will fit on stack  */
5399
0
        needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
5400
0
        if (needbytes>sizeof(bufr)) {   /* need malloc space  */
5401
0
          allocrhs = static_cast<decNumber*>(malloc(needbytes));
5402
0
          if (allocrhs==nullptr) {         /* hopeless -- abandon  */
5403
0
            *status|=DEC_Insufficient_storage;
5404
0
            break;}
5405
0
          newrhs=allocrhs;              /* use the allocated space  */
5406
0
          }
5407
0
        uprv_decNumberCopy(newrhs, rhs);     /* copy to safe space  */
5408
0
        newrhs->exponent=use;           /* normalize; now <1  */
5409
0
        x=newrhs;                       /* ready for use  */
5410
        /* decNumberShow(x);  */
5411
0
        }
5412
5413
      /* Now use the usual power series to evaluate exp(x).  The  */
5414
      /* series starts as 1 + x + x^2/2 ... so prime ready for the  */
5415
      /* third term by setting the term variable t=x, the accumulator  */
5416
      /* a=1, and the divisor d=2.  */
5417
5418
      /* First determine the working precision.  From Hull & Abrham  */
5419
      /* this is set->digits+h+2.  However, if x is 'over-precise' we  */
5420
      /* need to allow for all its digits to potentially participate  */
5421
      /* (consider an x where all the excess digits are 9s) so in  */
5422
      /* this case use x->digits+h+2  */
5423
0
      p=MAXI(x->digits, set->digits)+h+2;    /* [h<=8]  */
5424
5425
      /* a and t are variable precision, and depend on p, so space  */
5426
      /* must be allocated for them if necessary  */
5427
5428
      /* the accumulator needs to be able to hold 2p digits so that  */
5429
      /* the additions on the second and subsequent iterations are  */
5430
      /* sufficiently exact.  */
5431
0
      needbytes=sizeof(decNumber)+(D2U(p*2)-1)*sizeof(Unit);
5432
0
      if (needbytes>sizeof(bufa)) {     /* need malloc space  */
5433
0
        allocbufa = static_cast<decNumber*>(malloc(needbytes));
5434
0
        if (allocbufa==nullptr) {          /* hopeless -- abandon  */
5435
0
          *status|=DEC_Insufficient_storage;
5436
0
          break;}
5437
0
        a=allocbufa;                    /* use the allocated space  */
5438
0
        }
5439
      /* the term needs to be able to hold p digits (which is  */
5440
      /* guaranteed to be larger than x->digits, so the initial copy  */
5441
      /* is safe); it may also be used for the raise-to-power  */
5442
      /* calculation below, which needs an extra two digits  */
5443
0
      needbytes=sizeof(decNumber)+(D2U(p+2)-1)*sizeof(Unit);
5444
0
      if (needbytes>sizeof(buft)) {     /* need malloc space  */
5445
0
        allocbuft = static_cast<decNumber*>(malloc(needbytes));
5446
0
        if (allocbuft==nullptr) {          /* hopeless -- abandon  */
5447
0
          *status|=DEC_Insufficient_storage;
5448
0
          break;}
5449
0
        t=allocbuft;                    /* use the allocated space  */
5450
0
        }
5451
5452
0
      uprv_decNumberCopy(t, x);              /* term=x  */
5453
0
      uprv_decNumberZero(a); *a->lsu=1;      /* accumulator=1  */
5454
0
      uprv_decNumberZero(d); *d->lsu=2;      /* divisor=2  */
5455
0
      uprv_decNumberZero(&numone); *numone.lsu=1; /* constant 1 for increment  */
5456
5457
      /* set up the contexts for calculating a, t, and d  */
5458
0
      uprv_decContextDefault(&tset, DEC_INIT_DECIMAL64);
5459
0
      dset=tset;
5460
      /* accumulator bounds are set above, set precision now  */
5461
0
      aset.digits=p*2;                  /* double  */
5462
      /* term bounds avoid any underflow or overflow  */
5463
0
      tset.digits=p;
5464
0
      tset.emin=DEC_MIN_EMIN;           /* [emax is plenty]  */
5465
      /* [dset.digits=16, etc., are sufficient]  */
5466
5467
      /* finally ready to roll  */
5468
0
      for (;;) {
5469
        #if DECCHECK
5470
        iterations++;
5471
        #endif
5472
        /* only the status from the accumulation is interesting  */
5473
        /* [but it should remain unchanged after first add]  */
5474
0
        decAddOp(a, a, t, &aset, 0, status);           /* a=a+t  */
5475
0
        decMultiplyOp(t, t, x, &tset, &ignore);        /* t=t*x  */
5476
0
        decDivideOp(t, t, d, &tset, DIVIDE, &ignore);  /* t=t/d  */
5477
        /* the iteration ends when the term cannot affect the result,  */
5478
        /* if rounded to p digits, which is when its value is smaller  */
5479
        /* than the accumulator by p+1 digits.  There must also be  */
5480
        /* full precision in a.  */
5481
0
        if (((a->digits+a->exponent)>=(t->digits+t->exponent+p+1))
5482
0
            && (a->digits>=p)) break;
5483
0
        decAddOp(d, d, &numone, &dset, 0, &ignore);    /* d=d+1  */
5484
0
        } /* iterate  */
5485
5486
      #if DECCHECK
5487
      /* just a sanity check; comment out test to show always  */
5488
      if (iterations>p+3)
5489
        printf("Exp iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
5490
               (LI)iterations, (LI)*status, (LI)p, (LI)x->digits);
5491
      #endif
5492
0
      } /* h<=8  */
5493
5494
    /* apply postconditioning: a=a**(10**h) -- this is calculated  */
5495
    /* at a slightly higher precision than Hull & Abrham suggest  */
5496
0
    if (h>0) {
5497
0
      Int seenbit=0;               /* set once a 1-bit is seen  */
5498
0
      Int i;                       /* counter  */
5499
0
      Int n=powers[h];             /* always positive  */
5500
0
      aset.digits=p+2;             /* sufficient precision  */
5501
      /* avoid the overhead and many extra digits of decNumberPower  */
5502
      /* as all that is needed is the short 'multipliers' loop; here  */
5503
      /* accumulate the answer into t  */
5504
0
      uprv_decNumberZero(t); *t->lsu=1; /* acc=1  */
5505
0
      for (i=1;;i++){              /* for each bit [top bit ignored]  */
5506
        /* abandon if have had overflow or terminal underflow  */
5507
0
        if (*status & (DEC_Overflow|DEC_Underflow)) { /* interesting?  */
5508
0
          if (*status&DEC_Overflow || ISZERO(t)) break;}
5509
0
        n=n<<1;                    /* move next bit to testable position  */
5510
0
        if (n<0) {                 /* top bit is set  */
5511
0
          seenbit=1;               /* OK, have a significant bit  */
5512
0
          decMultiplyOp(t, t, a, &aset, status); /* acc=acc*x  */
5513
0
          }
5514
0
        if (i==31) break;          /* that was the last bit  */
5515
0
        if (!seenbit) continue;    /* no need to square 1  */
5516
0
        decMultiplyOp(t, t, t, &aset, status); /* acc=acc*acc [square]  */
5517
0
        } /*i*/ /* 32 bits  */
5518
      /* decNumberShow(t);  */
5519
0
      a=t;                         /* and carry on using t instead of a  */
5520
0
      }
5521
5522
    /* Copy and round the result to res  */
5523
0
    residue=1;                          /* indicate dirt to right ..  */
5524
0
    if (ISZERO(a)) residue=0;           /* .. unless underflowed to 0  */
5525
0
    aset.digits=set->digits;            /* [use default rounding]  */
5526
0
    decCopyFit(res, a, &aset, &residue, status); /* copy & shorten  */
5527
0
    decFinish(res, set, &residue, status);       /* cleanup/set flags  */
5528
0
    } while(0);                         /* end protected  */
5529
5530
0
  if (allocrhs !=nullptr) free(allocrhs);  /* drop any storage used  */
5531
0
  if (allocbufa!=nullptr) free(allocbufa); /* ..  */
5532
0
  if (allocbuft!=nullptr) free(allocbuft); /* ..  */
5533
  /* [status is handled by caller]  */
5534
0
  return res;
5535
0
  } /* decExpOp  */
5536
5537
/* ------------------------------------------------------------------ */
5538
/* Initial-estimate natural logarithm table                           */
5539
/*                                                                    */
5540
/*   LNnn -- 90-entry 16-bit table for values from .10 through .99.   */
5541
/*           The result is a 4-digit encode of the coefficient (c=the */
5542
/*           top 14 bits encoding 0-9999) and a 2-digit encode of the */
5543
/*           exponent (e=the bottom 2 bits encoding 0-3)              */
5544
/*                                                                    */
5545
/*           The resulting value is given by:                         */
5546
/*                                                                    */
5547
/*             v = -c * 10**(-e-3)                                    */
5548
/*                                                                    */
5549
/*           where e and c are extracted from entry k = LNnn[x-10]    */
5550
/*           where x is truncated (NB) into the range 10 through 99,  */
5551
/*           and then c = k>>2 and e = k&3.                           */
5552
/* ------------------------------------------------------------------ */
5553
static const uShort LNnn[90]={9016,  8652,  8316,  8008,  7724,  7456,  7208,
5554
  6972,  6748,  6540,  6340,  6148,  5968,  5792,  5628,  5464,  5312,
5555
  5164,  5020,  4884,  4748,  4620,  4496,  4376,  4256,  4144,  4032,
5556
 39233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629,
5557
 29777, 28945, 28129, 27329, 26545, 25777, 25021, 24281, 23553, 22837,
5558
 22137, 21445, 20769, 20101, 19445, 18801, 18165, 17541, 16925, 16321,
5559
 15721, 15133, 14553, 13985, 13421, 12865, 12317, 11777, 11241, 10717,
5560
 10197,  9685,  9177,  8677,  8185,  7697,  7213,  6737,  6269,  5801,
5561
  5341,  4889,  4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254,
5562
 10130,  6046, 20055};
5563
5564
/* ------------------------------------------------------------------ */
5565
/* decLnOp -- effect natural logarithm                                */
5566
/*                                                                    */
5567
/*   This computes C = ln(A)                                          */
5568
/*                                                                    */
5569
/*   res is C, the result.  C may be A                                */
5570
/*   rhs is A                                                         */
5571
/*   set is the context; note that rounding mode has no effect        */
5572
/*                                                                    */
5573
/* C must have space for set->digits digits.                          */
5574
/*                                                                    */
5575
/* Notable cases:                                                     */
5576
/*   A<0 -> Invalid                                                   */
5577
/*   A=0 -> -Infinity (Exact)                                         */
5578
/*   A=+Infinity -> +Infinity (Exact)                                 */
5579
/*   A=1 exactly -> 0 (Exact)                                         */
5580
/*                                                                    */
5581
/* Restrictions (as for Exp):                                         */
5582
/*                                                                    */
5583
/*   digits, emax, and -emin in the context must be less than         */
5584
/*   DEC_MAX_MATH+11 (1000010), and the rhs must be within these      */
5585
/*   bounds or a zero.  This is an internal routine, so these         */
5586
/*   restrictions are contractual and not enforced.                   */
5587
/*                                                                    */
5588
/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will      */
5589
/* almost always be correctly rounded, but may be up to 1 ulp in      */
5590
/* error in rare cases.                                               */
5591
/* ------------------------------------------------------------------ */
5592
/* The result is calculated using Newton's method, with each          */
5593
/* iteration calculating a' = a + x * exp(-a) - 1.  See, for example, */
5594
/* Epperson 1989.                                                     */
5595
/*                                                                    */
5596
/* The iteration ends when the adjustment x*exp(-a)-1 is tiny enough. */
5597
/* This has to be calculated at the sum of the precision of x and the */
5598
/* working precision.                                                 */
5599
/*                                                                    */
5600
/* Implementation notes:                                              */
5601
/*                                                                    */
5602
/* 1. This is separated out as decLnOp so it can be called from       */
5603
/*    other Mathematical functions (e.g., Log 10) with a wider range  */
5604
/*    than normal.  In particular, it can handle the slightly wider   */
5605
/*    (+9+2) range needed by a power function.                        */
5606
/*                                                                    */
5607
/* 2. The speed of this function is about 10x slower than exp, as     */
5608
/*    it typically needs 4-6 iterations for short numbers, and the    */
5609
/*    extra precision needed adds a squaring effect, twice.           */
5610
/*                                                                    */
5611
/* 3. Fastpaths are included for ln(10) and ln(2), up to length 40,   */
5612
/*    as these are common requests.  ln(10) is used by log10(x).      */
5613
/*                                                                    */
5614
/* 4. An iteration might be saved by widening the LNnn table, and     */
5615
/*    would certainly save at least one if it were made ten times     */
5616
/*    bigger, too (for truncated fractions 0.100 through 0.999).      */
5617
/*    However, for most practical evaluations, at least four or five  */
5618
/*    iterations will be needed -- so this would only speed up by      */
5619
/*    20-25% and that probably does not justify increasing the table  */
5620
/*    size.                                                           */
5621
/*                                                                    */
5622
/* 5. The static buffers are larger than might be expected to allow   */
5623
/*    for calls from decNumberPower.                                  */
5624
/* ------------------------------------------------------------------ */
5625
#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
5626
#pragma GCC diagnostic push
5627
#pragma GCC diagnostic ignored "-Warray-bounds"
5628
#endif
5629
decNumber * decLnOp(decNumber *res, const decNumber *rhs,
5630
0
                    decContext *set, uInt *status) {
5631
0
  uInt ignore=0;                   /* working status accumulator  */
5632
0
  uInt needbytes;                  /* for space calculations  */
5633
0
  Int residue;                     /* rounding residue  */
5634
0
  Int r;                           /* rhs=f*10**r [see below]  */
5635
0
  Int p;                           /* working precision  */
5636
0
  Int pp;                          /* precision for iteration  */
5637
0
  Int t;                           /* work  */
5638
5639
  /* buffers for a (accumulator, typically precision+2) and b  */
5640
  /* (adjustment calculator, same size)  */
5641
0
  decNumber bufa[D2N(DECBUFFER+12)];
5642
0
  decNumber *allocbufa=nullptr;       /* -> allocated bufa, iff allocated  */
5643
0
  decNumber *a=bufa;               /* accumulator/work  */
5644
0
  decNumber bufb[D2N(DECBUFFER*2+2)];
5645
0
  decNumber *allocbufb=nullptr;       /* -> allocated bufa, iff allocated  */
5646
0
  decNumber *b=bufb;               /* adjustment/work  */
5647
5648
0
  decNumber  numone;               /* constant 1  */
5649
0
  decNumber  cmp;                  /* work  */
5650
0
  decContext aset, bset;           /* working contexts  */
5651
5652
  #if DECCHECK
5653
  Int iterations=0;                /* for later sanity check  */
5654
  if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
5655
  #endif
5656
5657
0
  do {                                  /* protect allocated storage  */
5658
0
    if (SPECIALARG) {                   /* handle infinities and NaNs  */
5659
0
      if (decNumberIsInfinite(rhs)) {   /* an infinity  */
5660
0
        if (decNumberIsNegative(rhs))   /* -Infinity -> error  */
5661
0
          *status|=DEC_Invalid_operation;
5662
0
         else uprv_decNumberCopy(res, rhs);  /* +Infinity -> self  */
5663
0
        }
5664
0
       else decNaNs(res, rhs, nullptr, set, status); /* a NaN  */
5665
0
      break;}
5666
5667
0
    if (ISZERO(rhs)) {                  /* +/- zeros -> -Infinity  */
5668
0
      uprv_decNumberZero(res);               /* make clean  */
5669
0
      res->bits=DECINF|DECNEG;          /* set - infinity  */
5670
0
      break;}                           /* [no status to set]  */
5671
5672
    /* Non-zero negatives are bad...  */
5673
0
    if (decNumberIsNegative(rhs)) {     /* -x -> error  */
5674
0
      *status|=DEC_Invalid_operation;
5675
0
      break;}
5676
5677
    /* Here, rhs is positive, finite, and in range  */
5678
5679
    /* lookaside fastpath code for ln(2) and ln(10) at common lengths  */
5680
0
    if (rhs->exponent==0 && set->digits<=40) {
5681
0
      #if DECDPUN==1
5682
0
      if (rhs->lsu[0]==0 && rhs->lsu[1]==1 && rhs->digits==2) { /* ln(10)  */
5683
      #else
5684
      if (rhs->lsu[0]==10 && rhs->digits==2) {                  /* ln(10)  */
5685
      #endif
5686
0
        aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
5687
0
        #define LN10 "2.302585092994045684017991454684364207601"
5688
0
        uprv_decNumberFromString(res, LN10, &aset);
5689
0
        *status|=(DEC_Inexact | DEC_Rounded); /* is inexact  */
5690
0
        break;}
5691
0
      if (rhs->lsu[0]==2 && rhs->digits==1) { /* ln(2)  */
5692
0
        aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
5693
0
        #define LN2 "0.6931471805599453094172321214581765680755"
5694
0
        uprv_decNumberFromString(res, LN2, &aset);
5695
0
        *status|=(DEC_Inexact | DEC_Rounded);
5696
0
        break;}
5697
0
      } /* integer and short  */
5698
5699
    /* Determine the working precision.  This is normally the  */
5700
    /* requested precision + 2, with a minimum of 9.  However, if  */
5701
    /* the rhs is 'over-precise' then allow for all its digits to  */
5702
    /* potentially participate (consider an rhs where all the excess  */
5703
    /* digits are 9s) so in this case use rhs->digits+2.  */
5704
0
    p=MAXI(rhs->digits, MAXI(set->digits, 7))+2;
5705
5706
    /* Allocate space for the accumulator and the high-precision  */
5707
    /* adjustment calculator, if necessary.  The accumulator must  */
5708
    /* be able to hold p digits, and the adjustment up to  */
5709
    /* rhs->digits+p digits.  They are also made big enough for 16  */
5710
    /* digits so that they can be used for calculating the initial  */
5711
    /* estimate.  */
5712
0
    needbytes=sizeof(decNumber)+(D2U(MAXI(p,16))-1)*sizeof(Unit);
5713
0
    if (needbytes>sizeof(bufa)) {     /* need malloc space  */
5714
0
      allocbufa = static_cast<decNumber*>(malloc(needbytes));
5715
0
      if (allocbufa==nullptr) {          /* hopeless -- abandon  */
5716
0
        *status|=DEC_Insufficient_storage;
5717
0
        break;}
5718
0
      a=allocbufa;                    /* use the allocated space  */
5719
0
      }
5720
0
    pp=p+rhs->digits;
5721
0
    needbytes=sizeof(decNumber)+(D2U(MAXI(pp,16))-1)*sizeof(Unit);
5722
0
    if (needbytes>sizeof(bufb)) {     /* need malloc space  */
5723
0
      allocbufb = static_cast<decNumber*>(malloc(needbytes));
5724
0
      if (allocbufb==nullptr) {          /* hopeless -- abandon  */
5725
0
        *status|=DEC_Insufficient_storage;
5726
0
        break;}
5727
0
      b=allocbufb;                    /* use the allocated space  */
5728
0
      }
5729
5730
    /* Prepare an initial estimate in acc. Calculate this by  */
5731
    /* considering the coefficient of x to be a normalized fraction,  */
5732
    /* f, with the decimal point at far left and multiplied by  */
5733
    /* 10**r.  Then, rhs=f*10**r and 0.1<=f<1, and  */
5734
    /*   ln(x) = ln(f) + ln(10)*r  */
5735
    /* Get the initial estimate for ln(f) from a small lookup  */
5736
    /* table (see above) indexed by the first two digits of f,  */
5737
    /* truncated.  */
5738
5739
0
    uprv_decContextDefault(&aset, DEC_INIT_DECIMAL64); /* 16-digit extended  */
5740
0
    r=rhs->exponent+rhs->digits;        /* 'normalised' exponent  */
5741
0
    uprv_decNumberFromInt32(a, r);           /* a=r  */
5742
0
    uprv_decNumberFromInt32(b, 2302585);     /* b=ln(10) (2.302585)  */
5743
0
    b->exponent=-6;                     /*  ..  */
5744
0
    decMultiplyOp(a, a, b, &aset, &ignore);  /* a=a*b  */
5745
    /* now get top two digits of rhs into b by simple truncate and  */
5746
    /* force to integer  */
5747
0
    residue=0;                          /* (no residue)  */
5748
0
    aset.digits=2; aset.round=DEC_ROUND_DOWN;
5749
0
    decCopyFit(b, rhs, &aset, &residue, &ignore); /* copy & shorten  */
5750
0
    b->exponent=0;                      /* make integer  */
5751
0
    t=decGetInt(b);                     /* [cannot fail]  */
5752
0
    if (t<10) t=X10(t);                 /* adjust single-digit b  */
5753
0
    t=LNnn[t-10];                       /* look up ln(b)  */
5754
0
    uprv_decNumberFromInt32(b, t>>2);        /* b=ln(b) coefficient  */
5755
0
    b->exponent=-(t&3)-3;               /* set exponent  */
5756
0
    b->bits=DECNEG;                     /* ln(0.10)->ln(0.99) always -ve  */
5757
0
    aset.digits=16; aset.round=DEC_ROUND_HALF_EVEN; /* restore  */
5758
0
    decAddOp(a, a, b, &aset, 0, &ignore); /* acc=a+b  */
5759
    /* the initial estimate is now in a, with up to 4 digits correct.  */
5760
    /* When rhs is at or near Nmax the estimate will be low, so we  */
5761
    /* will approach it from below, avoiding overflow when calling exp.  */
5762
5763
0
    uprv_decNumberZero(&numone); *numone.lsu=1;   /* constant 1 for adjustment  */
5764
5765
    /* accumulator bounds are as requested (could underflow, but  */
5766
    /* cannot overflow)  */
5767
0
    aset.emax=set->emax;
5768
0
    aset.emin=set->emin;
5769
0
    aset.clamp=0;                       /* no concrete format  */
5770
    /* set up a context to be used for the multiply and subtract  */
5771
0
    bset=aset;
5772
0
    bset.emax=DEC_MAX_MATH*2;           /* use double bounds for the  */
5773
0
    bset.emin=-DEC_MAX_MATH*2;          /* adjustment calculation  */
5774
                                        /* [see decExpOp call below]  */
5775
    /* for each iteration double the number of digits to calculate,  */
5776
    /* up to a maximum of p  */
5777
0
    pp=9;                               /* initial precision  */
5778
    /* [initially 9 as then the sequence starts 7+2, 16+2, and  */
5779
    /* 34+2, which is ideal for standard-sized numbers]  */
5780
0
    aset.digits=pp;                     /* working context  */
5781
0
    bset.digits=pp+rhs->digits;         /* wider context  */
5782
0
    for (;;) {                          /* iterate  */
5783
      #if DECCHECK
5784
      iterations++;
5785
      if (iterations>24) break;         /* consider 9 * 2**24  */
5786
      #endif
5787
      /* calculate the adjustment (exp(-a)*x-1) into b.  This is a  */
5788
      /* catastrophic subtraction but it really is the difference  */
5789
      /* from 1 that is of interest.  */
5790
      /* Use the internal entry point to Exp as it allows the double  */
5791
      /* range for calculating exp(-a) when a is the tiniest subnormal.  */
5792
0
      a->bits^=DECNEG;                  /* make -a  */
5793
0
      decExpOp(b, a, &bset, &ignore);   /* b=exp(-a)  */
5794
0
      a->bits^=DECNEG;                  /* restore sign of a  */
5795
      /* now multiply by rhs and subtract 1, at the wider precision  */
5796
0
      decMultiplyOp(b, b, rhs, &bset, &ignore);        /* b=b*rhs  */
5797
0
      decAddOp(b, b, &numone, &bset, DECNEG, &ignore); /* b=b-1  */
5798
5799
      /* the iteration ends when the adjustment cannot affect the  */
5800
      /* result by >=0.5 ulp (at the requested digits), which  */
5801
      /* is when its value is smaller than the accumulator by  */
5802
      /* set->digits+1 digits (or it is zero) -- this is a looser  */
5803
      /* requirement than for Exp because all that happens to the  */
5804
      /* accumulator after this is the final rounding (but note that  */
5805
      /* there must also be full precision in a, or a=0).  */
5806
5807
0
      if (decNumberIsZero(b) ||
5808
0
          (a->digits+a->exponent)>=(b->digits+b->exponent+set->digits+1)) {
5809
0
        if (a->digits==p) break;
5810
0
        if (decNumberIsZero(a)) {
5811
0
          decCompareOp(&cmp, rhs, &numone, &aset, COMPARE, &ignore); /* rhs=1 ?  */
5812
0
          if (cmp.lsu[0]==0) a->exponent=0;            /* yes, exact 0  */
5813
0
           else *status|=(DEC_Inexact | DEC_Rounded);  /* no, inexact  */
5814
0
          break;
5815
0
          }
5816
        /* force padding if adjustment has gone to 0 before full length  */
5817
0
        if (decNumberIsZero(b)) b->exponent=a->exponent-p;
5818
0
        }
5819
5820
      /* not done yet ...  */
5821
0
      decAddOp(a, a, b, &aset, 0, &ignore);  /* a=a+b for next estimate  */
5822
0
      if (pp==p) continue;                   /* precision is at maximum  */
5823
      /* lengthen the next calculation  */
5824
0
      pp=pp*2;                               /* double precision  */
5825
0
      if (pp>p) pp=p;                        /* clamp to maximum  */
5826
0
      aset.digits=pp;                        /* working context  */
5827
0
      bset.digits=pp+rhs->digits;            /* wider context  */
5828
0
      } /* Newton's iteration  */
5829
5830
    #if DECCHECK
5831
    /* just a sanity check; remove the test to show always  */
5832
    if (iterations>24)
5833
      printf("Ln iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
5834
            (LI)iterations, (LI)*status, (LI)p, (LI)rhs->digits);
5835
    #endif
5836
5837
    /* Copy and round the result to res  */
5838
0
    residue=1;                          /* indicate dirt to right  */
5839
0
    if (ISZERO(a)) residue=0;           /* .. unless underflowed to 0  */
5840
0
    aset.digits=set->digits;            /* [use default rounding]  */
5841
0
    decCopyFit(res, a, &aset, &residue, status); /* copy & shorten  */
5842
0
    decFinish(res, set, &residue, status);       /* cleanup/set flags  */
5843
0
    } while(0);                         /* end protected  */
5844
5845
0
  if (allocbufa!=nullptr) free(allocbufa); /* drop any storage used  */
5846
0
  if (allocbufb!=nullptr) free(allocbufb); /* ..  */
5847
  /* [status is handled by caller]  */
5848
0
  return res;
5849
0
  } /* decLnOp  */
5850
#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406
5851
#pragma GCC diagnostic pop
5852
#endif
5853
5854
/* ------------------------------------------------------------------ */
5855
/* decQuantizeOp  -- force exponent to requested value                */
5856
/*                                                                    */
5857
/*   This computes C = op(A, B), where op adjusts the coefficient     */
5858
/*   of C (by rounding or shifting) such that the exponent (-scale)   */
5859
/*   of C has the value B or matches the exponent of B.               */
5860
/*   The numerical value of C will equal A, except for the effects of */
5861
/*   any rounding that occurred.                                      */
5862
/*                                                                    */
5863
/*   res is C, the result.  C may be A or B                           */
5864
/*   lhs is A, the number to adjust                                   */
5865
/*   rhs is B, the requested exponent                                 */
5866
/*   set is the context                                               */
5867
/*   quant is 1 for quantize or 0 for rescale                         */
5868
/*   status is the status accumulator (this can be called without     */
5869
/*          risk of control loss)                                     */
5870
/*                                                                    */
5871
/* C must have space for set->digits digits.                          */
5872
/*                                                                    */
5873
/* Unless there is an error or the result is infinite, the exponent   */
5874
/* after the operation is guaranteed to be that requested.            */
5875
/* ------------------------------------------------------------------ */
5876
static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs,
5877
                                 const decNumber *rhs, decContext *set,
5878
0
                                 Flag quant, uInt *status) {
5879
  #if DECSUBSET
5880
  decNumber *alloclhs=nullptr;        /* non-nullptr if rounded lhs allocated  */
5881
  decNumber *allocrhs=nullptr;        /* .., rhs  */
5882
  #endif
5883
0
  const decNumber *inrhs=rhs;      /* save original rhs  */
5884
0
  Int   reqdigits=set->digits;     /* requested DIGITS  */
5885
0
  Int   reqexp;                    /* requested exponent [-scale]  */
5886
0
  Int   residue=0;                 /* rounding residue  */
5887
0
  Int   etiny=set->emin-(reqdigits-1);
5888
5889
  #if DECCHECK
5890
  if (decCheckOperands(res, lhs, rhs, set)) return res;
5891
  #endif
5892
5893
0
  do {                             /* protect allocated storage  */
5894
    #if DECSUBSET
5895
    if (!set->extended) {
5896
      /* reduce operands and set lostDigits status, as needed  */
5897
      if (lhs->digits>reqdigits) {
5898
        alloclhs=decRoundOperand(lhs, set, status);
5899
        if (alloclhs==nullptr) break;
5900
        lhs=alloclhs;
5901
        }
5902
      if (rhs->digits>reqdigits) { /* [this only checks lostDigits]  */
5903
        allocrhs=decRoundOperand(rhs, set, status);
5904
        if (allocrhs==nullptr) break;
5905
        rhs=allocrhs;
5906
        }
5907
      }
5908
    #endif
5909
    /* [following code does not require input rounding]  */
5910
5911
    /* Handle special values  */
5912
0
    if (SPECIALARGS) {
5913
      /* NaNs get usual processing  */
5914
0
      if (SPECIALARGS & (DECSNAN | DECNAN))
5915
0
        decNaNs(res, lhs, rhs, set, status);
5916
      /* one infinity but not both is bad  */
5917
0
      else if ((lhs->bits ^ rhs->bits) & DECINF)
5918
0
        *status|=DEC_Invalid_operation;
5919
      /* both infinity: return lhs  */
5920
0
      else uprv_decNumberCopy(res, lhs);          /* [nop if in place]  */
5921
0
      break;
5922
0
      }
5923
5924
    /* set requested exponent  */
5925
0
    if (quant) reqexp=inrhs->exponent;  /* quantize -- match exponents  */
5926
0
     else {                             /* rescale -- use value of rhs  */
5927
      /* Original rhs must be an integer that fits and is in range,  */
5928
      /* which could be from -1999999997 to +999999999, thanks to  */
5929
      /* subnormals  */
5930
0
      reqexp=decGetInt(inrhs);               /* [cannot fail]  */
5931
0
      }
5932
5933
    #if DECSUBSET
5934
    if (!set->extended) etiny=set->emin;     /* no subnormals  */
5935
    #endif
5936
5937
0
    if (reqexp==BADINT                       /* bad (rescale only) or ..  */
5938
0
     || reqexp==BIGODD || reqexp==BIGEVEN    /* very big (ditto) or ..  */
5939
0
     || (reqexp<etiny)                       /* < lowest  */
5940
0
     || (reqexp>set->emax)) {                /* > emax  */
5941
0
      *status|=DEC_Invalid_operation;
5942
0
      break;}
5943
5944
    /* the RHS has been processed, so it can be overwritten now if necessary  */
5945
0
    if (ISZERO(lhs)) {                       /* zero coefficient unchanged  */
5946
0
      uprv_decNumberCopy(res, lhs);               /* [nop if in place]  */
5947
0
      res->exponent=reqexp;                  /* .. just set exponent  */
5948
      #if DECSUBSET
5949
      if (!set->extended) res->bits=0;       /* subset specification; no -0  */
5950
      #endif
5951
0
      }
5952
0
     else {                                  /* non-zero lhs  */
5953
0
      Int adjust=reqexp-lhs->exponent;       /* digit adjustment needed  */
5954
      /* if adjusted coefficient will definitely not fit, give up now  */
5955
0
      if ((lhs->digits-adjust)>reqdigits) {
5956
0
        *status|=DEC_Invalid_operation;
5957
0
        break;
5958
0
        }
5959
5960
0
      if (adjust>0) {                        /* increasing exponent  */
5961
        /* this will decrease the length of the coefficient by adjust  */
5962
        /* digits, and must round as it does so  */
5963
0
        decContext workset;                  /* work  */
5964
0
        workset=*set;                        /* clone rounding, etc.  */
5965
0
        workset.digits=lhs->digits-adjust;   /* set requested length  */
5966
        /* [note that the latter can be <1, here]  */
5967
0
        decCopyFit(res, lhs, &workset, &residue, status); /* fit to result  */
5968
0
        decApplyRound(res, &workset, residue, status);    /* .. and round  */
5969
0
        residue=0;                                        /* [used]  */
5970
        /* If just rounded a 999s case, exponent will be off by one;  */
5971
        /* adjust back (after checking space), if so.  */
5972
0
        if (res->exponent>reqexp) {
5973
          /* re-check needed, e.g., for quantize(0.9999, 0.001) under  */
5974
          /* set->digits==3  */
5975
0
          if (res->digits==reqdigits) {      /* cannot shift by 1  */
5976
0
            *status&=~(DEC_Inexact | DEC_Rounded); /* [clean these]  */
5977
0
            *status|=DEC_Invalid_operation;
5978
0
            break;
5979
0
            }
5980
0
          res->digits=decShiftToMost(res->lsu, res->digits, 1); /* shift  */
5981
0
          res->exponent--;                   /* (re)adjust the exponent.  */
5982
0
          }
5983
        #if DECSUBSET
5984
        if (ISZERO(res) && !set->extended) res->bits=0; /* subset; no -0  */
5985
        #endif
5986
0
        } /* increase  */
5987
0
       else /* adjust<=0 */ {                /* decreasing or = exponent  */
5988
        /* this will increase the length of the coefficient by -adjust  */
5989
        /* digits, by adding zero or more trailing zeros; this is  */
5990
        /* already checked for fit, above  */
5991
0
        uprv_decNumberCopy(res, lhs);             /* [it will fit]  */
5992
        /* if padding needed (adjust<0), add it now...  */
5993
0
        if (adjust<0) {
5994
0
          res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
5995
0
          res->exponent+=adjust;             /* adjust the exponent  */
5996
0
          }
5997
0
        } /* decrease  */
5998
0
      } /* non-zero  */
5999
6000
    /* Check for overflow [do not use Finalize in this case, as an  */
6001
    /* overflow here is a "don't fit" situation]  */
6002
0
    if (res->exponent>set->emax-res->digits+1) {  /* too big  */
6003
0
      *status|=DEC_Invalid_operation;
6004
0
      break;
6005
0
      }
6006
0
     else {
6007
0
      decFinalize(res, set, &residue, status);    /* set subnormal flags  */
6008
0
      *status&=~DEC_Underflow;          /* suppress Underflow [as per 754]  */
6009
0
      }
6010
0
    } while(0);                         /* end protected  */
6011
6012
  #if DECSUBSET
6013
  if (allocrhs!=nullptr) free(allocrhs);   /* drop any storage used  */
6014
  if (alloclhs!=nullptr) free(alloclhs);   /* ..  */
6015
  #endif
6016
0
  return res;
6017
0
  } /* decQuantizeOp  */
6018
6019
/* ------------------------------------------------------------------ */
6020
/* decCompareOp -- compare, min, or max two Numbers                   */
6021
/*                                                                    */
6022
/*   This computes C = A ? B and carries out one of four operations:  */
6023
/*     COMPARE    -- returns the signum (as a number) giving the      */
6024
/*                   result of a comparison unless one or both        */
6025
/*                   operands is a NaN (in which case a NaN results)  */
6026
/*     COMPSIG    -- as COMPARE except that a quiet NaN raises        */
6027
/*                   Invalid operation.                               */
6028
/*     COMPMAX    -- returns the larger of the operands, using the    */
6029
/*                   754 maxnum operation                             */
6030
/*     COMPMAXMAG -- ditto, comparing absolute values                 */
6031
/*     COMPMIN    -- the 754 minnum operation                         */
6032
/*     COMPMINMAG -- ditto, comparing absolute values                 */
6033
/*     COMTOTAL   -- returns the signum (as a number) giving the      */
6034
/*                   result of a comparison using 754 total ordering  */
6035
/*                                                                    */
6036
/*   res is C, the result.  C may be A and/or B (e.g., X=X?X)         */
6037
/*   lhs is A                                                         */
6038
/*   rhs is B                                                         */
6039
/*   set is the context                                               */
6040
/*   op  is the operation flag                                        */
6041
/*   status is the usual accumulator                                  */
6042
/*                                                                    */
6043
/* C must have space for one digit for COMPARE or set->digits for     */
6044
/* COMPMAX, COMPMIN, COMPMAXMAG, or COMPMINMAG.                       */
6045
/* ------------------------------------------------------------------ */
6046
/* The emphasis here is on speed for common cases, and avoiding       */
6047
/* coefficient comparison if possible.                                */
6048
/* ------------------------------------------------------------------ */
6049
static decNumber * decCompareOp(decNumber *res, const decNumber *lhs,
6050
                         const decNumber *rhs, decContext *set,
6051
0
                         Flag op, uInt *status) {
6052
  #if DECSUBSET
6053
  decNumber *alloclhs=nullptr;        /* non-nullptr if rounded lhs allocated  */
6054
  decNumber *allocrhs=nullptr;        /* .., rhs  */
6055
  #endif
6056
0
  Int   result=0;                  /* default result value  */
6057
0
  uByte merged;                    /* work  */
6058
6059
  #if DECCHECK
6060
  if (decCheckOperands(res, lhs, rhs, set)) return res;
6061
  #endif
6062
6063
0
  do {                             /* protect allocated storage  */
6064
    #if DECSUBSET
6065
    if (!set->extended) {
6066
      /* reduce operands and set lostDigits status, as needed  */
6067
      if (lhs->digits>set->digits) {
6068
        alloclhs=decRoundOperand(lhs, set, status);
6069
        if (alloclhs==nullptr) {result=BADINT; break;}
6070
        lhs=alloclhs;
6071
        }
6072
      if (rhs->digits>set->digits) {
6073
        allocrhs=decRoundOperand(rhs, set, status);
6074
        if (allocrhs==nullptr) {result=BADINT; break;}
6075
        rhs=allocrhs;
6076
        }
6077
      }
6078
    #endif
6079
    /* [following code does not require input rounding]  */
6080
6081
    /* If total ordering then handle differing signs 'up front'  */
6082
0
    if (op==COMPTOTAL) {                /* total ordering  */
6083
0
      if (decNumberIsNegative(lhs) && !decNumberIsNegative(rhs)) {
6084
0
        result=-1;
6085
0
        break;
6086
0
        }
6087
0
      if (!decNumberIsNegative(lhs) && decNumberIsNegative(rhs)) {
6088
0
        result=+1;
6089
0
        break;
6090
0
        }
6091
0
      }
6092
6093
    /* handle NaNs specially; let infinities drop through  */
6094
    /* This assumes sNaN (even just one) leads to NaN.  */
6095
0
    merged=(lhs->bits | rhs->bits) & (DECSNAN | DECNAN);
6096
0
    if (merged) {                       /* a NaN bit set  */
6097
0
      if (op==COMPARE);                 /* result will be NaN  */
6098
0
       else if (op==COMPSIG)            /* treat qNaN as sNaN  */
6099
0
        *status|=DEC_Invalid_operation | DEC_sNaN;
6100
0
       else if (op==COMPTOTAL) {        /* total ordering, always finite  */
6101
        /* signs are known to be the same; compute the ordering here  */
6102
        /* as if the signs are both positive, then invert for negatives  */
6103
0
        if (!decNumberIsNaN(lhs)) result=-1;
6104
0
         else if (!decNumberIsNaN(rhs)) result=+1;
6105
         /* here if both NaNs  */
6106
0
         else if (decNumberIsSNaN(lhs) && decNumberIsQNaN(rhs)) result=-1;
6107
0
         else if (decNumberIsQNaN(lhs) && decNumberIsSNaN(rhs)) result=+1;
6108
0
         else { /* both NaN or both sNaN  */
6109
          /* now it just depends on the payload  */
6110
0
          result=decUnitCompare(lhs->lsu, D2U(lhs->digits),
6111
0
                                rhs->lsu, D2U(rhs->digits), 0);
6112
          /* [Error not possible, as these are 'aligned']  */
6113
0
          } /* both same NaNs  */
6114
0
        if (decNumberIsNegative(lhs)) result=-result;
6115
0
        break;
6116
0
        } /* total order  */
6117
6118
0
       else if (merged & DECSNAN);           /* sNaN -> qNaN  */
6119
0
       else { /* here if MIN or MAX and one or two quiet NaNs  */
6120
        /* min or max -- 754 rules ignore single NaN  */
6121
0
        if (!decNumberIsNaN(lhs) || !decNumberIsNaN(rhs)) {
6122
          /* just one NaN; force choice to be the non-NaN operand  */
6123
0
          op=COMPMAX;
6124
0
          if (lhs->bits & DECNAN) result=-1; /* pick rhs  */
6125
0
                             else result=+1; /* pick lhs  */
6126
0
          break;
6127
0
          }
6128
0
        } /* max or min  */
6129
0
      op=COMPNAN;                            /* use special path  */
6130
0
      decNaNs(res, lhs, rhs, set, status);   /* propagate NaN  */
6131
0
      break;
6132
0
      }
6133
    /* have numbers  */
6134
0
    if (op==COMPMAXMAG || op==COMPMINMAG) result=decCompare(lhs, rhs, 1);
6135
0
     else result=decCompare(lhs, rhs, 0);    /* sign matters  */
6136
0
    } while(0);                              /* end protected  */
6137
6138
0
  if (result==BADINT) *status|=DEC_Insufficient_storage; /* rare  */
6139
0
   else {
6140
0
    if (op==COMPARE || op==COMPSIG ||op==COMPTOTAL) { /* returning signum  */
6141
0
      if (op==COMPTOTAL && result==0) {
6142
        /* operands are numerically equal or same NaN (and same sign,  */
6143
        /* tested first); if identical, leave result 0  */
6144
0
        if (lhs->exponent!=rhs->exponent) {
6145
0
          if (lhs->exponent<rhs->exponent) result=-1;
6146
0
           else result=+1;
6147
0
          if (decNumberIsNegative(lhs)) result=-result;
6148
0
          } /* lexp!=rexp  */
6149
0
        } /* total-order by exponent  */
6150
0
      uprv_decNumberZero(res);               /* [always a valid result]  */
6151
0
      if (result!=0) {                  /* must be -1 or +1  */
6152
0
        *res->lsu=1;
6153
0
        if (result<0) res->bits=DECNEG;
6154
0
        }
6155
0
      }
6156
0
     else if (op==COMPNAN);             /* special, drop through  */
6157
0
     else {                             /* MAX or MIN, non-NaN result  */
6158
0
      Int residue=0;                    /* rounding accumulator  */
6159
      /* choose the operand for the result  */
6160
0
      const decNumber *choice;
6161
0
      if (result==0) { /* operands are numerically equal  */
6162
        /* choose according to sign then exponent (see 754)  */
6163
0
        uByte slhs=(lhs->bits & DECNEG);
6164
0
        uByte srhs=(rhs->bits & DECNEG);
6165
        #if DECSUBSET
6166
        if (!set->extended) {           /* subset: force left-hand  */
6167
          op=COMPMAX;
6168
          result=+1;
6169
          }
6170
        else
6171
        #endif
6172
0
        if (slhs!=srhs) {          /* signs differ  */
6173
0
          if (slhs) result=-1;     /* rhs is max  */
6174
0
               else result=+1;     /* lhs is max  */
6175
0
          }
6176
0
         else if (slhs && srhs) {  /* both negative  */
6177
0
          if (lhs->exponent<rhs->exponent) result=+1;
6178
0
                                      else result=-1;
6179
          /* [if equal, use lhs, technically identical]  */
6180
0
          }
6181
0
         else {                    /* both positive  */
6182
0
          if (lhs->exponent>rhs->exponent) result=+1;
6183
0
                                      else result=-1;
6184
          /* [ditto]  */
6185
0
          }
6186
0
        } /* numerically equal  */
6187
      /* here result will be non-0; reverse if looking for MIN  */
6188
0
      if (op==COMPMIN || op==COMPMINMAG) result=-result;
6189
0
      choice=(result>0 ? lhs : rhs);    /* choose  */
6190
      /* copy chosen to result, rounding if need be  */
6191
0
      decCopyFit(res, choice, set, &residue, status);
6192
0
      decFinish(res, set, &residue, status);
6193
0
      }
6194
0
    }
6195
  #if DECSUBSET
6196
  if (allocrhs!=nullptr) free(allocrhs);   /* free any storage used  */
6197
  if (alloclhs!=nullptr) free(alloclhs);   /* ..  */
6198
  #endif
6199
0
  return res;
6200
0
  } /* decCompareOp  */
6201
6202
/* ------------------------------------------------------------------ */
6203
/* decCompare -- compare two decNumbers by numerical value            */
6204
/*                                                                    */
6205
/*  This routine compares A ? B without altering them.                */
6206
/*                                                                    */
6207
/*  Arg1 is A, a decNumber which is not a NaN                         */
6208
/*  Arg2 is B, a decNumber which is not a NaN                         */
6209
/*  Arg3 is 1 for a sign-independent compare, 0 otherwise             */
6210
/*                                                                    */
6211
/*  returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure   */
6212
/*  (the only possible failure is an allocation error)                */
6213
/* ------------------------------------------------------------------ */
6214
static Int decCompare(const decNumber *lhs, const decNumber *rhs,
6215
0
                      Flag abs_c) {
6216
0
  Int   result;                    /* result value  */
6217
0
  Int   sigr;                      /* rhs signum  */
6218
0
  Int   compare;                   /* work  */
6219
6220
0
  result=1;                                  /* assume signum(lhs)  */
6221
0
  if (ISZERO(lhs)) result=0;
6222
0
  if (abs_c) {
6223
0
    if (ISZERO(rhs)) return result;          /* LHS wins or both 0  */
6224
    /* RHS is non-zero  */
6225
0
    if (result==0) return -1;                /* LHS is 0; RHS wins  */
6226
    /* [here, both non-zero, result=1]  */
6227
0
    }
6228
0
   else {                                    /* signs matter  */
6229
0
    if (result && decNumberIsNegative(lhs)) result=-1;
6230
0
    sigr=1;                                  /* compute signum(rhs)  */
6231
0
    if (ISZERO(rhs)) sigr=0;
6232
0
     else if (decNumberIsNegative(rhs)) sigr=-1;
6233
0
    if (result > sigr) return +1;            /* L > R, return 1  */
6234
0
    if (result < sigr) return -1;            /* L < R, return -1  */
6235
0
    if (result==0) return 0;                   /* both 0  */
6236
0
    }
6237
6238
  /* signums are the same; both are non-zero  */
6239
0
  if ((lhs->bits | rhs->bits) & DECINF) {    /* one or more infinities  */
6240
0
    if (decNumberIsInfinite(rhs)) {
6241
0
      if (decNumberIsInfinite(lhs)) result=0;/* both infinite  */
6242
0
       else result=-result;                  /* only rhs infinite  */
6243
0
      }
6244
0
    return result;
6245
0
    }
6246
  /* must compare the coefficients, allowing for exponents  */
6247
0
  if (lhs->exponent>rhs->exponent) {         /* LHS exponent larger  */
6248
    /* swap sides, and sign  */
6249
0
    const decNumber *temp=lhs;
6250
0
    lhs=rhs;
6251
0
    rhs=temp;
6252
0
    result=-result;
6253
0
    }
6254
0
  compare=decUnitCompare(lhs->lsu, D2U(lhs->digits),
6255
0
                         rhs->lsu, D2U(rhs->digits),
6256
0
                         rhs->exponent-lhs->exponent);
6257
0
  if (compare!=BADINT) compare*=result;      /* comparison succeeded  */
6258
0
  return compare;
6259
0
  } /* decCompare  */
6260
6261
/* ------------------------------------------------------------------ */
6262
/* decUnitCompare -- compare two >=0 integers in Unit arrays          */
6263
/*                                                                    */
6264
/*  This routine compares A ? B*10**E where A and B are unit arrays   */
6265
/*  A is a plain integer                                              */
6266
/*  B has an exponent of E (which must be non-negative)               */
6267
/*                                                                    */
6268
/*  Arg1 is A first Unit (lsu)                                        */
6269
/*  Arg2 is A length in Units                                         */
6270
/*  Arg3 is B first Unit (lsu)                                        */
6271
/*  Arg4 is B length in Units                                         */
6272
/*  Arg5 is E (0 if the units are aligned)                            */
6273
/*                                                                    */
6274
/*  returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure   */
6275
/*  (the only possible failure is an allocation error, which can      */
6276
/*  only occur if E!=0)                                               */
6277
/* ------------------------------------------------------------------ */
6278
static Int decUnitCompare(const Unit *a, Int alength,
6279
0
                          const Unit *b, Int blength, Int exp) {
6280
0
  Unit  *acc;                      /* accumulator for result  */
6281
0
  Unit  accbuff[SD2U(DECBUFFER*2+1)]; /* local buffer  */
6282
0
  Unit  *allocacc=nullptr;            /* -> allocated acc buffer, iff allocated  */
6283
0
  Int   accunits, need;            /* units in use or needed for acc  */
6284
0
  const Unit *l, *r, *u;           /* work  */
6285
0
  Int   expunits, exprem, result;  /* ..  */
6286
6287
0
  if (exp==0) {                    /* aligned; fastpath  */
6288
0
    if (alength>blength) return 1;
6289
0
    if (alength<blength) return -1;
6290
    /* same number of units in both -- need unit-by-unit compare  */
6291
0
    l=a+alength-1;
6292
0
    r=b+alength-1;
6293
0
    for (;l>=a; l--, r--) {
6294
0
      if (*l>*r) return 1;
6295
0
      if (*l<*r) return -1;
6296
0
      }
6297
0
    return 0;                      /* all units match  */
6298
0
    } /* aligned  */
6299
6300
  /* Unaligned.  If one is >1 unit longer than the other, padded  */
6301
  /* approximately, then can return easily  */
6302
0
  if (alength > blength + static_cast<Int>(D2U(exp))) return 1;
6303
0
  if (alength + 1 < blength + static_cast<Int>(D2U(exp))) return -1;
6304
6305
  /* Need to do a real subtract.  For this, a result buffer is needed  */
6306
  /* even though only the sign is of interest.  Its length needs  */
6307
  /* to be the larger of alength and padded blength, +2  */
6308
0
  need=blength+D2U(exp);                /* maximum real length of B  */
6309
0
  if (need<alength) need=alength;
6310
0
  need+=2;
6311
0
  acc=accbuff;                          /* assume use local buffer  */
6312
0
  if (need*sizeof(Unit)>sizeof(accbuff)) {
6313
0
    allocacc = static_cast<Unit*>(malloc(need * sizeof(Unit)));
6314
0
    if (allocacc==nullptr) return BADINT;  /* hopeless -- abandon  */
6315
0
    acc=allocacc;
6316
0
    }
6317
  /* Calculate units and remainder from exponent.  */
6318
0
  expunits=exp/DECDPUN;
6319
0
  exprem=exp%DECDPUN;
6320
  /* subtract [A+B*(-m)]  */
6321
0
  accunits=decUnitAddSub(a, alength, b, blength, expunits, acc,
6322
0
                         -static_cast<Int>(powers[exprem]));
6323
  /* [UnitAddSub result may have leading zeros, even on zero]  */
6324
0
  if (accunits<0) result=-1;            /* negative result  */
6325
0
   else {                               /* non-negative result  */
6326
    /* check units of the result before freeing any storage  */
6327
0
    for (u=acc; u<acc+accunits-1 && *u==0;) u++;
6328
0
    result=(*u==0 ? 0 : +1);
6329
0
    }
6330
  /* clean up and return the result  */
6331
0
  if (allocacc!=nullptr) free(allocacc);   /* drop any storage used  */
6332
0
  return result;
6333
0
  } /* decUnitCompare  */
6334
6335
/* ------------------------------------------------------------------ */
6336
/* decUnitAddSub -- add or subtract two >=0 integers in Unit arrays   */
6337
/*                                                                    */
6338
/*  This routine performs the calculation:                            */
6339
/*                                                                    */
6340
/*  C=A+(B*M)                                                         */
6341
/*                                                                    */
6342
/*  Where M is in the range -DECDPUNMAX through +DECDPUNMAX.          */
6343
/*                                                                    */
6344
/*  A may be shorter or longer than B.                                */
6345
/*                                                                    */
6346
/*  Leading zeros are not removed after a calculation.  The result is */
6347
/*  either the same length as the longer of A and B (adding any       */
6348
/*  shift), or one Unit longer than that (if a Unit carry occurred).  */
6349
/*                                                                    */
6350
/*  A and B content are not altered unless C is also A or B.          */
6351
/*  C may be the same array as A or B, but only if no zero padding is */
6352
/*  requested (that is, C may be B only if bshift==0).                */
6353
/*  C is filled from the lsu; only those units necessary to complete  */
6354
/*  the calculation are referenced.                                   */
6355
/*                                                                    */
6356
/*  Arg1 is A first Unit (lsu)                                        */
6357
/*  Arg2 is A length in Units                                         */
6358
/*  Arg3 is B first Unit (lsu)                                        */
6359
/*  Arg4 is B length in Units                                         */
6360
/*  Arg5 is B shift in Units  (>=0; pads with 0 units if positive)    */
6361
/*  Arg6 is C first Unit (lsu)                                        */
6362
/*  Arg7 is M, the multiplier                                         */
6363
/*                                                                    */
6364
/*  returns the count of Units written to C, which will be non-zero   */
6365
/*  and negated if the result is negative.  That is, the sign of the  */
6366
/*  returned Int is the sign of the result (positive for zero) and    */
6367
/*  the absolute value of the Int is the count of Units.              */
6368
/*                                                                    */
6369
/*  It is the caller's responsibility to make sure that C size is     */
6370
/*  safe, allowing space if necessary for a one-Unit carry.           */
6371
/*                                                                    */
6372
/*  This routine is severely performance-critical; *any* change here  */
6373
/*  must be measured (timed) to assure no performance degradation.    */
6374
/*  In particular, trickery here tends to be counter-productive, as   */
6375
/*  increased complexity of code hurts register optimizations on      */
6376
/*  register-poor architectures.  Avoiding divisions is nearly        */
6377
/*  always a Good Idea, however.                                      */
6378
/*                                                                    */
6379
/* Special thanks to Rick McGuire (IBM Cambridge, MA) and Dave Clark  */
6380
/* (IBM Warwick, UK) for some of the ideas used in this routine.      */
6381
/* ------------------------------------------------------------------ */
6382
static Int decUnitAddSub(const Unit *a, Int alength,
6383
                         const Unit *b, Int blength, Int bshift,
6384
0
                         Unit *c, Int m) {
6385
0
  const Unit *alsu=a;              /* A lsu [need to remember it]  */
6386
0
  Unit *clsu=c;                    /* C ditto  */
6387
0
  Unit *minC;                      /* low water mark for C  */
6388
0
  Unit *maxC;                      /* high water mark for C  */
6389
0
  eInt carry=0;                    /* carry integer (could be Long)  */
6390
0
  Int  add;                        /* work  */
6391
0
  #if DECDPUN<=4                   /* myriadal, millenary, etc.  */
6392
0
  Int  est;                        /* estimated quotient  */
6393
0
  #endif
6394
6395
  #if DECTRACE
6396
  if (alength<1 || blength<1)
6397
    printf("decUnitAddSub: alen blen m %ld %ld [%ld]\n", alength, blength, m);
6398
  #endif
6399
6400
0
  maxC=c+alength;                  /* A is usually the longer  */
6401
0
  minC=c+blength;                  /* .. and B the shorter  */
6402
0
  if (bshift!=0) {                 /* B is shifted; low As copy across  */
6403
0
    minC+=bshift;
6404
    /* if in place [common], skip copy unless there's a gap [rare]  */
6405
0
    if (a==c && bshift<=alength) {
6406
0
      c+=bshift;
6407
0
      a+=bshift;
6408
0
      }
6409
0
     else for (; c<clsu+bshift; a++, c++) {  /* copy needed  */
6410
0
      if (a<alsu+alength) *c=*a;
6411
0
       else *c=0;
6412
0
      }
6413
0
    }
6414
0
  if (minC>maxC) { /* swap  */
6415
0
    Unit *hold=minC;
6416
0
    minC=maxC;
6417
0
    maxC=hold;
6418
0
    }
6419
6420
  /* For speed, do the addition as two loops; the first where both A  */
6421
  /* and B contribute, and the second (if necessary) where only one or  */
6422
  /* other of the numbers contribute.  */
6423
  /* Carry handling is the same (i.e., duplicated) in each case.  */
6424
0
  for (; c<minC; c++) {
6425
0
    carry+=*a;
6426
0
    a++;
6427
0
    carry += (static_cast<eInt>(*b)) * m; /* [special-casing m=1/-1  */
6428
0
    b++;                                /* here is not a win]  */
6429
    /* here carry is new Unit of digits; it could be +ve or -ve  */
6430
0
    if (static_cast<ueInt>(carry) <= DECDPUNMAX) { /* fastpath 0-DECDPUNMAX  */
6431
0
      *c = static_cast<Unit>(carry);
6432
0
      carry=0;
6433
0
      continue;
6434
0
      }
6435
    #if DECDPUN==4                           /* use divide-by-multiply  */
6436
      if (carry>=0) {
6437
        est=(((ueInt)carry>>11)*53687)>>18;
6438
        *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder  */
6439
        carry=est;                           /* likely quotient [89%]  */
6440
        if (*c<DECDPUNMAX+1) continue;       /* estimate was correct  */
6441
        carry++;
6442
        *c-=DECDPUNMAX+1;
6443
        continue;
6444
        }
6445
      /* negative case  */
6446
      carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive  */
6447
      est=(((ueInt)carry>>11)*53687)>>18;
6448
      *c=(Unit)(carry-est*(DECDPUNMAX+1));
6449
      carry=est-(DECDPUNMAX+1);              /* correctly negative  */
6450
      if (*c<DECDPUNMAX+1) continue;         /* was OK  */
6451
      carry++;
6452
      *c-=DECDPUNMAX+1;
6453
    #elif DECDPUN==3
6454
      if (carry>=0) {
6455
        est=(((ueInt)carry>>3)*16777)>>21;
6456
        *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder  */
6457
        carry=est;                           /* likely quotient [99%]  */
6458
        if (*c<DECDPUNMAX+1) continue;       /* estimate was correct  */
6459
        carry++;
6460
        *c-=DECDPUNMAX+1;
6461
        continue;
6462
        }
6463
      /* negative case  */
6464
      carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive  */
6465
      est=(((ueInt)carry>>3)*16777)>>21;
6466
      *c=(Unit)(carry-est*(DECDPUNMAX+1));
6467
      carry=est-(DECDPUNMAX+1);              /* correctly negative  */
6468
      if (*c<DECDPUNMAX+1) continue;         /* was OK  */
6469
      carry++;
6470
      *c-=DECDPUNMAX+1;
6471
    #elif DECDPUN<=2
6472
      /* Can use QUOT10 as carry <= 4 digits  */
6473
0
      if (carry>=0) {
6474
0
        est=QUOT10(carry, DECDPUN);
6475
0
        *c = static_cast<Unit>(carry - est * (DECDPUNMAX + 1)); /* remainder  */
6476
0
        carry=est;                           /* quotient  */
6477
0
        continue;
6478
0
        }
6479
      /* negative case  */
6480
0
      carry = carry + static_cast<eInt>(DECDPUNMAX + 1) * (DECDPUNMAX + 1); /* make positive  */
6481
0
      est=QUOT10(carry, DECDPUN);
6482
0
      *c = static_cast<Unit>(carry - est * (DECDPUNMAX + 1));
6483
0
      carry=est-(DECDPUNMAX+1);              /* correctly negative  */
6484
    #else
6485
      /* remainder operator is undefined if negative, so must test  */
6486
      if ((ueInt)carry<(DECDPUNMAX+1)*2) {   /* fastpath carry +1  */
6487
        *c=(Unit)(carry-(DECDPUNMAX+1));     /* [helps additions]  */
6488
        carry=1;
6489
        continue;
6490
        }
6491
      if (carry>=0) {
6492
        *c=(Unit)(carry%(DECDPUNMAX+1));
6493
        carry=carry/(DECDPUNMAX+1);
6494
        continue;
6495
        }
6496
      /* negative case  */
6497
      carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive  */
6498
      *c=(Unit)(carry%(DECDPUNMAX+1));
6499
      carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);
6500
    #endif
6501
0
    } /* c  */
6502
6503
  /* now may have one or other to complete  */
6504
  /* [pretest to avoid loop setup/shutdown]  */
6505
0
  if (c<maxC) for (; c<maxC; c++) {
6506
0
    if (a<alsu+alength) {               /* still in A  */
6507
0
      carry+=*a;
6508
0
      a++;
6509
0
      }
6510
0
     else {                             /* inside B  */
6511
0
      carry += static_cast<eInt>(*b) * m;
6512
0
      b++;
6513
0
      }
6514
    /* here carry is new Unit of digits; it could be +ve or -ve and  */
6515
    /* magnitude up to DECDPUNMAX squared  */
6516
0
    if (static_cast<ueInt>(carry) <= DECDPUNMAX) { /* fastpath 0-DECDPUNMAX  */
6517
0
      *c = static_cast<Unit>(carry);
6518
0
      carry=0;
6519
0
      continue;
6520
0
      }
6521
    /* result for this unit is negative or >DECDPUNMAX  */
6522
    #if DECDPUN==4                           /* use divide-by-multiply  */
6523
      if (carry>=0) {
6524
        est=(((ueInt)carry>>11)*53687)>>18;
6525
        *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder  */
6526
        carry=est;                           /* likely quotient [79.7%]  */
6527
        if (*c<DECDPUNMAX+1) continue;       /* estimate was correct  */
6528
        carry++;
6529
        *c-=DECDPUNMAX+1;
6530
        continue;
6531
        }
6532
      /* negative case  */
6533
      carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive  */
6534
      est=(((ueInt)carry>>11)*53687)>>18;
6535
      *c=(Unit)(carry-est*(DECDPUNMAX+1));
6536
      carry=est-(DECDPUNMAX+1);              /* correctly negative  */
6537
      if (*c<DECDPUNMAX+1) continue;         /* was OK  */
6538
      carry++;
6539
      *c-=DECDPUNMAX+1;
6540
    #elif DECDPUN==3
6541
      if (carry>=0) {
6542
        est=(((ueInt)carry>>3)*16777)>>21;
6543
        *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder  */
6544
        carry=est;                           /* likely quotient [99%]  */
6545
        if (*c<DECDPUNMAX+1) continue;       /* estimate was correct  */
6546
        carry++;
6547
        *c-=DECDPUNMAX+1;
6548
        continue;
6549
        }
6550
      /* negative case  */
6551
      carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive  */
6552
      est=(((ueInt)carry>>3)*16777)>>21;
6553
      *c=(Unit)(carry-est*(DECDPUNMAX+1));
6554
      carry=est-(DECDPUNMAX+1);              /* correctly negative  */
6555
      if (*c<DECDPUNMAX+1) continue;         /* was OK  */
6556
      carry++;
6557
      *c-=DECDPUNMAX+1;
6558
    #elif DECDPUN<=2
6559
0
      if (carry>=0) {
6560
0
        est=QUOT10(carry, DECDPUN);
6561
0
        *c = static_cast<Unit>(carry - est * (DECDPUNMAX + 1)); /* remainder  */
6562
0
        carry=est;                           /* quotient  */
6563
0
        continue;
6564
0
        }
6565
      /* negative case  */
6566
0
      carry = carry + static_cast<eInt>(DECDPUNMAX + 1) * (DECDPUNMAX + 1); /* make positive  */
6567
0
      est=QUOT10(carry, DECDPUN);
6568
0
      *c = static_cast<Unit>(carry - est * (DECDPUNMAX + 1));
6569
0
      carry=est-(DECDPUNMAX+1);              /* correctly negative  */
6570
    #else
6571
      if ((ueInt)carry<(DECDPUNMAX+1)*2){    /* fastpath carry 1  */
6572
        *c=(Unit)(carry-(DECDPUNMAX+1));
6573
        carry=1;
6574
        continue;
6575
        }
6576
      /* remainder operator is undefined if negative, so must test  */
6577
      if (carry>=0) {
6578
        *c=(Unit)(carry%(DECDPUNMAX+1));
6579
        carry=carry/(DECDPUNMAX+1);
6580
        continue;
6581
        }
6582
      /* negative case  */
6583
      carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive  */
6584
      *c=(Unit)(carry%(DECDPUNMAX+1));
6585
      carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);
6586
    #endif
6587
0
    } /* c  */
6588
6589
  /* OK, all A and B processed; might still have carry or borrow  */
6590
  /* return number of Units in the result, negated if a borrow  */
6591
0
  if (carry==0) return static_cast<int32_t>(c-clsu);     /* no carry, so no more to do  */
6592
0
  if (carry>0) {                   /* positive carry  */
6593
0
    *c = static_cast<Unit>(carry); /* place as new unit  */
6594
0
    c++;                           /* ..  */
6595
0
    return static_cast<int32_t>(c-clsu);
6596
0
    }
6597
  /* -ve carry: it's a borrow; complement needed  */
6598
0
  add=1;                           /* temporary carry...  */
6599
0
  for (c=clsu; c<maxC; c++) {
6600
0
    add=DECDPUNMAX+add-*c;
6601
0
    if (add<=DECDPUNMAX) {
6602
0
      *c = static_cast<Unit>(add);
6603
0
      add=0;
6604
0
      }
6605
0
     else {
6606
0
      *c=0;
6607
0
      add=1;
6608
0
      }
6609
0
    }
6610
  /* add an extra unit iff it would be non-zero  */
6611
  #if DECTRACE
6612
    printf("UAS borrow: add %ld, carry %ld\n", add, carry);
6613
  #endif
6614
0
  if ((add-carry-1)!=0) {
6615
0
    *c = static_cast<Unit>(add - carry - 1);
6616
0
    c++;                      /* interesting, include it  */
6617
0
    }
6618
0
  return static_cast<int32_t>(clsu-c);              /* -ve result indicates borrowed  */
6619
0
  } /* decUnitAddSub  */
6620
6621
/* ------------------------------------------------------------------ */
6622
/* decTrim -- trim trailing zeros or normalize                        */
6623
/*                                                                    */
6624
/*   dn is the number to trim or normalize                            */
6625
/*   set is the context to use to check for clamp                     */
6626
/*   all is 1 to remove all trailing zeros, 0 for just fraction ones  */
6627
/*   noclamp is 1 to unconditional (unclamped) trim                   */
6628
/*   dropped returns the number of discarded trailing zeros           */
6629
/*   returns dn                                                       */
6630
/*                                                                    */
6631
/* If clamp is set in the context then the number of zeros trimmed    */
6632
/* may be limited if the exponent is high.                            */
6633
/* All fields are updated as required.  This is a utility operation,  */
6634
/* so special values are unchanged and no error is possible.          */
6635
/* ------------------------------------------------------------------ */
6636
static decNumber * decTrim(decNumber *dn, decContext *set, Flag all,
6637
0
                           Flag noclamp, Int *dropped) {
6638
0
  Int   d, exp;                    /* work  */
6639
0
  uInt  cut;                       /* ..  */
6640
0
  Unit  *up;                       /* -> current Unit  */
6641
6642
  #if DECCHECK
6643
  if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
6644
  #endif
6645
6646
0
  *dropped=0;                           /* assume no zeros dropped  */
6647
0
  if ((dn->bits & DECSPECIAL)           /* fast exit if special ..  */
6648
0
    || (*dn->lsu & 0x01)) return dn;    /* .. or odd  */
6649
0
  if (ISZERO(dn)) {                     /* .. or 0  */
6650
0
    dn->exponent=0;                     /* (sign is preserved)  */
6651
0
    return dn;
6652
0
    }
6653
6654
  /* have a finite number which is even  */
6655
0
  exp=dn->exponent;
6656
0
  cut=1;                           /* digit (1-DECDPUN) in Unit  */
6657
0
  up=dn->lsu;                      /* -> current Unit  */
6658
0
  for (d=0; d<dn->digits-1; d++) { /* [don't strip the final digit]  */
6659
    /* slice by powers  */
6660
0
    #if DECDPUN<=4
6661
0
      uInt quot=QUOT10(*up, cut);
6662
0
      if ((*up-quot*powers[cut])!=0) break;  /* found non-0 digit  */
6663
    #else
6664
      if (*up%powers[cut]!=0) break;         /* found non-0 digit  */
6665
    #endif
6666
    /* have a trailing 0  */
6667
0
    if (!all) {                    /* trimming  */
6668
      /* [if exp>0 then all trailing 0s are significant for trim]  */
6669
0
      if (exp<=0) {                /* if digit might be significant  */
6670
0
        if (exp==0) break;         /* then quit  */
6671
0
        exp++;                     /* next digit might be significant  */
6672
0
        }
6673
0
      }
6674
0
    cut++;                         /* next power  */
6675
0
    if (cut>DECDPUN) {             /* need new Unit  */
6676
0
      up++;
6677
0
      cut=1;
6678
0
      }
6679
0
    } /* d  */
6680
0
  if (d==0) return dn;             /* none to drop  */
6681
6682
  /* may need to limit drop if clamping  */
6683
0
  if (set->clamp && !noclamp) {
6684
0
    Int maxd=set->emax-set->digits+1-dn->exponent;
6685
0
    if (maxd<=0) return dn;        /* nothing possible  */
6686
0
    if (d>maxd) d=maxd;
6687
0
    }
6688
6689
  /* effect the drop  */
6690
0
  decShiftToLeast(dn->lsu, D2U(dn->digits), d);
6691
0
  dn->exponent+=d;                 /* maintain numerical value  */
6692
0
  dn->digits-=d;                   /* new length  */
6693
0
  *dropped=d;                      /* report the count  */
6694
0
  return dn;
6695
0
  } /* decTrim  */
6696
6697
/* ------------------------------------------------------------------ */
6698
/* decReverse -- reverse a Unit array in place                        */
6699
/*                                                                    */
6700
/*   ulo    is the start of the array                                 */
6701
/*   uhi    is the end of the array (highest Unit to include)         */
6702
/*                                                                    */
6703
/* The units ulo through uhi are reversed in place (if the number     */
6704
/* of units is odd, the middle one is untouched).  Note that the      */
6705
/* digit(s) in each unit are unaffected.                              */
6706
/* ------------------------------------------------------------------ */
6707
0
static void decReverse(Unit *ulo, Unit *uhi) {
6708
0
  Unit temp;
6709
0
  for (; ulo<uhi; ulo++, uhi--) {
6710
0
    temp=*ulo;
6711
0
    *ulo=*uhi;
6712
0
    *uhi=temp;
6713
0
    }
6714
0
  } /* decReverse  */
6715
6716
/* ------------------------------------------------------------------ */
6717
/* decShiftToMost -- shift digits in array towards most significant   */
6718
/*                                                                    */
6719
/*   uar    is the array                                              */
6720
/*   digits is the count of digits in use in the array                */
6721
/*   shift  is the number of zeros to pad with (least significant);   */
6722
/*     it must be zero or positive                                    */
6723
/*                                                                    */
6724
/*   returns the new length of the integer in the array, in digits    */
6725
/*                                                                    */
6726
/* No overflow is permitted (that is, the uar array must be known to  */
6727
/* be large enough to hold the result, after shifting).               */
6728
/* ------------------------------------------------------------------ */
6729
0
static Int decShiftToMost(Unit *uar, Int digits, Int shift) {
6730
0
  Unit  *target, *source, *first;  /* work  */
6731
0
  Int   cut;                       /* odd 0's to add  */
6732
0
  uInt  next;                      /* work  */
6733
6734
0
  if (shift==0) return digits;     /* [fastpath] nothing to do  */
6735
0
  if ((digits+shift)<=DECDPUN) {   /* [fastpath] single-unit case  */
6736
0
    *uar = static_cast<Unit>(*uar * powers[shift]);
6737
0
    return digits+shift;
6738
0
    }
6739
6740
0
  next=0;                          /* all paths  */
6741
0
  source=uar+D2U(digits)-1;        /* where msu comes from  */
6742
0
  target=source+D2U(shift);        /* where upper part of first cut goes  */
6743
0
  cut=DECDPUN-MSUDIGITS(shift);    /* where to slice  */
6744
0
  if (cut==0) {                    /* unit-boundary case  */
6745
0
    for (; source>=uar; source--, target--) *target=*source;
6746
0
    }
6747
0
   else {
6748
0
    first=uar+D2U(digits+shift)-1; /* where msu of source will end up  */
6749
0
    for (; source>=uar; source--, target--) {
6750
      /* split the source Unit and accumulate remainder for next  */
6751
0
      #if DECDPUN<=4
6752
0
        uInt quot=QUOT10(*source, cut);
6753
0
        uInt rem=*source-quot*powers[cut];
6754
0
        next+=quot;
6755
      #else
6756
        uInt rem=*source%powers[cut];
6757
        next+=*source/powers[cut];
6758
      #endif
6759
0
      if (target <= first) *target = static_cast<Unit>(next); /* write to target iff valid  */
6760
0
      next=rem*powers[DECDPUN-cut];            /* save remainder for next Unit  */
6761
0
      }
6762
0
    } /* shift-move  */
6763
6764
  /* propagate any partial unit to one below and clear the rest  */
6765
0
  for (; target>=uar; target--) {
6766
0
    *target = static_cast<Unit>(next);
6767
0
    next=0;
6768
0
    }
6769
0
  return digits+shift;
6770
0
  } /* decShiftToMost  */
6771
6772
/* ------------------------------------------------------------------ */
6773
/* decShiftToLeast -- shift digits in array towards least significant */
6774
/*                                                                    */
6775
/*   uar   is the array                                               */
6776
/*   units is length of the array, in units                           */
6777
/*   shift is the number of digits to remove from the lsu end; it     */
6778
/*     must be zero or positive and <= than units*DECDPUN.            */
6779
/*                                                                    */
6780
/*   returns the new length of the integer in the array, in units     */
6781
/*                                                                    */
6782
/* Removed digits are discarded (lost).  Units not required to hold   */
6783
/* the final result are unchanged.                                    */
6784
/* ------------------------------------------------------------------ */
6785
0
static Int decShiftToLeast(Unit *uar, Int units, Int shift) {
6786
0
  Unit  *target, *up;              /* work  */
6787
0
  Int   cut, count;                /* work  */
6788
0
  Int   quot, rem;                 /* for division  */
6789
6790
0
  if (shift==0) return units;      /* [fastpath] nothing to do  */
6791
0
  if (shift==units*DECDPUN) {      /* [fastpath] little to do  */
6792
0
    *uar=0;                        /* all digits cleared gives zero  */
6793
0
    return 1;                      /* leaves just the one  */
6794
0
    }
6795
6796
0
  target=uar;                      /* both paths  */
6797
0
  cut=MSUDIGITS(shift);
6798
0
  if (cut==DECDPUN) {              /* unit-boundary case; easy  */
6799
0
    up=uar+D2U(shift);
6800
0
    for (; up<uar+units; target++, up++) *target=*up;
6801
0
    return static_cast<int32_t>(target-uar);
6802
0
    }
6803
6804
  /* messier  */
6805
0
  up=uar+D2U(shift-cut);           /* source; correct to whole Units  */
6806
0
  count=units*DECDPUN-shift;       /* the maximum new length  */
6807
0
  #if DECDPUN<=4
6808
0
    quot=QUOT10(*up, cut);
6809
  #else
6810
    quot=*up/powers[cut];
6811
  #endif
6812
0
  for (; ; target++) {
6813
0
    *target = static_cast<Unit>(quot);
6814
0
    count-=(DECDPUN-cut);
6815
0
    if (count<=0) break;
6816
0
    up++;
6817
0
    quot=*up;
6818
0
    #if DECDPUN<=4
6819
0
      quot=QUOT10(quot, cut);
6820
0
      rem=*up-quot*powers[cut];
6821
    #else
6822
      rem=quot%powers[cut];
6823
      quot=quot/powers[cut];
6824
    #endif
6825
0
    *target = static_cast<Unit>(*target + rem * powers[DECDPUN - cut]);
6826
0
    count-=cut;
6827
0
    if (count<=0) break;
6828
0
    }
6829
0
  return static_cast<int32_t>(target-uar+1);
6830
0
  } /* decShiftToLeast  */
6831
6832
#if DECSUBSET
6833
/* ------------------------------------------------------------------ */
6834
/* decRoundOperand -- round an operand  [used for subset only]        */
6835
/*                                                                    */
6836
/*   dn is the number to round (dn->digits is > set->digits)          */
6837
/*   set is the relevant context                                      */
6838
/*   status is the status accumulator                                 */
6839
/*                                                                    */
6840
/*   returns an allocated decNumber with the rounded result.          */
6841
/*                                                                    */
6842
/* lostDigits and other status may be set by this.                    */
6843
/*                                                                    */
6844
/* Since the input is an operand, it must not be modified.            */
6845
/* Instead, return an allocated decNumber, rounded as required.       */
6846
/* It is the caller's responsibility to free the allocated storage.   */
6847
/*                                                                    */
6848
/* If no storage is available then the result cannot be used, so nullptr */
6849
/* is returned.                                                       */
6850
/* ------------------------------------------------------------------ */
6851
static decNumber *decRoundOperand(const decNumber *dn, decContext *set,
6852
                                  uInt *status) {
6853
  decNumber *res;                       /* result structure  */
6854
  uInt newstatus=0;                     /* status from round  */
6855
  Int  residue=0;                       /* rounding accumulator  */
6856
6857
  /* Allocate storage for the returned decNumber, big enough for the  */
6858
  /* length specified by the context  */
6859
  res=(decNumber *)malloc(sizeof(decNumber)
6860
                          +(D2U(set->digits)-1)*sizeof(Unit));
6861
  if (res==nullptr) {
6862
    *status|=DEC_Insufficient_storage;
6863
    return nullptr;
6864
    }
6865
  decCopyFit(res, dn, set, &residue, &newstatus);
6866
  decApplyRound(res, set, residue, &newstatus);
6867
6868
  /* If that set Inexact then "lost digits" is raised...  */
6869
  if (newstatus & DEC_Inexact) newstatus|=DEC_Lost_digits;
6870
  *status|=newstatus;
6871
  return res;
6872
  } /* decRoundOperand  */
6873
#endif
6874
6875
/* ------------------------------------------------------------------ */
6876
/* decCopyFit -- copy a number, truncating the coefficient if needed  */
6877
/*                                                                    */
6878
/*   dest is the target decNumber                                     */
6879
/*   src  is the source decNumber                                     */
6880
/*   set is the context [used for length (digits) and rounding mode]  */
6881
/*   residue is the residue accumulator                               */
6882
/*   status contains the current status to be updated                 */
6883
/*                                                                    */
6884
/* (dest==src is allowed and will be a no-op if fits)                 */
6885
/* All fields are updated as required.                                */
6886
/* ------------------------------------------------------------------ */
6887
static void decCopyFit(decNumber *dest, const decNumber *src,
6888
0
                       decContext *set, Int *residue, uInt *status) {
6889
0
  dest->bits=src->bits;
6890
0
  dest->exponent=src->exponent;
6891
0
  decSetCoeff(dest, set, src->lsu, src->digits, residue, status);
6892
0
  } /* decCopyFit  */
6893
6894
/* ------------------------------------------------------------------ */
6895
/* decSetCoeff -- set the coefficient of a number                     */
6896
/*                                                                    */
6897
/*   dn    is the number whose coefficient array is to be set.        */
6898
/*         It must have space for set->digits digits                  */
6899
/*   set   is the context [for size]                                  */
6900
/*   lsu   -> lsu of the source coefficient [may be dn->lsu]          */
6901
/*   len   is digits in the source coefficient [may be dn->digits]    */
6902
/*   residue is the residue accumulator.  This has values as in       */
6903
/*         decApplyRound, and will be unchanged unless the            */
6904
/*         target size is less than len.  In this case, the           */
6905
/*         coefficient is truncated and the residue is updated to     */
6906
/*         reflect the previous residue and the dropped digits.       */
6907
/*   status is the status accumulator, as usual                       */
6908
/*                                                                    */
6909
/* The coefficient may already be in the number, or it can be an      */
6910
/* external intermediate array.  If it is in the number, lsu must ==  */
6911
/* dn->lsu and len must == dn->digits.                                */
6912
/*                                                                    */
6913
/* Note that the coefficient length (len) may be < set->digits, and   */
6914
/* in this case this merely copies the coefficient (or is a no-op     */
6915
/* if dn->lsu==lsu).                                                  */
6916
/*                                                                    */
6917
/* Note also that (only internally, from decQuantizeOp and            */
6918
/* decSetSubnormal) the value of set->digits may be less than one,    */
6919
/* indicating a round to left.  This routine handles that case        */
6920
/* correctly; caller ensures space.                                   */
6921
/*                                                                    */
6922
/* dn->digits, dn->lsu (and as required), and dn->exponent are        */
6923
/* updated as necessary.   dn->bits (sign) is unchanged.              */
6924
/*                                                                    */
6925
/* DEC_Rounded status is set if any digits are discarded.             */
6926
/* DEC_Inexact status is set if any non-zero digits are discarded, or */
6927
/*                       incoming residue was non-0 (implies rounded) */
6928
/* ------------------------------------------------------------------ */
6929
/* mapping array: maps 0-9 to canonical residues, so that a residue  */
6930
/* can be adjusted in the range [-1, +1] and achieve correct rounding  */
6931
/*                             0  1  2  3  4  5  6  7  8  9  */
6932
static const uByte resmap[10]={0, 3, 3, 3, 3, 5, 7, 7, 7, 7};
6933
static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu,
6934
0
                        Int len, Int *residue, uInt *status) {
6935
0
  Int   discard;              /* number of digits to discard  */
6936
0
  uInt  cut;                  /* cut point in Unit  */
6937
0
  const Unit *up;             /* work  */
6938
0
  Unit  *target;              /* ..  */
6939
0
  Int   count;                /* ..  */
6940
0
  #if DECDPUN<=4
6941
0
  uInt  temp;                 /* ..  */
6942
0
  #endif
6943
6944
0
  discard=len-set->digits;    /* digits to discard  */
6945
0
  if (discard<=0) {           /* no digits are being discarded  */
6946
0
    if (dn->lsu!=lsu) {       /* copy needed  */
6947
      /* copy the coefficient array to the result number; no shift needed  */
6948
0
      count=len;              /* avoids D2U  */
6949
0
      up=lsu;
6950
0
      for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
6951
0
        *target=*up;
6952
0
      dn->digits=len;         /* set the new length  */
6953
0
      }
6954
    /* dn->exponent and residue are unchanged, record any inexactitude  */
6955
0
    if (*residue!=0) *status|=(DEC_Inexact | DEC_Rounded);
6956
0
    return;
6957
0
    }
6958
6959
  /* some digits must be discarded ...  */
6960
0
  dn->exponent+=discard;      /* maintain numerical value  */
6961
0
  *status|=DEC_Rounded;       /* accumulate Rounded status  */
6962
0
  if (*residue>1) *residue=1; /* previous residue now to right, so reduce  */
6963
6964
0
  if (discard>len) {          /* everything, +1, is being discarded  */
6965
    /* guard digit is 0  */
6966
    /* residue is all the number [NB could be all 0s]  */
6967
0
    if (*residue<=0) {        /* not already positive  */
6968
0
      count=len;              /* avoids D2U  */
6969
0
      for (up=lsu; count>0; up++, count-=DECDPUN) if (*up!=0) { /* found non-0  */
6970
0
        *residue=1;
6971
0
        break;                /* no need to check any others  */
6972
0
        }
6973
0
      }
6974
0
    if (*residue!=0) *status|=DEC_Inexact; /* record inexactitude  */
6975
0
    *dn->lsu=0;               /* coefficient will now be 0  */
6976
0
    dn->digits=1;             /* ..  */
6977
0
    return;
6978
0
    } /* total discard  */
6979
6980
  /* partial discard [most common case]  */
6981
  /* here, at least the first (most significant) discarded digit exists  */
6982
6983
  /* spin up the number, noting residue during the spin, until get to  */
6984
  /* the Unit with the first discarded digit.  When reach it, extract  */
6985
  /* it and remember its position  */
6986
0
  count=0;
6987
0
  for (up=lsu;; up++) {
6988
0
    count+=DECDPUN;
6989
0
    if (count>=discard) break; /* full ones all checked  */
6990
0
    if (*up!=0) *residue=1;
6991
0
    } /* up  */
6992
6993
  /* here up -> Unit with first discarded digit  */
6994
0
  cut=discard-(count-DECDPUN)-1;
6995
0
  if (cut==DECDPUN-1) {       /* unit-boundary case (fast)  */
6996
0
    Unit half = static_cast<Unit>(powers[DECDPUN]) >> 1;
6997
    /* set residue directly  */
6998
0
    if (*up>=half) {
6999
0
      if (*up>half) *residue=7;
7000
0
      else *residue+=5;       /* add sticky bit  */
7001
0
      }
7002
0
     else { /* <half  */
7003
0
      if (*up!=0) *residue=3; /* [else is 0, leave as sticky bit]  */
7004
0
      }
7005
0
    if (set->digits<=0) {     /* special for Quantize/Subnormal :-(  */
7006
0
      *dn->lsu=0;             /* .. result is 0  */
7007
0
      dn->digits=1;           /* ..  */
7008
0
      }
7009
0
     else {                   /* shift to least  */
7010
0
      count=set->digits;      /* now digits to end up with  */
7011
0
      dn->digits=count;       /* set the new length  */
7012
0
      up++;                   /* move to next  */
7013
      /* on unit boundary, so shift-down copy loop is simple  */
7014
0
      for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
7015
0
        *target=*up;
7016
0
      }
7017
0
    } /* unit-boundary case  */
7018
7019
0
   else { /* discard digit is in low digit(s), and not top digit  */
7020
0
    uInt  discard1;                /* first discarded digit  */
7021
0
    uInt  quot, rem;               /* for divisions  */
7022
0
    if (cut==0) quot=*up;          /* is at bottom of unit  */
7023
0
     else /* cut>0 */ {            /* it's not at bottom of unit  */
7024
0
      #if DECDPUN<=4
7025
0
        U_ASSERT(/* cut >= 0 &&*/ cut <= 4);
7026
0
        quot=QUOT10(*up, cut);
7027
0
        rem=*up-quot*powers[cut];
7028
      #else
7029
        rem=*up%powers[cut];
7030
        quot=*up/powers[cut];
7031
      #endif
7032
0
      if (rem!=0) *residue=1;
7033
0
      }
7034
    /* discard digit is now at bottom of quot  */
7035
0
    #if DECDPUN<=4
7036
0
      temp=(quot*6554)>>16;        /* fast /10  */
7037
      /* Vowels algorithm here not a win (9 instructions)  */
7038
0
      discard1=quot-X10(temp);
7039
0
      quot=temp;
7040
    #else
7041
      discard1=quot%10;
7042
      quot=quot/10;
7043
    #endif
7044
    /* here, discard1 is the guard digit, and residue is everything  */
7045
    /* else [use mapping array to accumulate residue safely]  */
7046
0
    *residue+=resmap[discard1];
7047
0
    cut++;                         /* update cut  */
7048
    /* here: up -> Unit of the array with bottom digit  */
7049
    /*       cut is the division point for each Unit  */
7050
    /*       quot holds the uncut high-order digits for the current unit  */
7051
0
    if (set->digits<=0) {          /* special for Quantize/Subnormal :-(  */
7052
0
      *dn->lsu=0;                  /* .. result is 0  */
7053
0
      dn->digits=1;                /* ..  */
7054
0
      }
7055
0
     else {                        /* shift to least needed  */
7056
0
      count=set->digits;           /* now digits to end up with  */
7057
0
      dn->digits=count;            /* set the new length  */
7058
      /* shift-copy the coefficient array to the result number  */
7059
0
      for (target=dn->lsu; ; target++) {
7060
0
        *target = static_cast<Unit>(quot);
7061
0
        count-=(DECDPUN-cut);
7062
0
        if (count<=0) break;
7063
0
        up++;
7064
0
        quot=*up;
7065
0
        #if DECDPUN<=4
7066
0
          quot=QUOT10(quot, cut);
7067
0
          rem=*up-quot*powers[cut];
7068
        #else
7069
          rem=quot%powers[cut];
7070
          quot=quot/powers[cut];
7071
        #endif
7072
0
        *target = static_cast<Unit>(*target + rem * powers[DECDPUN - cut]);
7073
0
        count-=cut;
7074
0
        if (count<=0) break;
7075
0
        } /* shift-copy loop  */
7076
0
      } /* shift to least  */
7077
0
    } /* not unit boundary  */
7078
7079
0
  if (*residue!=0) *status|=DEC_Inexact; /* record inexactitude  */
7080
0
  } /* decSetCoeff  */
7081
7082
/* ------------------------------------------------------------------ */
7083
/* decApplyRound -- apply pending rounding to a number                */
7084
/*                                                                    */
7085
/*   dn    is the number, with space for set->digits digits           */
7086
/*   set   is the context [for size and rounding mode]                */
7087
/*   residue indicates pending rounding, being any accumulated        */
7088
/*         guard and sticky information.  It may be:                  */
7089
/*         6-9: rounding digit is >5                                  */
7090
/*         5:   rounding digit is exactly half-way                    */
7091
/*         1-4: rounding digit is <5 and >0                           */
7092
/*         0:   the coefficient is exact                              */
7093
/*        -1:   as 1, but the hidden digits are subtractive, that     */
7094
/*              is, of the opposite sign to dn.  In this case the     */
7095
/*              coefficient must be non-0.  This case occurs when     */
7096
/*              subtracting a small number (which can be reduced to   */
7097
/*              a sticky bit); see decAddOp.                          */
7098
/*   status is the status accumulator, as usual                       */
7099
/*                                                                    */
7100
/* This routine applies rounding while keeping the length of the      */
7101
/* coefficient constant.  The exponent and status are unchanged       */
7102
/* except if:                                                         */
7103
/*                                                                    */
7104
/*   -- the coefficient was increased and is all nines (in which      */
7105
/*      case Overflow could occur, and is handled directly here so    */
7106
/*      the caller does not need to re-test for overflow)             */
7107
/*                                                                    */
7108
/*   -- the coefficient was decreased and becomes all nines (in which */
7109
/*      case Underflow could occur, and is also handled directly).    */
7110
/*                                                                    */
7111
/* All fields in dn are updated as required.                          */
7112
/*                                                                    */
7113
/* ------------------------------------------------------------------ */
7114
static void decApplyRound(decNumber *dn, decContext *set, Int residue,
7115
0
                          uInt *status) {
7116
0
  Int  bump;                  /* 1 if coefficient needs to be incremented  */
7117
                              /* -1 if coefficient needs to be decremented  */
7118
7119
0
  if (residue==0) return;     /* nothing to apply  */
7120
7121
0
  bump=0;                     /* assume a smooth ride  */
7122
7123
  /* now decide whether, and how, to round, depending on mode  */
7124
0
  switch (set->round) {
7125
0
    case DEC_ROUND_05UP: {    /* round zero or five up (for reround)  */
7126
      /* This is the same as DEC_ROUND_DOWN unless there is a  */
7127
      /* positive residue and the lsd of dn is 0 or 5, in which case  */
7128
      /* it is bumped; when residue is <0, the number is therefore  */
7129
      /* bumped down unless the final digit was 1 or 6 (in which  */
7130
      /* case it is bumped down and then up -- a no-op)  */
7131
0
      Int lsd5=*dn->lsu%5;     /* get lsd and quintate  */
7132
0
      if (residue<0 && lsd5!=1) bump=-1;
7133
0
       else if (residue>0 && lsd5==0) bump=1;
7134
      /* [bump==1 could be applied directly; use common path for clarity]  */
7135
0
      break;} /* r-05  */
7136
7137
0
    case DEC_ROUND_DOWN: {
7138
      /* no change, except if negative residue  */
7139
0
      if (residue<0) bump=-1;
7140
0
      break;} /* r-d  */
7141
7142
0
    case DEC_ROUND_HALF_DOWN: {
7143
0
      if (residue>5) bump=1;
7144
0
      break;} /* r-h-d  */
7145
7146
0
    case DEC_ROUND_HALF_EVEN: {
7147
0
      if (residue>5) bump=1;            /* >0.5 goes up  */
7148
0
       else if (residue==5) {           /* exactly 0.5000...  */
7149
        /* 0.5 goes up iff [new] lsd is odd  */
7150
0
        if (*dn->lsu & 0x01) bump=1;
7151
0
        }
7152
0
      break;} /* r-h-e  */
7153
7154
0
    case DEC_ROUND_HALF_UP: {
7155
0
      if (residue>=5) bump=1;
7156
0
      break;} /* r-h-u  */
7157
7158
0
    case DEC_ROUND_UP: {
7159
0
      if (residue>0) bump=1;
7160
0
      break;} /* r-u  */
7161
7162
0
    case DEC_ROUND_CEILING: {
7163
      /* same as _UP for positive numbers, and as _DOWN for negatives  */
7164
      /* [negative residue cannot occur on 0]  */
7165
0
      if (decNumberIsNegative(dn)) {
7166
0
        if (residue<0) bump=-1;
7167
0
        }
7168
0
       else {
7169
0
        if (residue>0) bump=1;
7170
0
        }
7171
0
      break;} /* r-c  */
7172
7173
0
    case DEC_ROUND_FLOOR: {
7174
      /* same as _UP for negative numbers, and as _DOWN for positive  */
7175
      /* [negative residue cannot occur on 0]  */
7176
0
      if (!decNumberIsNegative(dn)) {
7177
0
        if (residue<0) bump=-1;
7178
0
        }
7179
0
       else {
7180
0
        if (residue>0) bump=1;
7181
0
        }
7182
0
      break;} /* r-f  */
7183
7184
0
    default: {      /* e.g., DEC_ROUND_MAX  */
7185
0
      *status|=DEC_Invalid_context;
7186
      #if DECTRACE || (DECCHECK && DECVERB)
7187
      printf("Unknown rounding mode: %d\n", set->round);
7188
      #endif
7189
0
      break;}
7190
0
    } /* switch  */
7191
7192
  /* now bump the number, up or down, if need be  */
7193
0
  if (bump==0) return;                       /* no action required  */
7194
7195
  /* Simply use decUnitAddSub unless bumping up and the number is  */
7196
  /* all nines.  In this special case set to 100... explicitly  */
7197
  /* and adjust the exponent by one (as otherwise could overflow  */
7198
  /* the array)  */
7199
  /* Similarly handle all-nines result if bumping down.  */
7200
0
  if (bump>0) {
7201
0
    Unit *up;                                /* work  */
7202
0
    uInt count=dn->digits;                   /* digits to be checked  */
7203
0
    for (up=dn->lsu; ; up++) {
7204
0
      if (count<=DECDPUN) {
7205
        /* this is the last Unit (the msu)  */
7206
0
        if (*up!=powers[count]-1) break;     /* not still 9s  */
7207
        /* here if it, too, is all nines  */
7208
0
        *up = static_cast<Unit>(powers[count - 1]); /* here 999 -> 100 etc.  */
7209
0
        for (up=up-1; up>=dn->lsu; up--) *up=0; /* others all to 0  */
7210
0
        dn->exponent++;                      /* and bump exponent  */
7211
        /* [which, very rarely, could cause Overflow...]  */
7212
0
        if ((dn->exponent+dn->digits)>set->emax+1) {
7213
0
          decSetOverflow(dn, set, status);
7214
0
          }
7215
0
        return;                              /* done  */
7216
0
        }
7217
      /* a full unit to check, with more to come  */
7218
0
      if (*up!=DECDPUNMAX) break;            /* not still 9s  */
7219
0
      count-=DECDPUN;
7220
0
      } /* up  */
7221
0
    } /* bump>0  */
7222
0
   else {                                    /* -1  */
7223
    /* here checking for a pre-bump of 1000... (leading 1, all  */
7224
    /* other digits zero)  */
7225
0
    Unit *up, *sup;                          /* work  */
7226
0
    uInt count=dn->digits;                   /* digits to be checked  */
7227
0
    for (up=dn->lsu; ; up++) {
7228
0
      if (count<=DECDPUN) {
7229
        /* this is the last Unit (the msu)  */
7230
0
        if (*up!=powers[count-1]) break;     /* not 100..  */
7231
        /* here if have the 1000... case  */
7232
0
        sup=up;                              /* save msu pointer  */
7233
0
        *up = static_cast<Unit>(powers[count]) - 1; /* here 100 in msu -> 999  */
7234
        /* others all to all-nines, too  */
7235
0
        for (up=up-1; up>=dn->lsu; up--) *up = static_cast<Unit>(powers[DECDPUN]) - 1;
7236
0
        dn->exponent--;                      /* and bump exponent  */
7237
7238
        /* iff the number was at the subnormal boundary (exponent=etiny)  */
7239
        /* then the exponent is now out of range, so it will in fact get  */
7240
        /* clamped to etiny and the final 9 dropped.  */
7241
        /* printf(">> emin=%d exp=%d sdig=%d\n", set->emin,  */
7242
        /*        dn->exponent, set->digits);  */
7243
0
        if (dn->exponent+1==set->emin-set->digits+1) {
7244
0
          if (count==1 && dn->digits==1) *sup=0;  /* here 9 -> 0[.9]  */
7245
0
           else {
7246
0
            *sup = static_cast<Unit>(powers[count - 1]) - 1; /* here 999.. in msu -> 99..  */
7247
0
            dn->digits--;
7248
0
            }
7249
0
          dn->exponent++;
7250
0
          *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
7251
0
          }
7252
0
        return;                              /* done  */
7253
0
        }
7254
7255
      /* a full unit to check, with more to come  */
7256
0
      if (*up!=0) break;                     /* not still 0s  */
7257
0
      count-=DECDPUN;
7258
0
      } /* up  */
7259
7260
0
    } /* bump<0  */
7261
7262
  /* Actual bump needed.  Do it.  */
7263
0
  decUnitAddSub(dn->lsu, D2U(dn->digits), uarrone, 1, 0, dn->lsu, bump);
7264
0
  } /* decApplyRound  */
7265
7266
#if DECSUBSET
7267
/* ------------------------------------------------------------------ */
7268
/* decFinish -- finish processing a number                            */
7269
/*                                                                    */
7270
/*   dn is the number                                                 */
7271
/*   set is the context                                               */
7272
/*   residue is the rounding accumulator (as in decApplyRound)        */
7273
/*   status is the accumulator                                        */
7274
/*                                                                    */
7275
/* This finishes off the current number by:                           */
7276
/*    1. If not extended:                                             */
7277
/*       a. Converting a zero result to clean '0'                     */
7278
/*       b. Reducing positive exponents to 0, if would fit in digits  */
7279
/*    2. Checking for overflow and subnormals (always)                */
7280
/* Note this is just Finalize when no subset arithmetic.              */
7281
/* All fields are updated as required.                                */
7282
/* ------------------------------------------------------------------ */
7283
static void decFinish(decNumber *dn, decContext *set, Int *residue,
7284
                      uInt *status) {
7285
  if (!set->extended) {
7286
    if ISZERO(dn) {                /* value is zero  */
7287
      dn->exponent=0;              /* clean exponent ..  */
7288
      dn->bits=0;                  /* .. and sign  */
7289
      return;                      /* no error possible  */
7290
      }
7291
    if (dn->exponent>=0) {         /* non-negative exponent  */
7292
      /* >0; reduce to integer if possible  */
7293
      if (set->digits >= (dn->exponent+dn->digits)) {
7294
        dn->digits=decShiftToMost(dn->lsu, dn->digits, dn->exponent);
7295
        dn->exponent=0;
7296
        }
7297
      }
7298
    } /* !extended  */
7299
7300
  decFinalize(dn, set, residue, status);
7301
  } /* decFinish  */
7302
#endif
7303
7304
/* ------------------------------------------------------------------ */
7305
/* decFinalize -- final check, clamp, and round of a number           */
7306
/*                                                                    */
7307
/*   dn is the number                                                 */
7308
/*   set is the context                                               */
7309
/*   residue is the rounding accumulator (as in decApplyRound)        */
7310
/*   status is the status accumulator                                 */
7311
/*                                                                    */
7312
/* This finishes off the current number by checking for subnormal     */
7313
/* results, applying any pending rounding, checking for overflow,     */
7314
/* and applying any clamping.                                         */
7315
/* Underflow and overflow conditions are raised as appropriate.       */
7316
/* All fields are updated as required.                                */
7317
/* ------------------------------------------------------------------ */
7318
static void decFinalize(decNumber *dn, decContext *set, Int *residue,
7319
0
                        uInt *status) {
7320
0
  Int shift;                            /* shift needed if clamping  */
7321
0
  Int tinyexp=set->emin-dn->digits+1;   /* precalculate subnormal boundary  */
7322
7323
  /* Must be careful, here, when checking the exponent as the  */
7324
  /* adjusted exponent could overflow 31 bits [because it may already  */
7325
  /* be up to twice the expected].  */
7326
7327
  /* First test for subnormal.  This must be done before any final  */
7328
  /* round as the result could be rounded to Nmin or 0.  */
7329
0
  if (dn->exponent<=tinyexp) {          /* prefilter  */
7330
0
    Int comp;
7331
0
    decNumber nmin;
7332
    /* A very nasty case here is dn == Nmin and residue<0  */
7333
0
    if (dn->exponent<tinyexp) {
7334
      /* Go handle subnormals; this will apply round if needed.  */
7335
0
      decSetSubnormal(dn, set, residue, status);
7336
0
      return;
7337
0
      }
7338
    /* Equals case: only subnormal if dn=Nmin and negative residue  */
7339
0
    uprv_decNumberZero(&nmin);
7340
0
    nmin.lsu[0]=1;
7341
0
    nmin.exponent=set->emin;
7342
0
    comp=decCompare(dn, &nmin, 1);                /* (signless compare)  */
7343
0
    if (comp==BADINT) {                           /* oops  */
7344
0
      *status|=DEC_Insufficient_storage;          /* abandon...  */
7345
0
      return;
7346
0
      }
7347
0
    if (*residue<0 && comp==0) {                  /* neg residue and dn==Nmin  */
7348
0
      decApplyRound(dn, set, *residue, status);   /* might force down  */
7349
0
      decSetSubnormal(dn, set, residue, status);
7350
0
      return;
7351
0
      }
7352
0
    }
7353
7354
  /* now apply any pending round (this could raise overflow).  */
7355
0
  if (*residue!=0) decApplyRound(dn, set, *residue, status);
7356
7357
  /* Check for overflow [redundant in the 'rare' case] or clamp  */
7358
0
  if (dn->exponent<=set->emax-set->digits+1) return;   /* neither needed  */
7359
7360
7361
  /* here when might have an overflow or clamp to do  */
7362
0
  if (dn->exponent>set->emax-dn->digits+1) {           /* too big  */
7363
0
    decSetOverflow(dn, set, status);
7364
0
    return;
7365
0
    }
7366
  /* here when the result is normal but in clamp range  */
7367
0
  if (!set->clamp) return;
7368
7369
  /* here when need to apply the IEEE exponent clamp (fold-down)  */
7370
0
  shift=dn->exponent-(set->emax-set->digits+1);
7371
7372
  /* shift coefficient (if non-zero)  */
7373
0
  if (!ISZERO(dn)) {
7374
0
    dn->digits=decShiftToMost(dn->lsu, dn->digits, shift);
7375
0
    }
7376
0
  dn->exponent-=shift;   /* adjust the exponent to match  */
7377
0
  *status|=DEC_Clamped;  /* and record the dirty deed  */
7378
0
  } /* decFinalize  */
7379
7380
/* ------------------------------------------------------------------ */
7381
/* decSetOverflow -- set number to proper overflow value              */
7382
/*                                                                    */
7383
/*   dn is the number (used for sign [only] and result)               */
7384
/*   set is the context [used for the rounding mode, etc.]            */
7385
/*   status contains the current status to be updated                 */
7386
/*                                                                    */
7387
/* This sets the sign of a number and sets its value to either        */
7388
/* Infinity or the maximum finite value, depending on the sign of     */
7389
/* dn and the rounding mode, following IEEE 754 rules.                */
7390
/* ------------------------------------------------------------------ */
7391
0
static void decSetOverflow(decNumber *dn, decContext *set, uInt *status) {
7392
0
  Flag needmax=0;                  /* result is maximum finite value  */
7393
0
  uByte sign=dn->bits&DECNEG;      /* clean and save sign bit  */
7394
7395
0
  if (ISZERO(dn)) {                /* zero does not overflow magnitude  */
7396
0
    Int emax=set->emax;                      /* limit value  */
7397
0
    if (set->clamp) emax-=set->digits-1;     /* lower if clamping  */
7398
0
    if (dn->exponent>emax) {                 /* clamp required  */
7399
0
      dn->exponent=emax;
7400
0
      *status|=DEC_Clamped;
7401
0
      }
7402
0
    return;
7403
0
    }
7404
7405
0
  uprv_decNumberZero(dn);
7406
0
  switch (set->round) {
7407
0
    case DEC_ROUND_DOWN: {
7408
0
      needmax=1;                   /* never Infinity  */
7409
0
      break;} /* r-d  */
7410
0
    case DEC_ROUND_05UP: {
7411
0
      needmax=1;                   /* never Infinity  */
7412
0
      break;} /* r-05  */
7413
0
    case DEC_ROUND_CEILING: {
7414
0
      if (sign) needmax=1;         /* Infinity if non-negative  */
7415
0
      break;} /* r-c  */
7416
0
    case DEC_ROUND_FLOOR: {
7417
0
      if (!sign) needmax=1;        /* Infinity if negative  */
7418
0
      break;} /* r-f  */
7419
0
    default: break;                /* Infinity in all other cases  */
7420
0
    }
7421
0
  if (needmax) {
7422
0
    decSetMaxValue(dn, set);
7423
0
    dn->bits=sign;                 /* set sign  */
7424
0
    }
7425
0
   else dn->bits=sign|DECINF;      /* Value is +/-Infinity  */
7426
0
  *status|=DEC_Overflow | DEC_Inexact | DEC_Rounded;
7427
0
  } /* decSetOverflow  */
7428
7429
/* ------------------------------------------------------------------ */
7430
/* decSetMaxValue -- set number to +Nmax (maximum normal value)       */
7431
/*                                                                    */
7432
/*   dn is the number to set                                          */
7433
/*   set is the context [used for digits and emax]                    */
7434
/*                                                                    */
7435
/* This sets the number to the maximum positive value.                */
7436
/* ------------------------------------------------------------------ */
7437
0
static void decSetMaxValue(decNumber *dn, decContext *set) {
7438
0
  Unit *up;                        /* work  */
7439
0
  Int count=set->digits;           /* nines to add  */
7440
0
  dn->digits=count;
7441
  /* fill in all nines to set maximum value  */
7442
0
  for (up=dn->lsu; ; up++) {
7443
0
    if (count>DECDPUN) *up=DECDPUNMAX;  /* unit full o'nines  */
7444
0
     else {                             /* this is the msu  */
7445
0
      *up = static_cast<Unit>(powers[count] - 1);
7446
0
      break;
7447
0
      }
7448
0
    count-=DECDPUN;                /* filled those digits  */
7449
0
    } /* up  */
7450
0
  dn->bits=0;                      /* + sign  */
7451
0
  dn->exponent=set->emax-set->digits+1;
7452
0
  } /* decSetMaxValue  */
7453
7454
/* ------------------------------------------------------------------ */
7455
/* decSetSubnormal -- process value whose exponent is <Emin           */
7456
/*                                                                    */
7457
/*   dn is the number (used as input as well as output; it may have   */
7458
/*         an allowed subnormal value, which may need to be rounded)  */
7459
/*   set is the context [used for the rounding mode]                  */
7460
/*   residue is any pending residue                                   */
7461
/*   status contains the current status to be updated                 */
7462
/*                                                                    */
7463
/* If subset mode, set result to zero and set Underflow flags.        */
7464
/*                                                                    */
7465
/* Value may be zero with a low exponent; this does not set Subnormal */
7466
/* but the exponent will be clamped to Etiny.                         */
7467
/*                                                                    */
7468
/* Otherwise ensure exponent is not out of range, and round as        */
7469
/* necessary.  Underflow is set if the result is Inexact.             */
7470
/* ------------------------------------------------------------------ */
7471
static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
7472
0
                            uInt *status) {
7473
0
  decContext workset;         /* work  */
7474
0
  Int        etiny, adjust;   /* ..  */
7475
7476
  #if DECSUBSET
7477
  /* simple set to zero and 'hard underflow' for subset  */
7478
  if (!set->extended) {
7479
    uprv_decNumberZero(dn);
7480
    /* always full overflow  */
7481
    *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
7482
    return;
7483
    }
7484
  #endif
7485
7486
  /* Full arithmetic -- allow subnormals, rounded to minimum exponent  */
7487
  /* (Etiny) if needed  */
7488
0
  etiny=set->emin-(set->digits-1);      /* smallest allowed exponent  */
7489
7490
0
  if ISZERO(dn) {                       /* value is zero  */
7491
    /* residue can never be non-zero here  */
7492
    #if DECCHECK
7493
      if (*residue!=0) {
7494
        printf("++ Subnormal 0 residue %ld\n", (LI)*residue);
7495
        *status|=DEC_Invalid_operation;
7496
        }
7497
    #endif
7498
0
    if (dn->exponent<etiny) {           /* clamp required  */
7499
0
      dn->exponent=etiny;
7500
0
      *status|=DEC_Clamped;
7501
0
      }
7502
0
    return;
7503
0
    }
7504
7505
0
  *status|=DEC_Subnormal;               /* have a non-zero subnormal  */
7506
0
  adjust=etiny-dn->exponent;            /* calculate digits to remove  */
7507
0
  if (adjust<=0) {                      /* not out of range; unrounded  */
7508
    /* residue can never be non-zero here, except in the Nmin-residue  */
7509
    /* case (which is a subnormal result), so can take fast-path here  */
7510
    /* it may already be inexact (from setting the coefficient)  */
7511
0
    if (*status&DEC_Inexact) *status|=DEC_Underflow;
7512
0
    return;
7513
0
    }
7514
7515
  /* adjust>0, so need to rescale the result so exponent becomes Etiny  */
7516
  /* [this code is similar to that in rescale]  */
7517
0
  workset=*set;                         /* clone rounding, etc.  */
7518
0
  workset.digits=dn->digits-adjust;     /* set requested length  */
7519
0
  workset.emin-=adjust;                 /* and adjust emin to match  */
7520
  /* [note that the latter can be <1, here, similar to Rescale case]  */
7521
0
  decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);
7522
0
  decApplyRound(dn, &workset, *residue, status);
7523
7524
  /* Use 754 default rule: Underflow is set iff Inexact  */
7525
  /* [independent of whether trapped]  */
7526
0
  if (*status&DEC_Inexact) *status|=DEC_Underflow;
7527
7528
  /* if rounded up a 999s case, exponent will be off by one; adjust  */
7529
  /* back if so [it will fit, because it was shortened earlier]  */
7530
0
  if (dn->exponent>etiny) {
7531
0
    dn->digits=decShiftToMost(dn->lsu, dn->digits, 1);
7532
0
    dn->exponent--;                     /* (re)adjust the exponent.  */
7533
0
    }
7534
7535
  /* if rounded to zero, it is by definition clamped...  */
7536
0
  if (ISZERO(dn)) *status|=DEC_Clamped;
7537
0
  } /* decSetSubnormal  */
7538
7539
/* ------------------------------------------------------------------ */
7540
/* decCheckMath - check entry conditions for a math function          */
7541
/*                                                                    */
7542
/*   This checks the context and the operand                          */
7543
/*                                                                    */
7544
/*   rhs is the operand to check                                      */
7545
/*   set is the context to check                                      */
7546
/*   status is unchanged if both are good                             */
7547
/*                                                                    */
7548
/* returns non-zero if status is changed, 0 otherwise                 */
7549
/*                                                                    */
7550
/* Restrictions enforced:                                             */
7551
/*                                                                    */
7552
/*   digits, emax, and -emin in the context must be less than         */
7553
/*   DEC_MAX_MATH (999999), and A must be within these bounds if      */
7554
/*   non-zero.  Invalid_operation is set in the status if a           */
7555
/*   restriction is violated.                                         */
7556
/* ------------------------------------------------------------------ */
7557
static uInt decCheckMath(const decNumber *rhs, decContext *set,
7558
0
                         uInt *status) {
7559
0
  uInt save=*status;                         /* record  */
7560
0
  if (set->digits>DEC_MAX_MATH
7561
0
   || set->emax>DEC_MAX_MATH
7562
0
   || -set->emin>DEC_MAX_MATH) *status|=DEC_Invalid_context;
7563
0
   else if ((rhs->digits>DEC_MAX_MATH
7564
0
     || rhs->exponent+rhs->digits>DEC_MAX_MATH+1
7565
0
     || rhs->exponent+rhs->digits<2*(1-DEC_MAX_MATH))
7566
0
     && !ISZERO(rhs)) *status|=DEC_Invalid_operation;
7567
0
  return (*status!=save);
7568
0
  } /* decCheckMath  */
7569
7570
/* ------------------------------------------------------------------ */
7571
/* decGetInt -- get integer from a number                             */
7572
/*                                                                    */
7573
/*   dn is the number [which will not be altered]                     */
7574
/*                                                                    */
7575
/*   returns one of:                                                  */
7576
/*     BADINT if there is a non-zero fraction                         */
7577
/*     the converted integer                                          */
7578
/*     BIGEVEN if the integer is even and magnitude > 2*10**9         */
7579
/*     BIGODD  if the integer is odd  and magnitude > 2*10**9         */
7580
/*                                                                    */
7581
/* This checks and gets a whole number from the input decNumber.      */
7582
/* The sign can be determined from dn by the caller when BIGEVEN or   */
7583
/* BIGODD is returned.                                                */
7584
/* ------------------------------------------------------------------ */
7585
0
static Int decGetInt(const decNumber *dn) {
7586
0
  Int  theInt;                          /* result accumulator  */
7587
0
  const Unit *up;                       /* work  */
7588
0
  Int  got;                             /* digits (real or not) processed  */
7589
0
  Int  ilength=dn->digits+dn->exponent; /* integral length  */
7590
0
  Flag neg=decNumberIsNegative(dn);     /* 1 if -ve  */
7591
7592
  /* The number must be an integer that fits in 10 digits  */
7593
  /* Assert, here, that 10 is enough for any rescale Etiny  */
7594
  #if DEC_MAX_EMAX > 999999999
7595
    #error GetInt may need updating [for Emax]
7596
  #endif
7597
  #if DEC_MIN_EMIN < -999999999
7598
    #error GetInt may need updating [for Emin]
7599
  #endif
7600
0
  if (ISZERO(dn)) return 0;             /* zeros are OK, with any exponent  */
7601
7602
0
  up=dn->lsu;                           /* ready for lsu  */
7603
0
  theInt=0;                             /* ready to accumulate  */
7604
0
  if (dn->exponent>=0) {                /* relatively easy  */
7605
    /* no fractional part [usual]; allow for positive exponent  */
7606
0
    got=dn->exponent;
7607
0
    }
7608
0
   else { /* -ve exponent; some fractional part to check and discard  */
7609
0
    Int count=-dn->exponent;            /* digits to discard  */
7610
    /* spin up whole units until reach the Unit with the unit digit  */
7611
0
    for (; count>=DECDPUN; up++) {
7612
0
      if (*up!=0) return BADINT;        /* non-zero Unit to discard  */
7613
0
      count-=DECDPUN;
7614
0
      }
7615
0
    if (count==0) got=0;                /* [a multiple of DECDPUN]  */
7616
0
     else {                             /* [not multiple of DECDPUN]  */
7617
0
      Int rem;                          /* work  */
7618
      /* slice off fraction digits and check for non-zero  */
7619
0
      #if DECDPUN<=4
7620
0
        theInt=QUOT10(*up, count);
7621
0
        rem=*up-theInt*powers[count];
7622
      #else
7623
        rem=*up%powers[count];          /* slice off discards  */
7624
        theInt=*up/powers[count];
7625
      #endif
7626
0
      if (rem!=0) return BADINT;        /* non-zero fraction  */
7627
      /* it looks good  */
7628
0
      got=DECDPUN-count;                /* number of digits so far  */
7629
0
      up++;                             /* ready for next  */
7630
0
      }
7631
0
    }
7632
  /* now it's known there's no fractional part  */
7633
7634
  /* tricky code now, to accumulate up to 9.3 digits  */
7635
0
  if (got==0) {theInt=*up; got+=DECDPUN; up++;} /* ensure lsu is there  */
7636
7637
0
  if (ilength<11) {
7638
0
    Int save=theInt;
7639
    /* collect any remaining unit(s)  */
7640
0
    for (; got<ilength; up++) {
7641
0
      theInt+=*up*powers[got];
7642
0
      got+=DECDPUN;
7643
0
      }
7644
0
    if (ilength==10) {                  /* need to check for wrap  */
7645
0
      if (theInt / static_cast<Int>(powers[got - DECDPUN]) != static_cast<Int>(*(up - 1))) ilength = 11;
7646
         /* [that test also disallows the BADINT result case]  */
7647
0
       else if (neg && theInt>1999999997) ilength=11;
7648
0
       else if (!neg && theInt>999999999) ilength=11;
7649
0
      if (ilength==11) theInt=save;     /* restore correct low bit  */
7650
0
      }
7651
0
    }
7652
7653
0
  if (ilength>10) {                     /* too big  */
7654
0
    if (theInt&1) return BIGODD;        /* bottom bit 1  */
7655
0
    return BIGEVEN;                     /* bottom bit 0  */
7656
0
    }
7657
7658
0
  if (neg) theInt=-theInt;              /* apply sign  */
7659
0
  return theInt;
7660
0
  } /* decGetInt  */
7661
7662
/* ------------------------------------------------------------------ */
7663
/* decDecap -- decapitate the coefficient of a number                 */
7664
/*                                                                    */
7665
/*   dn   is the number to be decapitated                             */
7666
/*   drop is the number of digits to be removed from the left of dn;  */
7667
/*     this must be <= dn->digits (if equal, the coefficient is       */
7668
/*     set to 0)                                                      */
7669
/*                                                                    */
7670
/* Returns dn; dn->digits will be <= the initial digits less drop     */
7671
/* (after removing drop digits there may be leading zero digits       */
7672
/* which will also be removed).  Only dn->lsu and dn->digits change.  */
7673
/* ------------------------------------------------------------------ */
7674
0
static decNumber *decDecap(decNumber *dn, Int drop) {
7675
0
  Unit *msu;                            /* -> target cut point  */
7676
0
  Int cut;                              /* work  */
7677
0
  if (drop>=dn->digits) {               /* losing the whole thing  */
7678
    #if DECCHECK
7679
    if (drop>dn->digits)
7680
      printf("decDecap called with drop>digits [%ld>%ld]\n",
7681
             (LI)drop, (LI)dn->digits);
7682
    #endif
7683
0
    dn->lsu[0]=0;
7684
0
    dn->digits=1;
7685
0
    return dn;
7686
0
    }
7687
0
  msu=dn->lsu+D2U(dn->digits-drop)-1;   /* -> likely msu  */
7688
0
  cut=MSUDIGITS(dn->digits-drop);       /* digits to be in use in msu  */
7689
0
  if (cut!=DECDPUN) *msu%=powers[cut];  /* clear left digits  */
7690
  /* that may have left leading zero digits, so do a proper count...  */
7691
0
  dn->digits=decGetDigits(dn->lsu, static_cast<int32_t>(msu-dn->lsu+1));
7692
0
  return dn;
7693
0
  } /* decDecap  */
7694
7695
/* ------------------------------------------------------------------ */
7696
/* decBiStr -- compare string with pairwise options                   */
7697
/*                                                                    */
7698
/*   targ is the string to compare                                    */
7699
/*   str1 is one of the strings to compare against (length may be 0)  */
7700
/*   str2 is the other; it must be the same length as str1            */
7701
/*                                                                    */
7702
/*   returns 1 if strings compare equal, (that is, it is the same     */
7703
/*   length as str1 and str2, and each character of targ is in either */
7704
/*   str1 or str2 in the corresponding position), or 0 otherwise      */
7705
/*                                                                    */
7706
/* This is used for generic caseless compare, including the awkward   */
7707
/* case of the Turkish dotted and dotless Is.  Use as (for example):  */
7708
/*   if (decBiStr(test, "mike", "MIKE")) ...                          */
7709
/* ------------------------------------------------------------------ */
7710
0
static Flag decBiStr(const char *targ, const char *str1, const char *str2) {
7711
0
  for (;;targ++, str1++, str2++) {
7712
0
    if (*targ!=*str1 && *targ!=*str2) return 0;
7713
    /* *targ has a match in one (or both, if terminator)  */
7714
0
    if (*targ=='\0') break;
7715
0
    } /* forever  */
7716
0
  return 1;
7717
0
  } /* decBiStr  */
7718
7719
/* ------------------------------------------------------------------ */
7720
/* decNaNs -- handle NaN operand or operands                          */
7721
/*                                                                    */
7722
/*   res     is the result number                                     */
7723
/*   lhs     is the first operand                                     */
7724
/*   rhs     is the second operand, or nullptr if none                   */
7725
/*   context is used to limit payload length                          */
7726
/*   status  contains the current status                              */
7727
/*   returns res in case convenient                                   */
7728
/*                                                                    */
7729
/* Called when one or both operands is a NaN, and propagates the      */
7730
/* appropriate result to res.  When an sNaN is found, it is changed   */
7731
/* to a qNaN and Invalid operation is set.                            */
7732
/* ------------------------------------------------------------------ */
7733
static decNumber * decNaNs(decNumber *res, const decNumber *lhs,
7734
                           const decNumber *rhs, decContext *set,
7735
0
                           uInt *status) {
7736
  /* This decision tree ends up with LHS being the source pointer,  */
7737
  /* and status updated if need be  */
7738
0
  if (lhs->bits & DECSNAN)
7739
0
    *status|=DEC_Invalid_operation | DEC_sNaN;
7740
0
   else if (rhs==nullptr);
7741
0
   else if (rhs->bits & DECSNAN) {
7742
0
    lhs=rhs;
7743
0
    *status|=DEC_Invalid_operation | DEC_sNaN;
7744
0
    }
7745
0
   else if (lhs->bits & DECNAN);
7746
0
   else lhs=rhs;
7747
7748
  /* propagate the payload  */
7749
0
  if (lhs->digits<=set->digits) uprv_decNumberCopy(res, lhs); /* easy  */
7750
0
   else { /* too long  */
7751
0
    const Unit *ul;
7752
0
    Unit *ur, *uresp1;
7753
    /* copy safe number of units, then decapitate  */
7754
0
    res->bits=lhs->bits;                /* need sign etc.  */
7755
0
    uresp1=res->lsu+D2U(set->digits);
7756
0
    for (ur=res->lsu, ul=lhs->lsu; ur<uresp1; ur++, ul++) *ur=*ul;
7757
0
    res->digits=D2U(set->digits)*DECDPUN;
7758
    /* maybe still too long  */
7759
0
    if (res->digits>set->digits) decDecap(res, res->digits-set->digits);
7760
0
    }
7761
7762
0
  res->bits&=~DECSNAN;        /* convert any sNaN to NaN, while  */
7763
0
  res->bits|=DECNAN;          /* .. preserving sign  */
7764
0
  res->exponent=0;            /* clean exponent  */
7765
                              /* [coefficient was copied/decapitated]  */
7766
0
  return res;
7767
0
  } /* decNaNs  */
7768
7769
/* ------------------------------------------------------------------ */
7770
/* decStatus -- apply non-zero status                                 */
7771
/*                                                                    */
7772
/*   dn     is the number to set if error                             */
7773
/*   status contains the current status (not yet in context)          */
7774
/*   set    is the context                                            */
7775
/*                                                                    */
7776
/* If the status is an error status, the number is set to a NaN,      */
7777
/* unless the error was an overflow, divide-by-zero, or underflow,    */
7778
/* in which case the number will have already been set.               */
7779
/*                                                                    */
7780
/* The context status is then updated with the new status.  Note that */
7781
/* this may raise a signal, so control may never return from this     */
7782
/* routine (hence resources must be recovered before it is called).   */
7783
/* ------------------------------------------------------------------ */
7784
0
static void decStatus(decNumber *dn, uInt status, decContext *set) {
7785
0
  if (status & DEC_NaNs) {              /* error status -> NaN  */
7786
    /* if cause was an sNaN, clear and propagate [NaN is already set up]  */
7787
0
    if (status & DEC_sNaN) status&=~DEC_sNaN;
7788
0
     else {
7789
0
      uprv_decNumberZero(dn);                /* other error: clean throughout  */
7790
0
      dn->bits=DECNAN;                  /* and make a quiet NaN  */
7791
0
      }
7792
0
    }
7793
0
  uprv_decContextSetStatus(set, status);     /* [may not return]  */
7794
0
  } /* decStatus  */
7795
7796
/* ------------------------------------------------------------------ */
7797
/* decGetDigits -- count digits in a Units array                      */
7798
/*                                                                    */
7799
/*   uar is the Unit array holding the number (this is often an       */
7800
/*          accumulator of some sort)                                 */
7801
/*   len is the length of the array in units [>=1]                    */
7802
/*                                                                    */
7803
/*   returns the number of (significant) digits in the array          */
7804
/*                                                                    */
7805
/* All leading zeros are excluded, except the last if the array has   */
7806
/* only zero Units.                                                   */
7807
/* ------------------------------------------------------------------ */
7808
/* This may be called twice during some operations.  */
7809
0
static Int decGetDigits(Unit *uar, Int len) {
7810
0
  Unit *up=uar+(len-1);            /* -> msu  */
7811
0
  Int  digits=(len-1)*DECDPUN+1;   /* possible digits excluding msu  */
7812
  #if DECDPUN>4
7813
  uInt const *pow;                 /* work  */
7814
  #endif
7815
                                   /* (at least 1 in final msu)  */
7816
  #if DECCHECK
7817
  if (len<1) printf("decGetDigits called with len<1 [%ld]\n", (LI)len);
7818
  #endif
7819
7820
0
  for (; up>=uar; up--) {
7821
0
    if (*up==0) {                  /* unit is all 0s  */
7822
0
      if (digits==1) break;        /* a zero has one digit  */
7823
0
      digits-=DECDPUN;             /* adjust for 0 unit  */
7824
0
      continue;}
7825
    /* found the first (most significant) non-zero Unit  */
7826
    #if DECDPUN>1                  /* not done yet  */
7827
    if (*up<10) break;             /* is 1-9  */
7828
    digits++;
7829
    #if DECDPUN>2                  /* not done yet  */
7830
    if (*up<100) break;            /* is 10-99  */
7831
    digits++;
7832
    #if DECDPUN>3                  /* not done yet  */
7833
    if (*up<1000) break;           /* is 100-999  */
7834
    digits++;
7835
    #if DECDPUN>4                  /* count the rest ...  */
7836
    for (pow=&powers[4]; *up>=*pow; pow++) digits++;
7837
    #endif
7838
    #endif
7839
    #endif
7840
    #endif
7841
0
    break;
7842
0
    } /* up  */
7843
0
  return digits;
7844
0
  } /* decGetDigits  */
7845
7846
#if DECTRACE | DECCHECK
7847
/* ------------------------------------------------------------------ */
7848
/* decNumberShow -- display a number [debug aid]                      */
7849
/*   dn is the number to show                                         */
7850
/*                                                                    */
7851
/* Shows: sign, exponent, coefficient (msu first), digits             */
7852
/*    or: sign, special-value                                         */
7853
/* ------------------------------------------------------------------ */
7854
/* this is public so other modules can use it  */
7855
void uprv_decNumberShow(const decNumber *dn) {
7856
  const Unit *up;                  /* work  */
7857
  uInt u, d;                       /* ..  */
7858
  Int cut;                         /* ..  */
7859
  char isign='+';                  /* main sign  */
7860
  if (dn==nullptr) {
7861
    printf("nullptr\n");
7862
    return;}
7863
  if (decNumberIsNegative(dn)) isign='-';
7864
  printf(" >> %c ", isign);
7865
  if (dn->bits&DECSPECIAL) {       /* Is a special value  */
7866
    if (decNumberIsInfinite(dn)) printf("Infinity");
7867
     else {                                  /* a NaN  */
7868
      if (dn->bits&DECSNAN) printf("sNaN");  /* signalling NaN  */
7869
       else printf("NaN");
7870
      }
7871
    /* if coefficient and exponent are 0, no more to do  */
7872
    if (dn->exponent==0 && dn->digits==1 && *dn->lsu==0) {
7873
      printf("\n");
7874
      return;}
7875
    /* drop through to report other information  */
7876
    printf(" ");
7877
    }
7878
7879
  /* now carefully display the coefficient  */
7880
  up=dn->lsu+D2U(dn->digits)-1;         /* msu  */
7881
  printf("%ld", (LI)*up);
7882
  for (up=up-1; up>=dn->lsu; up--) {
7883
    u=*up;
7884
    printf(":");
7885
    for (cut=DECDPUN-1; cut>=0; cut--) {
7886
      d=u/powers[cut];
7887
      u-=d*powers[cut];
7888
      printf("%ld", (LI)d);
7889
      } /* cut  */
7890
    } /* up  */
7891
  if (dn->exponent!=0) {
7892
    char esign='+';
7893
    if (dn->exponent<0) esign='-';
7894
    printf(" E%c%ld", esign, (LI)abs(dn->exponent));
7895
    }
7896
  printf(" [%ld]\n", (LI)dn->digits);
7897
  } /* decNumberShow  */
7898
#endif
7899
7900
#if DECTRACE || DECCHECK
7901
/* ------------------------------------------------------------------ */
7902
/* decDumpAr -- display a unit array [debug/check aid]                */
7903
/*   name is a single-character tag name                              */
7904
/*   ar   is the array to display                                     */
7905
/*   len  is the length of the array in Units                         */
7906
/* ------------------------------------------------------------------ */
7907
static void decDumpAr(char name, const Unit *ar, Int len) {
7908
  Int i;
7909
  const char *spec;
7910
  #if DECDPUN==9
7911
    spec="%09d ";
7912
  #elif DECDPUN==8
7913
    spec="%08d ";
7914
  #elif DECDPUN==7
7915
    spec="%07d ";
7916
  #elif DECDPUN==6
7917
    spec="%06d ";
7918
  #elif DECDPUN==5
7919
    spec="%05d ";
7920
  #elif DECDPUN==4
7921
    spec="%04d ";
7922
  #elif DECDPUN==3
7923
    spec="%03d ";
7924
  #elif DECDPUN==2
7925
    spec="%02d ";
7926
  #else
7927
    spec="%d ";
7928
  #endif
7929
  printf("  :%c: ", name);
7930
  for (i=len-1; i>=0; i--) {
7931
    if (i==len-1) printf("%ld ", (LI)ar[i]);
7932
     else printf(spec, ar[i]);
7933
    }
7934
  printf("\n");
7935
  return;}
7936
#endif
7937
7938
#if DECCHECK
7939
/* ------------------------------------------------------------------ */
7940
/* decCheckOperands -- check operand(s) to a routine                  */
7941
/*   res is the result structure (not checked; it will be set to      */
7942
/*          quiet NaN if error found (and it is not nullptr))            */
7943
/*   lhs is the first operand (may be DECUNRESU)                      */
7944
/*   rhs is the second (may be DECUNUSED)                             */
7945
/*   set is the context (may be DECUNCONT)                            */
7946
/*   returns 0 if both operands, and the context are clean, or 1      */
7947
/*     otherwise (in which case the context will show an error,       */
7948
/*     unless nullptr).  Note that res is not cleaned; caller should     */
7949
/*     handle this so res=nullptr case is safe.                          */
7950
/* The caller is expected to abandon immediately if 1 is returned.    */
7951
/* ------------------------------------------------------------------ */
7952
static Flag decCheckOperands(decNumber *res, const decNumber *lhs,
7953
                             const decNumber *rhs, decContext *set) {
7954
  Flag bad=0;
7955
  if (set==nullptr) {                 /* oops; hopeless  */
7956
    #if DECTRACE || DECVERB
7957
    printf("Reference to context is nullptr.\n");
7958
    #endif
7959
    bad=1;
7960
    return 1;}
7961
   else if (set!=DECUNCONT
7962
     && (set->digits<1 || set->round>=DEC_ROUND_MAX)) {
7963
    bad=1;
7964
    #if DECTRACE || DECVERB
7965
    printf("Bad context [digits=%ld round=%ld].\n",
7966
           (LI)set->digits, (LI)set->round);
7967
    #endif
7968
    }
7969
   else {
7970
    if (res==nullptr) {
7971
      bad=1;
7972
      #if DECTRACE
7973
      /* this one not DECVERB as standard tests include nullptr  */
7974
      printf("Reference to result is nullptr.\n");
7975
      #endif
7976
      }
7977
    if (!bad && lhs!=DECUNUSED) bad=(decCheckNumber(lhs));
7978
    if (!bad && rhs!=DECUNUSED) bad=(decCheckNumber(rhs));
7979
    }
7980
  if (bad) {
7981
    if (set!=DECUNCONT) uprv_decContextSetStatus(set, DEC_Invalid_operation);
7982
    if (res!=DECUNRESU && res!=nullptr) {
7983
      uprv_decNumberZero(res);
7984
      res->bits=DECNAN;       /* qNaN  */
7985
      }
7986
    }
7987
  return bad;
7988
  } /* decCheckOperands  */
7989
7990
/* ------------------------------------------------------------------ */
7991
/* decCheckNumber -- check a number                                   */
7992
/*   dn is the number to check                                        */
7993
/*   returns 0 if the number is clean, or 1 otherwise                 */
7994
/*                                                                    */
7995
/* The number is considered valid if it could be a result from some   */
7996
/* operation in some valid context.                                   */
7997
/* ------------------------------------------------------------------ */
7998
static Flag decCheckNumber(const decNumber *dn) {
7999
  const Unit *up;             /* work  */
8000
  uInt maxuint;               /* ..  */
8001
  Int ae, d, digits;          /* ..  */
8002
  Int emin, emax;             /* ..  */
8003
8004
  if (dn==nullptr) {             /* hopeless  */
8005
    #if DECTRACE
8006
    /* this one not DECVERB as standard tests include nullptr  */
8007
    printf("Reference to decNumber is nullptr.\n");
8008
    #endif
8009
    return 1;}
8010
8011
  /* check special values  */
8012
  if (dn->bits & DECSPECIAL) {
8013
    if (dn->exponent!=0) {
8014
      #if DECTRACE || DECVERB
8015
      printf("Exponent %ld (not 0) for a special value [%02x].\n",
8016
             (LI)dn->exponent, dn->bits);
8017
      #endif
8018
      return 1;}
8019
8020
    /* 2003.09.08: NaNs may now have coefficients, so next tests Inf only  */
8021
    if (decNumberIsInfinite(dn)) {
8022
      if (dn->digits!=1) {
8023
        #if DECTRACE || DECVERB
8024
        printf("Digits %ld (not 1) for an infinity.\n", (LI)dn->digits);
8025
        #endif
8026
        return 1;}
8027
      if (*dn->lsu!=0) {
8028
        #if DECTRACE || DECVERB
8029
        printf("LSU %ld (not 0) for an infinity.\n", (LI)*dn->lsu);
8030
        #endif
8031
        decDumpAr('I', dn->lsu, D2U(dn->digits));
8032
        return 1;}
8033
      } /* Inf  */
8034
    /* 2002.12.26: negative NaNs can now appear through proposed IEEE  */
8035
    /*             concrete formats (decimal64, etc.).  */
8036
    return 0;
8037
    }
8038
8039
  /* check the coefficient  */
8040
  if (dn->digits<1 || dn->digits>DECNUMMAXP) {
8041
    #if DECTRACE || DECVERB
8042
    printf("Digits %ld in number.\n", (LI)dn->digits);
8043
    #endif
8044
    return 1;}
8045
8046
  d=dn->digits;
8047
8048
  for (up=dn->lsu; d>0; up++) {
8049
    if (d>DECDPUN) maxuint=DECDPUNMAX;
8050
     else {                   /* reached the msu  */
8051
      maxuint=powers[d]-1;
8052
      if (dn->digits>1 && *up<powers[d-1]) {
8053
        #if DECTRACE || DECVERB
8054
        printf("Leading 0 in number.\n");
8055
        uprv_decNumberShow(dn);
8056
        #endif
8057
        return 1;}
8058
      }
8059
    if (*up>maxuint) {
8060
      #if DECTRACE || DECVERB
8061
      printf("Bad Unit [%08lx] in %ld-digit number at offset %ld [maxuint %ld].\n",
8062
              (LI)*up, (LI)dn->digits, (LI)(up-dn->lsu), (LI)maxuint);
8063
      #endif
8064
      return 1;}
8065
    d-=DECDPUN;
8066
    }
8067
8068
  /* check the exponent.  Note that input operands can have exponents  */
8069
  /* which are out of the set->emin/set->emax and set->digits range  */
8070
  /* (just as they can have more digits than set->digits).  */
8071
  ae=dn->exponent+dn->digits-1;    /* adjusted exponent  */
8072
  emax=DECNUMMAXE;
8073
  emin=DECNUMMINE;
8074
  digits=DECNUMMAXP;
8075
  if (ae<emin-(digits-1)) {
8076
    #if DECTRACE || DECVERB
8077
    printf("Adjusted exponent underflow [%ld].\n", (LI)ae);
8078
    uprv_decNumberShow(dn);
8079
    #endif
8080
    return 1;}
8081
  if (ae>+emax) {
8082
    #if DECTRACE || DECVERB
8083
    printf("Adjusted exponent overflow [%ld].\n", (LI)ae);
8084
    uprv_decNumberShow(dn);
8085
    #endif
8086
    return 1;}
8087
8088
  return 0;              /* it's OK  */
8089
  } /* decCheckNumber  */
8090
8091
/* ------------------------------------------------------------------ */
8092
/* decCheckInexact -- check a normal finite inexact result has digits */
8093
/*   dn is the number to check                                        */
8094
/*   set is the context (for status and precision)                    */
8095
/*   sets Invalid operation, etc., if some digits are missing         */
8096
/* [this check is not made for DECSUBSET compilation or when          */
8097
/* subnormal is not set]                                              */
8098
/* ------------------------------------------------------------------ */
8099
static void decCheckInexact(const decNumber *dn, decContext *set) {
8100
  #if !DECSUBSET && DECEXTFLAG
8101
    if ((set->status & (DEC_Inexact|DEC_Subnormal))==DEC_Inexact
8102
     && (set->digits!=dn->digits) && !(dn->bits & DECSPECIAL)) {
8103
      #if DECTRACE || DECVERB
8104
      printf("Insufficient digits [%ld] on normal Inexact result.\n",
8105
             (LI)dn->digits);
8106
      uprv_decNumberShow(dn);
8107
      #endif
8108
      uprv_decContextSetStatus(set, DEC_Invalid_operation);
8109
      }
8110
  #else
8111
    /* next is a noop for quiet compiler  */
8112
    if (dn!=nullptr && dn->digits==0) set->status|=DEC_Invalid_operation;
8113
  #endif
8114
  return;
8115
  } /* decCheckInexact  */
8116
#endif
8117
8118
#if DECALLOC
8119
#undef malloc
8120
#undef free
8121
/* ------------------------------------------------------------------ */
8122
/* decMalloc -- accountable allocation routine                        */
8123
/*   n is the number of bytes to allocate                             */
8124
/*                                                                    */
8125
/* Semantics is the same as the stdlib malloc routine, but bytes      */
8126
/* allocated are accounted for globally, and corruption fences are    */
8127
/* added before and after the 'actual' storage.                       */
8128
/* ------------------------------------------------------------------ */
8129
/* This routine allocates storage with an extra twelve bytes; 8 are   */
8130
/* at the start and hold:                                             */
8131
/*   0-3 the original length requested                                */
8132
/*   4-7 buffer corruption detection fence (DECFENCE, x4)             */
8133
/* The 4 bytes at the end also hold a corruption fence (DECFENCE, x4) */
8134
/* ------------------------------------------------------------------ */
8135
static void *decMalloc(size_t n) {
8136
  uInt  size=n+12;                 /* true size  */
8137
  void  *alloc;                    /* -> allocated storage  */
8138
  uByte *b, *b0;                   /* work  */
8139
  uInt  uiwork;                    /* for macros  */
8140
8141
  alloc=malloc(size);              /* -> allocated storage  */
8142
  if (alloc==nullptr) return nullptr;    /* out of strorage  */
8143
  b0=(uByte *)alloc;               /* as bytes  */
8144
  decAllocBytes+=n;                /* account for storage  */
8145
  UBFROMUI(alloc, n);              /* save n  */
8146
  /* printf(" alloc ++ dAB: %ld (%ld)\n", (LI)decAllocBytes, (LI)n);  */
8147
  for (b=b0+4; b<b0+8; b++) *b=DECFENCE;
8148
  for (b=b0+n+8; b<b0+n+12; b++) *b=DECFENCE;
8149
  return b0+8;                     /* -> play area  */
8150
  } /* decMalloc  */
8151
8152
/* ------------------------------------------------------------------ */
8153
/* decFree -- accountable free routine                                */
8154
/*   alloc is the storage to free                                     */
8155
/*                                                                    */
8156
/* Semantics is the same as the stdlib malloc routine, except that    */
8157
/* the global storage accounting is updated and the fences are        */
8158
/* checked to ensure that no routine has written 'out of bounds'.     */
8159
/* ------------------------------------------------------------------ */
8160
/* This routine first checks that the fences have not been corrupted. */
8161
/* It then frees the storage using the 'truw' storage address (that   */
8162
/* is, offset by 8).                                                  */
8163
/* ------------------------------------------------------------------ */
8164
static void decFree(void *alloc) {
8165
  uInt  n;                         /* original length  */
8166
  uByte *b, *b0;                   /* work  */
8167
  uInt  uiwork;                    /* for macros  */
8168
8169
  if (alloc==nullptr) return;         /* allowed; it's a nop  */
8170
  b0=(uByte *)alloc;               /* as bytes  */
8171
  b0-=8;                           /* -> true start of storage  */
8172
  n=UBTOUI(b0);                    /* lift length  */
8173
  for (b=b0+4; b<b0+8; b++) if (*b!=DECFENCE)
8174
    printf("=== Corrupt byte [%02x] at offset %d from %ld ===\n", *b,
8175
           b-b0-8, (LI)b0);
8176
  for (b=b0+n+8; b<b0+n+12; b++) if (*b!=DECFENCE)
8177
    printf("=== Corrupt byte [%02x] at offset +%d from %ld, n=%ld ===\n", *b,
8178
           b-b0-8, (LI)b0, (LI)n);
8179
  free(b0);                        /* drop the storage  */
8180
  decAllocBytes-=n;                /* account for storage  */
8181
  /* printf(" free -- dAB: %d (%d)\n", decAllocBytes, -n);  */
8182
  } /* decFree  */
8183
#define malloc(a) decMalloc(a)
8184
#define free(a) decFree(a)
8185
#endif