Bug Summary

File:root/firefox-clang/intl/icu/source/i18n/decNumber.cpp
Warning:line 4802, column 13
Value stored to 'accunits' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name decNumber.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/config/external/icu/i18n -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/config/external/icu/i18n -resource-dir /usr/lib/llvm-21/lib/clang/21 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -D U_I18N_IMPLEMENTATION -D _LIBCPP_DISABLE_DEPRECATION_WARNINGS -D U_USING_ICU_NAMESPACE=0 -D U_NO_DEFAULT_INCLUDE_UTF_HEADERS=1 -D U_HIDE_OBSOLETE_UTF_OLD_H=1 -D UCONFIG_NO_LEGACY_CONVERSION -D UCONFIG_NO_TRANSLITERATION -D UCONFIG_NO_REGULAR_EXPRESSIONS -D UCONFIG_NO_BREAK_ITERATION -D UCONFIG_NO_IDNA -D UCONFIG_NO_MF2 -D U_CHARSET_IS_UTF8 -D UNISTR_FROM_CHAR_EXPLICIT=explicit -D UNISTR_FROM_STRING_EXPLICIT=explicit -D U_ENABLE_DYLOAD=0 -D U_DEBUG=1 -I /root/firefox-clang/config/external/icu/i18n -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/config/external/icu/i18n -I /root/firefox-clang/intl/icu/source/common -I /root/firefox-clang/mfbt/double-conversion -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-comma -Wno-implicit-const-int-float-conversion -Wno-macro-redefined -Wno-microsoft-include -Wno-tautological-unsigned-enum-zero-compare -Wno-unreachable-code-loop-increment -Wno-unreachable-code-return -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-06-27-100320-3286336-1 -x c++ /root/firefox-clang/intl/icu/source/i18n/decNumber.cpp
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 */
190static const uByteuint8_t d2utable[DECMAXD2U49+1]=D2UTABLE{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17, 18,19,20,21,22,
23,24,25,26,27,28,29,30,31,32, 33,34,35,36,37,38,39,40,41,42,
43,44,45,46,47, 48,49}
;
191
192#define DECVERB1 1 /* set to 1 for verbose DECCHECK */
193#define powersDECPOWERS DECPOWERS /* old internal name */
194
195/* Local constants */
196#define DIVIDE0x80 0x80 /* Divide operators */
197#define REMAINDER0x40 0x40 /* .. */
198#define DIVIDEINT0x20 0x20 /* .. */
199#define REMNEAR0x10 0x10 /* .. */
200#define COMPARE0x01 0x01 /* Compare operators */
201#define COMPMAX0x02 0x02 /* .. */
202#define COMPMIN0x03 0x03 /* .. */
203#define COMPTOTAL0x04 0x04 /* .. */
204#define COMPNAN0x05 0x05 /* .. [NaN processing] */
205#define COMPSIG0x06 0x06 /* .. [signaling COMPARE] */
206#define COMPMAXMAG0x07 0x07 /* .. */
207#define COMPMINMAG0x08 0x08 /* .. */
208
209#define DEC_sNaN0x40000000 0x40000000 /* local status: sNaN signal */
210#define BADINT(int32_t)0x80000000 (Intint32_t)0x80000000 /* most-negative Int; error indicator */
211/* Next two indicate an integer >= 10**6, and its parity (bottom bit) */
212#define BIGEVEN(int32_t)0x80000002 (Intint32_t)0x80000002
213#define BIGODD(int32_t)0x80000003 (Intint32_t)0x80000003
214
215static const Unituint8_t uarrone[1]={1}; /* Unit array of 1, used for incrementing */
216
217/* ------------------------------------------------------------------ */
218/* round-for-reround digits */
219/* ------------------------------------------------------------------ */
220#if 0
221static const uByteuint8_t 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/* ------------------------------------------------------------------ */
227static const uIntuint32_t DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
228 10000000, 100000000, 1000000000};
229
230
231/* Granularity-dependent code */
232#if DECDPUN1<=4
233 #define eIntint32_t Intint32_t /* extended integer */
234 #define ueIntuint32_t uIntuint32_t /* 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 uIntuint32_t multies[]={131073, 26215, 5243, 1049, 210};
239 /* QUOT10 -- macro to return the quotient of unit u divided by 10**n */
240 #define QUOT10(u, n)((((uint32_t)(u)>>(n))*multies[n])>>17) ((((uIntuint32_t)(u)>>(n))*multies[n])>>17)
241#else
242 /* For DECDPUN>4 non-ANSI-89 64-bit types are needed. */
243 #if !DECUSE641
244 #error decNumber.c: DECUSE641 must be 1 when DECDPUN1>4
245 #endif
246 #define eIntint32_t Longint64_t /* extended integer */
247 #define ueIntuint32_t uLonguint64_t /* unsigned extended integer */
248#endif
249
250/* Local routines */
251static decNumber * decAddOp(decNumber *, const decNumber *, const decNumber *,
252 decContext *, uByteuint8_t, uIntuint32_t *);
253static Flaguint8_t decBiStr(const char *, const char *, const char *);
254static uIntuint32_t decCheckMath(const decNumber *, decContext *, uIntuint32_t *);
255static void decApplyRound(decNumber *, decContext *, Intint32_t, uIntuint32_t *);
256static Intint32_t decCompare(const decNumber *lhs, const decNumber *rhs, Flaguint8_t);
257static decNumber * decCompareOp(decNumber *, const decNumber *,
258 const decNumber *, decContext *,
259 Flaguint8_t, uIntuint32_t *);
260static void decCopyFit(decNumber *, const decNumber *, decContext *,
261 Intint32_t *, uIntuint32_t *);
262static decNumber * decDecap(decNumber *, Intint32_t);
263static decNumber * decDivideOp(decNumber *, const decNumber *,
264 const decNumber *, decContext *, Flaguint8_t, uIntuint32_t *);
265static decNumber * decExpOp(decNumber *, const decNumber *,
266 decContext *, uIntuint32_t *);
267static void decFinalize(decNumber *, decContext *, Intint32_t *, uIntuint32_t *);
268static Intint32_t decGetDigits(Unituint8_t *, Intint32_t);
269static Intint32_t decGetInt(const decNumber *);
270static decNumber * decLnOp(decNumber *, const decNumber *,
271 decContext *, uIntuint32_t *);
272static decNumber * decMultiplyOp(decNumber *, const decNumber *,
273 const decNumber *, decContext *,
274 uIntuint32_t *);
275static decNumber * decNaNs(decNumber *, const decNumber *,
276 const decNumber *, decContext *, uIntuint32_t *);
277static decNumber * decQuantizeOp(decNumber *, const decNumber *,
278 const decNumber *, decContext *, Flaguint8_t,
279 uIntuint32_t *);
280static void decReverse(Unituint8_t *, Unituint8_t *);
281static void decSetCoeff(decNumber *, decContext *, const Unituint8_t *,
282 Intint32_t, Intint32_t *, uIntuint32_t *);
283static void decSetMaxValue(decNumber *, decContext *);
284static void decSetOverflow(decNumber *, decContext *, uIntuint32_t *);
285static void decSetSubnormal(decNumber *, decContext *, Intint32_t *, uIntuint32_t *);
286static Intint32_t decShiftToLeast(Unituint8_t *, Intint32_t, Intint32_t);
287static Intint32_t decShiftToMost(Unituint8_t *, Intint32_t, Intint32_t);
288static void decStatus(decNumber *, uIntuint32_t, decContext *);
289static void decToString(const decNumber *, char[], Flaguint8_t);
290static decNumber * decTrim(decNumber *, decContext *, Flaguint8_t, Flaguint8_t, Intint32_t *);
291static Intint32_t decUnitAddSub(const Unituint8_t *, Intint32_t, const Unituint8_t *, Intint32_t, Intint32_t,
292 Unituint8_t *, Intint32_t);
293static Intint32_t decUnitCompare(const Unituint8_t *, Intint32_t, const Unituint8_t *, Intint32_t, Intint32_t);
294
295#if !DECSUBSET0
296/* decFinish == decFinalize when no subset arithmetic needed */
297#define decFinish(a,b,c,d)decFinalize(a,b,c,d) decFinalize(a,b,c,d)
298#else
299static void decFinish(decNumber *, decContext *, Int *, uInt *)decFinalize(decNumber *,decContext *,int32_t *,uint32_t *);
300static decNumber * decRoundOperand(const decNumber *, decContext *, uIntuint32_t *);
301#endif
302
303/* Local macros */
304/* masked special-values bits */
305#define SPECIALARG(rhs->bits & (0x40|0x20|0x10)) (rhs->bits & DECSPECIAL(0x40|0x20|0x10))
306#define SPECIALARGS((lhs->bits | rhs->bits) & (0x40|0x20|0x10)) ((lhs->bits | rhs->bits) & DECSPECIAL(0x40|0x20|0x10))
307
308/* For use in ICU */
309#define malloc(a)uprv_malloc_77(a) uprv_mallocuprv_malloc_77(a)
310#define free(a)uprv_free_77(a) uprv_freeuprv_free_77(a)
311
312/* Diagnostic macros, etc. */
313#if DECALLOC0
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)uprv_malloc_77(a) decMalloc(a)
318#define free(a)uprv_free_77(a) decFree(a)
319#define DECFENCE 0x5a /* corruption detector */
320/* 'Our' malloc and free: */
321static void *decMalloc(size_t);
322static void decFree(void *);
323uIntuint32_t 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 DECCHECK0
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))
343static Flaguint8_t decCheckOperands(decNumber *, const decNumber *,
344 const decNumber *, decContext *);
345static Flaguint8_t decCheckNumber(const decNumber *);
346static void decCheckInexact(const decNumber *, decContext *);
347#endif
348
349#if DECTRACE0 || DECCHECK0
350/* Optional trace/debugging routines (may or may not be used) */
351void decNumberShow(const decNumber *); /* displays the components of a number */
352static void decDumpAr(char, const Unituint8_t *, Intint32_t);
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/* ------------------------------------------------------------------ */
368U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberFromInt32uprv_decNumberFromInt32_77(decNumber *dn, Intint32_t in) {
369 uIntuint32_t unsig;
370 if (in>=0) unsig=in;
371 else { /* negative (possibly BADINT) */
372 if (in==BADINT(int32_t)0x80000000) unsig=(uIntuint32_t)1073741824*2; /* special case */
373 else unsig=-in; /* invert */
374 }
375 /* in is now positive */
376 uprv_decNumberFromUInt32uprv_decNumberFromUInt32_77(dn, unsig);
377 if (in<0) dn->bits=DECNEG0x80; /* sign needed */
378 return dn;
379 } /* decNumberFromInt32 */
380
381U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberFromUInt32uprv_decNumberFromUInt32_77(decNumber *dn, uIntuint32_t uin) {
382 Unituint8_t *up; /* work pointer */
383 uprv_decNumberZerouprv_decNumberZero_77(dn); /* clean */
384 if (uin==0) return dn; /* [or decGetDigits bad call] */
385 for (up=dn->lsu; uin>0; up++) {
386 *up=(Unituint8_t)(uin%(DECDPUNMAX9+1));
387 uin=uin/(DECDPUNMAX9+1);
388 }
389 dn->digits=decGetDigits(dn->lsu, static_cast<int32_t>(up - dn->lsu));
390 return dn;
391 } /* 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/* ------------------------------------------------------------------ */
403U_CAPIextern "C" Intint32_t U_EXPORT2 uprv_decNumberToInt32uprv_decNumberToInt32_77(const decNumber *dn, decContext *set) {
404 #if DECCHECK0
405 if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
406 #endif
407
408 /* special or too many digits, or bad exponent */
409 if (dn->bits&DECSPECIAL(0x40|0x20|0x10) || dn->digits>10 || dn->exponent!=0) ; /* bad */
410 else { /* is a finite integer with 10 or fewer digits */
411 Intint32_t d; /* work */
412 const Unituint8_t *up; /* .. */
413 uIntuint32_t hi=0, lo; /* .. */
414 up=dn->lsu; /* -> lsu */
415 lo=*up; /* get 1 to 9 digits */
416 #if DECDPUN1>1 /* split to higher */
417 hi=lo/10;
418 lo=lo%10;
419 #endif
420 up++;
421 /* collect remaining Units, if any, into hi */
422 for (d=DECDPUN1; d<dn->digits; up++, d+=DECDPUN1) hi+=*up*powersDECPOWERS[d-1];
423 /* now low has the lsd, hi the remainder */
424 if (hi>214748364 || (hi==214748364 && lo>7)) { /* out of range? */
425 /* most-negative is a reprieve */
426 if (dn->bits&DECNEG0x80 && hi==214748364 && lo==8) return 0x80000000;
427 /* bad -- drop through */
428 }
429 else { /* in-range always */
430 Intint32_t i=X10(hi)(((hi)<<1)+((hi)<<3))+lo;
431 if (dn->bits&DECNEG0x80) return -i;
432 return i;
433 }
434 } /* integer */
435 uprv_decContextSetStatusuprv_decContextSetStatus_77(set, DEC_Invalid_operation0x00000080); /* [may not return] */
436 return 0;
437 } /* decNumberToInt32 */
438
439U_CAPIextern "C" uIntuint32_t U_EXPORT2 uprv_decNumberToUInt32uprv_decNumberToUInt32_77(const decNumber *dn, decContext *set) {
440 #if DECCHECK0
441 if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
442 #endif
443 /* special or too many digits, or bad exponent, or negative (<0) */
444 if (dn->bits&DECSPECIAL(0x40|0x20|0x10) || dn->digits>10 || dn->exponent!=0
445 || (dn->bits&DECNEG0x80 && !ISZERO(dn)(*(dn)->lsu==0 && (dn)->digits==1 && ((
(dn)->bits&(0x40|0x20|0x10))==0))
)); /* bad */
446 else { /* is a finite integer with 10 or fewer digits */
447 Intint32_t d; /* work */
448 const Unituint8_t *up; /* .. */
449 uIntuint32_t hi=0, lo; /* .. */
450 up=dn->lsu; /* -> lsu */
451 lo=*up; /* get 1 to 9 digits */
452 #if DECDPUN1>1 /* split to higher */
453 hi=lo/10;
454 lo=lo%10;
455 #endif
456 up++;
457 /* collect remaining Units, if any, into hi */
458 for (d=DECDPUN1; d<dn->digits; up++, d+=DECDPUN1) hi+=*up*powersDECPOWERS[d-1];
459
460 /* now low has the lsd, hi the remainder */
461 if (hi>429496729 || (hi==429496729 && lo>5)) ; /* no reprieve possible */
462 else return X10(hi)(((hi)<<1)+((hi)<<3))+lo;
463 } /* integer */
464 uprv_decContextSetStatusuprv_decContextSetStatus_77(set, DEC_Invalid_operation0x00000080); /* [may not return] */
465 return 0;
466 } /* 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/* ------------------------------------------------------------------ */
482U_CAPIextern "C" char * U_EXPORT2 uprv_decNumberToStringuprv_decNumberToString_77(const decNumber *dn, char *string){
483 decToString(dn, string, 0);
484 return string;
485 } /* DecNumberToString */
486
487U_CAPIextern "C" char * U_EXPORT2 uprv_decNumberToEngStringuprv_decNumberToEngString_77(const decNumber *dn, char *string){
488 decToString(dn, string, 1);
489 return string;
490 } /* 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/* ------------------------------------------------------------------ */
512U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberFromStringuprv_decNumberFromString_77(decNumber *dn, const char chars[],
513 decContext *set) {
514 Intint32_t exponent=0; /* working exponent [assume 0] */
515 uByteuint8_t bits=0; /* working flags [assume +ve] */
516 Unituint8_t *res; /* where result will be built */
517 Unituint8_t resbuff[SD2U(DECBUFFER+9)(((36 +9)+1 -1)/1)];/* local buffer in case need temporary */
518 /* [+9 allows for ln() constants] */
519 Unituint8_t *allocres=nullptr; /* -> allocated result, iff allocated */
520 Intint32_t d=0; /* count of digits found in decimal part */
521 const char *dotchar=nullptr; /* where dot was found */
522 const char *cfirst=chars; /* -> first character of decimal part */
523 const char *last=nullptr; /* -> last digit of decimal part */
524 const char *c; /* work */
525 Unituint8_t *up; /* .. */
526 #if DECDPUN1>1
527 Intint32_t cut, out; /* .. */
528 #endif
529 Intint32_t residue; /* rounding residue */
530 uIntuint32_t status=0; /* error code */
531
532 #if DECCHECK0
533 if (decCheckOperands(DECUNRESU, DECUNUSED, DECUNUSED, set))
534 return uprv_decNumberZerouprv_decNumberZero_77(dn);
535 #endif
536
537 do { /* status & malloc protection */
538 for (c=chars;; c++) { /* -> input character */
539 if (*c>='0' && *c<='9') { /* test for Arabic digit */
540 last=c;
541 d++; /* count of real digits */
542 continue; /* still in decimal part */
543 }
544 if (*c=='.' && dotchar==nullptr) { /* first '.' */
545 dotchar=c; /* record offset into decimal part */
546 if (c==cfirst) cfirst++; /* first digit must follow */
547 continue;}
548 if (c==chars) { /* first in string... */
549 if (*c=='-') { /* valid - sign */
550 cfirst++;
551 bits=DECNEG0x80;
552 continue;}
553 if (*c=='+') { /* valid + sign */
554 cfirst++;
555 continue;}
556 }
557 /* *c is not a digit, or a valid +, -, or '.' */
558 break;
559 } /* c */
560
561 if (last==nullptr) { /* no digits yet */
562 status=DEC_Conversion_syntax0x00000001;/* assume the worst */
563 if (*c=='\0') break; /* and no more to come... */
564 #if DECSUBSET0
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 if (dotchar!=nullptr) break; /* .. unless had a dot */
570 uprv_decNumberZerouprv_decNumberZero_77(dn); /* be optimistic */
571 if (decBiStr(c, "infinity", "INFINITY")
572 || decBiStr(c, "inf", "INF")) {
573 dn->bits=bits | DECINF0x40;
574 status=0; /* is OK */
575 break; /* all done */
576 }
577 /* a NaN expected */
578 /* 2003.09.10 NaNs are now permitted to have a sign */
579 dn->bits=bits | DECNAN0x20; /* assume simple NaN */
580 if (*c=='s' || *c=='S') { /* looks like an sNaN */
581 c++;
582 dn->bits=bits | DECSNAN0x10;
583 }
584 if (*c!='n' && *c!='N') break; /* check caseless "NaN" */
585 c++;
586 if (*c!='a' && *c!='A') break; /* .. */
587 c++;
588 if (*c!='n' && *c!='N') break; /* .. */
589 c++;
590 /* now either nothing, or nnnn payload, expected */
591 /* -> start of integer and skip leading 0s [including plain 0] */
592 for (cfirst=c; *cfirst=='0';) cfirst++;
593 if (*cfirst=='\0') { /* "NaN" or "sNaN", maybe with all 0s */
594 status=0; /* it's good */
595 break; /* .. */
596 }
597 /* something other than 0s; setup last and d as usual [no dots] */
598 for (c=cfirst;; c++, d++) {
599 if (*c<'0' || *c>'9') break; /* test for Arabic digit */
600 last=c;
601 }
602 if (*c!='\0') break; /* not all digits */
603 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 if (set->clamp) break;
607 if (d>set->digits) break;
608 } /* too many digits? */
609 /* good; drop through to convert the integer to coefficient */
610 status=0; /* syntax is OK */
611 bits=dn->bits; /* for copy-back */
612 } /* last==nullptr */
613
614 else if (*c!='\0') { /* more to process... */
615 /* had some digits; exponent is only valid sequence now */
616 Flaguint8_t nege; /* 1=negative exponent */
617 const char *firstexp; /* -> first significant exponent digit */
618 status=DEC_Conversion_syntax0x00000001;/* assume the worst */
619 if (*c!='e' && *c!='E') break;
620 /* Found 'e' or 'E' -- now process explicit exponent */
621 /* 1998.07.11: sign no longer required */
622 nege=0;
623 c++; /* to (possible) sign */
624 if (*c=='-') {nege=1; c++;}
625 else if (*c=='+') c++;
626 if (*c=='\0') break;
627
628 for (; *c=='0' && *(c+1)!='\0';) c++; /* strip insignificant zeros */
629 firstexp=c; /* save exponent digit place */
630 uIntuint32_t uexponent = 0; /* Avoid undefined behavior on signed int overflow */
631 for (; ;c++) {
632 if (*c<'0' || *c>'9') break; /* not a digit */
633 uexponent=X10(uexponent)(((uexponent)<<1)+((uexponent)<<3))+(uIntuint32_t)*c-(uIntuint32_t)'0';
634 } /* c */
635 exponent = (Intint32_t)uexponent;
636 /* if not now on a '\0', *c must not be a digit */
637 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 if (c>=firstexp+9+1) {
643 if (c>firstexp+9+1 || *firstexp>'1') exponent=DECNUMMAXE999999999*2;
644 /* [up to 1999999999 is OK, for example 1E-1000000998] */
645 }
646 if (nege) exponent=-exponent; /* was negative */
647 status=0; /* is OK */
648 } /* 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 if (*cfirst=='0') { /* [cfirst has stepped over .] */
655 for (c=cfirst; c<last; c++, cfirst++) {
656 if (*c=='.') continue; /* ignore dots */
657 if (*c!='0') break; /* non-zero found */
658 d--; /* 0 stripped */
659 } /* c */
660 #if DECSUBSET0
661 /* make a rapid exit for easy zeros if !extended */
662 if (*cfirst=='0' && !set->extended) {
663 uprv_decNumberZerouprv_decNumberZero_77(dn); /* clean result */
664 break; /* [could be return] */
665 }
666 #endif
667 } /* at least one leading 0 */
668
669 /* Handle decimal point... */
670 if (dotchar!=nullptr && dotchar<last) /* non-trailing '.' found? */
671 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 if (d<=set->digits) res=dn->lsu; /* fits into supplied decNumber */
677 else { /* rounding needed */
678 Intint32_t needbytes=D2U(d)((d)<=49?d2utable[d]:((d)+1 -1)/1)*sizeof(Unituint8_t);/* bytes needed */
679 res=resbuff; /* assume use local buffer */
680 if (needbytes>(Intint32_t)sizeof(resbuff)) { /* too big for local */
681 allocres=(Unituint8_t *)malloc(needbytes)uprv_malloc_77(needbytes);
682 if (allocres==nullptr) {status|=DEC_Insufficient_storage0x00000010; break;}
683 res=allocres;
684 }
685 }
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 DECDPUN1>1
691 out=0; /* accumulator */
692 up=res+D2U(d)((d)<=49?d2utable[d]:((d)+1 -1)/1)-1; /* -> msu */
693 cut=d-(up-res)*DECDPUN1; /* 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)(((out)<<1)+((out)<<3))+(Intint32_t)*c-(Intint32_t)'0';
697 if (c==last) break; /* done [never get to trailing '.'] */
698 cut--;
699 if (cut>0) continue; /* more for this unit */
700 *up=(Unituint8_t)out; /* write unit */
701 up--; /* prepare for unit below.. */
702 cut=DECDPUN1; /* .. */
703 out=0; /* .. */
704 } /* c */
705 *up=(Unituint8_t)out; /* write lsu */
706
707 #else
708 /* DECDPUN==1 */
709 up=res; /* -> lsu */
710 for (c=last; c>=cfirst; c--) { /* over each character, from least */
711 if (*c=='.') continue; /* ignore . [don't step up] */
712 *up=(Unituint8_t)((Intint32_t)*c-(Intint32_t)'0');
713 up++;
714 } /* c */
715 #endif
716
717 dn->bits=bits;
718 dn->exponent=exponent;
719 dn->digits=d;
720
721 /* if not in number (too long) shorten into the number */
722 if (d>set->digits) {
723 residue=0;
724 decSetCoeff(dn, set, res, d, &residue, &status);
725 /* always check for overflow or subnormal and round as needed */
726 decFinalize(dn, set, &residue, &status);
727 }
728 else { /* no rounding, but may still have overflow or subnormal */
729 /* [these tests are just for performance; finalize repeats them] */
730 if ((dn->exponent-1<set->emin-dn->digits)
731 || (dn->exponent-1>set->emax-set->digits)) {
732 residue=0;
733 decFinalize(dn, set, &residue, &status);
734 }
735 }
736 /* decNumberShow(dn); */
737 } while(0); /* [for break] */
738
739 if (allocres!=nullptr) free(allocres)uprv_free_77(allocres); /* drop any storage used */
740 if (status!=0) decStatus(dn, status, set);
741 return dn;
742 } /* 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/* ------------------------------------------------------------------ */
763U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberAbsuprv_decNumberAbs_77(decNumber *res, const decNumber *rhs,
764 decContext *set) {
765 decNumber dzero; /* for 0 */
766 uIntuint32_t status=0; /* accumulator */
767
768 #if DECCHECK0
769 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
770 #endif
771
772 uprv_decNumberZerouprv_decNumberZero_77(&dzero); /* set 0 */
773 dzero.exponent=rhs->exponent; /* [no coefficient expansion] */
774 decAddOp(res, &dzero, rhs, set, (uByteuint8_t)(rhs->bits & DECNEG0x80), &status);
775 if (status!=0) decStatus(res, status, set);
776 #if DECCHECK0
777 decCheckInexact(res, set);
778 #endif
779 return res;
780 } /* 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 */
795U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberAdduprv_decNumberAdd_77(decNumber *res, const decNumber *lhs,
796 const decNumber *rhs, decContext *set) {
797 uIntuint32_t status=0; /* accumulator */
798 decAddOp(res, lhs, rhs, set, 0, &status);
799 if (status!=0) decStatus(res, status, set);
800 #if DECCHECK0
801 decCheckInexact(res, set);
802 #endif
803 return res;
804 } /* 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/* ------------------------------------------------------------------ */
821U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberAnduprv_decNumberAnd_77(decNumber *res, const decNumber *lhs,
822 const decNumber *rhs, decContext *set) {
823 const Unituint8_t *ua, *ub; /* -> operands */
824 const Unituint8_t *msua, *msub; /* -> operand msus */
825 Unituint8_t *uc, *msuc; /* -> result and its msu */
826 Intint32_t msudigs; /* digits in res msu */
827 #if DECCHECK0
828 if (decCheckOperands(res, lhs, rhs, set)) return res;
829 #endif
830
831 if (lhs->exponent!=0 || decNumberIsSpecial(lhs)(((lhs)->bits&(0x40|0x20|0x10))!=0) || decNumberIsNegative(lhs)(((lhs)->bits&0x80)!=0)
832 || rhs->exponent!=0 || decNumberIsSpecial(rhs)(((rhs)->bits&(0x40|0x20|0x10))!=0) || decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) {
833 decStatus(res, DEC_Invalid_operation0x00000080, set);
834 return res;
835 }
836
837 /* operands are valid */
838 ua=lhs->lsu; /* bottom-up */
839 ub=rhs->lsu; /* .. */
840 uc=res->lsu; /* .. */
841 msua=ua+D2U(lhs->digits)((lhs->digits)<=49?d2utable[lhs->digits]:((lhs->digits
)+1 -1)/1)
-1; /* -> msu of lhs */
842 msub=ub+D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
-1; /* -> msu of rhs */
843 msuc=uc+D2U(set->digits)((set->digits)<=49?d2utable[set->digits]:((set->digits
)+1 -1)/1)
-1; /* -> msu of result */
844 msudigs=MSUDIGITS(set->digits)((set->digits)-(((set->digits)<=49?d2utable[set->
digits]:((set->digits)+1 -1)/1)-1)*1)
; /* [faster than remainder] */
845 for (; uc<=msuc; ua++, ub++, uc++) { /* Unit loop */
846 Unituint8_t a, b; /* extract units */
847 if (ua>msua) a=0;
848 else a=*ua;
849 if (ub>msub) b=0;
850 else b=*ub;
851 *uc=0; /* can now write back */
852 if (a|b) { /* maybe 1 bits to examine */
853 Intint32_t i, j;
854 *uc=0; /* can now write back */
855 /* This loop could be unrolled and/or use BIN2BCD tables */
856 for (i=0; i<DECDPUN1; i++) {
857 if (a&b&1) *uc=*uc+(Unituint8_t)powersDECPOWERS[i]; /* effect AND */
858 j=a%10;
859 a=a/10;
860 j|=b%10;
861 b=b/10;
862 if (j>1) {
863 decStatus(res, DEC_Invalid_operation0x00000080, set);
864 return res;
865 }
866 if (uc==msuc && i==msudigs-1) break; /* just did final digit */
867 } /* each digit */
868 } /* both OK */
869 } /* each unit */
870 /* [here uc-1 is the msu of the result] */
871 res->digits=decGetDigits(res->lsu, static_cast<int32_t>(uc - res->lsu));
872 res->exponent=0; /* integer */
873 res->bits=0; /* sign=0 */
874 return res; /* [no status to set] */
875 } /* 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/* ------------------------------------------------------------------ */
889U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberCompareuprv_decNumberCompare_77(decNumber *res, const decNumber *lhs,
890 const decNumber *rhs, decContext *set) {
891 uIntuint32_t status=0; /* accumulator */
892 decCompareOp(res, lhs, rhs, set, COMPARE0x01, &status);
893 if (status!=0) decStatus(res, status, set);
894 return res;
895 } /* 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/* ------------------------------------------------------------------ */
909U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberCompareSignaluprv_decNumberCompareSignal_77(decNumber *res, const decNumber *lhs,
910 const decNumber *rhs, decContext *set) {
911 uIntuint32_t status=0; /* accumulator */
912 decCompareOp(res, lhs, rhs, set, COMPSIG0x06, &status);
913 if (status!=0) decStatus(res, status, set);
914 return res;
915 } /* 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/* ------------------------------------------------------------------ */
930U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberCompareTotaluprv_decNumberCompareTotal_77(decNumber *res, const decNumber *lhs,
931 const decNumber *rhs, decContext *set) {
932 uIntuint32_t status=0; /* accumulator */
933 decCompareOp(res, lhs, rhs, set, COMPTOTAL0x04, &status);
934 if (status!=0) decStatus(res, status, set);
935 return res;
936 } /* 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/* ------------------------------------------------------------------ */
951U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberCompareTotalMaguprv_decNumberCompareTotalMag_77(decNumber *res, const decNumber *lhs,
952 const decNumber *rhs, decContext *set) {
953 uIntuint32_t status=0; /* accumulator */
954 uIntuint32_t needbytes; /* for space calculations */
955 decNumber bufa[D2N(DECBUFFER+1)(((((((36 +1)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)*
2-1)/sizeof(decNumber))
];/* +1 in case DECBUFFER=0 */
956 decNumber *allocbufa=nullptr; /* -> allocated bufa, iff allocated */
957 decNumber bufb[D2N(DECBUFFER+1)(((((((36 +1)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)*
2-1)/sizeof(decNumber))
];
958 decNumber *allocbufb=nullptr; /* -> allocated bufb, iff allocated */
959 decNumber *a, *b; /* temporary pointers */
960
961 #if DECCHECK0
962 if (decCheckOperands(res, lhs, rhs, set)) return res;
963 #endif
964
965 do { /* protect allocated storage */
966 /* if either is negative, take a copy and absolute */
967 if (decNumberIsNegative(lhs)(((lhs)->bits&0x80)!=0)) { /* lhs<0 */
968 a=bufa;
969 needbytes=sizeof(decNumber)+(D2U(lhs->digits)((lhs->digits)<=49?d2utable[lhs->digits]:((lhs->digits
)+1 -1)/1)
-1)*sizeof(Unituint8_t);
970 if (needbytes>sizeof(bufa)) { /* need malloc space */
971 allocbufa=(decNumber *)malloc(needbytes)uprv_malloc_77(needbytes);
972 if (allocbufa==nullptr) { /* hopeless -- abandon */
973 status|=DEC_Insufficient_storage0x00000010;
974 break;}
975 a=allocbufa; /* use the allocated space */
976 }
977 uprv_decNumberCopyuprv_decNumberCopy_77(a, lhs); /* copy content */
978 a->bits&=~DECNEG0x80; /* .. and clear the sign */
979 lhs=a; /* use copy from here on */
980 }
981 if (decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) { /* rhs<0 */
982 b=bufb;
983 needbytes=sizeof(decNumber)+(D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
-1)*sizeof(Unituint8_t);
984 if (needbytes>sizeof(bufb)) { /* need malloc space */
985 allocbufb=(decNumber *)malloc(needbytes)uprv_malloc_77(needbytes);
986 if (allocbufb==nullptr) { /* hopeless -- abandon */
987 status|=DEC_Insufficient_storage0x00000010;
988 break;}
989 b=allocbufb; /* use the allocated space */
990 }
991 uprv_decNumberCopyuprv_decNumberCopy_77(b, rhs); /* copy content */
992 b->bits&=~DECNEG0x80; /* .. and clear the sign */
993 rhs=b; /* use copy from here on */
994 }
995 decCompareOp(res, lhs, rhs, set, COMPTOTAL0x04, &status);
996 } while(0); /* end protected */
997
998 if (allocbufa!=nullptr) free(allocbufa)uprv_free_77(allocbufa); /* drop any storage used */
999 if (allocbufb!=nullptr) free(allocbufb)uprv_free_77(allocbufb); /* .. */
1000 if (status!=0) decStatus(res, status, set);
1001 return res;
1002 } /* 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/* ------------------------------------------------------------------ */
1016U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberDivideuprv_decNumberDivide_77(decNumber *res, const decNumber *lhs,
1017 const decNumber *rhs, decContext *set) {
1018 uIntuint32_t status=0; /* accumulator */
1019 decDivideOp(res, lhs, rhs, set, DIVIDE0x80, &status);
1020 if (status!=0) decStatus(res, status, set);
1021 #if DECCHECK0
1022 decCheckInexact(res, set);
1023 #endif
1024 return res;
1025 } /* 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/* ------------------------------------------------------------------ */
1039U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberDivideIntegeruprv_decNumberDivideInteger_77(decNumber *res, const decNumber *lhs,
1040 const decNumber *rhs, decContext *set) {
1041 uIntuint32_t status=0; /* accumulator */
1042 decDivideOp(res, lhs, rhs, set, DIVIDEINT0x20, &status);
1043 if (status!=0) decStatus(res, status, set);
1044 return res;
1045 } /* 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/* ------------------------------------------------------------------ */
1072U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberExpuprv_decNumberExp_77(decNumber *res, const decNumber *rhs,
1073 decContext *set) {
1074 uIntuint32_t status=0; /* accumulator */
1075 #if DECSUBSET0
1076 decNumber *allocrhs=nullptr; /* non-nullptr if rounded rhs allocated */
1077 #endif
1078
1079 #if DECCHECK0
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 if (!decCheckMath(rhs, set, &status)) do { /* protect allocation */
1088 #if DECSUBSET0
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 decExpOp(res, rhs, set, &status);
1099 } while(0); /* end protected */
1100
1101 #if DECSUBSET0
1102 if (allocrhs !=nullptr) free(allocrhs)uprv_free_77(allocrhs); /* drop any storage used */
1103 #endif
1104 /* apply significant status */
1105 if (status!=0) decStatus(res, status, set);
1106 #if DECCHECK0
1107 decCheckInexact(res, set);
1108 #endif
1109 return res;
1110 } /* 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/* ------------------------------------------------------------------ */
1128U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberFMAuprv_decNumberFMA_77(decNumber *res, const decNumber *lhs,
1129 const decNumber *rhs, const decNumber *fhs,
1130 decContext *set) {
1131 uIntuint32_t status=0; /* accumulator */
1132 decContext dcmul; /* context for the multiplication */
1133 uIntuint32_t needbytes; /* for space calculations */
1134 decNumber bufa[D2N(DECBUFFER*2+1)(((((((36*2+1)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)
*2-1)/sizeof(decNumber))
];
1135 decNumber *allocbufa=nullptr; /* -> allocated bufa, iff allocated */
1136 decNumber *acc; /* accumulator pointer */
1137 decNumber dzero; /* work */
1138
1139 #if DECCHECK0
1140 if (decCheckOperands(res, lhs, rhs, set)) return res;
1141 if (decCheckOperands(res, fhs, DECUNUSED, set)) return res;
1142 #endif
1143
1144 do { /* protect allocated storage */
1145 #if DECSUBSET0
1146 if (!set->extended) { /* [undefined if subset] */
1147 status|=DEC_Invalid_operation0x00000080;
1148 break;}
1149 #endif
1150 /* Check math restrictions [these ensure no overflow or underflow] */
1151 if ((!decNumberIsSpecial(lhs)(((lhs)->bits&(0x40|0x20|0x10))!=0) && decCheckMath(lhs, set, &status))
1152 || (!decNumberIsSpecial(rhs)(((rhs)->bits&(0x40|0x20|0x10))!=0) && decCheckMath(rhs, set, &status))
1153 || (!decNumberIsSpecial(fhs)(((fhs)->bits&(0x40|0x20|0x10))!=0) && decCheckMath(fhs, set, &status))) break;
1154 /* set up context for multiply */
1155 dcmul=*set;
1156 dcmul.digits=lhs->digits+rhs->digits; /* just enough */
1157 /* [The above may be an over-estimate for subset arithmetic, but that's OK] */
1158 dcmul.emax=DEC_MAX_EMAX999999999; /* effectively unbounded .. */
1159 dcmul.emin=DEC_MIN_EMIN-999999999; /* [thanks to Math restrictions] */
1160 /* set up decNumber space to receive the result of the multiply */
1161 acc=bufa; /* may fit */
1162 needbytes=sizeof(decNumber)+(D2U(dcmul.digits)((dcmul.digits)<=49?d2utable[dcmul.digits]:((dcmul.digits)
+1 -1)/1)
-1)*sizeof(Unituint8_t);
1163 if (needbytes>sizeof(bufa)) { /* need malloc space */
1164 allocbufa=(decNumber *)malloc(needbytes)uprv_malloc_77(needbytes);
1165 if (allocbufa==nullptr) { /* hopeless -- abandon */
1166 status|=DEC_Insufficient_storage0x00000010;
1167 break;}
1168 acc=allocbufa; /* use the allocated space */
1169 }
1170 /* multiply with extended range and necessary precision */
1171 /*printf("emin=%ld\n", dcmul.emin); */
1172 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 if ((status&DEC_Invalid_operation0x00000080)!=0) {
1180 if (!(status&DEC_sNaN0x40000000)) { /* but be true invalid */
1181 uprv_decNumberZerouprv_decNumberZero_77(res); /* acc not yet set */
1182 res->bits=DECNAN0x20;
1183 break;
1184 }
1185 uprv_decNumberZerouprv_decNumberZero_77(&dzero); /* make 0 (any non-NaN would do) */
1186 fhs=&dzero; /* use that */
1187 }
1188 #if DECCHECK0
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 decAddOp(res, acc, fhs, set, 0, &status);
1195 } while(0); /* end protected */
1196
1197 if (allocbufa!=nullptr) free(allocbufa)uprv_free_77(allocbufa); /* drop any storage used */
1198 if (status!=0) decStatus(res, status, set);
1199 #if DECCHECK0
1200 decCheckInexact(res, set);
1201 #endif
1202 return res;
1203 } /* 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/* ------------------------------------------------------------------ */
1219U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberInvertuprv_decNumberInvert_77(decNumber *res, const decNumber *rhs,
1220 decContext *set) {
1221 const Unituint8_t *ua, *msua; /* -> operand and its msu */
1222 Unituint8_t *uc, *msuc; /* -> result and its msu */
1223 Intint32_t msudigs; /* digits in res msu */
1224 #if DECCHECK0
1225 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1226 #endif
1227
1228 if (rhs->exponent!=0 || decNumberIsSpecial(rhs)(((rhs)->bits&(0x40|0x20|0x10))!=0) || decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) {
1229 decStatus(res, DEC_Invalid_operation0x00000080, set);
1230 return res;
1231 }
1232 /* operand is valid */
1233 ua=rhs->lsu; /* bottom-up */
1234 uc=res->lsu; /* .. */
1235 msua=ua+D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
-1; /* -> msu of rhs */
1236 msuc=uc+D2U(set->digits)((set->digits)<=49?d2utable[set->digits]:((set->digits
)+1 -1)/1)
-1; /* -> msu of result */
1237 msudigs=MSUDIGITS(set->digits)((set->digits)-(((set->digits)<=49?d2utable[set->
digits]:((set->digits)+1 -1)/1)-1)*1)
; /* [faster than remainder] */
1238 for (; uc<=msuc; ua++, uc++) { /* Unit loop */
1239 Unituint8_t a; /* extract unit */
1240 Intint32_t i, j; /* work */
1241 if (ua>msua) a=0;
1242 else a=*ua;
1243 *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 for (i=0; i<DECDPUN1; i++) {
1247 if ((~a)&1) *uc=*uc+(Unituint8_t)powersDECPOWERS[i]; /* effect INVERT */
1248 j=a%10;
1249 a=a/10;
1250 if (j>1) {
1251 decStatus(res, DEC_Invalid_operation0x00000080, set);
1252 return res;
1253 }
1254 if (uc==msuc && i==msudigs-1) break; /* just did final digit */
1255 } /* each digit */
1256 } /* each unit */
1257 /* [here uc-1 is the msu of the result] */
1258 res->digits=decGetDigits(res->lsu, static_cast<int32_t>(uc - res->lsu));
1259 res->exponent=0; /* integer */
1260 res->bits=0; /* sign=0 */
1261 return res; /* [no status to set] */
1262 } /* 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/* ------------------------------------------------------------------ */
1292U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberLnuprv_decNumberLn_77(decNumber *res, const decNumber *rhs,
1293 decContext *set) {
1294 uIntuint32_t status=0; /* accumulator */
1295 #if DECSUBSET0
1296 decNumber *allocrhs=nullptr; /* non-nullptr if rounded rhs allocated */
1297 #endif
1298
1299 #if DECCHECK0
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 if (!decCheckMath(rhs, set, &status)) do { /* protect allocation */
1306 #if DECSUBSET0
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)(*(rhs)->lsu==0 && (rhs)->digits==1 && (
((rhs)->bits&(0x40|0x20|0x10))==0))
) { /* +/- zeros -> error */
1316 status|=DEC_Invalid_operation0x00000080;
1317 break;}
1318 } /* extended=0 */
1319 #endif
1320 decLnOp(res, rhs, set, &status);
1321 } while(0); /* end protected */
1322
1323 #if DECSUBSET0
1324 if (allocrhs !=nullptr) free(allocrhs)uprv_free_77(allocrhs); /* drop any storage used */
1325 #endif
1326 /* apply significant status */
1327 if (status!=0) decStatus(res, status, set);
1328 #if DECCHECK0
1329 decCheckInexact(res, set);
1330 #endif
1331 return res;
1332 } /* 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/* ------------------------------------------------------------------ */
1358U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberLogBuprv_decNumberLogB_77(decNumber *res, const decNumber *rhs,
1359 decContext *set) {
1360 uIntuint32_t status=0; /* accumulator */
1361
1362 #if DECCHECK0
1363 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1364 #endif
1365
1366 /* NaNs as usual; Infinities return +Infinity; 0->oops */
1367 if (decNumberIsNaN(rhs)(((rhs)->bits&(0x20|0x10))!=0)) decNaNs(res, rhs, nullptr, set, &status);
1368 else if (decNumberIsInfinite(rhs)(((rhs)->bits&0x40)!=0)) uprv_decNumberCopyAbsuprv_decNumberCopyAbs_77(res, rhs);
1369 else if (decNumberIsZero(rhs)(*(rhs)->lsu==0 && (rhs)->digits==1 && (
((rhs)->bits&(0x40|0x20|0x10))==0))
) {
1370 uprv_decNumberZerouprv_decNumberZero_77(res); /* prepare for Infinity */
1371 res->bits=DECNEG0x80|DECINF0x40; /* -Infinity */
1372 status|=DEC_Division_by_zero0x00000002; /* as per 754 */
1373 }
1374 else { /* finite non-zero */
1375 Intint32_t ae=rhs->exponent+rhs->digits-1; /* adjusted exponent */
1376 uprv_decNumberFromInt32uprv_decNumberFromInt32_77(res, ae); /* lay it out */
1377 }
1378
1379 if (status!=0) decStatus(res, status, set);
1380 return res;
1381 } /* 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__1) || U_GCC_MAJOR_MINOR(4 * 100 + 2) >= 406
1415#pragma GCC diagnostic push
1416#pragma GCC diagnostic ignored "-Warray-bounds"
1417#endif
1418U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberLog10uprv_decNumberLog10_77(decNumber *res, const decNumber *rhs,
1419 decContext *set) {
1420 uIntuint32_t status=0, ignore=0; /* status accumulators */
1421 uIntuint32_t needbytes; /* for space calculations */
1422 Intint32_t p; /* working precision */
1423 Intint32_t t; /* digits in exponent of A */
1424
1425 /* buffers for a and b working decimals */
1426 /* (adjustment calculator, same size) */
1427 decNumber bufa[D2N(DECBUFFER+2)(((((((36 +2)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)*
2-1)/sizeof(decNumber))
];
1428 decNumber *allocbufa=nullptr; /* -> allocated bufa, iff allocated */
1429 decNumber *a=bufa; /* temporary a */
1430 decNumber bufb[D2N(DECBUFFER+2)(((((((36 +2)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)*
2-1)/sizeof(decNumber))
];
1431 decNumber *allocbufb=nullptr; /* -> allocated bufb, iff allocated */
1432 decNumber *b=bufb; /* temporary b */
1433 decNumber bufw[D2N(10)(((((((10)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)*2-1
)/sizeof(decNumber))
]; /* working 2-10 digit number */
1434 decNumber *w=bufw; /* .. */
1435 #if DECSUBSET0
1436 decNumber *allocrhs=nullptr; /* non-nullptr if rounded rhs allocated */
1437 #endif
1438
1439 decContext aset; /* working context */
1440
1441 #if DECCHECK0
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 if (!decCheckMath(rhs, set, &status)) do { /* protect malloc */
1448 #if DECSUBSET0
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)(*(rhs)->lsu==0 && (rhs)->digits==1 && (
((rhs)->bits&(0x40|0x20|0x10))==0))
) { /* +/- zeros -> error */
1458 status|=DEC_Invalid_operation0x00000080;
1459 break;}
1460 } /* extended=0 */
1461 #endif
1462
1463 uprv_decContextDefaultuprv_decContextDefault_77(&aset, DEC_INIT_DECIMAL6464); /* clean context */
1464
1465 /* handle exact powers of 10; only check if +ve finite */
1466 if (!(rhs->bits&(DECNEG0x80|DECSPECIAL(0x40|0x20|0x10))) && !ISZERO(rhs)(*(rhs)->lsu==0 && (rhs)->digits==1 && (
((rhs)->bits&(0x40|0x20|0x10))==0))
) {
1467 Intint32_t residue=0; /* (no residue) */
1468 uIntuint32_t copystat=0; /* clean status */
1469
1470 /* round to a single digit... */
1471 aset.digits=1;
1472 decCopyFit(w, rhs, &aset, &residue, &copystat); /* copy & shorten */
1473 /* if exact and the digit is 1, rhs is a power of 10 */
1474 if (!(copystat&DEC_Inexact0x00000020) && 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 uprv_decNumberFromInt32uprv_decNumberFromInt32_77(w, w->exponent);
1480 residue=0;
1481 decCopyFit(res, w, set, &residue, &status); /* copy & round */
1482 decFinish(res, set, &residue, &status)decFinalize(res,set,&residue,&status); /* cleanup/set flags */
1483 break;
1484 } /* not a power of 10 */
1485 } /* 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 t=6; /* it can never be >6 */
1492
1493 /* allocate space when needed... */
1494 p=(rhs->digits+t>set->digits?rhs->digits+t:set->digits)+3;
1495 needbytes=sizeof(decNumber)+(D2U(p)((p)<=49?d2utable[p]:((p)+1 -1)/1)-1)*sizeof(Unituint8_t);
1496 if (needbytes>sizeof(bufa)) { /* need malloc space */
1497 allocbufa=(decNumber *)malloc(needbytes)uprv_malloc_77(needbytes);
1498 if (allocbufa==nullptr) { /* hopeless -- abandon */
1499 status|=DEC_Insufficient_storage0x00000010;
1500 break;}
1501 a=allocbufa; /* use the allocated space */
1502 }
1503 aset.digits=p; /* as calculated */
1504 aset.emax=DEC_MAX_MATH999999; /* usual bounds */
1505 aset.emin=-DEC_MAX_MATH999999; /* .. */
1506 aset.clamp=0; /* and no concrete format */
1507 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 if (status&DEC_NaNs(0x00000001 | 0x00000004 | 0x00000008 | 0x00000010 | 0x00000040
| 0x00000080)
&& !(status&DEC_sNaN0x40000000)) break;
1512 if (a->bits&DECSPECIAL(0x40|0x20|0x10) || ISZERO(a)(*(a)->lsu==0 && (a)->digits==1 && (((a
)->bits&(0x40|0x20|0x10))==0))
) {
1513 uprv_decNumberCopyuprv_decNumberCopy_77(res, a); /* [will fit] */
1514 break;}
1515
1516 /* for ln(10) an extra 3 digits of precision are needed */
1517 p=set->digits+3;
1518 needbytes=sizeof(decNumber)+(D2U(p)((p)<=49?d2utable[p]:((p)+1 -1)/1)-1)*sizeof(Unituint8_t);
1519 if (needbytes>sizeof(bufb)) { /* need malloc space */
1520 allocbufb=(decNumber *)malloc(needbytes)uprv_malloc_77(needbytes);
1521 if (allocbufb==nullptr) { /* hopeless -- abandon */
1522 status|=DEC_Insufficient_storage0x00000010;
1523 break;}
1524 b=allocbufb; /* use the allocated space */
1525 }
1526 uprv_decNumberZerouprv_decNumberZero_77(w); /* set up 10... */
1527 #if DECDPUN1==1
1528 w->lsu[1]=1; w->lsu[0]=0; /* .. */
1529 #else
1530 w->lsu[0]=10; /* .. */
1531 #endif
1532 w->digits=2; /* .. */
1533
1534 aset.digits=p;
1535 decLnOp(b, w, &aset, &ignore); /* b=ln(10) */
1536
1537 aset.digits=set->digits; /* for final divide */
1538 decDivideOp(res, a, b, &aset, DIVIDE0x80, &status); /* into result */
1539 } while(0); /* [for break] */
1540
1541 if (allocbufa!=nullptr) free(allocbufa)uprv_free_77(allocbufa); /* drop any storage used */
1542 if (allocbufb!=nullptr) free(allocbufb)uprv_free_77(allocbufb); /* .. */
1543 #if DECSUBSET0
1544 if (allocrhs !=nullptr) free(allocrhs)uprv_free_77(allocrhs); /* .. */
1545 #endif
1546 /* apply significant status */
1547 if (status!=0) decStatus(res, status, set);
1548 #if DECCHECK0
1549 decCheckInexact(res, set);
1550 #endif
1551 return res;
1552 } /* decNumberLog10 */
1553#if defined(__clang__1) || U_GCC_MAJOR_MINOR(4 * 100 + 2) >= 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/* ------------------------------------------------------------------ */
1569U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberMaxuprv_decNumberMax_77(decNumber *res, const decNumber *lhs,
1570 const decNumber *rhs, decContext *set) {
1571 uIntuint32_t status=0; /* accumulator */
1572 decCompareOp(res, lhs, rhs, set, COMPMAX0x02, &status);
1573 if (status!=0) decStatus(res, status, set);
1574 #if DECCHECK0
1575 decCheckInexact(res, set);
1576 #endif
1577 return res;
1578 } /* 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/* ------------------------------------------------------------------ */
1592U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberMaxMaguprv_decNumberMaxMag_77(decNumber *res, const decNumber *lhs,
1593 const decNumber *rhs, decContext *set) {
1594 uIntuint32_t status=0; /* accumulator */
1595 decCompareOp(res, lhs, rhs, set, COMPMAXMAG0x07, &status);
1596 if (status!=0) decStatus(res, status, set);
1597 #if DECCHECK0
1598 decCheckInexact(res, set);
1599 #endif
1600 return res;
1601 } /* 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/* ------------------------------------------------------------------ */
1615U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberMinuprv_decNumberMin_77(decNumber *res, const decNumber *lhs,
1616 const decNumber *rhs, decContext *set) {
1617 uIntuint32_t status=0; /* accumulator */
1618 decCompareOp(res, lhs, rhs, set, COMPMIN0x03, &status);
1619 if (status!=0) decStatus(res, status, set);
1620 #if DECCHECK0
1621 decCheckInexact(res, set);
1622 #endif
1623 return res;
1624 } /* 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/* ------------------------------------------------------------------ */
1638U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberMinMaguprv_decNumberMinMag_77(decNumber *res, const decNumber *lhs,
1639 const decNumber *rhs, decContext *set) {
1640 uIntuint32_t status=0; /* accumulator */
1641 decCompareOp(res, lhs, rhs, set, COMPMINMAG0x08, &status);
1642 if (status!=0) decStatus(res, status, set);
1643 #if DECCHECK0
1644 decCheckInexact(res, set);
1645 #endif
1646 return res;
1647 } /* 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/* ------------------------------------------------------------------ */
1663U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberMinusuprv_decNumberMinus_77(decNumber *res, const decNumber *rhs,
1664 decContext *set) {
1665 decNumber dzero;
1666 uIntuint32_t status=0; /* accumulator */
1667
1668 #if DECCHECK0
1669 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1670 #endif
1671
1672 uprv_decNumberZerouprv_decNumberZero_77(&dzero); /* make 0 */
1673 dzero.exponent=rhs->exponent; /* [no coefficient expansion] */
1674 decAddOp(res, &dzero, rhs, set, DECNEG0x80, &status);
1675 if (status!=0) decStatus(res, status, set);
1676 #if DECCHECK0
1677 decCheckInexact(res, set);
1678 #endif
1679 return res;
1680 } /* 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/* ------------------------------------------------------------------ */
1693U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberNextMinusuprv_decNumberNextMinus_77(decNumber *res, const decNumber *rhs,
1694 decContext *set) {
1695 decNumber dtiny; /* constant */
1696 decContext workset=*set; /* work */
1697 uIntuint32_t status=0; /* accumulator */
1698 #if DECCHECK0
1699 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1700 #endif
1701
1702 /* +Infinity is the special case */
1703 if ((rhs->bits&(DECINF0x40|DECNEG0x80))==DECINF0x40) {
1704 decSetMaxValue(res, set); /* is +ve */
1705 /* there is no status to set */
1706 return res;
1707 }
1708 uprv_decNumberZerouprv_decNumberZero_77(&dtiny); /* start with 0 */
1709 dtiny.lsu[0]=1; /* make number that is .. */
1710 dtiny.exponent=DEC_MIN_EMIN-999999999-1; /* .. smaller than tiniest */
1711 workset.round=DEC_ROUND_FLOOR;
1712 decAddOp(res, rhs, &dtiny, &workset, DECNEG0x80, &status);
1713 status&=DEC_Invalid_operation0x00000080|DEC_sNaN0x40000000; /* only sNaN Invalid please */
1714 if (status!=0) decStatus(res, status, set);
1715 return res;
1716 } /* 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/* ------------------------------------------------------------------ */
1729U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberNextPlusuprv_decNumberNextPlus_77(decNumber *res, const decNumber *rhs,
1730 decContext *set) {
1731 decNumber dtiny; /* constant */
1732 decContext workset=*set; /* work */
1733 uIntuint32_t status=0; /* accumulator */
1734 #if DECCHECK0
1735 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1736 #endif
1737
1738 /* -Infinity is the special case */
1739 if ((rhs->bits&(DECINF0x40|DECNEG0x80))==(DECINF0x40|DECNEG0x80)) {
1740 decSetMaxValue(res, set);
1741 res->bits=DECNEG0x80; /* negative */
1742 /* there is no status to set */
1743 return res;
1744 }
1745 uprv_decNumberZerouprv_decNumberZero_77(&dtiny); /* start with 0 */
1746 dtiny.lsu[0]=1; /* make number that is .. */
1747 dtiny.exponent=DEC_MIN_EMIN-999999999-1; /* .. smaller than tiniest */
1748 workset.round=DEC_ROUND_CEILING;
1749 decAddOp(res, rhs, &dtiny, &workset, 0, &status);
1750 status&=DEC_Invalid_operation0x00000080|DEC_sNaN0x40000000; /* only sNaN Invalid please */
1751 if (status!=0) decStatus(res, status, set);
1752 return res;
1753 } /* 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/* ------------------------------------------------------------------ */
1769U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberNextTowarduprv_decNumberNextToward_77(decNumber *res, const decNumber *lhs,
1770 const decNumber *rhs, decContext *set) {
1771 decNumber dtiny; /* constant */
1772 decContext workset=*set; /* work */
1773 Intint32_t result; /* .. */
1774 uIntuint32_t status=0; /* accumulator */
1775 #if DECCHECK0
1776 if (decCheckOperands(res, lhs, rhs, set)) return res;
1777 #endif
1778
1779 if (decNumberIsNaN(lhs)(((lhs)->bits&(0x20|0x10))!=0) || decNumberIsNaN(rhs)(((rhs)->bits&(0x20|0x10))!=0)) {
1780 decNaNs(res, lhs, rhs, set, &status);
1781 }
1782 else { /* Is numeric, so no chance of sNaN Invalid, etc. */
1783 result=decCompare(lhs, rhs, 0); /* sign matters */
1784 if (result==BADINT(int32_t)0x80000000) status|=DEC_Insufficient_storage0x00000010; /* rare */
1785 else { /* valid compare */
1786 if (result==0) uprv_decNumberCopySignuprv_decNumberCopySign_77(res, lhs, rhs); /* easy */
1787 else { /* differ: need NextPlus or NextMinus */
1788 uByteuint8_t sub; /* add or subtract */
1789 if (result<0) { /* lhs<rhs, do nextplus */
1790 /* -Infinity is the special case */
1791 if ((lhs->bits&(DECINF0x40|DECNEG0x80))==(DECINF0x40|DECNEG0x80)) {
1792 decSetMaxValue(res, set);
1793 res->bits=DECNEG0x80; /* negative */
1794 return res; /* there is no status to set */
1795 }
1796 workset.round=DEC_ROUND_CEILING;
1797 sub=0; /* add, please */
1798 } /* plus */
1799 else { /* lhs>rhs, do nextminus */
1800 /* +Infinity is the special case */
1801 if ((lhs->bits&(DECINF0x40|DECNEG0x80))==DECINF0x40) {
1802 decSetMaxValue(res, set);
1803 return res; /* there is no status to set */
1804 }
1805 workset.round=DEC_ROUND_FLOOR;
1806 sub=DECNEG0x80; /* subtract, please */
1807 } /* minus */
1808 uprv_decNumberZerouprv_decNumberZero_77(&dtiny); /* start with 0 */
1809 dtiny.lsu[0]=1; /* make number that is .. */
1810 dtiny.exponent=DEC_MIN_EMIN-999999999-1; /* .. smaller than tiniest */
1811 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 if (uprv_decNumberIsNormaluprv_decNumberIsNormal_77(res, set)) status=0;
1815 } /* unequal */
1816 } /* compare OK */
1817 } /* numeric */
1818 if (status!=0) decStatus(res, status, set);
1819 return res;
1820 } /* 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/* ------------------------------------------------------------------ */
1837U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberOruprv_decNumberOr_77(decNumber *res, const decNumber *lhs,
1838 const decNumber *rhs, decContext *set) {
1839 const Unituint8_t *ua, *ub; /* -> operands */
1840 const Unituint8_t *msua, *msub; /* -> operand msus */
1841 Unituint8_t *uc, *msuc; /* -> result and its msu */
1842 Intint32_t msudigs; /* digits in res msu */
1843 #if DECCHECK0
1844 if (decCheckOperands(res, lhs, rhs, set)) return res;
1845 #endif
1846
1847 if (lhs->exponent!=0 || decNumberIsSpecial(lhs)(((lhs)->bits&(0x40|0x20|0x10))!=0) || decNumberIsNegative(lhs)(((lhs)->bits&0x80)!=0)
1848 || rhs->exponent!=0 || decNumberIsSpecial(rhs)(((rhs)->bits&(0x40|0x20|0x10))!=0) || decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) {
1849 decStatus(res, DEC_Invalid_operation0x00000080, set);
1850 return res;
1851 }
1852 /* operands are valid */
1853 ua=lhs->lsu; /* bottom-up */
1854 ub=rhs->lsu; /* .. */
1855 uc=res->lsu; /* .. */
1856 msua=ua+D2U(lhs->digits)((lhs->digits)<=49?d2utable[lhs->digits]:((lhs->digits
)+1 -1)/1)
-1; /* -> msu of lhs */
1857 msub=ub+D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
-1; /* -> msu of rhs */
1858 msuc=uc+D2U(set->digits)((set->digits)<=49?d2utable[set->digits]:((set->digits
)+1 -1)/1)
-1; /* -> msu of result */
1859 msudigs=MSUDIGITS(set->digits)((set->digits)-(((set->digits)<=49?d2utable[set->
digits]:((set->digits)+1 -1)/1)-1)*1)
; /* [faster than remainder] */
1860 for (; uc<=msuc; ua++, ub++, uc++) { /* Unit loop */
1861 Unituint8_t a, b; /* extract units */
1862 if (ua>msua) a=0;
1863 else a=*ua;
1864 if (ub>msub) b=0;
1865 else b=*ub;
1866 *uc=0; /* can now write back */
1867 if (a|b) { /* maybe 1 bits to examine */
1868 Intint32_t i, j;
1869 /* This loop could be unrolled and/or use BIN2BCD tables */
1870 for (i=0; i<DECDPUN1; i++) {
1871 if ((a|b)&1) *uc=*uc+(Unituint8_t)powersDECPOWERS[i]; /* effect OR */
1872 j=a%10;
1873 a=a/10;
1874 j|=b%10;
1875 b=b/10;
1876 if (j>1) {
1877 decStatus(res, DEC_Invalid_operation0x00000080, set);
1878 return res;
1879 }
1880 if (uc==msuc && i==msudigs-1) break; /* just did final digit */
1881 } /* each digit */
1882 } /* non-zero */
1883 } /* each unit */
1884 /* [here uc-1 is the msu of the result] */
1885 res->digits=decGetDigits(res->lsu, static_cast<int32_t>(uc-res->lsu));
1886 res->exponent=0; /* integer */
1887 res->bits=0; /* sign=0 */
1888 return res; /* [no status to set] */
1889 } /* 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/* ------------------------------------------------------------------ */
1907U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberPlusuprv_decNumberPlus_77(decNumber *res, const decNumber *rhs,
1908 decContext *set) {
1909 decNumber dzero;
1910 uIntuint32_t status=0; /* accumulator */
1911 #if DECCHECK0
1912 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1913 #endif
1914
1915 uprv_decNumberZerouprv_decNumberZero_77(&dzero); /* make 0 */
1916 dzero.exponent=rhs->exponent; /* [no coefficient expansion] */
1917 decAddOp(res, &dzero, rhs, set, 0, &status);
1918 if (status!=0) decStatus(res, status, set);
1919 #if DECCHECK0
1920 decCheckInexact(res, set);
1921 #endif
1922 return res;
1923 } /* 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/* ------------------------------------------------------------------ */
1937U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberMultiplyuprv_decNumberMultiply_77(decNumber *res, const decNumber *lhs,
1938 const decNumber *rhs, decContext *set) {
1939 uIntuint32_t status=0; /* accumulator */
1940 decMultiplyOp(res, lhs, rhs, set, &status);
1941 if (status!=0) decStatus(res, status, set);
1942 #if DECCHECK0
1943 decCheckInexact(res, set);
1944 #endif
1945 return res;
1946 } /* 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/* ------------------------------------------------------------------ */
1974U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberPoweruprv_decNumberPower_77(decNumber *res, const decNumber *lhs,
1975 const decNumber *rhs, decContext *set) {
1976 #if DECSUBSET0
1977 decNumber *alloclhs=nullptr; /* non-nullptr if rounded lhs allocated */
1978 decNumber *allocrhs=nullptr; /* .., rhs */
1979 #endif
1980 decNumber *allocdac=nullptr; /* -> allocated acc buffer, iff used */
1981 decNumber *allocinv=nullptr; /* -> allocated 1/x buffer, iff used */
1982 Intint32_t reqdigits=set->digits; /* requested DIGITS */
1983 Intint32_t n; /* rhs in binary */
1984 Flaguint8_t rhsint=0; /* 1 if rhs is an integer */
1985 Flaguint8_t useint=0; /* 1 if can use integer calculation */
1986 Flaguint8_t isoddint=0; /* 1 if rhs is an integer and odd */
1987 Intint32_t i; /* work */
1988 #if DECSUBSET0
1989 Intint32_t dropped; /* .. */
1990 #endif
1991 uIntuint32_t needbytes; /* buffer size needed */
1992 Flaguint8_t seenbit; /* seen a bit while powering */
1993 Intint32_t residue=0; /* rounding residue */
1994 uIntuint32_t status=0; /* accumulators */
1995 uByteuint8_t bits=0; /* result sign if errors */
1996 decContext aset; /* working context */
1997 decNumber dnOne; /* work value 1... */
1998 /* local accumulator buffer [a decNumber, with digits+elength+1 digits] */
1999 decNumber dacbuff[D2N(DECBUFFER+9)(((((((36 +9)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)*
2-1)/sizeof(decNumber))
];
2000 decNumber *dac=dacbuff; /* -> result accumulator */
2001 /* same again for possible 1/lhs calculation */
2002 decNumber invbuff[D2N(DECBUFFER+9)(((((((36 +9)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)*
2-1)/sizeof(decNumber))
];
2003
2004 #if DECCHECK0
2005 if (decCheckOperands(res, lhs, rhs, set)) return res;
2006 #endif
2007
2008 do { /* protect allocated storage */
2009 #if DECSUBSET0
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 if (SPECIALARGS((lhs->bits | rhs->bits) & (0x40|0x20|0x10))) {
2027 if (decNumberIsNaN(lhs)(((lhs)->bits&(0x20|0x10))!=0) || decNumberIsNaN(rhs)(((rhs)->bits&(0x20|0x10))!=0)) { /* NaNs */
2028 decNaNs(res, lhs, rhs, set, &status);
2029 break;}
2030 if (decNumberIsInfinite(rhs)(((rhs)->bits&0x40)!=0)) { /* rhs Infinity */
2031 Flaguint8_t rhsneg=rhs->bits&DECNEG0x80; /* save rhs sign */
2032 if (decNumberIsNegative(lhs)(((lhs)->bits&0x80)!=0) /* lhs<0 */
2033 && !decNumberIsZero(lhs)(*(lhs)->lsu==0 && (lhs)->digits==1 && (
((lhs)->bits&(0x40|0x20|0x10))==0))
) /* .. */
2034 status|=DEC_Invalid_operation0x00000080;
2035 else { /* lhs >=0 */
2036 uprv_decNumberZerouprv_decNumberZero_77(&dnOne); /* set up 1 */
2037 dnOne.lsu[0]=1;
2038 uprv_decNumberCompareuprv_decNumberCompare_77(dac, lhs, &dnOne, set); /* lhs ? 1 */
2039 uprv_decNumberZerouprv_decNumberZero_77(res); /* prepare for 0/1/Infinity */
2040 if (decNumberIsNegative(dac)(((dac)->bits&0x80)!=0)) { /* lhs<1 */
2041 if (rhsneg) res->bits|=DECINF0x40; /* +Infinity [else is +0] */
2042 }
2043 else if (dac->lsu[0]==0) { /* lhs=1 */
2044 /* 1**Infinity is inexact, so return fully-padded 1.0000 */
2045 Intint32_t shift=set->digits-1;
2046 *res->lsu=1; /* was 0, make int 1 */
2047 res->digits=decShiftToMost(res->lsu, 1, shift);
2048 res->exponent=-shift; /* make 1.0000... */
2049 status|=DEC_Inexact0x00000020|DEC_Rounded0x00000800; /* deemed inexact */
2050 }
2051 else { /* lhs>1 */
2052 if (!rhsneg) res->bits|=DECINF0x40; /* +Infinity [else is +0] */
2053 }
2054 } /* lhs>=0 */
2055 break;}
2056 /* [lhs infinity drops through] */
2057 } /* specials */
2058
2059 /* Original rhs may be an integer that fits and is in range */
2060 n=decGetInt(rhs);
2061 if (n!=BADINT(int32_t)0x80000000) { /* it is an integer */
2062 rhsint=1; /* record the fact for 1**n */
2063 isoddint=(Flaguint8_t)n&1; /* [works even if big] */
2064 if (n!=BIGEVEN(int32_t)0x80000002 && n!=BIGODD(int32_t)0x80000003) /* can use integer path? */
2065 useint=1; /* looks good */
2066 }
2067
2068 if (decNumberIsNegative(lhs)(((lhs)->bits&0x80)!=0) /* -x .. */
2069 && isoddint) bits=DECNEG0x80; /* .. to an odd power */
2070
2071 /* handle LHS infinity */
2072 if (decNumberIsInfinite(lhs)(((lhs)->bits&0x40)!=0)) { /* [NaNs already handled] */
2073 uByteuint8_t rbits=rhs->bits; /* save */
2074 uprv_decNumberZerouprv_decNumberZero_77(res); /* prepare */
2075 if (n==0) *res->lsu=1; /* [-]Inf**0 => 1 */
2076 else {
2077 /* -Inf**nonint -> error */
2078 if (!rhsint && decNumberIsNegative(lhs)(((lhs)->bits&0x80)!=0)) {
2079 status|=DEC_Invalid_operation0x00000080; /* -Inf**nonint is error */
2080 break;}
2081 if (!(rbits & DECNEG0x80)) bits|=DECINF0x40; /* was not a **-n */
2082 /* [otherwise will be 0 or -0] */
2083 res->bits=bits;
2084 }
2085 break;}
2086
2087 /* similarly handle LHS zero */
2088 if (decNumberIsZero(lhs)(*(lhs)->lsu==0 && (lhs)->digits==1 && (
((lhs)->bits&(0x40|0x20|0x10))==0))
) {
2089 if (n==0) { /* 0**0 => Error */
2090 #if DECSUBSET0
2091 if (!set->extended) { /* [unless subset] */
2092 uprv_decNumberZerouprv_decNumberZero_77(res);
2093 *res->lsu=1; /* return 1 */
2094 break;}
2095 #endif
2096 status|=DEC_Invalid_operation0x00000080;
2097 }
2098 else { /* 0**x */
2099 uByteuint8_t rbits=rhs->bits; /* save */
2100 if (rbits & DECNEG0x80) { /* was a 0**(-n) */
2101 #if DECSUBSET0
2102 if (!set->extended) { /* [bad if subset] */
2103 status|=DEC_Invalid_operation0x00000080;
2104 break;}
2105 #endif
2106 bits|=DECINF0x40;
2107 }
2108 uprv_decNumberZerouprv_decNumberZero_77(res); /* prepare */
2109 /* [otherwise will be 0 or -0] */
2110 res->bits=bits;
2111 }
2112 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 if (!useint) { /* non-integral rhs */
2117 /* any -ve lhs is bad, as is either operand or context out of */
2118 /* bounds */
2119 if (decNumberIsNegative(lhs)(((lhs)->bits&0x80)!=0)) {
2120 status|=DEC_Invalid_operation0x00000080;
2121 break;}
2122 if (decCheckMath(lhs, set, &status)
2123 || decCheckMath(rhs, set, &status)) break; /* variable status */
2124
2125 uprv_decContextDefaultuprv_decContextDefault_77(&aset, DEC_INIT_DECIMAL6464); /* clean context */
2126 aset.emax=DEC_MAX_MATH999999; /* usual bounds */
2127 aset.emin=-DEC_MAX_MATH999999; /* .. */
2128 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 aset.digits=MAXI(lhs->digits, set->digits)((lhs->digits)<(set->digits)?(set->digits):(lhs->
digits))
+6+4;
2141 } /* non-integer rhs */
2142
2143 else { /* rhs is in-range integer */
2144 if (n==0) { /* x**0 = 1 */
2145 /* (0**0 was handled above) */
2146 uprv_decNumberZerouprv_decNumberZero_77(res); /* result=1 */
2147 *res->lsu=1; /* .. */
2148 break;}
2149 /* rhs is a non-zero integer */
2150 if (n<0) n=-n; /* use abs(n) */
2151
2152 aset=*set; /* clone the context */
2153 aset.round=DEC_ROUND_HALF_EVEN; /* internally use balanced */
2154 /* calculate the working DIGITS */
2155 aset.digits=reqdigits+(rhs->digits+rhs->exponent)+2;
2156 #if DECSUBSET0
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 if (aset.digits>DECNUMMAXP999999999) {status|=DEC_Invalid_operation0x00000080; break;}
2161 } /* 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 needbytes=sizeof(decNumber)+(D2U(aset.digits)((aset.digits)<=49?d2utable[aset.digits]:((aset.digits)+1 -
1)/1)
-1)*sizeof(Unituint8_t);
2166 /* [needbytes also used below if 1/lhs needed] */
2167 if (needbytes>sizeof(dacbuff)) {
2168 allocdac=(decNumber *)malloc(needbytes)uprv_malloc_77(needbytes);
2169 if (allocdac==nullptr) { /* hopeless -- abandon */
2170 status|=DEC_Insufficient_storage0x00000010;
2171 break;}
2172 dac=allocdac; /* use the allocated space */
2173 }
2174 /* here, aset is set up and accumulator is ready for use */
2175
2176 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 decLnOp(dac, lhs, &aset, &status); /* dac=ln(lhs) */
2181 /* [no error possible, as lhs 0 already handled] */
2182 if (ISZERO(dac)(*(dac)->lsu==0 && (dac)->digits==1 && (
((dac)->bits&(0x40|0x20|0x10))==0))
) { /* x==1, 1.0, etc. */
2183 /* need to return fully-padded 1.0000 etc., but rhsint->1 */
2184 *dac->lsu=1; /* was 0, make int 1 */
2185 if (!rhsint) { /* add padding */
2186 Intint32_t shift=set->digits-1;
2187 dac->digits=decShiftToMost(dac->lsu, 1, shift);
2188 dac->exponent=-shift; /* make 1.0000... */
2189 status|=DEC_Inexact0x00000020|DEC_Rounded0x00000800; /* deemed inexact */
2190 }
2191 }
2192 else {
2193 decMultiplyOp(dac, dac, rhs, &aset, &status); /* dac=dac*rhs */
2194 decExpOp(dac, dac, &aset, &status); /* dac=exp(dac) */
2195 }
2196 /* and drop through for final rounding */
2197 } /* non-integer rhs */
2198
2199 else { /* carry on with integer */
2200 uprv_decNumberZerouprv_decNumberZero_77(dac); /* acc=1 */
2201 *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 if (decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) { /* was a **-n [hence digits>0] */
2206 decNumber *inv=invbuff; /* assume use fixed buffer */
2207 uprv_decNumberCopyuprv_decNumberCopy_77(&dnOne, dac); /* dnOne=1; [needed now or later] */
2208 #if DECSUBSET0
2209 if (set->extended) { /* need to calculate 1/lhs */
2210 #endif
2211 /* divide lhs into 1, putting result in dac [dac=1/dac] */
2212 decDivideOp(dac, &dnOne, lhs, &aset, DIVIDE0x80, &status);
2213 /* now locate or allocate space for the inverted lhs */
2214 if (needbytes>sizeof(invbuff)) {
2215 allocinv=(decNumber *)malloc(needbytes)uprv_malloc_77(needbytes);
2216 if (allocinv==nullptr) { /* hopeless -- abandon */
2217 status|=DEC_Insufficient_storage0x00000010;
2218 break;}
2219 inv=allocinv; /* use the allocated space */
2220 }
2221 /* [inv now points to big-enough buffer or allocated storage] */
2222 uprv_decNumberCopyuprv_decNumberCopy_77(inv, dac); /* copy the 1/lhs */
2223 uprv_decNumberCopyuprv_decNumberCopy_77(dac, &dnOne); /* restore acc=1 */
2224 lhs=inv; /* .. and go forward with new lhs */
2225 #if DECSUBSET0
2226 }
2227 #endif
2228 }
2229
2230 /* Raise-to-the-power loop... */
2231 seenbit=0; /* set once a 1-bit is encountered */
2232 for (i=1;;i++){ /* for each bit [top bit ignored] */
2233 /* abandon if had overflow or terminal underflow */
2234 if (status & (DEC_Overflow0x00000200|DEC_Underflow0x00002000)) { /* interesting? */
2235 if (status&DEC_Overflow0x00000200 || ISZERO(dac)(*(dac)->lsu==0 && (dac)->digits==1 && (
((dac)->bits&(0x40|0x20|0x10))==0))
) break;
2236 }
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 n=n<<1; /* move next bit to testable position */
2240 if (n<0) { /* top bit is set */
2241 seenbit=1; /* OK, significant bit seen */
2242 decMultiplyOp(dac, dac, lhs, &aset, &status); /* dac=dac*x */
2243 }
2244 if (i==31) break; /* that was the last bit */
2245 if (!seenbit) continue; /* no need to square 1 */
2246 decMultiplyOp(dac, dac, dac, &aset, &status); /* dac=dac*dac [square] */
2247 } /*i*/ /* 32 bits */
2248
2249 /* complete internal overflow or underflow processing */
2250 if (status & (DEC_Overflow0x00000200|DEC_Underflow0x00002000)) {
2251 #if DECSUBSET0
2252 /* If subset, and power was negative, reverse the kind of -erflow */
2253 /* [1/x not yet done] */
2254 if (!set->extended && decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) {
2255 if (status & DEC_Overflow0x00000200)
2256 status^=DEC_Overflow0x00000200 | DEC_Underflow0x00002000 | DEC_Subnormal0x00001000;
2257 else { /* trickier -- Underflow may or may not be set */
2258 status&=~(DEC_Underflow0x00002000 | DEC_Subnormal0x00001000); /* [one or both] */
2259 status|=DEC_Overflow0x00000200;
2260 }
2261 }
2262 #endif
2263 dac->bits=(dac->bits & ~DECNEG0x80) | bits; /* force correct sign */
2264 /* round subnormals [to set.digits rather than aset.digits] */
2265 /* or set overflow result similarly as required */
2266 decFinalize(dac, set, &residue, &status);
2267 uprv_decNumberCopyuprv_decNumberCopy_77(res, dac); /* copy to result (is now OK length) */
2268 break;
2269 }
2270
2271 #if DECSUBSET0
2272 if (!set->extended && /* subset math */
2273 decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) { /* was a **-n [hence digits>0] */
2274 /* so divide result into 1 [dac=1/dac] */
2275 decDivideOp(dac, &dnOne, dac, &aset, DIVIDE0x80, &status);
2276 }
2277 #endif
2278 } /* rhs integer path */
2279
2280 /* reduce result to the requested length and copy to result */
2281 decCopyFit(res, dac, set, &residue, &status);
2282 decFinish(res, set, &residue, &status)decFinalize(res,set,&residue,&status); /* final cleanup */
2283 #if DECSUBSET0
2284 if (!set->extended) decTrim(res, set, 0, 1, &dropped); /* trailing zeros */
2285 #endif
2286 } while(0); /* end protected */
2287
2288 if (allocdac!=nullptr) free(allocdac)uprv_free_77(allocdac); /* drop any storage used */
2289 if (allocinv!=nullptr) free(allocinv)uprv_free_77(allocinv); /* .. */
2290 #if DECSUBSET0
2291 if (alloclhs!=nullptr) free(alloclhs)uprv_free_77(alloclhs); /* .. */
2292 if (allocrhs!=nullptr) free(allocrhs)uprv_free_77(allocrhs); /* .. */
2293 #endif
2294 if (status!=0) decStatus(res, status, set);
2295 #if DECCHECK0
2296 decCheckInexact(res, set);
2297 #endif
2298 return res;
2299 } /* 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/* ------------------------------------------------------------------ */
2319U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberQuantizeuprv_decNumberQuantize_77(decNumber *res, const decNumber *lhs,
2320 const decNumber *rhs, decContext *set) {
2321 uIntuint32_t status=0; /* accumulator */
2322 decQuantizeOp(res, lhs, rhs, set, 1, &status);
2323 if (status!=0) decStatus(res, status, set);
2324 return res;
2325 } /* 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 */
2339U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberNormalizeuprv_decNumberNormalize_77(decNumber *res, const decNumber *rhs,
2340 decContext *set) {
2341 return uprv_decNumberReduceuprv_decNumberReduce_77(res, rhs, set);
2342 } /* decNumberNormalize */
2343
2344U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberReduceuprv_decNumberReduce_77(decNumber *res, const decNumber *rhs,
2345 decContext *set) {
2346 #if DECSUBSET0
2347 decNumber *allocrhs=nullptr; /* non-nullptr if rounded rhs allocated */
2348 #endif
2349 uIntuint32_t status=0; /* as usual */
2350 Intint32_t residue=0; /* as usual */
2351 Intint32_t dropped; /* work */
2352
2353 #if DECCHECK0
2354 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
2355 #endif
2356
2357 do { /* protect allocated storage */
2358 #if DECSUBSET0
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 if (decNumberIsNaN(rhs)(((rhs)->bits&(0x20|0x10))!=0)) {
2372 decNaNs(res, rhs, nullptr, set, &status);
2373 break;
2374 }
2375
2376 /* reduce result to the requested length and copy to result */
2377 decCopyFit(res, rhs, set, &residue, &status); /* copy & round */
2378 decFinish(res, set, &residue, &status)decFinalize(res,set,&residue,&status); /* cleanup/set flags */
2379 decTrim(res, set, 1, 0, &dropped); /* normalize in place */
2380 /* [may clamp] */
2381 } while(0); /* end protected */
2382
2383 #if DECSUBSET0
2384 if (allocrhs !=nullptr) free(allocrhs)uprv_free_77(allocrhs); /* .. */
2385 #endif
2386 if (status!=0) decStatus(res, status, set);/* then report status */
2387 return res;
2388 } /* 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/* ------------------------------------------------------------------ */
2408U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberRescaleuprv_decNumberRescale_77(decNumber *res, const decNumber *lhs,
2409 const decNumber *rhs, decContext *set) {
2410 uIntuint32_t status=0; /* accumulator */
2411 decQuantizeOp(res, lhs, rhs, set, 0, &status);
2412 if (status!=0) decStatus(res, status, set);
2413 return res;
2414 } /* 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/* ------------------------------------------------------------------ */
2428U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberRemainderuprv_decNumberRemainder_77(decNumber *res, const decNumber *lhs,
2429 const decNumber *rhs, decContext *set) {
2430 uIntuint32_t status=0; /* accumulator */
2431 decDivideOp(res, lhs, rhs, set, REMAINDER0x40, &status);
2432 if (status!=0) decStatus(res, status, set);
2433 #if DECCHECK0
2434 decCheckInexact(res, set);
2435 #endif
2436 return res;
2437 } /* 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/* ------------------------------------------------------------------ */
2451U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberRemainderNearuprv_decNumberRemainderNear_77(decNumber *res, const decNumber *lhs,
2452 const decNumber *rhs, decContext *set) {
2453 uIntuint32_t status=0; /* accumulator */
2454 decDivideOp(res, lhs, rhs, set, REMNEAR0x10, &status);
2455 if (status!=0) decStatus(res, status, set);
2456 #if DECCHECK0
2457 decCheckInexact(res, set);
2458 #endif
2459 return res;
2460 } /* 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/* ------------------------------------------------------------------ */
2487U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberRotateuprv_decNumberRotate_77(decNumber *res, const decNumber *lhs,
2488 const decNumber *rhs, decContext *set) {
2489 uIntuint32_t status=0; /* accumulator */
2490 Intint32_t rotate; /* rhs as an Int */
2491
2492 #if DECCHECK0
2493 if (decCheckOperands(res, lhs, rhs, set)) return res;
2494 #endif
2495
2496 /* NaNs propagate as normal */
2497 if (decNumberIsNaN(lhs)(((lhs)->bits&(0x20|0x10))!=0) || decNumberIsNaN(rhs)(((rhs)->bits&(0x20|0x10))!=0))
2498 decNaNs(res, lhs, rhs, set, &status);
2499 /* rhs must be an integer */
2500 else if (decNumberIsInfinite(rhs)(((rhs)->bits&0x40)!=0) || rhs->exponent!=0)
2501 status=DEC_Invalid_operation0x00000080;
2502 else { /* both numeric, rhs is an integer */
2503 rotate=decGetInt(rhs); /* [cannot fail] */
2504 if (rotate==BADINT(int32_t)0x80000000 /* something bad .. */
2505 || rotate==BIGODD(int32_t)0x80000003 || rotate==BIGEVEN(int32_t)0x80000002 /* .. very big .. */
2506 || abs(rotate)>set->digits) /* .. or out of range */
2507 status=DEC_Invalid_operation0x00000080;
2508 else { /* rhs is OK */
2509 uprv_decNumberCopyuprv_decNumberCopy_77(res, lhs);
2510 /* convert -ve rotate to equivalent positive rotation */
2511 if (rotate<0) rotate=set->digits+rotate;
2512 if (rotate!=0 && rotate!=set->digits /* zero or full rotation */
2513 && !decNumberIsInfinite(res)(((res)->bits&0x40)!=0)) { /* lhs was infinite */
2514 /* left-rotate to do; 0 < rotate < set->digits */
2515 uIntuint32_t units, shift; /* work */
2516 uIntuint32_t msudigits; /* digits in result msu */
2517 Unituint8_t *msu=res->lsu+D2U(res->digits)((res->digits)<=49?d2utable[res->digits]:((res->digits
)+1 -1)/1)
-1; /* current msu */
2518 Unituint8_t *msumax=res->lsu+D2U(set->digits)((set->digits)<=49?d2utable[set->digits]:((set->digits
)+1 -1)/1)
-1; /* rotation msu */
2519 for (msu++; msu<=msumax; msu++) *msu=0; /* ensure high units=0 */
2520 res->digits=set->digits; /* now full-length */
2521 msudigits=MSUDIGITS(res->digits)((res->digits)-(((res->digits)<=49?d2utable[res->
digits]:((res->digits)+1 -1)/1)-1)*1)
; /* 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 rotate=set->digits-rotate; /* make it right-rotate */
2555 units=rotate/DECDPUN1; /* whole units to rotate */
2556 shift=rotate%DECDPUN1; /* left-over digits count */
2557 if (shift>0) { /* not an exact number of units */
2558 uIntuint32_t save=res->lsu[0]%powersDECPOWERS[shift]; /* save low digit(s) */
2559 decShiftToLeast(res->lsu, D2U(res->digits)((res->digits)<=49?d2utable[res->digits]:((res->digits
)+1 -1)/1)
, shift);
2560 if (shift>msudigits) { /* msumax-1 needs >0 digits */
2561 uIntuint32_t rem=save%powersDECPOWERS[shift-msudigits];/* split save */
2562 *msumax=(Unituint8_t)(save/powersDECPOWERS[shift-msudigits]); /* and insert */
2563 *(msumax-1)=*(msumax-1)
2564 +(Unituint8_t)(rem*powersDECPOWERS[DECDPUN1-(shift-msudigits)]); /* .. */
2565 }
2566 else { /* all fits in msumax */
2567 *msumax=*msumax+(Unituint8_t)(save*powersDECPOWERS[msudigits-shift]); /* [maybe *1] */
2568 }
2569 } /* digits shift needed */
2570
2571 /* If whole units to rotate... */
2572 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 shift=DECDPUN1-msudigits;
2577 if (shift>0) { /* not an exact number of units */
2578 uIntuint32_t save=res->lsu[0]%powersDECPOWERS[shift]; /* save low digit(s) */
2579 decShiftToLeast(res->lsu, units, shift);
2580 *msumax=*msumax+(Unituint8_t)(save*powersDECPOWERS[msudigits]);
2581 } /* partial shift needed */
2582
2583 /* Step 3: rotate the units array using triple reverse */
2584 /* (reversing is easy and fast) */
2585 decReverse(res->lsu+units, msumax); /* left part */
2586 decReverse(res->lsu, res->lsu+units-1); /* right part */
2587 decReverse(res->lsu, msumax); /* whole */
2588 } /* 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 res->digits=decGetDigits(res->lsu, static_cast<int32_t>(msumax-res->lsu+1));
2592 } /* rotate needed */
2593 } /* rhs OK */
2594 } /* numerics */
2595 if (status!=0) decStatus(res, status, set);
2596 return res;
2597 } /* 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/* ------------------------------------------------------------------ */
2608U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberSameQuantumuprv_decNumberSameQuantum_77(decNumber *res, const decNumber *lhs,
2609 const decNumber *rhs) {
2610 Unituint8_t ret=0; /* return value */
2611
2612 #if DECCHECK0
2613 if (decCheckOperands(res, lhs, rhs, DECUNCONT)) return res;
2614 #endif
2615
2616 if (SPECIALARGS((lhs->bits | rhs->bits) & (0x40|0x20|0x10))) {
2617 if (decNumberIsNaN(lhs)(((lhs)->bits&(0x20|0x10))!=0) && decNumberIsNaN(rhs)(((rhs)->bits&(0x20|0x10))!=0)) ret=1;
2618 else if (decNumberIsInfinite(lhs)(((lhs)->bits&0x40)!=0) && decNumberIsInfinite(rhs)(((rhs)->bits&0x40)!=0)) ret=1;
2619 /* [anything else with a special gives 0] */
2620 }
2621 else if (lhs->exponent==rhs->exponent) ret=1;
2622
2623 uprv_decNumberZerouprv_decNumberZero_77(res); /* OK to overwrite an operand now */
2624 *res->lsu=ret;
2625 return res;
2626 } /* 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/* ------------------------------------------------------------------ */
2643U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberScaleBuprv_decNumberScaleB_77(decNumber *res, const decNumber *lhs,
2644 const decNumber *rhs, decContext *set) {
2645 Intint32_t reqexp; /* requested exponent change [B] */
2646 uIntuint32_t status=0; /* accumulator */
2647 Intint32_t residue; /* work */
2648
2649 #if DECCHECK0
2650 if (decCheckOperands(res, lhs, rhs, set)) return res;
2651 #endif
2652
2653 /* Handle special values except lhs infinite */
2654 if (decNumberIsNaN(lhs)(((lhs)->bits&(0x20|0x10))!=0) || decNumberIsNaN(rhs)(((rhs)->bits&(0x20|0x10))!=0))
2655 decNaNs(res, lhs, rhs, set, &status);
2656 /* rhs must be an integer */
2657 else if (decNumberIsInfinite(rhs)(((rhs)->bits&0x40)!=0) || rhs->exponent!=0)
2658 status=DEC_Invalid_operation0x00000080;
2659 else {
2660 /* lhs is a number; rhs is a finite with q==0 */
2661 reqexp=decGetInt(rhs); /* [cannot fail] */
2662 if (reqexp==BADINT(int32_t)0x80000000 /* something bad .. */
2663 || reqexp==BIGODD(int32_t)0x80000003 || reqexp==BIGEVEN(int32_t)0x80000002 /* .. very big .. */
2664 || abs(reqexp)>(2*(set->digits+set->emax))) /* .. or out of range */
2665 status=DEC_Invalid_operation0x00000080;
2666 else { /* rhs is OK */
2667 uprv_decNumberCopyuprv_decNumberCopy_77(res, lhs); /* all done if infinite lhs */
2668 if (!decNumberIsInfinite(res)(((res)->bits&0x40)!=0)) { /* prepare to scale */
2669 res->exponent+=reqexp; /* adjust the exponent */
2670 residue=0;
2671 decFinalize(res, set, &residue, &status); /* .. and check */
2672 } /* finite LHS */
2673 } /* rhs OK */
2674 } /* rhs finite */
2675 if (status!=0) decStatus(res, status, set);
2676 return res;
2677 } /* 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/* ------------------------------------------------------------------ */
2700U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberShiftuprv_decNumberShift_77(decNumber *res, const decNumber *lhs,
2701 const decNumber *rhs, decContext *set) {
2702 uIntuint32_t status=0; /* accumulator */
2703 Intint32_t shift; /* rhs as an Int */
2704
2705 #if DECCHECK0
2706 if (decCheckOperands(res, lhs, rhs, set)) return res;
2707 #endif
2708
2709 /* NaNs propagate as normal */
2710 if (decNumberIsNaN(lhs)(((lhs)->bits&(0x20|0x10))!=0) || decNumberIsNaN(rhs)(((rhs)->bits&(0x20|0x10))!=0))
2711 decNaNs(res, lhs, rhs, set, &status);
2712 /* rhs must be an integer */
2713 else if (decNumberIsInfinite(rhs)(((rhs)->bits&0x40)!=0) || rhs->exponent!=0)
2714 status=DEC_Invalid_operation0x00000080;
2715 else { /* both numeric, rhs is an integer */
2716 shift=decGetInt(rhs); /* [cannot fail] */
2717 if (shift==BADINT(int32_t)0x80000000 /* something bad .. */
2718 || shift==BIGODD(int32_t)0x80000003 || shift==BIGEVEN(int32_t)0x80000002 /* .. very big .. */
2719 || abs(shift)>set->digits) /* .. or out of range */
2720 status=DEC_Invalid_operation0x00000080;
2721 else { /* rhs is OK */
2722 uprv_decNumberCopyuprv_decNumberCopy_77(res, lhs);
2723 if (shift!=0 && !decNumberIsInfinite(res)(((res)->bits&0x40)!=0)) { /* something to do */
2724 if (shift>0) { /* to left */
2725 if (shift==set->digits) { /* removing all */
2726 *res->lsu=0; /* so place 0 */
2727 res->digits=1; /* .. */
2728 }
2729 else { /* */
2730 /* first remove leading digits if necessary */
2731 if (res->digits+shift>set->digits) {
2732 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 }
2736 if (res->digits>1 || *res->lsu) /* if non-zero.. */
2737 res->digits=decShiftToMost(res->lsu, res->digits, shift);
2738 } /* partial left */
2739 } /* left */
2740 else { /* to right */
2741 if (-shift>=res->digits) { /* discarding all */
2742 *res->lsu=0; /* so place 0 */
2743 res->digits=1; /* .. */
2744 }
2745 else {
2746 decShiftToLeast(res->lsu, D2U(res->digits)((res->digits)<=49?d2utable[res->digits]:((res->digits
)+1 -1)/1)
, -shift);
2747 res->digits-=(-shift);
2748 }
2749 } /* to right */
2750 } /* non-0 non-Inf shift */
2751 } /* rhs OK */
2752 } /* numerics */
2753 if (status!=0) decStatus(res, status, set);
2754 return res;
2755 } /* 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__1) || U_GCC_MAJOR_MINOR(4 * 100 + 2) >= 406
2830#pragma GCC diagnostic push
2831#pragma GCC diagnostic ignored "-Warray-bounds"
2832#endif
2833U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberSquareRootuprv_decNumberSquareRoot_77(decNumber *res, const decNumber *rhs,
2834 decContext *set) {
2835 decContext workset, approxset; /* work contexts */
2836 decNumber dzero; /* used for constant zero */
2837 Intint32_t maxp; /* largest working precision */
2838 Intint32_t workp; /* working precision */
2839 Intint32_t residue=0; /* rounding residue */
2840 uIntuint32_t status=0, ignore=0; /* status accumulators */
2841 uIntuint32_t rstatus; /* .. */
2842 Intint32_t exp; /* working exponent */
2843 Intint32_t ideal; /* ideal (preferred) exponent */
2844 Intint32_t needbytes; /* work */
2845 Intint32_t dropped; /* .. */
2846
2847 #if DECSUBSET0
2848 decNumber *allocrhs=nullptr; /* non-nullptr if rounded rhs allocated */
2849 #endif
2850 /* buffer for f [needs +1 in case DECBUFFER 0] */
2851 decNumber buff[D2N(DECBUFFER+1)(((((((36 +1)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)*
2-1)/sizeof(decNumber))
];
2852 /* buffer for a [needs +2 to match likely maxp] */
2853 decNumber bufa[D2N(DECBUFFER+2)(((((((36 +2)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)*
2-1)/sizeof(decNumber))
];
2854 /* buffer for temporary, b [must be same size as a] */
2855 decNumber bufb[D2N(DECBUFFER+2)(((((((36 +2)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)*
2-1)/sizeof(decNumber))
];
2856 decNumber *allocbuff=nullptr; /* -> allocated buff, iff allocated */
2857 decNumber *allocbufa=nullptr; /* -> allocated bufa, iff allocated */
2858 decNumber *allocbufb=nullptr; /* -> allocated bufb, iff allocated */
2859 decNumber *f=buff; /* reduced fraction */
2860 decNumber *a=bufa; /* approximation to result */
2861 decNumber *b=bufb; /* intermediate result */
2862 /* buffer for temporary variable, up to 3 digits */
2863 decNumber buft[D2N(3)(((((((3)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)*2-1)
/sizeof(decNumber))
];
2864 decNumber *t=buft; /* up-to-3-digit constant or work */
2865
2866 #if DECCHECK0
2867 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
2868 #endif
2869
2870 do { /* protect allocated storage */
2871 #if DECSUBSET0
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 if (SPECIALARG(rhs->bits & (0x40|0x20|0x10))) {
2887 if (decNumberIsInfinite(rhs)(((rhs)->bits&0x40)!=0)) { /* an infinity */
2888 if (decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) status|=DEC_Invalid_operation0x00000080;
2889 else uprv_decNumberCopyuprv_decNumberCopy_77(res, rhs); /* +Infinity */
2890 }
2891 else decNaNs(res, rhs, nullptr, set, &status); /* a NaN */
2892 break;
2893 }
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 ideal=(rhs->exponent&~1)/2; /* target */
2899
2900 /* handle zeros */
2901 if (ISZERO(rhs)(*(rhs)->lsu==0 && (rhs)->digits==1 && (
((rhs)->bits&(0x40|0x20|0x10))==0))
) {
2902 uprv_decNumberCopyuprv_decNumberCopy_77(res, rhs); /* could be 0 or -0 */
2903 res->exponent=ideal; /* use the ideal [safe] */
2904 /* use decFinish to clamp any out-of-range exponent, etc. */
2905 decFinish(res, set, &residue, &status)decFinalize(res,set,&residue,&status);
2906 break;
2907 }
2908
2909 /* any other -x is an oops */
2910 if (decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) {
2911 status|=DEC_Invalid_operation0x00000080;
2912 break;
2913 }
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 workp=MAXI(set->digits+1, rhs->digits)((set->digits+1)<(rhs->digits)?(rhs->digits):(set
->digits+1))
; /* actual rounding precision */
2923 workp=MAXI(workp, 7)((workp)<(7)?(7):(workp)); /* at least 7 for low cases */
2924 maxp=workp+2; /* largest working precision */
2925
2926 needbytes=sizeof(decNumber)+(D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
-1)*sizeof(Unituint8_t);
2927 if (needbytes>(Intint32_t)sizeof(buff)) {
2928 allocbuff=(decNumber *)malloc(needbytes)uprv_malloc_77(needbytes);
2929 if (allocbuff==nullptr) { /* hopeless -- abandon */
2930 status|=DEC_Insufficient_storage0x00000010;
2931 break;}
2932 f=allocbuff; /* use the allocated space */
2933 }
2934 /* a and b both need to be able to hold a maxp-length number */
2935 needbytes=sizeof(decNumber)+(D2U(maxp)((maxp)<=49?d2utable[maxp]:((maxp)+1 -1)/1)-1)*sizeof(Unituint8_t);
2936 if (needbytes>(Intint32_t)sizeof(bufa)) { /* [same applies to b] */
2937 allocbufa=(decNumber *)malloc(needbytes)uprv_malloc_77(needbytes);
2938 allocbufb=(decNumber *)malloc(needbytes)uprv_malloc_77(needbytes);
2939 if (allocbufa==nullptr || allocbufb==nullptr) { /* hopeless */
2940 status|=DEC_Insufficient_storage0x00000010;
2941 break;}
2942 a=allocbufa; /* use the allocated spaces */
2943 b=allocbufb; /* .. */
2944 }
2945
2946 /* copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1 */
2947 uprv_decNumberCopyuprv_decNumberCopy_77(f, rhs);
2948 exp=f->exponent+f->digits; /* adjusted to Hull rules */
2949 f->exponent=-(f->digits); /* to range */
2950
2951 /* set up working context */
2952 uprv_decContextDefaultuprv_decContextDefault_77(&workset, DEC_INIT_DECIMAL6464);
2953 workset.emax=DEC_MAX_EMAX999999999;
2954 workset.emin=DEC_MIN_EMIN-999999999;
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 workset.digits=workp; /* p for initial calculation */
2961 t->bits=0; t->digits=3;
2962 a->bits=0; a->digits=3;
2963 if ((exp & 1)==0) { /* even exponent */
2964 /* Set t=0.259, a=0.819 */
2965 t->exponent=-3;
2966 a->exponent=-3;
2967 #if DECDPUN1>=3
2968 t->lsu[0]=259;
2969 a->lsu[0]=819;
2970 #elif DECDPUN1==2
2971 t->lsu[0]=59; t->lsu[1]=2;
2972 a->lsu[0]=19; a->lsu[1]=8;
2973 #else
2974 t->lsu[0]=9; t->lsu[1]=5; t->lsu[2]=2;
2975 a->lsu[0]=9; a->lsu[1]=1; a->lsu[2]=8;
2976 #endif
2977 }
2978 else { /* odd exponent */
2979 /* Set t=0.0819, a=2.59 */
2980 f->exponent--; /* f=f/10 */
2981 exp++; /* e=e+1 */
2982 t->exponent=-4;
2983 a->exponent=-2;
2984 #if DECDPUN1>=3
2985 t->lsu[0]=819;
2986 a->lsu[0]=259;
2987 #elif DECDPUN1==2
2988 t->lsu[0]=19; t->lsu[1]=8;
2989 a->lsu[0]=59; a->lsu[1]=2;
2990 #else
2991 t->lsu[0]=9; t->lsu[1]=1; t->lsu[2]=8;
2992 a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;
2993 #endif
2994 }
2995
2996 decMultiplyOp(a, a, f, &workset, &ignore); /* a=a*f */
2997 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 uprv_decNumberZerouprv_decNumberZero_77(&dzero); /* make 0 */
3003 uprv_decNumberZerouprv_decNumberZero_77(t); /* set t = 0.5 */
3004 t->lsu[0]=5; /* .. */
3005 t->exponent=-1; /* .. */
3006 workset.digits=3; /* initial p */
3007 for (; workset.digits<maxp;) {
3008 /* set p to min(2*p - 2, maxp) [hence 3; or: 4, 6, 10, ... , maxp] */
3009 workset.digits=MINI(workset.digits*2-2, maxp)((workset.digits*2-2)>(maxp)?(maxp):(workset.digits*2-2));
3010 /* a = 0.5 * (a + f/a) */
3011 /* [calculated at p then rounded to currentprecision] */
3012 decDivideOp(b, f, a, &workset, DIVIDE0x80, &ignore); /* b=f/a */
3013 decAddOp(b, b, a, &workset, 0, &ignore); /* b=b+a */
3014 decMultiplyOp(a, b, t, &workset, &ignore); /* a=b*0.5 */
3015 } /* 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 approxset=*set; /* get emin, emax, etc. */
3022 approxset.round=DEC_ROUND_HALF_EVEN;
3023 a->exponent+=exp/2; /* set correct exponent */
3024 rstatus=0; /* clear status */
3025 residue=0; /* .. and accumulator */
3026 decCopyFit(a, a, &approxset, &residue, &rstatus); /* reduce (if needed) */
3027 decFinish(a, &approxset, &residue, &rstatus)decFinalize(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 if (rstatus&DEC_Overflow0x00000200) {
3032 status=rstatus; /* use the status as-is */
3033 uprv_decNumberCopyuprv_decNumberCopy_77(res, a); /* copy to result */
3034 break;
3035 }
3036
3037 /* Preserve status except Inexact/Rounded */
3038 status|=(rstatus & ~(DEC_Rounded0x00000800|DEC_Inexact0x00000020));
3039
3040 /* Carry out the Hull correction */
3041 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 workset.digits--; /* maxp-1 is OK now */
3049 t->exponent=-a->digits-1; /* make 0.5 ulp */
3050 decAddOp(b, a, t, &workset, DECNEG0x80, &ignore); /* b = a - 0.5 ulp */
3051 workset.round=DEC_ROUND_UP;
3052 decMultiplyOp(b, b, b, &workset, &ignore); /* b = mulru(b, b) */
3053 decCompareOp(b, f, b, &workset, COMPARE0x01, &ignore); /* b ? f, reversed */
3054 if (decNumberIsNegative(b)(((b)->bits&0x80)!=0)) { /* f < b [i.e., b > f] */
3055 /* this is the more common adjustment, though both are rare */
3056 t->exponent++; /* make 1.0 ulp */
3057 t->lsu[0]=1; /* .. */
3058 decAddOp(a, a, t, &workset, DECNEG0x80, &ignore); /* a = a - 1 ulp */
3059 /* assign to approx [round to length] */
3060 approxset.emin-=exp/2; /* adjust to match a */
3061 approxset.emax-=exp/2;
3062 decAddOp(a, &dzero, a, &approxset, 0, &ignore);
3063 }
3064 else {
3065 decAddOp(b, a, t, &workset, 0, &ignore); /* b = a + 0.5 ulp */
3066 workset.round=DEC_ROUND_DOWN;
3067 decMultiplyOp(b, b, b, &workset, &ignore); /* b = mulrd(b, b) */
3068 decCompareOp(b, b, f, &workset, COMPARE0x01, &ignore); /* b ? f */
3069 if (decNumberIsNegative(b)(((b)->bits&0x80)!=0)) { /* b < f */
3070 t->exponent++; /* make 1.0 ulp */
3071 t->lsu[0]=1; /* .. */
3072 decAddOp(a, a, t, &workset, 0, &ignore); /* a = a + 1 ulp */
3073 /* assign to approx [round to length] */
3074 approxset.emin-=exp/2; /* adjust to match a */
3075 approxset.emax-=exp/2;
3076 decAddOp(a, &dzero, a, &approxset, 0, &ignore);
3077 }
3078 }
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 a->exponent+=exp/2; /* set correct exponent */
3084
3085 /* count droppable zeros [after any subnormal rounding] by */
3086 /* trimming a copy */
3087 uprv_decNumberCopyuprv_decNumberCopy_77(b, a);
3088 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 if (b->digits*2-1 > workp) { /* cannot fit */
3095 status|=DEC_Inexact0x00000020|DEC_Rounded0x00000800;
3096 }
3097 else { /* could be exact/unrounded */
3098 uIntuint32_t mstatus=0; /* local status */
3099 decMultiplyOp(b, b, b, &workset, &mstatus); /* try the multiply */
3100 if (mstatus&DEC_Overflow0x00000200) { /* result just won't fit */
3101 status|=DEC_Inexact0x00000020|DEC_Rounded0x00000800;
3102 }
3103 else { /* plausible */
3104 decCompareOp(t, b, rhs, &workset, COMPARE0x01, &mstatus); /* b ? rhs */
3105 if (!ISZERO(t)(*(t)->lsu==0 && (t)->digits==1 && (((t
)->bits&(0x40|0x20|0x10))==0))
) status|=DEC_Inexact0x00000020|DEC_Rounded0x00000800; /* not equal */
3106 else { /* is Exact */
3107 /* here, dropped is the count of trailing zeros in 'a' */
3108 /* use closest exponent to ideal... */
3109 Intint32_t todrop=ideal-a->exponent; /* most that can be dropped */
3110 if (todrop<0) status|=DEC_Rounded0x00000800; /* ideally would add 0s */
3111 else { /* unrounded */
3112 /* there are some to drop, but emax may not allow all */
3113 Intint32_t maxexp=set->emax-set->digits+1;
3114 Intint32_t maxdrop=maxexp-a->exponent;
3115 if (todrop>maxdrop && set->clamp) { /* apply clamping */
3116 todrop=maxdrop;
3117 status|=DEC_Clamped0x00000400;
3118 }
3119 if (dropped<todrop) { /* clamp to those available */
3120 todrop=dropped;
3121 status|=DEC_Clamped0x00000400;
3122 }
3123 if (todrop>0) { /* have some to drop */
3124 decShiftToLeast(a->lsu, D2U(a->digits)((a->digits)<=49?d2utable[a->digits]:((a->digits)
+1 -1)/1)
, todrop);
3125 a->exponent+=todrop; /* maintain numerical value */
3126 a->digits-=todrop; /* new length */
3127 }
3128 }
3129 }
3130 }
3131 }
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 if (status&DEC_Underflow0x00002000) {
3136 Intint32_t ae=rhs->exponent+rhs->digits-1; /* adjusted exponent */
3137 /* check if truly subnormal */
3138 #if DECEXTFLAG1 /* DEC_Subnormal too */
3139 if (ae>=set->emin*2) status&=~(DEC_Subnormal0x00001000|DEC_Underflow0x00002000);
3140 #else
3141 if (ae>=set->emin*2) status&=~DEC_Underflow0x00002000;
3142 #endif
3143 /* check if truly inexact */
3144 if (!(status&DEC_Inexact0x00000020)) status&=~DEC_Underflow0x00002000;
3145 }
3146
3147 uprv_decNumberCopyuprv_decNumberCopy_77(res, a); /* a is now the result */
3148 } while(0); /* end protected */
3149
3150 if (allocbuff!=nullptr) free(allocbuff)uprv_free_77(allocbuff); /* drop any storage used */
3151 if (allocbufa!=nullptr) free(allocbufa)uprv_free_77(allocbufa); /* .. */
3152 if (allocbufb!=nullptr) free(allocbufb)uprv_free_77(allocbufb); /* .. */
3153 #if DECSUBSET0
3154 if (allocrhs !=nullptr) free(allocrhs)uprv_free_77(allocrhs); /* .. */
3155 #endif
3156 if (status!=0) decStatus(res, status, set);/* then report status */
3157 #if DECCHECK0
3158 decCheckInexact(res, set);
3159 #endif
3160 return res;
3161 } /* decNumberSquareRoot */
3162#if defined(__clang__1) || U_GCC_MAJOR_MINOR(4 * 100 + 2) >= 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/* ------------------------------------------------------------------ */
3178U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberSubtractuprv_decNumberSubtract_77(decNumber *res, const decNumber *lhs,
3179 const decNumber *rhs, decContext *set) {
3180 uIntuint32_t status=0; /* accumulator */
3181
3182 decAddOp(res, lhs, rhs, set, DECNEG0x80, &status);
3183 if (status!=0) decStatus(res, status, set);
3184 #if DECCHECK0
3185 decCheckInexact(res, set);
3186 #endif
3187 return res;
3188 } /* 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/* ------------------------------------------------------------------ */
3211U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberToIntegralExactuprv_decNumberToIntegralExact_77(decNumber *res, const decNumber *rhs,
3212 decContext *set) {
3213 decNumber dn;
3214 decContext workset; /* working context */
3215 uIntuint32_t status=0; /* accumulator */
3216
3217 #if DECCHECK0
3218 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
3219 #endif
3220
3221 /* handle infinities and NaNs */
3222 if (SPECIALARG(rhs->bits & (0x40|0x20|0x10))) {
3223 if (decNumberIsInfinite(rhs)(((rhs)->bits&0x40)!=0)) uprv_decNumberCopyuprv_decNumberCopy_77(res, rhs); /* an Infinity */
3224 else decNaNs(res, rhs, nullptr, set, &status); /* a NaN */
3225 }
3226 else { /* finite */
3227 /* have a finite number; no error possible (res must be big enough) */
3228 if (rhs->exponent>=0) return uprv_decNumberCopyuprv_decNumberCopy_77(res, rhs);
3229 /* that was easy, but if negative exponent there is work to do... */
3230 workset=*set; /* clone rounding, etc. */
3231 workset.digits=rhs->digits; /* no length rounding */
3232 workset.traps=0; /* no traps */
3233 uprv_decNumberZerouprv_decNumberZero_77(&dn); /* make a number with exponent 0 */
3234 uprv_decNumberQuantizeuprv_decNumberQuantize_77(res, rhs, &dn, &workset);
3235 status|=workset.status;
3236 }
3237 if (status!=0) decStatus(res, status, set);
3238 return res;
3239 } /* decNumberToIntegralExact */
3240
3241U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberToIntegralValueuprv_decNumberToIntegralValue_77(decNumber *res, const decNumber *rhs,
3242 decContext *set) {
3243 decContext workset=*set; /* working context */
3244 workset.traps=0; /* no traps */
3245 uprv_decNumberToIntegralExactuprv_decNumberToIntegralExact_77(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 set->status|=workset.status&DEC_Invalid_operation0x00000080;
3249 return res;
3250 } /* 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/* ------------------------------------------------------------------ */
3267U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberXoruprv_decNumberXor_77(decNumber *res, const decNumber *lhs,
3268 const decNumber *rhs, decContext *set) {
3269 const Unituint8_t *ua, *ub; /* -> operands */
3270 const Unituint8_t *msua, *msub; /* -> operand msus */
3271 Unituint8_t *uc, *msuc; /* -> result and its msu */
3272 Intint32_t msudigs; /* digits in res msu */
3273 #if DECCHECK0
3274 if (decCheckOperands(res, lhs, rhs, set)) return res;
3275 #endif
3276
3277 if (lhs->exponent!=0 || decNumberIsSpecial(lhs)(((lhs)->bits&(0x40|0x20|0x10))!=0) || decNumberIsNegative(lhs)(((lhs)->bits&0x80)!=0)
3278 || rhs->exponent!=0 || decNumberIsSpecial(rhs)(((rhs)->bits&(0x40|0x20|0x10))!=0) || decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) {
3279 decStatus(res, DEC_Invalid_operation0x00000080, set);
3280 return res;
3281 }
3282 /* operands are valid */
3283 ua=lhs->lsu; /* bottom-up */
3284 ub=rhs->lsu; /* .. */
3285 uc=res->lsu; /* .. */
3286 msua=ua+D2U(lhs->digits)((lhs->digits)<=49?d2utable[lhs->digits]:((lhs->digits
)+1 -1)/1)
-1; /* -> msu of lhs */
3287 msub=ub+D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
-1; /* -> msu of rhs */
3288 msuc=uc+D2U(set->digits)((set->digits)<=49?d2utable[set->digits]:((set->digits
)+1 -1)/1)
-1; /* -> msu of result */
3289 msudigs=MSUDIGITS(set->digits)((set->digits)-(((set->digits)<=49?d2utable[set->
digits]:((set->digits)+1 -1)/1)-1)*1)
; /* [faster than remainder] */
3290 for (; uc<=msuc; ua++, ub++, uc++) { /* Unit loop */
3291 Unituint8_t a, b; /* extract units */
3292 if (ua>msua) a=0;
3293 else a=*ua;
3294 if (ub>msub) b=0;
3295 else b=*ub;
3296 *uc=0; /* can now write back */
3297 if (a|b) { /* maybe 1 bits to examine */
3298 Intint32_t i, j;
3299 /* This loop could be unrolled and/or use BIN2BCD tables */
3300 for (i=0; i<DECDPUN1; i++) {
3301 if ((a^b)&1) *uc=*uc+(Unituint8_t)powersDECPOWERS[i]; /* effect XOR */
3302 j=a%10;
3303 a=a/10;
3304 j|=b%10;
3305 b=b/10;
3306 if (j>1) {
3307 decStatus(res, DEC_Invalid_operation0x00000080, set);
3308 return res;
3309 }
3310 if (uc==msuc && i==msudigs-1) break; /* just did final digit */
3311 } /* each digit */
3312 } /* non-zero */
3313 } /* each unit */
3314 /* [here uc-1 is the msu of the result] */
3315 res->digits=decGetDigits(res->lsu, static_cast<int32_t>(uc-res->lsu));
3316 res->exponent=0; /* integer */
3317 res->bits=0; /* sign=0 */
3318 return res; /* [no status to set] */
3319 } /* 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/* ------------------------------------------------------------------ */
3332enum decClass uprv_decNumberClassuprv_decNumberClass_77(const decNumber *dn, decContext *set) {
3333 if (decNumberIsSpecial(dn)(((dn)->bits&(0x40|0x20|0x10))!=0)) {
3334 if (decNumberIsQNaN(dn)(((dn)->bits&(0x20))!=0)) return DEC_CLASS_QNAN;
3335 if (decNumberIsSNaN(dn)(((dn)->bits&(0x10))!=0)) return DEC_CLASS_SNAN;
3336 /* must be an infinity */
3337 if (decNumberIsNegative(dn)(((dn)->bits&0x80)!=0)) return DEC_CLASS_NEG_INF;
3338 return DEC_CLASS_POS_INF;
3339 }
3340 /* is finite */
3341 if (uprv_decNumberIsNormaluprv_decNumberIsNormal_77(dn, set)) { /* most common */
3342 if (decNumberIsNegative(dn)(((dn)->bits&0x80)!=0)) return DEC_CLASS_NEG_NORMAL;
3343 return DEC_CLASS_POS_NORMAL;
3344 }
3345 /* is subnormal or zero */
3346 if (decNumberIsZero(dn)(*(dn)->lsu==0 && (dn)->digits==1 && ((
(dn)->bits&(0x40|0x20|0x10))==0))
) { /* most common */
3347 if (decNumberIsNegative(dn)(((dn)->bits&0x80)!=0)) return DEC_CLASS_NEG_ZERO;
3348 return DEC_CLASS_POS_ZERO;
3349 }
3350 if (decNumberIsNegative(dn)(((dn)->bits&0x80)!=0)) return DEC_CLASS_NEG_SUBNORMAL;
3351 return DEC_CLASS_POS_SUBNORMAL;
3352 } /* 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/* ------------------------------------------------------------------ */
3360const char *uprv_decNumberClassToStringuprv_decNumberClassToString_77(enum decClass eclass) {
3361 if (eclass==DEC_CLASS_POS_NORMAL) return DEC_ClassString_PN"+Normal";
3362 if (eclass==DEC_CLASS_NEG_NORMAL) return DEC_ClassString_NN"-Normal";
3363 if (eclass==DEC_CLASS_POS_ZERO) return DEC_ClassString_PZ"+Zero";
3364 if (eclass==DEC_CLASS_NEG_ZERO) return DEC_ClassString_NZ"-Zero";
3365 if (eclass==DEC_CLASS_POS_SUBNORMAL) return DEC_ClassString_PS"+Subnormal";
3366 if (eclass==DEC_CLASS_NEG_SUBNORMAL) return DEC_ClassString_NS"-Subnormal";
3367 if (eclass==DEC_CLASS_POS_INF) return DEC_ClassString_PI"+Infinity";
3368 if (eclass==DEC_CLASS_NEG_INF) return DEC_ClassString_NI"-Infinity";
3369 if (eclass==DEC_CLASS_QNAN) return DEC_ClassString_QN"NaN";
3370 if (eclass==DEC_CLASS_SNAN) return DEC_ClassString_SN"sNaN";
3371 return DEC_ClassString_UN"Invalid"; /* Unknown */
3372 } /* 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/* ------------------------------------------------------------------ */
3385U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberCopyuprv_decNumberCopy_77(decNumber *dest, const decNumber *src) {
3386
3387 #if DECCHECK0
3388 if (src==nullptr) return uprv_decNumberZerouprv_decNumberZero_77(dest);
3389 #endif
3390
3391 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 dest->bits=src->bits;
3398 dest->exponent=src->exponent;
3399 dest->digits=src->digits;
3400 dest->lsu[0]=src->lsu[0];
3401 if (src->digits>DECDPUN1) { /* more Units to come */
3402 const Unituint8_t *smsup, *s; /* work */
3403 Unituint8_t *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 d=dest->lsu+1; /* -> first destination */
3407 smsup=src->lsu+D2U(src->digits)((src->digits)<=49?d2utable[src->digits]:((src->digits
)+1 -1)/1)
; /* -> source msu+1 */
3408 for (s=src->lsu+1; s<smsup; s++, d++) *d=*s;
3409 }
3410 return dest;
3411 } /* 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/* ------------------------------------------------------------------ */
3425U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberCopyAbsuprv_decNumberCopyAbs_77(decNumber *res, const decNumber *rhs) {
3426 #if DECCHECK0
3427 if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
3428 #endif
3429 uprv_decNumberCopyuprv_decNumberCopy_77(res, rhs);
3430 res->bits&=~DECNEG0x80; /* turn off sign */
3431 return res;
3432 } /* 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/* ------------------------------------------------------------------ */
3446U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberCopyNegateuprv_decNumberCopyNegate_77(decNumber *res, const decNumber *rhs) {
3447 #if DECCHECK0
3448 if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
3449 #endif
3450 uprv_decNumberCopyuprv_decNumberCopy_77(res, rhs);
3451 res->bits^=DECNEG0x80; /* invert the sign */
3452 return res;
3453 } /* 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/* ------------------------------------------------------------------ */
3467U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberCopySignuprv_decNumberCopySign_77(decNumber *res, const decNumber *lhs,
3468 const decNumber *rhs) {
3469 uByteuint8_t sign; /* rhs sign */
3470 #if DECCHECK0
3471 if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
3472 #endif
3473 sign=rhs->bits & DECNEG0x80; /* save sign bit */
3474 uprv_decNumberCopyuprv_decNumberCopy_77(res, lhs);
3475 res->bits&=~DECNEG0x80; /* clear the sign */
3476 res->bits|=sign; /* set from rhs */
3477 return res;
3478 } /* 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/* ------------------------------------------------------------------ */
3490U_CAPIextern "C" uByteuint8_t * U_EXPORT2 uprv_decNumberGetBCDuprv_decNumberGetBCD_77(const decNumber *dn, uByteuint8_t *bcd) {
3491 uByteuint8_t *ub=bcd+dn->digits-1; /* -> lsd */
3492 const Unituint8_t *up=dn->lsu; /* Unit pointer, -> lsu */
3493
3494 #if DECDPUN1==1 /* trivial simple copy */
3495 for (; ub>=bcd; ub--, up++) *ub=*up;
3496 #else /* chopping needed */
3497 uIntuint32_t u=*up; /* work */
3498 uIntuint32_t cut=DECDPUN1; /* downcounter through unit */
3499 for (; ub>=bcd; ub--) {
3500 *ub=(uByteuint8_t)(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=DECDPUN1;
3507 }
3508 #endif
3509 return bcd;
3510 } /* 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/* ------------------------------------------------------------------ */
3524U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberSetBCDuprv_decNumberSetBCD_77(decNumber *dn, const uByteuint8_t *bcd, uIntuint32_t n) {
3525 Unituint8_t *up=dn->lsu+D2U(dn->digits)((dn->digits)<=49?d2utable[dn->digits]:((dn->digits
)+1 -1)/1)
-1; /* -> msu [target pointer] */
3526 const uByteuint8_t *ub=bcd; /* -> source msd */
3527
3528 #if DECDPUN1==1 /* trivial simple copy */
3529 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 Intint32_t cut=MSUDIGITS(n)((n)-(((n)<=49?d2utable[n]:((n)+1 -1)/1)-1)*1); /* [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)(((*up)<<1)+((*up)<<3))+*ub;
3536 cut=DECDPUN1; /* next Unit has all digits */
3537 }
3538 #endif
3539 dn->digits=n; /* set digit count */
3540 return dn;
3541 } /* 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/* ------------------------------------------------------------------ */
3549Intint32_t uprv_decNumberIsNormaluprv_decNumberIsNormal_77(const decNumber *dn, decContext *set) {
3550 Intint32_t ae; /* adjusted exponent */
3551 #if DECCHECK0
3552 if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
3553 #endif
3554
3555 if (decNumberIsSpecial(dn)(((dn)->bits&(0x40|0x20|0x10))!=0)) return 0; /* not finite */
3556 if (decNumberIsZero(dn)(*(dn)->lsu==0 && (dn)->digits==1 && ((
(dn)->bits&(0x40|0x20|0x10))==0))
) return 0; /* not non-zero */
3557
3558 ae=dn->exponent+dn->digits-1; /* adjusted exponent */
3559 if (ae<set->emin) return 0; /* is subnormal */
3560 return 1;
3561 } /* 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/* ------------------------------------------------------------------ */
3569Intint32_t uprv_decNumberIsSubnormaluprv_decNumberIsSubnormal_77(const decNumber *dn, decContext *set) {
3570 Intint32_t ae; /* adjusted exponent */
3571 #if DECCHECK0
3572 if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
3573 #endif
3574
3575 if (decNumberIsSpecial(dn)(((dn)->bits&(0x40|0x20|0x10))!=0)) return 0; /* not finite */
3576 if (decNumberIsZero(dn)(*(dn)->lsu==0 && (dn)->digits==1 && ((
(dn)->bits&(0x40|0x20|0x10))==0))
) return 0; /* not non-zero */
3577
3578 ae=dn->exponent+dn->digits-1; /* adjusted exponent */
3579 if (ae<set->emin) return 1; /* is subnormal */
3580 return 0;
3581 } /* 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/* ------------------------------------------------------------------ */
3593U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberTrimuprv_decNumberTrim_77(decNumber *dn) {
3594 Intint32_t dropped; /* work */
3595 decContext set; /* .. */
3596 #if DECCHECK0
3597 if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn;
3598 #endif
3599 uprv_decContextDefaultuprv_decContextDefault_77(&set, DEC_INIT_BASE0); /* clamp=0 */
3600 return decTrim(dn, &set, 0, 1, &dropped);
3601 } /* decNumberTrim */
3602
3603/* ------------------------------------------------------------------ */
3604/* decNumberVersion -- return the name and version of this module */
3605/* */
3606/* No error is possible. */
3607/* ------------------------------------------------------------------ */
3608const char * uprv_decNumberVersionuprv_decNumberVersion_77() {
3609 return DECVERSION"decNumber 3.61";
3610 } /* 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. */
3621U_CAPIextern "C" decNumber * U_EXPORT2 uprv_decNumberZerouprv_decNumberZero_77(decNumber *dn) {
3622
3623 #if DECCHECK0
3624 if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
3625 #endif
3626
3627 dn->bits=0;
3628 dn->exponent=0;
3629 dn->digits=1;
3630 dn->lsu[0]=0;
3631 return dn;
3632 } /* 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. */
3654static void decToString(const decNumber *dn, char *string, Flaguint8_t eng) {
3655 Intint32_t exp=dn->exponent; /* local copy */
3656 Intint32_t e; /* E-part value */
3657 Intint32_t pre; /* digits before the '.' */
3658 Intint32_t cut; /* for counting digits in a Unit */
3659 char *c=string; /* work [output pointer] */
3660 const Unituint8_t *up=dn->lsu+D2U(dn->digits)((dn->digits)<=49?d2utable[dn->digits]:((dn->digits
)+1 -1)/1)
-1; /* -> msu [input pointer] */
3661 uIntuint32_t u, pow; /* work */
3662
3663 #if DECCHECK0
3664 if (decCheckOperands(DECUNRESU, dn, DECUNUSED, DECUNCONT)) {
3665 strcpy(string, "?");
3666 return;}
3667 #endif
3668
3669 if (decNumberIsNegative(dn)(((dn)->bits&0x80)!=0)) { /* Negatives get a minus */
3670 *c='-';
3671 c++;
3672 }
3673 if (dn->bits&DECSPECIAL(0x40|0x20|0x10)) { /* Is a special value */
3674 if (decNumberIsInfinite(dn)(((dn)->bits&0x40)!=0)) {
3675 strcpy(c, "Inf");
3676 strcpy(c+3, "inity");
3677 return;}
3678 /* a NaN */
3679 if (dn->bits&DECSNAN0x10) { /* signalling NaN */
3680 *c='s';
3681 c++;
3682 }
3683 strcpy(c, "NaN");
3684 c+=3; /* step past */
3685 /* if not a clean non-zero coefficient, that's all there is in a */
3686 /* NaN string */
3687 if (exp!=0 || (*dn->lsu==0 && dn->digits==1)) return;
3688 /* [drop through to add integer] */
3689 }
3690
3691 /* calculate how many digits in msu, and hence first cut */
3692 cut=MSUDIGITS(dn->digits)((dn->digits)-(((dn->digits)<=49?d2utable[dn->digits
]:((dn->digits)+1 -1)/1)-1)*1)
; /* [faster than remainder] */
3693 cut--; /* power of ten for digit */
3694
3695 if (exp==0) { /* simple integer [common fastpath] */
3696 for (;up>=dn->lsu; up--) { /* each Unit from msu */
3697 u=*up; /* contains DECDPUN digits to lay out */
3698 for (; cut>=0; c++, cut--) TODIGIT(u, cut, c, pow)do { *(c)='0'; pow=DECPOWERS[cut]*2; if ((u)>pow) { pow*=4
; if ((u)>=pow) {(u)-=pow; *(c)+=8;} pow/=2; if ((u)>=pow
) {(u)-=pow; *(c)+=4;} pow/=2; } if ((u)>=pow) {(u)-=pow; *
(c)+=2;} pow/=2; if ((u)>=pow) {(u)-=pow; *(c)+=1;} } while
(false)
;
3699 cut=DECDPUN1-1; /* next Unit has all digits */
3700 }
3701 *c='\0'; /* terminate the string */
3702 return;}
3703
3704 /* non-0 exponent -- assume plain form */
3705 pre=dn->digits+exp; /* digits before '.' */
3706 e=0; /* no E */
3707 if ((exp>0) || (pre<-5)) { /* need exponential form */
3708 e=exp+dn->digits-1; /* calculate E value */
3709 pre=1; /* assume one digit before '.' */
3710 if (eng && (e!=0)) { /* engineering: may need to adjust */
3711 Intint32_t adj; /* adjustment */
3712 /* The C remainder operator is undefined for negative numbers, so */
3713 /* a positive remainder calculation must be used here */
3714 if (e<0) {
3715 adj=(-e)%3;
3716 if (adj!=0) adj=3-adj;
3717 }
3718 else { /* e>0 */
3719 adj=e%3;
3720 }
3721 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 if (!ISZERO(dn)(*(dn)->lsu==0 && (dn)->digits==1 && ((
(dn)->bits&(0x40|0x20|0x10))==0))
) pre+=adj;
3726 else { /* is zero */
3727 if (adj!=0) { /* 0.00Esnn needed */
3728 e=e+3;
3729 pre=-(2-adj);
3730 }
3731 } /* zero */
3732 } /* eng */
3733 } /* need exponent */
3734
3735 /* lay out the digits of the coefficient, adding 0s and . as needed */
3736 u=*up;
3737 if (pre>0) { /* xxx.xxx or xx00 (engineering) form */
3738 Intint32_t n=pre;
3739 for (; pre>0; pre--, c++, cut--) {
3740 if (cut<0) { /* need new Unit */
3741 if (up==dn->lsu) break; /* out of input digits (pre>digits) */
3742 up--;
3743 cut=DECDPUN1-1;
3744 u=*up;
3745 }
3746 TODIGIT(u, cut, c, pow)do { *(c)='0'; pow=DECPOWERS[cut]*2; if ((u)>pow) { pow*=4
; if ((u)>=pow) {(u)-=pow; *(c)+=8;} pow/=2; if ((u)>=pow
) {(u)-=pow; *(c)+=4;} pow/=2; } if ((u)>=pow) {(u)-=pow; *
(c)+=2;} pow/=2; if ((u)>=pow) {(u)-=pow; *(c)+=1;} } while
(false)
;
3747 }
3748 if (n<dn->digits) { /* more to come, after '.' */
3749 *c='.'; c++;
3750 for (;; c++, cut--) {
3751 if (cut<0) { /* need new Unit */
3752 if (up==dn->lsu) break; /* out of input digits */
3753 up--;
3754 cut=DECDPUN1-1;
3755 u=*up;
3756 }
3757 TODIGIT(u, cut, c, pow)do { *(c)='0'; pow=DECPOWERS[cut]*2; if ((u)>pow) { pow*=4
; if ((u)>=pow) {(u)-=pow; *(c)+=8;} pow/=2; if ((u)>=pow
) {(u)-=pow; *(c)+=4;} pow/=2; } if ((u)>=pow) {(u)-=pow; *
(c)+=2;} pow/=2; if ((u)>=pow) {(u)-=pow; *(c)+=1;} } while
(false)
;
3758 }
3759 }
3760 else for (; pre>0; pre--, c++) *c='0'; /* 0 padding (for engineering) needed */
3761 }
3762 else { /* 0.xxx or 0.000xxx form */
3763 *c='0'; c++;
3764 *c='.'; c++;
3765 for (; pre<0; pre++, c++) *c='0'; /* add any 0's after '.' */
3766 for (; ; c++, cut--) {
3767 if (cut<0) { /* need new Unit */
3768 if (up==dn->lsu) break; /* out of input digits */
3769 up--;
3770 cut=DECDPUN1-1;
3771 u=*up;
3772 }
3773 TODIGIT(u, cut, c, pow)do { *(c)='0'; pow=DECPOWERS[cut]*2; if ((u)>pow) { pow*=4
; if ((u)>=pow) {(u)-=pow; *(c)+=8;} pow/=2; if ((u)>=pow
) {(u)-=pow; *(c)+=4;} pow/=2; } if ((u)>=pow) {(u)-=pow; *
(c)+=2;} pow/=2; if ((u)>=pow) {(u)-=pow; *(c)+=1;} } while
(false)
;
3774 }
3775 }
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 if (e!=0) {
3781 Flaguint8_t had=0; /* 1=had non-zero */
3782 *c='E'; c++;
3783 *c='+'; c++; /* assume positive */
3784 u=e; /* .. */
3785 if (e<0) {
3786 *(c-1)='-'; /* oops, need - */
3787 u=-e; /* uInt, please */
3788 }
3789 /* lay out the exponent [_itoa or equivalent is not ANSI C] */
3790 for (cut=9; cut>=0; cut--) {
3791 TODIGIT(u, cut, c, pow)do { *(c)='0'; pow=DECPOWERS[cut]*2; if ((u)>pow) { pow*=4
; if ((u)>=pow) {(u)-=pow; *(c)+=8;} pow/=2; if ((u)>=pow
) {(u)-=pow; *(c)+=4;} pow/=2; } if ((u)>=pow) {(u)-=pow; *
(c)+=2;} pow/=2; if ((u)>=pow) {(u)-=pow; *(c)+=1;} } while
(false)
;
3792 if (*c=='0' && !had) continue; /* skip leading zeros */
3793 had=1; /* had non-0 */
3794 c++; /* step for next */
3795 } /* cut */
3796 }
3797 *c='\0'; /* terminate the string (all paths) */
3798 } /* 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/* ------------------------------------------------------------------ */
3835static decNumber * decAddOp(decNumber *res, const decNumber *lhs,
3836 const decNumber *rhs, decContext *set,
3837 uByteuint8_t negate, uIntuint32_t *status) {
3838 #if DECSUBSET0
3839 decNumber *alloclhs=nullptr; /* non-nullptr if rounded lhs allocated */
3840 decNumber *allocrhs=nullptr; /* .., rhs */
3841 #endif
3842 Intint32_t rhsshift; /* working shift (in Units) */
3843 Intint32_t maxdigits; /* longest logical length */
3844 Intint32_t mult; /* multiplier */
3845 Intint32_t residue; /* rounding accumulator */
3846 uByteuint8_t bits; /* result bits */
3847 Flaguint8_t diffsign; /* non-0 if arguments have different sign */
3848 Unituint8_t *acc; /* accumulator for result */
3849 Unituint8_t accbuff[SD2U(DECBUFFER*2+20)(((36*2+20)+1 -1)/1)]; /* local buffer [*2+20 reduces many */
3850 /* allocations when called from */
3851 /* other operations, notable exp] */
3852 Unituint8_t *allocacc=nullptr; /* -> allocated acc buffer, iff allocated */
3853 Intint32_t reqdigits=set->digits; /* local copy; requested DIGITS */
3854 Intint32_t padding; /* work */
3855
3856 #if DECCHECK0
3857 if (decCheckOperands(res, lhs, rhs, set)) return res;
3858 #endif
3859
3860 do { /* protect allocated storage */
3861 #if DECSUBSET0
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 diffsign = static_cast<Flaguint8_t>((lhs->bits ^ rhs->bits ^ negate) & DECNEG0x80);
3880
3881 /* handle infinities and NaNs */
3882 if (SPECIALARGS((lhs->bits | rhs->bits) & (0x40|0x20|0x10))) { /* a special bit set */
3883 if (SPECIALARGS((lhs->bits | rhs->bits) & (0x40|0x20|0x10)) & (DECSNAN0x10 | DECNAN0x20)) /* a NaN */
3884 decNaNs(res, lhs, rhs, set, status);
3885 else { /* one or two infinities */
3886 if (decNumberIsInfinite(lhs)(((lhs)->bits&0x40)!=0)) { /* LHS is infinity */
3887 /* two infinities with different signs is invalid */
3888 if (decNumberIsInfinite(rhs)(((rhs)->bits&0x40)!=0) && diffsign) {
3889 *status|=DEC_Invalid_operation0x00000080;
3890 break;
3891 }
3892 bits=lhs->bits & DECNEG0x80; /* get sign from LHS */
3893 }
3894 else bits=(rhs->bits^negate) & DECNEG0x80;/* RHS must be Infinity */
3895 bits|=DECINF0x40;
3896 uprv_decNumberZerouprv_decNumberZero_77(res);
3897 res->bits=bits; /* set +/- infinity */
3898 } /* an infinity */
3899 break;
3900 }
3901
3902 /* Quick exit for add 0s; return the non-0, modified as need be */
3903 if (ISZERO(lhs)(*(lhs)->lsu==0 && (lhs)->digits==1 && (
((lhs)->bits&(0x40|0x20|0x10))==0))
) {
3904 Intint32_t adjust; /* work */
3905 Intint32_t lexp=lhs->exponent; /* save in case LHS==RES */
3906 bits=lhs->bits; /* .. */
3907 residue=0; /* clear accumulator */
3908 decCopyFit(res, rhs, set, &residue, status); /* copy (as needed) */
3909 res->bits^=negate; /* flip if rhs was negated */
3910 #if DECSUBSET0
3911 if (set->extended) { /* exponents on zeros count */
3912 #endif
3913 /* exponent will be the lower of the two */
3914 adjust=lexp-res->exponent; /* adjustment needed [if -ve] */
3915 if (ISZERO(res)(*(res)->lsu==0 && (res)->digits==1 && (
((res)->bits&(0x40|0x20|0x10))==0))
) { /* both 0: special IEEE 754 rules */
3916 if (adjust<0) res->exponent=lexp; /* set exponent */
3917 /* 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0 */
3918 if (diffsign) {
3919 if (set->round!=DEC_ROUND_FLOOR) res->bits=0;
3920 else res->bits=DECNEG0x80; /* preserve 0 sign */
3921 }
3922 }
3923 else { /* non-0 res */
3924 if (adjust<0) { /* 0-padding needed */
3925 if ((res->digits-adjust)>set->digits) {
3926 adjust=res->digits-set->digits; /* to fit exactly */
3927 *status|=DEC_Rounded0x00000800; /* [but exact] */
3928 }
3929 res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
3930 res->exponent+=adjust; /* set the exponent. */
3931 }
3932 } /* non-0 res */
3933 #if DECSUBSET0
3934 } /* extended */
3935 #endif
3936 decFinish(res, set, &residue, status)decFinalize(res,set,&residue,status); /* clean and finalize */
3937 break;}
3938
3939 if (ISZERO(rhs)(*(rhs)->lsu==0 && (rhs)->digits==1 && (
((rhs)->bits&(0x40|0x20|0x10))==0))
) { /* [lhs is non-zero] */
3940 Intint32_t adjust; /* work */
3941 Intint32_t rexp=rhs->exponent; /* save in case RHS==RES */
3942 bits=rhs->bits; /* be clean */
3943 residue=0; /* clear accumulator */
3944 decCopyFit(res, lhs, set, &residue, status); /* copy (as needed) */
3945 #if DECSUBSET0
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 adjust=rexp-res->exponent; /* adjustment needed [if -ve] */
3951 if (adjust<0) { /* 0-padding needed */
3952 if ((res->digits-adjust)>set->digits) {
3953 adjust=res->digits-set->digits; /* to fit exactly */
3954 *status|=DEC_Rounded0x00000800; /* [but exact] */
3955 }
3956 res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
3957 res->exponent+=adjust; /* set the exponent. */
3958 }
3959 #if DECSUBSET0
3960 } /* extended */
3961 #endif
3962 decFinish(res, set, &residue, status)decFinalize(res,set,&residue,status); /* clean and finalize */
3963 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 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 if (padding==0
3975 && rhs->digits<=DECDPUN1
3976 && rhs->exponent>=set->emin /* [some normals drop through] */
3977 && rhs->exponent<=set->emax-set->digits+1 /* [could clamp] */
3978 && rhs->digits<=reqdigits
3979 && lhs->digits<=reqdigits) {
3980 Intint32_t partial=*lhs->lsu;
3981 if (!diffsign) { /* adding */
3982 partial+=*rhs->lsu;
3983 if ((partial<=DECDPUNMAX9) /* result fits in unit */
3984 && (lhs->digits>=DECDPUN1 || /* .. and no digits-count change */
3985 partial < static_cast<Intint32_t>(powersDECPOWERS[lhs->digits]))) { /* .. */
3986 if (res!=lhs) uprv_decNumberCopyuprv_decNumberCopy_77(res, lhs); /* not in place */
3987 *res->lsu = static_cast<Unituint8_t>(partial); /* [copy could have overwritten RHS] */
3988 break;
3989 }
3990 /* else drop out for careful add */
3991 }
3992 else { /* signs differ */
3993 partial-=*rhs->lsu;
3994 if (partial>0) { /* no borrow needed, and non-0 result */
3995 if (res!=lhs) uprv_decNumberCopyuprv_decNumberCopy_77(res, lhs); /* not in place */
3996 *res->lsu = static_cast<Unituint8_t>(partial);
3997 /* this could have reduced digits [but result>0] */
3998 res->digits=decGetDigits(res->lsu, D2U(res->digits)((res->digits)<=49?d2utable[res->digits]:((res->digits
)+1 -1)/1)
);
3999 break;
4000 }
4001 /* else drop out for careful subtract */
4002 }
4003 }
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 rhsshift=0; /* rhs shift to left (padding) in Units */
4013 bits=lhs->bits; /* assume sign is that of LHS */
4014 mult=1; /* likely multiplier */
4015
4016 /* [if padding==0 the operands are aligned; no padding is needed] */
4017 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 Flaguint8_t swapped=0;
4022 if (padding<0) { /* LHS needs the padding */
4023 const decNumber *t;
4024 padding=-padding; /* will be +ve */
4025 bits = static_cast<uByteuint8_t>(rhs->bits ^ negate); /* assumed sign is now that of RHS */
4026 t=lhs; lhs=rhs; rhs=t;
4027 swapped=1;
4028 }
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 if (rhs->digits+padding > lhs->digits+reqdigits+1) {
4034 /* The RHS is sufficient */
4035 /* for residue use the relative sign indication... */
4036 Intint32_t shift=reqdigits-rhs->digits; /* left shift needed */
4037 residue=1; /* residue for rounding */
4038 if (diffsign) residue=-residue; /* signs differ */
4039 /* copy, shortening if necessary */
4040 decCopyFit(res, rhs, set, &residue, status);
4041 /* if it was already shorter, then need to pad with zeros */
4042 if (shift>0) {
4043 res->digits=decShiftToMost(res->lsu, res->digits, shift);
4044 res->exponent-=shift; /* adjust the exponent. */
4045 }
4046 /* flip the result sign if unswapped and rhs was negated */
4047 if (!swapped) res->bits^=negate;
4048 decFinish(res, set, &residue, status)decFinalize(res,set,&residue,status); /* done */
4049 break;}
4050
4051 /* LHS digits may affect result */
4052 rhsshift=D2U(padding+1)((padding+1)<=49?d2utable[padding+1]:((padding+1)+1 -1)/1)-1; /* this much by Unit shift .. */
4053 mult=powersDECPOWERS[padding-(rhsshift*DECDPUN1)]; /* .. this by multiplication */
4054 } /* padding needed */
4055
4056 if (diffsign) mult=-mult; /* signs differ */
4057
4058 /* determine the longer operand */
4059 maxdigits=rhs->digits+padding; /* virtual length of RHS */
4060 if (lhs->digits>maxdigits) maxdigits=lhs->digits;
4061
4062 /* Decide on the result buffer to use; if possible place directly */
4063 /* into result. */
4064 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 if ((maxdigits>=reqdigits) /* is, or could be, too large */
4069 || (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 Intint32_t need=D2U(maxdigits)((maxdigits)<=49?d2utable[maxdigits]:((maxdigits)+1 -1)/1)+1;
4073 acc=accbuff; /* assume use local buffer */
4074 if (need*sizeof(Unituint8_t)>sizeof(accbuff)) {
4075 /* printf("malloc add %ld %ld\n", need, sizeof(accbuff)); */
4076 allocacc = static_cast<Unituint8_t*>(malloc(need * sizeof(Unit))uprv_malloc_77(need * sizeof(uint8_t)));
4077 if (allocacc==nullptr) { /* hopeless -- abandon */
4078 *status|=DEC_Insufficient_storage0x00000010;
4079 break;}
4080 acc=allocacc;
4081 }
4082 }
4083
4084 res->bits = static_cast<uByteuint8_t>(bits & DECNEG0x80); /* it's now safe to overwrite.. */
4085 res->exponent=lhs->exponent; /* .. operands (even if aliased) */
4086
4087 #if DECTRACE0
4088 decDumpAr('A', lhs->lsu, D2U(lhs->digits)((lhs->digits)<=49?d2utable[lhs->digits]:((lhs->digits
)+1 -1)/1)
);
4089 decDumpAr('B', rhs->lsu, D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
);
4090 printf(" :h: %ld %ld\n", rhsshift, mult);
4091 #endif
4092
4093 /* add [A+B*m] or subtract [A+B*(-m)] */
4094 U_ASSERT(rhs->digits > 0)(static_cast <bool> (rhs->digits > 0) ? void (0) :
__assert_fail ("rhs->digits > 0", __builtin_FILE (), __builtin_LINE
(), __extension__ __PRETTY_FUNCTION__))
;
4095 U_ASSERT(lhs->digits > 0)(static_cast <bool> (lhs->digits > 0) ? void (0) :
__assert_fail ("lhs->digits > 0", __builtin_FILE (), __builtin_LINE
(), __extension__ __PRETTY_FUNCTION__))
;
4096 res->digits=decUnitAddSub(lhs->lsu, D2U(lhs->digits)((lhs->digits)<=49?d2utable[lhs->digits]:((lhs->digits
)+1 -1)/1)
,
4097 rhs->lsu, D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
,
4098 rhsshift, acc, mult)
4099 *DECDPUN1; /* [units -> digits] */
4100 if (res->digits<0) { /* borrowed... */
4101 res->digits=-res->digits;
4102 res->bits^=DECNEG0x80; /* flip the sign */
4103 }
4104 #if DECTRACE0
4105 decDumpAr('+', acc, D2U(res->digits)((res->digits)<=49?d2utable[res->digits]:((res->digits
)+1 -1)/1)
);
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 residue=0; /* clear accumulator */
4112 if (acc!=res->lsu) {
4113 #if DECSUBSET0
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 if (res->digits>reqdigits)
4119 res->digits=decGetDigits(acc, D2U(res->digits)((res->digits)<=49?d2utable[res->digits]:((res->digits
)+1 -1)/1)
);
4120 decSetCoeff(res, set, acc, res->digits, &residue, status);
4121 #if DECSUBSET0
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)((res->digits)<=49?d2utable[res->digits]:((res->digits
)+1 -1)/1)
)=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)((res->digits)<=49?d2utable[res->digits]:((res->digits
)+1 -1)/1)
);
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 } /* used buffer */
4152
4153 /* strip leading zeros [these were left on in case of subset subtract] */
4154 res->digits=decGetDigits(res->lsu, D2U(res->digits)((res->digits)<=49?d2utable[res->digits]:((res->digits
)+1 -1)/1)
);
4155
4156 /* apply checks and rounding */
4157 decFinish(res, set, &residue, status)decFinalize(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 if (ISZERO(res)(*(res)->lsu==0 && (res)->digits==1 && (
((res)->bits&(0x40|0x20|0x10))==0))
&& diffsign
4164 #if DECSUBSET0
4165 && set->extended
4166 #endif
4167 && (*status&DEC_Inexact0x00000020)==0) {
4168 if (set->round==DEC_ROUND_FLOOR) res->bits|=DECNEG0x80; /* sign - */
4169 else res->bits&=~DECNEG0x80; /* sign + */
4170 }
4171 } while(0); /* end protected */
4172
4173 if (allocacc!=nullptr) free(allocacc)uprv_free_77(allocacc); /* drop any storage used */
4174 #if DECSUBSET0
4175 if (allocrhs!=nullptr) free(allocrhs)uprv_free_77(allocrhs); /* .. */
4176 if (alloclhs!=nullptr) free(alloclhs)uprv_free_77(alloclhs); /* .. */
4177 #endif
4178 return res;
4179 } /* 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/* ------------------------------------------------------------------ */
4251static decNumber * decDivideOp(decNumber *res,
4252 const decNumber *lhs, const decNumber *rhs,
4253 decContext *set, Flaguint8_t op, uIntuint32_t *status) {
4254 #if DECSUBSET0
4255 decNumber *alloclhs=nullptr; /* non-nullptr if rounded lhs allocated */
4256 decNumber *allocrhs=nullptr; /* .., rhs */
4257 #endif
4258 Unituint8_t accbuff[SD2U(DECBUFFER+DECDPUN+10)(((36 +1 +10)+1 -1)/1)]; /* local buffer */
4259 Unituint8_t *acc=accbuff; /* -> accumulator array for result */
4260 Unituint8_t *allocacc=nullptr; /* -> allocated buffer, iff allocated */
4261 Unituint8_t *accnext; /* -> where next digit will go */
4262 Intint32_t acclength; /* length of acc needed [Units] */
4263 Intint32_t accunits; /* count of units accumulated */
4264 Intint32_t accdigits; /* count of digits accumulated */
4265
4266 Unituint8_t varbuff[SD2U(DECBUFFER*2+DECDPUN)(((36*2+1)+1 -1)/1)]; /* buffer for var1 */
4267 Unituint8_t *var1=varbuff; /* -> var1 array for long subtraction */
4268 Unituint8_t *varalloc=nullptr; /* -> allocated buffer, iff used */
4269 Unituint8_t *msu1; /* -> msu of var1 */
4270
4271 const Unituint8_t *var2; /* -> var2 array */
4272 const Unituint8_t *msu2; /* -> msu of var2 */
4273 Intint32_t msu2plus; /* msu2 plus one [does not vary] */
4274 eIntint32_t msu2pair; /* msu2 pair plus one [does not vary] */
4275
4276 Intint32_t var1units, var2units; /* actual lengths */
4277 Intint32_t var2ulen; /* logical length (units) */
4278 Intint32_t var1initpad=0; /* var1 initial padding (digits) */
4279 Intint32_t maxdigits; /* longest LHS or required acc length */
4280 Intint32_t mult; /* multiplier for subtraction */
4281 Unituint8_t thisunit; /* current unit being accumulated */
4282 Intint32_t residue; /* for rounding */
4283 Intint32_t reqdigits=set->digits; /* requested DIGITS */
4284 Intint32_t exponent; /* working exponent */
4285 Intint32_t maxexponent=0; /* DIVIDE maximum exponent if unrounded */
4286 uByteuint8_t bits; /* working sign */
4287 Unituint8_t *target; /* work */
4288 const Unituint8_t *source; /* .. */
4289 uIntuint32_t const *pow; /* .. */
4290 Intint32_t shift, cut; /* .. */
4291 #if DECSUBSET0
4292 Intint32_t dropped; /* work */
4293 #endif
4294
4295 #if DECCHECK0
4296 if (decCheckOperands(res, lhs, rhs, set)) return res;
4297 #endif
4298
4299 do { /* protect allocated storage */
4300 #if DECSUBSET0
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 bits=(lhs->bits^rhs->bits)&DECNEG0x80; /* assumed sign for divisions */
4318
4319 /* handle infinities and NaNs */
4320 if (SPECIALARGS((lhs->bits | rhs->bits) & (0x40|0x20|0x10))) { /* a special bit set */
4321 if (SPECIALARGS((lhs->bits | rhs->bits) & (0x40|0x20|0x10)) & (DECSNAN0x10 | DECNAN0x20)) { /* one or two NaNs */
4322 decNaNs(res, lhs, rhs, set, status);
4323 break;
4324 }
4325 /* one or two infinities */
4326 if (decNumberIsInfinite(lhs)(((lhs)->bits&0x40)!=0)) { /* LHS (dividend) is infinite */
4327 if (decNumberIsInfinite(rhs)(((rhs)->bits&0x40)!=0) || /* two infinities are invalid .. */
4328 op & (REMAINDER0x40 | REMNEAR0x10)) { /* as is remainder of infinity */
4329 *status|=DEC_Invalid_operation0x00000080;
4330 break;
4331 }
4332 /* [Note that infinity/0 raises no exceptions] */
4333 uprv_decNumberZerouprv_decNumberZero_77(res);
4334 res->bits=bits|DECINF0x40; /* set +/- infinity */
4335 break;
4336 }
4337 else { /* RHS (divisor) is infinite */
4338 residue=0;
4339 if (op&(REMAINDER0x40|REMNEAR0x10)) {
4340 /* result is [finished clone of] lhs */
4341 decCopyFit(res, lhs, set, &residue, status);
4342 }
4343 else { /* a division */
4344 uprv_decNumberZerouprv_decNumberZero_77(res);
4345 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 if (op&DIVIDE0x80) {
4349 res->exponent=set->emin-set->digits+1;
4350 *status|=DEC_Clamped0x00000400;
4351 }
4352 }
4353 decFinish(res, set, &residue, status)decFinalize(res,set,&residue,status);
4354 break;
4355 }
4356 }
4357
4358 /* handle 0 rhs (x/0) */
4359 if (ISZERO(rhs)(*(rhs)->lsu==0 && (rhs)->digits==1 && (
((rhs)->bits&(0x40|0x20|0x10))==0))
) { /* x/0 is always exceptional */
4360 if (ISZERO(lhs)(*(lhs)->lsu==0 && (lhs)->digits==1 && (
((lhs)->bits&(0x40|0x20|0x10))==0))
) {
4361 uprv_decNumberZerouprv_decNumberZero_77(res); /* [after lhs test] */
4362 *status|=DEC_Division_undefined0x00000008;/* 0/0 will become NaN */
4363 }
4364 else {
4365 uprv_decNumberZerouprv_decNumberZero_77(res);
4366 if (op&(REMAINDER0x40|REMNEAR0x10)) *status|=DEC_Invalid_operation0x00000080;
4367 else {
4368 *status|=DEC_Division_by_zero0x00000002; /* x/0 */
4369 res->bits=bits|DECINF0x40; /* .. is +/- Infinity */
4370 }
4371 }
4372 break;}
4373
4374 /* handle 0 lhs (0/x) */
4375 if (ISZERO(lhs)(*(lhs)->lsu==0 && (lhs)->digits==1 && (
((lhs)->bits&(0x40|0x20|0x10))==0))
) { /* 0/x [x!=0] */
4376 #if DECSUBSET0
4377 if (!set->extended) uprv_decNumberZerouprv_decNumberZero_77(res);
4378 else {
4379 #endif
4380 if (op&DIVIDE0x80) {
4381 residue=0;
4382 exponent=lhs->exponent-rhs->exponent; /* ideal exponent */
4383 uprv_decNumberCopyuprv_decNumberCopy_77(res, lhs); /* [zeros always fit] */
4384 res->bits=bits; /* sign as computed */
4385 res->exponent=exponent; /* exponent, too */
4386 decFinalize(res, set, &residue, status); /* check exponent */
4387 }
4388 else if (op&DIVIDEINT0x20) {
4389 uprv_decNumberZerouprv_decNumberZero_77(res); /* integer 0 */
4390 res->bits=bits; /* sign as computed */
4391 }
4392 else { /* a remainder */
4393 exponent=rhs->exponent; /* [save in case overwrite] */
4394 uprv_decNumberCopyuprv_decNumberCopy_77(res, lhs); /* [zeros always fit] */
4395 if (exponent<res->exponent) res->exponent=exponent; /* use lower */
4396 }
4397 #if DECSUBSET0
4398 }
4399 #endif
4400 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 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 if (exponent<0 && !(op==DIVIDE0x80)) {
4412 if (op&DIVIDEINT0x20) {
4413 uprv_decNumberZerouprv_decNumberZero_77(res); /* integer part is 0 */
4414 #if DECSUBSET0
4415 if (set->extended)
4416 #endif
4417 res->bits=bits; /* set +/- zero */
4418 break;}
4419 /* fastpath remainders so long as the lhs has the smaller */
4420 /* (or equal) exponent */
4421 if (lhs->exponent<=rhs->exponent) {
4422 if (op&REMAINDER0x40 || exponent<-1) {
4423 /* It is REMAINDER or safe REMNEAR; result is [finished */
4424 /* clone of] lhs (r = x - 0*y) */
4425 residue=0;
4426 decCopyFit(res, lhs, set, &residue, status);
4427 decFinish(res, set, &residue, status)decFinalize(res,set,&residue,status);
4428 break;
4429 }
4430 /* [unsafe REMNEAR drops through] */
4431 }
4432 } /* 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 acclength=D2U(reqdigits+DECDPUN)((reqdigits+1)<=49?d2utable[reqdigits+1]:((reqdigits+1)+1 -
1)/1)
; /* in Units */
4439 if (acclength*sizeof(Unituint8_t)>sizeof(accbuff)) {
4440 /* printf("malloc dvacc %ld units\n", acclength); */
4441 allocacc = static_cast<Unituint8_t*>(malloc(acclength * sizeof(Unit))uprv_malloc_77(acclength * sizeof(uint8_t)));
4442 if (allocacc==nullptr) { /* hopeless -- abandon */
4443 *status|=DEC_Insufficient_storage0x00000010;
4444 break;}
4445 acc=allocacc; /* use the allocated space */
4446 }
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 maxdigits=rhs->digits+reqdigits-1;
4460 if (lhs->digits>maxdigits) maxdigits=lhs->digits;
4461 var1units=D2U(maxdigits)((maxdigits)<=49?d2utable[maxdigits]:((maxdigits)+1 -1)/1)+2;
4462 /* allocate a guard unit above msu1 for REMAINDERNEAR */
4463 if (!(op&DIVIDE0x80)) var1units++;
4464 if ((var1units+1)*sizeof(Unituint8_t)>sizeof(varbuff)) {
4465 /* printf("malloc dvvar %ld units\n", var1units+1); */
4466 varalloc = static_cast<Unituint8_t*>(malloc((var1units + 1) * sizeof(Unit))uprv_malloc_77((var1units + 1) * sizeof(uint8_t)));
4467 if (varalloc==nullptr) { /* hopeless -- abandon */
4468 *status|=DEC_Insufficient_storage0x00000010;
4469 break;}
4470 var1=varalloc; /* use the allocated space */
4471 }
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 msu1=var1+var1units-1; /* msu of var1 */
4480 source=lhs->lsu+D2U(lhs->digits)((lhs->digits)<=49?d2utable[lhs->digits]:((lhs->digits
)+1 -1)/1)
-1; /* msu of input array */
4481 for (target=msu1; source>=lhs->lsu; source--, target--) *target=*source;
4482 for (; target>=var1; target--) *target=0;
4483
4484 /* rhs (var2) is left-aligned with var1 at the start */
4485 var2ulen=var1units; /* rhs logical length (units) */
4486 var2units=D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
; /* rhs actual length (units) */
4487 var2=rhs->lsu; /* -> rhs array */
4488 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 msu2plus=*msu2; /* it's value .. */
4493 if (var2units>1) msu2plus++; /* .. +1 if any more */
4494 msu2pair = static_cast<eIntint32_t>(*msu2) * (DECDPUNMAX9 + 1); /* top two pair .. */
4495 if (var2units>1) { /* .. [else treat 2nd as 0] */
4496 msu2pair+=*(msu2-1); /* .. */
4497 if (var2units>2) msu2pair++; /* .. +1 if any more */
4498 }
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 for (pow=&powersDECPOWERS[1]; *msu1>=*pow; pow++) exponent--;
4507 for (pow=&powersDECPOWERS[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 if (!(op&DIVIDE0x80)) {
4515 Unituint8_t *u; /* work */
4516 /* save the initial 'false' padding of var1, in digits */
4517 var1initpad=(var1units-D2U(lhs->digits)((lhs->digits)<=49?d2utable[lhs->digits]:((lhs->digits
)+1 -1)/1)
)*DECDPUN1;
4518 /* Determine the shift to do. */
4519 if (exponent<0) cut=-exponent;
4520 else cut=DECDPUN1-exponent%DECDPUN1;
4521 decShiftToLeast(var1, var1units, cut);
4522 exponent+=cut; /* maintain numerical value */
4523 var1initpad-=cut; /* .. and reduce padding */
4524 /* clean any most-significant units which were just emptied */
4525 for (u=msu1; cut>=DECDPUN1; cut-=DECDPUN1, u--) *u=0;
4526 } /* align */
4527 else { /* is DIVIDE */
4528 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 if (*msu1<*msu2) {
4532 var2ulen--; /* shift down */
4533 exponent-=DECDPUN1; /* update the exponent */
4534 }
4535 }
4536
4537 /* ---- start the long-division loops ------------------------------ */
4538 accunits=0; /* no units accumulated yet */
4539 accdigits=0; /* .. or digits */
4540 accnext=acc+acclength-1; /* -> msu of acc [NB: allows digits+1] */
4541 for (;;) { /* outer forever loop */
4542 thisunit=0; /* current unit assumed 0 */
4543 /* find the next unit */
4544 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 for (; *msu1==0 && msu1>var1; msu1--) var1units--;
4548
4549 if (var1units<var2ulen) break; /* var1 too low for subtract */
4550 if (var1units==var2ulen) { /* unit-by-unit compare needed */
4551 /* compare the two numbers, from msu */
4552 const Unituint8_t *pv1, *pv2;
4553 Unituint8_t v2; /* units to compare */
4554 pv2=msu2; /* -> msu */
4555 for (pv1=msu1; ; pv1--, pv2--) {
4556 /* v1=*pv1 -- always OK */
4557 v2=0; /* assume in padding */
4558 if (pv2>=var2) v2=*pv2; /* in range */
4559 if (*pv1!=v2) break; /* no longer the same */
4560 if (pv1==var1) break; /* done; leave pv1 as is */
4561 }
4562 /* here when all inspected or a difference seen */
4563 if (*pv1<v2) break; /* var1 too low to subtract */
4564 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 thisunit++; /* as though subtracted */
4569 *var1=0; /* set var1 to 0 */
4570 var1units=1; /* .. */
4571 break; /* from inner */
4572 } /* 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 mult = static_cast<Intint32_t>((static_cast<eIntint32_t>(*msu1) * (DECDPUNMAX9 + 1) + *(msu1 - 1)) / msu2pair);
4577 } /* lengths the same */
4578 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 mult = static_cast<Intint32_t>((static_cast<eIntint32_t>(*msu1) * (DECDPUNMAX9 + 1) + *(msu1 - 1)) / msu2plus);
4582 }
4583 if (mult==0) mult=1; /* must always be at least 1 */
4584 /* subtraction needed; var1 is > var2 */
4585 thisunit = static_cast<Unituint8_t>(thisunit + mult); /* accumulate */
4586 /* subtract var1-var2, into var1; only the overlap needs */
4587 /* processing, as this is an in-place calculation */
4588 shift=var2ulen-var2units;
4589 #if DECTRACE0
4590 decDumpAr('1', &var1[shift], var1units-shift);
4591 decDumpAr('2', var2, var2units);
4592 printf("m=%ld\n", -mult);
4593 #endif
4594 decUnitAddSub(&var1[shift], var1units-shift,
4595 var2, var2units, 0,
4596 &var1[shift], -mult);
4597 #if DECTRACE0
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 } /* inner loop */
4603
4604 /* The next unit has been calculated in full; unless it's a */
4605 /* leading zero, add to acc */
4606 if (accunits!=0 || thisunit!=0) { /* is first or non-zero */
4607 *accnext=thisunit; /* store in accumulator */
4608 /* account exactly for the new digits */
4609 if (accunits==0) {
4610 accdigits++; /* at least one */
4611 for (pow=&powersDECPOWERS[1]; thisunit>=*pow; pow++) accdigits++;
4612 }
4613 else accdigits+=DECDPUN1;
4614 accunits++; /* update count */
4615 accnext--; /* ready for next */
4616 if (accdigits>reqdigits) break; /* have enough digits */
4617 }
4618
4619 /* if the residue is zero, the operation is done (unless divide */
4620 /* or divideInteger and still not enough digits yet) */
4621 if (*var1==0 && var1units==1) { /* residue is 0 */
4622 if (op&(REMAINDER0x40|REMNEAR0x10)) break;
4623 if ((op&DIVIDE0x80) && (exponent<=maxexponent)) break;
4624 /* [drop through if divideInteger] */
4625 }
4626 /* also done enough if calculating remainder or integer */
4627 /* divide and just did the last ('units') unit */
4628 if (exponent==0 && !(op&DIVIDE0x80)) 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 var2ulen--; /* shift down */
4633 exponent-=DECDPUN1; /* update the exponent */
4634 } /* 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 if (accunits==0) { /* acc is 0 */
4642 accunits=1; /* show have a unit .. */
4643 accdigits=1; /* .. */
4644 *accnext=0; /* .. whose value is 0 */
4645 }
4646 else accnext++; /* back to last placed */
4647 /* accnext now -> lowest unit of result */
4648
4649 residue=0; /* assume no residue */
4650 if (op&DIVIDE0x80) {
4651 /* record the presence of any residue, for rounding */
4652 if (*var1!=0 || var1units>1) residue=1;
4653 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 DECDPUN1>1
4659 Unituint8_t lsu=*accnext;
4660 if (!(lsu&0x01) && (lsu!=0)) {
4661 /* count the trailing zeros */
4662 Intint32_t drop=0;
4663 for (;; drop++) { /* [will terminate because lsu!=0] */
4664 if (exponent>=maxexponent) break; /* don't chop real 0s */
4665 #if DECDPUN1<=4
4666 if ((lsu-QUOT10(lsu, drop+1)((((uint32_t)(lsu)>>(drop+1))*multies[drop+1])>>17
)
4667 *powersDECPOWERS[drop+1])!=0) break; /* found non-0 digit */
4668 #else
4669 if (lsu%powersDECPOWERS[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)((accdigits)<=49?d2utable[accdigits]:((accdigits)+1 -1)/1);
4677 /* [exponent was adjusted in the loop] */
4678 }
4679 } /* neither odd nor 0 */
4680 #endif
4681 } /* exact divide */
4682 } /* divide */
4683 else /* op!=DIVIDE */ {
4684 /* check for coefficient overflow */
4685 if (accdigits+exponent>reqdigits) {
4686 *status|=DEC_Division_impossible0x00000004;
4687 break;
4688 }
4689 if (op & (REMAINDER0x40|REMNEAR0x10)) {
4690 /* [Here, the exponent will be 0, because var1 was adjusted */
4691 /* appropriately.] */
4692 Intint32_t postshift; /* work */
4693 Flaguint8_t wasodd=0; /* integer was odd */
4694 Unituint8_t *quotlsu; /* for save */
4695 Intint32_t quotdigits; /* .. */
4696
4697 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 if (*var1==0 && var1units==1) { /* residue is 0 */
4702 Intint32_t exp=lhs->exponent; /* save min(exponents) */
4703 if (rhs->exponent<exp) exp=rhs->exponent;
4704 uprv_decNumberZerouprv_decNumberZero_77(res); /* 0 coefficient */
4705 #if DECSUBSET0
4706 if (set->extended)
4707 #endif
4708 res->exponent=exp; /* .. with proper exponent */
4709 res->bits = static_cast<uByteuint8_t>(bits & DECNEG0x80); /* [cleaned] */
4710 decFinish(res, set, &residue, status)decFinalize(res,set,&residue,status); /* might clamp */
4711 break;
4712 }
4713 /* note if the quotient was odd */
4714 if (*accnext & 0x01) wasodd=1; /* acc is odd */
4715 quotlsu=accnext; /* save in case need to reinspect */
4716 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 postshift=var1initpad+exponent-lhs->exponent+rhs->exponent;
4723 /* [the 'exponent' term accounts for the shifts during divide] */
4724 if (var1initpad<postshift) postshift=var1initpad;
4725
4726 /* shift var1 the requested amount, and adjust its digits */
4727 var1units=decShiftToLeast(var1, var1units, postshift);
4728 accnext=var1;
4729 accdigits=decGetDigits(var1, var1units);
4730 accunits=D2U(accdigits)((accdigits)<=49?d2utable[accdigits]:((accdigits)+1 -1)/1);
4731
4732 exponent=lhs->exponent; /* exponent is smaller of lhs & rhs */
4733 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 if (op&REMNEAR0x10) {
4739 Intint32_t compare, tarunits; /* work */
4740 Unituint8_t *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 tarunits=decUnitAddSub(accnext, accunits, accnext, accunits,
4745 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 compare=decUnitCompare(accnext, tarunits, rhs->lsu, D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
,
4752 rhs->exponent-exponent);
4753 if (compare==BADINT(int32_t)0x80000000) { /* deep trouble */
4754 *status|=DEC_Insufficient_storage0x00000010;
4755 break;}
4756
4757 /* now restore the remainder by dividing by two; the lsu */
4758 /* is known to be even. */
4759 for (up=accnext; up<accnext+tarunits; up++) {
4760 Intint32_t half; /* half to add to lower unit */
4761 half=*up & 0x01;
4762 *up/=2; /* [shift] */
4763 if (!half) continue;
4764 *(up-1)+=(DECDPUNMAX9+1)/2;
4765 }
4766 /* [accunits still describes the original remainder length] */
4767
4768 if (compare>0 || (compare==0 && wasodd)) { /* adjustment needed */
4769 Intint32_t 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 Flaguint8_t allnines=0; /* 1 if quotient all nines */
4775 if (quotdigits==reqdigits) { /* could be borderline */
4776 for (up=quotlsu; ; up++) {
4777 if (quotdigits>DECDPUN1) {
4778 if (*up!=DECDPUNMAX9) break;/* non-nines */
4779 }
4780 else { /* this is the last Unit */
4781 if (*up==powersDECPOWERS[quotdigits]-1) allnines=1;
4782 break;
4783 }
4784 quotdigits-=DECDPUN1; /* checked those digits */
4785 } /* up */
4786 } /* borderline check */
4787 if (allnines) {
4788 *status|=DEC_Division_impossible0x00000004;
4789 break;}
4790
4791 /* rem-rhs is needed; the sign will invert. Again, var1 */
4792 /* can safely be used for the working Units array. */
4793 exp=rhs->exponent-exponent; /* RHS padding needed */
4794 /* Calculate units and remainder from exponent. */
4795 expunits=exp/DECDPUN1;
4796 exprem=exp%DECDPUN1;
4797 /* subtract [A+B*(-m)]; the result will always be negative */
4798 accunits=-decUnitAddSub(accnext, accunits,
4799 rhs->lsu, D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
,
4800 expunits, accnext, -static_cast<Intint32_t>(powersDECPOWERS[exprem]));
4801 accdigits=decGetDigits(accnext, accunits); /* count digits exactly */
4802 accunits=D2U(accdigits)((accdigits)<=49?d2utable[accdigits]:((accdigits)+1 -1)/1); /* and recalculate the units for copy */
Value stored to 'accunits' is never read
4803 /* [exponent is as for original remainder] */
4804 bits^=DECNEG0x80; /* flip the sign */
4805 }
4806 } /* REMNEAR */
4807 } /* REMAINDER or REMNEAR */
4808 } /* not DIVIDE */
4809
4810 /* Set exponent and bits */
4811 res->exponent=exponent;
4812 res->bits = static_cast<uByteuint8_t>(bits & DECNEG0x80); /* [cleaned] */
4813
4814 /* Now the coefficient. */
4815 decSetCoeff(res, set, accnext, accdigits, &residue, status);
4816
4817 decFinish(res, set, &residue, status)decFinalize(res,set,&residue,status); /* final cleanup */
4818
4819 #if DECSUBSET0
4820 /* If a divide then strip trailing zeros if subset [after round] */
4821 if (!set->extended && (op==DIVIDE0x80)) decTrim(res, set, 0, 1, &dropped);
4822 #endif
4823 } while(0); /* end protected */
4824
4825 if (varalloc!=nullptr) free(varalloc)uprv_free_77(varalloc); /* drop any storage used */
4826 if (allocacc!=nullptr) free(allocacc)uprv_free_77(allocacc); /* .. */
4827 #if DECSUBSET0
4828 if (allocrhs!=nullptr) free(allocrhs)uprv_free_77(allocrhs); /* .. */
4829 if (alloclhs!=nullptr) free(alloclhs)uprv_free_77(alloclhs); /* .. */
4830 #endif
4831 return res;
4832 } /* 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(1 && 1<5) (DECUSE641 && DECDPUN1<5)
4871static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs,
4872 const decNumber *rhs, decContext *set,
4873 uIntuint32_t *status) {
4874 Intint32_t accunits; /* Units of accumulator in use */
4875 Intint32_t exponent; /* work */
4876 Intint32_t residue=0; /* rounding residue */
4877 uByteuint8_t bits; /* result sign */
4878 Unituint8_t *acc; /* -> accumulator Unit array */
4879 Intint32_t needbytes; /* size calculator */
4880 void *allocacc=nullptr; /* -> allocated accumulator, iff allocated */
4881 Unituint8_t accbuff[SD2U(DECBUFFER*4+1)(((36*4+1)+1 -1)/1)]; /* buffer (+1 for DECBUFFER==0, */
4882 /* *4 for calls from other operations) */
4883 const Unituint8_t *mer, *mermsup; /* work */
4884 Intint32_t madlength; /* Units in multiplicand */
4885 Intint32_t shift; /* Units to shift multiplicand by */
4886
4887 #if FASTMUL(1 && 1<5)
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 #if DECDPUN1 & 1 /* odd */
4891 #define FASTBASE1000000000 1000000000 /* base */
4892 #define FASTDIGS9 9 /* digits in base */
4893 #define FASTLAZY18 18 /* carry resolution point [1->18] */
4894 #else
4895 #define FASTBASE1000000000 100000000
4896 #define FASTDIGS9 8
4897 #define FASTLAZY18 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 uIntuint32_t zlhibuff[(DECBUFFER36*2+1)/8+1]; /* buffer (+1 for DECBUFFER==0) */
4903 uIntuint32_t *zlhi=zlhibuff; /* -> lhs array */
4904 uIntuint32_t *alloclhi=nullptr; /* -> allocated buffer, iff allocated */
4905 uIntuint32_t zrhibuff[(DECBUFFER36*2+1)/8+1]; /* buffer (+1 for DECBUFFER==0) */
4906 uIntuint32_t *zrhi=zrhibuff; /* -> rhs array */
4907 uIntuint32_t *allocrhi=nullptr; /* -> allocated buffer, iff allocated */
4908 uLonguint64_t zaccbuff[(DECBUFFER36*2+1)/4+2]; /* buffer (+1 for DECBUFFER==0) */
4909 /* [allocacc is shared for both paths, as only one will run] */
4910 uLonguint64_t *zacc=zaccbuff; /* -> accumulator array for exact result */
4911 #if DECDPUN1==1
4912 Intint32_t zoff; /* accumulator offset */
4913 #endif
4914 uIntuint32_t *lip, *rip; /* item pointers */
4915 uIntuint32_t *lmsi, *rmsi; /* most significant items */
4916 Intint32_t ilhs, irhs, iacc; /* item counts in the arrays */
4917 Intint32_t lazy; /* lazy carry counter */
4918 uLonguint64_t lcarry; /* uLong carry */
4919 uIntuint32_t carry; /* carry (NB not uLong) */
4920 Intint32_t count; /* work */
4921 const Unituint8_t *cup; /* .. */
4922 Unituint8_t *up; /* .. */
4923 uLonguint64_t *lp; /* .. */
4924 Intint32_t p; /* .. */
4925 #endif
4926
4927 #if DECSUBSET0
4928 decNumber *alloclhs=nullptr; /* -> allocated buffer, iff allocated */
4929 decNumber *allocrhs=nullptr; /* -> allocated buffer, iff allocated */
4930 #endif
4931
4932 #if DECCHECK0
4933 if (decCheckOperands(res, lhs, rhs, set)) return res;
4934 #endif
4935
4936 /* precalculate result sign */
4937 bits = static_cast<uByteuint8_t>((lhs->bits ^ rhs->bits) & DECNEG0x80);
4938
4939 /* handle infinities and NaNs */
4940 if (SPECIALARGS((lhs->bits | rhs->bits) & (0x40|0x20|0x10))) { /* a special bit set */
4941 if (SPECIALARGS((lhs->bits | rhs->bits) & (0x40|0x20|0x10)) & (DECSNAN0x10 | DECNAN0x20)) { /* one or two NaNs */
4942 decNaNs(res, lhs, rhs, set, status);
4943 return res;}
4944 /* one or two infinities; Infinity * 0 is invalid */
4945 if (((lhs->bits & DECINF0x40)==0 && ISZERO(lhs)(*(lhs)->lsu==0 && (lhs)->digits==1 && (
((lhs)->bits&(0x40|0x20|0x10))==0))
)
4946 ||((rhs->bits & DECINF0x40)==0 && ISZERO(rhs)(*(rhs)->lsu==0 && (rhs)->digits==1 && (
((rhs)->bits&(0x40|0x20|0x10))==0))
)) {
4947 *status|=DEC_Invalid_operation0x00000080;
4948 return res;}
4949 uprv_decNumberZerouprv_decNumberZero_77(res);
4950 res->bits=bits|DECINF0x40; /* infinity */
4951 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 if (lhs->digits<rhs->digits) { /* swap... */
4958 const decNumber *hold=lhs;
4959 lhs=rhs;
4960 rhs=hold;
4961 }
4962
4963 do { /* protect allocated storage */
4964 #if DECSUBSET0
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(1 && 1<5) /* 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 #define NEEDTWO(1*2) (DECDPUN1*2) /* within two decUnitAddSub calls */
4985 if (rhs->digits>NEEDTWO(1*2)) { /* use fastpath... */
4986 /* calculate the number of elements in each array */
4987 ilhs=(lhs->digits+FASTDIGS9-1)/FASTDIGS9; /* [ceiling] */
4988 irhs=(rhs->digits+FASTDIGS9-1)/FASTDIGS9; /* .. */
4989 iacc=ilhs+irhs;
4990
4991 /* allocate buffers if required, as usual */
4992 needbytes=ilhs*sizeof(uIntuint32_t);
4993 if (needbytes > static_cast<Intint32_t>(sizeof(zlhibuff))) {
4994 alloclhi = static_cast<uIntuint32_t*>(malloc(needbytes)uprv_malloc_77(needbytes));
4995 zlhi=alloclhi;}
4996 needbytes=irhs*sizeof(uIntuint32_t);
4997 if (needbytes > static_cast<Intint32_t>(sizeof(zrhibuff))) {
4998 allocrhi = static_cast<uIntuint32_t*>(malloc(needbytes)uprv_malloc_77(needbytes));
4999 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 U_ASSERT((uint32_t)iacc <= INT32_MAX/sizeof(uLong))(static_cast <bool> ((uint32_t)iacc <= (2147483647)/
sizeof(uint64_t)) ? void (0) : __assert_fail ("(uint32_t)iacc <= (2147483647)/sizeof(uint64_t)"
, __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__
))
;
5012 needbytes=iacc*sizeof(uLonguint64_t);
5013 #if DECDPUN1==1
5014 zoff=(iacc+7)/8; /* items to offset by */
5015 needbytes+=zoff*8;
5016 #endif
5017 if (needbytes > static_cast<Intint32_t>(sizeof(zaccbuff))) {
5018 allocacc = static_cast<uLonguint64_t*>(malloc(needbytes)uprv_malloc_77(needbytes));
5019 zacc = static_cast<uLonguint64_t*>(allocacc);}
5020 if (zlhi==nullptr||zrhi==nullptr||zacc==nullptr) {
5021 *status|=DEC_Insufficient_storage0x00000010;
5022 break;}
5023
5024 acc = reinterpret_cast<Unituint8_t*>(zacc); /* -> target Unit array */
5025 #if DECDPUN1==1
5026 zacc+=zoff; /* start uLong accumulator to right */
5027 #endif
5028
5029 /* assemble the chunked copies of the left and right sides */
5030 for (count=lhs->digits, cup=lhs->lsu, lip=zlhi; count>0; lip++)
5031 for (p=0, *lip=0; p<FASTDIGS9 && count>0;
5032 p+=DECDPUN1, cup++, count-=DECDPUN1)
5033 *lip+=*cup*powersDECPOWERS[p];
5034 lmsi=lip-1; /* save -> msi */
5035 for (count=rhs->digits, cup=rhs->lsu, rip=zrhi; count>0; rip++)
5036 for (p=0, *rip=0; p<FASTDIGS9 && count>0;
5037 p+=DECDPUN1, cup++, count-=DECDPUN1)
5038 *rip+=*cup*powersDECPOWERS[p];
5039 rmsi=rip-1; /* save -> msi */
5040
5041 /* zero the accumulator */
5042 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 lazy=FASTLAZY18; /* carry delay count */
5062 for (rip=zrhi; rip<=rmsi; rip++) { /* over each item in rhs */
5063 lp=zacc+(rip-zrhi); /* where to add the lhs */
5064 for (lip=zlhi; lip<=lmsi; lip++, lp++) { /* over each item in lhs */
5065 *lp += static_cast<uLonguint64_t>(*lip) * (*rip); /* [this should in-line] */
5066 } /* lip loop */
5067 lazy--;
5068 if (lazy>0 && rip!=rmsi) continue;
5069 lazy=FASTLAZY18; /* reset delay count */
5070 /* spin up the accumulator resolving overflows */
5071 for (lp=zacc; lp<zacc+iacc; lp++) {
5072 if (*lp<FASTBASE1000000000) continue; /* it fits */
5073 lcarry=*lp/FASTBASE1000000000; /* 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 if (lcarry<FASTBASE1000000000) carry = static_cast<uIntuint32_t>(lcarry); /* [usual] */
5079 else { /* two-place carry [fairly rare] */
5080 uIntuint32_t carry2 = static_cast<uIntuint32_t>(lcarry / FASTBASE1000000000); /* top top part */
5081 *(lp+2)+=carry2; /* add to item+2 */
5082 *lp -= (static_cast<uLonguint64_t>(FASTBASE1000000000) * FASTBASE1000000000 * carry2); /* [slow] */
5083 carry = static_cast<uIntuint32_t>(lcarry - (static_cast<uLonguint64_t>(FASTBASE1000000000) * carry2)); /* [inline] */
5084 }
5085 *(lp+1)+=carry; /* add to item above [inline] */
5086 *lp -= (static_cast<uLonguint64_t>(FASTBASE1000000000) * carry); /* [inline] */
5087 } /* carry resolution */
5088 } /* 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 for (lp=zacc, up=acc; lp<zacc+iacc; lp++) {
5097 uIntuint32_t item = static_cast<uIntuint32_t>(*lp); /* decapitate to uInt */
5098 for (p=0; p<FASTDIGS9-DECDPUN1; p+=DECDPUN1, up++) {
5099 uIntuint32_t part=item/(DECDPUNMAX9+1);
5100 *up = static_cast<Unituint8_t>(item - (part * (DECDPUNMAX9 + 1)));
5101 item=part;
5102 } /* p */
5103 *up = static_cast<Unituint8_t>(item); up++; /* [final needs no division] */
5104 } /* lp */
5105 accunits = static_cast<int32_t>(up-acc); /* count of units */
5106 }
5107 else { /* here to use units directly, without chunking ['old code'] */
5108 #endif
5109
5110 /* if accumulator will be too long for local storage, then allocate */
5111 acc=accbuff; /* -> assume buffer for accumulator */
5112 needbytes=(D2U(lhs->digits)((lhs->digits)<=49?d2utable[lhs->digits]:((lhs->digits
)+1 -1)/1)
+D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
)*sizeof(Unituint8_t);
5113 if (needbytes > static_cast<Intint32_t>(sizeof(accbuff))) {
5114 allocacc = static_cast<Unituint8_t*>(malloc(needbytes)uprv_malloc_77(needbytes));
5115 if (allocacc==nullptr) {*status|=DEC_Insufficient_storage0x00000010; break;}
5116 acc = static_cast<Unituint8_t*>(allocacc); /* use the allocated space */
5117 }
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 accunits=1; /* accumulator starts at '0' */
5125 *acc=0; /* .. (lsu=0) */
5126 shift=0; /* no multiplicand shift at first */
5127 madlength=D2U(lhs->digits)((lhs->digits)<=49?d2utable[lhs->digits]:((lhs->digits
)+1 -1)/1)
; /* this won't change */
5128 mermsup=rhs->lsu+D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
; /* -> msu+1 of multiplier */
5129
5130 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 if (*mer!=0) accunits=decUnitAddSub(&acc[shift], accunits-shift,
5134 lhs->lsu, madlength, 0,
5135 &acc[shift], *mer)
5136 + shift;
5137 else { /* extend acc with a 0; it will be used shortly */
5138 *(acc+accunits)=0; /* [this avoids length of <=0 later] */
5139 accunits++;
5140 }
5141 /* multiply multiplicand by 10**DECDPUN for next Unit to left */
5142 shift++; /* add this for 'logical length' */
5143 } /* n */
5144 #if FASTMUL(1 && 1<5)
5145 } /* unchunked units */
5146 #endif
5147 /* common end-path */
5148 #if DECTRACE0
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 res->bits=bits; /* set sign */
5156 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 exponent=lhs->exponent+rhs->exponent; /* calculate exponent */
5164 if (lhs->exponent<0 && rhs->exponent<0 && exponent>0)
5165 exponent=-2*DECNUMMAXE999999999; /* force underflow */
5166 res->exponent=exponent; /* OK to overwrite now */
5167
5168
5169 /* Set the coefficient. If any rounding, residue records */
5170 decSetCoeff(res, set, acc, res->digits, &residue, status);
5171 decFinish(res, set, &residue, status)decFinalize(res,set,&residue,status); /* final cleanup */
5172 } while(0); /* end protected */
5173
5174 if (allocacc!=nullptr) free(allocacc)uprv_free_77(allocacc); /* drop any storage used */
5175 #if DECSUBSET0
5176 if (allocrhs!=nullptr) free(allocrhs)uprv_free_77(allocrhs); /* .. */
5177 if (alloclhs!=nullptr) free(alloclhs)uprv_free_77(alloclhs); /* .. */
5178 #endif
5179 #if FASTMUL(1 && 1<5)
5180 if (allocrhi!=nullptr) free(allocrhi)uprv_free_77(allocrhi); /* .. */
5181 if (alloclhi!=nullptr) free(alloclhi)uprv_free_77(alloclhi); /* .. */
5182 #endif
5183 return res;
5184 } /* 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/* ------------------------------------------------------------------ */
5265decNumber * decExpOp(decNumber *res, const decNumber *rhs,
5266 decContext *set, uIntuint32_t *status) {
5267 uIntuint32_t ignore=0; /* working status */
5268 Intint32_t h; /* adjusted exponent for 0.xxxx */
5269 Intint32_t p; /* working precision */
5270 Intint32_t residue; /* rounding residue */
5271 uIntuint32_t needbytes; /* for space calculations */
5272 const decNumber *x=rhs; /* (may point to safe copy later) */
5273 decContext aset, tset, dset; /* working contexts */
5274 Intint32_t 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 decNumber bufr[D2N(DECBUFFER*2+1)(((((((36*2+1)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)
*2-1)/sizeof(decNumber))
];
5280 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 decNumber buft[D2N(DECBUFFER*2+9+1)(((((((36*2+9+1)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber
)*2-1)/sizeof(decNumber))
];
5288 decNumber *allocbuft=nullptr; /* -> allocated buft, iff allocated */
5289 decNumber *t=buft; /* term */
5290 /* buffer for a, accumulator (working precision * 2), at least 9 */
5291 decNumber bufa[D2N(DECBUFFER*4+18+1)(((((((36*4+18+1)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber
)*2-1)/sizeof(decNumber))
];
5292 decNumber *allocbufa=nullptr; /* -> allocated bufa, iff allocated */
5293 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 decNumber bufd[D2N(16)(((((((16)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)*2-1
)/sizeof(decNumber))
];
5297 decNumber *d=bufd; /* divisor */
5298 decNumber numone; /* constant 1 */
5299
5300 #if DECCHECK0
5301 Intint32_t iterations=0; /* for later sanity check */
5302 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
5303 #endif
5304
5305 do { /* protect allocated storage */
5306 if (SPECIALARG(rhs->bits & (0x40|0x20|0x10))) { /* handle infinities and NaNs */
5307 if (decNumberIsInfinite(rhs)(((rhs)->bits&0x40)!=0)) { /* an infinity */
5308 if (decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) /* -Infinity -> +0 */
5309 uprv_decNumberZerouprv_decNumberZero_77(res);
5310 else uprv_decNumberCopyuprv_decNumberCopy_77(res, rhs); /* +Infinity -> self */
5311 }
5312 else decNaNs(res, rhs, nullptr, set, status); /* a NaN */
5313 break;}
5314
5315 if (ISZERO(rhs)(*(rhs)->lsu==0 && (rhs)->digits==1 && (
((rhs)->bits&(0x40|0x20|0x10))==0))
) { /* zeros -> exact 1 */
5316 uprv_decNumberZerouprv_decNumberZero_77(res); /* make clean 1 */
5317 *res->lsu=1; /* .. */
5318 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 uprv_decNumberZerouprv_decNumberZero_77(d); /* clean */
5335 *d->lsu=4; /* set 4 .. */
5336 d->exponent=-set->digits; /* * 10**(-d) */
5337 if (decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) d->exponent--; /* negative case */
5338 comp=decCompare(d, rhs, 1); /* signless compare */
5339 if (comp==BADINT(int32_t)0x80000000) {
5340 *status|=DEC_Insufficient_storage0x00000010;
5341 break;}
5342 if (comp>=0) { /* rhs < d */
5343 Intint32_t shift=set->digits-1;
5344 uprv_decNumberZerouprv_decNumberZero_77(res); /* set 1 */
5345 *res->lsu=1; /* .. */
5346 res->digits=decShiftToMost(res->lsu, 1, shift);
5347 res->exponent=-shift; /* make 1.0000... */
5348 *status|=DEC_Inexact0x00000020 | DEC_Rounded0x00000800; /* .. inexactly */
5349 break;} /* tiny */
5350
5351 /* set up the context to be used for calculating a, as this is */
5352 /* used on both paths below */
5353 uprv_decContextDefaultuprv_decContextDefault_77(&aset, DEC_INIT_DECIMAL6464);
5354 /* accumulator bounds are as requested (could underflow) */
5355 aset.emax=set->emax; /* usual bounds */
5356 aset.emin=set->emin; /* .. */
5357 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 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 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 uprv_decNumberZerouprv_decNumberZero_77(a);
5372 *a->lsu=2; /* not 1 but < exp(1) */
5373 if (decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) a->exponent=-2; /* make 0.02 */
5374 h=8; /* clamp so 10**h computable */
5375 p=9; /* set a working precision */
5376 }
5377 else { /* h<=8 */
5378 Intint32_t 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 Intint32_t lever=MINI(8-h, maxlever)((8-h)>(maxlever)?(maxlever):(8-h)); /* leverage attainable */
5390 Intint32_t use=-rhs->digits-lever; /* exponent to use for RHS */
5391 h+=lever; /* apply leverage selected */
5392 if (h<0) { /* clamp */
5393 use+=h; /* [may end up subnormal] */
5394 h=0;
5395 }
5396 /* Take a copy of RHS if it needs normalization (true whenever x>=1) */
5397 if (rhs->exponent!=use) {
5398 decNumber *newrhs=bufr; /* assume will fit on stack */
5399 needbytes=sizeof(decNumber)+(D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
-1)*sizeof(Unituint8_t);
5400 if (needbytes>sizeof(bufr)) { /* need malloc space */
5401 allocrhs = static_cast<decNumber*>(malloc(needbytes)uprv_malloc_77(needbytes));
5402 if (allocrhs==nullptr) { /* hopeless -- abandon */
5403 *status|=DEC_Insufficient_storage0x00000010;
5404 break;}
5405 newrhs=allocrhs; /* use the allocated space */
5406 }
5407 uprv_decNumberCopyuprv_decNumberCopy_77(newrhs, rhs); /* copy to safe space */
5408 newrhs->exponent=use; /* normalize; now <1 */
5409 x=newrhs; /* ready for use */
5410 /* decNumberShow(x); */
5411 }
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 p=MAXI(x->digits, set->digits)((x->digits)<(set->digits)?(set->digits):(x->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 needbytes=sizeof(decNumber)+(D2U(p*2)((p*2)<=49?d2utable[p*2]:((p*2)+1 -1)/1)-1)*sizeof(Unituint8_t);
5432 if (needbytes>sizeof(bufa)) { /* need malloc space */
5433 allocbufa = static_cast<decNumber*>(malloc(needbytes)uprv_malloc_77(needbytes));
5434 if (allocbufa==nullptr) { /* hopeless -- abandon */
5435 *status|=DEC_Insufficient_storage0x00000010;
5436 break;}
5437 a=allocbufa; /* use the allocated space */
5438 }
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 needbytes=sizeof(decNumber)+(D2U(p+2)((p+2)<=49?d2utable[p+2]:((p+2)+1 -1)/1)-1)*sizeof(Unituint8_t);
5444 if (needbytes>sizeof(buft)) { /* need malloc space */
5445 allocbuft = static_cast<decNumber*>(malloc(needbytes)uprv_malloc_77(needbytes));
5446 if (allocbuft==nullptr) { /* hopeless -- abandon */
5447 *status|=DEC_Insufficient_storage0x00000010;
5448 break;}
5449 t=allocbuft; /* use the allocated space */
5450 }
5451
5452 uprv_decNumberCopyuprv_decNumberCopy_77(t, x); /* term=x */
5453 uprv_decNumberZerouprv_decNumberZero_77(a); *a->lsu=1; /* accumulator=1 */
5454 uprv_decNumberZerouprv_decNumberZero_77(d); *d->lsu=2; /* divisor=2 */
5455 uprv_decNumberZerouprv_decNumberZero_77(&numone); *numone.lsu=1; /* constant 1 for increment */
5456
5457 /* set up the contexts for calculating a, t, and d */
5458 uprv_decContextDefaultuprv_decContextDefault_77(&tset, DEC_INIT_DECIMAL6464);
5459 dset=tset;
5460 /* accumulator bounds are set above, set precision now */
5461 aset.digits=p*2; /* double */
5462 /* term bounds avoid any underflow or overflow */
5463 tset.digits=p;
5464 tset.emin=DEC_MIN_EMIN-999999999; /* [emax is plenty] */
5465 /* [dset.digits=16, etc., are sufficient] */
5466
5467 /* finally ready to roll */
5468 for (;;) {
5469 #if DECCHECK0
5470 iterations++;
5471 #endif
5472 /* only the status from the accumulation is interesting */
5473 /* [but it should remain unchanged after first add] */
5474 decAddOp(a, a, t, &aset, 0, status); /* a=a+t */
5475 decMultiplyOp(t, t, x, &tset, &ignore); /* t=t*x */
5476 decDivideOp(t, t, d, &tset, DIVIDE0x80, &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 if (((a->digits+a->exponent)>=(t->digits+t->exponent+p+1))
5482 && (a->digits>=p)) break;
5483 decAddOp(d, d, &numone, &dset, 0, &ignore); /* d=d+1 */
5484 } /* iterate */
5485
5486 #if DECCHECK0
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 } /* h<=8 */
5493
5494 /* apply postconditioning: a=a**(10**h) -- this is calculated */
5495 /* at a slightly higher precision than Hull & Abrham suggest */
5496 if (h>0) {
5497 Intint32_t seenbit=0; /* set once a 1-bit is seen */
5498 Intint32_t i; /* counter */
5499 Intint32_t n=powersDECPOWERS[h]; /* always positive */
5500 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 uprv_decNumberZerouprv_decNumberZero_77(t); *t->lsu=1; /* acc=1 */
5505 for (i=1;;i++){ /* for each bit [top bit ignored] */
5506 /* abandon if have had overflow or terminal underflow */
5507 if (*status & (DEC_Overflow0x00000200|DEC_Underflow0x00002000)) { /* interesting? */
5508 if (*status&DEC_Overflow0x00000200 || ISZERO(t)(*(t)->lsu==0 && (t)->digits==1 && (((t
)->bits&(0x40|0x20|0x10))==0))
) break;}
5509 n=n<<1; /* move next bit to testable position */
5510 if (n<0) { /* top bit is set */
5511 seenbit=1; /* OK, have a significant bit */
5512 decMultiplyOp(t, t, a, &aset, status); /* acc=acc*x */
5513 }
5514 if (i==31) break; /* that was the last bit */
5515 if (!seenbit) continue; /* no need to square 1 */
5516 decMultiplyOp(t, t, t, &aset, status); /* acc=acc*acc [square] */
5517 } /*i*/ /* 32 bits */
5518 /* decNumberShow(t); */
5519 a=t; /* and carry on using t instead of a */
5520 }
5521
5522 /* Copy and round the result to res */
5523 residue=1; /* indicate dirt to right .. */
5524 if (ISZERO(a)(*(a)->lsu==0 && (a)->digits==1 && (((a
)->bits&(0x40|0x20|0x10))==0))
) residue=0; /* .. unless underflowed to 0 */
5525 aset.digits=set->digits; /* [use default rounding] */
5526 decCopyFit(res, a, &aset, &residue, status); /* copy & shorten */
5527 decFinish(res, set, &residue, status)decFinalize(res,set,&residue,status); /* cleanup/set flags */
5528 } while(0); /* end protected */
5529
5530 if (allocrhs !=nullptr) free(allocrhs)uprv_free_77(allocrhs); /* drop any storage used */
5531 if (allocbufa!=nullptr) free(allocbufa)uprv_free_77(allocbufa); /* .. */
5532 if (allocbuft!=nullptr) free(allocbuft)uprv_free_77(allocbuft); /* .. */
5533 /* [status is handled by caller] */
5534 return res;
5535 } /* 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/* ------------------------------------------------------------------ */
5553static const uShortuint16_t 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__1) || U_GCC_MAJOR_MINOR(4 * 100 + 2) >= 406
5626#pragma GCC diagnostic push
5627#pragma GCC diagnostic ignored "-Warray-bounds"
5628#endif
5629decNumber * decLnOp(decNumber *res, const decNumber *rhs,
5630 decContext *set, uIntuint32_t *status) {
5631 uIntuint32_t ignore=0; /* working status accumulator */
5632 uIntuint32_t needbytes; /* for space calculations */
5633 Intint32_t residue; /* rounding residue */
5634 Intint32_t r; /* rhs=f*10**r [see below] */
5635 Intint32_t p; /* working precision */
5636 Intint32_t pp; /* precision for iteration */
5637 Intint32_t t; /* work */
5638
5639 /* buffers for a (accumulator, typically precision+2) and b */
5640 /* (adjustment calculator, same size) */
5641 decNumber bufa[D2N(DECBUFFER+12)(((((((36 +12)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)
*2-1)/sizeof(decNumber))
];
5642 decNumber *allocbufa=nullptr; /* -> allocated bufa, iff allocated */
5643 decNumber *a=bufa; /* accumulator/work */
5644 decNumber bufb[D2N(DECBUFFER*2+2)(((((((36*2+2)+1 -1)/1)-1)*sizeof(uint8_t))+sizeof(decNumber)
*2-1)/sizeof(decNumber))
];
5645 decNumber *allocbufb=nullptr; /* -> allocated bufa, iff allocated */
5646 decNumber *b=bufb; /* adjustment/work */
5647
5648 decNumber numone; /* constant 1 */
5649 decNumber cmp; /* work */
5650 decContext aset, bset; /* working contexts */
5651
5652 #if DECCHECK0
5653 Intint32_t iterations=0; /* for later sanity check */
5654 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
5655 #endif
5656
5657 do { /* protect allocated storage */
5658 if (SPECIALARG(rhs->bits & (0x40|0x20|0x10))) { /* handle infinities and NaNs */
5659 if (decNumberIsInfinite(rhs)(((rhs)->bits&0x40)!=0)) { /* an infinity */
5660 if (decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) /* -Infinity -> error */
5661 *status|=DEC_Invalid_operation0x00000080;
5662 else uprv_decNumberCopyuprv_decNumberCopy_77(res, rhs); /* +Infinity -> self */
5663 }
5664 else decNaNs(res, rhs, nullptr, set, status); /* a NaN */
5665 break;}
5666
5667 if (ISZERO(rhs)(*(rhs)->lsu==0 && (rhs)->digits==1 && (
((rhs)->bits&(0x40|0x20|0x10))==0))
) { /* +/- zeros -> -Infinity */
5668 uprv_decNumberZerouprv_decNumberZero_77(res); /* make clean */
5669 res->bits=DECINF0x40|DECNEG0x80; /* set - infinity */
5670 break;} /* [no status to set] */
5671
5672 /* Non-zero negatives are bad... */
5673 if (decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) { /* -x -> error */
5674 *status|=DEC_Invalid_operation0x00000080;
5675 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 if (rhs->exponent==0 && set->digits<=40) {
5681 #if DECDPUN1==1
5682 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 aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
5687 #define LN10"2.302585092994045684017991454684364207601" "2.302585092994045684017991454684364207601"
5688 uprv_decNumberFromStringuprv_decNumberFromString_77(res, LN10"2.302585092994045684017991454684364207601", &aset);
5689 *status|=(DEC_Inexact0x00000020 | DEC_Rounded0x00000800); /* is inexact */
5690 break;}
5691 if (rhs->lsu[0]==2 && rhs->digits==1) { /* ln(2) */
5692 aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
5693 #define LN2"0.6931471805599453094172321214581765680755" "0.6931471805599453094172321214581765680755"
5694 uprv_decNumberFromStringuprv_decNumberFromString_77(res, LN2"0.6931471805599453094172321214581765680755", &aset);
5695 *status|=(DEC_Inexact0x00000020 | DEC_Rounded0x00000800);
5696 break;}
5697 } /* 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 p=MAXI(rhs->digits, MAXI(set->digits, 7))((rhs->digits)<(((set->digits)<(7)?(7):(set->digits
)))?(((set->digits)<(7)?(7):(set->digits))):(rhs->
digits))
+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 needbytes=sizeof(decNumber)+(D2U(MAXI(p,16))((((p)<(16)?(16):(p)))<=49?d2utable[((p)<(16)?(16):(
p))]:((((p)<(16)?(16):(p)))+1 -1)/1)
-1)*sizeof(Unituint8_t);
5713 if (needbytes>sizeof(bufa)) { /* need malloc space */
5714 allocbufa = static_cast<decNumber*>(malloc(needbytes)uprv_malloc_77(needbytes));
5715 if (allocbufa==nullptr) { /* hopeless -- abandon */
5716 *status|=DEC_Insufficient_storage0x00000010;
5717 break;}
5718 a=allocbufa; /* use the allocated space */
5719 }
5720 pp=p+rhs->digits;
5721 needbytes=sizeof(decNumber)+(D2U(MAXI(pp,16))((((pp)<(16)?(16):(pp)))<=49?d2utable[((pp)<(16)?(16
):(pp))]:((((pp)<(16)?(16):(pp)))+1 -1)/1)
-1)*sizeof(Unituint8_t);
5722 if (needbytes>sizeof(bufb)) { /* need malloc space */
5723 allocbufb = static_cast<decNumber*>(malloc(needbytes)uprv_malloc_77(needbytes));
5724 if (allocbufb==nullptr) { /* hopeless -- abandon */
5725 *status|=DEC_Insufficient_storage0x00000010;
5726 break;}
5727 b=allocbufb; /* use the allocated space */
5728 }
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 uprv_decContextDefaultuprv_decContextDefault_77(&aset, DEC_INIT_DECIMAL6464); /* 16-digit extended */
5740 r=rhs->exponent+rhs->digits; /* 'normalised' exponent */
5741 uprv_decNumberFromInt32uprv_decNumberFromInt32_77(a, r); /* a=r */
5742 uprv_decNumberFromInt32uprv_decNumberFromInt32_77(b, 2302585); /* b=ln(10) (2.302585) */
5743 b->exponent=-6; /* .. */
5744 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 residue=0; /* (no residue) */
5748 aset.digits=2; aset.round=DEC_ROUND_DOWN;
5749 decCopyFit(b, rhs, &aset, &residue, &ignore); /* copy & shorten */
5750 b->exponent=0; /* make integer */
5751 t=decGetInt(b); /* [cannot fail] */
5752 if (t<10) t=X10(t)(((t)<<1)+((t)<<3)); /* adjust single-digit b */
5753 t=LNnn[t-10]; /* look up ln(b) */
5754 uprv_decNumberFromInt32uprv_decNumberFromInt32_77(b, t>>2); /* b=ln(b) coefficient */
5755 b->exponent=-(t&3)-3; /* set exponent */
5756 b->bits=DECNEG0x80; /* ln(0.10)->ln(0.99) always -ve */
5757 aset.digits=16; aset.round=DEC_ROUND_HALF_EVEN; /* restore */
5758 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 uprv_decNumberZerouprv_decNumberZero_77(&numone); *numone.lsu=1; /* constant 1 for adjustment */
5764
5765 /* accumulator bounds are as requested (could underflow, but */
5766 /* cannot overflow) */
5767 aset.emax=set->emax;
5768 aset.emin=set->emin;
5769 aset.clamp=0; /* no concrete format */
5770 /* set up a context to be used for the multiply and subtract */
5771 bset=aset;
5772 bset.emax=DEC_MAX_MATH999999*2; /* use double bounds for the */
5773 bset.emin=-DEC_MAX_MATH999999*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 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 aset.digits=pp; /* working context */
5781 bset.digits=pp+rhs->digits; /* wider context */
5782 for (;;) { /* iterate */
5783 #if DECCHECK0
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 a->bits^=DECNEG0x80; /* make -a */
5793 decExpOp(b, a, &bset, &ignore); /* b=exp(-a) */
5794 a->bits^=DECNEG0x80; /* restore sign of a */
5795 /* now multiply by rhs and subtract 1, at the wider precision */
5796 decMultiplyOp(b, b, rhs, &bset, &ignore); /* b=b*rhs */
5797 decAddOp(b, b, &numone, &bset, DECNEG0x80, &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 if (decNumberIsZero(b)(*(b)->lsu==0 && (b)->digits==1 && (((b
)->bits&(0x40|0x20|0x10))==0))
||
5808 (a->digits+a->exponent)>=(b->digits+b->exponent+set->digits+1)) {
5809 if (a->digits==p) break;
5810 if (decNumberIsZero(a)(*(a)->lsu==0 && (a)->digits==1 && (((a
)->bits&(0x40|0x20|0x10))==0))
) {
5811 decCompareOp(&cmp, rhs, &numone, &aset, COMPARE0x01, &ignore); /* rhs=1 ? */
5812 if (cmp.lsu[0]==0) a->exponent=0; /* yes, exact 0 */
5813 else *status|=(DEC_Inexact0x00000020 | DEC_Rounded0x00000800); /* no, inexact */
5814 break;
5815 }
5816 /* force padding if adjustment has gone to 0 before full length */
5817 if (decNumberIsZero(b)(*(b)->lsu==0 && (b)->digits==1 && (((b
)->bits&(0x40|0x20|0x10))==0))
) b->exponent=a->exponent-p;
5818 }
5819
5820 /* not done yet ... */
5821 decAddOp(a, a, b, &aset, 0, &ignore); /* a=a+b for next estimate */
5822 if (pp==p) continue; /* precision is at maximum */
5823 /* lengthen the next calculation */
5824 pp=pp*2; /* double precision */
5825 if (pp>p) pp=p; /* clamp to maximum */
5826 aset.digits=pp; /* working context */
5827 bset.digits=pp+rhs->digits; /* wider context */
5828 } /* Newton's iteration */
5829
5830 #if DECCHECK0
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 residue=1; /* indicate dirt to right */
5839 if (ISZERO(a)(*(a)->lsu==0 && (a)->digits==1 && (((a
)->bits&(0x40|0x20|0x10))==0))
) residue=0; /* .. unless underflowed to 0 */
5840 aset.digits=set->digits; /* [use default rounding] */
5841 decCopyFit(res, a, &aset, &residue, status); /* copy & shorten */
5842 decFinish(res, set, &residue, status)decFinalize(res,set,&residue,status); /* cleanup/set flags */
5843 } while(0); /* end protected */
5844
5845 if (allocbufa!=nullptr) free(allocbufa)uprv_free_77(allocbufa); /* drop any storage used */
5846 if (allocbufb!=nullptr) free(allocbufb)uprv_free_77(allocbufb); /* .. */
5847 /* [status is handled by caller] */
5848 return res;
5849 } /* decLnOp */
5850#if defined(__clang__1) || U_GCC_MAJOR_MINOR(4 * 100 + 2) >= 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/* ------------------------------------------------------------------ */
5876static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs,
5877 const decNumber *rhs, decContext *set,
5878 Flaguint8_t quant, uIntuint32_t *status) {
5879 #if DECSUBSET0
5880 decNumber *alloclhs=nullptr; /* non-nullptr if rounded lhs allocated */
5881 decNumber *allocrhs=nullptr; /* .., rhs */
5882 #endif
5883 const decNumber *inrhs=rhs; /* save original rhs */
5884 Intint32_t reqdigits=set->digits; /* requested DIGITS */
5885 Intint32_t reqexp; /* requested exponent [-scale] */
5886 Intint32_t residue=0; /* rounding residue */
5887 Intint32_t etiny=set->emin-(reqdigits-1);
5888
5889 #if DECCHECK0
5890 if (decCheckOperands(res, lhs, rhs, set)) return res;
5891 #endif
5892
5893 do { /* protect allocated storage */
5894 #if DECSUBSET0
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 if (SPECIALARGS((lhs->bits | rhs->bits) & (0x40|0x20|0x10))) {
5913 /* NaNs get usual processing */
5914 if (SPECIALARGS((lhs->bits | rhs->bits) & (0x40|0x20|0x10)) & (DECSNAN0x10 | DECNAN0x20))
5915 decNaNs(res, lhs, rhs, set, status);
5916 /* one infinity but not both is bad */
5917 else if ((lhs->bits ^ rhs->bits) & DECINF0x40)
5918 *status|=DEC_Invalid_operation0x00000080;
5919 /* both infinity: return lhs */
5920 else uprv_decNumberCopyuprv_decNumberCopy_77(res, lhs); /* [nop if in place] */
5921 break;
5922 }
5923
5924 /* set requested exponent */
5925 if (quant) reqexp=inrhs->exponent; /* quantize -- match exponents */
5926 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 reqexp=decGetInt(inrhs); /* [cannot fail] */
5931 }
5932
5933 #if DECSUBSET0
5934 if (!set->extended) etiny=set->emin; /* no subnormals */
5935 #endif
5936
5937 if (reqexp==BADINT(int32_t)0x80000000 /* bad (rescale only) or .. */
5938 || reqexp==BIGODD(int32_t)0x80000003 || reqexp==BIGEVEN(int32_t)0x80000002 /* very big (ditto) or .. */
5939 || (reqexp<etiny) /* < lowest */
5940 || (reqexp>set->emax)) { /* > emax */
5941 *status|=DEC_Invalid_operation0x00000080;
5942 break;}
5943
5944 /* the RHS has been processed, so it can be overwritten now if necessary */
5945 if (ISZERO(lhs)(*(lhs)->lsu==0 && (lhs)->digits==1 && (
((lhs)->bits&(0x40|0x20|0x10))==0))
) { /* zero coefficient unchanged */
5946 uprv_decNumberCopyuprv_decNumberCopy_77(res, lhs); /* [nop if in place] */
5947 res->exponent=reqexp; /* .. just set exponent */
5948 #if DECSUBSET0
5949 if (!set->extended) res->bits=0; /* subset specification; no -0 */
5950 #endif
5951 }
5952 else { /* non-zero lhs */
5953 Intint32_t adjust=reqexp-lhs->exponent; /* digit adjustment needed */
5954 /* if adjusted coefficient will definitely not fit, give up now */
5955 if ((lhs->digits-adjust)>reqdigits) {
5956 *status|=DEC_Invalid_operation0x00000080;
5957 break;
5958 }
5959
5960 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 decContext workset; /* work */
5964 workset=*set; /* clone rounding, etc. */
5965 workset.digits=lhs->digits-adjust; /* set requested length */
5966 /* [note that the latter can be <1, here] */
5967 decCopyFit(res, lhs, &workset, &residue, status); /* fit to result */
5968 decApplyRound(res, &workset, residue, status); /* .. and round */
5969 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 if (res->exponent>reqexp) {
5973 /* re-check needed, e.g., for quantize(0.9999, 0.001) under */
5974 /* set->digits==3 */
5975 if (res->digits==reqdigits) { /* cannot shift by 1 */
5976 *status&=~(DEC_Inexact0x00000020 | DEC_Rounded0x00000800); /* [clean these] */
5977 *status|=DEC_Invalid_operation0x00000080;
5978 break;
5979 }
5980 res->digits=decShiftToMost(res->lsu, res->digits, 1); /* shift */
5981 res->exponent--; /* (re)adjust the exponent. */
5982 }
5983 #if DECSUBSET0
5984 if (ISZERO(res)(*(res)->lsu==0 && (res)->digits==1 && (
((res)->bits&(0x40|0x20|0x10))==0))
&& !set->extended) res->bits=0; /* subset; no -0 */
5985 #endif
5986 } /* increase */
5987 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 uprv_decNumberCopyuprv_decNumberCopy_77(res, lhs); /* [it will fit] */
5992 /* if padding needed (adjust<0), add it now... */
5993 if (adjust<0) {
5994 res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
5995 res->exponent+=adjust; /* adjust the exponent */
5996 }
5997 } /* decrease */
5998 } /* 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 if (res->exponent>set->emax-res->digits+1) { /* too big */
6003 *status|=DEC_Invalid_operation0x00000080;
6004 break;
6005 }
6006 else {
6007 decFinalize(res, set, &residue, status); /* set subnormal flags */
6008 *status&=~DEC_Underflow0x00002000; /* suppress Underflow [as per 754] */
6009 }
6010 } while(0); /* end protected */
6011
6012 #if DECSUBSET0
6013 if (allocrhs!=nullptr) free(allocrhs)uprv_free_77(allocrhs); /* drop any storage used */
6014 if (alloclhs!=nullptr) free(alloclhs)uprv_free_77(alloclhs); /* .. */
6015 #endif
6016 return res;
6017 } /* 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/* ------------------------------------------------------------------ */
6049static decNumber * decCompareOp(decNumber *res, const decNumber *lhs,
6050 const decNumber *rhs, decContext *set,
6051 Flaguint8_t op, uIntuint32_t *status) {
6052 #if DECSUBSET0
6053 decNumber *alloclhs=nullptr; /* non-nullptr if rounded lhs allocated */
6054 decNumber *allocrhs=nullptr; /* .., rhs */
6055 #endif
6056 Intint32_t result=0; /* default result value */
6057 uByteuint8_t merged; /* work */
6058
6059 #if DECCHECK0
6060 if (decCheckOperands(res, lhs, rhs, set)) return res;
6061 #endif
6062
6063 do { /* protect allocated storage */
6064 #if DECSUBSET0
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(int32_t)0x80000000; break;}
6070 lhs=alloclhs;
6071 }
6072 if (rhs->digits>set->digits) {
6073 allocrhs=decRoundOperand(rhs, set, status);
6074 if (allocrhs==nullptr) {result=BADINT(int32_t)0x80000000; 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 if (op==COMPTOTAL0x04) { /* total ordering */
6083 if (decNumberIsNegative(lhs)(((lhs)->bits&0x80)!=0) && !decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) {
6084 result=-1;
6085 break;
6086 }
6087 if (!decNumberIsNegative(lhs)(((lhs)->bits&0x80)!=0) && decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) {
6088 result=+1;
6089 break;
6090 }
6091 }
6092
6093 /* handle NaNs specially; let infinities drop through */
6094 /* This assumes sNaN (even just one) leads to NaN. */
6095 merged=(lhs->bits | rhs->bits) & (DECSNAN0x10 | DECNAN0x20);
6096 if (merged) { /* a NaN bit set */
6097 if (op==COMPARE0x01); /* result will be NaN */
6098 else if (op==COMPSIG0x06) /* treat qNaN as sNaN */
6099 *status|=DEC_Invalid_operation0x00000080 | DEC_sNaN0x40000000;
6100 else if (op==COMPTOTAL0x04) { /* 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 if (!decNumberIsNaN(lhs)(((lhs)->bits&(0x20|0x10))!=0)) result=-1;
6104 else if (!decNumberIsNaN(rhs)(((rhs)->bits&(0x20|0x10))!=0)) result=+1;
6105 /* here if both NaNs */
6106 else if (decNumberIsSNaN(lhs)(((lhs)->bits&(0x10))!=0) && decNumberIsQNaN(rhs)(((rhs)->bits&(0x20))!=0)) result=-1;
6107 else if (decNumberIsQNaN(lhs)(((lhs)->bits&(0x20))!=0) && decNumberIsSNaN(rhs)(((rhs)->bits&(0x10))!=0)) result=+1;
6108 else { /* both NaN or both sNaN */
6109 /* now it just depends on the payload */
6110 result=decUnitCompare(lhs->lsu, D2U(lhs->digits)((lhs->digits)<=49?d2utable[lhs->digits]:((lhs->digits
)+1 -1)/1)
,
6111 rhs->lsu, D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
, 0);
6112 /* [Error not possible, as these are 'aligned'] */
6113 } /* both same NaNs */
6114 if (decNumberIsNegative(lhs)(((lhs)->bits&0x80)!=0)) result=-result;
6115 break;
6116 } /* total order */
6117
6118 else if (merged & DECSNAN0x10); /* sNaN -> qNaN */
6119 else { /* here if MIN or MAX and one or two quiet NaNs */
6120 /* min or max -- 754 rules ignore single NaN */
6121 if (!decNumberIsNaN(lhs)(((lhs)->bits&(0x20|0x10))!=0) || !decNumberIsNaN(rhs)(((rhs)->bits&(0x20|0x10))!=0)) {
6122 /* just one NaN; force choice to be the non-NaN operand */
6123 op=COMPMAX0x02;
6124 if (lhs->bits & DECNAN0x20) result=-1; /* pick rhs */
6125 else result=+1; /* pick lhs */
6126 break;
6127 }
6128 } /* max or min */
6129 op=COMPNAN0x05; /* use special path */
6130 decNaNs(res, lhs, rhs, set, status); /* propagate NaN */
6131 break;
6132 }
6133 /* have numbers */
6134 if (op==COMPMAXMAG0x07 || op==COMPMINMAG0x08) result=decCompare(lhs, rhs, 1);
6135 else result=decCompare(lhs, rhs, 0); /* sign matters */
6136 } while(0); /* end protected */
6137
6138 if (result==BADINT(int32_t)0x80000000) *status|=DEC_Insufficient_storage0x00000010; /* rare */
6139 else {
6140 if (op==COMPARE0x01 || op==COMPSIG0x06 ||op==COMPTOTAL0x04) { /* returning signum */
6141 if (op==COMPTOTAL0x04 && result==0) {
6142 /* operands are numerically equal or same NaN (and same sign, */
6143 /* tested first); if identical, leave result 0 */
6144 if (lhs->exponent!=rhs->exponent) {
6145 if (lhs->exponent<rhs->exponent) result=-1;
6146 else result=+1;
6147 if (decNumberIsNegative(lhs)(((lhs)->bits&0x80)!=0)) result=-result;
6148 } /* lexp!=rexp */
6149 } /* total-order by exponent */
6150 uprv_decNumberZerouprv_decNumberZero_77(res); /* [always a valid result] */
6151 if (result!=0) { /* must be -1 or +1 */
6152 *res->lsu=1;
6153 if (result<0) res->bits=DECNEG0x80;
6154 }
6155 }
6156 else if (op==COMPNAN0x05); /* special, drop through */
6157 else { /* MAX or MIN, non-NaN result */
6158 Intint32_t residue=0; /* rounding accumulator */
6159 /* choose the operand for the result */
6160 const decNumber *choice;
6161 if (result==0) { /* operands are numerically equal */
6162 /* choose according to sign then exponent (see 754) */
6163 uByteuint8_t slhs=(lhs->bits & DECNEG0x80);
6164 uByteuint8_t srhs=(rhs->bits & DECNEG0x80);
6165 #if DECSUBSET0
6166 if (!set->extended) { /* subset: force left-hand */
6167 op=COMPMAX0x02;
6168 result=+1;
6169 }
6170 else
6171 #endif
6172 if (slhs!=srhs) { /* signs differ */
6173 if (slhs) result=-1; /* rhs is max */
6174 else result=+1; /* lhs is max */
6175 }
6176 else if (slhs && srhs) { /* both negative */
6177 if (lhs->exponent<rhs->exponent) result=+1;
6178 else result=-1;
6179 /* [if equal, use lhs, technically identical] */
6180 }
6181 else { /* both positive */
6182 if (lhs->exponent>rhs->exponent) result=+1;
6183 else result=-1;
6184 /* [ditto] */
6185 }
6186 } /* numerically equal */
6187 /* here result will be non-0; reverse if looking for MIN */
6188 if (op==COMPMIN0x03 || op==COMPMINMAG0x08) result=-result;
6189 choice=(result>0 ? lhs : rhs); /* choose */
6190 /* copy chosen to result, rounding if need be */
6191 decCopyFit(res, choice, set, &residue, status);
6192 decFinish(res, set, &residue, status)decFinalize(res,set,&residue,status);
6193 }
6194 }
6195 #if DECSUBSET0
6196 if (allocrhs!=nullptr) free(allocrhs)uprv_free_77(allocrhs); /* free any storage used */
6197 if (alloclhs!=nullptr) free(alloclhs)uprv_free_77(alloclhs); /* .. */
6198 #endif
6199 return res;
6200 } /* 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/* ------------------------------------------------------------------ */
6214static Intint32_t decCompare(const decNumber *lhs, const decNumber *rhs,
6215 Flaguint8_t abs_c) {
6216 Intint32_t result; /* result value */
6217 Intint32_t sigr; /* rhs signum */
6218 Intint32_t compare; /* work */
6219
6220 result=1; /* assume signum(lhs) */
6221 if (ISZERO(lhs)(*(lhs)->lsu==0 && (lhs)->digits==1 && (
((lhs)->bits&(0x40|0x20|0x10))==0))
) result=0;
6222 if (abs_c) {
6223 if (ISZERO(rhs)(*(rhs)->lsu==0 && (rhs)->digits==1 && (
((rhs)->bits&(0x40|0x20|0x10))==0))
) return result; /* LHS wins or both 0 */
6224 /* RHS is non-zero */
6225 if (result==0) return -1; /* LHS is 0; RHS wins */
6226 /* [here, both non-zero, result=1] */
6227 }
6228 else { /* signs matter */
6229 if (result && decNumberIsNegative(lhs)(((lhs)->bits&0x80)!=0)) result=-1;
6230 sigr=1; /* compute signum(rhs) */
6231 if (ISZERO(rhs)(*(rhs)->lsu==0 && (rhs)->digits==1 && (
((rhs)->bits&(0x40|0x20|0x10))==0))
) sigr=0;
6232 else if (decNumberIsNegative(rhs)(((rhs)->bits&0x80)!=0)) sigr=-1;
6233 if (result > sigr) return +1; /* L > R, return 1 */
6234 if (result < sigr) return -1; /* L < R, return -1 */
6235 if (result==0) return 0; /* both 0 */
6236 }
6237
6238 /* signums are the same; both are non-zero */
6239 if ((lhs->bits | rhs->bits) & DECINF0x40) { /* one or more infinities */
6240 if (decNumberIsInfinite(rhs)(((rhs)->bits&0x40)!=0)) {
6241 if (decNumberIsInfinite(lhs)(((lhs)->bits&0x40)!=0)) result=0;/* both infinite */
6242 else result=-result; /* only rhs infinite */
6243 }
6244 return result;
6245 }
6246 /* must compare the coefficients, allowing for exponents */
6247 if (lhs->exponent>rhs->exponent) { /* LHS exponent larger */
6248 /* swap sides, and sign */
6249 const decNumber *temp=lhs;
6250 lhs=rhs;
6251 rhs=temp;
6252 result=-result;
6253 }
6254 compare=decUnitCompare(lhs->lsu, D2U(lhs->digits)((lhs->digits)<=49?d2utable[lhs->digits]:((lhs->digits
)+1 -1)/1)
,
6255 rhs->lsu, D2U(rhs->digits)((rhs->digits)<=49?d2utable[rhs->digits]:((rhs->digits
)+1 -1)/1)
,
6256 rhs->exponent-lhs->exponent);
6257 if (compare!=BADINT(int32_t)0x80000000) compare*=result; /* comparison succeeded */
6258 return compare;
6259 } /* 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/* ------------------------------------------------------------------ */
6278static Intint32_t decUnitCompare(const Unituint8_t *a, Intint32_t alength,
6279 const Unituint8_t *b, Intint32_t blength, Intint32_t exp) {
6280 Unituint8_t *acc; /* accumulator for result */
6281 Unituint8_t accbuff[SD2U(DECBUFFER*2+1)(((36*2+1)+1 -1)/1)]; /* local buffer */
6282 Unituint8_t *allocacc=nullptr; /* -> allocated acc buffer, iff allocated */
6283 Intint32_t accunits, need; /* units in use or needed for acc */
6284 const Unituint8_t *l, *r, *u; /* work */
6285 Intint32_t expunits, exprem, result; /* .. */
6286
6287 if (exp==0) { /* aligned; fastpath */
6288 if (alength>blength) return 1;
6289 if (alength<blength) return -1;
6290 /* same number of units in both -- need unit-by-unit compare */
6291 l=a+alength-1;
6292 r=b+alength-1;
6293 for (;l>=a; l--, r--) {
6294 if (*l>*r) return 1;
6295 if (*l<*r) return -1;
6296 }
6297 return 0; /* all units match */
6298 } /* aligned */
6299
6300 /* Unaligned. If one is >1 unit longer than the other, padded */
6301 /* approximately, then can return easily */
6302 if (alength > blength + static_cast<Intint32_t>(D2U(exp)((exp)<=49?d2utable[exp]:((exp)+1 -1)/1))) return 1;
6303 if (alength + 1 < blength + static_cast<Intint32_t>(D2U(exp)((exp)<=49?d2utable[exp]:((exp)+1 -1)/1))) 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 need=blength+D2U(exp)((exp)<=49?d2utable[exp]:((exp)+1 -1)/1); /* maximum real length of B */
6309 if (need<alength) need=alength;
6310 need+=2;
6311 acc=accbuff; /* assume use local buffer */
6312 if (need*sizeof(Unituint8_t)>sizeof(accbuff)) {
6313 allocacc = static_cast<Unituint8_t*>(malloc(need * sizeof(Unit))uprv_malloc_77(need * sizeof(uint8_t)));
6314 if (allocacc==nullptr) return BADINT(int32_t)0x80000000; /* hopeless -- abandon */
6315 acc=allocacc;
6316 }
6317 /* Calculate units and remainder from exponent. */
6318 expunits=exp/DECDPUN1;
6319 exprem=exp%DECDPUN1;
6320 /* subtract [A+B*(-m)] */
6321 accunits=decUnitAddSub(a, alength, b, blength, expunits, acc,
6322 -static_cast<Intint32_t>(powersDECPOWERS[exprem]));
6323 /* [UnitAddSub result may have leading zeros, even on zero] */
6324 if (accunits<0) result=-1; /* negative result */
6325 else { /* non-negative result */
6326 /* check units of the result before freeing any storage */
6327 for (u=acc; u<acc+accunits-1 && *u==0;) u++;
6328 result=(*u==0 ? 0 : +1);
6329 }
6330 /* clean up and return the result */
6331 if (allocacc!=nullptr) free(allocacc)uprv_free_77(allocacc); /* drop any storage used */
6332 return result;
6333 } /* 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/* ------------------------------------------------------------------ */
6382static Intint32_t decUnitAddSub(const Unituint8_t *a, Intint32_t alength,
6383 const Unituint8_t *b, Intint32_t blength, Intint32_t bshift,
6384 Unituint8_t *c, Intint32_t m) {
6385 const Unituint8_t *alsu=a; /* A lsu [need to remember it] */
6386 Unituint8_t *clsu=c; /* C ditto */
6387 Unituint8_t *minC; /* low water mark for C */
6388 Unituint8_t *maxC; /* high water mark for C */
6389 eIntint32_t carry=0; /* carry integer (could be Long) */
6390 Intint32_t add; /* work */
6391 #if DECDPUN1<=4 /* myriadal, millenary, etc. */
6392 Intint32_t est; /* estimated quotient */
6393 #endif
6394
6395 #if DECTRACE0
6396 if (alength<1 || blength<1)
6397 printf("decUnitAddSub: alen blen m %ld %ld [%ld]\n", alength, blength, m);
6398 #endif
6399
6400 maxC=c+alength; /* A is usually the longer */
6401 minC=c+blength; /* .. and B the shorter */
6402 if (bshift!=0) { /* B is shifted; low As copy across */
6403 minC+=bshift;
6404 /* if in place [common], skip copy unless there's a gap [rare] */
6405 if (a==c && bshift<=alength) {
6406 c+=bshift;
6407 a+=bshift;
6408 }
6409 else for (; c<clsu+bshift; a++, c++) { /* copy needed */
6410 if (a<alsu+alength) *c=*a;
6411 else *c=0;
6412 }
6413 }
6414 if (minC>maxC) { /* swap */
6415 Unituint8_t *hold=minC;
6416 minC=maxC;
6417 maxC=hold;
6418 }
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 for (; c<minC; c++) {
6425 carry+=*a;
6426 a++;
6427 carry += (static_cast<eIntint32_t>(*b)) * m; /* [special-casing m=1/-1 */
6428 b++; /* here is not a win] */
6429 /* here carry is new Unit of digits; it could be +ve or -ve */
6430 if (static_cast<ueIntuint32_t>(carry) <= DECDPUNMAX9) { /* fastpath 0-DECDPUNMAX */
6431 *c = static_cast<Unituint8_t>(carry);
6432 carry=0;
6433 continue;
6434 }
6435 #if DECDPUN1==4 /* use divide-by-multiply */
6436 if (carry>=0) {
6437 est=(((ueIntuint32_t)carry>>11)*53687)>>18;
6438 *c=(Unituint8_t)(carry-est*(DECDPUNMAX9+1)); /* remainder */
6439 carry=est; /* likely quotient [89%] */
6440 if (*c<DECDPUNMAX9+1) continue; /* estimate was correct */
6441 carry++;
6442 *c-=DECDPUNMAX9+1;
6443 continue;
6444 }
6445 /* negative case */
6446 carry=carry+(eIntint32_t)(DECDPUNMAX9+1)*(DECDPUNMAX9+1); /* make positive */
6447 est=(((ueIntuint32_t)carry>>11)*53687)>>18;
6448 *c=(Unituint8_t)(carry-est*(DECDPUNMAX9+1));
6449 carry=est-(DECDPUNMAX9+1); /* correctly negative */
6450 if (*c<DECDPUNMAX9+1) continue; /* was OK */
6451 carry++;
6452 *c-=DECDPUNMAX9+1;
6453 #elif DECDPUN1==3
6454 if (carry>=0) {
6455 est=(((ueIntuint32_t)carry>>3)*16777)>>21;
6456 *c=(Unituint8_t)(carry-est*(DECDPUNMAX9+1)); /* remainder */
6457 carry=est; /* likely quotient [99%] */
6458 if (*c<DECDPUNMAX9+1) continue; /* estimate was correct */
6459 carry++;
6460 *c-=DECDPUNMAX9+1;
6461 continue;
6462 }
6463 /* negative case */
6464 carry=carry+(eIntint32_t)(DECDPUNMAX9+1)*(DECDPUNMAX9+1); /* make positive */
6465 est=(((ueIntuint32_t)carry>>3)*16777)>>21;
6466 *c=(Unituint8_t)(carry-est*(DECDPUNMAX9+1));
6467 carry=est-(DECDPUNMAX9+1); /* correctly negative */
6468 if (*c<DECDPUNMAX9+1) continue; /* was OK */
6469 carry++;
6470 *c-=DECDPUNMAX9+1;
6471 #elif DECDPUN1<=2
6472 /* Can use QUOT10 as carry <= 4 digits */
6473 if (carry>=0) {
6474 est=QUOT10(carry, DECDPUN)((((uint32_t)(carry)>>(1))*multies[1])>>17);
6475 *c = static_cast<Unituint8_t>(carry - est * (DECDPUNMAX9 + 1)); /* remainder */
6476 carry=est; /* quotient */
6477 continue;
6478 }
6479 /* negative case */
6480 carry = carry + static_cast<eIntint32_t>(DECDPUNMAX9 + 1) * (DECDPUNMAX9 + 1); /* make positive */
6481 est=QUOT10(carry, DECDPUN)((((uint32_t)(carry)>>(1))*multies[1])>>17);
6482 *c = static_cast<Unituint8_t>(carry - est * (DECDPUNMAX9 + 1));
6483 carry=est-(DECDPUNMAX9+1); /* correctly negative */
6484 #else
6485 /* remainder operator is undefined if negative, so must test */
6486 if ((ueIntuint32_t)carry<(DECDPUNMAX9+1)*2) { /* fastpath carry +1 */
6487 *c=(Unituint8_t)(carry-(DECDPUNMAX9+1)); /* [helps additions] */
6488 carry=1;
6489 continue;
6490 }
6491 if (carry>=0) {
6492 *c=(Unituint8_t)(carry%(DECDPUNMAX9+1));
6493 carry=carry/(DECDPUNMAX9+1);
6494 continue;
6495 }
6496 /* negative case */
6497 carry=carry+(eIntint32_t)(DECDPUNMAX9+1)*(DECDPUNMAX9+1); /* make positive */
6498 *c=(Unituint8_t)(carry%(DECDPUNMAX9+1));
6499 carry=carry/(DECDPUNMAX9+1)-(DECDPUNMAX9+1);
6500 #endif
6501 } /* c */
6502
6503 /* now may have one or other to complete */
6504 /* [pretest to avoid loop setup/shutdown] */
6505 if (c<maxC) for (; c<maxC; c++) {
6506 if (a<alsu+alength) { /* still in A */
6507 carry+=*a;
6508 a++;
6509 }
6510 else { /* inside B */
6511 carry += static_cast<eIntint32_t>(*b) * m;
6512 b++;
6513 }
6514 /* here carry is new Unit of digits; it could be +ve or -ve and */
6515 /* magnitude up to DECDPUNMAX squared */
6516 if (static_cast<ueIntuint32_t>(carry) <= DECDPUNMAX9) { /* fastpath 0-DECDPUNMAX */
6517 *c = static_cast<Unituint8_t>(carry);
6518 carry=0;
6519 continue;
6520 }
6521 /* result for this unit is negative or >DECDPUNMAX */
6522 #if DECDPUN1==4 /* use divide-by-multiply */
6523 if (carry>=0) {
6524 est=(((ueIntuint32_t)carry>>11)*53687)>>18;
6525 *c=(Unituint8_t)(carry-est*(DECDPUNMAX9+1)); /* remainder */
6526 carry=est; /* likely quotient [79.7%] */
6527 if (*c<DECDPUNMAX9+1) continue; /* estimate was correct */
6528 carry++;
6529 *c-=DECDPUNMAX9+1;
6530 continue;
6531 }
6532 /* negative case */
6533 carry=carry+(eIntint32_t)(DECDPUNMAX9+1)*(DECDPUNMAX9+1); /* make positive */
6534 est=(((ueIntuint32_t)carry>>11)*53687)>>18;
6535 *c=(Unituint8_t)(carry-est*(DECDPUNMAX9+1));
6536 carry=est-(DECDPUNMAX9+1); /* correctly negative */
6537 if (*c<DECDPUNMAX9+1) continue; /* was OK */
6538 carry++;
6539 *c-=DECDPUNMAX9+1;
6540 #elif DECDPUN1==3
6541 if (carry>=0) {
6542 est=(((ueIntuint32_t)carry>>3)*16777)>>21;
6543 *c=(Unituint8_t)(carry-est*(DECDPUNMAX9+1)); /* remainder */
6544 carry=est; /* likely quotient [99%] */
6545 if (*c<DECDPUNMAX9+1) continue; /* estimate was correct */
6546 carry++;
6547 *c-=DECDPUNMAX9+1;
6548 continue;
6549 }
6550 /* negative case */
6551 carry=carry+(eIntint32_t)(DECDPUNMAX9+1)*(DECDPUNMAX9+1); /* make positive */
6552 est=(((ueIntuint32_t)carry>>3)*16777)>>21;
6553 *c=(Unituint8_t)(carry-est*(DECDPUNMAX9+1));
6554 carry=est-(DECDPUNMAX9+1); /* correctly negative */
6555 if (*c<DECDPUNMAX9+1) continue; /* was OK */
6556 carry++;
6557 *c-=DECDPUNMAX9+1;
6558 #elif DECDPUN1<=2
6559 if (carry>=0) {
6560 est=QUOT10(carry, DECDPUN)((((uint32_t)(carry)>>(1))*multies[1])>>17);
6561 *c = static_cast<Unituint8_t>(carry - est * (DECDPUNMAX9 + 1)); /* remainder */
6562 carry=est; /* quotient */
6563 continue;
6564 }
6565 /* negative case */
6566 carry = carry + static_cast<eIntint32_t>(DECDPUNMAX9 + 1) * (DECDPUNMAX9 + 1); /* make positive */
6567 est=QUOT10(carry, DECDPUN)((((uint32_t)(carry)>>(1))*multies[1])>>17);
6568 *c = static_cast<Unituint8_t>(carry - est * (DECDPUNMAX9 + 1));
6569 carry=est-(DECDPUNMAX9+1); /* correctly negative */
6570 #else
6571 if ((ueIntuint32_t)carry<(DECDPUNMAX9+1)*2){ /* fastpath carry 1 */
6572 *c=(Unituint8_t)(carry-(DECDPUNMAX9+1));
6573 carry=1;
6574 continue;
6575 }
6576 /* remainder operator is undefined if negative, so must test */
6577 if (carry>=0) {
6578 *c=(Unituint8_t)(carry%(DECDPUNMAX9+1));
6579 carry=carry/(DECDPUNMAX9+1);
6580 continue;
6581 }
6582 /* negative case */
6583 carry=carry+(eIntint32_t)(DECDPUNMAX9+1)*(DECDPUNMAX9+1); /* make positive */
6584 *c=(Unituint8_t)(carry%(DECDPUNMAX9+1));
6585 carry=carry/(DECDPUNMAX9+1)-(DECDPUNMAX9+1);
6586 #endif
6587 } /* 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 if (carry==0) return static_cast<int32_t>(c-clsu); /* no carry, so no more to do */
6592 if (carry>0) { /* positive carry */
6593 *c = static_cast<Unituint8_t>(carry); /* place as new unit */
6594 c++; /* .. */
6595 return static_cast<int32_t>(c-clsu);
6596 }
6597 /* -ve carry: it's a borrow; complement needed */
6598 add=1; /* temporary carry... */
6599 for (c=clsu; c<maxC; c++) {
6600 add=DECDPUNMAX9+add-*c;
6601 if (add<=DECDPUNMAX9) {
6602 *c = static_cast<Unituint8_t>(add);
6603 add=0;
6604 }
6605 else {
6606 *c=0;
6607 add=1;
6608 }
6609 }
6610 /* add an extra unit iff it would be non-zero */
6611 #if DECTRACE0
6612 printf("UAS borrow: add %ld, carry %ld\n", add, carry);
6613 #endif
6614 if ((add-carry-1)!=0) {
6615 *c = static_cast<Unituint8_t>(add - carry - 1);
6616 c++; /* interesting, include it */
6617 }
6618 return static_cast<int32_t>(clsu-c); /* -ve result indicates borrowed */
6619 } /* 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/* ------------------------------------------------------------------ */
6636static decNumber * decTrim(decNumber *dn, decContext *set, Flaguint8_t all,
6637 Flaguint8_t noclamp, Intint32_t *dropped) {
6638 Intint32_t d, exp; /* work */
6639 uIntuint32_t cut; /* .. */
6640 Unituint8_t *up; /* -> current Unit */
6641
6642 #if DECCHECK0
6643 if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
6644 #endif
6645
6646 *dropped=0; /* assume no zeros dropped */
6647 if ((dn->bits & DECSPECIAL(0x40|0x20|0x10)) /* fast exit if special .. */
6648 || (*dn->lsu & 0x01)) return dn; /* .. or odd */
6649 if (ISZERO(dn)(*(dn)->lsu==0 && (dn)->digits==1 && ((
(dn)->bits&(0x40|0x20|0x10))==0))
) { /* .. or 0 */
6650 dn->exponent=0; /* (sign is preserved) */
6651 return dn;
6652 }
6653
6654 /* have a finite number which is even */
6655 exp=dn->exponent;
6656 cut=1; /* digit (1-DECDPUN) in Unit */
6657 up=dn->lsu; /* -> current Unit */
6658 for (d=0; d<dn->digits-1; d++) { /* [don't strip the final digit] */
6659 /* slice by powers */
6660 #if DECDPUN1<=4
6661 uIntuint32_t quot=QUOT10(*up, cut)((((uint32_t)(*up)>>(cut))*multies[cut])>>17);
6662 if ((*up-quot*powersDECPOWERS[cut])!=0) break; /* found non-0 digit */
6663 #else
6664 if (*up%powersDECPOWERS[cut]!=0) break; /* found non-0 digit */
6665 #endif
6666 /* have a trailing 0 */
6667 if (!all) { /* trimming */
6668 /* [if exp>0 then all trailing 0s are significant for trim] */
6669 if (exp<=0) { /* if digit might be significant */
6670 if (exp==0) break; /* then quit */
6671 exp++; /* next digit might be significant */
6672 }
6673 }
6674 cut++; /* next power */
6675 if (cut>DECDPUN1) { /* need new Unit */
6676 up++;
6677 cut=1;
6678 }
6679 } /* d */
6680 if (d==0) return dn; /* none to drop */
6681
6682 /* may need to limit drop if clamping */
6683 if (set->clamp && !noclamp) {
6684 Intint32_t maxd=set->emax-set->digits+1-dn->exponent;
6685 if (maxd<=0) return dn; /* nothing possible */
6686 if (d>maxd) d=maxd;
6687 }
6688
6689 /* effect the drop */
6690 decShiftToLeast(dn->lsu, D2U(dn->digits)((dn->digits)<=49?d2utable[dn->digits]:((dn->digits
)+1 -1)/1)
, d);
6691 dn->exponent+=d; /* maintain numerical value */
6692 dn->digits-=d; /* new length */
6693 *dropped=d; /* report the count */
6694 return dn;
6695 } /* 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/* ------------------------------------------------------------------ */
6707static void decReverse(Unituint8_t *ulo, Unituint8_t *uhi) {
6708 Unituint8_t temp;
6709 for (; ulo<uhi; ulo++, uhi--) {
6710 temp=*ulo;
6711 *ulo=*uhi;
6712 *uhi=temp;
6713 }
6714 } /* 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/* ------------------------------------------------------------------ */
6729static Intint32_t decShiftToMost(Unituint8_t *uar, Intint32_t digits, Intint32_t shift) {
6730 Unituint8_t *target, *source, *first; /* work */
6731 Intint32_t cut; /* odd 0's to add */
6732 uIntuint32_t next; /* work */
6733
6734 if (shift==0) return digits; /* [fastpath] nothing to do */
6735 if ((digits+shift)<=DECDPUN1) { /* [fastpath] single-unit case */
6736 *uar = static_cast<Unituint8_t>(*uar * powersDECPOWERS[shift]);
6737 return digits+shift;
6738 }
6739
6740 next=0; /* all paths */
6741 source=uar+D2U(digits)((digits)<=49?d2utable[digits]:((digits)+1 -1)/1)-1; /* where msu comes from */
6742 target=source+D2U(shift)((shift)<=49?d2utable[shift]:((shift)+1 -1)/1); /* where upper part of first cut goes */
6743 cut=DECDPUN1-MSUDIGITS(shift)((shift)-(((shift)<=49?d2utable[shift]:((shift)+1 -1)/1)-1
)*1)
; /* where to slice */
6744 if (cut==0) { /* unit-boundary case */
6745 for (; source>=uar; source--, target--) *target=*source;
6746 }
6747 else {
6748 first=uar+D2U(digits+shift)((digits+shift)<=49?d2utable[digits+shift]:((digits+shift)
+1 -1)/1)
-1; /* where msu of source will end up */
6749 for (; source>=uar; source--, target--) {
6750 /* split the source Unit and accumulate remainder for next */
6751 #if DECDPUN1<=4
6752 uIntuint32_t quot=QUOT10(*source, cut)((((uint32_t)(*source)>>(cut))*multies[cut])>>17);
6753 uIntuint32_t rem=*source-quot*powersDECPOWERS[cut];
6754 next+=quot;
6755 #else
6756 uIntuint32_t rem=*source%powersDECPOWERS[cut];
6757 next+=*source/powersDECPOWERS[cut];
6758 #endif
6759 if (target <= first) *target = static_cast<Unituint8_t>(next); /* write to target iff valid */
6760 next=rem*powersDECPOWERS[DECDPUN1-cut]; /* save remainder for next Unit */
6761 }
6762 } /* shift-move */
6763
6764 /* propagate any partial unit to one below and clear the rest */
6765 for (; target>=uar; target--) {
6766 *target = static_cast<Unituint8_t>(next);
6767 next=0;
6768 }
6769 return digits+shift;
6770 } /* 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/* ------------------------------------------------------------------ */
6785static Intint32_t decShiftToLeast(Unituint8_t *uar, Intint32_t units, Intint32_t shift) {
6786 Unituint8_t *target, *up; /* work */
6787 Intint32_t cut, count; /* work */
6788 Intint32_t quot, rem; /* for division */
6789
6790 if (shift==0) return units; /* [fastpath] nothing to do */
6791 if (shift==units*DECDPUN1) { /* [fastpath] little to do */
6792 *uar=0; /* all digits cleared gives zero */
6793 return 1; /* leaves just the one */
6794 }
6795
6796 target=uar; /* both paths */
6797 cut=MSUDIGITS(shift)((shift)-(((shift)<=49?d2utable[shift]:((shift)+1 -1)/1)-1
)*1)
;
6798 if (cut==DECDPUN1) { /* unit-boundary case; easy */
6799 up=uar+D2U(shift)((shift)<=49?d2utable[shift]:((shift)+1 -1)/1);
6800 for (; up<uar+units; target++, up++) *target=*up;
6801 return static_cast<int32_t>(target-uar);
6802 }
6803
6804 /* messier */
6805 up=uar+D2U(shift-cut)((shift-cut)<=49?d2utable[shift-cut]:((shift-cut)+1 -1)/1); /* source; correct to whole Units */
6806 count=units*DECDPUN1-shift; /* the maximum new length */
6807 #if DECDPUN1<=4
6808 quot=QUOT10(*up, cut)((((uint32_t)(*up)>>(cut))*multies[cut])>>17);
6809 #else
6810 quot=*up/powersDECPOWERS[cut];
6811 #endif
6812 for (; ; target++) {
6813 *target = static_cast<Unituint8_t>(quot);
6814 count-=(DECDPUN1-cut);
6815 if (count<=0) break;
6816 up++;
6817 quot=*up;
6818 #if DECDPUN1<=4
6819 quot=QUOT10(quot, cut)((((uint32_t)(quot)>>(cut))*multies[cut])>>17);
6820 rem=*up-quot*powersDECPOWERS[cut];
6821 #else
6822 rem=quot%powersDECPOWERS[cut];
6823 quot=quot/powersDECPOWERS[cut];
6824 #endif
6825 *target = static_cast<Unituint8_t>(*target + rem * powersDECPOWERS[DECDPUN1 - cut]);
6826 count-=cut;
6827 if (count<=0) break;
6828 }
6829 return static_cast<int32_t>(target-uar+1);
6830 } /* decShiftToLeast */
6831
6832#if DECSUBSET0
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/* ------------------------------------------------------------------ */
6851static decNumber *decRoundOperand(const decNumber *dn, decContext *set,
6852 uIntuint32_t *status) {
6853 decNumber *res; /* result structure */
6854 uIntuint32_t newstatus=0; /* status from round */
6855 Intint32_t 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)uprv_malloc_77(sizeof(decNumber) +(((set->digits)<=49?d2utable
[set->digits]:((set->digits)+1 -1)/1)-1)*sizeof(uint8_t
))
6860 +(D2U(set->digits)-1)*sizeof(Unit))uprv_malloc_77(sizeof(decNumber) +(((set->digits)<=49?d2utable
[set->digits]:((set->digits)+1 -1)/1)-1)*sizeof(uint8_t
))
;
6861 if (res==nullptr) {
6862 *status|=DEC_Insufficient_storage0x00000010;
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_Inexact0x00000020) 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/* ------------------------------------------------------------------ */
6887static void decCopyFit(decNumber *dest, const decNumber *src,
6888 decContext *set, Intint32_t *residue, uIntuint32_t *status) {
6889 dest->bits=src->bits;
6890 dest->exponent=src->exponent;
6891 decSetCoeff(dest, set, src->lsu, src->digits, residue, status);
6892 } /* 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 */
6932static const uByteuint8_t resmap[10]={0, 3, 3, 3, 3, 5, 7, 7, 7, 7};
6933static void decSetCoeff(decNumber *dn, decContext *set, const Unituint8_t *lsu,
6934 Intint32_t len, Intint32_t *residue, uIntuint32_t *status) {
6935 Intint32_t discard; /* number of digits to discard */
6936 uIntuint32_t cut; /* cut point in Unit */
6937 const Unituint8_t *up; /* work */
6938 Unituint8_t *target; /* .. */
6939 Intint32_t count; /* .. */
6940 #if DECDPUN1<=4
6941 uIntuint32_t temp; /* .. */
6942 #endif
6943
6944 discard=len-set->digits; /* digits to discard */
6945 if (discard<=0) { /* no digits are being discarded */
6946 if (dn->lsu!=lsu) { /* copy needed */
6947 /* copy the coefficient array to the result number; no shift needed */
6948 count=len; /* avoids D2U */
6949 up=lsu;
6950 for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN1)
6951 *target=*up;
6952 dn->digits=len; /* set the new length */
6953 }
6954 /* dn->exponent and residue are unchanged, record any inexactitude */
6955 if (*residue!=0) *status|=(DEC_Inexact0x00000020 | DEC_Rounded0x00000800);
6956 return;
6957 }
6958
6959 /* some digits must be discarded ... */
6960 dn->exponent+=discard; /* maintain numerical value */
6961 *status|=DEC_Rounded0x00000800; /* accumulate Rounded status */
6962 if (*residue>1) *residue=1; /* previous residue now to right, so reduce */
6963
6964 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 if (*residue<=0) { /* not already positive */
6968 count=len; /* avoids D2U */
6969 for (up=lsu; count>0; up++, count-=DECDPUN1) if (*up!=0) { /* found non-0 */
6970 *residue=1;
6971 break; /* no need to check any others */
6972 }
6973 }
6974 if (*residue!=0) *status|=DEC_Inexact0x00000020; /* record inexactitude */
6975 *dn->lsu=0; /* coefficient will now be 0 */
6976 dn->digits=1; /* .. */
6977 return;
6978 } /* 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 count=0;
6987 for (up=lsu;; up++) {
6988 count+=DECDPUN1;
6989 if (count>=discard) break; /* full ones all checked */
6990 if (*up!=0) *residue=1;
6991 } /* up */
6992
6993 /* here up -> Unit with first discarded digit */
6994 cut=discard-(count-DECDPUN1)-1;
6995 if (cut==DECDPUN1-1) { /* unit-boundary case (fast) */
6996 Unituint8_t half = static_cast<Unituint8_t>(powersDECPOWERS[DECDPUN1]) >> 1;
6997 /* set residue directly */
6998 if (*up>=half) {
6999 if (*up>half) *residue=7;
7000 else *residue+=5; /* add sticky bit */
7001 }
7002 else { /* <half */
7003 if (*up!=0) *residue=3; /* [else is 0, leave as sticky bit] */
7004 }
7005 if (set->digits<=0) { /* special for Quantize/Subnormal :-( */
7006 *dn->lsu=0; /* .. result is 0 */
7007 dn->digits=1; /* .. */
7008 }
7009 else { /* shift to least */
7010 count=set->digits; /* now digits to end up with */
7011 dn->digits=count; /* set the new length */
7012 up++; /* move to next */
7013 /* on unit boundary, so shift-down copy loop is simple */
7014 for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN1)
7015 *target=*up;
7016 }
7017 } /* unit-boundary case */
7018
7019 else { /* discard digit is in low digit(s), and not top digit */
7020 uIntuint32_t discard1; /* first discarded digit */
7021 uIntuint32_t quot, rem; /* for divisions */
7022 if (cut==0) quot=*up; /* is at bottom of unit */
7023 else /* cut>0 */ { /* it's not at bottom of unit */
7024 #if DECDPUN1<=4
7025 U_ASSERT(/* cut >= 0 &&*/ cut <= 4)(static_cast <bool> (cut <= 4) ? void (0) : __assert_fail
("cut <= 4", __builtin_FILE (), __builtin_LINE (), __extension__
__PRETTY_FUNCTION__))
;
7026 quot=QUOT10(*up, cut)((((uint32_t)(*up)>>(cut))*multies[cut])>>17);
7027 rem=*up-quot*powersDECPOWERS[cut];
7028 #else
7029 rem=*up%powersDECPOWERS[cut];
7030 quot=*up/powersDECPOWERS[cut];
7031 #endif
7032 if (rem!=0) *residue=1;
7033 }
7034 /* discard digit is now at bottom of quot */
7035 #if DECDPUN1<=4
7036 temp=(quot*6554)>>16; /* fast /10 */
7037 /* Vowels algorithm here not a win (9 instructions) */
7038 discard1=quot-X10(temp)(((temp)<<1)+((temp)<<3));
7039 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 *residue+=resmap[discard1];
7047 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 if (set->digits<=0) { /* special for Quantize/Subnormal :-( */
7052 *dn->lsu=0; /* .. result is 0 */
7053 dn->digits=1; /* .. */
7054 }
7055 else { /* shift to least needed */
7056 count=set->digits; /* now digits to end up with */
7057 dn->digits=count; /* set the new length */
7058 /* shift-copy the coefficient array to the result number */
7059 for (target=dn->lsu; ; target++) {
7060 *target = static_cast<Unituint8_t>(quot);
7061 count-=(DECDPUN1-cut);
7062 if (count<=0) break;
7063 up++;
7064 quot=*up;
7065 #if DECDPUN1<=4
7066 quot=QUOT10(quot, cut)((((uint32_t)(quot)>>(cut))*multies[cut])>>17);
7067 rem=*up-quot*powersDECPOWERS[cut];
7068 #else
7069 rem=quot%powersDECPOWERS[cut];
7070 quot=quot/powersDECPOWERS[cut];
7071 #endif
7072 *target = static_cast<Unituint8_t>(*target + rem * powersDECPOWERS[DECDPUN1 - cut]);
7073 count-=cut;
7074 if (count<=0) break;
7075 } /* shift-copy loop */
7076 } /* shift to least */
7077 } /* not unit boundary */
7078
7079 if (*residue!=0) *status|=DEC_Inexact0x00000020; /* record inexactitude */
7080 } /* 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/* ------------------------------------------------------------------ */
7114static void decApplyRound(decNumber *dn, decContext *set, Intint32_t residue,
7115 uIntuint32_t *status) {
7116 Intint32_t bump; /* 1 if coefficient needs to be incremented */
7117 /* -1 if coefficient needs to be decremented */
7118
7119 if (residue==0) return; /* nothing to apply */
7120
7121 bump=0; /* assume a smooth ride */
7122
7123 /* now decide whether, and how, to round, depending on mode */
7124 switch (set->round) {
7125 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 Intint32_t lsd5=*dn->lsu%5; /* get lsd and quintate */
7132 if (residue<0 && lsd5!=1) bump=-1;
7133 else if (residue>0 && lsd5==0) bump=1;
7134 /* [bump==1 could be applied directly; use common path for clarity] */
7135 break;} /* r-05 */
7136
7137 case DEC_ROUND_DOWN: {
7138 /* no change, except if negative residue */
7139 if (residue<0) bump=-1;
7140 break;} /* r-d */
7141
7142 case DEC_ROUND_HALF_DOWN: {
7143 if (residue>5) bump=1;
7144 break;} /* r-h-d */
7145
7146 case DEC_ROUND_HALF_EVEN: {
7147 if (residue>5) bump=1; /* >0.5 goes up */
7148 else if (residue==5) { /* exactly 0.5000... */
7149 /* 0.5 goes up iff [new] lsd is odd */
7150 if (*dn->lsu & 0x01) bump=1;
7151 }
7152 break;} /* r-h-e */
7153
7154 case DEC_ROUND_HALF_UP: {
7155 if (residue>=5) bump=1;
7156 break;} /* r-h-u */
7157
7158 case DEC_ROUND_UP: {
7159 if (residue>0) bump=1;
7160 break;} /* r-u */
7161
7162 case DEC_ROUND_CEILING: {
7163 /* same as _UP for positive numbers, and as _DOWN for negatives */
7164 /* [negative residue cannot occur on 0] */
7165 if (decNumberIsNegative(dn)(((dn)->bits&0x80)!=0)) {
7166 if (residue<0) bump=-1;
7167 }
7168 else {
7169 if (residue>0) bump=1;
7170 }
7171 break;} /* r-c */
7172
7173 case DEC_ROUND_FLOOR: {
7174 /* same as _UP for negative numbers, and as _DOWN for positive */
7175 /* [negative residue cannot occur on 0] */
7176 if (!decNumberIsNegative(dn)(((dn)->bits&0x80)!=0)) {
7177 if (residue<0) bump=-1;
7178 }
7179 else {
7180 if (residue>0) bump=1;
7181 }
7182 break;} /* r-f */
7183
7184 default: { /* e.g., DEC_ROUND_MAX */
7185 *status|=DEC_Invalid_context0x00000040;
7186 #if DECTRACE0 || (DECCHECK0 && DECVERB1)
7187 printf("Unknown rounding mode: %d\n", set->round);
7188 #endif
7189 break;}
7190 } /* switch */
7191
7192 /* now bump the number, up or down, if need be */
7193 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 if (bump>0) {
7201 Unituint8_t *up; /* work */
7202 uIntuint32_t count=dn->digits; /* digits to be checked */
7203 for (up=dn->lsu; ; up++) {
7204 if (count<=DECDPUN1) {
7205 /* this is the last Unit (the msu) */
7206 if (*up!=powersDECPOWERS[count]-1) break; /* not still 9s */
7207 /* here if it, too, is all nines */
7208 *up = static_cast<Unituint8_t>(powersDECPOWERS[count - 1]); /* here 999 -> 100 etc. */
7209 for (up=up-1; up>=dn->lsu; up--) *up=0; /* others all to 0 */
7210 dn->exponent++; /* and bump exponent */
7211 /* [which, very rarely, could cause Overflow...] */
7212 if ((dn->exponent+dn->digits)>set->emax+1) {
7213 decSetOverflow(dn, set, status);
7214 }
7215 return; /* done */
7216 }
7217 /* a full unit to check, with more to come */
7218 if (*up!=DECDPUNMAX9) break; /* not still 9s */
7219 count-=DECDPUN1;
7220 } /* up */
7221 } /* bump>0 */
7222 else { /* -1 */
7223 /* here checking for a pre-bump of 1000... (leading 1, all */
7224 /* other digits zero) */
7225 Unituint8_t *up, *sup; /* work */
7226 uIntuint32_t count=dn->digits; /* digits to be checked */
7227 for (up=dn->lsu; ; up++) {
7228 if (count<=DECDPUN1) {
7229 /* this is the last Unit (the msu) */
7230 if (*up!=powersDECPOWERS[count-1]) break; /* not 100.. */
7231 /* here if have the 1000... case */
7232 sup=up; /* save msu pointer */
7233 *up = static_cast<Unituint8_t>(powersDECPOWERS[count]) - 1; /* here 100 in msu -> 999 */
7234 /* others all to all-nines, too */
7235 for (up=up-1; up>=dn->lsu; up--) *up = static_cast<Unituint8_t>(powersDECPOWERS[DECDPUN1]) - 1;
7236 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 if (dn->exponent+1==set->emin-set->digits+1) {
7244 if (count==1 && dn->digits==1) *sup=0; /* here 9 -> 0[.9] */
7245 else {
7246 *sup = static_cast<Unituint8_t>(powersDECPOWERS[count - 1]) - 1; /* here 999.. in msu -> 99.. */
7247 dn->digits--;
7248 }
7249 dn->exponent++;
7250 *status|=DEC_Underflow0x00002000 | DEC_Subnormal0x00001000 | DEC_Inexact0x00000020 | DEC_Rounded0x00000800;
7251 }
7252 return; /* done */
7253 }
7254
7255 /* a full unit to check, with more to come */
7256 if (*up!=0) break; /* not still 0s */
7257 count-=DECDPUN1;
7258 } /* up */
7259
7260 } /* bump<0 */
7261
7262 /* Actual bump needed. Do it. */
7263 decUnitAddSub(dn->lsu, D2U(dn->digits)((dn->digits)<=49?d2utable[dn->digits]:((dn->digits
)+1 -1)/1)
, uarrone, 1, 0, dn->lsu, bump);
7264 } /* decApplyRound */
7265
7266#if DECSUBSET0
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/* ------------------------------------------------------------------ */
7283static void decFinish(decNumber *dn, decContext *set, Int *residue,decFinalize(decNumber *dn,decContext *set,int32_t *residue,uint32_t
*status)
7284 uInt *status)decFinalize(decNumber *dn,decContext *set,int32_t *residue,uint32_t
*status)
{
7285 if (!set->extended) {
7286 if ISZERO(dn)(*(dn)->lsu==0 && (dn)->digits==1 && ((
(dn)->bits&(0x40|0x20|0x10))==0))
{ /* 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/* ------------------------------------------------------------------ */
7318static void decFinalize(decNumber *dn, decContext *set, Intint32_t *residue,
7319 uIntuint32_t *status) {
7320 Intint32_t shift; /* shift needed if clamping */
7321 Intint32_t 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 if (dn->exponent<=tinyexp) { /* prefilter */
7330 Intint32_t comp;
7331 decNumber nmin;
7332 /* A very nasty case here is dn == Nmin and residue<0 */
7333 if (dn->exponent<tinyexp) {
7334 /* Go handle subnormals; this will apply round if needed. */
7335 decSetSubnormal(dn, set, residue, status);
7336 return;
7337 }
7338 /* Equals case: only subnormal if dn=Nmin and negative residue */
7339 uprv_decNumberZerouprv_decNumberZero_77(&nmin);
7340 nmin.lsu[0]=1;
7341 nmin.exponent=set->emin;
7342 comp=decCompare(dn, &nmin, 1); /* (signless compare) */
7343 if (comp==BADINT(int32_t)0x80000000) { /* oops */
7344 *status|=DEC_Insufficient_storage0x00000010; /* abandon... */
7345 return;
7346 }
7347 if (*residue<0 && comp==0) { /* neg residue and dn==Nmin */
7348 decApplyRound(dn, set, *residue, status); /* might force down */
7349 decSetSubnormal(dn, set, residue, status);
7350 return;
7351 }
7352 }
7353
7354 /* now apply any pending round (this could raise overflow). */
7355 if (*residue!=0) decApplyRound(dn, set, *residue, status);
7356
7357 /* Check for overflow [redundant in the 'rare' case] or clamp */
7358 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 if (dn->exponent>set->emax-dn->digits+1) { /* too big */
7363 decSetOverflow(dn, set, status);
7364 return;
7365 }
7366 /* here when the result is normal but in clamp range */
7367 if (!set->clamp) return;
7368
7369 /* here when need to apply the IEEE exponent clamp (fold-down) */
7370 shift=dn->exponent-(set->emax-set->digits+1);
7371
7372 /* shift coefficient (if non-zero) */
7373 if (!ISZERO(dn)(*(dn)->lsu==0 && (dn)->digits==1 && ((
(dn)->bits&(0x40|0x20|0x10))==0))
) {
7374 dn->digits=decShiftToMost(dn->lsu, dn->digits, shift);
7375 }
7376 dn->exponent-=shift; /* adjust the exponent to match */
7377 *status|=DEC_Clamped0x00000400; /* and record the dirty deed */
7378 } /* 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/* ------------------------------------------------------------------ */
7391static void decSetOverflow(decNumber *dn, decContext *set, uIntuint32_t *status) {
7392 Flaguint8_t needmax=0; /* result is maximum finite value */
7393 uByteuint8_t sign=dn->bits&DECNEG0x80; /* clean and save sign bit */
7394
7395 if (ISZERO(dn)(*(dn)->lsu==0 && (dn)->digits==1 && ((
(dn)->bits&(0x40|0x20|0x10))==0))
) { /* zero does not overflow magnitude */
7396 Intint32_t emax=set->emax; /* limit value */
7397 if (set->clamp) emax-=set->digits-1; /* lower if clamping */
7398 if (dn->exponent>emax) { /* clamp required */
7399 dn->exponent=emax;
7400 *status|=DEC_Clamped0x00000400;
7401 }
7402 return;
7403 }
7404
7405 uprv_decNumberZerouprv_decNumberZero_77(dn);
7406 switch (set->round) {
7407 case DEC_ROUND_DOWN: {
7408 needmax=1; /* never Infinity */
7409 break;} /* r-d */
7410 case DEC_ROUND_05UP: {
7411 needmax=1; /* never Infinity */
7412 break;} /* r-05 */
7413 case DEC_ROUND_CEILING: {
7414 if (sign) needmax=1; /* Infinity if non-negative */
7415 break;} /* r-c */
7416 case DEC_ROUND_FLOOR: {
7417 if (!sign) needmax=1; /* Infinity if negative */
7418 break;} /* r-f */
7419 default: break; /* Infinity in all other cases */
7420 }
7421 if (needmax) {
7422 decSetMaxValue(dn, set);
7423 dn->bits=sign; /* set sign */
7424 }
7425 else dn->bits=sign|DECINF0x40; /* Value is +/-Infinity */
7426 *status|=DEC_Overflow0x00000200 | DEC_Inexact0x00000020 | DEC_Rounded0x00000800;
7427 } /* 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/* ------------------------------------------------------------------ */
7437static void decSetMaxValue(decNumber *dn, decContext *set) {
7438 Unituint8_t *up; /* work */
7439 Intint32_t count=set->digits; /* nines to add */
7440 dn->digits=count;
7441 /* fill in all nines to set maximum value */
7442 for (up=dn->lsu; ; up++) {
7443 if (count>DECDPUN1) *up=DECDPUNMAX9; /* unit full o'nines */
7444 else { /* this is the msu */
7445 *up = static_cast<Unituint8_t>(powersDECPOWERS[count] - 1);
7446 break;
7447 }
7448 count-=DECDPUN1; /* filled those digits */
7449 } /* up */
7450 dn->bits=0; /* + sign */
7451 dn->exponent=set->emax-set->digits+1;
7452 } /* 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/* ------------------------------------------------------------------ */
7471static void decSetSubnormal(decNumber *dn, decContext *set, Intint32_t *residue,
7472 uIntuint32_t *status) {
7473 decContext workset; /* work */
7474 Intint32_t etiny, adjust; /* .. */
7475
7476 #if DECSUBSET0
7477 /* simple set to zero and 'hard underflow' for subset */
7478 if (!set->extended) {
7479 uprv_decNumberZerouprv_decNumberZero_77(dn);
7480 /* always full overflow */
7481 *status|=DEC_Underflow0x00002000 | DEC_Subnormal0x00001000 | DEC_Inexact0x00000020 | DEC_Rounded0x00000800;
7482 return;
7483 }
7484 #endif
7485
7486 /* Full arithmetic -- allow subnormals, rounded to minimum exponent */
7487 /* (Etiny) if needed */
7488 etiny=set->emin-(set->digits-1); /* smallest allowed exponent */
7489
7490 if ISZERO(dn)(*(dn)->lsu==0 && (dn)->digits==1 && ((
(dn)->bits&(0x40|0x20|0x10))==0))
{ /* value is zero */
7491 /* residue can never be non-zero here */
7492 #if DECCHECK0
7493 if (*residue!=0) {
7494 printf("++ Subnormal 0 residue %ld\n", (LI)*residue);
7495 *status|=DEC_Invalid_operation0x00000080;
7496 }
7497 #endif
7498 if (dn->exponent<etiny) { /* clamp required */
7499 dn->exponent=etiny;
7500 *status|=DEC_Clamped0x00000400;
7501 }
7502 return;
7503 }
7504
7505 *status|=DEC_Subnormal0x00001000; /* have a non-zero subnormal */
7506 adjust=etiny-dn->exponent; /* calculate digits to remove */
7507 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 if (*status&DEC_Inexact0x00000020) *status|=DEC_Underflow0x00002000;
7512 return;
7513 }
7514
7515 /* adjust>0, so need to rescale the result so exponent becomes Etiny */
7516 /* [this code is similar to that in rescale] */
7517 workset=*set; /* clone rounding, etc. */
7518 workset.digits=dn->digits-adjust; /* set requested length */
7519 workset.emin-=adjust; /* and adjust emin to match */
7520 /* [note that the latter can be <1, here, similar to Rescale case] */
7521 decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);
7522 decApplyRound(dn, &workset, *residue, status);
7523
7524 /* Use 754 default rule: Underflow is set iff Inexact */
7525 /* [independent of whether trapped] */
7526 if (*status&DEC_Inexact0x00000020) *status|=DEC_Underflow0x00002000;
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 if (dn->exponent>etiny) {
7531 dn->digits=decShiftToMost(dn->lsu, dn->digits, 1);
7532 dn->exponent--; /* (re)adjust the exponent. */
7533 }
7534
7535 /* if rounded to zero, it is by definition clamped... */
7536 if (ISZERO(dn)(*(dn)->lsu==0 && (dn)->digits==1 && ((
(dn)->bits&(0x40|0x20|0x10))==0))
) *status|=DEC_Clamped0x00000400;
7537 } /* 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/* ------------------------------------------------------------------ */
7557static uIntuint32_t decCheckMath(const decNumber *rhs, decContext *set,
7558 uIntuint32_t *status) {
7559 uIntuint32_t save=*status; /* record */
7560 if (set->digits>DEC_MAX_MATH999999
7561 || set->emax>DEC_MAX_MATH999999
7562 || -set->emin>DEC_MAX_MATH999999) *status|=DEC_Invalid_context0x00000040;
7563 else if ((rhs->digits>DEC_MAX_MATH999999
7564 || rhs->exponent+rhs->digits>DEC_MAX_MATH999999+1
7565 || rhs->exponent+rhs->digits<2*(1-DEC_MAX_MATH999999))
7566 && !ISZERO(rhs)(*(rhs)->lsu==0 && (rhs)->digits==1 && (
((rhs)->bits&(0x40|0x20|0x10))==0))
) *status|=DEC_Invalid_operation0x00000080;
7567 return (*status!=save);
7568 } /* 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/* ------------------------------------------------------------------ */
7585static Intint32_t decGetInt(const decNumber *dn) {
7586 Intint32_t theInt; /* result accumulator */
7587 const Unituint8_t *up; /* work */
7588 Intint32_t got; /* digits (real or not) processed */
7589 Intint32_t ilength=dn->digits+dn->exponent; /* integral length */
7590 Flaguint8_t neg=decNumberIsNegative(dn)(((dn)->bits&0x80)!=0); /* 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_EMAX999999999 > 999999999
7595 #error GetInt may need updating [for Emax]
7596 #endif
7597 #if DEC_MIN_EMIN-999999999 < -999999999
7598 #error GetInt may need updating [for Emin]
7599 #endif
7600 if (ISZERO(dn)(*(dn)->lsu==0 && (dn)->digits==1 && ((
(dn)->bits&(0x40|0x20|0x10))==0))
) return 0; /* zeros are OK, with any exponent */
7601
7602 up=dn->lsu; /* ready for lsu */
7603 theInt=0; /* ready to accumulate */
7604 if (dn->exponent>=0) { /* relatively easy */
7605 /* no fractional part [usual]; allow for positive exponent */
7606 got=dn->exponent;
7607 }
7608 else { /* -ve exponent; some fractional part to check and discard */
7609 Intint32_t count=-dn->exponent; /* digits to discard */
7610 /* spin up whole units until reach the Unit with the unit digit */
7611 for (; count>=DECDPUN1; up++) {
7612 if (*up!=0) return BADINT(int32_t)0x80000000; /* non-zero Unit to discard */
7613 count-=DECDPUN1;
7614 }
7615 if (count==0) got=0; /* [a multiple of DECDPUN] */
7616 else { /* [not multiple of DECDPUN] */
7617 Intint32_t rem; /* work */
7618 /* slice off fraction digits and check for non-zero */
7619 #if DECDPUN1<=4
7620 theInt=QUOT10(*up, count)((((uint32_t)(*up)>>(count))*multies[count])>>17);
7621 rem=*up-theInt*powersDECPOWERS[count];
7622 #else
7623 rem=*up%powersDECPOWERS[count]; /* slice off discards */
7624 theInt=*up/powersDECPOWERS[count];
7625 #endif
7626 if (rem!=0) return BADINT(int32_t)0x80000000; /* non-zero fraction */
7627 /* it looks good */
7628 got=DECDPUN1-count; /* number of digits so far */
7629 up++; /* ready for next */
7630 }
7631 }
7632 /* now it's known there's no fractional part */
7633
7634 /* tricky code now, to accumulate up to 9.3 digits */
7635 if (got==0) {theInt=*up; got+=DECDPUN1; up++;} /* ensure lsu is there */
7636
7637 if (ilength<11) {
7638 Intint32_t save=theInt;
7639 /* collect any remaining unit(s) */
7640 for (; got<ilength; up++) {
7641 theInt+=*up*powersDECPOWERS[got];
7642 got+=DECDPUN1;
7643 }
7644 if (ilength==10) { /* need to check for wrap */
7645 if (theInt / static_cast<Intint32_t>(powersDECPOWERS[got - DECDPUN1]) != static_cast<Intint32_t>(*(up - 1))) ilength = 11;
7646 /* [that test also disallows the BADINT result case] */
7647 else if (neg && theInt>1999999997) ilength=11;
7648 else if (!neg && theInt>999999999) ilength=11;
7649 if (ilength==11) theInt=save; /* restore correct low bit */
7650 }
7651 }
7652
7653 if (ilength>10) { /* too big */
7654 if (theInt&1) return BIGODD(int32_t)0x80000003; /* bottom bit 1 */
7655 return BIGEVEN(int32_t)0x80000002; /* bottom bit 0 */
7656 }
7657
7658 if (neg) theInt=-theInt; /* apply sign */
7659 return theInt;
7660 } /* 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/* ------------------------------------------------------------------ */
7674static decNumber *decDecap(decNumber *dn, Intint32_t drop) {
7675 Unituint8_t *msu; /* -> target cut point */
7676 Intint32_t cut; /* work */
7677 if (drop>=dn->digits) { /* losing the whole thing */
7678 #if DECCHECK0
7679 if (drop>dn->digits)
7680 printf("decDecap called with drop>digits [%ld>%ld]\n",
7681 (LI)drop, (LI)dn->digits);
7682 #endif
7683 dn->lsu[0]=0;
7684 dn->digits=1;
7685 return dn;
7686 }
7687 msu=dn->lsu+D2U(dn->digits-drop)((dn->digits-drop)<=49?d2utable[dn->digits-drop]:((dn
->digits-drop)+1 -1)/1)
-1; /* -> likely msu */
7688 cut=MSUDIGITS(dn->digits-drop)((dn->digits-drop)-(((dn->digits-drop)<=49?d2utable[
dn->digits-drop]:((dn->digits-drop)+1 -1)/1)-1)*1)
; /* digits to be in use in msu */
7689 if (cut!=DECDPUN1) *msu%=powersDECPOWERS[cut]; /* clear left digits */
7690 /* that may have left leading zero digits, so do a proper count... */
7691 dn->digits=decGetDigits(dn->lsu, static_cast<int32_t>(msu-dn->lsu+1));
7692 return dn;
7693 } /* 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/* ------------------------------------------------------------------ */
7710static Flaguint8_t decBiStr(const char *targ, const char *str1, const char *str2) {
7711 for (;;targ++, str1++, str2++) {
7712 if (*targ!=*str1 && *targ!=*str2) return 0;
7713 /* *targ has a match in one (or both, if terminator) */
7714 if (*targ=='\0') break;
7715 } /* forever */
7716 return 1;
7717 } /* 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/* ------------------------------------------------------------------ */
7733static decNumber * decNaNs(decNumber *res, const decNumber *lhs,
7734 const decNumber *rhs, decContext *set,
7735 uIntuint32_t *status) {
7736 /* This decision tree ends up with LHS being the source pointer, */
7737 /* and status updated if need be */
7738 if (lhs->bits & DECSNAN0x10)
7739 *status|=DEC_Invalid_operation0x00000080 | DEC_sNaN0x40000000;
7740 else if (rhs==nullptr);
7741 else if (rhs->bits & DECSNAN0x10) {
7742 lhs=rhs;
7743 *status|=DEC_Invalid_operation0x00000080 | DEC_sNaN0x40000000;
7744 }
7745 else if (lhs->bits & DECNAN0x20);
7746 else lhs=rhs;
7747
7748 /* propagate the payload */
7749 if (lhs->digits<=set->digits) uprv_decNumberCopyuprv_decNumberCopy_77(res, lhs); /* easy */
7750 else { /* too long */
7751 const Unituint8_t *ul;
7752 Unituint8_t *ur, *uresp1;
7753 /* copy safe number of units, then decapitate */
7754 res->bits=lhs->bits; /* need sign etc. */
7755 uresp1=res->lsu+D2U(set->digits)((set->digits)<=49?d2utable[set->digits]:((set->digits
)+1 -1)/1)
;
7756 for (ur=res->lsu, ul=lhs->lsu; ur<uresp1; ur++, ul++) *ur=*ul;
7757 res->digits=D2U(set->digits)((set->digits)<=49?d2utable[set->digits]:((set->digits
)+1 -1)/1)
*DECDPUN1;
7758 /* maybe still too long */
7759 if (res->digits>set->digits) decDecap(res, res->digits-set->digits);
7760 }
7761
7762 res->bits&=~DECSNAN0x10; /* convert any sNaN to NaN, while */
7763 res->bits|=DECNAN0x20; /* .. preserving sign */
7764 res->exponent=0; /* clean exponent */
7765 /* [coefficient was copied/decapitated] */
7766 return res;
7767 } /* 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/* ------------------------------------------------------------------ */
7784static void decStatus(decNumber *dn, uIntuint32_t status, decContext *set) {
7785 if (status & DEC_NaNs(0x00000001 | 0x00000004 | 0x00000008 | 0x00000010 | 0x00000040
| 0x00000080)
) { /* error status -> NaN */
7786 /* if cause was an sNaN, clear and propagate [NaN is already set up] */
7787 if (status & DEC_sNaN0x40000000) status&=~DEC_sNaN0x40000000;
7788 else {
7789 uprv_decNumberZerouprv_decNumberZero_77(dn); /* other error: clean throughout */
7790 dn->bits=DECNAN0x20; /* and make a quiet NaN */
7791 }
7792 }
7793 uprv_decContextSetStatusuprv_decContextSetStatus_77(set, status); /* [may not return] */
7794 } /* 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. */
7809static Intint32_t decGetDigits(Unituint8_t *uar, Intint32_t len) {
7810 Unituint8_t *up=uar+(len-1); /* -> msu */
7811 Intint32_t digits=(len-1)*DECDPUN1+1; /* possible digits excluding msu */
7812 #if DECDPUN1>4
7813 uIntuint32_t const *pow; /* work */
7814 #endif
7815 /* (at least 1 in final msu) */
7816 #if DECCHECK0
7817 if (len<1) printf("decGetDigits called with len<1 [%ld]\n", (LI)len);
7818 #endif
7819
7820 for (; up>=uar; up--) {
7821 if (*up==0) { /* unit is all 0s */
7822 if (digits==1) break; /* a zero has one digit */
7823 digits-=DECDPUN1; /* adjust for 0 unit */
7824 continue;}
7825 /* found the first (most significant) non-zero Unit */
7826 #if DECDPUN1>1 /* not done yet */
7827 if (*up<10) break; /* is 1-9 */
7828 digits++;
7829 #if DECDPUN1>2 /* not done yet */
7830 if (*up<100) break; /* is 10-99 */
7831 digits++;
7832 #if DECDPUN1>3 /* not done yet */
7833 if (*up<1000) break; /* is 100-999 */
7834 digits++;
7835 #if DECDPUN1>4 /* count the rest ... */
7836 for (pow=&powersDECPOWERS[4]; *up>=*pow; pow++) digits++;
7837 #endif
7838 #endif
7839 #endif
7840 #endif
7841 break;
7842 } /* up */
7843 return digits;
7844 } /* decGetDigits */
7845
7846#if DECTRACE0 | DECCHECK0
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 */
7855void uprv_decNumberShow(const decNumber *dn) {
7856 const Unituint8_t *up; /* work */
7857 uIntuint32_t u, d; /* .. */
7858 Intint32_t cut; /* .. */
7859 char isign='+'; /* main sign */
7860 if (dn==nullptr) {
7861 printf("nullptr\n");
7862 return;}
7863 if (decNumberIsNegative(dn)(((dn)->bits&0x80)!=0)) isign='-';
7864 printf(" >> %c ", isign);
7865 if (dn->bits&DECSPECIAL(0x40|0x20|0x10)) { /* Is a special value */
7866 if (decNumberIsInfinite(dn)(((dn)->bits&0x40)!=0)) printf("Infinity");
7867 else { /* a NaN */
7868 if (dn->bits&DECSNAN0x10) 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)((dn->digits)<=49?d2utable[dn->digits]:((dn->digits
)+1 -1)/1)
-1; /* msu */
7881 printf("%ld", (LI)*up);
7882 for (up=up-1; up>=dn->lsu; up--) {
7883 u=*up;
7884 printf(":");
7885 for (cut=DECDPUN1-1; cut>=0; cut--) {
7886 d=u/powersDECPOWERS[cut];
7887 u-=d*powersDECPOWERS[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 DECTRACE0 || DECCHECK0
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/* ------------------------------------------------------------------ */
7907static void decDumpAr(char name, const Unituint8_t *ar, Intint32_t len) {
7908 Intint32_t i;
7909 const char *spec;
7910 #if DECDPUN1==9
7911 spec="%09d ";
7912 #elif DECDPUN1==8
7913 spec="%08d ";
7914 #elif DECDPUN1==7
7915 spec="%07d ";
7916 #elif DECDPUN1==6
7917 spec="%06d ";
7918 #elif DECDPUN1==5
7919 spec="%05d ";
7920 #elif DECDPUN1==4
7921 spec="%04d ";
7922 #elif DECDPUN1==3
7923 spec="%03d ";
7924 #elif DECDPUN1==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 DECCHECK0
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/* ------------------------------------------------------------------ */
7952static Flaguint8_t decCheckOperands(decNumber *res, const decNumber *lhs,
7953 const decNumber *rhs, decContext *set) {
7954 Flaguint8_t bad=0;
7955 if (set==nullptr) { /* oops; hopeless */
7956 #if DECTRACE0 || DECVERB1
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 DECTRACE0 || DECVERB1
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 DECTRACE0
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_decContextSetStatusuprv_decContextSetStatus_77(set, DEC_Invalid_operation0x00000080);
7982 if (res!=DECUNRESU && res!=nullptr) {
7983 uprv_decNumberZerouprv_decNumberZero_77(res);
7984 res->bits=DECNAN0x20; /* 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/* ------------------------------------------------------------------ */
7998static Flaguint8_t decCheckNumber(const decNumber *dn) {
7999 const Unituint8_t *up; /* work */
8000 uIntuint32_t maxuint; /* .. */
8001 Intint32_t ae, d, digits; /* .. */
8002 Intint32_t emin, emax; /* .. */
8003
8004 if (dn==nullptr) { /* hopeless */
8005 #if DECTRACE0
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(0x40|0x20|0x10)) {
8013 if (dn->exponent!=0) {
8014 #if DECTRACE0 || DECVERB1
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)(((dn)->bits&0x40)!=0)) {
8022 if (dn->digits!=1) {
8023 #if DECTRACE0 || DECVERB1
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 DECTRACE0 || DECVERB1
8029 printf("LSU %ld (not 0) for an infinity.\n", (LI)*dn->lsu);
8030 #endif
8031 decDumpAr('I', dn->lsu, D2U(dn->digits)((dn->digits)<=49?d2utable[dn->digits]:((dn->digits
)+1 -1)/1)
);
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>DECNUMMAXP999999999) {
8041 #if DECTRACE0 || DECVERB1
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>DECDPUN1) maxuint=DECDPUNMAX9;
8050 else { /* reached the msu */
8051 maxuint=powersDECPOWERS[d]-1;
8052 if (dn->digits>1 && *up<powersDECPOWERS[d-1]) {
8053 #if DECTRACE0 || DECVERB1
8054 printf("Leading 0 in number.\n");
8055 uprv_decNumberShow(dn);
8056 #endif
8057 return 1;}
8058 }
8059 if (*up>maxuint) {
8060 #if DECTRACE0 || DECVERB1
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-=DECDPUN1;
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=DECNUMMAXE999999999;
8073 emin=DECNUMMINE-999999999;
8074 digits=DECNUMMAXP999999999;
8075 if (ae<emin-(digits-1)) {
8076 #if DECTRACE0 || DECVERB1
8077 printf("Adjusted exponent underflow [%ld].\n", (LI)ae);
8078 uprv_decNumberShow(dn);
8079 #endif
8080 return 1;}
8081 if (ae>+emax) {
8082 #if DECTRACE0 || DECVERB1
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/* ------------------------------------------------------------------ */
8099static void decCheckInexact(const decNumber *dn, decContext *set) {
8100 #if !DECSUBSET0 && DECEXTFLAG1
8101 if ((set->status & (DEC_Inexact0x00000020|DEC_Subnormal0x00001000))==DEC_Inexact0x00000020
8102 && (set->digits!=dn->digits) && !(dn->bits & DECSPECIAL(0x40|0x20|0x10))) {
8103 #if DECTRACE0 || DECVERB1
8104 printf("Insufficient digits [%ld] on normal Inexact result.\n",
8105 (LI)dn->digits);
8106 uprv_decNumberShow(dn);
8107 #endif
8108 uprv_decContextSetStatusuprv_decContextSetStatus_77(set, DEC_Invalid_operation0x00000080);
8109 }
8110 #else
8111 /* next is a noop for quiet compiler */
8112 if (dn!=nullptr && dn->digits==0) set->status|=DEC_Invalid_operation0x00000080;
8113 #endif
8114 return;
8115 } /* decCheckInexact */
8116#endif
8117
8118#if DECALLOC0
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/* ------------------------------------------------------------------ */
8135static void *decMalloc(size_t n) {
8136 uIntuint32_t size=n+12; /* true size */
8137 void *alloc; /* -> allocated storage */
8138 uByteuint8_t *b, *b0; /* work */
8139 uIntuint32_t uiwork; /* for macros */
8140
8141 alloc=malloc(size)uprv_malloc_77(size); /* -> allocated storage */
8142 if (alloc==nullptr) return nullptr; /* out of strorage */
8143 b0=(uByteuint8_t *)alloc; /* as bytes */
8144 decAllocBytes+=n; /* account for storage */
8145 UBFROMUI(alloc, n)(uiwork=(n), memcpy(alloc, (void *)&uiwork, 4), uiwork); /* 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/* ------------------------------------------------------------------ */
8164static void decFree(void *alloc) {
8165 uIntuint32_t n; /* original length */
8166 uByteuint8_t *b, *b0; /* work */
8167 uIntuint32_t uiwork; /* for macros */
8168
8169 if (alloc==nullptr) return; /* allowed; it's a nop */
8170 b0=(uByteuint8_t *)alloc; /* as bytes */
8171 b0-=8; /* -> true start of storage */
8172 n=UBTOUI(b0)(memcpy((void *)&uiwork, b0, 4), uiwork); /* 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)uprv_free_77(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)uprv_malloc_77(a) decMalloc(a)
8184#define free(a)uprv_free_77(a) decFree(a)
8185#endif