qemu
8323 строки · 328.2 Кб
1/* Decimal number arithmetic module for the decNumber C Library.
2Copyright (C) 2005, 2007 Free Software Foundation, Inc.
3Contributed by IBM Corporation. Author Mike Cowlishaw.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12In addition to the permissions in the GNU General Public License,
13the Free Software Foundation gives you unlimited permission to link
14the compiled version of this file into combinations with other
15programs, and to distribute those combinations without any
16restriction coming from the use of this file. (The General Public
17License restrictions do apply in other respects; for example, they
18cover modification of the file, and distribution when not linked
19into a combine executable.)
20
21GCC is distributed in the hope that it will be useful, but WITHOUT ANY
22WARRANTY; without even the implied warranty of MERCHANTABILITY or
23FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24for more details.
25
26You should have received a copy of the GNU General Public License
27along with GCC; see the file COPYING. If not, write to the Free
28Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2902110-1301, USA. */
30
31/* ------------------------------------------------------------------ */
32/* Decimal Number arithmetic module */
33/* ------------------------------------------------------------------ */
34/* This module comprises the routines for General Decimal Arithmetic */
35/* as defined in the specification which may be found on the */
36/* http://www2.hursley.ibm.com/decimal web pages. It implements both */
37/* the full ('extended') arithmetic and the simpler ('subset') */
38/* arithmetic. */
39/* */
40/* Usage notes: */
41/* */
42/* 1. This code is ANSI C89 except: */
43/* */
44/* If DECDPUN>4 or DECUSE64=1, the C99 64-bit int64_t and */
45/* uint64_t types may be used. To avoid these, set DECUSE64=0 */
46/* and DECDPUN<=4 (see documentation). */
47/* */
48/* 2. The decNumber format which this library uses is optimized for */
49/* efficient processing of relatively short numbers; in particular */
50/* it allows the use of fixed sized structures and minimizes copy */
51/* and move operations. It does, however, support arbitrary */
52/* precision (up to 999,999,999 digits) and arbitrary exponent */
53/* range (Emax in the range 0 through 999,999,999 and Emin in the */
54/* range -999,999,999 through 0). Mathematical functions (for */
55/* example decNumberExp) as identified below are restricted more */
56/* tightly: digits, emax, and -emin in the context must be <= */
57/* DEC_MAX_MATH (999999), and their operand(s) must be within */
58/* these bounds. */
59/* */
60/* 3. Logical functions are further restricted; their operands must */
61/* be finite, positive, have an exponent of zero, and all digits */
62/* must be either 0 or 1. The result will only contain digits */
63/* which are 0 or 1 (and will have exponent=0 and a sign of 0). */
64/* */
65/* 4. Operands to operator functions are never modified unless they */
66/* are also specified to be the result number (which is always */
67/* permitted). Other than that case, operands must not overlap. */
68/* */
69/* 5. Error handling: the type of the error is ORed into the status */
70/* flags in the current context (decContext structure). The */
71/* SIGFPE signal is then raised if the corresponding trap-enabler */
72/* flag in the decContext is set (is 1). */
73/* */
74/* It is the responsibility of the caller to clear the status */
75/* flags as required. */
76/* */
77/* The result of any routine which returns a number will always */
78/* be a valid number (which may be a special value, such as an */
79/* Infinity or NaN). */
80/* */
81/* 6. The decNumber format is not an exchangeable concrete */
82/* representation as it comprises fields which may be machine- */
83/* dependent (packed or unpacked, or special length, for example). */
84/* Canonical conversions to and from strings are provided; other */
85/* conversions are available in separate modules. */
86/* */
87/* 7. Normally, input operands are assumed to be valid. Set DECCHECK */
88/* to 1 for extended operand checking (including NULL operands). */
89/* Results are undefined if a badly-formed structure (or a NULL */
90/* pointer to a structure) is provided, though with DECCHECK */
91/* enabled the operator routines are protected against exceptions. */
92/* (Except if the result pointer is NULL, which is unrecoverable.) */
93/* */
94/* However, the routines will never cause exceptions if they are */
95/* given well-formed operands, even if the value of the operands */
96/* is inappropriate for the operation and DECCHECK is not set. */
97/* (Except for SIGFPE, as and where documented.) */
98/* */
99/* 8. Subset arithmetic is available only if DECSUBSET is set to 1. */
100/* ------------------------------------------------------------------ */
101/* Implementation notes for maintenance of this module: */
102/* */
103/* 1. Storage leak protection: Routines which use malloc are not */
104/* permitted to use return for fastpath or error exits (i.e., */
105/* they follow strict structured programming conventions). */
106/* Instead they have a do{}while(0); construct surrounding the */
107/* code which is protected -- break may be used to exit this. */
108/* Other routines can safely use the return statement inline. */
109/* */
110/* Storage leak accounting can be enabled using DECALLOC. */
111/* */
112/* 2. All loops use the for(;;) construct. Any do construct does */
113/* not loop; it is for allocation protection as just described. */
114/* */
115/* 3. Setting status in the context must always be the very last */
116/* action in a routine, as non-0 status may raise a trap and hence */
117/* the call to set status may not return (if the handler uses long */
118/* jump). Therefore all cleanup must be done first. In general, */
119/* to achieve this status is accumulated and is only applied just */
120/* before return by calling decContextSetStatus (via decStatus). */
121/* */
122/* Routines which allocate storage cannot, in general, use the */
123/* 'top level' routines which could cause a non-returning */
124/* transfer of control. The decXxxxOp routines are safe (do not */
125/* call decStatus even if traps are set in the context) and should */
126/* be used instead (they are also a little faster). */
127/* */
128/* 4. Exponent checking is minimized by allowing the exponent to */
129/* grow outside its limits during calculations, provided that */
130/* the decFinalize function is called later. Multiplication and */
131/* division, and intermediate calculations in exponentiation, */
132/* require more careful checks because of the risk of 31-bit */
133/* overflow (the most negative valid exponent is -1999999997, for */
134/* a 999999999-digit number with adjusted exponent of -999999999). */
135/* */
136/* 5. Rounding is deferred until finalization of results, with any */
137/* 'off to the right' data being represented as a single digit */
138/* residue (in the range -1 through 9). This avoids any double- */
139/* rounding when more than one shortening takes place (for */
140/* example, when a result is subnormal). */
141/* */
142/* 6. The digits count is allowed to rise to a multiple of DECDPUN */
143/* during many operations, so whole Units are handled and exact */
144/* accounting of digits is not needed. The correct digits value */
145/* is found by decGetDigits, which accounts for leading zeros. */
146/* This must be called before any rounding if the number of digits */
147/* is not known exactly. */
148/* */
149/* 7. The multiply-by-reciprocal 'trick' is used for partitioning */
150/* numbers up to four digits, using appropriate constants. This */
151/* is not useful for longer numbers because overflow of 32 bits */
152/* would lead to 4 multiplies, which is almost as expensive as */
153/* a divide (unless a floating-point or 64-bit multiply is */
154/* assumed to be available). */
155/* */
156/* 8. Unusual abbreviations that may be used in the commentary: */
157/* lhs -- left hand side (operand, of an operation) */
158/* lsd -- least significant digit (of coefficient) */
159/* lsu -- least significant Unit (of coefficient) */
160/* msd -- most significant digit (of coefficient) */
161/* msi -- most significant item (in an array) */
162/* msu -- most significant Unit (of coefficient) */
163/* rhs -- right hand side (operand, of an operation) */
164/* +ve -- positive */
165/* -ve -- negative */
166/* ** -- raise to the power */
167/* ------------------------------------------------------------------ */
168
169#include "qemu/osdep.h"170#include "qemu/host-utils.h"171#include "libdecnumber/dconfig.h"172#include "libdecnumber/decNumber.h"173#include "libdecnumber/decNumberLocal.h"174
175/* Constants */
176/* Public lookup table used by the D2U macro */
177const uByte d2utable[DECMAXD2U+1]=D2UTABLE;178
179#define DECVERB 1 /* set to 1 for verbose DECCHECK */180#define powers DECPOWERS /* old internal name */181
182/* Local constants */
183#define DIVIDE 0x80 /* Divide operators */184#define REMAINDER 0x40 /* .. */185#define DIVIDEINT 0x20 /* .. */186#define REMNEAR 0x10 /* .. */187#define COMPARE 0x01 /* Compare operators */188#define COMPMAX 0x02 /* .. */189#define COMPMIN 0x03 /* .. */190#define COMPTOTAL 0x04 /* .. */191#define COMPNAN 0x05 /* .. [NaN processing] */192#define COMPSIG 0x06 /* .. [signaling COMPARE] */193#define COMPMAXMAG 0x07 /* .. */194#define COMPMINMAG 0x08 /* .. */195
196#define DEC_sNaN 0x40000000 /* local status: sNaN signal */197#define BADINT (Int)0x80000000 /* most-negative Int; error indicator */198/* Next two indicate an integer >= 10**6, and its parity (bottom bit) */
199#define BIGEVEN (Int)0x80000002200#define BIGODD (Int)0x80000003201
202static Unit uarrone[1]={1}; /* Unit array of 1, used for incrementing */203
204/* Granularity-dependent code */
205#if DECDPUN<=4206#define eInt Int /* extended integer */207#define ueInt uInt /* unsigned extended integer */208/* Constant multipliers for divide-by-power-of five using reciprocal */209/* multiply, after removing powers of 2 by shifting, and final shift */210/* of 17 [we only need up to **4] */211static const uInt multies[]={131073, 26215, 5243, 1049, 210};212/* QUOT10 -- macro to return the quotient of unit u divided by 10**n */213#define QUOT10(u, n) ((((uInt)(u)>>(n))*multies[n])>>17)214#else215/* For DECDPUN>4 non-ANSI-89 64-bit types are needed. */216#if !DECUSE64217#error decNumber.c: DECUSE64 must be 1 when DECDPUN>4218#endif219#define eInt Long /* extended integer */220#define ueInt uLong /* unsigned extended integer */221#endif222
223/* Local routines */
224static decNumber * decAddOp(decNumber *, const decNumber *, const decNumber *,225decContext *, uByte, uInt *);226static Flag decBiStr(const char *, const char *, const char *);227static uInt decCheckMath(const decNumber *, decContext *, uInt *);228static void decApplyRound(decNumber *, decContext *, Int, uInt *);229static Int decCompare(const decNumber *lhs, const decNumber *rhs, Flag);230static decNumber * decCompareOp(decNumber *, const decNumber *,231const decNumber *, decContext *,232Flag, uInt *);233static void decCopyFit(decNumber *, const decNumber *, decContext *,234Int *, uInt *);235static decNumber * decDecap(decNumber *, Int);236static decNumber * decDivideOp(decNumber *, const decNumber *,237const decNumber *, decContext *, Flag, uInt *);238static decNumber * decExpOp(decNumber *, const decNumber *,239decContext *, uInt *);240static void decFinalize(decNumber *, decContext *, Int *, uInt *);241static Int decGetDigits(Unit *, Int);242static Int decGetInt(const decNumber *);243static decNumber * decLnOp(decNumber *, const decNumber *,244decContext *, uInt *);245static decNumber * decMultiplyOp(decNumber *, const decNumber *,246const decNumber *, decContext *,247uInt *);248static decNumber * decNaNs(decNumber *, const decNumber *,249const decNumber *, decContext *, uInt *);250static decNumber * decQuantizeOp(decNumber *, const decNumber *,251const decNumber *, decContext *, Flag,252uInt *);253static void decReverse(Unit *, Unit *);254static void decSetCoeff(decNumber *, decContext *, const Unit *,255Int, Int *, uInt *);256static void decSetMaxValue(decNumber *, decContext *);257static void decSetOverflow(decNumber *, decContext *, uInt *);258static void decSetSubnormal(decNumber *, decContext *, Int *, uInt *);259static Int decShiftToLeast(Unit *, Int, Int);260static Int decShiftToMost(Unit *, Int, Int);261static void decStatus(decNumber *, uInt, decContext *);262static void decToString(const decNumber *, char[], Flag);263static decNumber * decTrim(decNumber *, decContext *, Flag, Int *);264static Int decUnitAddSub(const Unit *, Int, const Unit *, Int, Int,265Unit *, Int);266static Int decUnitCompare(const Unit *, Int, const Unit *, Int, Int);267static bool mulUInt128ByPowOf10(uLong *, uLong *, uInt);268
269#if !DECSUBSET270/* decFinish == decFinalize when no subset arithmetic needed */
271#define decFinish(a,b,c,d) decFinalize(a,b,c,d)272#else273static void decFinish(decNumber *, decContext *, Int *, uInt *);274static decNumber * decRoundOperand(const decNumber *, decContext *, uInt *);275#endif276
277/* Local macros */
278/* masked special-values bits */
279#define SPECIALARG (rhs->bits & DECSPECIAL)280#define SPECIALARGS ((lhs->bits | rhs->bits) & DECSPECIAL)281
282/* Diagnostic macros, etc. */
283#if DECALLOC284/* Handle malloc/free accounting. If enabled, our accountable routines */
285/* are used; otherwise the code just goes straight to the system malloc */
286/* and free routines. */
287#define malloc(a) decMalloc(a)288#define free(a) decFree(a)289#define DECFENCE 0x5a /* corruption detector */290/* 'Our' malloc and free: */
291static void *decMalloc(size_t);292static void decFree(void *);293uInt decAllocBytes=0; /* count of bytes allocated */294/* Note that DECALLOC code only checks for storage buffer overflow. */
295/* To check for memory leaks, the decAllocBytes variable must be */
296/* checked to be 0 at appropriate times (e.g., after the test */
297/* harness completes a set of tests). This checking may be unreliable */
298/* if the testing is done in a multi-thread environment. */
299#endif300
301#if DECCHECK302/* Optional checking routines. Enabling these means that decNumber */
303/* and decContext operands to operator routines are checked for */
304/* correctness. This roughly doubles the execution time of the */
305/* fastest routines (and adds 600+ bytes), so should not normally be */
306/* used in 'production'. */
307/* decCheckInexact is used to check that inexact results have a full */
308/* complement of digits (where appropriate -- this is not the case */
309/* for Quantize, for example) */
310#define DECUNRESU ((decNumber *)(void *)0xffffffff)311#define DECUNUSED ((const decNumber *)(void *)0xffffffff)312#define DECUNCONT ((decContext *)(void *)(0xffffffff))313static Flag decCheckOperands(decNumber *, const decNumber *,314const decNumber *, decContext *);315static Flag decCheckNumber(const decNumber *);316static void decCheckInexact(const decNumber *, decContext *);317#endif318
319#if DECTRACE || DECCHECK320/* Optional trace/debugging routines (may or may not be used) */
321void decNumberShow(const decNumber *); /* displays the components of a number */322static void decDumpAr(char, const Unit *, Int);323#endif324
325/* ================================================================== */
326/* Conversions */
327/* ================================================================== */
328
329/* ------------------------------------------------------------------ */
330/* from-int32 -- conversion from Int or uInt */
331/* */
332/* dn is the decNumber to receive the integer */
333/* in or uin is the integer to be converted */
334/* returns dn */
335/* */
336/* No error is possible. */
337/* ------------------------------------------------------------------ */
338decNumber * decNumberFromInt32(decNumber *dn, Int in) {339uInt unsig;340if (in>=0) unsig=in;341else { /* negative (possibly BADINT) */342if (in==BADINT) unsig=(uInt)1073741824*2; /* special case */343else unsig=-in; /* invert */344}345/* in is now positive */346decNumberFromUInt32(dn, unsig);347if (in<0) dn->bits=DECNEG; /* sign needed */348return dn;349} /* decNumberFromInt32 */350
351decNumber * decNumberFromUInt32(decNumber *dn, uInt uin) {352Unit *up; /* work pointer */353decNumberZero(dn); /* clean */354if (uin==0) return dn; /* [or decGetDigits bad call] */355for (up=dn->lsu; uin>0; up++) {356*up=(Unit)(uin%(DECDPUNMAX+1));357uin=uin/(DECDPUNMAX+1);358}359dn->digits=decGetDigits(dn->lsu, up-dn->lsu);360return dn;361} /* decNumberFromUInt32 */362
363/* ------------------------------------------------------------------ */
364/* to-int32 -- conversion to Int or uInt */
365/* */
366/* dn is the decNumber to convert */
367/* set is the context for reporting errors */
368/* returns the converted decNumber, or 0 if Invalid is set */
369/* */
370/* Invalid is set if the decNumber does not have exponent==0 or if */
371/* it is a NaN, Infinite, or out-of-range. */
372/* ------------------------------------------------------------------ */
373Int decNumberToInt32(const decNumber *dn, decContext *set) {374#if DECCHECK375if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;376#endif377
378/* special or too many digits, or bad exponent */379if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0) ; /* bad */380else { /* is a finite integer with 10 or fewer digits */381Int d; /* work */382const Unit *up; /* .. */383uInt hi=0, lo; /* .. */384up=dn->lsu; /* -> lsu */385lo=*up; /* get 1 to 9 digits */386#if DECDPUN>1 /* split to higher */387hi=lo/10;388lo=lo%10;389#endif390up++;391/* collect remaining Units, if any, into hi */392for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];393/* now low has the lsd, hi the remainder */394if (hi>214748364 || (hi==214748364 && lo>7)) { /* out of range? */395/* most-negative is a reprieve */396if (dn->bits&DECNEG && hi==214748364 && lo==8) return 0x80000000;397/* bad -- drop through */398}399else { /* in-range always */400Int i=X10(hi)+lo;401if (dn->bits&DECNEG) return -i;402return i;403}404} /* integer */405decContextSetStatus(set, DEC_Invalid_operation); /* [may not return] */406return 0;407} /* decNumberToInt32 */408
409uInt decNumberToUInt32(const decNumber *dn, decContext *set) {410#if DECCHECK411if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;412#endif413/* special or too many digits, or bad exponent, or negative (<0) */414if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0415|| (dn->bits&DECNEG && !ISZERO(dn))); /* bad */416else { /* is a finite integer with 10 or fewer digits */417Int d; /* work */418const Unit *up; /* .. */419uInt hi=0, lo; /* .. */420up=dn->lsu; /* -> lsu */421lo=*up; /* get 1 to 9 digits */422#if DECDPUN>1 /* split to higher */423hi=lo/10;424lo=lo%10;425#endif426up++;427/* collect remaining Units, if any, into hi */428for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];429
430/* now low has the lsd, hi the remainder */431if (hi>429496729 || (hi==429496729 && lo>5)) ; /* no reprieve possible */432else return X10(hi)+lo;433} /* integer */434decContextSetStatus(set, DEC_Invalid_operation); /* [may not return] */435return 0;436} /* decNumberToUInt32 */437
438decNumber *decNumberFromInt64(decNumber *dn, int64_t in)439{
440uint64_t unsig = in;441if (in < 0) {442unsig = -unsig;443}444
445decNumberFromUInt64(dn, unsig);446if (in < 0) {447dn->bits = DECNEG; /* sign needed */448}449return dn;450} /* decNumberFromInt64 */451
452decNumber *decNumberFromUInt64(decNumber *dn, uint64_t uin)453{
454Unit *up; /* work pointer */455decNumberZero(dn); /* clean */456if (uin == 0) {457return dn; /* [or decGetDigits bad call] */458}459for (up = dn->lsu; uin > 0; up++) {460*up = (Unit)(uin % (DECDPUNMAX + 1));461uin = uin / (DECDPUNMAX + 1);462}463dn->digits = decGetDigits(dn->lsu, up-dn->lsu);464return dn;465} /* decNumberFromUInt64 */466
467decNumber *decNumberFromInt128(decNumber *dn, uint64_t lo, int64_t hi)468{
469uint64_t unsig_hi = hi;470if (hi < 0) {471if (lo == 0) {472unsig_hi = -unsig_hi;473} else {474unsig_hi = ~unsig_hi;475lo = -lo;476}477}478
479decNumberFromUInt128(dn, lo, unsig_hi);480if (hi < 0) {481dn->bits = DECNEG; /* sign needed */482}483return dn;484} /* decNumberFromInt128 */485
486decNumber *decNumberFromUInt128(decNumber *dn, uint64_t lo, uint64_t hi)487{
488uint64_t rem;489Unit *up; /* work pointer */490decNumberZero(dn); /* clean */491if (lo == 0 && hi == 0) {492return dn; /* [or decGetDigits bad call] */493}494for (up = dn->lsu; hi > 0 || lo > 0; up++) {495rem = divu128(&lo, &hi, DECDPUNMAX + 1);496*up = (Unit)rem;497}498dn->digits = decGetDigits(dn->lsu, up - dn->lsu);499return dn;500} /* decNumberFromUInt128 */501
502/* ------------------------------------------------------------------ */
503/* to-int64 -- conversion to int64 */
504/* */
505/* dn is the decNumber to convert. dn is assumed to have been */
506/* rounded to a floating point integer value. */
507/* set is the context for reporting errors */
508/* returns the converted decNumber, or 0 if Invalid is set */
509/* */
510/* Invalid is set if the decNumber is a NaN, Infinite or is out of */
511/* range for a signed 64 bit integer. */
512/* ------------------------------------------------------------------ */
513
514int64_t decNumberIntegralToInt64(const decNumber *dn, decContext *set)515{
516if (decNumberIsSpecial(dn) || (dn->exponent < 0) ||517(dn->digits + dn->exponent > 19)) {518goto Invalid;519} else {520int64_t d; /* work */521const Unit *up; /* .. */522uint64_t hi = 0;523up = dn->lsu; /* -> lsu */524
525for (d = 1; d <= dn->digits; up++, d += DECDPUN) {526uint64_t prev = hi;527hi += *up * powers[d-1];528if ((hi < prev) || (hi > INT64_MAX)) {529goto Invalid;530}531}532
533uint64_t prev = hi;534hi *= (uint64_t)powers[dn->exponent];535if ((hi < prev) || (hi > INT64_MAX)) {536goto Invalid;537}538return (decNumberIsNegative(dn)) ? -((int64_t)hi) : (int64_t)hi;539}540
541Invalid:542decContextSetStatus(set, DEC_Invalid_operation);543return 0;544} /* decNumberIntegralToInt64 */545
546/* ------------------------------------------------------------------ */
547/* decNumberIntegralToInt128 -- conversion to int128 */
548/* */
549/* dn is the decNumber to convert. dn is assumed to have been */
550/* rounded to a floating point integer value. */
551/* set is the context for reporting errors */
552/* returns the converted decNumber via plow and phigh */
553/* */
554/* Invalid is set if the decNumber is a NaN, Infinite or is out of */
555/* range for a signed 128 bit integer. */
556/* ------------------------------------------------------------------ */
557
558void decNumberIntegralToInt128(const decNumber *dn, decContext *set,559uint64_t *plow, uint64_t *phigh)560{
561int d; /* work */562const Unit *up; /* .. */563uint64_t lo = 0, hi = 0;564
565if (decNumberIsSpecial(dn) || (dn->exponent < 0) ||566(dn->digits + dn->exponent > 39)) {567goto Invalid;568}569
570up = dn->lsu; /* -> lsu */571
572for (d = (dn->digits - 1) / DECDPUN; d >= 0; d--) {573if (mulu128(&lo, &hi, DECDPUNMAX + 1)) {574/* overflow */575goto Invalid;576}577if (uadd64_overflow(lo, up[d], &lo)) {578if (uadd64_overflow(hi, 1, &hi)) {579/* overflow */580goto Invalid;581}582}583}584
585if (mulUInt128ByPowOf10(&lo, &hi, dn->exponent)) {586/* overflow */587goto Invalid;588}589
590if (decNumberIsNegative(dn)) {591if (lo == 0) {592*phigh = -hi;593*plow = 0;594} else {595*phigh = ~hi;596*plow = -lo;597}598} else {599*plow = lo;600*phigh = hi;601}602
603return;604
605Invalid:606decContextSetStatus(set, DEC_Invalid_operation);607} /* decNumberIntegralToInt128 */608
609/* ------------------------------------------------------------------ */
610/* to-scientific-string -- conversion to numeric string */
611/* to-engineering-string -- conversion to numeric string */
612/* */
613/* decNumberToString(dn, string); */
614/* decNumberToEngString(dn, string); */
615/* */
616/* dn is the decNumber to convert */
617/* string is the string where the result will be laid out */
618/* */
619/* string must be at least dn->digits+14 characters long */
620/* */
621/* No error is possible, and no status can be set. */
622/* ------------------------------------------------------------------ */
623char * decNumberToString(const decNumber *dn, char *string){624decToString(dn, string, 0);625return string;626} /* DecNumberToString */627
628char * decNumberToEngString(const decNumber *dn, char *string){629decToString(dn, string, 1);630return string;631} /* DecNumberToEngString */632
633/* ------------------------------------------------------------------ */
634/* to-number -- conversion from numeric string */
635/* */
636/* decNumberFromString -- convert string to decNumber */
637/* dn -- the number structure to fill */
638/* chars[] -- the string to convert ('\0' terminated) */
639/* set -- the context used for processing any error, */
640/* determining the maximum precision available */
641/* (set.digits), determining the maximum and minimum */
642/* exponent (set.emax and set.emin), determining if */
643/* extended values are allowed, and checking the */
644/* rounding mode if overflow occurs or rounding is */
645/* needed. */
646/* */
647/* The length of the coefficient and the size of the exponent are */
648/* checked by this routine, so the correct error (Underflow or */
649/* Overflow) can be reported or rounding applied, as necessary. */
650/* */
651/* If bad syntax is detected, the result will be a quiet NaN. */
652/* ------------------------------------------------------------------ */
653decNumber * decNumberFromString(decNumber *dn, const char chars[],654decContext *set) {655Int exponent=0; /* working exponent [assume 0] */656uByte bits=0; /* working flags [assume +ve] */657Unit *res; /* where result will be built */658Unit resbuff[SD2U(DECBUFFER+9)];/* local buffer in case need temporary */659/* [+9 allows for ln() constants] */660Unit *allocres=NULL; /* -> allocated result, iff allocated */661Int d=0; /* count of digits found in decimal part */662const char *dotchar=NULL; /* where dot was found */663const char *cfirst=chars; /* -> first character of decimal part */664const char *last=NULL; /* -> last digit of decimal part */665const char *c; /* work */666Unit *up; /* .. */667#if DECDPUN>1668Int cut, out; /* .. */669#endif670Int residue; /* rounding residue */671uInt status=0; /* error code */672
673#if DECCHECK674if (decCheckOperands(DECUNRESU, DECUNUSED, DECUNUSED, set))675return decNumberZero(dn);676#endif677
678do { /* status & malloc protection */679for (c=chars;; c++) { /* -> input character */680if (*c>='0' && *c<='9') { /* test for Arabic digit */681last=c;682d++; /* count of real digits */683continue; /* still in decimal part */684}685if (*c=='.' && dotchar==NULL) { /* first '.' */686dotchar=c; /* record offset into decimal part */687if (c==cfirst) cfirst++; /* first digit must follow */688continue;}689if (c==chars) { /* first in string... */690if (*c=='-') { /* valid - sign */691cfirst++;692bits=DECNEG;693continue;}694if (*c=='+') { /* valid + sign */695cfirst++;696continue;}697}698/* *c is not a digit, or a valid +, -, or '.' */699break;700} /* c */701
702if (last==NULL) { /* no digits yet */703status=DEC_Conversion_syntax;/* assume the worst */704if (*c=='\0') break; /* and no more to come... */705#if DECSUBSET706/* if subset then infinities and NaNs are not allowed */707if (!set->extended) break; /* hopeless */708#endif709/* Infinities and NaNs are possible, here */710if (dotchar!=NULL) break; /* .. unless had a dot */711decNumberZero(dn); /* be optimistic */712if (decBiStr(c, "infinity", "INFINITY")713|| decBiStr(c, "inf", "INF")) {714dn->bits=bits | DECINF;715status=0; /* is OK */716break; /* all done */717}718/* a NaN expected */719/* 2003.09.10 NaNs are now permitted to have a sign */720dn->bits=bits | DECNAN; /* assume simple NaN */721if (*c=='s' || *c=='S') { /* looks like an sNaN */722c++;723dn->bits=bits | DECSNAN;724}725if (*c!='n' && *c!='N') break; /* check caseless "NaN" */726c++;727if (*c!='a' && *c!='A') break; /* .. */728c++;729if (*c!='n' && *c!='N') break; /* .. */730c++;731/* now either nothing, or nnnn payload, expected */732/* -> start of integer and skip leading 0s [including plain 0] */733for (cfirst=c; *cfirst=='0';) cfirst++;734if (*cfirst=='\0') { /* "NaN" or "sNaN", maybe with all 0s */735status=0; /* it's good */736break; /* .. */737}738/* something other than 0s; setup last and d as usual [no dots] */739for (c=cfirst;; c++, d++) {740if (*c<'0' || *c>'9') break; /* test for Arabic digit */741last=c;742}743if (*c!='\0') break; /* not all digits */744if (d>set->digits-1) {745/* [NB: payload in a decNumber can be full length unless */746/* clamped, in which case can only be digits-1] */747if (set->clamp) break;748if (d>set->digits) break;749} /* too many digits? */750/* good; drop through to convert the integer to coefficient */751status=0; /* syntax is OK */752bits=dn->bits; /* for copy-back */753} /* last==NULL */754
755else if (*c!='\0') { /* more to process... */756/* had some digits; exponent is only valid sequence now */757Flag nege; /* 1=negative exponent */758const char *firstexp; /* -> first significant exponent digit */759status=DEC_Conversion_syntax;/* assume the worst */760if (*c!='e' && *c!='E') break;761/* Found 'e' or 'E' -- now process explicit exponent */762/* 1998.07.11: sign no longer required */763nege=0;764c++; /* to (possible) sign */765if (*c=='-') {nege=1; c++;}766else if (*c=='+') c++;767if (*c=='\0') break;768
769for (; *c=='0' && *(c+1)!='\0';) c++; /* strip insignificant zeros */770firstexp=c; /* save exponent digit place */771for (; ;c++) {772if (*c<'0' || *c>'9') break; /* not a digit */773exponent=X10(exponent)+(Int)*c-(Int)'0';774} /* c */775/* if not now on a '\0', *c must not be a digit */776if (*c!='\0') break;777
778/* (this next test must be after the syntax checks) */779/* if it was too long the exponent may have wrapped, so check */780/* carefully and set it to a certain overflow if wrap possible */781if (c>=firstexp+9+1) {782if (c>firstexp+9+1 || *firstexp>'1') exponent=DECNUMMAXE*2;783/* [up to 1999999999 is OK, for example 1E-1000000998] */784}785if (nege) exponent=-exponent; /* was negative */786status=0; /* is OK */787} /* stuff after digits */788
789/* Here when whole string has been inspected; syntax is good */790/* cfirst->first digit (never dot), last->last digit (ditto) */791
792/* strip leading zeros/dot [leave final 0 if all 0's] */793if (*cfirst=='0') { /* [cfirst has stepped over .] */794for (c=cfirst; c<last; c++, cfirst++) {795if (*c=='.') continue; /* ignore dots */796if (*c!='0') break; /* non-zero found */797d--; /* 0 stripped */798} /* c */799#if DECSUBSET800/* make a rapid exit for easy zeros if !extended */801if (*cfirst=='0' && !set->extended) {802decNumberZero(dn); /* clean result */803break; /* [could be return] */804}805#endif806} /* at least one leading 0 */807
808/* Handle decimal point... */809if (dotchar!=NULL && dotchar<last) /* non-trailing '.' found? */810exponent-=(last-dotchar); /* adjust exponent */811/* [we can now ignore the .] */812
813/* OK, the digits string is good. Assemble in the decNumber, or in */814/* a temporary units array if rounding is needed */815if (d<=set->digits) res=dn->lsu; /* fits into supplied decNumber */816else { /* rounding needed */817Int needbytes=D2U(d)*sizeof(Unit);/* bytes needed */818res=resbuff; /* assume use local buffer */819if (needbytes>(Int)sizeof(resbuff)) { /* too big for local */820allocres=(Unit *)malloc(needbytes);821if (allocres==NULL) {status|=DEC_Insufficient_storage; break;}822res=allocres;823}824}825/* res now -> number lsu, buffer, or allocated storage for Unit array */826
827/* Place the coefficient into the selected Unit array */828/* [this is often 70% of the cost of this function when DECDPUN>1] */829#if DECDPUN>1830out=0; /* accumulator */831up=res+D2U(d)-1; /* -> msu */832cut=d-(up-res)*DECDPUN; /* digits in top unit */833for (c=cfirst;; c++) { /* along the digits */834if (*c=='.') continue; /* ignore '.' [don't decrement cut] */835out=X10(out)+(Int)*c-(Int)'0';836if (c==last) break; /* done [never get to trailing '.'] */837cut--;838if (cut>0) continue; /* more for this unit */839*up=(Unit)out; /* write unit */840up--; /* prepare for unit below.. */841cut=DECDPUN; /* .. */842out=0; /* .. */843} /* c */844*up=(Unit)out; /* write lsu */845
846#else847/* DECDPUN==1 */848up=res; /* -> lsu */849for (c=last; c>=cfirst; c--) { /* over each character, from least */850if (*c=='.') continue; /* ignore . [don't step up] */851*up=(Unit)((Int)*c-(Int)'0');852up++;853} /* c */854#endif855
856dn->bits=bits;857dn->exponent=exponent;858dn->digits=d;859
860/* if not in number (too long) shorten into the number */861if (d>set->digits) {862residue=0;863decSetCoeff(dn, set, res, d, &residue, &status);864/* always check for overflow or subnormal and round as needed */865decFinalize(dn, set, &residue, &status);866}867else { /* no rounding, but may still have overflow or subnormal */868/* [these tests are just for performance; finalize repeats them] */869if ((dn->exponent-1<set->emin-dn->digits)870|| (dn->exponent-1>set->emax-set->digits)) {871residue=0;872decFinalize(dn, set, &residue, &status);873}874}875/* decNumberShow(dn); */876} while(0); /* [for break] */877
878if (allocres!=NULL) free(allocres); /* drop any storage used */879if (status!=0) decStatus(dn, status, set);880return dn;881} /* decNumberFromString */882
883/* ================================================================== */
884/* Operators */
885/* ================================================================== */
886
887/* ------------------------------------------------------------------ */
888/* decNumberAbs -- absolute value operator */
889/* */
890/* This computes C = abs(A) */
891/* */
892/* res is C, the result. C may be A */
893/* rhs is A */
894/* set is the context */
895/* */
896/* See also decNumberCopyAbs for a quiet bitwise version of this. */
897/* C must have space for set->digits digits. */
898/* ------------------------------------------------------------------ */
899/* This has the same effect as decNumberPlus unless A is negative, */
900/* in which case it has the same effect as decNumberMinus. */
901/* ------------------------------------------------------------------ */
902decNumber * decNumberAbs(decNumber *res, const decNumber *rhs,903decContext *set) {904decNumber dzero; /* for 0 */905uInt status=0; /* accumulator */906
907#if DECCHECK908if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;909#endif910
911decNumberZero(&dzero); /* set 0 */912dzero.exponent=rhs->exponent; /* [no coefficient expansion] */913decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status);914if (status!=0) decStatus(res, status, set);915#if DECCHECK916decCheckInexact(res, set);917#endif918return res;919} /* decNumberAbs */920
921/* ------------------------------------------------------------------ */
922/* decNumberAdd -- add two Numbers */
923/* */
924/* This computes C = A + B */
925/* */
926/* res is C, the result. C may be A and/or B (e.g., X=X+X) */
927/* lhs is A */
928/* rhs is B */
929/* set is the context */
930/* */
931/* C must have space for set->digits digits. */
932/* ------------------------------------------------------------------ */
933/* This just calls the routine shared with Subtract */
934decNumber * decNumberAdd(decNumber *res, const decNumber *lhs,935const decNumber *rhs, decContext *set) {936uInt status=0; /* accumulator */937decAddOp(res, lhs, rhs, set, 0, &status);938if (status!=0) decStatus(res, status, set);939#if DECCHECK940decCheckInexact(res, set);941#endif942return res;943} /* decNumberAdd */944
945/* ------------------------------------------------------------------ */
946/* decNumberAnd -- AND two Numbers, digitwise */
947/* */
948/* This computes C = A & B */
949/* */
950/* res is C, the result. C may be A and/or B (e.g., X=X&X) */
951/* lhs is A */
952/* rhs is B */
953/* set is the context (used for result length and error report) */
954/* */
955/* C must have space for set->digits digits. */
956/* */
957/* Logical function restrictions apply (see above); a NaN is */
958/* returned with Invalid_operation if a restriction is violated. */
959/* ------------------------------------------------------------------ */
960decNumber * decNumberAnd(decNumber *res, const decNumber *lhs,961const decNumber *rhs, decContext *set) {962const Unit *ua, *ub; /* -> operands */963const Unit *msua, *msub; /* -> operand msus */964Unit *uc, *msuc; /* -> result and its msu */965Int msudigs; /* digits in res msu */966#if DECCHECK967if (decCheckOperands(res, lhs, rhs, set)) return res;968#endif969
970if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)971|| rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {972decStatus(res, DEC_Invalid_operation, set);973return res;974}975
976/* operands are valid */977ua=lhs->lsu; /* bottom-up */978ub=rhs->lsu; /* .. */979uc=res->lsu; /* .. */980msua=ua+D2U(lhs->digits)-1; /* -> msu of lhs */981msub=ub+D2U(rhs->digits)-1; /* -> msu of rhs */982msuc=uc+D2U(set->digits)-1; /* -> msu of result */983msudigs=MSUDIGITS(set->digits); /* [faster than remainder] */984for (; uc<=msuc; ua++, ub++, uc++) { /* Unit loop */985Unit a, b; /* extract units */986if (ua>msua) a=0;987else a=*ua;988if (ub>msub) b=0;989else b=*ub;990*uc=0; /* can now write back */991if (a|b) { /* maybe 1 bits to examine */992Int i, j;993*uc=0; /* can now write back */994/* This loop could be unrolled and/or use BIN2BCD tables */995for (i=0; i<DECDPUN; i++) {996if (a&b&1) *uc=*uc+(Unit)powers[i]; /* effect AND */997j=a%10;998a=a/10;999j|=b%10;1000b=b/10;1001if (j>1) {1002decStatus(res, DEC_Invalid_operation, set);1003return res;1004}1005if (uc==msuc && i==msudigs-1) break; /* just did final digit */1006} /* each digit */1007} /* both OK */1008} /* each unit */1009/* [here uc-1 is the msu of the result] */1010res->digits=decGetDigits(res->lsu, uc-res->lsu);1011res->exponent=0; /* integer */1012res->bits=0; /* sign=0 */1013return res; /* [no status to set] */1014} /* decNumberAnd */1015
1016/* ------------------------------------------------------------------ */
1017/* decNumberCompare -- compare two Numbers */
1018/* */
1019/* This computes C = A ? B */
1020/* */
1021/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
1022/* lhs is A */
1023/* rhs is B */
1024/* set is the context */
1025/* */
1026/* C must have space for one digit (or NaN). */
1027/* ------------------------------------------------------------------ */
1028decNumber * decNumberCompare(decNumber *res, const decNumber *lhs,1029const decNumber *rhs, decContext *set) {1030uInt status=0; /* accumulator */1031decCompareOp(res, lhs, rhs, set, COMPARE, &status);1032if (status!=0) decStatus(res, status, set);1033return res;1034} /* decNumberCompare */1035
1036/* ------------------------------------------------------------------ */
1037/* decNumberCompareSignal -- compare, signalling on all NaNs */
1038/* */
1039/* This computes C = A ? B */
1040/* */
1041/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
1042/* lhs is A */
1043/* rhs is B */
1044/* set is the context */
1045/* */
1046/* C must have space for one digit (or NaN). */
1047/* ------------------------------------------------------------------ */
1048decNumber * decNumberCompareSignal(decNumber *res, const decNumber *lhs,1049const decNumber *rhs, decContext *set) {1050uInt status=0; /* accumulator */1051decCompareOp(res, lhs, rhs, set, COMPSIG, &status);1052if (status!=0) decStatus(res, status, set);1053return res;1054} /* decNumberCompareSignal */1055
1056/* ------------------------------------------------------------------ */
1057/* decNumberCompareTotal -- compare two Numbers, using total ordering */
1058/* */
1059/* This computes C = A ? B, under total ordering */
1060/* */
1061/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
1062/* lhs is A */
1063/* rhs is B */
1064/* set is the context */
1065/* */
1066/* C must have space for one digit; the result will always be one of */
1067/* -1, 0, or 1. */
1068/* ------------------------------------------------------------------ */
1069decNumber * decNumberCompareTotal(decNumber *res, const decNumber *lhs,1070const decNumber *rhs, decContext *set) {1071uInt status=0; /* accumulator */1072decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);1073if (status!=0) decStatus(res, status, set);1074return res;1075} /* decNumberCompareTotal */1076
1077/* ------------------------------------------------------------------ */
1078/* decNumberCompareTotalMag -- compare, total ordering of magnitudes */
1079/* */
1080/* This computes C = |A| ? |B|, under total ordering */
1081/* */
1082/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
1083/* lhs is A */
1084/* rhs is B */
1085/* set is the context */
1086/* */
1087/* C must have space for one digit; the result will always be one of */
1088/* -1, 0, or 1. */
1089/* ------------------------------------------------------------------ */
1090decNumber * decNumberCompareTotalMag(decNumber *res, const decNumber *lhs,1091const decNumber *rhs, decContext *set) {1092uInt status=0; /* accumulator */1093uInt needbytes; /* for space calculations */1094decNumber bufa[D2N(DECBUFFER+1)];/* +1 in case DECBUFFER=0 */1095decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */1096decNumber bufb[D2N(DECBUFFER+1)];1097decNumber *allocbufb=NULL; /* -> allocated bufb, iff allocated */1098decNumber *a, *b; /* temporary pointers */1099
1100#if DECCHECK1101if (decCheckOperands(res, lhs, rhs, set)) return res;1102#endif1103
1104do { /* protect allocated storage */1105/* if either is negative, take a copy and absolute */1106if (decNumberIsNegative(lhs)) { /* lhs<0 */1107a=bufa;1108needbytes=sizeof(decNumber)+(D2U(lhs->digits)-1)*sizeof(Unit);1109if (needbytes>sizeof(bufa)) { /* need malloc space */1110allocbufa=(decNumber *)malloc(needbytes);1111if (allocbufa==NULL) { /* hopeless -- abandon */1112status|=DEC_Insufficient_storage;1113break;}1114a=allocbufa; /* use the allocated space */1115}1116decNumberCopy(a, lhs); /* copy content */1117a->bits&=~DECNEG; /* .. and clear the sign */1118lhs=a; /* use copy from here on */1119}1120if (decNumberIsNegative(rhs)) { /* rhs<0 */1121b=bufb;1122needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);1123if (needbytes>sizeof(bufb)) { /* need malloc space */1124allocbufb=(decNumber *)malloc(needbytes);1125if (allocbufb==NULL) { /* hopeless -- abandon */1126status|=DEC_Insufficient_storage;1127break;}1128b=allocbufb; /* use the allocated space */1129}1130decNumberCopy(b, rhs); /* copy content */1131b->bits&=~DECNEG; /* .. and clear the sign */1132rhs=b; /* use copy from here on */1133}1134decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);1135} while(0); /* end protected */1136
1137if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */1138if (allocbufb!=NULL) free(allocbufb); /* .. */1139if (status!=0) decStatus(res, status, set);1140return res;1141} /* decNumberCompareTotalMag */1142
1143/* ------------------------------------------------------------------ */
1144/* decNumberDivide -- divide one number by another */
1145/* */
1146/* This computes C = A / B */
1147/* */
1148/* res is C, the result. C may be A and/or B (e.g., X=X/X) */
1149/* lhs is A */
1150/* rhs is B */
1151/* set is the context */
1152/* */
1153/* C must have space for set->digits digits. */
1154/* ------------------------------------------------------------------ */
1155decNumber * decNumberDivide(decNumber *res, const decNumber *lhs,1156const decNumber *rhs, decContext *set) {1157uInt status=0; /* accumulator */1158decDivideOp(res, lhs, rhs, set, DIVIDE, &status);1159if (status!=0) decStatus(res, status, set);1160#if DECCHECK1161decCheckInexact(res, set);1162#endif1163return res;1164} /* decNumberDivide */1165
1166/* ------------------------------------------------------------------ */
1167/* decNumberDivideInteger -- divide and return integer quotient */
1168/* */
1169/* This computes C = A # B, where # is the integer divide operator */
1170/* */
1171/* res is C, the result. C may be A and/or B (e.g., X=X#X) */
1172/* lhs is A */
1173/* rhs is B */
1174/* set is the context */
1175/* */
1176/* C must have space for set->digits digits. */
1177/* ------------------------------------------------------------------ */
1178decNumber * decNumberDivideInteger(decNumber *res, const decNumber *lhs,1179const decNumber *rhs, decContext *set) {1180uInt status=0; /* accumulator */1181decDivideOp(res, lhs, rhs, set, DIVIDEINT, &status);1182if (status!=0) decStatus(res, status, set);1183return res;1184} /* decNumberDivideInteger */1185
1186/* ------------------------------------------------------------------ */
1187/* decNumberExp -- exponentiation */
1188/* */
1189/* This computes C = exp(A) */
1190/* */
1191/* res is C, the result. C may be A */
1192/* rhs is A */
1193/* set is the context; note that rounding mode has no effect */
1194/* */
1195/* C must have space for set->digits digits. */
1196/* */
1197/* Mathematical function restrictions apply (see above); a NaN is */
1198/* returned with Invalid_operation if a restriction is violated. */
1199/* */
1200/* Finite results will always be full precision and Inexact, except */
1201/* when A is a zero or -Infinity (giving 1 or 0 respectively). */
1202/* */
1203/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */
1204/* almost always be correctly rounded, but may be up to 1 ulp in */
1205/* error in rare cases. */
1206/* ------------------------------------------------------------------ */
1207/* This is a wrapper for decExpOp which can handle the slightly wider */
1208/* (double) range needed by Ln (which has to be able to calculate */
1209/* exp(-a) where a can be the tiniest number (Ntiny). */
1210/* ------------------------------------------------------------------ */
1211decNumber * decNumberExp(decNumber *res, const decNumber *rhs,1212decContext *set) {1213uInt status=0; /* accumulator */1214#if DECSUBSET1215decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */1216#endif1217
1218#if DECCHECK1219if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;1220#endif1221
1222/* Check restrictions; these restrictions ensure that if h=8 (see */1223/* decExpOp) then the result will either overflow or underflow to 0. */1224/* Other math functions restrict the input range, too, for inverses. */1225/* If not violated then carry out the operation. */1226if (!decCheckMath(rhs, set, &status)) do { /* protect allocation */1227#if DECSUBSET1228if (!set->extended) {1229/* reduce operand and set lostDigits status, as needed */1230if (rhs->digits>set->digits) {1231allocrhs=decRoundOperand(rhs, set, &status);1232if (allocrhs==NULL) break;1233rhs=allocrhs;1234}1235}1236#endif1237decExpOp(res, rhs, set, &status);1238} while(0); /* end protected */1239
1240#if DECSUBSET1241if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */1242#endif1243/* apply significant status */1244if (status!=0) decStatus(res, status, set);1245#if DECCHECK1246decCheckInexact(res, set);1247#endif1248return res;1249} /* decNumberExp */1250
1251/* ------------------------------------------------------------------ */
1252/* decNumberFMA -- fused multiply add */
1253/* */
1254/* This computes D = (A * B) + C with only one rounding */
1255/* */
1256/* res is D, the result. D may be A or B or C (e.g., X=FMA(X,X,X)) */
1257/* lhs is A */
1258/* rhs is B */
1259/* fhs is C [far hand side] */
1260/* set is the context */
1261/* */
1262/* Mathematical function restrictions apply (see above); a NaN is */
1263/* returned with Invalid_operation if a restriction is violated. */
1264/* */
1265/* C must have space for set->digits digits. */
1266/* ------------------------------------------------------------------ */
1267decNumber * decNumberFMA(decNumber *res, const decNumber *lhs,1268const decNumber *rhs, const decNumber *fhs,1269decContext *set) {1270uInt status=0; /* accumulator */1271decContext dcmul; /* context for the multiplication */1272uInt needbytes; /* for space calculations */1273decNumber bufa[D2N(DECBUFFER*2+1)];1274decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */1275decNumber *acc; /* accumulator pointer */1276decNumber dzero; /* work */1277
1278#if DECCHECK1279if (decCheckOperands(res, lhs, rhs, set)) return res;1280if (decCheckOperands(res, fhs, DECUNUSED, set)) return res;1281#endif1282
1283do { /* protect allocated storage */1284#if DECSUBSET1285if (!set->extended) { /* [undefined if subset] */1286status|=DEC_Invalid_operation;1287break;}1288#endif1289/* Check math restrictions [these ensure no overflow or underflow] */1290if ((!decNumberIsSpecial(lhs) && decCheckMath(lhs, set, &status))1291|| (!decNumberIsSpecial(rhs) && decCheckMath(rhs, set, &status))1292|| (!decNumberIsSpecial(fhs) && decCheckMath(fhs, set, &status))) break;1293/* set up context for multiply */1294dcmul=*set;1295dcmul.digits=lhs->digits+rhs->digits; /* just enough */1296/* [The above may be an over-estimate for subset arithmetic, but that's OK] */1297dcmul.emax=DEC_MAX_EMAX; /* effectively unbounded .. */1298dcmul.emin=DEC_MIN_EMIN; /* [thanks to Math restrictions] */1299/* set up decNumber space to receive the result of the multiply */1300acc=bufa; /* may fit */1301needbytes=sizeof(decNumber)+(D2U(dcmul.digits)-1)*sizeof(Unit);1302if (needbytes>sizeof(bufa)) { /* need malloc space */1303allocbufa=(decNumber *)malloc(needbytes);1304if (allocbufa==NULL) { /* hopeless -- abandon */1305status|=DEC_Insufficient_storage;1306break;}1307acc=allocbufa; /* use the allocated space */1308}1309/* multiply with extended range and necessary precision */1310/*printf("emin=%ld\n", dcmul.emin); */1311decMultiplyOp(acc, lhs, rhs, &dcmul, &status);1312/* Only Invalid operation (from sNaN or Inf * 0) is possible in */1313/* status; if either is seen than ignore fhs (in case it is */1314/* another sNaN) and set acc to NaN unless we had an sNaN */1315/* [decMultiplyOp leaves that to caller] */1316/* Note sNaN has to go through addOp to shorten payload if */1317/* necessary */1318if ((status&DEC_Invalid_operation)!=0) {1319if (!(status&DEC_sNaN)) { /* but be true invalid */1320decNumberZero(res); /* acc not yet set */1321res->bits=DECNAN;1322break;1323}1324decNumberZero(&dzero); /* make 0 (any non-NaN would do) */1325fhs=&dzero; /* use that */1326}1327#if DECCHECK1328else { /* multiply was OK */1329if (status!=0) printf("Status=%08lx after FMA multiply\n", status);1330}1331#endif1332/* add the third operand and result -> res, and all is done */1333decAddOp(res, acc, fhs, set, 0, &status);1334} while(0); /* end protected */1335
1336if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */1337if (status!=0) decStatus(res, status, set);1338#if DECCHECK1339decCheckInexact(res, set);1340#endif1341return res;1342} /* decNumberFMA */1343
1344/* ------------------------------------------------------------------ */
1345/* decNumberInvert -- invert a Number, digitwise */
1346/* */
1347/* This computes C = ~A */
1348/* */
1349/* res is C, the result. C may be A (e.g., X=~X) */
1350/* rhs is A */
1351/* set is the context (used for result length and error report) */
1352/* */
1353/* C must have space for set->digits digits. */
1354/* */
1355/* Logical function restrictions apply (see above); a NaN is */
1356/* returned with Invalid_operation if a restriction is violated. */
1357/* ------------------------------------------------------------------ */
1358decNumber * decNumberInvert(decNumber *res, const decNumber *rhs,1359decContext *set) {1360const Unit *ua, *msua; /* -> operand and its msu */1361Unit *uc, *msuc; /* -> result and its msu */1362Int msudigs; /* digits in res msu */1363#if DECCHECK1364if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;1365#endif1366
1367if (rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {1368decStatus(res, DEC_Invalid_operation, set);1369return res;1370}1371/* operand is valid */1372ua=rhs->lsu; /* bottom-up */1373uc=res->lsu; /* .. */1374msua=ua+D2U(rhs->digits)-1; /* -> msu of rhs */1375msuc=uc+D2U(set->digits)-1; /* -> msu of result */1376msudigs=MSUDIGITS(set->digits); /* [faster than remainder] */1377for (; uc<=msuc; ua++, uc++) { /* Unit loop */1378Unit a; /* extract unit */1379Int i, j; /* work */1380if (ua>msua) a=0;1381else a=*ua;1382*uc=0; /* can now write back */1383/* always need to examine all bits in rhs */1384/* This loop could be unrolled and/or use BIN2BCD tables */1385for (i=0; i<DECDPUN; i++) {1386if ((~a)&1) *uc=*uc+(Unit)powers[i]; /* effect INVERT */1387j=a%10;1388a=a/10;1389if (j>1) {1390decStatus(res, DEC_Invalid_operation, set);1391return res;1392}1393if (uc==msuc && i==msudigs-1) break; /* just did final digit */1394} /* each digit */1395} /* each unit */1396/* [here uc-1 is the msu of the result] */1397res->digits=decGetDigits(res->lsu, uc-res->lsu);1398res->exponent=0; /* integer */1399res->bits=0; /* sign=0 */1400return res; /* [no status to set] */1401} /* decNumberInvert */1402
1403/* ------------------------------------------------------------------ */
1404/* decNumberLn -- natural logarithm */
1405/* */
1406/* This computes C = ln(A) */
1407/* */
1408/* res is C, the result. C may be A */
1409/* rhs is A */
1410/* set is the context; note that rounding mode has no effect */
1411/* */
1412/* C must have space for set->digits digits. */
1413/* */
1414/* Notable cases: */
1415/* A<0 -> Invalid */
1416/* A=0 -> -Infinity (Exact) */
1417/* A=+Infinity -> +Infinity (Exact) */
1418/* A=1 exactly -> 0 (Exact) */
1419/* */
1420/* Mathematical function restrictions apply (see above); a NaN is */
1421/* returned with Invalid_operation if a restriction is violated. */
1422/* */
1423/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */
1424/* almost always be correctly rounded, but may be up to 1 ulp in */
1425/* error in rare cases. */
1426/* ------------------------------------------------------------------ */
1427/* This is a wrapper for decLnOp which can handle the slightly wider */
1428/* (+11) range needed by Ln, Log10, etc. (which may have to be able */
1429/* to calculate at p+e+2). */
1430/* ------------------------------------------------------------------ */
1431decNumber * decNumberLn(decNumber *res, const decNumber *rhs,1432decContext *set) {1433uInt status=0; /* accumulator */1434#if DECSUBSET1435decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */1436#endif1437
1438#if DECCHECK1439if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;1440#endif1441
1442/* Check restrictions; this is a math function; if not violated */1443/* then carry out the operation. */1444if (!decCheckMath(rhs, set, &status)) do { /* protect allocation */1445#if DECSUBSET1446if (!set->extended) {1447/* reduce operand and set lostDigits status, as needed */1448if (rhs->digits>set->digits) {1449allocrhs=decRoundOperand(rhs, set, &status);1450if (allocrhs==NULL) break;1451rhs=allocrhs;1452}1453/* special check in subset for rhs=0 */1454if (ISZERO(rhs)) { /* +/- zeros -> error */1455status|=DEC_Invalid_operation;1456break;}1457} /* extended=0 */1458#endif1459decLnOp(res, rhs, set, &status);1460} while(0); /* end protected */1461
1462#if DECSUBSET1463if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */1464#endif1465/* apply significant status */1466if (status!=0) decStatus(res, status, set);1467#if DECCHECK1468decCheckInexact(res, set);1469#endif1470return res;1471} /* decNumberLn */1472
1473/* ------------------------------------------------------------------ */
1474/* decNumberLogB - get adjusted exponent, by 754r rules */
1475/* */
1476/* This computes C = adjustedexponent(A) */
1477/* */
1478/* res is C, the result. C may be A */
1479/* rhs is A */
1480/* set is the context, used only for digits and status */
1481/* */
1482/* C must have space for 10 digits (A might have 10**9 digits and */
1483/* an exponent of +999999999, or one digit and an exponent of */
1484/* -1999999999). */
1485/* */
1486/* This returns the adjusted exponent of A after (in theory) padding */
1487/* with zeros on the right to set->digits digits while keeping the */
1488/* same value. The exponent is not limited by emin/emax. */
1489/* */
1490/* Notable cases: */
1491/* A<0 -> Use |A| */
1492/* A=0 -> -Infinity (Division by zero) */
1493/* A=Infinite -> +Infinity (Exact) */
1494/* A=1 exactly -> 0 (Exact) */
1495/* NaNs are propagated as usual */
1496/* ------------------------------------------------------------------ */
1497decNumber * decNumberLogB(decNumber *res, const decNumber *rhs,1498decContext *set) {1499uInt status=0; /* accumulator */1500
1501#if DECCHECK1502if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;1503#endif1504
1505/* NaNs as usual; Infinities return +Infinity; 0->oops */1506if (decNumberIsNaN(rhs)) decNaNs(res, rhs, NULL, set, &status);1507else if (decNumberIsInfinite(rhs)) decNumberCopyAbs(res, rhs);1508else if (decNumberIsZero(rhs)) {1509decNumberZero(res); /* prepare for Infinity */1510res->bits=DECNEG|DECINF; /* -Infinity */1511status|=DEC_Division_by_zero; /* as per 754r */1512}1513else { /* finite non-zero */1514Int ae=rhs->exponent+rhs->digits-1; /* adjusted exponent */1515decNumberFromInt32(res, ae); /* lay it out */1516}1517
1518if (status!=0) decStatus(res, status, set);1519return res;1520} /* decNumberLogB */1521
1522/* ------------------------------------------------------------------ */
1523/* decNumberLog10 -- logarithm in base 10 */
1524/* */
1525/* This computes C = log10(A) */
1526/* */
1527/* res is C, the result. C may be A */
1528/* rhs is A */
1529/* set is the context; note that rounding mode has no effect */
1530/* */
1531/* C must have space for set->digits digits. */
1532/* */
1533/* Notable cases: */
1534/* A<0 -> Invalid */
1535/* A=0 -> -Infinity (Exact) */
1536/* A=+Infinity -> +Infinity (Exact) */
1537/* A=10**n (if n is an integer) -> n (Exact) */
1538/* */
1539/* Mathematical function restrictions apply (see above); a NaN is */
1540/* returned with Invalid_operation if a restriction is violated. */
1541/* */
1542/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */
1543/* almost always be correctly rounded, but may be up to 1 ulp in */
1544/* error in rare cases. */
1545/* ------------------------------------------------------------------ */
1546/* This calculates ln(A)/ln(10) using appropriate precision. For */
1547/* ln(A) this is the max(p, rhs->digits + t) + 3, where p is the */
1548/* requested digits and t is the number of digits in the exponent */
1549/* (maximum 6). For ln(10) it is p + 3; this is often handled by the */
1550/* fastpath in decLnOp. The final division is done to the requested */
1551/* precision. */
1552/* ------------------------------------------------------------------ */
1553decNumber * decNumberLog10(decNumber *res, const decNumber *rhs,1554decContext *set) {1555uInt status=0, ignore=0; /* status accumulators */1556uInt needbytes; /* for space calculations */1557Int p; /* working precision */1558Int t; /* digits in exponent of A */1559
1560/* buffers for a and b working decimals */1561/* (adjustment calculator, same size) */1562decNumber bufa[D2N(DECBUFFER+2)];1563decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */1564decNumber *a=bufa; /* temporary a */1565decNumber bufb[D2N(DECBUFFER+2)];1566decNumber *allocbufb=NULL; /* -> allocated bufb, iff allocated */1567decNumber *b=bufb; /* temporary b */1568decNumber bufw[D2N(10)]; /* working 2-10 digit number */1569decNumber *w=bufw; /* .. */1570#if DECSUBSET1571decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */1572#endif1573
1574decContext aset; /* working context */1575
1576#if DECCHECK1577if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;1578#endif1579
1580/* Check restrictions; this is a math function; if not violated */1581/* then carry out the operation. */1582if (!decCheckMath(rhs, set, &status)) do { /* protect malloc */1583#if DECSUBSET1584if (!set->extended) {1585/* reduce operand and set lostDigits status, as needed */1586if (rhs->digits>set->digits) {1587allocrhs=decRoundOperand(rhs, set, &status);1588if (allocrhs==NULL) break;1589rhs=allocrhs;1590}1591/* special check in subset for rhs=0 */1592if (ISZERO(rhs)) { /* +/- zeros -> error */1593status|=DEC_Invalid_operation;1594break;}1595} /* extended=0 */1596#endif1597
1598decContextDefault(&aset, DEC_INIT_DECIMAL64); /* clean context */1599
1600/* handle exact powers of 10; only check if +ve finite */1601if (!(rhs->bits&(DECNEG|DECSPECIAL)) && !ISZERO(rhs)) {1602Int residue=0; /* (no residue) */1603uInt copystat=0; /* clean status */1604
1605/* round to a single digit... */1606aset.digits=1;1607decCopyFit(w, rhs, &aset, &residue, ©stat); /* copy & shorten */1608/* if exact and the digit is 1, rhs is a power of 10 */1609if (!(copystat&DEC_Inexact) && w->lsu[0]==1) {1610/* the exponent, conveniently, is the power of 10; making */1611/* this the result needs a little care as it might not fit, */1612/* so first convert it into the working number, and then move */1613/* to res */1614decNumberFromInt32(w, w->exponent);1615residue=0;1616decCopyFit(res, w, set, &residue, &status); /* copy & round */1617decFinish(res, set, &residue, &status); /* cleanup/set flags */1618break;1619} /* not a power of 10 */1620} /* not a candidate for exact */1621
1622/* simplify the information-content calculation to use 'total */1623/* number of digits in a, including exponent' as compared to the */1624/* requested digits, as increasing this will only rarely cost an */1625/* iteration in ln(a) anyway */1626t=6; /* it can never be >6 */1627
1628/* allocate space when needed... */1629p=(rhs->digits+t>set->digits?rhs->digits+t:set->digits)+3;1630needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);1631if (needbytes>sizeof(bufa)) { /* need malloc space */1632allocbufa=(decNumber *)malloc(needbytes);1633if (allocbufa==NULL) { /* hopeless -- abandon */1634status|=DEC_Insufficient_storage;1635break;}1636a=allocbufa; /* use the allocated space */1637}1638aset.digits=p; /* as calculated */1639aset.emax=DEC_MAX_MATH; /* usual bounds */1640aset.emin=-DEC_MAX_MATH; /* .. */1641aset.clamp=0; /* and no concrete format */1642decLnOp(a, rhs, &aset, &status); /* a=ln(rhs) */1643
1644/* skip the division if the result so far is infinite, NaN, or */1645/* zero, or there was an error; note NaN from sNaN needs copy */1646if (status&DEC_NaNs && !(status&DEC_sNaN)) break;1647if (a->bits&DECSPECIAL || ISZERO(a)) {1648decNumberCopy(res, a); /* [will fit] */1649break;}1650
1651/* for ln(10) an extra 3 digits of precision are needed */1652p=set->digits+3;1653needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);1654if (needbytes>sizeof(bufb)) { /* need malloc space */1655allocbufb=(decNumber *)malloc(needbytes);1656if (allocbufb==NULL) { /* hopeless -- abandon */1657status|=DEC_Insufficient_storage;1658break;}1659b=allocbufb; /* use the allocated space */1660}1661decNumberZero(w); /* set up 10... */1662#if DECDPUN==11663w->lsu[1]=1; w->lsu[0]=0; /* .. */1664#else1665w->lsu[0]=10; /* .. */1666#endif1667w->digits=2; /* .. */1668
1669aset.digits=p;1670decLnOp(b, w, &aset, &ignore); /* b=ln(10) */1671
1672aset.digits=set->digits; /* for final divide */1673decDivideOp(res, a, b, &aset, DIVIDE, &status); /* into result */1674} while(0); /* [for break] */1675
1676if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */1677if (allocbufb!=NULL) free(allocbufb); /* .. */1678#if DECSUBSET1679if (allocrhs !=NULL) free(allocrhs); /* .. */1680#endif1681/* apply significant status */1682if (status!=0) decStatus(res, status, set);1683#if DECCHECK1684decCheckInexact(res, set);1685#endif1686return res;1687} /* decNumberLog10 */1688
1689/* ------------------------------------------------------------------ */
1690/* decNumberMax -- compare two Numbers and return the maximum */
1691/* */
1692/* This computes C = A ? B, returning the maximum by 754R rules */
1693/* */
1694/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
1695/* lhs is A */
1696/* rhs is B */
1697/* set is the context */
1698/* */
1699/* C must have space for set->digits digits. */
1700/* ------------------------------------------------------------------ */
1701decNumber * decNumberMax(decNumber *res, const decNumber *lhs,1702const decNumber *rhs, decContext *set) {1703uInt status=0; /* accumulator */1704decCompareOp(res, lhs, rhs, set, COMPMAX, &status);1705if (status!=0) decStatus(res, status, set);1706#if DECCHECK1707decCheckInexact(res, set);1708#endif1709return res;1710} /* decNumberMax */1711
1712/* ------------------------------------------------------------------ */
1713/* decNumberMaxMag -- compare and return the maximum by magnitude */
1714/* */
1715/* This computes C = A ? B, returning the maximum by 754R rules */
1716/* */
1717/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
1718/* lhs is A */
1719/* rhs is B */
1720/* set is the context */
1721/* */
1722/* C must have space for set->digits digits. */
1723/* ------------------------------------------------------------------ */
1724decNumber * decNumberMaxMag(decNumber *res, const decNumber *lhs,1725const decNumber *rhs, decContext *set) {1726uInt status=0; /* accumulator */1727decCompareOp(res, lhs, rhs, set, COMPMAXMAG, &status);1728if (status!=0) decStatus(res, status, set);1729#if DECCHECK1730decCheckInexact(res, set);1731#endif1732return res;1733} /* decNumberMaxMag */1734
1735/* ------------------------------------------------------------------ */
1736/* decNumberMin -- compare two Numbers and return the minimum */
1737/* */
1738/* This computes C = A ? B, returning the minimum by 754R rules */
1739/* */
1740/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
1741/* lhs is A */
1742/* rhs is B */
1743/* set is the context */
1744/* */
1745/* C must have space for set->digits digits. */
1746/* ------------------------------------------------------------------ */
1747decNumber * decNumberMin(decNumber *res, const decNumber *lhs,1748const decNumber *rhs, decContext *set) {1749uInt status=0; /* accumulator */1750decCompareOp(res, lhs, rhs, set, COMPMIN, &status);1751if (status!=0) decStatus(res, status, set);1752#if DECCHECK1753decCheckInexact(res, set);1754#endif1755return res;1756} /* decNumberMin */1757
1758/* ------------------------------------------------------------------ */
1759/* decNumberMinMag -- compare and return the minimum by magnitude */
1760/* */
1761/* This computes C = A ? B, returning the minimum by 754R rules */
1762/* */
1763/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
1764/* lhs is A */
1765/* rhs is B */
1766/* set is the context */
1767/* */
1768/* C must have space for set->digits digits. */
1769/* ------------------------------------------------------------------ */
1770decNumber * decNumberMinMag(decNumber *res, const decNumber *lhs,1771const decNumber *rhs, decContext *set) {1772uInt status=0; /* accumulator */1773decCompareOp(res, lhs, rhs, set, COMPMINMAG, &status);1774if (status!=0) decStatus(res, status, set);1775#if DECCHECK1776decCheckInexact(res, set);1777#endif1778return res;1779} /* decNumberMinMag */1780
1781/* ------------------------------------------------------------------ */
1782/* decNumberMinus -- prefix minus operator */
1783/* */
1784/* This computes C = 0 - A */
1785/* */
1786/* res is C, the result. C may be A */
1787/* rhs is A */
1788/* set is the context */
1789/* */
1790/* See also decNumberCopyNegate for a quiet bitwise version of this. */
1791/* C must have space for set->digits digits. */
1792/* ------------------------------------------------------------------ */
1793/* Simply use AddOp for the subtract, which will do the necessary. */
1794/* ------------------------------------------------------------------ */
1795decNumber * decNumberMinus(decNumber *res, const decNumber *rhs,1796decContext *set) {1797decNumber dzero;1798uInt status=0; /* accumulator */1799
1800#if DECCHECK1801if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;1802#endif1803
1804decNumberZero(&dzero); /* make 0 */1805dzero.exponent=rhs->exponent; /* [no coefficient expansion] */1806decAddOp(res, &dzero, rhs, set, DECNEG, &status);1807if (status!=0) decStatus(res, status, set);1808#if DECCHECK1809decCheckInexact(res, set);1810#endif1811return res;1812} /* decNumberMinus */1813
1814/* ------------------------------------------------------------------ */
1815/* decNumberNextMinus -- next towards -Infinity */
1816/* */
1817/* This computes C = A - infinitesimal, rounded towards -Infinity */
1818/* */
1819/* res is C, the result. C may be A */
1820/* rhs is A */
1821/* set is the context */
1822/* */
1823/* This is a generalization of 754r NextDown. */
1824/* ------------------------------------------------------------------ */
1825decNumber * decNumberNextMinus(decNumber *res, const decNumber *rhs,1826decContext *set) {1827decNumber dtiny; /* constant */1828decContext workset=*set; /* work */1829uInt status=0; /* accumulator */1830#if DECCHECK1831if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;1832#endif1833
1834/* +Infinity is the special case */1835if ((rhs->bits&(DECINF|DECNEG))==DECINF) {1836decSetMaxValue(res, set); /* is +ve */1837/* there is no status to set */1838return res;1839}1840decNumberZero(&dtiny); /* start with 0 */1841dtiny.lsu[0]=1; /* make number that is .. */1842dtiny.exponent=DEC_MIN_EMIN-1; /* .. smaller than tiniest */1843workset.round=DEC_ROUND_FLOOR;1844decAddOp(res, rhs, &dtiny, &workset, DECNEG, &status);1845status&=DEC_Invalid_operation|DEC_sNaN; /* only sNaN Invalid please */1846if (status!=0) decStatus(res, status, set);1847return res;1848} /* decNumberNextMinus */1849
1850/* ------------------------------------------------------------------ */
1851/* decNumberNextPlus -- next towards +Infinity */
1852/* */
1853/* This computes C = A + infinitesimal, rounded towards +Infinity */
1854/* */
1855/* res is C, the result. C may be A */
1856/* rhs is A */
1857/* set is the context */
1858/* */
1859/* This is a generalization of 754r NextUp. */
1860/* ------------------------------------------------------------------ */
1861decNumber * decNumberNextPlus(decNumber *res, const decNumber *rhs,1862decContext *set) {1863decNumber dtiny; /* constant */1864decContext workset=*set; /* work */1865uInt status=0; /* accumulator */1866#if DECCHECK1867if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;1868#endif1869
1870/* -Infinity is the special case */1871if ((rhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {1872decSetMaxValue(res, set);1873res->bits=DECNEG; /* negative */1874/* there is no status to set */1875return res;1876}1877decNumberZero(&dtiny); /* start with 0 */1878dtiny.lsu[0]=1; /* make number that is .. */1879dtiny.exponent=DEC_MIN_EMIN-1; /* .. smaller than tiniest */1880workset.round=DEC_ROUND_CEILING;1881decAddOp(res, rhs, &dtiny, &workset, 0, &status);1882status&=DEC_Invalid_operation|DEC_sNaN; /* only sNaN Invalid please */1883if (status!=0) decStatus(res, status, set);1884return res;1885} /* decNumberNextPlus */1886
1887/* ------------------------------------------------------------------ */
1888/* decNumberNextToward -- next towards rhs */
1889/* */
1890/* This computes C = A +/- infinitesimal, rounded towards */
1891/* +/-Infinity in the direction of B, as per 754r nextafter rules */
1892/* */
1893/* res is C, the result. C may be A or B. */
1894/* lhs is A */
1895/* rhs is B */
1896/* set is the context */
1897/* */
1898/* This is a generalization of 754r NextAfter. */
1899/* ------------------------------------------------------------------ */
1900decNumber * decNumberNextToward(decNumber *res, const decNumber *lhs,1901const decNumber *rhs, decContext *set) {1902decNumber dtiny; /* constant */1903decContext workset=*set; /* work */1904Int result; /* .. */1905uInt status=0; /* accumulator */1906#if DECCHECK1907if (decCheckOperands(res, lhs, rhs, set)) return res;1908#endif1909
1910if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) {1911decNaNs(res, lhs, rhs, set, &status);1912}1913else { /* Is numeric, so no chance of sNaN Invalid, etc. */1914result=decCompare(lhs, rhs, 0); /* sign matters */1915if (result==BADINT) status|=DEC_Insufficient_storage; /* rare */1916else { /* valid compare */1917if (result==0) decNumberCopySign(res, lhs, rhs); /* easy */1918else { /* differ: need NextPlus or NextMinus */1919uByte sub; /* add or subtract */1920if (result<0) { /* lhs<rhs, do nextplus */1921/* -Infinity is the special case */1922if ((lhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {1923decSetMaxValue(res, set);1924res->bits=DECNEG; /* negative */1925return res; /* there is no status to set */1926}1927workset.round=DEC_ROUND_CEILING;1928sub=0; /* add, please */1929} /* plus */1930else { /* lhs>rhs, do nextminus */1931/* +Infinity is the special case */1932if ((lhs->bits&(DECINF|DECNEG))==DECINF) {1933decSetMaxValue(res, set);1934return res; /* there is no status to set */1935}1936workset.round=DEC_ROUND_FLOOR;1937sub=DECNEG; /* subtract, please */1938} /* minus */1939decNumberZero(&dtiny); /* start with 0 */1940dtiny.lsu[0]=1; /* make number that is .. */1941dtiny.exponent=DEC_MIN_EMIN-1; /* .. smaller than tiniest */1942decAddOp(res, lhs, &dtiny, &workset, sub, &status); /* + or - */1943/* turn off exceptions if the result is a normal number */1944/* (including Nmin), otherwise let all status through */1945if (decNumberIsNormal(res, set)) status=0;1946} /* unequal */1947} /* compare OK */1948} /* numeric */1949if (status!=0) decStatus(res, status, set);1950return res;1951} /* decNumberNextToward */1952
1953/* ------------------------------------------------------------------ */
1954/* decNumberOr -- OR two Numbers, digitwise */
1955/* */
1956/* This computes C = A | B */
1957/* */
1958/* res is C, the result. C may be A and/or B (e.g., X=X|X) */
1959/* lhs is A */
1960/* rhs is B */
1961/* set is the context (used for result length and error report) */
1962/* */
1963/* C must have space for set->digits digits. */
1964/* */
1965/* Logical function restrictions apply (see above); a NaN is */
1966/* returned with Invalid_operation if a restriction is violated. */
1967/* ------------------------------------------------------------------ */
1968decNumber * decNumberOr(decNumber *res, const decNumber *lhs,1969const decNumber *rhs, decContext *set) {1970const Unit *ua, *ub; /* -> operands */1971const Unit *msua, *msub; /* -> operand msus */1972Unit *uc, *msuc; /* -> result and its msu */1973Int msudigs; /* digits in res msu */1974#if DECCHECK1975if (decCheckOperands(res, lhs, rhs, set)) return res;1976#endif1977
1978if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)1979|| rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {1980decStatus(res, DEC_Invalid_operation, set);1981return res;1982}1983/* operands are valid */1984ua=lhs->lsu; /* bottom-up */1985ub=rhs->lsu; /* .. */1986uc=res->lsu; /* .. */1987msua=ua+D2U(lhs->digits)-1; /* -> msu of lhs */1988msub=ub+D2U(rhs->digits)-1; /* -> msu of rhs */1989msuc=uc+D2U(set->digits)-1; /* -> msu of result */1990msudigs=MSUDIGITS(set->digits); /* [faster than remainder] */1991for (; uc<=msuc; ua++, ub++, uc++) { /* Unit loop */1992Unit a, b; /* extract units */1993if (ua>msua) a=0;1994else a=*ua;1995if (ub>msub) b=0;1996else b=*ub;1997*uc=0; /* can now write back */1998if (a|b) { /* maybe 1 bits to examine */1999Int i, j;2000/* This loop could be unrolled and/or use BIN2BCD tables */2001for (i=0; i<DECDPUN; i++) {2002if ((a|b)&1) *uc=*uc+(Unit)powers[i]; /* effect OR */2003j=a%10;2004a=a/10;2005j|=b%10;2006b=b/10;2007if (j>1) {2008decStatus(res, DEC_Invalid_operation, set);2009return res;2010}2011if (uc==msuc && i==msudigs-1) break; /* just did final digit */2012} /* each digit */2013} /* non-zero */2014} /* each unit */2015/* [here uc-1 is the msu of the result] */2016res->digits=decGetDigits(res->lsu, uc-res->lsu);2017res->exponent=0; /* integer */2018res->bits=0; /* sign=0 */2019return res; /* [no status to set] */2020} /* decNumberOr */2021
2022/* ------------------------------------------------------------------ */
2023/* decNumberPlus -- prefix plus operator */
2024/* */
2025/* This computes C = 0 + A */
2026/* */
2027/* res is C, the result. C may be A */
2028/* rhs is A */
2029/* set is the context */
2030/* */
2031/* See also decNumberCopy for a quiet bitwise version of this. */
2032/* C must have space for set->digits digits. */
2033/* ------------------------------------------------------------------ */
2034/* This simply uses AddOp; Add will take fast path after preparing A. */
2035/* Performance is a concern here, as this routine is often used to */
2036/* check operands and apply rounding and overflow/underflow testing. */
2037/* ------------------------------------------------------------------ */
2038decNumber * decNumberPlus(decNumber *res, const decNumber *rhs,2039decContext *set) {2040decNumber dzero;2041uInt status=0; /* accumulator */2042#if DECCHECK2043if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;2044#endif2045
2046decNumberZero(&dzero); /* make 0 */2047dzero.exponent=rhs->exponent; /* [no coefficient expansion] */2048decAddOp(res, &dzero, rhs, set, 0, &status);2049if (status!=0) decStatus(res, status, set);2050#if DECCHECK2051decCheckInexact(res, set);2052#endif2053return res;2054} /* decNumberPlus */2055
2056/* ------------------------------------------------------------------ */
2057/* decNumberMultiply -- multiply two Numbers */
2058/* */
2059/* This computes C = A x B */
2060/* */
2061/* res is C, the result. C may be A and/or B (e.g., X=X+X) */
2062/* lhs is A */
2063/* rhs is B */
2064/* set is the context */
2065/* */
2066/* C must have space for set->digits digits. */
2067/* ------------------------------------------------------------------ */
2068decNumber * decNumberMultiply(decNumber *res, const decNumber *lhs,2069const decNumber *rhs, decContext *set) {2070uInt status=0; /* accumulator */2071decMultiplyOp(res, lhs, rhs, set, &status);2072if (status!=0) decStatus(res, status, set);2073#if DECCHECK2074decCheckInexact(res, set);2075#endif2076return res;2077} /* decNumberMultiply */2078
2079/* ------------------------------------------------------------------ */
2080/* decNumberPower -- raise a number to a power */
2081/* */
2082/* This computes C = A ** B */
2083/* */
2084/* res is C, the result. C may be A and/or B (e.g., X=X**X) */
2085/* lhs is A */
2086/* rhs is B */
2087/* set is the context */
2088/* */
2089/* C must have space for set->digits digits. */
2090/* */
2091/* Mathematical function restrictions apply (see above); a NaN is */
2092/* returned with Invalid_operation if a restriction is violated. */
2093/* */
2094/* However, if 1999999997<=B<=999999999 and B is an integer then the */
2095/* restrictions on A and the context are relaxed to the usual bounds, */
2096/* for compatibility with the earlier (integer power only) version */
2097/* of this function. */
2098/* */
2099/* When B is an integer, the result may be exact, even if rounded. */
2100/* */
2101/* The final result is rounded according to the context; it will */
2102/* almost always be correctly rounded, but may be up to 1 ulp in */
2103/* error in rare cases. */
2104/* ------------------------------------------------------------------ */
2105decNumber * decNumberPower(decNumber *res, const decNumber *lhs,2106const decNumber *rhs, decContext *set) {2107#if DECSUBSET2108decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */2109decNumber *allocrhs=NULL; /* .., rhs */2110#endif2111decNumber *allocdac=NULL; /* -> allocated acc buffer, iff used */2112decNumber *allocinv=NULL; /* -> allocated 1/x buffer, iff used */2113Int reqdigits=set->digits; /* requested DIGITS */2114Int n; /* rhs in binary */2115Flag rhsint=0; /* 1 if rhs is an integer */2116Flag useint=0; /* 1 if can use integer calculation */2117Flag isoddint=0; /* 1 if rhs is an integer and odd */2118Int i; /* work */2119#if DECSUBSET2120Int dropped; /* .. */2121#endif2122uInt needbytes; /* buffer size needed */2123Flag seenbit; /* seen a bit while powering */2124Int residue=0; /* rounding residue */2125uInt status=0; /* accumulators */2126uByte bits=0; /* result sign if errors */2127decContext aset; /* working context */2128decNumber dnOne; /* work value 1... */2129/* local accumulator buffer [a decNumber, with digits+elength+1 digits] */2130decNumber dacbuff[D2N(DECBUFFER+9)];2131decNumber *dac=dacbuff; /* -> result accumulator */2132/* same again for possible 1/lhs calculation */2133decNumber invbuff[D2N(DECBUFFER+9)];2134
2135#if DECCHECK2136if (decCheckOperands(res, lhs, rhs, set)) return res;2137#endif2138
2139do { /* protect allocated storage */2140#if DECSUBSET2141if (!set->extended) { /* reduce operands and set status, as needed */2142if (lhs->digits>reqdigits) {2143alloclhs=decRoundOperand(lhs, set, &status);2144if (alloclhs==NULL) break;2145lhs=alloclhs;2146}2147if (rhs->digits>reqdigits) {2148allocrhs=decRoundOperand(rhs, set, &status);2149if (allocrhs==NULL) break;2150rhs=allocrhs;2151}2152}2153#endif2154/* [following code does not require input rounding] */2155
2156/* handle NaNs and rhs Infinity (lhs infinity is harder) */2157if (SPECIALARGS) {2158if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) { /* NaNs */2159decNaNs(res, lhs, rhs, set, &status);2160break;}2161if (decNumberIsInfinite(rhs)) { /* rhs Infinity */2162Flag rhsneg=rhs->bits&DECNEG; /* save rhs sign */2163if (decNumberIsNegative(lhs) /* lhs<0 */2164&& !decNumberIsZero(lhs)) /* .. */2165status|=DEC_Invalid_operation;2166else { /* lhs >=0 */2167decNumberZero(&dnOne); /* set up 1 */2168dnOne.lsu[0]=1;2169decNumberCompare(dac, lhs, &dnOne, set); /* lhs ? 1 */2170decNumberZero(res); /* prepare for 0/1/Infinity */2171if (decNumberIsNegative(dac)) { /* lhs<1 */2172if (rhsneg) res->bits|=DECINF; /* +Infinity [else is +0] */2173}2174else if (dac->lsu[0]==0) { /* lhs=1 */2175/* 1**Infinity is inexact, so return fully-padded 1.0000 */2176Int shift=set->digits-1;2177*res->lsu=1; /* was 0, make int 1 */2178res->digits=decShiftToMost(res->lsu, 1, shift);2179res->exponent=-shift; /* make 1.0000... */2180status|=DEC_Inexact|DEC_Rounded; /* deemed inexact */2181}2182else { /* lhs>1 */2183if (!rhsneg) res->bits|=DECINF; /* +Infinity [else is +0] */2184}2185} /* lhs>=0 */2186break;}2187/* [lhs infinity drops through] */2188} /* specials */2189
2190/* Original rhs may be an integer that fits and is in range */2191n=decGetInt(rhs);2192if (n!=BADINT) { /* it is an integer */2193rhsint=1; /* record the fact for 1**n */2194isoddint=(Flag)n&1; /* [works even if big] */2195if (n!=BIGEVEN && n!=BIGODD) /* can use integer path? */2196useint=1; /* looks good */2197}2198
2199if (decNumberIsNegative(lhs) /* -x .. */2200&& isoddint) bits=DECNEG; /* .. to an odd power */2201
2202/* handle LHS infinity */2203if (decNumberIsInfinite(lhs)) { /* [NaNs already handled] */2204uByte rbits=rhs->bits; /* save */2205decNumberZero(res); /* prepare */2206if (n==0) *res->lsu=1; /* [-]Inf**0 => 1 */2207else {2208/* -Inf**nonint -> error */2209if (!rhsint && decNumberIsNegative(lhs)) {2210status|=DEC_Invalid_operation; /* -Inf**nonint is error */2211break;}2212if (!(rbits & DECNEG)) bits|=DECINF; /* was not a **-n */2213/* [otherwise will be 0 or -0] */2214res->bits=bits;2215}2216break;}2217
2218/* similarly handle LHS zero */2219if (decNumberIsZero(lhs)) {2220if (n==0) { /* 0**0 => Error */2221#if DECSUBSET2222if (!set->extended) { /* [unless subset] */2223decNumberZero(res);2224*res->lsu=1; /* return 1 */2225break;}2226#endif2227status|=DEC_Invalid_operation;2228}2229else { /* 0**x */2230uByte rbits=rhs->bits; /* save */2231if (rbits & DECNEG) { /* was a 0**(-n) */2232#if DECSUBSET2233if (!set->extended) { /* [bad if subset] */2234status|=DEC_Invalid_operation;2235break;}2236#endif2237bits|=DECINF;2238}2239decNumberZero(res); /* prepare */2240/* [otherwise will be 0 or -0] */2241res->bits=bits;2242}2243break;}2244
2245/* here both lhs and rhs are finite; rhs==0 is handled in the */2246/* integer path. Next handle the non-integer cases */2247if (!useint) { /* non-integral rhs */2248/* any -ve lhs is bad, as is either operand or context out of */2249/* bounds */2250if (decNumberIsNegative(lhs)) {2251status|=DEC_Invalid_operation;2252break;}2253if (decCheckMath(lhs, set, &status)2254|| decCheckMath(rhs, set, &status)) break; /* variable status */2255
2256decContextDefault(&aset, DEC_INIT_DECIMAL64); /* clean context */2257aset.emax=DEC_MAX_MATH; /* usual bounds */2258aset.emin=-DEC_MAX_MATH; /* .. */2259aset.clamp=0; /* and no concrete format */2260
2261/* calculate the result using exp(ln(lhs)*rhs), which can */2262/* all be done into the accumulator, dac. The precision needed */2263/* is enough to contain the full information in the lhs (which */2264/* is the total digits, including exponent), or the requested */2265/* precision, if larger, + 4; 6 is used for the exponent */2266/* maximum length, and this is also used when it is shorter */2267/* than the requested digits as it greatly reduces the >0.5 ulp */2268/* cases at little cost (because Ln doubles digits each */2269/* iteration so a few extra digits rarely causes an extra */2270/* iteration) */2271aset.digits=MAXI(lhs->digits, set->digits)+6+4;2272} /* non-integer rhs */2273
2274else { /* rhs is in-range integer */2275if (n==0) { /* x**0 = 1 */2276/* (0**0 was handled above) */2277decNumberZero(res); /* result=1 */2278*res->lsu=1; /* .. */2279break;}2280/* rhs is a non-zero integer */2281if (n<0) n=-n; /* use abs(n) */2282
2283aset=*set; /* clone the context */2284aset.round=DEC_ROUND_HALF_EVEN; /* internally use balanced */2285/* calculate the working DIGITS */2286aset.digits=reqdigits+(rhs->digits+rhs->exponent)+2;2287#if DECSUBSET2288if (!set->extended) aset.digits--; /* use classic precision */2289#endif2290/* it's an error if this is more than can be handled */2291if (aset.digits>DECNUMMAXP) {status|=DEC_Invalid_operation; break;}2292} /* integer path */2293
2294/* aset.digits is the count of digits for the accumulator needed */2295/* if accumulator is too long for local storage, then allocate */2296needbytes=sizeof(decNumber)+(D2U(aset.digits)-1)*sizeof(Unit);2297/* [needbytes also used below if 1/lhs needed] */2298if (needbytes>sizeof(dacbuff)) {2299allocdac=(decNumber *)malloc(needbytes);2300if (allocdac==NULL) { /* hopeless -- abandon */2301status|=DEC_Insufficient_storage;2302break;}2303dac=allocdac; /* use the allocated space */2304}2305/* here, aset is set up and accumulator is ready for use */2306
2307if (!useint) { /* non-integral rhs */2308/* x ** y; special-case x=1 here as it will otherwise always */2309/* reduce to integer 1; decLnOp has a fastpath which detects */2310/* the case of x=1 */2311decLnOp(dac, lhs, &aset, &status); /* dac=ln(lhs) */2312/* [no error possible, as lhs 0 already handled] */2313if (ISZERO(dac)) { /* x==1, 1.0, etc. */2314/* need to return fully-padded 1.0000 etc., but rhsint->1 */2315*dac->lsu=1; /* was 0, make int 1 */2316if (!rhsint) { /* add padding */2317Int shift=set->digits-1;2318dac->digits=decShiftToMost(dac->lsu, 1, shift);2319dac->exponent=-shift; /* make 1.0000... */2320status|=DEC_Inexact|DEC_Rounded; /* deemed inexact */2321}2322}2323else {2324decMultiplyOp(dac, dac, rhs, &aset, &status); /* dac=dac*rhs */2325decExpOp(dac, dac, &aset, &status); /* dac=exp(dac) */2326}2327/* and drop through for final rounding */2328} /* non-integer rhs */2329
2330else { /* carry on with integer */2331decNumberZero(dac); /* acc=1 */2332*dac->lsu=1; /* .. */2333
2334/* if a negative power the constant 1 is needed, and if not subset */2335/* invert the lhs now rather than inverting the result later */2336if (decNumberIsNegative(rhs)) { /* was a **-n [hence digits>0] */2337decNumber *inv=invbuff; /* assume use fixed buffer */2338decNumberCopy(&dnOne, dac); /* dnOne=1; [needed now or later] */2339#if DECSUBSET2340if (set->extended) { /* need to calculate 1/lhs */2341#endif2342/* divide lhs into 1, putting result in dac [dac=1/dac] */2343decDivideOp(dac, &dnOne, lhs, &aset, DIVIDE, &status);2344/* now locate or allocate space for the inverted lhs */2345if (needbytes>sizeof(invbuff)) {2346allocinv=(decNumber *)malloc(needbytes);2347if (allocinv==NULL) { /* hopeless -- abandon */2348status|=DEC_Insufficient_storage;2349break;}2350inv=allocinv; /* use the allocated space */2351}2352/* [inv now points to big-enough buffer or allocated storage] */2353decNumberCopy(inv, dac); /* copy the 1/lhs */2354decNumberCopy(dac, &dnOne); /* restore acc=1 */2355lhs=inv; /* .. and go forward with new lhs */2356#if DECSUBSET2357}2358#endif2359}2360
2361/* Raise-to-the-power loop... */2362seenbit=0; /* set once a 1-bit is encountered */2363for (i=1;;i++){ /* for each bit [top bit ignored] */2364/* abandon if had overflow or terminal underflow */2365if (status & (DEC_Overflow|DEC_Underflow)) { /* interesting? */2366if (status&DEC_Overflow || ISZERO(dac)) break;2367}2368/* [the following two lines revealed an optimizer bug in a C++ */2369/* compiler, with symptom: 5**3 -> 25, when n=n+n was used] */2370n=n<<1; /* move next bit to testable position */2371if (n<0) { /* top bit is set */2372seenbit=1; /* OK, significant bit seen */2373decMultiplyOp(dac, dac, lhs, &aset, &status); /* dac=dac*x */2374}2375if (i==31) break; /* that was the last bit */2376if (!seenbit) continue; /* no need to square 1 */2377decMultiplyOp(dac, dac, dac, &aset, &status); /* dac=dac*dac [square] */2378} /*i*/ /* 32 bits */2379
2380/* complete internal overflow or underflow processing */2381if (status & (DEC_Overflow|DEC_Underflow)) {2382#if DECSUBSET2383/* If subset, and power was negative, reverse the kind of -erflow */2384/* [1/x not yet done] */2385if (!set->extended && decNumberIsNegative(rhs)) {2386if (status & DEC_Overflow)2387status^=DEC_Overflow | DEC_Underflow | DEC_Subnormal;2388else { /* trickier -- Underflow may or may not be set */2389status&=~(DEC_Underflow | DEC_Subnormal); /* [one or both] */2390status|=DEC_Overflow;2391}2392}2393#endif2394dac->bits=(dac->bits & ~DECNEG) | bits; /* force correct sign */2395/* round subnormals [to set.digits rather than aset.digits] */2396/* or set overflow result similarly as required */2397decFinalize(dac, set, &residue, &status);2398decNumberCopy(res, dac); /* copy to result (is now OK length) */2399break;2400}2401
2402#if DECSUBSET2403if (!set->extended && /* subset math */2404decNumberIsNegative(rhs)) { /* was a **-n [hence digits>0] */2405/* so divide result into 1 [dac=1/dac] */2406decDivideOp(dac, &dnOne, dac, &aset, DIVIDE, &status);2407}2408#endif2409} /* rhs integer path */2410
2411/* reduce result to the requested length and copy to result */2412decCopyFit(res, dac, set, &residue, &status);2413decFinish(res, set, &residue, &status); /* final cleanup */2414#if DECSUBSET2415if (!set->extended) decTrim(res, set, 0, &dropped); /* trailing zeros */2416#endif2417} while(0); /* end protected */2418
2419if (allocdac!=NULL) free(allocdac); /* drop any storage used */2420if (allocinv!=NULL) free(allocinv); /* .. */2421#if DECSUBSET2422if (alloclhs!=NULL) free(alloclhs); /* .. */2423if (allocrhs!=NULL) free(allocrhs); /* .. */2424#endif2425if (status!=0) decStatus(res, status, set);2426#if DECCHECK2427decCheckInexact(res, set);2428#endif2429return res;2430} /* decNumberPower */2431
2432/* ------------------------------------------------------------------ */
2433/* decNumberQuantize -- force exponent to requested value */
2434/* */
2435/* This computes C = op(A, B), where op adjusts the coefficient */
2436/* of C (by rounding or shifting) such that the exponent (-scale) */
2437/* of C has exponent of B. The numerical value of C will equal A, */
2438/* except for the effects of any rounding that occurred. */
2439/* */
2440/* res is C, the result. C may be A or B */
2441/* lhs is A, the number to adjust */
2442/* rhs is B, the number with exponent to match */
2443/* set is the context */
2444/* */
2445/* C must have space for set->digits digits. */
2446/* */
2447/* Unless there is an error or the result is infinite, the exponent */
2448/* after the operation is guaranteed to be equal to that of B. */
2449/* ------------------------------------------------------------------ */
2450decNumber * decNumberQuantize(decNumber *res, const decNumber *lhs,2451const decNumber *rhs, decContext *set) {2452uInt status=0; /* accumulator */2453decQuantizeOp(res, lhs, rhs, set, 1, &status);2454if (status!=0) decStatus(res, status, set);2455return res;2456} /* decNumberQuantize */2457
2458/* ------------------------------------------------------------------ */
2459/* decNumberReduce -- remove trailing zeros */
2460/* */
2461/* This computes C = 0 + A, and normalizes the result */
2462/* */
2463/* res is C, the result. C may be A */
2464/* rhs is A */
2465/* set is the context */
2466/* */
2467/* C must have space for set->digits digits. */
2468/* ------------------------------------------------------------------ */
2469/* Previously known as Normalize */
2470decNumber * decNumberNormalize(decNumber *res, const decNumber *rhs,2471decContext *set) {2472return decNumberReduce(res, rhs, set);2473} /* decNumberNormalize */2474
2475decNumber * decNumberReduce(decNumber *res, const decNumber *rhs,2476decContext *set) {2477#if DECSUBSET2478decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */2479#endif2480uInt status=0; /* as usual */2481Int residue=0; /* as usual */2482Int dropped; /* work */2483
2484#if DECCHECK2485if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;2486#endif2487
2488do { /* protect allocated storage */2489#if DECSUBSET2490if (!set->extended) {2491/* reduce operand and set lostDigits status, as needed */2492if (rhs->digits>set->digits) {2493allocrhs=decRoundOperand(rhs, set, &status);2494if (allocrhs==NULL) break;2495rhs=allocrhs;2496}2497}2498#endif2499/* [following code does not require input rounding] */2500
2501/* Infinities copy through; NaNs need usual treatment */2502if (decNumberIsNaN(rhs)) {2503decNaNs(res, rhs, NULL, set, &status);2504break;2505}2506
2507/* reduce result to the requested length and copy to result */2508decCopyFit(res, rhs, set, &residue, &status); /* copy & round */2509decFinish(res, set, &residue, &status); /* cleanup/set flags */2510decTrim(res, set, 1, &dropped); /* normalize in place */2511} while(0); /* end protected */2512
2513#if DECSUBSET2514if (allocrhs !=NULL) free(allocrhs); /* .. */2515#endif2516if (status!=0) decStatus(res, status, set);/* then report status */2517return res;2518} /* decNumberReduce */2519
2520/* ------------------------------------------------------------------ */
2521/* decNumberRescale -- force exponent to requested value */
2522/* */
2523/* This computes C = op(A, B), where op adjusts the coefficient */
2524/* of C (by rounding or shifting) such that the exponent (-scale) */
2525/* of C has the value B. The numerical value of C will equal A, */
2526/* except for the effects of any rounding that occurred. */
2527/* */
2528/* res is C, the result. C may be A or B */
2529/* lhs is A, the number to adjust */
2530/* rhs is B, the requested exponent */
2531/* set is the context */
2532/* */
2533/* C must have space for set->digits digits. */
2534/* */
2535/* Unless there is an error or the result is infinite, the exponent */
2536/* after the operation is guaranteed to be equal to B. */
2537/* ------------------------------------------------------------------ */
2538decNumber * decNumberRescale(decNumber *res, const decNumber *lhs,2539const decNumber *rhs, decContext *set) {2540uInt status=0; /* accumulator */2541decQuantizeOp(res, lhs, rhs, set, 0, &status);2542if (status!=0) decStatus(res, status, set);2543return res;2544} /* decNumberRescale */2545
2546/* ------------------------------------------------------------------ */
2547/* decNumberRemainder -- divide and return remainder */
2548/* */
2549/* This computes C = A % B */
2550/* */
2551/* res is C, the result. C may be A and/or B (e.g., X=X%X) */
2552/* lhs is A */
2553/* rhs is B */
2554/* set is the context */
2555/* */
2556/* C must have space for set->digits digits. */
2557/* ------------------------------------------------------------------ */
2558decNumber * decNumberRemainder(decNumber *res, const decNumber *lhs,2559const decNumber *rhs, decContext *set) {2560uInt status=0; /* accumulator */2561decDivideOp(res, lhs, rhs, set, REMAINDER, &status);2562if (status!=0) decStatus(res, status, set);2563#if DECCHECK2564decCheckInexact(res, set);2565#endif2566return res;2567} /* decNumberRemainder */2568
2569/* ------------------------------------------------------------------ */
2570/* decNumberRemainderNear -- divide and return remainder from nearest */
2571/* */
2572/* This computes C = A % B, where % is the IEEE remainder operator */
2573/* */
2574/* res is C, the result. C may be A and/or B (e.g., X=X%X) */
2575/* lhs is A */
2576/* rhs is B */
2577/* set is the context */
2578/* */
2579/* C must have space for set->digits digits. */
2580/* ------------------------------------------------------------------ */
2581decNumber * decNumberRemainderNear(decNumber *res, const decNumber *lhs,2582const decNumber *rhs, decContext *set) {2583uInt status=0; /* accumulator */2584decDivideOp(res, lhs, rhs, set, REMNEAR, &status);2585if (status!=0) decStatus(res, status, set);2586#if DECCHECK2587decCheckInexact(res, set);2588#endif2589return res;2590} /* decNumberRemainderNear */2591
2592/* ------------------------------------------------------------------ */
2593/* decNumberRotate -- rotate the coefficient of a Number left/right */
2594/* */
2595/* This computes C = A rot B (in base ten and rotating set->digits */
2596/* digits). */
2597/* */
2598/* res is C, the result. C may be A and/or B (e.g., X=XrotX) */
2599/* lhs is A */
2600/* rhs is B, the number of digits to rotate (-ve to right) */
2601/* set is the context */
2602/* */
2603/* The digits of the coefficient of A are rotated to the left (if B */
2604/* is positive) or to the right (if B is negative) without adjusting */
2605/* the exponent or the sign of A. If lhs->digits is less than */
2606/* set->digits the coefficient is padded with zeros on the left */
2607/* before the rotate. Any leading zeros in the result are removed */
2608/* as usual. */
2609/* */
2610/* B must be an integer (q=0) and in the range -set->digits through */
2611/* +set->digits. */
2612/* C must have space for set->digits digits. */
2613/* NaNs are propagated as usual. Infinities are unaffected (but */
2614/* B must be valid). No status is set unless B is invalid or an */
2615/* operand is an sNaN. */
2616/* ------------------------------------------------------------------ */
2617decNumber * decNumberRotate(decNumber *res, const decNumber *lhs,2618const decNumber *rhs, decContext *set) {2619uInt status=0; /* accumulator */2620Int rotate; /* rhs as an Int */2621
2622#if DECCHECK2623if (decCheckOperands(res, lhs, rhs, set)) return res;2624#endif2625
2626/* NaNs propagate as normal */2627if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))2628decNaNs(res, lhs, rhs, set, &status);2629/* rhs must be an integer */2630else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)2631status=DEC_Invalid_operation;2632else { /* both numeric, rhs is an integer */2633rotate=decGetInt(rhs); /* [cannot fail] */2634if (rotate==BADINT /* something bad .. */2635|| rotate==BIGODD || rotate==BIGEVEN /* .. very big .. */2636|| abs(rotate)>set->digits) /* .. or out of range */2637status=DEC_Invalid_operation;2638else { /* rhs is OK */2639decNumberCopy(res, lhs);2640/* convert -ve rotate to equivalent positive rotation */2641if (rotate<0) rotate=set->digits+rotate;2642if (rotate!=0 && rotate!=set->digits /* zero or full rotation */2643&& !decNumberIsInfinite(res)) { /* lhs was infinite */2644/* left-rotate to do; 0 < rotate < set->digits */2645uInt units, shift; /* work */2646uInt msudigits; /* digits in result msu */2647Unit *msu=res->lsu+D2U(res->digits)-1; /* current msu */2648Unit *msumax=res->lsu+D2U(set->digits)-1; /* rotation msu */2649for (msu++; msu<=msumax; msu++) *msu=0; /* ensure high units=0 */2650res->digits=set->digits; /* now full-length */2651msudigits=MSUDIGITS(res->digits); /* actual digits in msu */2652
2653/* rotation here is done in-place, in three steps */2654/* 1. shift all to least up to one unit to unit-align final */2655/* lsd [any digits shifted out are rotated to the left, */2656/* abutted to the original msd (which may require split)] */2657/* */2658/* [if there are no whole units left to rotate, the */2659/* rotation is now complete] */2660/* */2661/* 2. shift to least, from below the split point only, so that */2662/* the final msd is in the right place in its Unit [any */2663/* digits shifted out will fit exactly in the current msu, */2664/* left aligned, no split required] */2665/* */2666/* 3. rotate all the units by reversing left part, right */2667/* part, and then whole */2668/* */2669/* example: rotate right 8 digits (2 units + 2), DECDPUN=3. */2670/* */2671/* start: 00a bcd efg hij klm npq */2672/* */2673/* 1a 000 0ab cde fgh|ijk lmn [pq saved] */2674/* 1b 00p qab cde fgh|ijk lmn */2675/* */2676/* 2a 00p qab cde fgh|00i jkl [mn saved] */2677/* 2b mnp qab cde fgh|00i jkl */2678/* */2679/* 3a fgh cde qab mnp|00i jkl */2680/* 3b fgh cde qab mnp|jkl 00i */2681/* 3c 00i jkl mnp qab cde fgh */2682
2683/* Step 1: amount to shift is the partial right-rotate count */2684rotate=set->digits-rotate; /* make it right-rotate */2685units=rotate/DECDPUN; /* whole units to rotate */2686shift=rotate%DECDPUN; /* left-over digits count */2687if (shift>0) { /* not an exact number of units */2688uInt save=res->lsu[0]%powers[shift]; /* save low digit(s) */2689decShiftToLeast(res->lsu, D2U(res->digits), shift);2690if (shift>msudigits) { /* msumax-1 needs >0 digits */2691uInt rem=save%powers[shift-msudigits];/* split save */2692*msumax=(Unit)(save/powers[shift-msudigits]); /* and insert */2693*(msumax-1)=*(msumax-1)2694+(Unit)(rem*powers[DECDPUN-(shift-msudigits)]); /* .. */2695}2696else { /* all fits in msumax */2697*msumax=*msumax+(Unit)(save*powers[msudigits-shift]); /* [maybe *1] */2698}2699} /* digits shift needed */2700
2701/* If whole units to rotate... */2702if (units>0) { /* some to do */2703/* Step 2: the units to touch are the whole ones in rotate, */2704/* if any, and the shift is DECDPUN-msudigits (which may be */2705/* 0, again) */2706shift=DECDPUN-msudigits;2707if (shift>0) { /* not an exact number of units */2708uInt save=res->lsu[0]%powers[shift]; /* save low digit(s) */2709decShiftToLeast(res->lsu, units, shift);2710*msumax=*msumax+(Unit)(save*powers[msudigits]);2711} /* partial shift needed */2712
2713/* Step 3: rotate the units array using triple reverse */2714/* (reversing is easy and fast) */2715decReverse(res->lsu+units, msumax); /* left part */2716decReverse(res->lsu, res->lsu+units-1); /* right part */2717decReverse(res->lsu, msumax); /* whole */2718} /* whole units to rotate */2719/* the rotation may have left an undetermined number of zeros */2720/* on the left, so true length needs to be calculated */2721res->digits=decGetDigits(res->lsu, msumax-res->lsu+1);2722} /* rotate needed */2723} /* rhs OK */2724} /* numerics */2725if (status!=0) decStatus(res, status, set);2726return res;2727} /* decNumberRotate */2728
2729/* ------------------------------------------------------------------ */
2730/* decNumberSameQuantum -- test for equal exponents */
2731/* */
2732/* res is the result number, which will contain either 0 or 1 */
2733/* lhs is a number to test */
2734/* rhs is the second (usually a pattern) */
2735/* */
2736/* No errors are possible and no context is needed. */
2737/* ------------------------------------------------------------------ */
2738decNumber * decNumberSameQuantum(decNumber *res, const decNumber *lhs,2739const decNumber *rhs) {2740Unit ret=0; /* return value */2741
2742#if DECCHECK2743if (decCheckOperands(res, lhs, rhs, DECUNCONT)) return res;2744#endif2745
2746if (SPECIALARGS) {2747if (decNumberIsNaN(lhs) && decNumberIsNaN(rhs)) ret=1;2748else if (decNumberIsInfinite(lhs) && decNumberIsInfinite(rhs)) ret=1;2749/* [anything else with a special gives 0] */2750}2751else if (lhs->exponent==rhs->exponent) ret=1;2752
2753decNumberZero(res); /* OK to overwrite an operand now */2754*res->lsu=ret;2755return res;2756} /* decNumberSameQuantum */2757
2758/* ------------------------------------------------------------------ */
2759/* decNumberScaleB -- multiply by a power of 10 */
2760/* */
2761/* This computes C = A x 10**B where B is an integer (q=0) with */
2762/* maximum magnitude 2*(emax+digits) */
2763/* */
2764/* res is C, the result. C may be A or B */
2765/* lhs is A, the number to adjust */
2766/* rhs is B, the requested power of ten to use */
2767/* set is the context */
2768/* */
2769/* C must have space for set->digits digits. */
2770/* */
2771/* The result may underflow or overflow. */
2772/* ------------------------------------------------------------------ */
2773decNumber * decNumberScaleB(decNumber *res, const decNumber *lhs,2774const decNumber *rhs, decContext *set) {2775Int reqexp; /* requested exponent change [B] */2776uInt status=0; /* accumulator */2777Int residue; /* work */2778
2779#if DECCHECK2780if (decCheckOperands(res, lhs, rhs, set)) return res;2781#endif2782
2783/* Handle special values except lhs infinite */2784if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))2785decNaNs(res, lhs, rhs, set, &status);2786/* rhs must be an integer */2787else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)2788status=DEC_Invalid_operation;2789else {2790/* lhs is a number; rhs is a finite with q==0 */2791reqexp=decGetInt(rhs); /* [cannot fail] */2792if (reqexp==BADINT /* something bad .. */2793|| reqexp==BIGODD || reqexp==BIGEVEN /* .. very big .. */2794|| abs(reqexp)>(2*(set->digits+set->emax))) /* .. or out of range */2795status=DEC_Invalid_operation;2796else { /* rhs is OK */2797decNumberCopy(res, lhs); /* all done if infinite lhs */2798if (!decNumberIsInfinite(res)) { /* prepare to scale */2799res->exponent+=reqexp; /* adjust the exponent */2800residue=0;2801decFinalize(res, set, &residue, &status); /* .. and check */2802} /* finite LHS */2803} /* rhs OK */2804} /* rhs finite */2805if (status!=0) decStatus(res, status, set);2806return res;2807} /* decNumberScaleB */2808
2809/* ------------------------------------------------------------------ */
2810/* decNumberShift -- shift the coefficient of a Number left or right */
2811/* */
2812/* This computes C = A << B or C = A >> -B (in base ten). */
2813/* */
2814/* res is C, the result. C may be A and/or B (e.g., X=X<<X) */
2815/* lhs is A */
2816/* rhs is B, the number of digits to shift (-ve to right) */
2817/* set is the context */
2818/* */
2819/* The digits of the coefficient of A are shifted to the left (if B */
2820/* is positive) or to the right (if B is negative) without adjusting */
2821/* the exponent or the sign of A. */
2822/* */
2823/* B must be an integer (q=0) and in the range -set->digits through */
2824/* +set->digits. */
2825/* C must have space for set->digits digits. */
2826/* NaNs are propagated as usual. Infinities are unaffected (but */
2827/* B must be valid). No status is set unless B is invalid or an */
2828/* operand is an sNaN. */
2829/* ------------------------------------------------------------------ */
2830decNumber * decNumberShift(decNumber *res, const decNumber *lhs,2831const decNumber *rhs, decContext *set) {2832uInt status=0; /* accumulator */2833Int shift; /* rhs as an Int */2834
2835#if DECCHECK2836if (decCheckOperands(res, lhs, rhs, set)) return res;2837#endif2838
2839/* NaNs propagate as normal */2840if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))2841decNaNs(res, lhs, rhs, set, &status);2842/* rhs must be an integer */2843else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)2844status=DEC_Invalid_operation;2845else { /* both numeric, rhs is an integer */2846shift=decGetInt(rhs); /* [cannot fail] */2847if (shift==BADINT /* something bad .. */2848|| shift==BIGODD || shift==BIGEVEN /* .. very big .. */2849|| abs(shift)>set->digits) /* .. or out of range */2850status=DEC_Invalid_operation;2851else { /* rhs is OK */2852decNumberCopy(res, lhs);2853if (shift!=0 && !decNumberIsInfinite(res)) { /* something to do */2854if (shift>0) { /* to left */2855if (shift==set->digits) { /* removing all */2856*res->lsu=0; /* so place 0 */2857res->digits=1; /* .. */2858}2859else { /* */2860/* first remove leading digits if necessary */2861if (res->digits+shift>set->digits) {2862decDecap(res, res->digits+shift-set->digits);2863/* that updated res->digits; may have gone to 1 (for a */2864/* single digit or for zero */2865}2866if (res->digits>1 || *res->lsu) /* if non-zero.. */2867res->digits=decShiftToMost(res->lsu, res->digits, shift);2868} /* partial left */2869} /* left */2870else { /* to right */2871if (-shift>=res->digits) { /* discarding all */2872*res->lsu=0; /* so place 0 */2873res->digits=1; /* .. */2874}2875else {2876decShiftToLeast(res->lsu, D2U(res->digits), -shift);2877res->digits-=(-shift);2878}2879} /* to right */2880} /* non-0 non-Inf shift */2881} /* rhs OK */2882} /* numerics */2883if (status!=0) decStatus(res, status, set);2884return res;2885} /* decNumberShift */2886
2887/* ------------------------------------------------------------------ */
2888/* decNumberSquareRoot -- square root operator */
2889/* */
2890/* This computes C = squareroot(A) */
2891/* */
2892/* res is C, the result. C may be A */
2893/* rhs is A */
2894/* set is the context; note that rounding mode has no effect */
2895/* */
2896/* C must have space for set->digits digits. */
2897/* ------------------------------------------------------------------ */
2898/* This uses the following varying-precision algorithm in: */
2899/* */
2900/* Properly Rounded Variable Precision Square Root, T. E. Hull and */
2901/* A. Abrham, ACM Transactions on Mathematical Software, Vol 11 #3, */
2902/* pp229-237, ACM, September 1985. */
2903/* */
2904/* The square-root is calculated using Newton's method, after which */
2905/* a check is made to ensure the result is correctly rounded. */
2906/* */
2907/* % [Reformatted original Numerical Turing source code follows.] */
2908/* function sqrt(x : real) : real */
2909/* % sqrt(x) returns the properly rounded approximation to the square */
2910/* % root of x, in the precision of the calling environment, or it */
2911/* % fails if x < 0. */
2912/* % t e hull and a abrham, august, 1984 */
2913/* if x <= 0 then */
2914/* if x < 0 then */
2915/* assert false */
2916/* else */
2917/* result 0 */
2918/* end if */
2919/* end if */
2920/* var f := setexp(x, 0) % fraction part of x [0.1 <= x < 1] */
2921/* var e := getexp(x) % exponent part of x */
2922/* var approx : real */
2923/* if e mod 2 = 0 then */
2924/* approx := .259 + .819 * f % approx to root of f */
2925/* else */
2926/* f := f/l0 % adjustments */
2927/* e := e + 1 % for odd */
2928/* approx := .0819 + 2.59 * f % exponent */
2929/* end if */
2930/* */
2931/* var p:= 3 */
2932/* const maxp := currentprecision + 2 */
2933/* loop */
2934/* p := min(2*p - 2, maxp) % p = 4,6,10, . . . , maxp */
2935/* precision p */
2936/* approx := .5 * (approx + f/approx) */
2937/* exit when p = maxp */
2938/* end loop */
2939/* */
2940/* % approx is now within 1 ulp of the properly rounded square root */
2941/* % of f; to ensure proper rounding, compare squares of (approx - */
2942/* % l/2 ulp) and (approx + l/2 ulp) with f. */
2943/* p := currentprecision */
2944/* begin */
2945/* precision p + 2 */
2946/* const approxsubhalf := approx - setexp(.5, -p) */
2947/* if mulru(approxsubhalf, approxsubhalf) > f then */
2948/* approx := approx - setexp(.l, -p + 1) */
2949/* else */
2950/* const approxaddhalf := approx + setexp(.5, -p) */
2951/* if mulrd(approxaddhalf, approxaddhalf) < f then */
2952/* approx := approx + setexp(.l, -p + 1) */
2953/* end if */
2954/* end if */
2955/* end */
2956/* result setexp(approx, e div 2) % fix exponent */
2957/* end sqrt */
2958/* ------------------------------------------------------------------ */
2959decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,2960decContext *set) {2961decContext workset, approxset; /* work contexts */2962decNumber dzero; /* used for constant zero */2963Int maxp; /* largest working precision */2964Int workp; /* working precision */2965Int residue=0; /* rounding residue */2966uInt status=0, ignore=0; /* status accumulators */2967uInt rstatus; /* .. */2968Int exp; /* working exponent */2969Int ideal; /* ideal (preferred) exponent */2970Int needbytes; /* work */2971Int dropped; /* .. */2972
2973#if DECSUBSET2974decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */2975#endif2976/* buffer for f [needs +1 in case DECBUFFER 0] */2977decNumber buff[D2N(DECBUFFER+1)];2978/* buffer for a [needs +2 to match likely maxp] */2979decNumber bufa[D2N(DECBUFFER+2)];2980/* buffer for temporary, b [must be same size as a] */2981decNumber bufb[D2N(DECBUFFER+2)];2982decNumber *allocbuff=NULL; /* -> allocated buff, iff allocated */2983decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */2984decNumber *allocbufb=NULL; /* -> allocated bufb, iff allocated */2985decNumber *f=buff; /* reduced fraction */2986decNumber *a=bufa; /* approximation to result */2987decNumber *b=bufb; /* intermediate result */2988/* buffer for temporary variable, up to 3 digits */2989decNumber buft[D2N(3)];2990decNumber *t=buft; /* up-to-3-digit constant or work */2991
2992#if DECCHECK2993if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;2994#endif2995
2996do { /* protect allocated storage */2997#if DECSUBSET2998if (!set->extended) {2999/* reduce operand and set lostDigits status, as needed */3000if (rhs->digits>set->digits) {3001allocrhs=decRoundOperand(rhs, set, &status);3002if (allocrhs==NULL) break;3003/* [Note: 'f' allocation below could reuse this buffer if */3004/* used, but as this is rare they are kept separate for clarity.] */3005rhs=allocrhs;3006}3007}3008#endif3009/* [following code does not require input rounding] */3010
3011/* handle infinities and NaNs */3012if (SPECIALARG) {3013if (decNumberIsInfinite(rhs)) { /* an infinity */3014if (decNumberIsNegative(rhs)) status|=DEC_Invalid_operation;3015else decNumberCopy(res, rhs); /* +Infinity */3016}3017else decNaNs(res, rhs, NULL, set, &status); /* a NaN */3018break;3019}3020
3021/* calculate the ideal (preferred) exponent [floor(exp/2)] */3022/* [We would like to write: ideal=rhs->exponent>>1, but this */3023/* generates a compiler warning. Generated code is the same.] */3024ideal=(rhs->exponent&~1)/2; /* target */3025
3026/* handle zeros */3027if (ISZERO(rhs)) {3028decNumberCopy(res, rhs); /* could be 0 or -0 */3029res->exponent=ideal; /* use the ideal [safe] */3030/* use decFinish to clamp any out-of-range exponent, etc. */3031decFinish(res, set, &residue, &status);3032break;3033}3034
3035/* any other -x is an oops */3036if (decNumberIsNegative(rhs)) {3037status|=DEC_Invalid_operation;3038break;3039}3040
3041/* space is needed for three working variables */3042/* f -- the same precision as the RHS, reduced to 0.01->0.99... */3043/* a -- Hull's approximation -- precision, when assigned, is */3044/* currentprecision+1 or the input argument precision, */3045/* whichever is larger (+2 for use as temporary) */3046/* b -- intermediate temporary result (same size as a) */3047/* if any is too long for local storage, then allocate */3048workp=MAXI(set->digits+1, rhs->digits); /* actual rounding precision */3049maxp=workp+2; /* largest working precision */3050
3051needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);3052if (needbytes>(Int)sizeof(buff)) {3053allocbuff=(decNumber *)malloc(needbytes);3054if (allocbuff==NULL) { /* hopeless -- abandon */3055status|=DEC_Insufficient_storage;3056break;}3057f=allocbuff; /* use the allocated space */3058}3059/* a and b both need to be able to hold a maxp-length number */3060needbytes=sizeof(decNumber)+(D2U(maxp)-1)*sizeof(Unit);3061if (needbytes>(Int)sizeof(bufa)) { /* [same applies to b] */3062allocbufa=(decNumber *)malloc(needbytes);3063allocbufb=(decNumber *)malloc(needbytes);3064if (allocbufa==NULL || allocbufb==NULL) { /* hopeless */3065status|=DEC_Insufficient_storage;3066break;}3067a=allocbufa; /* use the allocated spaces */3068b=allocbufb; /* .. */3069}3070
3071/* copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1 */3072decNumberCopy(f, rhs);3073exp=f->exponent+f->digits; /* adjusted to Hull rules */3074f->exponent=-(f->digits); /* to range */3075
3076/* set up working context */3077decContextDefault(&workset, DEC_INIT_DECIMAL64);3078
3079/* [Until further notice, no error is possible and status bits */3080/* (Rounded, etc.) should be ignored, not accumulated.] */3081
3082/* Calculate initial approximation, and allow for odd exponent */3083workset.digits=workp; /* p for initial calculation */3084t->bits=0; t->digits=3;3085a->bits=0; a->digits=3;3086if ((exp & 1)==0) { /* even exponent */3087/* Set t=0.259, a=0.819 */3088t->exponent=-3;3089a->exponent=-3;3090#if DECDPUN>=33091t->lsu[0]=259;3092a->lsu[0]=819;3093#elif DECDPUN==23094t->lsu[0]=59; t->lsu[1]=2;3095a->lsu[0]=19; a->lsu[1]=8;3096#else3097t->lsu[0]=9; t->lsu[1]=5; t->lsu[2]=2;3098a->lsu[0]=9; a->lsu[1]=1; a->lsu[2]=8;3099#endif3100}3101else { /* odd exponent */3102/* Set t=0.0819, a=2.59 */3103f->exponent--; /* f=f/10 */3104exp++; /* e=e+1 */3105t->exponent=-4;3106a->exponent=-2;3107#if DECDPUN>=33108t->lsu[0]=819;3109a->lsu[0]=259;3110#elif DECDPUN==23111t->lsu[0]=19; t->lsu[1]=8;3112a->lsu[0]=59; a->lsu[1]=2;3113#else3114t->lsu[0]=9; t->lsu[1]=1; t->lsu[2]=8;3115a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;3116#endif3117}3118decMultiplyOp(a, a, f, &workset, &ignore); /* a=a*f */3119decAddOp(a, a, t, &workset, 0, &ignore); /* ..+t */3120/* [a is now the initial approximation for sqrt(f), calculated with */3121/* currentprecision, which is also a's precision.] */3122
3123/* the main calculation loop */3124decNumberZero(&dzero); /* make 0 */3125decNumberZero(t); /* set t = 0.5 */3126t->lsu[0]=5; /* .. */3127t->exponent=-1; /* .. */3128workset.digits=3; /* initial p */3129for (;;) {3130/* set p to min(2*p - 2, maxp) [hence 3; or: 4, 6, 10, ... , maxp] */3131workset.digits=workset.digits*2-2;3132if (workset.digits>maxp) workset.digits=maxp;3133/* a = 0.5 * (a + f/a) */3134/* [calculated at p then rounded to currentprecision] */3135decDivideOp(b, f, a, &workset, DIVIDE, &ignore); /* b=f/a */3136decAddOp(b, b, a, &workset, 0, &ignore); /* b=b+a */3137decMultiplyOp(a, b, t, &workset, &ignore); /* a=b*0.5 */3138if (a->digits==maxp) break; /* have required digits */3139} /* loop */3140
3141/* Here, 0.1 <= a < 1 [Hull], and a has maxp digits */3142/* now reduce to length, etc.; this needs to be done with a */3143/* having the correct exponent so as to handle subnormals */3144/* correctly */3145approxset=*set; /* get emin, emax, etc. */3146approxset.round=DEC_ROUND_HALF_EVEN;3147a->exponent+=exp/2; /* set correct exponent */3148
3149rstatus=0; /* clear status */3150residue=0; /* .. and accumulator */3151decCopyFit(a, a, &approxset, &residue, &rstatus); /* reduce (if needed) */3152decFinish(a, &approxset, &residue, &rstatus); /* clean and finalize */3153
3154/* Overflow was possible if the input exponent was out-of-range, */3155/* in which case quit */3156if (rstatus&DEC_Overflow) {3157status=rstatus; /* use the status as-is */3158decNumberCopy(res, a); /* copy to result */3159break;3160}3161
3162/* Preserve status except Inexact/Rounded */3163status|=(rstatus & ~(DEC_Rounded|DEC_Inexact));3164
3165/* Carry out the Hull correction */3166a->exponent-=exp/2; /* back to 0.1->1 */3167
3168/* a is now at final precision and within 1 ulp of the properly */3169/* rounded square root of f; to ensure proper rounding, compare */3170/* squares of (a - l/2 ulp) and (a + l/2 ulp) with f. */3171/* Here workset.digits=maxp and t=0.5, and a->digits determines */3172/* the ulp */3173workset.digits--; /* maxp-1 is OK now */3174t->exponent=-a->digits-1; /* make 0.5 ulp */3175decAddOp(b, a, t, &workset, DECNEG, &ignore); /* b = a - 0.5 ulp */3176workset.round=DEC_ROUND_UP;3177decMultiplyOp(b, b, b, &workset, &ignore); /* b = mulru(b, b) */3178decCompareOp(b, f, b, &workset, COMPARE, &ignore); /* b ? f, reversed */3179if (decNumberIsNegative(b)) { /* f < b [i.e., b > f] */3180/* this is the more common adjustment, though both are rare */3181t->exponent++; /* make 1.0 ulp */3182t->lsu[0]=1; /* .. */3183decAddOp(a, a, t, &workset, DECNEG, &ignore); /* a = a - 1 ulp */3184/* assign to approx [round to length] */3185approxset.emin-=exp/2; /* adjust to match a */3186approxset.emax-=exp/2;3187decAddOp(a, &dzero, a, &approxset, 0, &ignore);3188}3189else {3190decAddOp(b, a, t, &workset, 0, &ignore); /* b = a + 0.5 ulp */3191workset.round=DEC_ROUND_DOWN;3192decMultiplyOp(b, b, b, &workset, &ignore); /* b = mulrd(b, b) */3193decCompareOp(b, b, f, &workset, COMPARE, &ignore); /* b ? f */3194if (decNumberIsNegative(b)) { /* b < f */3195t->exponent++; /* make 1.0 ulp */3196t->lsu[0]=1; /* .. */3197decAddOp(a, a, t, &workset, 0, &ignore); /* a = a + 1 ulp */3198/* assign to approx [round to length] */3199approxset.emin-=exp/2; /* adjust to match a */3200approxset.emax-=exp/2;3201decAddOp(a, &dzero, a, &approxset, 0, &ignore);3202}3203}3204/* [no errors are possible in the above, and rounding/inexact during */3205/* estimation are irrelevant, so status was not accumulated] */3206
3207/* Here, 0.1 <= a < 1 (still), so adjust back */3208a->exponent+=exp/2; /* set correct exponent */3209
3210/* count droppable zeros [after any subnormal rounding] by */3211/* trimming a copy */3212decNumberCopy(b, a);3213decTrim(b, set, 1, &dropped); /* [drops trailing zeros] */3214
3215/* Set Inexact and Rounded. The answer can only be exact if */3216/* it is short enough so that squaring it could fit in workp digits, */3217/* and it cannot have trailing zeros due to clamping, so these are */3218/* the only (relatively rare) conditions a careful check is needed */3219if (b->digits*2-1 > workp && !set->clamp) { /* cannot fit */3220status|=DEC_Inexact|DEC_Rounded;3221}3222else { /* could be exact/unrounded */3223uInt mstatus=0; /* local status */3224decMultiplyOp(b, b, b, &workset, &mstatus); /* try the multiply */3225if (mstatus&DEC_Overflow) { /* result just won't fit */3226status|=DEC_Inexact|DEC_Rounded;3227}3228else { /* plausible */3229decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); /* b ? rhs */3230if (!ISZERO(t)) status|=DEC_Inexact|DEC_Rounded; /* not equal */3231else { /* is Exact */3232/* here, dropped is the count of trailing zeros in 'a' */3233/* use closest exponent to ideal... */3234Int todrop=ideal-a->exponent; /* most that can be dropped */3235if (todrop<0) status|=DEC_Rounded; /* ideally would add 0s */3236else { /* unrounded */3237if (dropped<todrop) { /* clamp to those available */3238todrop=dropped;3239status|=DEC_Clamped;3240}3241if (todrop>0) { /* have some to drop */3242decShiftToLeast(a->lsu, D2U(a->digits), todrop);3243a->exponent+=todrop; /* maintain numerical value */3244a->digits-=todrop; /* new length */3245}3246}3247}3248}3249}3250
3251/* double-check Underflow, as perhaps the result could not have */3252/* been subnormal (initial argument too big), or it is now Exact */3253if (status&DEC_Underflow) {3254Int ae=rhs->exponent+rhs->digits-1; /* adjusted exponent */3255/* check if truly subnormal */3256#if DECEXTFLAG /* DEC_Subnormal too */3257if (ae>=set->emin*2) status&=~(DEC_Subnormal|DEC_Underflow);3258#else3259if (ae>=set->emin*2) status&=~DEC_Underflow;3260#endif3261/* check if truly inexact */3262if (!(status&DEC_Inexact)) status&=~DEC_Underflow;3263}3264
3265decNumberCopy(res, a); /* a is now the result */3266} while(0); /* end protected */3267
3268if (allocbuff!=NULL) free(allocbuff); /* drop any storage used */3269if (allocbufa!=NULL) free(allocbufa); /* .. */3270if (allocbufb!=NULL) free(allocbufb); /* .. */3271#if DECSUBSET3272if (allocrhs !=NULL) free(allocrhs); /* .. */3273#endif3274if (status!=0) decStatus(res, status, set);/* then report status */3275#if DECCHECK3276decCheckInexact(res, set);3277#endif3278return res;3279} /* decNumberSquareRoot */3280
3281/* ------------------------------------------------------------------ */
3282/* decNumberSubtract -- subtract two Numbers */
3283/* */
3284/* This computes C = A - B */
3285/* */
3286/* res is C, the result. C may be A and/or B (e.g., X=X-X) */
3287/* lhs is A */
3288/* rhs is B */
3289/* set is the context */
3290/* */
3291/* C must have space for set->digits digits. */
3292/* ------------------------------------------------------------------ */
3293decNumber * decNumberSubtract(decNumber *res, const decNumber *lhs,3294const decNumber *rhs, decContext *set) {3295uInt status=0; /* accumulator */3296
3297decAddOp(res, lhs, rhs, set, DECNEG, &status);3298if (status!=0) decStatus(res, status, set);3299#if DECCHECK3300decCheckInexact(res, set);3301#endif3302return res;3303} /* decNumberSubtract */3304
3305/* ------------------------------------------------------------------ */
3306/* decNumberToIntegralExact -- round-to-integral-value with InExact */
3307/* decNumberToIntegralValue -- round-to-integral-value */
3308/* */
3309/* res is the result */
3310/* rhs is input number */
3311/* set is the context */
3312/* */
3313/* res must have space for any value of rhs. */
3314/* */
3315/* This implements the IEEE special operators and therefore treats */
3316/* special values as valid. For finite numbers it returns */
3317/* rescale(rhs, 0) if rhs->exponent is <0. */
3318/* Otherwise the result is rhs (so no error is possible, except for */
3319/* sNaN). */
3320/* */
3321/* The context is used for rounding mode and status after sNaN, but */
3322/* the digits setting is ignored. The Exact version will signal */
3323/* Inexact if the result differs numerically from rhs; the other */
3324/* never signals Inexact. */
3325/* ------------------------------------------------------------------ */
3326decNumber * decNumberToIntegralExact(decNumber *res, const decNumber *rhs,3327decContext *set) {3328decNumber dn;3329decContext workset; /* working context */3330uInt status=0; /* accumulator */3331
3332#if DECCHECK3333if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;3334#endif3335
3336/* handle infinities and NaNs */3337if (SPECIALARG) {3338if (decNumberIsInfinite(rhs)) decNumberCopy(res, rhs); /* an Infinity */3339else decNaNs(res, rhs, NULL, set, &status); /* a NaN */3340}3341else { /* finite */3342/* have a finite number; no error possible (res must be big enough) */3343if (rhs->exponent>=0) return decNumberCopy(res, rhs);3344/* that was easy, but if negative exponent there is work to do... */3345workset=*set; /* clone rounding, etc. */3346workset.digits=rhs->digits; /* no length rounding */3347workset.traps=0; /* no traps */3348decNumberZero(&dn); /* make a number with exponent 0 */3349decNumberQuantize(res, rhs, &dn, &workset);3350status|=workset.status;3351}3352if (status!=0) decStatus(res, status, set);3353return res;3354} /* decNumberToIntegralExact */3355
3356decNumber * decNumberToIntegralValue(decNumber *res, const decNumber *rhs,3357decContext *set) {3358decContext workset=*set; /* working context */3359workset.traps=0; /* no traps */3360decNumberToIntegralExact(res, rhs, &workset);3361/* this never affects set, except for sNaNs; NaN will have been set */3362/* or propagated already, so no need to call decStatus */3363set->status|=workset.status&DEC_Invalid_operation;3364return res;3365} /* decNumberToIntegralValue */3366
3367/* ------------------------------------------------------------------ */
3368/* decNumberXor -- XOR two Numbers, digitwise */
3369/* */
3370/* This computes C = A ^ B */
3371/* */
3372/* res is C, the result. C may be A and/or B (e.g., X=X^X) */
3373/* lhs is A */
3374/* rhs is B */
3375/* set is the context (used for result length and error report) */
3376/* */
3377/* C must have space for set->digits digits. */
3378/* */
3379/* Logical function restrictions apply (see above); a NaN is */
3380/* returned with Invalid_operation if a restriction is violated. */
3381/* ------------------------------------------------------------------ */
3382decNumber * decNumberXor(decNumber *res, const decNumber *lhs,3383const decNumber *rhs, decContext *set) {3384const Unit *ua, *ub; /* -> operands */3385const Unit *msua, *msub; /* -> operand msus */3386Unit *uc, *msuc; /* -> result and its msu */3387Int msudigs; /* digits in res msu */3388#if DECCHECK3389if (decCheckOperands(res, lhs, rhs, set)) return res;3390#endif3391
3392if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)3393|| rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {3394decStatus(res, DEC_Invalid_operation, set);3395return res;3396}3397/* operands are valid */3398ua=lhs->lsu; /* bottom-up */3399ub=rhs->lsu; /* .. */3400uc=res->lsu; /* .. */3401msua=ua+D2U(lhs->digits)-1; /* -> msu of lhs */3402msub=ub+D2U(rhs->digits)-1; /* -> msu of rhs */3403msuc=uc+D2U(set->digits)-1; /* -> msu of result */3404msudigs=MSUDIGITS(set->digits); /* [faster than remainder] */3405for (; uc<=msuc; ua++, ub++, uc++) { /* Unit loop */3406Unit a, b; /* extract units */3407if (ua>msua) a=0;3408else a=*ua;3409if (ub>msub) b=0;3410else b=*ub;3411*uc=0; /* can now write back */3412if (a|b) { /* maybe 1 bits to examine */3413Int i, j;3414/* This loop could be unrolled and/or use BIN2BCD tables */3415for (i=0; i<DECDPUN; i++) {3416if ((a^b)&1) *uc=*uc+(Unit)powers[i]; /* effect XOR */3417j=a%10;3418a=a/10;3419j|=b%10;3420b=b/10;3421if (j>1) {3422decStatus(res, DEC_Invalid_operation, set);3423return res;3424}3425if (uc==msuc && i==msudigs-1) break; /* just did final digit */3426} /* each digit */3427} /* non-zero */3428} /* each unit */3429/* [here uc-1 is the msu of the result] */3430res->digits=decGetDigits(res->lsu, uc-res->lsu);3431res->exponent=0; /* integer */3432res->bits=0; /* sign=0 */3433return res; /* [no status to set] */3434} /* decNumberXor */3435
3436
3437/* ================================================================== */
3438/* Utility routines */
3439/* ================================================================== */
3440
3441/* ------------------------------------------------------------------ */
3442/* decNumberClass -- return the decClass of a decNumber */
3443/* dn -- the decNumber to test */
3444/* set -- the context to use for Emin */
3445/* returns the decClass enum */
3446/* ------------------------------------------------------------------ */
3447enum decClass decNumberClass(const decNumber *dn, decContext *set) {3448if (decNumberIsSpecial(dn)) {3449if (decNumberIsQNaN(dn)) return DEC_CLASS_QNAN;3450if (decNumberIsSNaN(dn)) return DEC_CLASS_SNAN;3451/* must be an infinity */3452if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_INF;3453return DEC_CLASS_POS_INF;3454}3455/* is finite */3456if (decNumberIsNormal(dn, set)) { /* most common */3457if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_NORMAL;3458return DEC_CLASS_POS_NORMAL;3459}3460/* is subnormal or zero */3461if (decNumberIsZero(dn)) { /* most common */3462if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_ZERO;3463return DEC_CLASS_POS_ZERO;3464}3465if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_SUBNORMAL;3466return DEC_CLASS_POS_SUBNORMAL;3467} /* decNumberClass */3468
3469/* ------------------------------------------------------------------ */
3470/* decNumberClassToString -- convert decClass to a string */
3471/* */
3472/* eclass is a valid decClass */
3473/* returns a constant string describing the class (max 13+1 chars) */
3474/* ------------------------------------------------------------------ */
3475const char *decNumberClassToString(enum decClass eclass) {3476if (eclass==DEC_CLASS_POS_NORMAL) return DEC_ClassString_PN;3477if (eclass==DEC_CLASS_NEG_NORMAL) return DEC_ClassString_NN;3478if (eclass==DEC_CLASS_POS_ZERO) return DEC_ClassString_PZ;3479if (eclass==DEC_CLASS_NEG_ZERO) return DEC_ClassString_NZ;3480if (eclass==DEC_CLASS_POS_SUBNORMAL) return DEC_ClassString_PS;3481if (eclass==DEC_CLASS_NEG_SUBNORMAL) return DEC_ClassString_NS;3482if (eclass==DEC_CLASS_POS_INF) return DEC_ClassString_PI;3483if (eclass==DEC_CLASS_NEG_INF) return DEC_ClassString_NI;3484if (eclass==DEC_CLASS_QNAN) return DEC_ClassString_QN;3485if (eclass==DEC_CLASS_SNAN) return DEC_ClassString_SN;3486return DEC_ClassString_UN; /* Unknown */3487} /* decNumberClassToString */3488
3489/* ------------------------------------------------------------------ */
3490/* decNumberCopy -- copy a number */
3491/* */
3492/* dest is the target decNumber */
3493/* src is the source decNumber */
3494/* returns dest */
3495/* */
3496/* (dest==src is allowed and is a no-op) */
3497/* All fields are updated as required. This is a utility operation, */
3498/* so special values are unchanged and no error is possible. */
3499/* ------------------------------------------------------------------ */
3500decNumber * decNumberCopy(decNumber *dest, const decNumber *src) {3501
3502#if DECCHECK3503if (src==NULL) return decNumberZero(dest);3504#endif3505
3506if (dest==src) return dest; /* no copy required */3507
3508/* Use explicit assignments here as structure assignment could copy */3509/* more than just the lsu (for small DECDPUN). This would not affect */3510/* the value of the results, but could disturb test harness spill */3511/* checking. */3512dest->bits=src->bits;3513dest->exponent=src->exponent;3514dest->digits=src->digits;3515dest->lsu[0]=src->lsu[0];3516if (src->digits>DECDPUN) { /* more Units to come */3517const Unit *smsup, *s; /* work */3518Unit *d; /* .. */3519/* memcpy for the remaining Units would be safe as they cannot */3520/* overlap. However, this explicit loop is faster in short cases. */3521d=dest->lsu+1; /* -> first destination */3522smsup=src->lsu+D2U(src->digits); /* -> source msu+1 */3523for (s=src->lsu+1; s<smsup; s++, d++) *d=*s;3524}3525return dest;3526} /* decNumberCopy */3527
3528/* ------------------------------------------------------------------ */
3529/* decNumberCopyAbs -- quiet absolute value operator */
3530/* */
3531/* This sets C = abs(A) */
3532/* */
3533/* res is C, the result. C may be A */
3534/* rhs is A */
3535/* */
3536/* C must have space for set->digits digits. */
3537/* No exception or error can occur; this is a quiet bitwise operation.*/
3538/* See also decNumberAbs for a checking version of this. */
3539/* ------------------------------------------------------------------ */
3540decNumber * decNumberCopyAbs(decNumber *res, const decNumber *rhs) {3541#if DECCHECK3542if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;3543#endif3544decNumberCopy(res, rhs);3545res->bits&=~DECNEG; /* turn off sign */3546return res;3547} /* decNumberCopyAbs */3548
3549/* ------------------------------------------------------------------ */
3550/* decNumberCopyNegate -- quiet negate value operator */
3551/* */
3552/* This sets C = negate(A) */
3553/* */
3554/* res is C, the result. C may be A */
3555/* rhs is A */
3556/* */
3557/* C must have space for set->digits digits. */
3558/* No exception or error can occur; this is a quiet bitwise operation.*/
3559/* See also decNumberMinus for a checking version of this. */
3560/* ------------------------------------------------------------------ */
3561decNumber * decNumberCopyNegate(decNumber *res, const decNumber *rhs) {3562#if DECCHECK3563if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;3564#endif3565decNumberCopy(res, rhs);3566res->bits^=DECNEG; /* invert the sign */3567return res;3568} /* decNumberCopyNegate */3569
3570/* ------------------------------------------------------------------ */
3571/* decNumberCopySign -- quiet copy and set sign operator */
3572/* */
3573/* This sets C = A with the sign of B */
3574/* */
3575/* res is C, the result. C may be A */
3576/* lhs is A */
3577/* rhs is B */
3578/* */
3579/* C must have space for set->digits digits. */
3580/* No exception or error can occur; this is a quiet bitwise operation.*/
3581/* ------------------------------------------------------------------ */
3582decNumber * decNumberCopySign(decNumber *res, const decNumber *lhs,3583const decNumber *rhs) {3584uByte sign; /* rhs sign */3585#if DECCHECK3586if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;3587#endif3588sign=rhs->bits & DECNEG; /* save sign bit */3589decNumberCopy(res, lhs);3590res->bits&=~DECNEG; /* clear the sign */3591res->bits|=sign; /* set from rhs */3592return res;3593} /* decNumberCopySign */3594
3595/* ------------------------------------------------------------------ */
3596/* decNumberGetBCD -- get the coefficient in BCD8 */
3597/* dn is the source decNumber */
3598/* bcd is the uInt array that will receive dn->digits BCD bytes, */
3599/* most-significant at offset 0 */
3600/* returns bcd */
3601/* */
3602/* bcd must have at least dn->digits bytes. No error is possible; if */
3603/* dn is a NaN or Infinite, digits must be 1 and the coefficient 0. */
3604/* ------------------------------------------------------------------ */
3605uByte * decNumberGetBCD(const decNumber *dn, uint8_t *bcd) {3606uByte *ub=bcd+dn->digits-1; /* -> lsd */3607const Unit *up=dn->lsu; /* Unit pointer, -> lsu */3608
3609#if DECDPUN==1 /* trivial simple copy */3610for (; ub>=bcd; ub--, up++) *ub=*up;3611#else /* chopping needed */3612uInt u=*up; /* work */3613uInt cut=DECDPUN; /* downcounter through unit */3614for (; ub>=bcd; ub--) {3615*ub=(uByte)(u%10); /* [*6554 trick inhibits, here] */3616u=u/10;3617cut--;3618if (cut>0) continue; /* more in this unit */3619up++;3620u=*up;3621cut=DECDPUN;3622}3623#endif3624return bcd;3625} /* decNumberGetBCD */3626
3627/* ------------------------------------------------------------------ */
3628/* decNumberSetBCD -- set (replace) the coefficient from BCD8 */
3629/* dn is the target decNumber */
3630/* bcd is the uInt array that will source n BCD bytes, most- */
3631/* significant at offset 0 */
3632/* n is the number of digits in the source BCD array (bcd) */
3633/* returns dn */
3634/* */
3635/* dn must have space for at least n digits. No error is possible; */
3636/* if dn is a NaN, or Infinite, or is to become a zero, n must be 1 */
3637/* and bcd[0] zero. */
3638/* ------------------------------------------------------------------ */
3639decNumber * decNumberSetBCD(decNumber *dn, const uByte *bcd, uInt n) {3640Unit *up = dn->lsu + D2U(n) - 1; /* -> msu [target pointer] */3641const uByte *ub=bcd; /* -> source msd */3642
3643#if DECDPUN==1 /* trivial simple copy */3644for (; ub<bcd+n; ub++, up--) *up=*ub;3645#else /* some assembly needed */3646/* calculate how many digits in msu, and hence first cut */3647Int cut=MSUDIGITS(n); /* [faster than remainder] */3648for (;up>=dn->lsu; up--) { /* each Unit from msu */3649*up=0; /* will take <=DECDPUN digits */3650for (; cut>0; ub++, cut--) *up=X10(*up)+*ub;3651cut=DECDPUN; /* next Unit has all digits */3652}3653#endif3654dn->digits=n; /* set digit count */3655return dn;3656} /* decNumberSetBCD */3657
3658/* ------------------------------------------------------------------ */
3659/* decNumberIsNormal -- test normality of a decNumber */
3660/* dn is the decNumber to test */
3661/* set is the context to use for Emin */
3662/* returns 1 if |dn| is finite and >=Nmin, 0 otherwise */
3663/* ------------------------------------------------------------------ */
3664Int decNumberIsNormal(const decNumber *dn, decContext *set) {3665Int ae; /* adjusted exponent */3666#if DECCHECK3667if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;3668#endif3669
3670if (decNumberIsSpecial(dn)) return 0; /* not finite */3671if (decNumberIsZero(dn)) return 0; /* not non-zero */3672
3673ae=dn->exponent+dn->digits-1; /* adjusted exponent */3674if (ae<set->emin) return 0; /* is subnormal */3675return 1;3676} /* decNumberIsNormal */3677
3678/* ------------------------------------------------------------------ */
3679/* decNumberIsSubnormal -- test subnormality of a decNumber */
3680/* dn is the decNumber to test */
3681/* set is the context to use for Emin */
3682/* returns 1 if |dn| is finite, non-zero, and <Nmin, 0 otherwise */
3683/* ------------------------------------------------------------------ */
3684Int decNumberIsSubnormal(const decNumber *dn, decContext *set) {3685Int ae; /* adjusted exponent */3686#if DECCHECK3687if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;3688#endif3689
3690if (decNumberIsSpecial(dn)) return 0; /* not finite */3691if (decNumberIsZero(dn)) return 0; /* not non-zero */3692
3693ae=dn->exponent+dn->digits-1; /* adjusted exponent */3694if (ae<set->emin) return 1; /* is subnormal */3695return 0;3696} /* decNumberIsSubnormal */3697
3698/* ------------------------------------------------------------------ */
3699/* decNumberTrim -- remove insignificant zeros */
3700/* */
3701/* dn is the number to trim */
3702/* returns dn */
3703/* */
3704/* All fields are updated as required. This is a utility operation, */
3705/* so special values are unchanged and no error is possible. */
3706/* ------------------------------------------------------------------ */
3707decNumber * decNumberTrim(decNumber *dn) {3708Int dropped; /* work */3709decContext set; /* .. */3710#if DECCHECK3711if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn;3712#endif3713decContextDefault(&set, DEC_INIT_BASE); /* clamp=0 */3714return decTrim(dn, &set, 0, &dropped);3715} /* decNumberTrim */3716
3717/* ------------------------------------------------------------------ */
3718/* decNumberVersion -- return the name and version of this module */
3719/* */
3720/* No error is possible. */
3721/* ------------------------------------------------------------------ */
3722const char * decNumberVersion(void) {3723return DECVERSION;3724} /* decNumberVersion */3725
3726/* ------------------------------------------------------------------ */
3727/* decNumberZero -- set a number to 0 */
3728/* */
3729/* dn is the number to set, with space for one digit */
3730/* returns dn */
3731/* */
3732/* No error is possible. */
3733/* ------------------------------------------------------------------ */
3734/* Memset is not used as it is much slower in some environments. */
3735decNumber * decNumberZero(decNumber *dn) {3736
3737#if DECCHECK3738if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;3739#endif3740
3741dn->bits=0;3742dn->exponent=0;3743dn->digits=1;3744dn->lsu[0]=0;3745return dn;3746} /* decNumberZero */3747
3748/* ================================================================== */
3749/* Local routines */
3750/* ================================================================== */
3751
3752/* ------------------------------------------------------------------ */
3753/* decToString -- lay out a number into a string */
3754/* */
3755/* dn is the number to lay out */
3756/* string is where to lay out the number */
3757/* eng is 1 if Engineering, 0 if Scientific */
3758/* */
3759/* string must be at least dn->digits+14 characters long */
3760/* No error is possible. */
3761/* */
3762/* Note that this routine can generate a -0 or 0.000. These are */
3763/* never generated in subset to-number or arithmetic, but can occur */
3764/* in non-subset arithmetic (e.g., -1*0 or 1.234-1.234). */
3765/* ------------------------------------------------------------------ */
3766/* If DECCHECK is enabled the string "?" is returned if a number is */
3767/* invalid. */
3768static void decToString(const decNumber *dn, char *string, Flag eng) {3769Int exp=dn->exponent; /* local copy */3770Int e; /* E-part value */3771Int pre; /* digits before the '.' */3772Int cut; /* for counting digits in a Unit */3773char *c=string; /* work [output pointer] */3774const Unit *up=dn->lsu+D2U(dn->digits)-1; /* -> msu [input pointer] */3775uInt u, pow; /* work */3776
3777#if DECCHECK3778if (decCheckOperands(DECUNRESU, dn, DECUNUSED, DECUNCONT)) {3779strcpy(string, "?");3780return;}3781#endif3782
3783if (decNumberIsNegative(dn)) { /* Negatives get a minus */3784*c='-';3785c++;3786}3787if (dn->bits&DECSPECIAL) { /* Is a special value */3788if (decNumberIsInfinite(dn)) {3789strcpy(c, "Inf");3790strcpy(c+3, "inity");3791return;}3792/* a NaN */3793if (dn->bits&DECSNAN) { /* signalling NaN */3794*c='s';3795c++;3796}3797strcpy(c, "NaN");3798c+=3; /* step past */3799/* if not a clean non-zero coefficient, that's all there is in a */3800/* NaN string */3801if (exp!=0 || (*dn->lsu==0 && dn->digits==1)) return;3802/* [drop through to add integer] */3803}3804
3805/* calculate how many digits in msu, and hence first cut */3806cut=MSUDIGITS(dn->digits); /* [faster than remainder] */3807cut--; /* power of ten for digit */3808
3809if (exp==0) { /* simple integer [common fastpath] */3810for (;up>=dn->lsu; up--) { /* each Unit from msu */3811u=*up; /* contains DECDPUN digits to lay out */3812for (; cut>=0; c++, cut--) TODIGIT(u, cut, c, pow);3813cut=DECDPUN-1; /* next Unit has all digits */3814}3815*c='\0'; /* terminate the string */3816return;}3817
3818/* non-0 exponent -- assume plain form */3819pre=dn->digits+exp; /* digits before '.' */3820e=0; /* no E */3821if ((exp>0) || (pre<-5)) { /* need exponential form */3822e=exp+dn->digits-1; /* calculate E value */3823pre=1; /* assume one digit before '.' */3824if (eng && (e!=0)) { /* engineering: may need to adjust */3825Int adj; /* adjustment */3826/* The C remainder operator is undefined for negative numbers, so */3827/* a positive remainder calculation must be used here */3828if (e<0) {3829adj=(-e)%3;3830if (adj!=0) adj=3-adj;3831}3832else { /* e>0 */3833adj=e%3;3834}3835e=e-adj;3836/* if dealing with zero still produce an exponent which is a */3837/* multiple of three, as expected, but there will only be the */3838/* one zero before the E, still. Otherwise note the padding. */3839if (!ISZERO(dn)) pre+=adj;3840else { /* is zero */3841if (adj!=0) { /* 0.00Esnn needed */3842e=e+3;3843pre=-(2-adj);3844}3845} /* zero */3846} /* eng */3847} /* need exponent */3848
3849/* lay out the digits of the coefficient, adding 0s and . as needed */3850u=*up;3851if (pre>0) { /* xxx.xxx or xx00 (engineering) form */3852Int n=pre;3853for (; pre>0; pre--, c++, cut--) {3854if (cut<0) { /* need new Unit */3855if (up==dn->lsu) break; /* out of input digits (pre>digits) */3856up--;3857cut=DECDPUN-1;3858u=*up;3859}3860TODIGIT(u, cut, c, pow);3861}3862if (n<dn->digits) { /* more to come, after '.' */3863*c='.'; c++;3864for (;; c++, cut--) {3865if (cut<0) { /* need new Unit */3866if (up==dn->lsu) break; /* out of input digits */3867up--;3868cut=DECDPUN-1;3869u=*up;3870}3871TODIGIT(u, cut, c, pow);3872}3873}3874else for (; pre>0; pre--, c++) *c='0'; /* 0 padding (for engineering) needed */3875}3876else { /* 0.xxx or 0.000xxx form */3877*c='0'; c++;3878*c='.'; c++;3879for (; pre<0; pre++, c++) *c='0'; /* add any 0's after '.' */3880for (; ; c++, cut--) {3881if (cut<0) { /* need new Unit */3882if (up==dn->lsu) break; /* out of input digits */3883up--;3884cut=DECDPUN-1;3885u=*up;3886}3887TODIGIT(u, cut, c, pow);3888}3889}3890
3891/* Finally add the E-part, if needed. It will never be 0, has a3892base maximum and minimum of +999999999 through -999999999, but
3893could range down to -1999999998 for anormal numbers */
3894if (e!=0) {3895Flag had=0; /* 1=had non-zero */3896*c='E'; c++;3897*c='+'; c++; /* assume positive */3898u=e; /* .. */3899if (e<0) {3900*(c-1)='-'; /* oops, need - */3901u=-e; /* uInt, please */3902}3903/* lay out the exponent [_itoa or equivalent is not ANSI C] */3904for (cut=9; cut>=0; cut--) {3905TODIGIT(u, cut, c, pow);3906if (*c=='0' && !had) continue; /* skip leading zeros */3907had=1; /* had non-0 */3908c++; /* step for next */3909} /* cut */3910}3911*c='\0'; /* terminate the string (all paths) */3912return;3913} /* decToString */3914
3915/* ------------------------------------------------------------------ */
3916/* decAddOp -- add/subtract operation */
3917/* */
3918/* This computes C = A + B */
3919/* */
3920/* res is C, the result. C may be A and/or B (e.g., X=X+X) */
3921/* lhs is A */
3922/* rhs is B */
3923/* set is the context */
3924/* negate is DECNEG if rhs should be negated, or 0 otherwise */
3925/* status accumulates status for the caller */
3926/* */
3927/* C must have space for set->digits digits. */
3928/* Inexact in status must be 0 for correct Exact zero sign in result */
3929/* ------------------------------------------------------------------ */
3930/* If possible, the coefficient is calculated directly into C. */
3931/* However, if: */
3932/* -- a digits+1 calculation is needed because the numbers are */
3933/* unaligned and span more than set->digits digits */
3934/* -- a carry to digits+1 digits looks possible */
3935/* -- C is the same as A or B, and the result would destructively */
3936/* overlap the A or B coefficient */
3937/* then the result must be calculated into a temporary buffer. In */
3938/* this case a local (stack) buffer is used if possible, and only if */
3939/* too long for that does malloc become the final resort. */
3940/* */
3941/* Misalignment is handled as follows: */
3942/* Apad: (AExp>BExp) Swap operands and proceed as for BExp>AExp. */
3943/* BPad: Apply the padding by a combination of shifting (whole */
3944/* units) and multiplication (part units). */
3945/* */
3946/* Addition, especially x=x+1, is speed-critical. */
3947/* The static buffer is larger than might be expected to allow for */
3948/* calls from higher-level functions (notably exp). */
3949/* ------------------------------------------------------------------ */
3950static decNumber * decAddOp(decNumber *res, const decNumber *lhs,3951const decNumber *rhs, decContext *set,3952uByte negate, uInt *status) {3953#if DECSUBSET3954decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */3955decNumber *allocrhs=NULL; /* .., rhs */3956#endif3957Int rhsshift; /* working shift (in Units) */3958Int maxdigits; /* longest logical length */3959Int mult; /* multiplier */3960Int residue; /* rounding accumulator */3961uByte bits; /* result bits */3962Flag diffsign; /* non-0 if arguments have different sign */3963Unit *acc; /* accumulator for result */3964Unit accbuff[SD2U(DECBUFFER*2+20)]; /* local buffer [*2+20 reduces many */3965/* allocations when called from */3966/* other operations, notable exp] */3967Unit *allocacc=NULL; /* -> allocated acc buffer, iff allocated */3968Int reqdigits=set->digits; /* local copy; requested DIGITS */3969Int padding; /* work */3970
3971#if DECCHECK3972if (decCheckOperands(res, lhs, rhs, set)) return res;3973#endif3974
3975do { /* protect allocated storage */3976#if DECSUBSET3977if (!set->extended) {3978/* reduce operands and set lostDigits status, as needed */3979if (lhs->digits>reqdigits) {3980alloclhs=decRoundOperand(lhs, set, status);3981if (alloclhs==NULL) break;3982lhs=alloclhs;3983}3984if (rhs->digits>reqdigits) {3985allocrhs=decRoundOperand(rhs, set, status);3986if (allocrhs==NULL) break;3987rhs=allocrhs;3988}3989}3990#endif3991/* [following code does not require input rounding] */3992
3993/* note whether signs differ [used all paths] */3994diffsign=(Flag)((lhs->bits^rhs->bits^negate)&DECNEG);3995
3996/* handle infinities and NaNs */3997if (SPECIALARGS) { /* a special bit set */3998if (SPECIALARGS & (DECSNAN | DECNAN)) /* a NaN */3999decNaNs(res, lhs, rhs, set, status);4000else { /* one or two infinities */4001if (decNumberIsInfinite(lhs)) { /* LHS is infinity */4002/* two infinities with different signs is invalid */4003if (decNumberIsInfinite(rhs) && diffsign) {4004*status|=DEC_Invalid_operation;4005break;4006}4007bits=lhs->bits & DECNEG; /* get sign from LHS */4008}4009else bits=(rhs->bits^negate) & DECNEG;/* RHS must be Infinity */4010bits|=DECINF;4011decNumberZero(res);4012res->bits=bits; /* set +/- infinity */4013} /* an infinity */4014break;4015}4016
4017/* Quick exit for add 0s; return the non-0, modified as need be */4018if (ISZERO(lhs)) {4019Int adjust; /* work */4020Int lexp=lhs->exponent; /* save in case LHS==RES */4021bits=lhs->bits; /* .. */4022residue=0; /* clear accumulator */4023decCopyFit(res, rhs, set, &residue, status); /* copy (as needed) */4024res->bits^=negate; /* flip if rhs was negated */4025#if DECSUBSET4026if (set->extended) { /* exponents on zeros count */4027#endif4028/* exponent will be the lower of the two */4029adjust=lexp-res->exponent; /* adjustment needed [if -ve] */4030if (ISZERO(res)) { /* both 0: special IEEE 854 rules */4031if (adjust<0) res->exponent=lexp; /* set exponent */4032/* 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0 */4033if (diffsign) {4034if (set->round!=DEC_ROUND_FLOOR) res->bits=0;4035else res->bits=DECNEG; /* preserve 0 sign */4036}4037}4038else { /* non-0 res */4039if (adjust<0) { /* 0-padding needed */4040if ((res->digits-adjust)>set->digits) {4041adjust=res->digits-set->digits; /* to fit exactly */4042*status|=DEC_Rounded; /* [but exact] */4043}4044res->digits=decShiftToMost(res->lsu, res->digits, -adjust);4045res->exponent+=adjust; /* set the exponent. */4046}4047} /* non-0 res */4048#if DECSUBSET4049} /* extended */4050#endif4051decFinish(res, set, &residue, status); /* clean and finalize */4052break;}4053
4054if (ISZERO(rhs)) { /* [lhs is non-zero] */4055Int adjust; /* work */4056Int rexp=rhs->exponent; /* save in case RHS==RES */4057bits=rhs->bits; /* be clean */4058residue=0; /* clear accumulator */4059decCopyFit(res, lhs, set, &residue, status); /* copy (as needed) */4060#if DECSUBSET4061if (set->extended) { /* exponents on zeros count */4062#endif4063/* exponent will be the lower of the two */4064/* [0-0 case handled above] */4065adjust=rexp-res->exponent; /* adjustment needed [if -ve] */4066if (adjust<0) { /* 0-padding needed */4067if ((res->digits-adjust)>set->digits) {4068adjust=res->digits-set->digits; /* to fit exactly */4069*status|=DEC_Rounded; /* [but exact] */4070}4071res->digits=decShiftToMost(res->lsu, res->digits, -adjust);4072res->exponent+=adjust; /* set the exponent. */4073}4074#if DECSUBSET4075} /* extended */4076#endif4077decFinish(res, set, &residue, status); /* clean and finalize */4078break;}4079
4080/* [NB: both fastpath and mainpath code below assume these cases */4081/* (notably 0-0) have already been handled] */4082
4083/* calculate the padding needed to align the operands */4084padding=rhs->exponent-lhs->exponent;4085
4086/* Fastpath cases where the numbers are aligned and normal, the RHS */4087/* is all in one unit, no operand rounding is needed, and no carry, */4088/* lengthening, or borrow is needed */4089if (padding==04090&& rhs->digits<=DECDPUN4091&& rhs->exponent>=set->emin /* [some normals drop through] */4092&& rhs->exponent<=set->emax-set->digits+1 /* [could clamp] */4093&& rhs->digits<=reqdigits4094&& lhs->digits<=reqdigits) {4095Int partial=*lhs->lsu;4096if (!diffsign) { /* adding */4097partial+=*rhs->lsu;4098if ((partial<=DECDPUNMAX) /* result fits in unit */4099&& (lhs->digits>=DECDPUN || /* .. and no digits-count change */4100partial<(Int)powers[lhs->digits])) { /* .. */4101if (res!=lhs) decNumberCopy(res, lhs); /* not in place */4102*res->lsu=(Unit)partial; /* [copy could have overwritten RHS] */4103break;4104}4105/* else drop out for careful add */4106}4107else { /* signs differ */4108partial-=*rhs->lsu;4109if (partial>0) { /* no borrow needed, and non-0 result */4110if (res!=lhs) decNumberCopy(res, lhs); /* not in place */4111*res->lsu=(Unit)partial;4112/* this could have reduced digits [but result>0] */4113res->digits=decGetDigits(res->lsu, D2U(res->digits));4114break;4115}4116/* else drop out for careful subtract */4117}4118}4119
4120/* Now align (pad) the lhs or rhs so they can be added or */4121/* subtracted, as necessary. If one number is much larger than */4122/* the other (that is, if in plain form there is a least one */4123/* digit between the lowest digit of one and the highest of the */4124/* other) padding with up to DIGITS-1 trailing zeros may be */4125/* needed; then apply rounding (as exotic rounding modes may be */4126/* affected by the residue). */4127rhsshift=0; /* rhs shift to left (padding) in Units */4128bits=lhs->bits; /* assume sign is that of LHS */4129mult=1; /* likely multiplier */4130
4131/* [if padding==0 the operands are aligned; no padding is needed] */4132if (padding!=0) {4133/* some padding needed; always pad the RHS, as any required */4134/* padding can then be effected by a simple combination of */4135/* shifts and a multiply */4136Flag swapped=0;4137if (padding<0) { /* LHS needs the padding */4138const decNumber *t;4139padding=-padding; /* will be +ve */4140bits=(uByte)(rhs->bits^negate); /* assumed sign is now that of RHS */4141t=lhs; lhs=rhs; rhs=t;4142swapped=1;4143}4144
4145/* If, after pad, rhs would be longer than lhs by digits+1 or */4146/* more then lhs cannot affect the answer, except as a residue, */4147/* so only need to pad up to a length of DIGITS+1. */4148if (rhs->digits+padding > lhs->digits+reqdigits+1) {4149/* The RHS is sufficient */4150/* for residue use the relative sign indication... */4151Int shift=reqdigits-rhs->digits; /* left shift needed */4152residue=1; /* residue for rounding */4153if (diffsign) residue=-residue; /* signs differ */4154/* copy, shortening if necessary */4155decCopyFit(res, rhs, set, &residue, status);4156/* if it was already shorter, then need to pad with zeros */4157if (shift>0) {4158res->digits=decShiftToMost(res->lsu, res->digits, shift);4159res->exponent-=shift; /* adjust the exponent. */4160}4161/* flip the result sign if unswapped and rhs was negated */4162if (!swapped) res->bits^=negate;4163decFinish(res, set, &residue, status); /* done */4164break;}4165
4166/* LHS digits may affect result */4167rhsshift=D2U(padding+1)-1; /* this much by Unit shift .. */4168mult=powers[padding-(rhsshift*DECDPUN)]; /* .. this by multiplication */4169} /* padding needed */4170
4171if (diffsign) mult=-mult; /* signs differ */4172
4173/* determine the longer operand */4174maxdigits=rhs->digits+padding; /* virtual length of RHS */4175if (lhs->digits>maxdigits) maxdigits=lhs->digits;4176
4177/* Decide on the result buffer to use; if possible place directly */4178/* into result. */4179acc=res->lsu; /* assume add direct to result */4180/* If destructive overlap, or the number is too long, or a carry or */4181/* borrow to DIGITS+1 might be possible, a buffer must be used. */4182/* [Might be worth more sophisticated tests when maxdigits==reqdigits] */4183if ((maxdigits>=reqdigits) /* is, or could be, too large */4184|| (res==rhs && rhsshift>0)) { /* destructive overlap */4185/* buffer needed, choose it; units for maxdigits digits will be */4186/* needed, +1 Unit for carry or borrow */4187Int need=D2U(maxdigits)+1;4188acc=accbuff; /* assume use local buffer */4189if (need*sizeof(Unit)>sizeof(accbuff)) {4190/* printf("malloc add %ld %ld\n", need, sizeof(accbuff)); */4191allocacc=(Unit *)malloc(need*sizeof(Unit));4192if (allocacc==NULL) { /* hopeless -- abandon */4193*status|=DEC_Insufficient_storage;4194break;}4195acc=allocacc;4196}4197}4198
4199res->bits=(uByte)(bits&DECNEG); /* it's now safe to overwrite.. */4200res->exponent=lhs->exponent; /* .. operands (even if aliased) */4201
4202#if DECTRACE4203decDumpAr('A', lhs->lsu, D2U(lhs->digits));4204decDumpAr('B', rhs->lsu, D2U(rhs->digits));4205printf(" :h: %ld %ld\n", rhsshift, mult);4206#endif4207
4208/* add [A+B*m] or subtract [A+B*(-m)] */4209res->digits=decUnitAddSub(lhs->lsu, D2U(lhs->digits),4210rhs->lsu, D2U(rhs->digits),4211rhsshift, acc, mult)4212*DECDPUN; /* [units -> digits] */4213if (res->digits<0) { /* borrowed... */4214res->digits=-res->digits;4215res->bits^=DECNEG; /* flip the sign */4216}4217#if DECTRACE4218decDumpAr('+', acc, D2U(res->digits));4219#endif4220
4221/* If a buffer was used the result must be copied back, possibly */4222/* shortening. (If no buffer was used then the result must have */4223/* fit, so can't need rounding and residue must be 0.) */4224residue=0; /* clear accumulator */4225if (acc!=res->lsu) {4226#if DECSUBSET4227if (set->extended) { /* round from first significant digit */4228#endif4229/* remove leading zeros that were added due to rounding up to */4230/* integral Units -- before the test for rounding. */4231if (res->digits>reqdigits)4232res->digits=decGetDigits(acc, D2U(res->digits));4233decSetCoeff(res, set, acc, res->digits, &residue, status);4234#if DECSUBSET4235}4236else { /* subset arithmetic rounds from original significant digit */4237/* May have an underestimate. This only occurs when both */4238/* numbers fit in DECDPUN digits and are padding with a */4239/* negative multiple (-10, -100...) and the top digit(s) become */4240/* 0. (This only matters when using X3.274 rules where the */4241/* leading zero could be included in the rounding.) */4242if (res->digits<maxdigits) {4243*(acc+D2U(res->digits))=0; /* ensure leading 0 is there */4244res->digits=maxdigits;4245}4246else {4247/* remove leading zeros that added due to rounding up to */4248/* integral Units (but only those in excess of the original */4249/* maxdigits length, unless extended) before test for rounding. */4250if (res->digits>reqdigits) {4251res->digits=decGetDigits(acc, D2U(res->digits));4252if (res->digits<maxdigits) res->digits=maxdigits;4253}4254}4255decSetCoeff(res, set, acc, res->digits, &residue, status);4256/* Now apply rounding if needed before removing leading zeros. */4257/* This is safe because subnormals are not a possibility */4258if (residue!=0) {4259decApplyRound(res, set, residue, status);4260residue=0; /* did what needed to be done */4261}4262} /* subset */4263#endif4264} /* used buffer */4265
4266/* strip leading zeros [these were left on in case of subset subtract] */4267res->digits=decGetDigits(res->lsu, D2U(res->digits));4268
4269/* apply checks and rounding */4270decFinish(res, set, &residue, status);4271
4272/* "When the sum of two operands with opposite signs is exactly */4273/* zero, the sign of that sum shall be '+' in all rounding modes */4274/* except round toward -Infinity, in which mode that sign shall be */4275/* '-'." [Subset zeros also never have '-', set by decFinish.] */4276if (ISZERO(res) && diffsign4277#if DECSUBSET4278&& set->extended4279#endif4280&& (*status&DEC_Inexact)==0) {4281if (set->round==DEC_ROUND_FLOOR) res->bits|=DECNEG; /* sign - */4282else res->bits&=~DECNEG; /* sign + */4283}4284} while(0); /* end protected */4285
4286if (allocacc!=NULL) free(allocacc); /* drop any storage used */4287#if DECSUBSET4288if (allocrhs!=NULL) free(allocrhs); /* .. */4289if (alloclhs!=NULL) free(alloclhs); /* .. */4290#endif4291return res;4292} /* decAddOp */4293
4294/* ------------------------------------------------------------------ */
4295/* decDivideOp -- division operation */
4296/* */
4297/* This routine performs the calculations for all four division */
4298/* operators (divide, divideInteger, remainder, remainderNear). */
4299/* */
4300/* C=A op B */
4301/* */
4302/* res is C, the result. C may be A and/or B (e.g., X=X/X) */
4303/* lhs is A */
4304/* rhs is B */
4305/* set is the context */
4306/* op is DIVIDE, DIVIDEINT, REMAINDER, or REMNEAR respectively. */
4307/* status is the usual accumulator */
4308/* */
4309/* C must have space for set->digits digits. */
4310/* */
4311/* ------------------------------------------------------------------ */
4312/* The underlying algorithm of this routine is the same as in the */
4313/* 1981 S/370 implementation, that is, non-restoring long division */
4314/* with bi-unit (rather than bi-digit) estimation for each unit */
4315/* multiplier. In this pseudocode overview, complications for the */
4316/* Remainder operators and division residues for exact rounding are */
4317/* omitted for clarity. */
4318/* */
4319/* Prepare operands and handle special values */
4320/* Test for x/0 and then 0/x */
4321/* Exp =Exp1 - Exp2 */
4322/* Exp =Exp +len(var1) -len(var2) */
4323/* Sign=Sign1 * Sign2 */
4324/* Pad accumulator (Var1) to double-length with 0's (pad1) */
4325/* Pad Var2 to same length as Var1 */
4326/* msu2pair/plus=1st 2 or 1 units of var2, +1 to allow for round */
4327/* have=0 */
4328/* Do until (have=digits+1 OR residue=0) */
4329/* if exp<0 then if integer divide/residue then leave */
4330/* this_unit=0 */
4331/* Do forever */
4332/* compare numbers */
4333/* if <0 then leave inner_loop */
4334/* if =0 then (* quick exit without subtract *) do */
4335/* this_unit=this_unit+1; output this_unit */
4336/* leave outer_loop; end */
4337/* Compare lengths of numbers (mantissae): */
4338/* If same then tops2=msu2pair -- {units 1&2 of var2} */
4339/* else tops2=msu2plus -- {0, unit 1 of var2} */
4340/* tops1=first_unit_of_Var1*10**DECDPUN +second_unit_of_var1 */
4341/* mult=tops1/tops2 -- Good and safe guess at divisor */
4342/* if mult=0 then mult=1 */
4343/* this_unit=this_unit+mult */
4344/* subtract */
4345/* end inner_loop */
4346/* if have\=0 | this_unit\=0 then do */
4347/* output this_unit */
4348/* have=have+1; end */
4349/* var2=var2/10 */
4350/* exp=exp-1 */
4351/* end outer_loop */
4352/* exp=exp+1 -- set the proper exponent */
4353/* if have=0 then generate answer=0 */
4354/* Return (Result is defined by Var1) */
4355/* */
4356/* ------------------------------------------------------------------ */
4357/* Two working buffers are needed during the division; one (digits+ */
4358/* 1) to accumulate the result, and the other (up to 2*digits+1) for */
4359/* long subtractions. These are acc and var1 respectively. */
4360/* var1 is a copy of the lhs coefficient, var2 is the rhs coefficient.*/
4361/* The static buffers may be larger than might be expected to allow */
4362/* for calls from higher-level functions (notably exp). */
4363/* ------------------------------------------------------------------ */
4364static decNumber * decDivideOp(decNumber *res,4365const decNumber *lhs, const decNumber *rhs,4366decContext *set, Flag op, uInt *status) {4367#if DECSUBSET4368decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */4369decNumber *allocrhs=NULL; /* .., rhs */4370#endif4371Unit accbuff[SD2U(DECBUFFER+DECDPUN+10)]; /* local buffer */4372Unit *acc=accbuff; /* -> accumulator array for result */4373Unit *allocacc=NULL; /* -> allocated buffer, iff allocated */4374Unit *accnext; /* -> where next digit will go */4375Int acclength; /* length of acc needed [Units] */4376Int accunits; /* count of units accumulated */4377Int accdigits; /* count of digits accumulated */4378
4379Unit varbuff[SD2U(DECBUFFER*2+DECDPUN)*sizeof(Unit)]; /* buffer for var1 */4380Unit *var1=varbuff; /* -> var1 array for long subtraction */4381Unit *varalloc=NULL; /* -> allocated buffer, iff used */4382Unit *msu1; /* -> msu of var1 */4383
4384const Unit *var2; /* -> var2 array */4385const Unit *msu2; /* -> msu of var2 */4386Int msu2plus; /* msu2 plus one [does not vary] */4387eInt msu2pair; /* msu2 pair plus one [does not vary] */4388
4389Int var1units, var2units; /* actual lengths */4390Int var2ulen; /* logical length (units) */4391Int var1initpad=0; /* var1 initial padding (digits) */4392Int maxdigits; /* longest LHS or required acc length */4393Int mult; /* multiplier for subtraction */4394Unit thisunit; /* current unit being accumulated */4395Int residue; /* for rounding */4396Int reqdigits=set->digits; /* requested DIGITS */4397Int exponent; /* working exponent */4398Int maxexponent=0; /* DIVIDE maximum exponent if unrounded */4399uByte bits; /* working sign */4400Unit *target; /* work */4401const Unit *source; /* .. */4402uLong const *pow; /* .. */4403Int shift, cut; /* .. */4404#if DECSUBSET4405Int dropped; /* work */4406#endif4407
4408#if DECCHECK4409if (decCheckOperands(res, lhs, rhs, set)) return res;4410#endif4411
4412do { /* protect allocated storage */4413#if DECSUBSET4414if (!set->extended) {4415/* reduce operands and set lostDigits status, as needed */4416if (lhs->digits>reqdigits) {4417alloclhs=decRoundOperand(lhs, set, status);4418if (alloclhs==NULL) break;4419lhs=alloclhs;4420}4421if (rhs->digits>reqdigits) {4422allocrhs=decRoundOperand(rhs, set, status);4423if (allocrhs==NULL) break;4424rhs=allocrhs;4425}4426}4427#endif4428/* [following code does not require input rounding] */4429
4430bits=(lhs->bits^rhs->bits)&DECNEG; /* assumed sign for divisions */4431
4432/* handle infinities and NaNs */4433if (SPECIALARGS) { /* a special bit set */4434if (SPECIALARGS & (DECSNAN | DECNAN)) { /* one or two NaNs */4435decNaNs(res, lhs, rhs, set, status);4436break;4437}4438/* one or two infinities */4439if (decNumberIsInfinite(lhs)) { /* LHS (dividend) is infinite */4440if (decNumberIsInfinite(rhs) || /* two infinities are invalid .. */4441op & (REMAINDER | REMNEAR)) { /* as is remainder of infinity */4442*status|=DEC_Invalid_operation;4443break;4444}4445/* [Note that infinity/0 raises no exceptions] */4446decNumberZero(res);4447res->bits=bits|DECINF; /* set +/- infinity */4448break;4449}4450else { /* RHS (divisor) is infinite */4451residue=0;4452if (op&(REMAINDER|REMNEAR)) {4453/* result is [finished clone of] lhs */4454decCopyFit(res, lhs, set, &residue, status);4455}4456else { /* a division */4457decNumberZero(res);4458res->bits=bits; /* set +/- zero */4459/* for DIVIDEINT the exponent is always 0. For DIVIDE, result */4460/* is a 0 with infinitely negative exponent, clamped to minimum */4461if (op&DIVIDE) {4462res->exponent=set->emin-set->digits+1;4463*status|=DEC_Clamped;4464}4465}4466decFinish(res, set, &residue, status);4467break;4468}4469}4470
4471/* handle 0 rhs (x/0) */4472if (ISZERO(rhs)) { /* x/0 is always exceptional */4473if (ISZERO(lhs)) {4474decNumberZero(res); /* [after lhs test] */4475*status|=DEC_Division_undefined;/* 0/0 will become NaN */4476}4477else {4478decNumberZero(res);4479if (op&(REMAINDER|REMNEAR)) *status|=DEC_Invalid_operation;4480else {4481*status|=DEC_Division_by_zero; /* x/0 */4482res->bits=bits|DECINF; /* .. is +/- Infinity */4483}4484}4485break;}4486
4487/* handle 0 lhs (0/x) */4488if (ISZERO(lhs)) { /* 0/x [x!=0] */4489#if DECSUBSET4490if (!set->extended) decNumberZero(res);4491else {4492#endif4493if (op&DIVIDE) {4494residue=0;4495exponent=lhs->exponent-rhs->exponent; /* ideal exponent */4496decNumberCopy(res, lhs); /* [zeros always fit] */4497res->bits=bits; /* sign as computed */4498res->exponent=exponent; /* exponent, too */4499decFinalize(res, set, &residue, status); /* check exponent */4500}4501else if (op&DIVIDEINT) {4502decNumberZero(res); /* integer 0 */4503res->bits=bits; /* sign as computed */4504}4505else { /* a remainder */4506exponent=rhs->exponent; /* [save in case overwrite] */4507decNumberCopy(res, lhs); /* [zeros always fit] */4508if (exponent<res->exponent) res->exponent=exponent; /* use lower */4509}4510#if DECSUBSET4511}4512#endif4513break;}4514
4515/* Precalculate exponent. This starts off adjusted (and hence fits */4516/* in 31 bits) and becomes the usual unadjusted exponent as the */4517/* division proceeds. The order of evaluation is important, here, */4518/* to avoid wrap. */4519exponent=(lhs->exponent+lhs->digits)-(rhs->exponent+rhs->digits);4520
4521/* If the working exponent is -ve, then some quick exits are */4522/* possible because the quotient is known to be <1 */4523/* [for REMNEAR, it needs to be < -1, as -0.5 could need work] */4524if (exponent<0 && !(op==DIVIDE)) {4525if (op&DIVIDEINT) {4526decNumberZero(res); /* integer part is 0 */4527#if DECSUBSET4528if (set->extended)4529#endif4530res->bits=bits; /* set +/- zero */4531break;}4532/* fastpath remainders so long as the lhs has the smaller */4533/* (or equal) exponent */4534if (lhs->exponent<=rhs->exponent) {4535if (op&REMAINDER || exponent<-1) {4536/* It is REMAINDER or safe REMNEAR; result is [finished */4537/* clone of] lhs (r = x - 0*y) */4538residue=0;4539decCopyFit(res, lhs, set, &residue, status);4540decFinish(res, set, &residue, status);4541break;4542}4543/* [unsafe REMNEAR drops through] */4544}4545} /* fastpaths */4546
4547/* Long (slow) division is needed; roll up the sleeves... */4548
4549/* The accumulator will hold the quotient of the division. */4550/* If it needs to be too long for stack storage, then allocate. */4551acclength=D2U(reqdigits+DECDPUN); /* in Units */4552if (acclength*sizeof(Unit)>sizeof(accbuff)) {4553/* printf("malloc dvacc %ld units\n", acclength); */4554allocacc=(Unit *)malloc(acclength*sizeof(Unit));4555if (allocacc==NULL) { /* hopeless -- abandon */4556*status|=DEC_Insufficient_storage;4557break;}4558acc=allocacc; /* use the allocated space */4559}4560
4561/* var1 is the padded LHS ready for subtractions. */4562/* If it needs to be too long for stack storage, then allocate. */4563/* The maximum units needed for var1 (long subtraction) is: */4564/* Enough for */4565/* (rhs->digits+reqdigits-1) -- to allow full slide to right */4566/* or (lhs->digits) -- to allow for long lhs */4567/* whichever is larger */4568/* +1 -- for rounding of slide to right */4569/* +1 -- for leading 0s */4570/* +1 -- for pre-adjust if a remainder or DIVIDEINT */4571/* [Note: unused units do not participate in decUnitAddSub data] */4572maxdigits=rhs->digits+reqdigits-1;4573if (lhs->digits>maxdigits) maxdigits=lhs->digits;4574var1units=D2U(maxdigits)+2;4575/* allocate a guard unit above msu1 for REMAINDERNEAR */4576if (!(op&DIVIDE)) var1units++;4577if ((var1units+1)*sizeof(Unit)>sizeof(varbuff)) {4578/* printf("malloc dvvar %ld units\n", var1units+1); */4579varalloc=(Unit *)malloc((var1units+1)*sizeof(Unit));4580if (varalloc==NULL) { /* hopeless -- abandon */4581*status|=DEC_Insufficient_storage;4582break;}4583var1=varalloc; /* use the allocated space */4584}4585
4586/* Extend the lhs and rhs to full long subtraction length. The lhs */4587/* is truly extended into the var1 buffer, with 0 padding, so a */4588/* subtract in place is always possible. The rhs (var2) has */4589/* virtual padding (implemented by decUnitAddSub). */4590/* One guard unit was allocated above msu1 for rem=rem+rem in */4591/* REMAINDERNEAR. */4592msu1=var1+var1units-1; /* msu of var1 */4593source=lhs->lsu+D2U(lhs->digits)-1; /* msu of input array */4594for (target=msu1; source>=lhs->lsu; source--, target--) *target=*source;4595for (; target>=var1; target--) *target=0;4596
4597/* rhs (var2) is left-aligned with var1 at the start */4598var2ulen=var1units; /* rhs logical length (units) */4599var2units=D2U(rhs->digits); /* rhs actual length (units) */4600var2=rhs->lsu; /* -> rhs array */4601msu2=var2+var2units-1; /* -> msu of var2 [never changes] */4602/* now set up the variables which will be used for estimating the */4603/* multiplication factor. If these variables are not exact, add */4604/* 1 to make sure that the multiplier is never overestimated. */4605msu2plus=*msu2; /* it's value .. */4606if (var2units>1) msu2plus++; /* .. +1 if any more */4607msu2pair=(eInt)*msu2*(DECDPUNMAX+1);/* top two pair .. */4608if (var2units>1) { /* .. [else treat 2nd as 0] */4609msu2pair+=*(msu2-1); /* .. */4610if (var2units>2) msu2pair++; /* .. +1 if any more */4611}4612
4613/* The calculation is working in units, which may have leading zeros, */4614/* but the exponent was calculated on the assumption that they are */4615/* both left-aligned. Adjust the exponent to compensate: add the */4616/* number of leading zeros in var1 msu and subtract those in var2 msu. */4617/* [This is actually done by counting the digits and negating, as */4618/* lead1=DECDPUN-digits1, and similarly for lead2.] */4619for (pow=&powers[1]; *msu1>=*pow; pow++) exponent--;4620for (pow=&powers[1]; *msu2>=*pow; pow++) exponent++;4621
4622/* Now, if doing an integer divide or remainder, ensure that */4623/* the result will be Unit-aligned. To do this, shift the var1 */4624/* accumulator towards least if need be. (It's much easier to */4625/* do this now than to reassemble the residue afterwards, if */4626/* doing a remainder.) Also ensure the exponent is not negative. */4627if (!(op&DIVIDE)) {4628Unit *u; /* work */4629/* save the initial 'false' padding of var1, in digits */4630var1initpad=(var1units-D2U(lhs->digits))*DECDPUN;4631/* Determine the shift to do. */4632if (exponent<0) cut=-exponent;4633else cut=DECDPUN-exponent%DECDPUN;4634decShiftToLeast(var1, var1units, cut);4635exponent+=cut; /* maintain numerical value */4636var1initpad-=cut; /* .. and reduce padding */4637/* clean any most-significant units which were just emptied */4638for (u=msu1; cut>=DECDPUN; cut-=DECDPUN, u--) *u=0;4639} /* align */4640else { /* is DIVIDE */4641maxexponent=lhs->exponent-rhs->exponent; /* save */4642/* optimization: if the first iteration will just produce 0, */4643/* preadjust to skip it [valid for DIVIDE only] */4644if (*msu1<*msu2) {4645var2ulen--; /* shift down */4646exponent-=DECDPUN; /* update the exponent */4647}4648}4649
4650/* ---- start the long-division loops ------------------------------ */4651accunits=0; /* no units accumulated yet */4652accdigits=0; /* .. or digits */4653accnext=acc+acclength-1; /* -> msu of acc [NB: allows digits+1] */4654for (;;) { /* outer forever loop */4655thisunit=0; /* current unit assumed 0 */4656/* find the next unit */4657for (;;) { /* inner forever loop */4658/* strip leading zero units [from either pre-adjust or from */4659/* subtract last time around]. Leave at least one unit. */4660for (; *msu1==0 && msu1>var1; msu1--) var1units--;4661
4662if (var1units<var2ulen) break; /* var1 too low for subtract */4663if (var1units==var2ulen) { /* unit-by-unit compare needed */4664/* compare the two numbers, from msu */4665const Unit *pv1, *pv2;4666Unit v2; /* units to compare */4667pv2=msu2; /* -> msu */4668for (pv1=msu1; ; pv1--, pv2--) {4669/* v1=*pv1 -- always OK */4670v2=0; /* assume in padding */4671if (pv2>=var2) v2=*pv2; /* in range */4672if (*pv1!=v2) break; /* no longer the same */4673if (pv1==var1) break; /* done; leave pv1 as is */4674}4675/* here when all inspected or a difference seen */4676if (*pv1<v2) break; /* var1 too low to subtract */4677if (*pv1==v2) { /* var1 == var2 */4678/* reach here if var1 and var2 are identical; subtraction */4679/* would increase digit by one, and the residue will be 0 so */4680/* the calculation is done; leave the loop with residue=0. */4681thisunit++; /* as though subtracted */4682*var1=0; /* set var1 to 0 */4683var1units=1; /* .. */4684break; /* from inner */4685} /* var1 == var2 */4686/* *pv1>v2. Prepare for real subtraction; the lengths are equal */4687/* Estimate the multiplier (there's always a msu1-1)... */4688/* Bring in two units of var2 to provide a good estimate. */4689mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2pair);4690} /* lengths the same */4691else { /* var1units > var2ulen, so subtraction is safe */4692/* The var2 msu is one unit towards the lsu of the var1 msu, */4693/* so only one unit for var2 can be used. */4694mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2plus);4695}4696if (mult==0) mult=1; /* must always be at least 1 */4697/* subtraction needed; var1 is > var2 */4698thisunit=(Unit)(thisunit+mult); /* accumulate */4699/* subtract var1-var2, into var1; only the overlap needs */4700/* processing, as this is an in-place calculation */4701shift=var2ulen-var2units;4702#if DECTRACE4703decDumpAr('1', &var1[shift], var1units-shift);4704decDumpAr('2', var2, var2units);4705printf("m=%ld\n", -mult);4706#endif4707decUnitAddSub(&var1[shift], var1units-shift,4708var2, var2units, 0,4709&var1[shift], -mult);4710#if DECTRACE4711decDumpAr('#', &var1[shift], var1units-shift);4712#endif4713/* var1 now probably has leading zeros; these are removed at the */4714/* top of the inner loop. */4715} /* inner loop */4716
4717/* The next unit has been calculated in full; unless it's a */4718/* leading zero, add to acc */4719if (accunits!=0 || thisunit!=0) { /* is first or non-zero */4720*accnext=thisunit; /* store in accumulator */4721/* account exactly for the new digits */4722if (accunits==0) {4723accdigits++; /* at least one */4724for (pow=&powers[1]; thisunit>=*pow; pow++) accdigits++;4725}4726else accdigits+=DECDPUN;4727accunits++; /* update count */4728accnext--; /* ready for next */4729if (accdigits>reqdigits) break; /* have enough digits */4730}4731
4732/* if the residue is zero, the operation is done (unless divide */4733/* or divideInteger and still not enough digits yet) */4734if (*var1==0 && var1units==1) { /* residue is 0 */4735if (op&(REMAINDER|REMNEAR)) break;4736if ((op&DIVIDE) && (exponent<=maxexponent)) break;4737/* [drop through if divideInteger] */4738}4739/* also done enough if calculating remainder or integer */4740/* divide and just did the last ('units') unit */4741if (exponent==0 && !(op&DIVIDE)) break;4742
4743/* to get here, var1 is less than var2, so divide var2 by the per- */4744/* Unit power of ten and go for the next digit */4745var2ulen--; /* shift down */4746exponent-=DECDPUN; /* update the exponent */4747} /* outer loop */4748
4749/* ---- division is complete --------------------------------------- */4750/* here: acc has at least reqdigits+1 of good results (or fewer */4751/* if early stop), starting at accnext+1 (its lsu) */4752/* var1 has any residue at the stopping point */4753/* accunits is the number of digits collected in acc */4754if (accunits==0) { /* acc is 0 */4755accunits=1; /* show have a unit .. */4756accdigits=1; /* .. */4757*accnext=0; /* .. whose value is 0 */4758}4759else accnext++; /* back to last placed */4760/* accnext now -> lowest unit of result */4761
4762residue=0; /* assume no residue */4763if (op&DIVIDE) {4764/* record the presence of any residue, for rounding */4765if (*var1!=0 || var1units>1) residue=1;4766else { /* no residue */4767/* Had an exact division; clean up spurious trailing 0s. */4768/* There will be at most DECDPUN-1, from the final multiply, */4769/* and then only if the result is non-0 (and even) and the */4770/* exponent is 'loose'. */4771#if DECDPUN>14772Unit lsu=*accnext;4773if (!(lsu&0x01) && (lsu!=0)) {4774/* count the trailing zeros */4775Int drop=0;4776for (;; drop++) { /* [will terminate because lsu!=0] */4777if (exponent>=maxexponent) break; /* don't chop real 0s */4778#if DECDPUN<=44779if ((lsu-QUOT10(lsu, drop+1)4780*powers[drop+1])!=0) break; /* found non-0 digit */4781#else4782if (lsu%powers[drop+1]!=0) break; /* found non-0 digit */4783#endif4784exponent++;4785}4786if (drop>0) {4787accunits=decShiftToLeast(accnext, accunits, drop);4788accdigits=decGetDigits(accnext, accunits);4789accunits=D2U(accdigits);4790/* [exponent was adjusted in the loop] */4791}4792} /* neither odd nor 0 */4793#endif4794} /* exact divide */4795} /* divide */4796else /* op!=DIVIDE */ {4797/* check for coefficient overflow */4798if (accdigits+exponent>reqdigits) {4799*status|=DEC_Division_impossible;4800break;4801}4802if (op & (REMAINDER|REMNEAR)) {4803/* [Here, the exponent will be 0, because var1 was adjusted */4804/* appropriately.] */4805Int postshift; /* work */4806Flag wasodd=0; /* integer was odd */4807Unit *quotlsu; /* for save */4808Int quotdigits; /* .. */4809
4810bits=lhs->bits; /* remainder sign is always as lhs */4811
4812/* Fastpath when residue is truly 0 is worthwhile [and */4813/* simplifies the code below] */4814if (*var1==0 && var1units==1) { /* residue is 0 */4815Int exp=lhs->exponent; /* save min(exponents) */4816if (rhs->exponent<exp) exp=rhs->exponent;4817decNumberZero(res); /* 0 coefficient */4818#if DECSUBSET4819if (set->extended)4820#endif4821res->exponent=exp; /* .. with proper exponent */4822res->bits=(uByte)(bits&DECNEG); /* [cleaned] */4823decFinish(res, set, &residue, status); /* might clamp */4824break;4825}4826/* note if the quotient was odd */4827if (*accnext & 0x01) wasodd=1; /* acc is odd */4828quotlsu=accnext; /* save in case need to reinspect */4829quotdigits=accdigits; /* .. */4830
4831/* treat the residue, in var1, as the value to return, via acc */4832/* calculate the unused zero digits. This is the smaller of: */4833/* var1 initial padding (saved above) */4834/* var2 residual padding, which happens to be given by: */4835postshift=var1initpad+exponent-lhs->exponent+rhs->exponent;4836/* [the 'exponent' term accounts for the shifts during divide] */4837if (var1initpad<postshift) postshift=var1initpad;4838
4839/* shift var1 the requested amount, and adjust its digits */4840var1units=decShiftToLeast(var1, var1units, postshift);4841accnext=var1;4842accdigits=decGetDigits(var1, var1units);4843accunits=D2U(accdigits);4844
4845exponent=lhs->exponent; /* exponent is smaller of lhs & rhs */4846if (rhs->exponent<exponent) exponent=rhs->exponent;4847
4848/* Now correct the result if doing remainderNear; if it */4849/* (looking just at coefficients) is > rhs/2, or == rhs/2 and */4850/* the integer was odd then the result should be rem-rhs. */4851if (op&REMNEAR) {4852Int compare, tarunits; /* work */4853Unit *up; /* .. */4854/* calculate remainder*2 into the var1 buffer (which has */4855/* 'headroom' of an extra unit and hence enough space) */4856/* [a dedicated 'double' loop would be faster, here] */4857tarunits=decUnitAddSub(accnext, accunits, accnext, accunits,48580, accnext, 1);4859/* decDumpAr('r', accnext, tarunits); */4860
4861/* Here, accnext (var1) holds tarunits Units with twice the */4862/* remainder's coefficient, which must now be compared to the */4863/* RHS. The remainder's exponent may be smaller than the RHS's. */4864compare=decUnitCompare(accnext, tarunits, rhs->lsu, D2U(rhs->digits),4865rhs->exponent-exponent);4866if (compare==BADINT) { /* deep trouble */4867*status|=DEC_Insufficient_storage;4868break;}4869
4870/* now restore the remainder by dividing by two; the lsu */4871/* is known to be even. */4872for (up=accnext; up<accnext+tarunits; up++) {4873Int half; /* half to add to lower unit */4874half=*up & 0x01;4875*up/=2; /* [shift] */4876if (!half) continue;4877*(up-1)+=DIV_ROUND_UP(DECDPUNMAX, 2);4878}4879/* [accunits still describes the original remainder length] */4880
4881if (compare>0 || (compare==0 && wasodd)) { /* adjustment needed */4882Int exp, expunits, exprem; /* work */4883/* This is effectively causing round-up of the quotient, */4884/* so if it was the rare case where it was full and all */4885/* nines, it would overflow and hence division-impossible */4886/* should be raised */4887Flag allnines=0; /* 1 if quotient all nines */4888if (quotdigits==reqdigits) { /* could be borderline */4889for (up=quotlsu; ; up++) {4890if (quotdigits>DECDPUN) {4891if (*up!=DECDPUNMAX) break;/* non-nines */4892}4893else { /* this is the last Unit */4894if (*up==powers[quotdigits]-1) allnines=1;4895break;4896}4897quotdigits-=DECDPUN; /* checked those digits */4898} /* up */4899} /* borderline check */4900if (allnines) {4901*status|=DEC_Division_impossible;4902break;}4903
4904/* rem-rhs is needed; the sign will invert. Again, var1 */4905/* can safely be used for the working Units array. */4906exp=rhs->exponent-exponent; /* RHS padding needed */4907/* Calculate units and remainder from exponent. */4908expunits=exp/DECDPUN;4909exprem=exp%DECDPUN;4910/* subtract [A+B*(-m)]; the result will always be negative */4911accunits=-decUnitAddSub(accnext, accunits,4912rhs->lsu, D2U(rhs->digits),4913expunits, accnext, -(Int)powers[exprem]);4914accdigits=decGetDigits(accnext, accunits); /* count digits exactly */4915accunits=D2U(accdigits); /* and recalculate the units for copy */4916/* [exponent is as for original remainder] */4917bits^=DECNEG; /* flip the sign */4918}4919} /* REMNEAR */4920} /* REMAINDER or REMNEAR */4921} /* not DIVIDE */4922
4923/* Set exponent and bits */4924res->exponent=exponent;4925res->bits=(uByte)(bits&DECNEG); /* [cleaned] */4926
4927/* Now the coefficient. */4928decSetCoeff(res, set, accnext, accdigits, &residue, status);4929
4930decFinish(res, set, &residue, status); /* final cleanup */4931
4932#if DECSUBSET4933/* If a divide then strip trailing zeros if subset [after round] */4934if (!set->extended && (op==DIVIDE)) decTrim(res, set, 0, &dropped);4935#endif4936} while(0); /* end protected */4937
4938if (varalloc!=NULL) free(varalloc); /* drop any storage used */4939if (allocacc!=NULL) free(allocacc); /* .. */4940#if DECSUBSET4941if (allocrhs!=NULL) free(allocrhs); /* .. */4942if (alloclhs!=NULL) free(alloclhs); /* .. */4943#endif4944return res;4945} /* decDivideOp */4946
4947/* ------------------------------------------------------------------ */
4948/* decMultiplyOp -- multiplication operation */
4949/* */
4950/* This routine performs the multiplication C=A x B. */
4951/* */
4952/* res is C, the result. C may be A and/or B (e.g., X=X*X) */
4953/* lhs is A */
4954/* rhs is B */
4955/* set is the context */
4956/* status is the usual accumulator */
4957/* */
4958/* C must have space for set->digits digits. */
4959/* */
4960/* ------------------------------------------------------------------ */
4961/* 'Classic' multiplication is used rather than Karatsuba, as the */
4962/* latter would give only a minor improvement for the short numbers */
4963/* expected to be handled most (and uses much more memory). */
4964/* */
4965/* There are two major paths here: the general-purpose ('old code') */
4966/* path which handles all DECDPUN values, and a fastpath version */
4967/* which is used if 64-bit ints are available, DECDPUN<=4, and more */
4968/* than two calls to decUnitAddSub would be made. */
4969/* */
4970/* The fastpath version lumps units together into 8-digit or 9-digit */
4971/* chunks, and also uses a lazy carry strategy to minimise expensive */
4972/* 64-bit divisions. The chunks are then broken apart again into */
4973/* units for continuing processing. Despite this overhead, the */
4974/* fastpath can speed up some 16-digit operations by 10x (and much */
4975/* more for higher-precision calculations). */
4976/* */
4977/* A buffer always has to be used for the accumulator; in the */
4978/* fastpath, buffers are also always needed for the chunked copies of */
4979/* of the operand coefficients. */
4980/* Static buffers are larger than needed just for multiply, to allow */
4981/* for calls from other operations (notably exp). */
4982/* ------------------------------------------------------------------ */
4983#define FASTMUL (DECUSE64 && DECDPUN<5)4984static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs,4985const decNumber *rhs, decContext *set,4986uInt *status) {4987Int accunits; /* Units of accumulator in use */4988Int exponent; /* work */4989Int residue=0; /* rounding residue */4990uByte bits; /* result sign */4991Unit *acc; /* -> accumulator Unit array */4992Int needbytes; /* size calculator */4993void *allocacc=NULL; /* -> allocated accumulator, iff allocated */4994Unit accbuff[SD2U(DECBUFFER*4+1)]; /* buffer (+1 for DECBUFFER==0, */4995/* *4 for calls from other operations) */4996const Unit *mer, *mermsup; /* work */4997Int madlength; /* Units in multiplicand */4998Int shift; /* Units to shift multiplicand by */4999
5000#if FASTMUL5001/* if DECDPUN is 1 or 3 work in base 10**9, otherwise */5002/* (DECDPUN is 2 or 4) then work in base 10**8 */5003#if DECDPUN & 1 /* odd */5004#define FASTBASE 1000000000 /* base */5005#define FASTDIGS 9 /* digits in base */5006#define FASTLAZY 18 /* carry resolution point [1->18] */5007#else5008#define FASTBASE 1000000005009#define FASTDIGS 85010#define FASTLAZY 1844 /* carry resolution point [1->1844] */5011#endif5012/* three buffers are used, two for chunked copies of the operands */5013/* (base 10**8 or base 10**9) and one base 2**64 accumulator with */5014/* lazy carry evaluation */5015uInt zlhibuff[(DECBUFFER*2+1)/8+1]; /* buffer (+1 for DECBUFFER==0) */5016uInt *zlhi=zlhibuff; /* -> lhs array */5017uInt *alloclhi=NULL; /* -> allocated buffer, iff allocated */5018uInt zrhibuff[(DECBUFFER*2+1)/8+1]; /* buffer (+1 for DECBUFFER==0) */5019uInt *zrhi=zrhibuff; /* -> rhs array */5020uInt *allocrhi=NULL; /* -> allocated buffer, iff allocated */5021uLong zaccbuff[(DECBUFFER*2+1)/4+2]; /* buffer (+1 for DECBUFFER==0) */5022/* [allocacc is shared for both paths, as only one will run] */5023uLong *zacc=zaccbuff; /* -> accumulator array for exact result */5024#if DECDPUN==15025Int zoff; /* accumulator offset */5026#endif5027uInt *lip, *rip; /* item pointers */5028uInt *lmsi, *rmsi; /* most significant items */5029Int ilhs, irhs, iacc; /* item counts in the arrays */5030Int lazy; /* lazy carry counter */5031uLong lcarry; /* uLong carry */5032uInt carry; /* carry (NB not uLong) */5033Int count; /* work */5034const Unit *cup; /* .. */5035Unit *up; /* .. */5036uLong *lp; /* .. */5037Int p; /* .. */5038#endif5039
5040#if DECSUBSET5041decNumber *alloclhs=NULL; /* -> allocated buffer, iff allocated */5042decNumber *allocrhs=NULL; /* -> allocated buffer, iff allocated */5043#endif5044
5045#if DECCHECK5046if (decCheckOperands(res, lhs, rhs, set)) return res;5047#endif5048
5049/* precalculate result sign */5050bits=(uByte)((lhs->bits^rhs->bits)&DECNEG);5051
5052/* handle infinities and NaNs */5053if (SPECIALARGS) { /* a special bit set */5054if (SPECIALARGS & (DECSNAN | DECNAN)) { /* one or two NaNs */5055decNaNs(res, lhs, rhs, set, status);5056return res;}5057/* one or two infinities; Infinity * 0 is invalid */5058if (((lhs->bits & DECINF)==0 && ISZERO(lhs))5059||((rhs->bits & DECINF)==0 && ISZERO(rhs))) {5060*status|=DEC_Invalid_operation;5061return res;}5062decNumberZero(res);5063res->bits=bits|DECINF; /* infinity */5064return res;}5065
5066/* For best speed, as in DMSRCN [the original Rexx numerics */5067/* module], use the shorter number as the multiplier (rhs) and */5068/* the longer as the multiplicand (lhs) to minimise the number of */5069/* adds (partial products) */5070if (lhs->digits<rhs->digits) { /* swap... */5071const decNumber *hold=lhs;5072lhs=rhs;5073rhs=hold;5074}5075
5076do { /* protect allocated storage */5077#if DECSUBSET5078if (!set->extended) {5079/* reduce operands and set lostDigits status, as needed */5080if (lhs->digits>set->digits) {5081alloclhs=decRoundOperand(lhs, set, status);5082if (alloclhs==NULL) break;5083lhs=alloclhs;5084}5085if (rhs->digits>set->digits) {5086allocrhs=decRoundOperand(rhs, set, status);5087if (allocrhs==NULL) break;5088rhs=allocrhs;5089}5090}5091#endif5092/* [following code does not require input rounding] */5093
5094#if FASTMUL /* fastpath can be used */5095/* use the fast path if there are enough digits in the shorter */5096/* operand to make the setup and takedown worthwhile */5097#define NEEDTWO (DECDPUN*2) /* within two decUnitAddSub calls */5098if (rhs->digits>NEEDTWO) { /* use fastpath... */5099/* calculate the number of elements in each array */5100ilhs=(lhs->digits+FASTDIGS-1)/FASTDIGS; /* [ceiling] */5101irhs=(rhs->digits+FASTDIGS-1)/FASTDIGS; /* .. */5102iacc=ilhs+irhs;5103
5104/* allocate buffers if required, as usual */5105needbytes=ilhs*sizeof(uInt);5106if (needbytes>(Int)sizeof(zlhibuff)) {5107alloclhi=(uInt *)malloc(needbytes);5108zlhi=alloclhi;}5109needbytes=irhs*sizeof(uInt);5110if (needbytes>(Int)sizeof(zrhibuff)) {5111allocrhi=(uInt *)malloc(needbytes);5112zrhi=allocrhi;}5113
5114/* Allocating the accumulator space needs a special case when */5115/* DECDPUN=1 because when converting the accumulator to Units */5116/* after the multiplication each 8-byte item becomes 9 1-byte */5117/* units. Therefore iacc extra bytes are needed at the front */5118/* (rounded up to a multiple of 8 bytes), and the uLong */5119/* accumulator starts offset the appropriate number of units */5120/* to the right to avoid overwrite during the unchunking. */5121needbytes=iacc*sizeof(uLong);5122#if DECDPUN==15123zoff=(iacc+7)/8; /* items to offset by */5124needbytes+=zoff*8;5125#endif5126if (needbytes>(Int)sizeof(zaccbuff)) {5127allocacc=(uLong *)malloc(needbytes);5128zacc=(uLong *)allocacc;}5129if (zlhi==NULL||zrhi==NULL||zacc==NULL) {5130*status|=DEC_Insufficient_storage;5131break;}5132
5133acc=(Unit *)zacc; /* -> target Unit array */5134#if DECDPUN==15135zacc+=zoff; /* start uLong accumulator to right */5136#endif5137
5138/* assemble the chunked copies of the left and right sides */5139for (count=lhs->digits, cup=lhs->lsu, lip=zlhi; count>0; lip++)5140for (p=0, *lip=0; p<FASTDIGS && count>0;5141p+=DECDPUN, cup++, count-=DECDPUN)5142*lip+=*cup*powers[p];5143lmsi=lip-1; /* save -> msi */5144for (count=rhs->digits, cup=rhs->lsu, rip=zrhi; count>0; rip++)5145for (p=0, *rip=0; p<FASTDIGS && count>0;5146p+=DECDPUN, cup++, count-=DECDPUN)5147*rip+=*cup*powers[p];5148rmsi=rip-1; /* save -> msi */5149
5150/* zero the accumulator */5151for (lp=zacc; lp<zacc+iacc; lp++) *lp=0;5152
5153/* Start the multiplication */5154/* Resolving carries can dominate the cost of accumulating the */5155/* partial products, so this is only done when necessary. */5156/* Each uLong item in the accumulator can hold values up to */5157/* 2**64-1, and each partial product can be as large as */5158/* (10**FASTDIGS-1)**2. When FASTDIGS=9, this can be added to */5159/* itself 18.4 times in a uLong without overflowing, so during */5160/* the main calculation resolution is carried out every 18th */5161/* add -- every 162 digits. Similarly, when FASTDIGS=8, the */5162/* partial products can be added to themselves 1844.6 times in */5163/* a uLong without overflowing, so intermediate carry */5164/* resolution occurs only every 14752 digits. Hence for common */5165/* short numbers usually only the one final carry resolution */5166/* occurs. */5167/* (The count is set via FASTLAZY to simplify experiments to */5168/* measure the value of this approach: a 35% improvement on a */5169/* [34x34] multiply.) */5170lazy=FASTLAZY; /* carry delay count */5171for (rip=zrhi; rip<=rmsi; rip++) { /* over each item in rhs */5172lp=zacc+(rip-zrhi); /* where to add the lhs */5173for (lip=zlhi; lip<=lmsi; lip++, lp++) { /* over each item in lhs */5174*lp+=(uLong)(*lip)*(*rip); /* [this should in-line] */5175} /* lip loop */5176lazy--;5177if (lazy>0 && rip!=rmsi) continue;5178lazy=FASTLAZY; /* reset delay count */5179/* spin up the accumulator resolving overflows */5180for (lp=zacc; lp<zacc+iacc; lp++) {5181if (*lp<FASTBASE) continue; /* it fits */5182lcarry=*lp/FASTBASE; /* top part [slow divide] */5183/* lcarry can exceed 2**32-1, so check again; this check */5184/* and occasional extra divide (slow) is well worth it, as */5185/* it allows FASTLAZY to be increased to 18 rather than 4 */5186/* in the FASTDIGS=9 case */5187if (lcarry<FASTBASE) carry=(uInt)lcarry; /* [usual] */5188else { /* two-place carry [fairly rare] */5189uInt carry2=(uInt)(lcarry/FASTBASE); /* top top part */5190*(lp+2)+=carry2; /* add to item+2 */5191*lp-=((uLong)FASTBASE*FASTBASE*carry2); /* [slow] */5192carry=(uInt)(lcarry-((uLong)FASTBASE*carry2)); /* [inline] */5193}5194*(lp+1)+=carry; /* add to item above [inline] */5195*lp-=((uLong)FASTBASE*carry); /* [inline] */5196} /* carry resolution */5197} /* rip loop */5198
5199/* The multiplication is complete; time to convert back into */5200/* units. This can be done in-place in the accumulator and in */5201/* 32-bit operations, because carries were resolved after the */5202/* final add. This needs N-1 divides and multiplies for */5203/* each item in the accumulator (which will become up to N */5204/* units, where 2<=N<=9). */5205for (lp=zacc, up=acc; lp<zacc+iacc; lp++) {5206uInt item=(uInt)*lp; /* decapitate to uInt */5207for (p=0; p<FASTDIGS-DECDPUN; p+=DECDPUN, up++) {5208uInt part=item/(DECDPUNMAX+1);5209*up=(Unit)(item-(part*(DECDPUNMAX+1)));5210item=part;5211} /* p */5212*up=(Unit)item; up++; /* [final needs no division] */5213} /* lp */5214accunits=up-acc; /* count of units */5215}5216else { /* here to use units directly, without chunking ['old code'] */5217#endif5218
5219/* if accumulator will be too long for local storage, then allocate */5220acc=accbuff; /* -> assume buffer for accumulator */5221needbytes=(D2U(lhs->digits)+D2U(rhs->digits))*sizeof(Unit);5222if (needbytes>(Int)sizeof(accbuff)) {5223allocacc=(Unit *)malloc(needbytes);5224if (allocacc==NULL) {*status|=DEC_Insufficient_storage; break;}5225acc=(Unit *)allocacc; /* use the allocated space */5226}5227
5228/* Now the main long multiplication loop */5229/* Unlike the equivalent in the IBM Java implementation, there */5230/* is no advantage in calculating from msu to lsu. So, do it */5231/* by the book, as it were. */5232/* Each iteration calculates ACC=ACC+MULTAND*MULT */5233accunits=1; /* accumulator starts at '0' */5234*acc=0; /* .. (lsu=0) */5235shift=0; /* no multiplicand shift at first */5236madlength=D2U(lhs->digits); /* this won't change */5237mermsup=rhs->lsu+D2U(rhs->digits); /* -> msu+1 of multiplier */5238
5239for (mer=rhs->lsu; mer<mermsup; mer++) {5240/* Here, *mer is the next Unit in the multiplier to use */5241/* If non-zero [optimization] add it... */5242if (*mer!=0) accunits=decUnitAddSub(&acc[shift], accunits-shift,5243lhs->lsu, madlength, 0,5244&acc[shift], *mer)5245+ shift;5246else { /* extend acc with a 0; it will be used shortly */5247*(acc+accunits)=0; /* [this avoids length of <=0 later] */5248accunits++;5249}5250/* multiply multiplicand by 10**DECDPUN for next Unit to left */5251shift++; /* add this for 'logical length' */5252} /* n */5253#if FASTMUL5254} /* unchunked units */5255#endif5256/* common end-path */5257#if DECTRACE5258decDumpAr('*', acc, accunits); /* Show exact result */5259#endif5260
5261/* acc now contains the exact result of the multiplication, */5262/* possibly with a leading zero unit; build the decNumber from */5263/* it, noting if any residue */5264res->bits=bits; /* set sign */5265res->digits=decGetDigits(acc, accunits); /* count digits exactly */5266
5267/* There can be a 31-bit wrap in calculating the exponent. */5268/* This can only happen if both input exponents are negative and */5269/* both their magnitudes are large. If there was a wrap, set a */5270/* safe very negative exponent, from which decFinalize() will */5271/* raise a hard underflow shortly. */5272exponent=lhs->exponent+rhs->exponent; /* calculate exponent */5273if (lhs->exponent<0 && rhs->exponent<0 && exponent>0)5274exponent=-2*DECNUMMAXE; /* force underflow */5275res->exponent=exponent; /* OK to overwrite now */5276
5277
5278/* Set the coefficient. If any rounding, residue records */5279decSetCoeff(res, set, acc, res->digits, &residue, status);5280decFinish(res, set, &residue, status); /* final cleanup */5281} while(0); /* end protected */5282
5283if (allocacc!=NULL) free(allocacc); /* drop any storage used */5284#if DECSUBSET5285if (allocrhs!=NULL) free(allocrhs); /* .. */5286if (alloclhs!=NULL) free(alloclhs); /* .. */5287#endif5288#if FASTMUL5289if (allocrhi!=NULL) free(allocrhi); /* .. */5290if (alloclhi!=NULL) free(alloclhi); /* .. */5291#endif5292return res;5293} /* decMultiplyOp */5294
5295/* ------------------------------------------------------------------ */
5296/* decExpOp -- effect exponentiation */
5297/* */
5298/* This computes C = exp(A) */
5299/* */
5300/* res is C, the result. C may be A */
5301/* rhs is A */
5302/* set is the context; note that rounding mode has no effect */
5303/* */
5304/* C must have space for set->digits digits. status is updated but */
5305/* not set. */
5306/* */
5307/* Restrictions: */
5308/* */
5309/* digits, emax, and -emin in the context must be less than */
5310/* 2*DEC_MAX_MATH (1999998), and the rhs must be within these */
5311/* bounds or a zero. This is an internal routine, so these */
5312/* restrictions are contractual and not enforced. */
5313/* */
5314/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will */
5315/* almost always be correctly rounded, but may be up to 1 ulp in */
5316/* error in rare cases. */
5317/* */
5318/* Finite results will always be full precision and Inexact, except */
5319/* when A is a zero or -Infinity (giving 1 or 0 respectively). */
5320/* ------------------------------------------------------------------ */
5321/* This approach used here is similar to the algorithm described in */
5322/* */
5323/* Variable Precision Exponential Function, T. E. Hull and */
5324/* A. Abrham, ACM Transactions on Mathematical Software, Vol 12 #2, */
5325/* pp79-91, ACM, June 1986. */
5326/* */
5327/* with the main difference being that the iterations in the series */
5328/* evaluation are terminated dynamically (which does not require the */
5329/* extra variable-precision variables which are expensive in this */
5330/* context). */
5331/* */
5332/* The error analysis in Hull & Abrham's paper applies except for the */
5333/* round-off error accumulation during the series evaluation. This */
5334/* code does not precalculate the number of iterations and so cannot */
5335/* use Horner's scheme. Instead, the accumulation is done at double- */
5336/* precision, which ensures that the additions of the terms are exact */
5337/* and do not accumulate round-off (and any round-off errors in the */
5338/* terms themselves move 'to the right' faster than they can */
5339/* accumulate). This code also extends the calculation by allowing, */
5340/* in the spirit of other decNumber operators, the input to be more */
5341/* precise than the result (the precision used is based on the more */
5342/* precise of the input or requested result). */
5343/* */
5344/* Implementation notes: */
5345/* */
5346/* 1. This is separated out as decExpOp so it can be called from */
5347/* other Mathematical functions (notably Ln) with a wider range */
5348/* than normal. In particular, it can handle the slightly wider */
5349/* (double) range needed by Ln (which has to be able to calculate */
5350/* exp(-x) where x can be the tiniest number (Ntiny). */
5351/* */
5352/* 2. Normalizing x to be <=0.1 (instead of <=1) reduces loop */
5353/* iterations by approximately a third with additional (although */
5354/* diminishing) returns as the range is reduced to even smaller */
5355/* fractions. However, h (the power of 10 used to correct the */
5356/* result at the end, see below) must be kept <=8 as otherwise */
5357/* the final result cannot be computed. Hence the leverage is a */
5358/* sliding value (8-h), where potentially the range is reduced */
5359/* more for smaller values. */
5360/* */
5361/* The leverage that can be applied in this way is severely */
5362/* limited by the cost of the raise-to-the power at the end, */
5363/* which dominates when the number of iterations is small (less */
5364/* than ten) or when rhs is short. As an example, the adjustment */
5365/* x**10,000,000 needs 31 multiplications, all but one full-width. */
5366/* */
5367/* 3. The restrictions (especially precision) could be raised with */
5368/* care, but the full decNumber range seems very hard within the */
5369/* 32-bit limits. */
5370/* */
5371/* 4. The working precisions for the static buffers are twice the */
5372/* obvious size to allow for calls from decNumberPower. */
5373/* ------------------------------------------------------------------ */
5374static decNumber *decExpOp(decNumber *res, const decNumber *rhs,5375decContext *set, uInt *status) {5376uInt ignore=0; /* working status */5377Int h; /* adjusted exponent for 0.xxxx */5378Int p; /* working precision */5379Int residue; /* rounding residue */5380uInt needbytes; /* for space calculations */5381const decNumber *x=rhs; /* (may point to safe copy later) */5382decContext aset, tset, dset; /* working contexts */5383Int comp; /* work */5384
5385/* the argument is often copied to normalize it, so (unusually) it */5386/* is treated like other buffers, using DECBUFFER, +1 in case */5387/* DECBUFFER is 0 */5388decNumber bufr[D2N(DECBUFFER*2+1)];5389decNumber *allocrhs=NULL; /* non-NULL if rhs buffer allocated */5390
5391/* the working precision will be no more than set->digits+8+1 */5392/* so for on-stack buffers DECBUFFER+9 is used, +1 in case DECBUFFER */5393/* is 0 (and twice that for the accumulator) */5394
5395/* buffer for t, term (working precision plus) */5396decNumber buft[D2N(DECBUFFER*2+9+1)];5397decNumber *allocbuft=NULL; /* -> allocated buft, iff allocated */5398decNumber *t=buft; /* term */5399/* buffer for a, accumulator (working precision * 2), at least 9 */5400decNumber bufa[D2N(DECBUFFER*4+18+1)];5401decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */5402decNumber *a=bufa; /* accumulator */5403/* decNumber for the divisor term; this needs at most 9 digits */5404/* and so can be fixed size [16 so can use standard context] */5405decNumber bufd[D2N(16)];5406decNumber *d=bufd; /* divisor */5407decNumber numone; /* constant 1 */5408
5409#if DECCHECK5410Int iterations=0; /* for later sanity check */5411if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;5412#endif5413
5414do { /* protect allocated storage */5415if (SPECIALARG) { /* handle infinities and NaNs */5416if (decNumberIsInfinite(rhs)) { /* an infinity */5417if (decNumberIsNegative(rhs)) /* -Infinity -> +0 */5418decNumberZero(res);5419else decNumberCopy(res, rhs); /* +Infinity -> self */5420}5421else decNaNs(res, rhs, NULL, set, status); /* a NaN */5422break;}5423
5424if (ISZERO(rhs)) { /* zeros -> exact 1 */5425decNumberZero(res); /* make clean 1 */5426*res->lsu=1; /* .. */5427break;} /* [no status to set] */5428
5429/* e**x when 0 < x < 0.66 is < 1+3x/2, hence can fast-path */5430/* positive and negative tiny cases which will result in inexact */5431/* 1. This also allows the later add-accumulate to always be */5432/* exact (because its length will never be more than twice the */5433/* working precision). */5434/* The comparator (tiny) needs just one digit, so use the */5435/* decNumber d for it (reused as the divisor, etc., below); its */5436/* exponent is such that if x is positive it will have */5437/* set->digits-1 zeros between the decimal point and the digit, */5438/* which is 4, and if x is negative one more zero there as the */5439/* more precise result will be of the form 0.9999999 rather than */5440/* 1.0000001. Hence, tiny will be 0.0000004 if digits=7 and x>0 */5441/* or 0.00000004 if digits=7 and x<0. If RHS not larger than */5442/* this then the result will be 1.000000 */5443decNumberZero(d); /* clean */5444*d->lsu=4; /* set 4 .. */5445d->exponent=-set->digits; /* * 10**(-d) */5446if (decNumberIsNegative(rhs)) d->exponent--; /* negative case */5447comp=decCompare(d, rhs, 1); /* signless compare */5448if (comp==BADINT) {5449*status|=DEC_Insufficient_storage;5450break;}5451if (comp>=0) { /* rhs < d */5452Int shift=set->digits-1;5453decNumberZero(res); /* set 1 */5454*res->lsu=1; /* .. */5455res->digits=decShiftToMost(res->lsu, 1, shift);5456res->exponent=-shift; /* make 1.0000... */5457*status|=DEC_Inexact | DEC_Rounded; /* .. inexactly */5458break;} /* tiny */5459
5460/* set up the context to be used for calculating a, as this is */5461/* used on both paths below */5462decContextDefault(&aset, DEC_INIT_DECIMAL64);5463/* accumulator bounds are as requested (could underflow) */5464aset.emax=set->emax; /* usual bounds */5465aset.emin=set->emin; /* .. */5466aset.clamp=0; /* and no concrete format */5467
5468/* calculate the adjusted (Hull & Abrham) exponent (where the */5469/* decimal point is just to the left of the coefficient msd) */5470h=rhs->exponent+rhs->digits;5471/* if h>8 then 10**h cannot be calculated safely; however, when */5472/* h=8 then exp(|rhs|) will be at least exp(1E+7) which is at */5473/* least 6.59E+4342944, so (due to the restriction on Emax/Emin) */5474/* overflow (or underflow to 0) is guaranteed -- so this case can */5475/* be handled by simply forcing the appropriate excess */5476if (h>8) { /* overflow/underflow */5477/* set up here so Power call below will over or underflow to */5478/* zero; set accumulator to either 2 or 0.02 */5479/* [stack buffer for a is always big enough for this] */5480decNumberZero(a);5481*a->lsu=2; /* not 1 but < exp(1) */5482if (decNumberIsNegative(rhs)) a->exponent=-2; /* make 0.02 */5483h=8; /* clamp so 10**h computable */5484p=9; /* set a working precision */5485}5486else { /* h<=8 */5487Int maxlever=(rhs->digits>8?1:0);5488/* [could/should increase this for precisions >40 or so, too] */5489
5490/* if h is 8, cannot normalize to a lower upper limit because */5491/* the final result will not be computable (see notes above), */5492/* but leverage can be applied whenever h is less than 8. */5493/* Apply as much as possible, up to a MAXLEVER digits, which */5494/* sets the tradeoff against the cost of the later a**(10**h). */5495/* As h is increased, the working precision below also */5496/* increases to compensate for the "constant digits at the */5497/* front" effect. */5498Int lever=MINI(8-h, maxlever); /* leverage attainable */5499Int use=-rhs->digits-lever; /* exponent to use for RHS */5500h+=lever; /* apply leverage selected */5501if (h<0) { /* clamp */5502use+=h; /* [may end up subnormal] */5503h=0;5504}5505/* Take a copy of RHS if it needs normalization (true whenever x>=1) */5506if (rhs->exponent!=use) {5507decNumber *newrhs=bufr; /* assume will fit on stack */5508needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);5509if (needbytes>sizeof(bufr)) { /* need malloc space */5510allocrhs=(decNumber *)malloc(needbytes);5511if (allocrhs==NULL) { /* hopeless -- abandon */5512*status|=DEC_Insufficient_storage;5513break;}5514newrhs=allocrhs; /* use the allocated space */5515}5516decNumberCopy(newrhs, rhs); /* copy to safe space */5517newrhs->exponent=use; /* normalize; now <1 */5518x=newrhs; /* ready for use */5519/* decNumberShow(x); */5520}5521
5522/* Now use the usual power series to evaluate exp(x). The */5523/* series starts as 1 + x + x^2/2 ... so prime ready for the */5524/* third term by setting the term variable t=x, the accumulator */5525/* a=1, and the divisor d=2. */5526
5527/* First determine the working precision. From Hull & Abrham */5528/* this is set->digits+h+2. However, if x is 'over-precise' we */5529/* need to allow for all its digits to potentially participate */5530/* (consider an x where all the excess digits are 9s) so in */5531/* this case use x->digits+h+2 */5532p=MAXI(x->digits, set->digits)+h+2; /* [h<=8] */5533
5534/* a and t are variable precision, and depend on p, so space */5535/* must be allocated for them if necessary */5536
5537/* the accumulator needs to be able to hold 2p digits so that */5538/* the additions on the second and subsequent iterations are */5539/* sufficiently exact. */5540needbytes=sizeof(decNumber)+(D2U(p*2)-1)*sizeof(Unit);5541if (needbytes>sizeof(bufa)) { /* need malloc space */5542allocbufa=(decNumber *)malloc(needbytes);5543if (allocbufa==NULL) { /* hopeless -- abandon */5544*status|=DEC_Insufficient_storage;5545break;}5546a=allocbufa; /* use the allocated space */5547}5548/* the term needs to be able to hold p digits (which is */5549/* guaranteed to be larger than x->digits, so the initial copy */5550/* is safe); it may also be used for the raise-to-power */5551/* calculation below, which needs an extra two digits */5552needbytes=sizeof(decNumber)+(D2U(p+2)-1)*sizeof(Unit);5553if (needbytes>sizeof(buft)) { /* need malloc space */5554allocbuft=(decNumber *)malloc(needbytes);5555if (allocbuft==NULL) { /* hopeless -- abandon */5556*status|=DEC_Insufficient_storage;5557break;}5558t=allocbuft; /* use the allocated space */5559}5560
5561decNumberCopy(t, x); /* term=x */5562decNumberZero(a); *a->lsu=1; /* accumulator=1 */5563decNumberZero(d); *d->lsu=2; /* divisor=2 */5564decNumberZero(&numone); *numone.lsu=1; /* constant 1 for increment */5565
5566/* set up the contexts for calculating a, t, and d */5567decContextDefault(&tset, DEC_INIT_DECIMAL64);5568dset=tset;5569/* accumulator bounds are set above, set precision now */5570aset.digits=p*2; /* double */5571/* term bounds avoid any underflow or overflow */5572tset.digits=p;5573tset.emin=DEC_MIN_EMIN; /* [emax is plenty] */5574/* [dset.digits=16, etc., are sufficient] */5575
5576/* finally ready to roll */5577for (;;) {5578#if DECCHECK5579iterations++;5580#endif5581/* only the status from the accumulation is interesting */5582/* [but it should remain unchanged after first add] */5583decAddOp(a, a, t, &aset, 0, status); /* a=a+t */5584decMultiplyOp(t, t, x, &tset, &ignore); /* t=t*x */5585decDivideOp(t, t, d, &tset, DIVIDE, &ignore); /* t=t/d */5586/* the iteration ends when the term cannot affect the result, */5587/* if rounded to p digits, which is when its value is smaller */5588/* than the accumulator by p+1 digits. There must also be */5589/* full precision in a. */5590if (((a->digits+a->exponent)>=(t->digits+t->exponent+p+1))5591&& (a->digits>=p)) break;5592decAddOp(d, d, &numone, &dset, 0, &ignore); /* d=d+1 */5593} /* iterate */5594
5595#if DECCHECK5596/* just a sanity check; comment out test to show always */5597if (iterations>p+3)5598printf("Exp iterations=%ld, status=%08lx, p=%ld, d=%ld\n",5599iterations, *status, p, x->digits);5600#endif5601} /* h<=8 */5602
5603/* apply postconditioning: a=a**(10**h) -- this is calculated */5604/* at a slightly higher precision than Hull & Abrham suggest */5605if (h>0) {5606Int seenbit=0; /* set once a 1-bit is seen */5607Int i; /* counter */5608Int n=powers[h]; /* always positive */5609aset.digits=p+2; /* sufficient precision */5610/* avoid the overhead and many extra digits of decNumberPower */5611/* as all that is needed is the short 'multipliers' loop; here */5612/* accumulate the answer into t */5613decNumberZero(t); *t->lsu=1; /* acc=1 */5614for (i=1;;i++){ /* for each bit [top bit ignored] */5615/* abandon if have had overflow or terminal underflow */5616if (*status & (DEC_Overflow|DEC_Underflow)) { /* interesting? */5617if (*status&DEC_Overflow || ISZERO(t)) break;}5618n=n<<1; /* move next bit to testable position */5619if (n<0) { /* top bit is set */5620seenbit=1; /* OK, have a significant bit */5621decMultiplyOp(t, t, a, &aset, status); /* acc=acc*x */5622}5623if (i==31) break; /* that was the last bit */5624if (!seenbit) continue; /* no need to square 1 */5625decMultiplyOp(t, t, t, &aset, status); /* acc=acc*acc [square] */5626} /*i*/ /* 32 bits */5627/* decNumberShow(t); */5628a=t; /* and carry on using t instead of a */5629}5630
5631/* Copy and round the result to res */5632residue=1; /* indicate dirt to right .. */5633if (ISZERO(a)) residue=0; /* .. unless underflowed to 0 */5634aset.digits=set->digits; /* [use default rounding] */5635decCopyFit(res, a, &aset, &residue, status); /* copy & shorten */5636decFinish(res, set, &residue, status); /* cleanup/set flags */5637} while(0); /* end protected */5638
5639if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */5640if (allocbufa!=NULL) free(allocbufa); /* .. */5641if (allocbuft!=NULL) free(allocbuft); /* .. */5642/* [status is handled by caller] */5643return res;5644} /* decExpOp */5645
5646/* ------------------------------------------------------------------ */
5647/* Initial-estimate natural logarithm table */
5648/* */
5649/* LNnn -- 90-entry 16-bit table for values from .10 through .99. */
5650/* The result is a 4-digit encode of the coefficient (c=the */
5651/* top 14 bits encoding 0-9999) and a 2-digit encode of the */
5652/* exponent (e=the bottom 2 bits encoding 0-3) */
5653/* */
5654/* The resulting value is given by: */
5655/* */
5656/* v = -c * 10**(-e-3) */
5657/* */
5658/* where e and c are extracted from entry k = LNnn[x-10] */
5659/* where x is truncated (NB) into the range 10 through 99, */
5660/* and then c = k>>2 and e = k&3. */
5661/* ------------------------------------------------------------------ */
5662static const uShort LNnn[90] = {56639016, 8652, 8316, 8008, 7724, 7456, 7208,56646972, 6748, 6540, 6340, 6148, 5968, 5792, 5628, 5464, 5312,56655164, 5020, 4884, 4748, 4620, 4496, 4376, 4256, 4144, 4032,566639233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629,566729777, 28945, 28129, 27329, 26545, 25777, 25021, 24281, 23553, 22837,566822137, 21445, 20769, 20101, 19445, 18801, 18165, 17541, 16925, 16321,566915721, 15133, 14553, 13985, 13421, 12865, 12317, 11777, 11241, 10717,567010197, 9685, 9177, 8677, 8185, 7697, 7213, 6737, 6269, 5801,56715341, 4889, 4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254,567210130, 6046, 20055};5673
5674/* ------------------------------------------------------------------ */
5675/* decLnOp -- effect natural logarithm */
5676/* */
5677/* This computes C = ln(A) */
5678/* */
5679/* res is C, the result. C may be A */
5680/* rhs is A */
5681/* set is the context; note that rounding mode has no effect */
5682/* */
5683/* C must have space for set->digits digits. */
5684/* */
5685/* Notable cases: */
5686/* A<0 -> Invalid */
5687/* A=0 -> -Infinity (Exact) */
5688/* A=+Infinity -> +Infinity (Exact) */
5689/* A=1 exactly -> 0 (Exact) */
5690/* */
5691/* Restrictions (as for Exp): */
5692/* */
5693/* digits, emax, and -emin in the context must be less than */
5694/* DEC_MAX_MATH+11 (1000010), and the rhs must be within these */
5695/* bounds or a zero. This is an internal routine, so these */
5696/* restrictions are contractual and not enforced. */
5697/* */
5698/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will */
5699/* almost always be correctly rounded, but may be up to 1 ulp in */
5700/* error in rare cases. */
5701/* ------------------------------------------------------------------ */
5702/* The result is calculated using Newton's method, with each */
5703/* iteration calculating a' = a + x * exp(-a) - 1. See, for example, */
5704/* Epperson 1989. */
5705/* */
5706/* The iteration ends when the adjustment x*exp(-a)-1 is tiny enough. */
5707/* This has to be calculated at the sum of the precision of x and the */
5708/* working precision. */
5709/* */
5710/* Implementation notes: */
5711/* */
5712/* 1. This is separated out as decLnOp so it can be called from */
5713/* other Mathematical functions (e.g., Log 10) with a wider range */
5714/* than normal. In particular, it can handle the slightly wider */
5715/* (+9+2) range needed by a power function. */
5716/* */
5717/* 2. The speed of this function is about 10x slower than exp, as */
5718/* it typically needs 4-6 iterations for short numbers, and the */
5719/* extra precision needed adds a squaring effect, twice. */
5720/* */
5721/* 3. Fastpaths are included for ln(10) and ln(2), up to length 40, */
5722/* as these are common requests. ln(10) is used by log10(x). */
5723/* */
5724/* 4. An iteration might be saved by widening the LNnn table, and */
5725/* would certainly save at least one if it were made ten times */
5726/* bigger, too (for truncated fractions 0.100 through 0.999). */
5727/* However, for most practical evaluations, at least four or five */
5728/* iterations will be needed -- so this would only speed up by */
5729/* 20-25% and that probably does not justify increasing the table */
5730/* size. */
5731/* */
5732/* 5. The static buffers are larger than might be expected to allow */
5733/* for calls from decNumberPower. */
5734/* ------------------------------------------------------------------ */
5735static decNumber *decLnOp(decNumber *res, const decNumber *rhs,5736decContext *set, uInt *status) {5737uInt ignore=0; /* working status accumulator */5738uInt needbytes; /* for space calculations */5739Int residue; /* rounding residue */5740Int r; /* rhs=f*10**r [see below] */5741Int p; /* working precision */5742Int pp; /* precision for iteration */5743Int t; /* work */5744
5745/* buffers for a (accumulator, typically precision+2) and b */5746/* (adjustment calculator, same size) */5747decNumber bufa[D2N(DECBUFFER+12)];5748decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */5749decNumber *a=bufa; /* accumulator/work */5750decNumber bufb[D2N(DECBUFFER*2+2)];5751decNumber *allocbufb=NULL; /* -> allocated bufa, iff allocated */5752decNumber *b=bufb; /* adjustment/work */5753
5754decNumber numone; /* constant 1 */5755decNumber cmp; /* work */5756decContext aset, bset; /* working contexts */5757
5758#if DECCHECK5759Int iterations=0; /* for later sanity check */5760if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;5761#endif5762
5763do { /* protect allocated storage */5764if (SPECIALARG) { /* handle infinities and NaNs */5765if (decNumberIsInfinite(rhs)) { /* an infinity */5766if (decNumberIsNegative(rhs)) /* -Infinity -> error */5767*status|=DEC_Invalid_operation;5768else decNumberCopy(res, rhs); /* +Infinity -> self */5769}5770else decNaNs(res, rhs, NULL, set, status); /* a NaN */5771break;}5772
5773if (ISZERO(rhs)) { /* +/- zeros -> -Infinity */5774decNumberZero(res); /* make clean */5775res->bits=DECINF|DECNEG; /* set - infinity */5776break;} /* [no status to set] */5777
5778/* Non-zero negatives are bad... */5779if (decNumberIsNegative(rhs)) { /* -x -> error */5780*status|=DEC_Invalid_operation;5781break;}5782
5783/* Here, rhs is positive, finite, and in range */5784
5785/* lookaside fastpath code for ln(2) and ln(10) at common lengths */5786if (rhs->exponent==0 && set->digits<=40) {5787#if DECDPUN==15788if (rhs->lsu[0]==0 && rhs->lsu[1]==1 && rhs->digits==2) { /* ln(10) */5789#else5790if (rhs->lsu[0]==10 && rhs->digits==2) { /* ln(10) */5791#endif5792aset=*set; aset.round=DEC_ROUND_HALF_EVEN;5793#define LN10 "2.302585092994045684017991454684364207601"5794decNumberFromString(res, LN10, &aset);5795*status|=(DEC_Inexact | DEC_Rounded); /* is inexact */5796break;}5797if (rhs->lsu[0]==2 && rhs->digits==1) { /* ln(2) */5798aset=*set; aset.round=DEC_ROUND_HALF_EVEN;5799#define LN2 "0.6931471805599453094172321214581765680755"5800decNumberFromString(res, LN2, &aset);5801*status|=(DEC_Inexact | DEC_Rounded);5802break;}5803} /* integer and short */5804
5805/* Determine the working precision. This is normally the */5806/* requested precision + 2, with a minimum of 9. However, if */5807/* the rhs is 'over-precise' then allow for all its digits to */5808/* potentially participate (consider an rhs where all the excess */5809/* digits are 9s) so in this case use rhs->digits+2. */5810p=MAXI(rhs->digits, MAXI(set->digits, 7))+2;5811
5812/* Allocate space for the accumulator and the high-precision */5813/* adjustment calculator, if necessary. The accumulator must */5814/* be able to hold p digits, and the adjustment up to */5815/* rhs->digits+p digits. They are also made big enough for 16 */5816/* digits so that they can be used for calculating the initial */5817/* estimate. */5818needbytes=sizeof(decNumber)+(D2U(MAXI(p,16))-1)*sizeof(Unit);5819if (needbytes>sizeof(bufa)) { /* need malloc space */5820allocbufa=(decNumber *)malloc(needbytes);5821if (allocbufa==NULL) { /* hopeless -- abandon */5822*status|=DEC_Insufficient_storage;5823break;}5824a=allocbufa; /* use the allocated space */5825}5826pp=p+rhs->digits;5827needbytes=sizeof(decNumber)+(D2U(MAXI(pp,16))-1)*sizeof(Unit);5828if (needbytes>sizeof(bufb)) { /* need malloc space */5829allocbufb=(decNumber *)malloc(needbytes);5830if (allocbufb==NULL) { /* hopeless -- abandon */5831*status|=DEC_Insufficient_storage;5832break;}5833b=allocbufb; /* use the allocated space */5834}5835
5836/* Prepare an initial estimate in acc. Calculate this by */5837/* considering the coefficient of x to be a normalized fraction, */5838/* f, with the decimal point at far left and multiplied by */5839/* 10**r. Then, rhs=f*10**r and 0.1<=f<1, and */5840/* ln(x) = ln(f) + ln(10)*r */5841/* Get the initial estimate for ln(f) from a small lookup */5842/* table (see above) indexed by the first two digits of f, */5843/* truncated. */5844
5845decContextDefault(&aset, DEC_INIT_DECIMAL64); /* 16-digit extended */5846r=rhs->exponent+rhs->digits; /* 'normalised' exponent */5847decNumberFromInt32(a, r); /* a=r */5848decNumberFromInt32(b, 2302585); /* b=ln(10) (2.302585) */5849b->exponent=-6; /* .. */5850decMultiplyOp(a, a, b, &aset, &ignore); /* a=a*b */5851/* now get top two digits of rhs into b by simple truncate and */5852/* force to integer */5853residue=0; /* (no residue) */5854aset.digits=2; aset.round=DEC_ROUND_DOWN;5855decCopyFit(b, rhs, &aset, &residue, &ignore); /* copy & shorten */5856b->exponent=0; /* make integer */5857t=decGetInt(b); /* [cannot fail] */5858if (t<10) t=X10(t); /* adjust single-digit b */5859t=LNnn[t-10]; /* look up ln(b) */5860decNumberFromInt32(b, t>>2); /* b=ln(b) coefficient */5861b->exponent=-(t&3)-3; /* set exponent */5862b->bits=DECNEG; /* ln(0.10)->ln(0.99) always -ve */5863aset.digits=16; aset.round=DEC_ROUND_HALF_EVEN; /* restore */5864decAddOp(a, a, b, &aset, 0, &ignore); /* acc=a+b */5865/* the initial estimate is now in a, with up to 4 digits correct. */5866/* When rhs is at or near Nmax the estimate will be low, so we */5867/* will approach it from below, avoiding overflow when calling exp. */5868
5869decNumberZero(&numone); *numone.lsu=1; /* constant 1 for adjustment */5870
5871/* accumulator bounds are as requested (could underflow, but */5872/* cannot overflow) */5873aset.emax=set->emax;5874aset.emin=set->emin;5875aset.clamp=0; /* no concrete format */5876/* set up a context to be used for the multiply and subtract */5877bset=aset;5878bset.emax=DEC_MAX_MATH*2; /* use double bounds for the */5879bset.emin=-DEC_MAX_MATH*2; /* adjustment calculation */5880/* [see decExpOp call below] */5881/* for each iteration double the number of digits to calculate, */5882/* up to a maximum of p */5883pp=9; /* initial precision */5884/* [initially 9 as then the sequence starts 7+2, 16+2, and */5885/* 34+2, which is ideal for standard-sized numbers] */5886aset.digits=pp; /* working context */5887bset.digits=pp+rhs->digits; /* wider context */5888for (;;) { /* iterate */5889#if DECCHECK5890iterations++;5891if (iterations>24) break; /* consider 9 * 2**24 */5892#endif5893/* calculate the adjustment (exp(-a)*x-1) into b. This is a */5894/* catastrophic subtraction but it really is the difference */5895/* from 1 that is of interest. */5896/* Use the internal entry point to Exp as it allows the double */5897/* range for calculating exp(-a) when a is the tiniest subnormal. */5898a->bits^=DECNEG; /* make -a */5899decExpOp(b, a, &bset, &ignore); /* b=exp(-a) */5900a->bits^=DECNEG; /* restore sign of a */5901/* now multiply by rhs and subtract 1, at the wider precision */5902decMultiplyOp(b, b, rhs, &bset, &ignore); /* b=b*rhs */5903decAddOp(b, b, &numone, &bset, DECNEG, &ignore); /* b=b-1 */5904
5905/* the iteration ends when the adjustment cannot affect the */5906/* result by >=0.5 ulp (at the requested digits), which */5907/* is when its value is smaller than the accumulator by */5908/* set->digits+1 digits (or it is zero) -- this is a looser */5909/* requirement than for Exp because all that happens to the */5910/* accumulator after this is the final rounding (but note that */5911/* there must also be full precision in a, or a=0). */5912
5913if (decNumberIsZero(b) ||5914(a->digits+a->exponent)>=(b->digits+b->exponent+set->digits+1)) {5915if (a->digits==p) break;5916if (decNumberIsZero(a)) {5917decCompareOp(&cmp, rhs, &numone, &aset, COMPARE, &ignore); /* rhs=1 ? */5918if (cmp.lsu[0]==0) a->exponent=0; /* yes, exact 0 */5919else *status|=(DEC_Inexact | DEC_Rounded); /* no, inexact */5920break;5921}5922/* force padding if adjustment has gone to 0 before full length */5923if (decNumberIsZero(b)) b->exponent=a->exponent-p;5924}5925
5926/* not done yet ... */5927decAddOp(a, a, b, &aset, 0, &ignore); /* a=a+b for next estimate */5928if (pp==p) continue; /* precision is at maximum */5929/* lengthen the next calculation */5930pp=pp*2; /* double precision */5931if (pp>p) pp=p; /* clamp to maximum */5932aset.digits=pp; /* working context */5933bset.digits=pp+rhs->digits; /* wider context */5934} /* Newton's iteration */5935
5936#if DECCHECK5937/* just a sanity check; remove the test to show always */5938if (iterations>24)5939printf("Ln iterations=%ld, status=%08lx, p=%ld, d=%ld\n",5940iterations, *status, p, rhs->digits);5941#endif5942
5943/* Copy and round the result to res */5944residue=1; /* indicate dirt to right */5945if (ISZERO(a)) residue=0; /* .. unless underflowed to 0 */5946aset.digits=set->digits; /* [use default rounding] */5947decCopyFit(res, a, &aset, &residue, status); /* copy & shorten */5948decFinish(res, set, &residue, status); /* cleanup/set flags */5949} while(0); /* end protected */5950
5951if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */5952if (allocbufb!=NULL) free(allocbufb); /* .. */5953/* [status is handled by caller] */5954return res;5955} /* decLnOp */5956
5957/* ------------------------------------------------------------------ */
5958/* decQuantizeOp -- force exponent to requested value */
5959/* */
5960/* This computes C = op(A, B), where op adjusts the coefficient */
5961/* of C (by rounding or shifting) such that the exponent (-scale) */
5962/* of C has the value B or matches the exponent of B. */
5963/* The numerical value of C will equal A, except for the effects of */
5964/* any rounding that occurred. */
5965/* */
5966/* res is C, the result. C may be A or B */
5967/* lhs is A, the number to adjust */
5968/* rhs is B, the requested exponent */
5969/* set is the context */
5970/* quant is 1 for quantize or 0 for rescale */
5971/* status is the status accumulator (this can be called without */
5972/* risk of control loss) */
5973/* */
5974/* C must have space for set->digits digits. */
5975/* */
5976/* Unless there is an error or the result is infinite, the exponent */
5977/* after the operation is guaranteed to be that requested. */
5978/* ------------------------------------------------------------------ */
5979static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs,5980const decNumber *rhs, decContext *set,5981Flag quant, uInt *status) {5982#if DECSUBSET5983decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */5984decNumber *allocrhs=NULL; /* .., rhs */5985#endif5986const decNumber *inrhs=rhs; /* save original rhs */5987Int reqdigits=set->digits; /* requested DIGITS */5988Int reqexp; /* requested exponent [-scale] */5989Int residue=0; /* rounding residue */5990Int etiny=set->emin-(reqdigits-1);5991
5992#if DECCHECK5993if (decCheckOperands(res, lhs, rhs, set)) return res;5994#endif5995
5996do { /* protect allocated storage */5997#if DECSUBSET5998if (!set->extended) {5999/* reduce operands and set lostDigits status, as needed */6000if (lhs->digits>reqdigits) {6001alloclhs=decRoundOperand(lhs, set, status);6002if (alloclhs==NULL) break;6003lhs=alloclhs;6004}6005if (rhs->digits>reqdigits) { /* [this only checks lostDigits] */6006allocrhs=decRoundOperand(rhs, set, status);6007if (allocrhs==NULL) break;6008rhs=allocrhs;6009}6010}6011#endif6012/* [following code does not require input rounding] */6013
6014/* Handle special values */6015if (SPECIALARGS) {6016/* NaNs get usual processing */6017if (SPECIALARGS & (DECSNAN | DECNAN))6018decNaNs(res, lhs, rhs, set, status);6019/* one infinity but not both is bad */6020else if ((lhs->bits ^ rhs->bits) & DECINF)6021*status|=DEC_Invalid_operation;6022/* both infinity: return lhs */6023else decNumberCopy(res, lhs); /* [nop if in place] */6024break;6025}6026
6027/* set requested exponent */6028if (quant) reqexp=inrhs->exponent; /* quantize -- match exponents */6029else { /* rescale -- use value of rhs */6030/* Original rhs must be an integer that fits and is in range, */6031/* which could be from -1999999997 to +999999999, thanks to */6032/* subnormals */6033reqexp=decGetInt(inrhs); /* [cannot fail] */6034}6035
6036#if DECSUBSET6037if (!set->extended) etiny=set->emin; /* no subnormals */6038#endif6039
6040if (reqexp==BADINT /* bad (rescale only) or .. */6041|| reqexp==BIGODD || reqexp==BIGEVEN /* very big (ditto) or .. */6042|| (reqexp<etiny) /* < lowest */6043|| (reqexp>set->emax)) { /* > emax */6044*status|=DEC_Invalid_operation;6045break;}6046
6047/* the RHS has been processed, so it can be overwritten now if necessary */6048if (ISZERO(lhs)) { /* zero coefficient unchanged */6049decNumberCopy(res, lhs); /* [nop if in place] */6050res->exponent=reqexp; /* .. just set exponent */6051#if DECSUBSET6052if (!set->extended) res->bits=0; /* subset specification; no -0 */6053#endif6054}6055else { /* non-zero lhs */6056Int adjust=reqexp-lhs->exponent; /* digit adjustment needed */6057/* if adjusted coefficient will definitely not fit, give up now */6058if ((lhs->digits-adjust)>reqdigits) {6059*status|=DEC_Invalid_operation;6060break;6061}6062
6063if (adjust>0) { /* increasing exponent */6064/* this will decrease the length of the coefficient by adjust */6065/* digits, and must round as it does so */6066decContext workset; /* work */6067workset=*set; /* clone rounding, etc. */6068workset.digits=lhs->digits-adjust; /* set requested length */6069/* [note that the latter can be <1, here] */6070decCopyFit(res, lhs, &workset, &residue, status); /* fit to result */6071decApplyRound(res, &workset, residue, status); /* .. and round */6072residue=0; /* [used] */6073/* If just rounded a 999s case, exponent will be off by one; */6074/* adjust back (after checking space), if so. */6075if (res->exponent>reqexp) {6076/* re-check needed, e.g., for quantize(0.9999, 0.001) under */6077/* set->digits==3 */6078if (res->digits==reqdigits) { /* cannot shift by 1 */6079*status&=~(DEC_Inexact | DEC_Rounded); /* [clean these] */6080*status|=DEC_Invalid_operation;6081break;6082}6083res->digits=decShiftToMost(res->lsu, res->digits, 1); /* shift */6084res->exponent--; /* (re)adjust the exponent. */6085}6086#if DECSUBSET6087if (ISZERO(res) && !set->extended) res->bits=0; /* subset; no -0 */6088#endif6089} /* increase */6090else /* adjust<=0 */ { /* decreasing or = exponent */6091/* this will increase the length of the coefficient by -adjust */6092/* digits, by adding zero or more trailing zeros; this is */6093/* already checked for fit, above */6094decNumberCopy(res, lhs); /* [it will fit] */6095/* if padding needed (adjust<0), add it now... */6096if (adjust<0) {6097res->digits=decShiftToMost(res->lsu, res->digits, -adjust);6098res->exponent+=adjust; /* adjust the exponent */6099}6100} /* decrease */6101} /* non-zero */6102
6103/* Check for overflow [do not use Finalize in this case, as an */6104/* overflow here is a "don't fit" situation] */6105if (res->exponent>set->emax-res->digits+1) { /* too big */6106*status|=DEC_Invalid_operation;6107break;6108}6109else {6110decFinalize(res, set, &residue, status); /* set subnormal flags */6111*status&=~DEC_Underflow; /* suppress Underflow [754r] */6112}6113} while(0); /* end protected */6114
6115#if DECSUBSET6116if (allocrhs!=NULL) free(allocrhs); /* drop any storage used */6117if (alloclhs!=NULL) free(alloclhs); /* .. */6118#endif6119return res;6120} /* decQuantizeOp */6121
6122/* ------------------------------------------------------------------ */
6123/* decCompareOp -- compare, min, or max two Numbers */
6124/* */
6125/* This computes C = A ? B and carries out one of four operations: */
6126/* COMPARE -- returns the signum (as a number) giving the */
6127/* result of a comparison unless one or both */
6128/* operands is a NaN (in which case a NaN results) */
6129/* COMPSIG -- as COMPARE except that a quiet NaN raises */
6130/* Invalid operation. */
6131/* COMPMAX -- returns the larger of the operands, using the */
6132/* 754r maxnum operation */
6133/* COMPMAXMAG -- ditto, comparing absolute values */
6134/* COMPMIN -- the 754r minnum operation */
6135/* COMPMINMAG -- ditto, comparing absolute values */
6136/* COMTOTAL -- returns the signum (as a number) giving the */
6137/* result of a comparison using 754r total ordering */
6138/* */
6139/* res is C, the result. C may be A and/or B (e.g., X=X?X) */
6140/* lhs is A */
6141/* rhs is B */
6142/* set is the context */
6143/* op is the operation flag */
6144/* status is the usual accumulator */
6145/* */
6146/* C must have space for one digit for COMPARE or set->digits for */
6147/* COMPMAX, COMPMIN, COMPMAXMAG, or COMPMINMAG. */
6148/* ------------------------------------------------------------------ */
6149/* The emphasis here is on speed for common cases, and avoiding */
6150/* coefficient comparison if possible. */
6151/* ------------------------------------------------------------------ */
6152static decNumber *decCompareOp(decNumber *res, const decNumber *lhs,6153const decNumber *rhs, decContext *set,6154Flag op, uInt *status) {6155#if DECSUBSET6156decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */6157decNumber *allocrhs=NULL; /* .., rhs */6158#endif6159Int result=0; /* default result value */6160uByte merged; /* work */6161
6162#if DECCHECK6163if (decCheckOperands(res, lhs, rhs, set)) return res;6164#endif6165
6166do { /* protect allocated storage */6167#if DECSUBSET6168if (!set->extended) {6169/* reduce operands and set lostDigits status, as needed */6170if (lhs->digits>set->digits) {6171alloclhs=decRoundOperand(lhs, set, status);6172if (alloclhs==NULL) {result=BADINT; break;}6173lhs=alloclhs;6174}6175if (rhs->digits>set->digits) {6176allocrhs=decRoundOperand(rhs, set, status);6177if (allocrhs==NULL) {result=BADINT; break;}6178rhs=allocrhs;6179}6180}6181#endif6182/* [following code does not require input rounding] */6183
6184/* If total ordering then handle differing signs 'up front' */6185if (op==COMPTOTAL) { /* total ordering */6186if (decNumberIsNegative(lhs) && !decNumberIsNegative(rhs)) {6187result=-1;6188break;6189}6190if (!decNumberIsNegative(lhs) && decNumberIsNegative(rhs)) {6191result=+1;6192break;6193}6194}6195
6196/* handle NaNs specially; let infinities drop through */6197/* This assumes sNaN (even just one) leads to NaN. */6198merged=(lhs->bits | rhs->bits) & (DECSNAN | DECNAN);6199if (merged) { /* a NaN bit set */6200if (op==COMPARE); /* result will be NaN */6201else if (op==COMPSIG) /* treat qNaN as sNaN */6202*status|=DEC_Invalid_operation | DEC_sNaN;6203else if (op==COMPTOTAL) { /* total ordering, always finite */6204/* signs are known to be the same; compute the ordering here */6205/* as if the signs are both positive, then invert for negatives */6206if (!decNumberIsNaN(lhs)) result=-1;6207else if (!decNumberIsNaN(rhs)) result=+1;6208/* here if both NaNs */6209else if (decNumberIsSNaN(lhs) && decNumberIsQNaN(rhs)) result=-1;6210else if (decNumberIsQNaN(lhs) && decNumberIsSNaN(rhs)) result=+1;6211else { /* both NaN or both sNaN */6212/* now it just depends on the payload */6213result=decUnitCompare(lhs->lsu, D2U(lhs->digits),6214rhs->lsu, D2U(rhs->digits), 0);6215/* [Error not possible, as these are 'aligned'] */6216} /* both same NaNs */6217if (decNumberIsNegative(lhs)) result=-result;6218break;6219} /* total order */6220
6221else if (merged & DECSNAN); /* sNaN -> qNaN */6222else { /* here if MIN or MAX and one or two quiet NaNs */6223/* min or max -- 754r rules ignore single NaN */6224if (!decNumberIsNaN(lhs) || !decNumberIsNaN(rhs)) {6225/* just one NaN; force choice to be the non-NaN operand */6226op=COMPMAX;6227if (lhs->bits & DECNAN) result=-1; /* pick rhs */6228else result=+1; /* pick lhs */6229break;6230}6231} /* max or min */6232op=COMPNAN; /* use special path */6233decNaNs(res, lhs, rhs, set, status); /* propagate NaN */6234break;6235}6236/* have numbers */6237if (op==COMPMAXMAG || op==COMPMINMAG) result=decCompare(lhs, rhs, 1);6238else result=decCompare(lhs, rhs, 0); /* sign matters */6239} while(0); /* end protected */6240
6241if (result==BADINT) *status|=DEC_Insufficient_storage; /* rare */6242else {6243if (op==COMPARE || op==COMPSIG ||op==COMPTOTAL) { /* returning signum */6244if (op==COMPTOTAL && result==0) {6245/* operands are numerically equal or same NaN (and same sign, */6246/* tested first); if identical, leave result 0 */6247if (lhs->exponent!=rhs->exponent) {6248if (lhs->exponent<rhs->exponent) result=-1;6249else result=+1;6250if (decNumberIsNegative(lhs)) result=-result;6251} /* lexp!=rexp */6252} /* total-order by exponent */6253decNumberZero(res); /* [always a valid result] */6254if (result!=0) { /* must be -1 or +1 */6255*res->lsu=1;6256if (result<0) res->bits=DECNEG;6257}6258}6259else if (op==COMPNAN); /* special, drop through */6260else { /* MAX or MIN, non-NaN result */6261Int residue=0; /* rounding accumulator */6262/* choose the operand for the result */6263const decNumber *choice;6264if (result==0) { /* operands are numerically equal */6265/* choose according to sign then exponent (see 754r) */6266uByte slhs=(lhs->bits & DECNEG);6267uByte srhs=(rhs->bits & DECNEG);6268#if DECSUBSET6269if (!set->extended) { /* subset: force left-hand */6270op=COMPMAX;6271result=+1;6272}6273else6274#endif6275if (slhs!=srhs) { /* signs differ */6276if (slhs) result=-1; /* rhs is max */6277else result=+1; /* lhs is max */6278}6279else if (slhs && srhs) { /* both negative */6280if (lhs->exponent<rhs->exponent) result=+1;6281else result=-1;6282/* [if equal, use lhs, technically identical] */6283}6284else { /* both positive */6285if (lhs->exponent>rhs->exponent) result=+1;6286else result=-1;6287/* [ditto] */6288}6289} /* numerically equal */6290/* here result will be non-0; reverse if looking for MIN */6291if (op==COMPMIN || op==COMPMINMAG) result=-result;6292choice=(result>0 ? lhs : rhs); /* choose */6293/* copy chosen to result, rounding if need be */6294decCopyFit(res, choice, set, &residue, status);6295decFinish(res, set, &residue, status);6296}6297}6298#if DECSUBSET6299if (allocrhs!=NULL) free(allocrhs); /* free any storage used */6300if (alloclhs!=NULL) free(alloclhs); /* .. */6301#endif6302return res;6303} /* decCompareOp */6304
6305/* ------------------------------------------------------------------ */
6306/* decCompare -- compare two decNumbers by numerical value */
6307/* */
6308/* This routine compares A ? B without altering them. */
6309/* */
6310/* Arg1 is A, a decNumber which is not a NaN */
6311/* Arg2 is B, a decNumber which is not a NaN */
6312/* Arg3 is 1 for a sign-independent compare, 0 otherwise */
6313/* */
6314/* returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure */
6315/* (the only possible failure is an allocation error) */
6316/* ------------------------------------------------------------------ */
6317static Int decCompare(const decNumber *lhs, const decNumber *rhs,6318Flag abs) {6319Int result; /* result value */6320Int sigr; /* rhs signum */6321Int compare; /* work */6322
6323result=1; /* assume signum(lhs) */6324if (ISZERO(lhs)) result=0;6325if (abs) {6326if (ISZERO(rhs)) return result; /* LHS wins or both 0 */6327/* RHS is non-zero */6328if (result==0) return -1; /* LHS is 0; RHS wins */6329/* [here, both non-zero, result=1] */6330}6331else { /* signs matter */6332if (result && decNumberIsNegative(lhs)) result=-1;6333sigr=1; /* compute signum(rhs) */6334if (ISZERO(rhs)) sigr=0;6335else if (decNumberIsNegative(rhs)) sigr=-1;6336if (result > sigr) return +1; /* L > R, return 1 */6337if (result < sigr) return -1; /* L < R, return -1 */6338if (result==0) return 0; /* both 0 */6339}6340
6341/* signums are the same; both are non-zero */6342if ((lhs->bits | rhs->bits) & DECINF) { /* one or more infinities */6343if (decNumberIsInfinite(rhs)) {6344if (decNumberIsInfinite(lhs)) result=0;/* both infinite */6345else result=-result; /* only rhs infinite */6346}6347return result;6348}6349/* must compare the coefficients, allowing for exponents */6350if (lhs->exponent>rhs->exponent) { /* LHS exponent larger */6351/* swap sides, and sign */6352const decNumber *temp=lhs;6353lhs=rhs;6354rhs=temp;6355result=-result;6356}6357compare=decUnitCompare(lhs->lsu, D2U(lhs->digits),6358rhs->lsu, D2U(rhs->digits),6359rhs->exponent-lhs->exponent);6360if (compare!=BADINT) compare*=result; /* comparison succeeded */6361return compare;6362} /* decCompare */6363
6364/* ------------------------------------------------------------------ */
6365/* decUnitCompare -- compare two >=0 integers in Unit arrays */
6366/* */
6367/* This routine compares A ? B*10**E where A and B are unit arrays */
6368/* A is a plain integer */
6369/* B has an exponent of E (which must be non-negative) */
6370/* */
6371/* Arg1 is A first Unit (lsu) */
6372/* Arg2 is A length in Units */
6373/* Arg3 is B first Unit (lsu) */
6374/* Arg4 is B length in Units */
6375/* Arg5 is E (0 if the units are aligned) */
6376/* */
6377/* returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure */
6378/* (the only possible failure is an allocation error, which can */
6379/* only occur if E!=0) */
6380/* ------------------------------------------------------------------ */
6381static Int decUnitCompare(const Unit *a, Int alength,6382const Unit *b, Int blength, Int exp) {6383Unit *acc; /* accumulator for result */6384Unit accbuff[SD2U(DECBUFFER*2+1)]; /* local buffer */6385Unit *allocacc=NULL; /* -> allocated acc buffer, iff allocated */6386Int accunits, need; /* units in use or needed for acc */6387const Unit *l, *r, *u; /* work */6388Int expunits, exprem, result; /* .. */6389
6390if (exp==0) { /* aligned; fastpath */6391if (alength>blength) return 1;6392if (alength<blength) return -1;6393/* same number of units in both -- need unit-by-unit compare */6394l=a+alength-1;6395r=b+alength-1;6396for (;l>=a; l--, r--) {6397if (*l>*r) return 1;6398if (*l<*r) return -1;6399}6400return 0; /* all units match */6401} /* aligned */6402
6403/* Unaligned. If one is >1 unit longer than the other, padded */6404/* approximately, then can return easily */6405if (alength>blength+(Int)D2U(exp)) return 1;6406if (alength+1<blength+(Int)D2U(exp)) return -1;6407
6408/* Need to do a real subtract. For this, a result buffer is needed */6409/* even though only the sign is of interest. Its length needs */6410/* to be the larger of alength and padded blength, +2 */6411need=blength+D2U(exp); /* maximum real length of B */6412if (need<alength) need=alength;6413need+=2;6414acc=accbuff; /* assume use local buffer */6415if (need*sizeof(Unit)>sizeof(accbuff)) {6416allocacc=(Unit *)malloc(need*sizeof(Unit));6417if (allocacc==NULL) return BADINT; /* hopeless -- abandon */6418acc=allocacc;6419}6420/* Calculate units and remainder from exponent. */6421expunits=exp/DECDPUN;6422exprem=exp%DECDPUN;6423/* subtract [A+B*(-m)] */6424accunits=decUnitAddSub(a, alength, b, blength, expunits, acc,6425-(Int)powers[exprem]);6426/* [UnitAddSub result may have leading zeros, even on zero] */6427if (accunits<0) result=-1; /* negative result */6428else { /* non-negative result */6429/* check units of the result before freeing any storage */6430for (u=acc; u<acc+accunits-1 && *u==0;) u++;6431result=(*u==0 ? 0 : +1);6432}6433/* clean up and return the result */6434if (allocacc!=NULL) free(allocacc); /* drop any storage used */6435return result;6436} /* decUnitCompare */6437
6438/* ------------------------------------------------------------------ */
6439/* decUnitAddSub -- add or subtract two >=0 integers in Unit arrays */
6440/* */
6441/* This routine performs the calculation: */
6442/* */
6443/* C=A+(B*M) */
6444/* */
6445/* Where M is in the range -DECDPUNMAX through +DECDPUNMAX. */
6446/* */
6447/* A may be shorter or longer than B. */
6448/* */
6449/* Leading zeros are not removed after a calculation. The result is */
6450/* either the same length as the longer of A and B (adding any */
6451/* shift), or one Unit longer than that (if a Unit carry occurred). */
6452/* */
6453/* A and B content are not altered unless C is also A or B. */
6454/* C may be the same array as A or B, but only if no zero padding is */
6455/* requested (that is, C may be B only if bshift==0). */
6456/* C is filled from the lsu; only those units necessary to complete */
6457/* the calculation are referenced. */
6458/* */
6459/* Arg1 is A first Unit (lsu) */
6460/* Arg2 is A length in Units */
6461/* Arg3 is B first Unit (lsu) */
6462/* Arg4 is B length in Units */
6463/* Arg5 is B shift in Units (>=0; pads with 0 units if positive) */
6464/* Arg6 is C first Unit (lsu) */
6465/* Arg7 is M, the multiplier */
6466/* */
6467/* returns the count of Units written to C, which will be non-zero */
6468/* and negated if the result is negative. That is, the sign of the */
6469/* returned Int is the sign of the result (positive for zero) and */
6470/* the absolute value of the Int is the count of Units. */
6471/* */
6472/* It is the caller's responsibility to make sure that C size is */
6473/* safe, allowing space if necessary for a one-Unit carry. */
6474/* */
6475/* This routine is severely performance-critical; *any* change here */
6476/* must be measured (timed) to assure no performance degradation. */
6477/* In particular, trickery here tends to be counter-productive, as */
6478/* increased complexity of code hurts register optimizations on */
6479/* register-poor architectures. Avoiding divisions is nearly */
6480/* always a Good Idea, however. */
6481/* */
6482/* Special thanks to Rick McGuire (IBM Cambridge, MA) and Dave Clark */
6483/* (IBM Warwick, UK) for some of the ideas used in this routine. */
6484/* ------------------------------------------------------------------ */
6485static Int decUnitAddSub(const Unit *a, Int alength,6486const Unit *b, Int blength, Int bshift,6487Unit *c, Int m) {6488const Unit *alsu=a; /* A lsu [need to remember it] */6489Unit *clsu=c; /* C ditto */6490Unit *minC; /* low water mark for C */6491Unit *maxC; /* high water mark for C */6492eInt carry=0; /* carry integer (could be Long) */6493Int add; /* work */6494#if DECDPUN<=4 /* myriadal, millenary, etc. */6495Int est; /* estimated quotient */6496#endif6497
6498#if DECTRACE6499if (alength<1 || blength<1)6500printf("decUnitAddSub: alen blen m %ld %ld [%ld]\n", alength, blength, m);6501#endif6502
6503maxC=c+alength; /* A is usually the longer */6504minC=c+blength; /* .. and B the shorter */6505if (bshift!=0) { /* B is shifted; low As copy across */6506minC+=bshift;6507/* if in place [common], skip copy unless there's a gap [rare] */6508if (a==c && bshift<=alength) {6509c+=bshift;6510a+=bshift;6511}6512else for (; c<clsu+bshift; a++, c++) { /* copy needed */6513if (a<alsu+alength) *c=*a;6514else *c=0;6515}6516}6517if (minC>maxC) { /* swap */6518Unit *hold=minC;6519minC=maxC;6520maxC=hold;6521}6522
6523/* For speed, do the addition as two loops; the first where both A */6524/* and B contribute, and the second (if necessary) where only one or */6525/* other of the numbers contribute. */6526/* Carry handling is the same (i.e., duplicated) in each case. */6527for (; c<minC; c++) {6528carry+=*a;6529a++;6530carry+=((eInt)*b)*m; /* [special-casing m=1/-1 */6531b++; /* here is not a win] */6532/* here carry is new Unit of digits; it could be +ve or -ve */6533if ((ueInt)carry<=DECDPUNMAX) { /* fastpath 0-DECDPUNMAX */6534*c=(Unit)carry;6535carry=0;6536continue;6537}6538#if DECDPUN==4 /* use divide-by-multiply */6539if (carry>=0) {6540est=(((ueInt)carry>>11)*53687)>>18;6541*c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */6542carry=est; /* likely quotient [89%] */6543if (*c<DECDPUNMAX+1) continue; /* estimate was correct */6544carry++;6545*c-=DECDPUNMAX+1;6546continue;6547}6548/* negative case */6549carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */6550est=(((ueInt)carry>>11)*53687)>>18;6551*c=(Unit)(carry-est*(DECDPUNMAX+1));6552carry=est-(DECDPUNMAX+1); /* correctly negative */6553if (*c<DECDPUNMAX+1) continue; /* was OK */6554carry++;6555*c-=DECDPUNMAX+1;6556#elif DECDPUN==36557if (carry>=0) {6558est=(((ueInt)carry>>3)*16777)>>21;6559*c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */6560carry=est; /* likely quotient [99%] */6561if (*c<DECDPUNMAX+1) continue; /* estimate was correct */6562carry++;6563*c-=DECDPUNMAX+1;6564continue;6565}6566/* negative case */6567carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */6568est=(((ueInt)carry>>3)*16777)>>21;6569*c=(Unit)(carry-est*(DECDPUNMAX+1));6570carry=est-(DECDPUNMAX+1); /* correctly negative */6571if (*c<DECDPUNMAX+1) continue; /* was OK */6572carry++;6573*c-=DECDPUNMAX+1;6574#elif DECDPUN<=26575/* Can use QUOT10 as carry <= 4 digits */6576if (carry>=0) {6577est=QUOT10(carry, DECDPUN);6578*c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */6579carry=est; /* quotient */6580continue;6581}6582/* negative case */6583carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */6584est=QUOT10(carry, DECDPUN);6585*c=(Unit)(carry-est*(DECDPUNMAX+1));6586carry=est-(DECDPUNMAX+1); /* correctly negative */6587#else6588/* remainder operator is undefined if negative, so must test */6589if ((ueInt)carry<(DECDPUNMAX+1)*2) { /* fastpath carry +1 */6590*c=(Unit)(carry-(DECDPUNMAX+1)); /* [helps additions] */6591carry=1;6592continue;6593}6594if (carry>=0) {6595*c=(Unit)(carry%(DECDPUNMAX+1));6596carry=carry/(DECDPUNMAX+1);6597continue;6598}6599/* negative case */6600carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */6601*c=(Unit)(carry%(DECDPUNMAX+1));6602carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);6603#endif6604} /* c */6605
6606/* now may have one or other to complete */6607/* [pretest to avoid loop setup/shutdown] */6608if (c<maxC) for (; c<maxC; c++) {6609if (a<alsu+alength) { /* still in A */6610carry+=*a;6611a++;6612}6613else { /* inside B */6614carry+=((eInt)*b)*m;6615b++;6616}6617/* here carry is new Unit of digits; it could be +ve or -ve and */6618/* magnitude up to DECDPUNMAX squared */6619if ((ueInt)carry<=DECDPUNMAX) { /* fastpath 0-DECDPUNMAX */6620*c=(Unit)carry;6621carry=0;6622continue;6623}6624/* result for this unit is negative or >DECDPUNMAX */6625#if DECDPUN==4 /* use divide-by-multiply */6626if (carry>=0) {6627est=(((ueInt)carry>>11)*53687)>>18;6628*c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */6629carry=est; /* likely quotient [79.7%] */6630if (*c<DECDPUNMAX+1) continue; /* estimate was correct */6631carry++;6632*c-=DECDPUNMAX+1;6633continue;6634}6635/* negative case */6636carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */6637est=(((ueInt)carry>>11)*53687)>>18;6638*c=(Unit)(carry-est*(DECDPUNMAX+1));6639carry=est-(DECDPUNMAX+1); /* correctly negative */6640if (*c<DECDPUNMAX+1) continue; /* was OK */6641carry++;6642*c-=DECDPUNMAX+1;6643#elif DECDPUN==36644if (carry>=0) {6645est=(((ueInt)carry>>3)*16777)>>21;6646*c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */6647carry=est; /* likely quotient [99%] */6648if (*c<DECDPUNMAX+1) continue; /* estimate was correct */6649carry++;6650*c-=DECDPUNMAX+1;6651continue;6652}6653/* negative case */6654carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */6655est=(((ueInt)carry>>3)*16777)>>21;6656*c=(Unit)(carry-est*(DECDPUNMAX+1));6657carry=est-(DECDPUNMAX+1); /* correctly negative */6658if (*c<DECDPUNMAX+1) continue; /* was OK */6659carry++;6660*c-=DECDPUNMAX+1;6661#elif DECDPUN<=26662if (carry>=0) {6663est=QUOT10(carry, DECDPUN);6664*c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */6665carry=est; /* quotient */6666continue;6667}6668/* negative case */6669carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */6670est=QUOT10(carry, DECDPUN);6671*c=(Unit)(carry-est*(DECDPUNMAX+1));6672carry=est-(DECDPUNMAX+1); /* correctly negative */6673#else6674if ((ueInt)carry<(DECDPUNMAX+1)*2){ /* fastpath carry 1 */6675*c=(Unit)(carry-(DECDPUNMAX+1));6676carry=1;6677continue;6678}6679/* remainder operator is undefined if negative, so must test */6680if (carry>=0) {6681*c=(Unit)(carry%(DECDPUNMAX+1));6682carry=carry/(DECDPUNMAX+1);6683continue;6684}6685/* negative case */6686carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */6687*c=(Unit)(carry%(DECDPUNMAX+1));6688carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);6689#endif6690} /* c */6691
6692/* OK, all A and B processed; might still have carry or borrow */6693/* return number of Units in the result, negated if a borrow */6694if (carry==0) return c-clsu; /* no carry, so no more to do */6695if (carry>0) { /* positive carry */6696*c=(Unit)carry; /* place as new unit */6697c++; /* .. */6698return c-clsu;6699}6700/* -ve carry: it's a borrow; complement needed */6701add=1; /* temporary carry... */6702for (c=clsu; c<maxC; c++) {6703add=DECDPUNMAX+add-*c;6704if (add<=DECDPUNMAX) {6705*c=(Unit)add;6706add=0;6707}6708else {6709*c=0;6710add=1;6711}6712}6713/* add an extra unit iff it would be non-zero */6714#if DECTRACE6715printf("UAS borrow: add %ld, carry %ld\n", add, carry);6716#endif6717if ((add-carry-1)!=0) {6718*c=(Unit)(add-carry-1);6719c++; /* interesting, include it */6720}6721return clsu-c; /* -ve result indicates borrowed */6722} /* decUnitAddSub */6723
6724/* ------------------------------------------------------------------ */
6725/* decTrim -- trim trailing zeros or normalize */
6726/* */
6727/* dn is the number to trim or normalize */
6728/* set is the context to use to check for clamp */
6729/* all is 1 to remove all trailing zeros, 0 for just fraction ones */
6730/* dropped returns the number of discarded trailing zeros */
6731/* returns dn */
6732/* */
6733/* If clamp is set in the context then the number of zeros trimmed */
6734/* may be limited if the exponent is high. */
6735/* All fields are updated as required. This is a utility operation, */
6736/* so special values are unchanged and no error is possible. */
6737/* ------------------------------------------------------------------ */
6738static decNumber * decTrim(decNumber *dn, decContext *set, Flag all,6739Int *dropped) {6740Int d, exp; /* work */6741uInt cut; /* .. */6742Unit *up; /* -> current Unit */6743
6744#if DECCHECK6745if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;6746#endif6747
6748*dropped=0; /* assume no zeros dropped */6749if ((dn->bits & DECSPECIAL) /* fast exit if special .. */6750|| (*dn->lsu & 0x01)) return dn; /* .. or odd */6751if (ISZERO(dn)) { /* .. or 0 */6752dn->exponent=0; /* (sign is preserved) */6753return dn;6754}6755
6756/* have a finite number which is even */6757exp=dn->exponent;6758cut=1; /* digit (1-DECDPUN) in Unit */6759up=dn->lsu; /* -> current Unit */6760for (d=0; d<dn->digits-1; d++) { /* [don't strip the final digit] */6761/* slice by powers */6762#if DECDPUN<=46763uInt quot=QUOT10(*up, cut);6764if ((*up-quot*powers[cut])!=0) break; /* found non-0 digit */6765#else6766if (*up%powers[cut]!=0) break; /* found non-0 digit */6767#endif6768/* have a trailing 0 */6769if (!all) { /* trimming */6770/* [if exp>0 then all trailing 0s are significant for trim] */6771if (exp<=0) { /* if digit might be significant */6772if (exp==0) break; /* then quit */6773exp++; /* next digit might be significant */6774}6775}6776cut++; /* next power */6777if (cut>DECDPUN) { /* need new Unit */6778up++;6779cut=1;6780}6781} /* d */6782if (d==0) return dn; /* none to drop */6783
6784/* may need to limit drop if clamping */6785if (set->clamp) {6786Int maxd=set->emax-set->digits+1-dn->exponent;6787if (maxd<=0) return dn; /* nothing possible */6788if (d>maxd) d=maxd;6789}6790
6791/* effect the drop */6792decShiftToLeast(dn->lsu, D2U(dn->digits), d);6793dn->exponent+=d; /* maintain numerical value */6794dn->digits-=d; /* new length */6795*dropped=d; /* report the count */6796return dn;6797} /* decTrim */6798
6799/* ------------------------------------------------------------------ */
6800/* decReverse -- reverse a Unit array in place */
6801/* */
6802/* ulo is the start of the array */
6803/* uhi is the end of the array (highest Unit to include) */
6804/* */
6805/* The units ulo through uhi are reversed in place (if the number */
6806/* of units is odd, the middle one is untouched). Note that the */
6807/* digit(s) in each unit are unaffected. */
6808/* ------------------------------------------------------------------ */
6809static void decReverse(Unit *ulo, Unit *uhi) {6810Unit temp;6811for (; ulo<uhi; ulo++, uhi--) {6812temp=*ulo;6813*ulo=*uhi;6814*uhi=temp;6815}6816return;6817} /* decReverse */6818
6819/* ------------------------------------------------------------------ */
6820/* decShiftToMost -- shift digits in array towards most significant */
6821/* */
6822/* uar is the array */
6823/* digits is the count of digits in use in the array */
6824/* shift is the number of zeros to pad with (least significant); */
6825/* it must be zero or positive */
6826/* */
6827/* returns the new length of the integer in the array, in digits */
6828/* */
6829/* No overflow is permitted (that is, the uar array must be known to */
6830/* be large enough to hold the result, after shifting). */
6831/* ------------------------------------------------------------------ */
6832static Int decShiftToMost(Unit *uar, Int digits, Int shift) {6833Unit *target, *source, *first; /* work */6834Int cut; /* odd 0's to add */6835uInt next; /* work */6836
6837if (shift==0) return digits; /* [fastpath] nothing to do */6838if ((digits+shift)<=DECDPUN) { /* [fastpath] single-unit case */6839*uar=(Unit)(*uar*powers[shift]);6840return digits+shift;6841}6842
6843next=0; /* all paths */6844source=uar+D2U(digits)-1; /* where msu comes from */6845target=source+D2U(shift); /* where upper part of first cut goes */6846cut=DECDPUN-MSUDIGITS(shift); /* where to slice */6847if (cut==0) { /* unit-boundary case */6848for (; source>=uar; source--, target--) *target=*source;6849}6850else {6851first=uar+D2U(digits+shift)-1; /* where msu of source will end up */6852for (; source>=uar; source--, target--) {6853/* split the source Unit and accumulate remainder for next */6854#if DECDPUN<=46855uInt quot=QUOT10(*source, cut);6856uInt rem=*source-quot*powers[cut];6857next+=quot;6858#else6859uInt rem=*source%powers[cut];6860next+=*source/powers[cut];6861#endif6862if (target<=first) *target=(Unit)next; /* write to target iff valid */6863next=rem*powers[DECDPUN-cut]; /* save remainder for next Unit */6864}6865} /* shift-move */6866
6867/* propagate any partial unit to one below and clear the rest */6868for (; target>=uar; target--) {6869*target=(Unit)next;6870next=0;6871}6872return digits+shift;6873} /* decShiftToMost */6874
6875/* ------------------------------------------------------------------ */
6876/* decShiftToLeast -- shift digits in array towards least significant */
6877/* */
6878/* uar is the array */
6879/* units is length of the array, in units */
6880/* shift is the number of digits to remove from the lsu end; it */
6881/* must be zero or positive and <= than units*DECDPUN. */
6882/* */
6883/* returns the new length of the integer in the array, in units */
6884/* */
6885/* Removed digits are discarded (lost). Units not required to hold */
6886/* the final result are unchanged. */
6887/* ------------------------------------------------------------------ */
6888static Int decShiftToLeast(Unit *uar, Int units, Int shift) {6889Unit *target, *up; /* work */6890Int cut, count; /* work */6891Int quot, rem; /* for division */6892
6893if (shift==0) return units; /* [fastpath] nothing to do */6894if (shift==units*DECDPUN) { /* [fastpath] little to do */6895*uar=0; /* all digits cleared gives zero */6896return 1; /* leaves just the one */6897}6898
6899target=uar; /* both paths */6900cut=MSUDIGITS(shift);6901if (cut==DECDPUN) { /* unit-boundary case; easy */6902up=uar+D2U(shift);6903for (; up<uar+units; target++, up++) *target=*up;6904return target-uar;6905}6906
6907/* messier */6908up=uar+D2U(shift-cut); /* source; correct to whole Units */6909count=units*DECDPUN-shift; /* the maximum new length */6910#if DECDPUN<=46911quot=QUOT10(*up, cut);6912#else6913quot=*up/powers[cut];6914#endif6915for (; ; target++) {6916*target=(Unit)quot;6917count-=(DECDPUN-cut);6918if (count<=0) break;6919up++;6920quot=*up;6921#if DECDPUN<=46922quot=QUOT10(quot, cut);6923rem=*up-quot*powers[cut];6924#else6925rem=quot%powers[cut];6926quot=quot/powers[cut];6927#endif6928*target=(Unit)(*target+rem*powers[DECDPUN-cut]);6929count-=cut;6930if (count<=0) break;6931}6932return target-uar+1;6933} /* decShiftToLeast */6934
6935#if DECSUBSET6936/* ------------------------------------------------------------------ */
6937/* decRoundOperand -- round an operand [used for subset only] */
6938/* */
6939/* dn is the number to round (dn->digits is > set->digits) */
6940/* set is the relevant context */
6941/* status is the status accumulator */
6942/* */
6943/* returns an allocated decNumber with the rounded result. */
6944/* */
6945/* lostDigits and other status may be set by this. */
6946/* */
6947/* Since the input is an operand, it must not be modified. */
6948/* Instead, return an allocated decNumber, rounded as required. */
6949/* It is the caller's responsibility to free the allocated storage. */
6950/* */
6951/* If no storage is available then the result cannot be used, so NULL */
6952/* is returned. */
6953/* ------------------------------------------------------------------ */
6954static decNumber *decRoundOperand(const decNumber *dn, decContext *set,6955uInt *status) {6956decNumber *res; /* result structure */6957uInt newstatus=0; /* status from round */6958Int residue=0; /* rounding accumulator */6959
6960/* Allocate storage for the returned decNumber, big enough for the */6961/* length specified by the context */6962res=(decNumber *)malloc(sizeof(decNumber)6963+(D2U(set->digits)-1)*sizeof(Unit));6964if (res==NULL) {6965*status|=DEC_Insufficient_storage;6966return NULL;6967}6968decCopyFit(res, dn, set, &residue, &newstatus);6969decApplyRound(res, set, residue, &newstatus);6970
6971/* If that set Inexact then "lost digits" is raised... */6972if (newstatus & DEC_Inexact) newstatus|=DEC_Lost_digits;6973*status|=newstatus;6974return res;6975} /* decRoundOperand */6976#endif6977
6978/* ------------------------------------------------------------------ */
6979/* decCopyFit -- copy a number, truncating the coefficient if needed */
6980/* */
6981/* dest is the target decNumber */
6982/* src is the source decNumber */
6983/* set is the context [used for length (digits) and rounding mode] */
6984/* residue is the residue accumulator */
6985/* status contains the current status to be updated */
6986/* */
6987/* (dest==src is allowed and will be a no-op if fits) */
6988/* All fields are updated as required. */
6989/* ------------------------------------------------------------------ */
6990static void decCopyFit(decNumber *dest, const decNumber *src,6991decContext *set, Int *residue, uInt *status) {6992dest->bits=src->bits;6993dest->exponent=src->exponent;6994decSetCoeff(dest, set, src->lsu, src->digits, residue, status);6995} /* decCopyFit */6996
6997/* ------------------------------------------------------------------ */
6998/* decSetCoeff -- set the coefficient of a number */
6999/* */
7000/* dn is the number whose coefficient array is to be set. */
7001/* It must have space for set->digits digits */
7002/* set is the context [for size] */
7003/* lsu -> lsu of the source coefficient [may be dn->lsu] */
7004/* len is digits in the source coefficient [may be dn->digits] */
7005/* residue is the residue accumulator. This has values as in */
7006/* decApplyRound, and will be unchanged unless the */
7007/* target size is less than len. In this case, the */
7008/* coefficient is truncated and the residue is updated to */
7009/* reflect the previous residue and the dropped digits. */
7010/* status is the status accumulator, as usual */
7011/* */
7012/* The coefficient may already be in the number, or it can be an */
7013/* external intermediate array. If it is in the number, lsu must == */
7014/* dn->lsu and len must == dn->digits. */
7015/* */
7016/* Note that the coefficient length (len) may be < set->digits, and */
7017/* in this case this merely copies the coefficient (or is a no-op */
7018/* if dn->lsu==lsu). */
7019/* */
7020/* Note also that (only internally, from decQuantizeOp and */
7021/* decSetSubnormal) the value of set->digits may be less than one, */
7022/* indicating a round to left. This routine handles that case */
7023/* correctly; caller ensures space. */
7024/* */
7025/* dn->digits, dn->lsu (and as required), and dn->exponent are */
7026/* updated as necessary. dn->bits (sign) is unchanged. */
7027/* */
7028/* DEC_Rounded status is set if any digits are discarded. */
7029/* DEC_Inexact status is set if any non-zero digits are discarded, or */
7030/* incoming residue was non-0 (implies rounded) */
7031/* ------------------------------------------------------------------ */
7032/* mapping array: maps 0-9 to canonical residues, so that a residue */
7033/* can be adjusted in the range [-1, +1] and achieve correct rounding */
7034/* 0 1 2 3 4 5 6 7 8 9 */
7035static const uByte resmap[10]={0, 3, 3, 3, 3, 5, 7, 7, 7, 7};7036static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu,7037Int len, Int *residue, uInt *status) {7038Int discard; /* number of digits to discard */7039uInt cut; /* cut point in Unit */7040const Unit *up; /* work */7041Unit *target; /* .. */7042Int count; /* .. */7043#if DECDPUN<=47044uInt temp; /* .. */7045#endif7046
7047discard=len-set->digits; /* digits to discard */7048if (discard<=0) { /* no digits are being discarded */7049if (dn->lsu!=lsu) { /* copy needed */7050/* copy the coefficient array to the result number; no shift needed */7051count=len; /* avoids D2U */7052up=lsu;7053for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)7054*target=*up;7055dn->digits=len; /* set the new length */7056}7057/* dn->exponent and residue are unchanged, record any inexactitude */7058if (*residue!=0) *status|=(DEC_Inexact | DEC_Rounded);7059return;7060}7061
7062/* some digits must be discarded ... */7063dn->exponent+=discard; /* maintain numerical value */7064*status|=DEC_Rounded; /* accumulate Rounded status */7065if (*residue>1) *residue=1; /* previous residue now to right, so reduce */7066
7067if (discard>len) { /* everything, +1, is being discarded */7068/* guard digit is 0 */7069/* residue is all the number [NB could be all 0s] */7070if (*residue<=0) { /* not already positive */7071count=len; /* avoids D2U */7072for (up=lsu; count>0; up++, count-=DECDPUN) if (*up!=0) { /* found non-0 */7073*residue=1;7074break; /* no need to check any others */7075}7076}7077if (*residue!=0) *status|=DEC_Inexact; /* record inexactitude */7078*dn->lsu=0; /* coefficient will now be 0 */7079dn->digits=1; /* .. */7080return;7081} /* total discard */7082
7083/* partial discard [most common case] */7084/* here, at least the first (most significant) discarded digit exists */7085
7086/* spin up the number, noting residue during the spin, until get to */7087/* the Unit with the first discarded digit. When reach it, extract */7088/* it and remember its position */7089count=0;7090for (up=lsu;; up++) {7091count+=DECDPUN;7092if (count>=discard) break; /* full ones all checked */7093if (*up!=0) *residue=1;7094} /* up */7095
7096/* here up -> Unit with first discarded digit */7097cut=discard-(count-DECDPUN)-1;7098if (cut==DECDPUN-1) { /* unit-boundary case (fast) */7099Unit half=(Unit)powers[DECDPUN]>>1;7100/* set residue directly */7101if (*up>=half) {7102if (*up>half) *residue=7;7103else *residue+=5; /* add sticky bit */7104}7105else { /* <half */7106if (*up!=0) *residue=3; /* [else is 0, leave as sticky bit] */7107}7108if (set->digits<=0) { /* special for Quantize/Subnormal :-( */7109*dn->lsu=0; /* .. result is 0 */7110dn->digits=1; /* .. */7111}7112else { /* shift to least */7113count=set->digits; /* now digits to end up with */7114dn->digits=count; /* set the new length */7115up++; /* move to next */7116/* on unit boundary, so shift-down copy loop is simple */7117for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)7118*target=*up;7119}7120} /* unit-boundary case */7121
7122else { /* discard digit is in low digit(s), and not top digit */7123uInt discard1; /* first discarded digit */7124uInt quot, rem; /* for divisions */7125if (cut==0) quot=*up; /* is at bottom of unit */7126else /* cut>0 */ { /* it's not at bottom of unit */7127#if DECDPUN<=47128quot=QUOT10(*up, cut);7129rem=*up-quot*powers[cut];7130#else7131rem=*up%powers[cut];7132quot=*up/powers[cut];7133#endif7134if (rem!=0) *residue=1;7135}7136/* discard digit is now at bottom of quot */7137#if DECDPUN<=47138temp=(quot*6554)>>16; /* fast /10 */7139/* Vowels algorithm here not a win (9 instructions) */7140discard1=quot-X10(temp);7141quot=temp;7142#else7143discard1=quot%10;7144quot=quot/10;7145#endif7146/* here, discard1 is the guard digit, and residue is everything */7147/* else [use mapping array to accumulate residue safely] */7148*residue+=resmap[discard1];7149cut++; /* update cut */7150/* here: up -> Unit of the array with bottom digit */7151/* cut is the division point for each Unit */7152/* quot holds the uncut high-order digits for the current unit */7153if (set->digits<=0) { /* special for Quantize/Subnormal :-( */7154*dn->lsu=0; /* .. result is 0 */7155dn->digits=1; /* .. */7156}7157else { /* shift to least needed */7158count=set->digits; /* now digits to end up with */7159dn->digits=count; /* set the new length */7160/* shift-copy the coefficient array to the result number */7161for (target=dn->lsu; ; target++) {7162*target=(Unit)quot;7163count-=(DECDPUN-cut);7164if (count<=0) break;7165up++;7166quot=*up;7167#if DECDPUN<=47168quot=QUOT10(quot, cut);7169rem=*up-quot*powers[cut];7170#else7171rem=quot%powers[cut];7172quot=quot/powers[cut];7173#endif7174*target=(Unit)(*target+rem*powers[DECDPUN-cut]);7175count-=cut;7176if (count<=0) break;7177} /* shift-copy loop */7178} /* shift to least */7179} /* not unit boundary */7180
7181if (*residue!=0) *status|=DEC_Inexact; /* record inexactitude */7182return;7183} /* decSetCoeff */7184
7185/* ------------------------------------------------------------------ */
7186/* decApplyRound -- apply pending rounding to a number */
7187/* */
7188/* dn is the number, with space for set->digits digits */
7189/* set is the context [for size and rounding mode] */
7190/* residue indicates pending rounding, being any accumulated */
7191/* guard and sticky information. It may be: */
7192/* 6-9: rounding digit is >5 */
7193/* 5: rounding digit is exactly half-way */
7194/* 1-4: rounding digit is <5 and >0 */
7195/* 0: the coefficient is exact */
7196/* -1: as 1, but the hidden digits are subtractive, that */
7197/* is, of the opposite sign to dn. In this case the */
7198/* coefficient must be non-0. This case occurs when */
7199/* subtracting a small number (which can be reduced to */
7200/* a sticky bit); see decAddOp. */
7201/* status is the status accumulator, as usual */
7202/* */
7203/* This routine applies rounding while keeping the length of the */
7204/* coefficient constant. The exponent and status are unchanged */
7205/* except if: */
7206/* */
7207/* -- the coefficient was increased and is all nines (in which */
7208/* case Overflow could occur, and is handled directly here so */
7209/* the caller does not need to re-test for overflow) */
7210/* */
7211/* -- the coefficient was decreased and becomes all nines (in which */
7212/* case Underflow could occur, and is also handled directly). */
7213/* */
7214/* All fields in dn are updated as required. */
7215/* */
7216/* ------------------------------------------------------------------ */
7217static void decApplyRound(decNumber *dn, decContext *set, Int residue,7218uInt *status) {7219Int bump; /* 1 if coefficient needs to be incremented */7220/* -1 if coefficient needs to be decremented */7221
7222if (residue==0) return; /* nothing to apply */7223
7224bump=0; /* assume a smooth ride */7225
7226/* now decide whether, and how, to round, depending on mode */7227switch (set->round) {7228case DEC_ROUND_05UP: { /* round zero or five up (for reround) */7229/* This is the same as DEC_ROUND_DOWN unless there is a */7230/* positive residue and the lsd of dn is 0 or 5, in which case */7231/* it is bumped; when residue is <0, the number is therefore */7232/* bumped down unless the final digit was 1 or 6 (in which */7233/* case it is bumped down and then up -- a no-op) */7234Int lsd5=*dn->lsu%5; /* get lsd and quintate */7235if (residue<0 && lsd5!=1) bump=-1;7236else if (residue>0 && lsd5==0) bump=1;7237/* [bump==1 could be applied directly; use common path for clarity] */7238break;} /* r-05 */7239
7240case DEC_ROUND_DOWN: {7241/* no change, except if negative residue */7242if (residue<0) bump=-1;7243break;} /* r-d */7244
7245case DEC_ROUND_HALF_DOWN: {7246if (residue>5) bump=1;7247break;} /* r-h-d */7248
7249case DEC_ROUND_HALF_EVEN: {7250if (residue>5) bump=1; /* >0.5 goes up */7251else if (residue==5) { /* exactly 0.5000... */7252/* 0.5 goes up iff [new] lsd is odd */7253if (*dn->lsu & 0x01) bump=1;7254}7255break;} /* r-h-e */7256
7257case DEC_ROUND_HALF_UP: {7258if (residue>=5) bump=1;7259break;} /* r-h-u */7260
7261case DEC_ROUND_UP: {7262if (residue>0) bump=1;7263break;} /* r-u */7264
7265case DEC_ROUND_CEILING: {7266/* same as _UP for positive numbers, and as _DOWN for negatives */7267/* [negative residue cannot occur on 0] */7268if (decNumberIsNegative(dn)) {7269if (residue<0) bump=-1;7270}7271else {7272if (residue>0) bump=1;7273}7274break;} /* r-c */7275
7276case DEC_ROUND_FLOOR: {7277/* same as _UP for negative numbers, and as _DOWN for positive */7278/* [negative residue cannot occur on 0] */7279if (!decNumberIsNegative(dn)) {7280if (residue<0) bump=-1;7281}7282else {7283if (residue>0) bump=1;7284}7285break;} /* r-f */7286
7287default: { /* e.g., DEC_ROUND_MAX */7288*status|=DEC_Invalid_context;7289#if DECTRACE || (DECCHECK && DECVERB)7290printf("Unknown rounding mode: %d\n", set->round);7291#endif7292break;}7293} /* switch */7294
7295/* now bump the number, up or down, if need be */7296if (bump==0) return; /* no action required */7297
7298/* Simply use decUnitAddSub unless bumping up and the number is */7299/* all nines. In this special case set to 100... explicitly */7300/* and adjust the exponent by one (as otherwise could overflow */7301/* the array) */7302/* Similarly handle all-nines result if bumping down. */7303if (bump>0) {7304Unit *up; /* work */7305uInt count=dn->digits; /* digits to be checked */7306for (up=dn->lsu; ; up++) {7307if (count<=DECDPUN) {7308/* this is the last Unit (the msu) */7309if (*up!=powers[count]-1) break; /* not still 9s */7310/* here if it, too, is all nines */7311*up=(Unit)powers[count-1]; /* here 999 -> 100 etc. */7312for (up=up-1; up>=dn->lsu; up--) *up=0; /* others all to 0 */7313dn->exponent++; /* and bump exponent */7314/* [which, very rarely, could cause Overflow...] */7315if ((dn->exponent+dn->digits)>set->emax+1) {7316decSetOverflow(dn, set, status);7317}7318return; /* done */7319}7320/* a full unit to check, with more to come */7321if (*up!=DECDPUNMAX) break; /* not still 9s */7322count-=DECDPUN;7323} /* up */7324} /* bump>0 */7325else { /* -1 */7326/* here checking for a pre-bump of 1000... (leading 1, all */7327/* other digits zero) */7328Unit *up, *sup; /* work */7329uInt count=dn->digits; /* digits to be checked */7330for (up=dn->lsu; ; up++) {7331if (count<=DECDPUN) {7332/* this is the last Unit (the msu) */7333if (*up!=powers[count-1]) break; /* not 100.. */7334/* here if have the 1000... case */7335sup=up; /* save msu pointer */7336*up=(Unit)powers[count]-1; /* here 100 in msu -> 999 */7337/* others all to all-nines, too */7338for (up=up-1; up>=dn->lsu; up--) *up=(Unit)powers[DECDPUN]-1;7339dn->exponent--; /* and bump exponent */7340
7341/* iff the number was at the subnormal boundary (exponent=etiny) */7342/* then the exponent is now out of range, so it will in fact get */7343/* clamped to etiny and the final 9 dropped. */7344/* printf(">> emin=%d exp=%d sdig=%d\n", set->emin, */7345/* dn->exponent, set->digits); */7346if (dn->exponent+1==set->emin-set->digits+1) {7347if (count==1 && dn->digits==1) *sup=0; /* here 9 -> 0[.9] */7348else {7349*sup=(Unit)powers[count-1]-1; /* here 999.. in msu -> 99.. */7350dn->digits--;7351}7352dn->exponent++;7353*status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;7354}7355return; /* done */7356}7357
7358/* a full unit to check, with more to come */7359if (*up!=0) break; /* not still 0s */7360count-=DECDPUN;7361} /* up */7362
7363} /* bump<0 */7364
7365/* Actual bump needed. Do it. */7366decUnitAddSub(dn->lsu, D2U(dn->digits), uarrone, 1, 0, dn->lsu, bump);7367} /* decApplyRound */7368
7369#if DECSUBSET7370/* ------------------------------------------------------------------ */
7371/* decFinish -- finish processing a number */
7372/* */
7373/* dn is the number */
7374/* set is the context */
7375/* residue is the rounding accumulator (as in decApplyRound) */
7376/* status is the accumulator */
7377/* */
7378/* This finishes off the current number by: */
7379/* 1. If not extended: */
7380/* a. Converting a zero result to clean '0' */
7381/* b. Reducing positive exponents to 0, if would fit in digits */
7382/* 2. Checking for overflow and subnormals (always) */
7383/* Note this is just Finalize when no subset arithmetic. */
7384/* All fields are updated as required. */
7385/* ------------------------------------------------------------------ */
7386static void decFinish(decNumber *dn, decContext *set, Int *residue,7387uInt *status) {7388if (!set->extended) {7389if ISZERO(dn) { /* value is zero */7390dn->exponent=0; /* clean exponent .. */7391dn->bits=0; /* .. and sign */7392return; /* no error possible */7393}7394if (dn->exponent>=0) { /* non-negative exponent */7395/* >0; reduce to integer if possible */7396if (set->digits >= (dn->exponent+dn->digits)) {7397dn->digits=decShiftToMost(dn->lsu, dn->digits, dn->exponent);7398dn->exponent=0;7399}7400}7401} /* !extended */7402
7403decFinalize(dn, set, residue, status);7404} /* decFinish */7405#endif7406
7407/* ------------------------------------------------------------------ */
7408/* decFinalize -- final check, clamp, and round of a number */
7409/* */
7410/* dn is the number */
7411/* set is the context */
7412/* residue is the rounding accumulator (as in decApplyRound) */
7413/* status is the status accumulator */
7414/* */
7415/* This finishes off the current number by checking for subnormal */
7416/* results, applying any pending rounding, checking for overflow, */
7417/* and applying any clamping. */
7418/* Underflow and overflow conditions are raised as appropriate. */
7419/* All fields are updated as required. */
7420/* ------------------------------------------------------------------ */
7421static void decFinalize(decNumber *dn, decContext *set, Int *residue,7422uInt *status) {7423Int shift; /* shift needed if clamping */7424Int tinyexp=set->emin-dn->digits+1; /* precalculate subnormal boundary */7425
7426/* Must be careful, here, when checking the exponent as the */7427/* adjusted exponent could overflow 31 bits [because it may already */7428/* be up to twice the expected]. */7429
7430/* First test for subnormal. This must be done before any final */7431/* round as the result could be rounded to Nmin or 0. */7432if (dn->exponent<=tinyexp) { /* prefilter */7433Int comp;7434decNumber nmin;7435/* A very nasty case here is dn == Nmin and residue<0 */7436if (dn->exponent<tinyexp) {7437/* Go handle subnormals; this will apply round if needed. */7438decSetSubnormal(dn, set, residue, status);7439return;7440}7441/* Equals case: only subnormal if dn=Nmin and negative residue */7442decNumberZero(&nmin);7443nmin.lsu[0]=1;7444nmin.exponent=set->emin;7445comp=decCompare(dn, &nmin, 1); /* (signless compare) */7446if (comp==BADINT) { /* oops */7447*status|=DEC_Insufficient_storage; /* abandon... */7448return;7449}7450if (*residue<0 && comp==0) { /* neg residue and dn==Nmin */7451decApplyRound(dn, set, *residue, status); /* might force down */7452decSetSubnormal(dn, set, residue, status);7453return;7454}7455}7456
7457/* now apply any pending round (this could raise overflow). */7458if (*residue!=0) decApplyRound(dn, set, *residue, status);7459
7460/* Check for overflow [redundant in the 'rare' case] or clamp */7461if (dn->exponent<=set->emax-set->digits+1) return; /* neither needed */7462
7463
7464/* here when might have an overflow or clamp to do */7465if (dn->exponent>set->emax-dn->digits+1) { /* too big */7466decSetOverflow(dn, set, status);7467return;7468}7469/* here when the result is normal but in clamp range */7470if (!set->clamp) return;7471
7472/* here when need to apply the IEEE exponent clamp (fold-down) */7473shift=dn->exponent-(set->emax-set->digits+1);7474
7475/* shift coefficient (if non-zero) */7476if (!ISZERO(dn)) {7477dn->digits=decShiftToMost(dn->lsu, dn->digits, shift);7478}7479dn->exponent-=shift; /* adjust the exponent to match */7480*status|=DEC_Clamped; /* and record the dirty deed */7481return;7482} /* decFinalize */7483
7484/* ------------------------------------------------------------------ */
7485/* decSetOverflow -- set number to proper overflow value */
7486/* */
7487/* dn is the number (used for sign [only] and result) */
7488/* set is the context [used for the rounding mode, etc.] */
7489/* status contains the current status to be updated */
7490/* */
7491/* This sets the sign of a number and sets its value to either */
7492/* Infinity or the maximum finite value, depending on the sign of */
7493/* dn and the rounding mode, following IEEE 854 rules. */
7494/* ------------------------------------------------------------------ */
7495static void decSetOverflow(decNumber *dn, decContext *set, uInt *status) {7496Flag needmax=0; /* result is maximum finite value */7497uByte sign=dn->bits&DECNEG; /* clean and save sign bit */7498
7499if (ISZERO(dn)) { /* zero does not overflow magnitude */7500Int emax=set->emax; /* limit value */7501if (set->clamp) emax-=set->digits-1; /* lower if clamping */7502if (dn->exponent>emax) { /* clamp required */7503dn->exponent=emax;7504*status|=DEC_Clamped;7505}7506return;7507}7508
7509decNumberZero(dn);7510switch (set->round) {7511case DEC_ROUND_DOWN: {7512needmax=1; /* never Infinity */7513break;} /* r-d */7514case DEC_ROUND_05UP: {7515needmax=1; /* never Infinity */7516break;} /* r-05 */7517case DEC_ROUND_CEILING: {7518if (sign) needmax=1; /* Infinity if non-negative */7519break;} /* r-c */7520case DEC_ROUND_FLOOR: {7521if (!sign) needmax=1; /* Infinity if negative */7522break;} /* r-f */7523default: break; /* Infinity in all other cases */7524}7525if (needmax) {7526decSetMaxValue(dn, set);7527dn->bits=sign; /* set sign */7528}7529else dn->bits=sign|DECINF; /* Value is +/-Infinity */7530*status|=DEC_Overflow | DEC_Inexact | DEC_Rounded;7531} /* decSetOverflow */7532
7533/* ------------------------------------------------------------------ */
7534/* decSetMaxValue -- set number to +Nmax (maximum normal value) */
7535/* */
7536/* dn is the number to set */
7537/* set is the context [used for digits and emax] */
7538/* */
7539/* This sets the number to the maximum positive value. */
7540/* ------------------------------------------------------------------ */
7541static void decSetMaxValue(decNumber *dn, decContext *set) {7542Unit *up; /* work */7543Int count=set->digits; /* nines to add */7544dn->digits=count;7545/* fill in all nines to set maximum value */7546for (up=dn->lsu; ; up++) {7547if (count>DECDPUN) *up=DECDPUNMAX; /* unit full o'nines */7548else { /* this is the msu */7549*up=(Unit)(powers[count]-1);7550break;7551}7552count-=DECDPUN; /* filled those digits */7553} /* up */7554dn->bits=0; /* + sign */7555dn->exponent=set->emax-set->digits+1;7556} /* decSetMaxValue */7557
7558/* ------------------------------------------------------------------ */
7559/* decSetSubnormal -- process value whose exponent is <Emin */
7560/* */
7561/* dn is the number (used as input as well as output; it may have */
7562/* an allowed subnormal value, which may need to be rounded) */
7563/* set is the context [used for the rounding mode] */
7564/* residue is any pending residue */
7565/* status contains the current status to be updated */
7566/* */
7567/* If subset mode, set result to zero and set Underflow flags. */
7568/* */
7569/* Value may be zero with a low exponent; this does not set Subnormal */
7570/* but the exponent will be clamped to Etiny. */
7571/* */
7572/* Otherwise ensure exponent is not out of range, and round as */
7573/* necessary. Underflow is set if the result is Inexact. */
7574/* ------------------------------------------------------------------ */
7575static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,7576uInt *status) {7577decContext workset; /* work */7578Int etiny, adjust; /* .. */7579
7580#if DECSUBSET7581/* simple set to zero and 'hard underflow' for subset */7582if (!set->extended) {7583decNumberZero(dn);7584/* always full overflow */7585*status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;7586return;7587}7588#endif7589
7590/* Full arithmetic -- allow subnormals, rounded to minimum exponent */7591/* (Etiny) if needed */7592etiny=set->emin-(set->digits-1); /* smallest allowed exponent */7593
7594if ISZERO(dn) { /* value is zero */7595/* residue can never be non-zero here */7596#if DECCHECK7597if (*residue!=0) {7598printf("++ Subnormal 0 residue %ld\n", (LI)*residue);7599*status|=DEC_Invalid_operation;7600}7601#endif7602if (dn->exponent<etiny) { /* clamp required */7603dn->exponent=etiny;7604*status|=DEC_Clamped;7605}7606return;7607}7608
7609*status|=DEC_Subnormal; /* have a non-zero subnormal */7610adjust=etiny-dn->exponent; /* calculate digits to remove */7611if (adjust<=0) { /* not out of range; unrounded */7612/* residue can never be non-zero here, except in the Nmin-residue */7613/* case (which is a subnormal result), so can take fast-path here */7614/* it may already be inexact (from setting the coefficient) */7615if (*status&DEC_Inexact) *status|=DEC_Underflow;7616return;7617}7618
7619/* adjust>0, so need to rescale the result so exponent becomes Etiny */7620/* [this code is similar to that in rescale] */7621workset=*set; /* clone rounding, etc. */7622workset.digits=dn->digits-adjust; /* set requested length */7623workset.emin-=adjust; /* and adjust emin to match */7624/* [note that the latter can be <1, here, similar to Rescale case] */7625decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);7626decApplyRound(dn, &workset, *residue, status);7627
7628/* Use 754R/854 default rule: Underflow is set iff Inexact */7629/* [independent of whether trapped] */7630if (*status&DEC_Inexact) *status|=DEC_Underflow;7631
7632/* if rounded up a 999s case, exponent will be off by one; adjust */7633/* back if so [it will fit, because it was shortened earlier] */7634if (dn->exponent>etiny) {7635dn->digits=decShiftToMost(dn->lsu, dn->digits, 1);7636dn->exponent--; /* (re)adjust the exponent. */7637}7638
7639/* if rounded to zero, it is by definition clamped... */7640if (ISZERO(dn)) *status|=DEC_Clamped;7641} /* decSetSubnormal */7642
7643/* ------------------------------------------------------------------ */
7644/* decCheckMath - check entry conditions for a math function */
7645/* */
7646/* This checks the context and the operand */
7647/* */
7648/* rhs is the operand to check */
7649/* set is the context to check */
7650/* status is unchanged if both are good */
7651/* */
7652/* returns non-zero if status is changed, 0 otherwise */
7653/* */
7654/* Restrictions enforced: */
7655/* */
7656/* digits, emax, and -emin in the context must be less than */
7657/* DEC_MAX_MATH (999999), and A must be within these bounds if */
7658/* non-zero. Invalid_operation is set in the status if a */
7659/* restriction is violated. */
7660/* ------------------------------------------------------------------ */
7661static uInt decCheckMath(const decNumber *rhs, decContext *set,7662uInt *status) {7663uInt save=*status; /* record */7664if (set->digits>DEC_MAX_MATH7665|| set->emax>DEC_MAX_MATH7666|| -set->emin>DEC_MAX_MATH) *status|=DEC_Invalid_context;7667else if ((rhs->digits>DEC_MAX_MATH7668|| rhs->exponent+rhs->digits>DEC_MAX_MATH+17669|| rhs->exponent+rhs->digits<2*(1-DEC_MAX_MATH))7670&& !ISZERO(rhs)) *status|=DEC_Invalid_operation;7671return (*status!=save);7672} /* decCheckMath */7673
7674/* ------------------------------------------------------------------ */
7675/* decGetInt -- get integer from a number */
7676/* */
7677/* dn is the number [which will not be altered] */
7678/* */
7679/* returns one of: */
7680/* BADINT if there is a non-zero fraction */
7681/* the converted integer */
7682/* BIGEVEN if the integer is even and magnitude > 2*10**9 */
7683/* BIGODD if the integer is odd and magnitude > 2*10**9 */
7684/* */
7685/* This checks and gets a whole number from the input decNumber. */
7686/* The sign can be determined from dn by the caller when BIGEVEN or */
7687/* BIGODD is returned. */
7688/* ------------------------------------------------------------------ */
7689static Int decGetInt(const decNumber *dn) {7690Int theInt; /* result accumulator */7691const Unit *up; /* work */7692Int got; /* digits (real or not) processed */7693Int ilength=dn->digits+dn->exponent; /* integral length */7694Flag neg=decNumberIsNegative(dn); /* 1 if -ve */7695
7696/* The number must be an integer that fits in 10 digits */7697/* Assert, here, that 10 is enough for any rescale Etiny */7698#if DEC_MAX_EMAX > 9999999997699#error GetInt may need updating [for Emax]7700#endif7701#if DEC_MIN_EMIN < -9999999997702#error GetInt may need updating [for Emin]7703#endif7704if (ISZERO(dn)) return 0; /* zeros are OK, with any exponent */7705
7706up=dn->lsu; /* ready for lsu */7707theInt=0; /* ready to accumulate */7708if (dn->exponent>=0) { /* relatively easy */7709/* no fractional part [usual]; allow for positive exponent */7710got=dn->exponent;7711}7712else { /* -ve exponent; some fractional part to check and discard */7713Int count=-dn->exponent; /* digits to discard */7714/* spin up whole units until reach the Unit with the unit digit */7715for (; count>=DECDPUN; up++) {7716if (*up!=0) return BADINT; /* non-zero Unit to discard */7717count-=DECDPUN;7718}7719if (count==0) got=0; /* [a multiple of DECDPUN] */7720else { /* [not multiple of DECDPUN] */7721Int rem; /* work */7722/* slice off fraction digits and check for non-zero */7723#if DECDPUN<=47724theInt=QUOT10(*up, count);7725rem=*up-theInt*powers[count];7726#else7727rem=*up%powers[count]; /* slice off discards */7728theInt=*up/powers[count];7729#endif7730if (rem!=0) return BADINT; /* non-zero fraction */7731/* it looks good */7732got=DECDPUN-count; /* number of digits so far */7733up++; /* ready for next */7734}7735}7736/* now it's known there's no fractional part */7737
7738/* tricky code now, to accumulate up to 9.3 digits */7739if (got==0) {theInt=*up; got+=DECDPUN; up++;} /* ensure lsu is there */7740
7741if (ilength<11) {7742Int save=theInt;7743/* collect any remaining unit(s) */7744for (; got<ilength; up++) {7745theInt+=*up*powers[got];7746got+=DECDPUN;7747}7748if (ilength==10) { /* need to check for wrap */7749if (theInt/(Int)powers[got-DECDPUN]!=(Int)*(up-1)) ilength=11;7750/* [that test also disallows the BADINT result case] */7751else if (neg && theInt>1999999997) ilength=11;7752else if (!neg && theInt>999999999) ilength=11;7753if (ilength==11) theInt=save; /* restore correct low bit */7754}7755}7756
7757if (ilength>10) { /* too big */7758if (theInt&1) return BIGODD; /* bottom bit 1 */7759return BIGEVEN; /* bottom bit 0 */7760}7761
7762if (neg) theInt=-theInt; /* apply sign */7763return theInt;7764} /* decGetInt */7765
7766/* ------------------------------------------------------------------ */
7767/* decDecap -- decapitate the coefficient of a number */
7768/* */
7769/* dn is the number to be decapitated */
7770/* drop is the number of digits to be removed from the left of dn; */
7771/* this must be <= dn->digits (if equal, the coefficient is */
7772/* set to 0) */
7773/* */
7774/* Returns dn; dn->digits will be <= the initial digits less drop */
7775/* (after removing drop digits there may be leading zero digits */
7776/* which will also be removed). Only dn->lsu and dn->digits change. */
7777/* ------------------------------------------------------------------ */
7778static decNumber *decDecap(decNumber *dn, Int drop) {7779Unit *msu; /* -> target cut point */7780Int cut; /* work */7781if (drop>=dn->digits) { /* losing the whole thing */7782#if DECCHECK7783if (drop>dn->digits)7784printf("decDecap called with drop>digits [%ld>%ld]\n",7785(LI)drop, (LI)dn->digits);7786#endif7787dn->lsu[0]=0;7788dn->digits=1;7789return dn;7790}7791msu=dn->lsu+D2U(dn->digits-drop)-1; /* -> likely msu */7792cut=MSUDIGITS(dn->digits-drop); /* digits to be in use in msu */7793if (cut!=DECDPUN) *msu%=powers[cut]; /* clear left digits */7794/* that may have left leading zero digits, so do a proper count... */7795dn->digits=decGetDigits(dn->lsu, msu-dn->lsu+1);7796return dn;7797} /* decDecap */7798
7799/* ------------------------------------------------------------------ */
7800/* decBiStr -- compare string with pairwise options */
7801/* */
7802/* targ is the string to compare */
7803/* str1 is one of the strings to compare against (length may be 0) */
7804/* str2 is the other; it must be the same length as str1 */
7805/* */
7806/* returns 1 if strings compare equal, (that is, it is the same */
7807/* length as str1 and str2, and each character of targ is in either */
7808/* str1 or str2 in the corresponding position), or 0 otherwise */
7809/* */
7810/* This is used for generic caseless compare, including the awkward */
7811/* case of the Turkish dotted and dotless Is. Use as (for example): */
7812/* if (decBiStr(test, "mike", "MIKE")) ... */
7813/* ------------------------------------------------------------------ */
7814static Flag decBiStr(const char *targ, const char *str1, const char *str2) {7815for (;;targ++, str1++, str2++) {7816if (*targ!=*str1 && *targ!=*str2) return 0;7817/* *targ has a match in one (or both, if terminator) */7818if (*targ=='\0') break;7819} /* forever */7820return 1;7821} /* decBiStr */7822
7823/* ------------------------------------------------------------------ */
7824/* decNaNs -- handle NaN operand or operands */
7825/* */
7826/* res is the result number */
7827/* lhs is the first operand */
7828/* rhs is the second operand, or NULL if none */
7829/* context is used to limit payload length */
7830/* status contains the current status */
7831/* returns res in case convenient */
7832/* */
7833/* Called when one or both operands is a NaN, and propagates the */
7834/* appropriate result to res. When an sNaN is found, it is changed */
7835/* to a qNaN and Invalid operation is set. */
7836/* ------------------------------------------------------------------ */
7837static decNumber * decNaNs(decNumber *res, const decNumber *lhs,7838const decNumber *rhs, decContext *set,7839uInt *status) {7840/* This decision tree ends up with LHS being the source pointer, */7841/* and status updated if need be */7842if (lhs->bits & DECSNAN)7843*status|=DEC_Invalid_operation | DEC_sNaN;7844else if (rhs==NULL);7845else if (rhs->bits & DECSNAN) {7846lhs=rhs;7847*status|=DEC_Invalid_operation | DEC_sNaN;7848}7849else if (lhs->bits & DECNAN);7850else lhs=rhs;7851
7852/* propagate the payload */7853if (lhs->digits<=set->digits) decNumberCopy(res, lhs); /* easy */7854else { /* too long */7855const Unit *ul;7856Unit *ur, *uresp1;7857/* copy safe number of units, then decapitate */7858res->bits=lhs->bits; /* need sign etc. */7859uresp1=res->lsu+D2U(set->digits);7860for (ur=res->lsu, ul=lhs->lsu; ur<uresp1; ur++, ul++) *ur=*ul;7861res->digits=D2U(set->digits)*DECDPUN;7862/* maybe still too long */7863if (res->digits>set->digits) decDecap(res, res->digits-set->digits);7864}7865
7866res->bits&=~DECSNAN; /* convert any sNaN to NaN, while */7867res->bits|=DECNAN; /* .. preserving sign */7868res->exponent=0; /* clean exponent */7869/* [coefficient was copied/decapitated] */7870return res;7871} /* decNaNs */7872
7873/* ------------------------------------------------------------------ */
7874/* decStatus -- apply non-zero status */
7875/* */
7876/* dn is the number to set if error */
7877/* status contains the current status (not yet in context) */
7878/* set is the context */
7879/* */
7880/* If the status is an error status, the number is set to a NaN, */
7881/* unless the error was an overflow, divide-by-zero, or underflow, */
7882/* in which case the number will have already been set. */
7883/* */
7884/* The context status is then updated with the new status. Note that */
7885/* this may raise a signal, so control may never return from this */
7886/* routine (hence resources must be recovered before it is called). */
7887/* ------------------------------------------------------------------ */
7888static void decStatus(decNumber *dn, uInt status, decContext *set) {7889if (status & DEC_NaNs) { /* error status -> NaN */7890/* if cause was an sNaN, clear and propagate [NaN is already set up] */7891if (status & DEC_sNaN) status&=~DEC_sNaN;7892else {7893decNumberZero(dn); /* other error: clean throughout */7894dn->bits=DECNAN; /* and make a quiet NaN */7895}7896}7897decContextSetStatus(set, status); /* [may not return] */7898return;7899} /* decStatus */7900
7901/* ------------------------------------------------------------------ */
7902/* decGetDigits -- count digits in a Units array */
7903/* */
7904/* uar is the Unit array holding the number (this is often an */
7905/* accumulator of some sort) */
7906/* len is the length of the array in units [>=1] */
7907/* */
7908/* returns the number of (significant) digits in the array */
7909/* */
7910/* All leading zeros are excluded, except the last if the array has */
7911/* only zero Units. */
7912/* ------------------------------------------------------------------ */
7913/* This may be called twice during some operations. */
7914static Int decGetDigits(Unit *uar, Int len) {7915Unit *up=uar+(len-1); /* -> msu */7916Int digits=(len-1)*DECDPUN+1; /* possible digits excluding msu */7917#if DECDPUN>47918uInt const *pow; /* work */7919#endif7920/* (at least 1 in final msu) */7921#if DECCHECK7922if (len<1) printf("decGetDigits called with len<1 [%ld]\n", (LI)len);7923#endif7924
7925for (; up>=uar; up--) {7926if (*up==0) { /* unit is all 0s */7927if (digits==1) break; /* a zero has one digit */7928digits-=DECDPUN; /* adjust for 0 unit */7929continue;}7930/* found the first (most significant) non-zero Unit */7931#if DECDPUN>1 /* not done yet */7932if (*up<10) break; /* is 1-9 */7933digits++;7934#if DECDPUN>2 /* not done yet */7935if (*up<100) break; /* is 10-99 */7936digits++;7937#if DECDPUN>3 /* not done yet */7938if (*up<1000) break; /* is 100-999 */7939digits++;7940#if DECDPUN>4 /* count the rest ... */7941for (pow=&powers[4]; *up>=*pow; pow++) digits++;7942#endif7943#endif7944#endif7945#endif7946break;7947} /* up */7948return digits;7949} /* decGetDigits */7950
7951/* ------------------------------------------------------------------ */
7952/* mulUInt128ByPowOf10 -- multiply a 128-bit unsigned integer by a */
7953/* power of 10. */
7954/* */
7955/* The 128-bit factor composed of plow and phigh is multiplied */
7956/* by 10^exp. */
7957/* */
7958/* plow pointer to the low 64 bits of the first factor */
7959/* phigh pointer to the high 64 bits of the first factor */
7960/* exp the exponent of the power of 10 of the second factor */
7961/* */
7962/* If the result fits in 128 bits, returns false and the */
7963/* multiplication result through plow and phigh. */
7964/* Otherwise, returns true. */
7965/* ------------------------------------------------------------------ */
7966static bool mulUInt128ByPowOf10(uLong *plow, uLong *phigh, uInt pow10)7967{
7968while (pow10 >= ARRAY_SIZE(powers)) {7969if (mulu128(plow, phigh, powers[ARRAY_SIZE(powers) - 1])) {7970/* Overflow */7971return true;7972}7973pow10 -= ARRAY_SIZE(powers) - 1;7974}7975
7976if (pow10 > 0) {7977return mulu128(plow, phigh, powers[pow10]);7978} else {7979return false;7980}7981}
7982
7983#if DECTRACE | DECCHECK7984/* ------------------------------------------------------------------ */
7985/* decNumberShow -- display a number [debug aid] */
7986/* dn is the number to show */
7987/* */
7988/* Shows: sign, exponent, coefficient (msu first), digits */
7989/* or: sign, special-value */
7990/* ------------------------------------------------------------------ */
7991/* this is public so other modules can use it */
7992void decNumberShow(const decNumber *dn) {7993const Unit *up; /* work */7994uInt u, d; /* .. */7995Int cut; /* .. */7996char isign='+'; /* main sign */7997if (dn==NULL) {7998printf("NULL\n");7999return;}8000if (decNumberIsNegative(dn)) isign='-';8001printf(" >> %c ", isign);8002if (dn->bits&DECSPECIAL) { /* Is a special value */8003if (decNumberIsInfinite(dn)) printf("Infinity");8004else { /* a NaN */8005if (dn->bits&DECSNAN) printf("sNaN"); /* signalling NaN */8006else printf("NaN");8007}8008/* if coefficient and exponent are 0, no more to do */8009if (dn->exponent==0 && dn->digits==1 && *dn->lsu==0) {8010printf("\n");8011return;}8012/* drop through to report other information */8013printf(" ");8014}8015
8016/* now carefully display the coefficient */8017up=dn->lsu+D2U(dn->digits)-1; /* msu */8018printf("%ld", (LI)*up);8019for (up=up-1; up>=dn->lsu; up--) {8020u=*up;8021printf(":");8022for (cut=DECDPUN-1; cut>=0; cut--) {8023d=u/powers[cut];8024u-=d*powers[cut];8025printf("%ld", (LI)d);8026} /* cut */8027} /* up */8028if (dn->exponent!=0) {8029char esign='+';8030if (dn->exponent<0) esign='-';8031printf(" E%c%ld", esign, (LI)abs(dn->exponent));8032}8033printf(" [%ld]\n", (LI)dn->digits);8034} /* decNumberShow */8035#endif8036
8037#if DECTRACE || DECCHECK8038/* ------------------------------------------------------------------ */
8039/* decDumpAr -- display a unit array [debug/check aid] */
8040/* name is a single-character tag name */
8041/* ar is the array to display */
8042/* len is the length of the array in Units */
8043/* ------------------------------------------------------------------ */
8044static void decDumpAr(char name, const Unit *ar, Int len) {8045Int i;8046const char *spec;8047#if DECDPUN==98048spec="%09d ";8049#elif DECDPUN==88050spec="%08d ";8051#elif DECDPUN==78052spec="%07d ";8053#elif DECDPUN==68054spec="%06d ";8055#elif DECDPUN==58056spec="%05d ";8057#elif DECDPUN==48058spec="%04d ";8059#elif DECDPUN==38060spec="%03d ";8061#elif DECDPUN==28062spec="%02d ";8063#else8064spec="%d ";8065#endif8066printf(" :%c: ", name);8067for (i=len-1; i>=0; i--) {8068if (i==len-1) printf("%ld ", (LI)ar[i]);8069else printf(spec, ar[i]);8070}8071printf("\n");8072return;}8073#endif8074
8075#if DECCHECK8076/* ------------------------------------------------------------------ */
8077/* decCheckOperands -- check operand(s) to a routine */
8078/* res is the result structure (not checked; it will be set to */
8079/* quiet NaN if error found (and it is not NULL)) */
8080/* lhs is the first operand (may be DECUNRESU) */
8081/* rhs is the second (may be DECUNUSED) */
8082/* set is the context (may be DECUNCONT) */
8083/* returns 0 if both operands, and the context are clean, or 1 */
8084/* otherwise (in which case the context will show an error, */
8085/* unless NULL). Note that res is not cleaned; caller should */
8086/* handle this so res=NULL case is safe. */
8087/* The caller is expected to abandon immediately if 1 is returned. */
8088/* ------------------------------------------------------------------ */
8089static Flag decCheckOperands(decNumber *res, const decNumber *lhs,8090const decNumber *rhs, decContext *set) {8091Flag bad=0;8092if (set==NULL) { /* oops; hopeless */8093#if DECTRACE || DECVERB8094printf("Reference to context is NULL.\n");8095#endif8096bad=1;8097return 1;}8098else if (set!=DECUNCONT8099&& (set->digits<1 || set->round>=DEC_ROUND_MAX)) {8100bad=1;8101#if DECTRACE || DECVERB8102printf("Bad context [digits=%ld round=%ld].\n",8103(LI)set->digits, (LI)set->round);8104#endif8105}8106else {8107if (res==NULL) {8108bad=1;8109#if DECTRACE8110/* this one not DECVERB as standard tests include NULL */8111printf("Reference to result is NULL.\n");8112#endif8113}8114if (!bad && lhs!=DECUNUSED) bad=(decCheckNumber(lhs));8115if (!bad && rhs!=DECUNUSED) bad=(decCheckNumber(rhs));8116}8117if (bad) {8118if (set!=DECUNCONT) decContextSetStatus(set, DEC_Invalid_operation);8119if (res!=DECUNRESU && res!=NULL) {8120decNumberZero(res);8121res->bits=DECNAN; /* qNaN */8122}8123}8124return bad;8125} /* decCheckOperands */8126
8127/* ------------------------------------------------------------------ */
8128/* decCheckNumber -- check a number */
8129/* dn is the number to check */
8130/* returns 0 if the number is clean, or 1 otherwise */
8131/* */
8132/* The number is considered valid if it could be a result from some */
8133/* operation in some valid context. */
8134/* ------------------------------------------------------------------ */
8135static Flag decCheckNumber(const decNumber *dn) {8136const Unit *up; /* work */8137uInt maxuint; /* .. */8138Int ae, d, digits; /* .. */8139Int emin, emax; /* .. */8140
8141if (dn==NULL) { /* hopeless */8142#if DECTRACE8143/* this one not DECVERB as standard tests include NULL */8144printf("Reference to decNumber is NULL.\n");8145#endif8146return 1;}8147
8148/* check special values */8149if (dn->bits & DECSPECIAL) {8150if (dn->exponent!=0) {8151#if DECTRACE || DECVERB8152printf("Exponent %ld (not 0) for a special value [%02x].\n",8153(LI)dn->exponent, dn->bits);8154#endif8155return 1;}8156
8157/* 2003.09.08: NaNs may now have coefficients, so next tests Inf only */8158if (decNumberIsInfinite(dn)) {8159if (dn->digits!=1) {8160#if DECTRACE || DECVERB8161printf("Digits %ld (not 1) for an infinity.\n", (LI)dn->digits);8162#endif8163return 1;}8164if (*dn->lsu!=0) {8165#if DECTRACE || DECVERB8166printf("LSU %ld (not 0) for an infinity.\n", (LI)*dn->lsu);8167#endif8168decDumpAr('I', dn->lsu, D2U(dn->digits));8169return 1;}8170} /* Inf */8171/* 2002.12.26: negative NaNs can now appear through proposed IEEE */8172/* concrete formats (decimal64, etc.). */8173return 0;8174}8175
8176/* check the coefficient */8177if (dn->digits<1 || dn->digits>DECNUMMAXP) {8178#if DECTRACE || DECVERB8179printf("Digits %ld in number.\n", (LI)dn->digits);8180#endif8181return 1;}8182
8183d=dn->digits;8184
8185for (up=dn->lsu; d>0; up++) {8186if (d>DECDPUN) maxuint=DECDPUNMAX;8187else { /* reached the msu */8188maxuint=powers[d]-1;8189if (dn->digits>1 && *up<powers[d-1]) {8190#if DECTRACE || DECVERB8191printf("Leading 0 in number.\n");8192decNumberShow(dn);8193#endif8194return 1;}8195}8196if (*up>maxuint) {8197#if DECTRACE || DECVERB8198printf("Bad Unit [%08lx] in %ld-digit number at offset %ld [maxuint %ld].\n",8199(LI)*up, (LI)dn->digits, (LI)(up-dn->lsu), (LI)maxuint);8200#endif8201return 1;}8202d-=DECDPUN;8203}8204
8205/* check the exponent. Note that input operands can have exponents */8206/* which are out of the set->emin/set->emax and set->digits range */8207/* (just as they can have more digits than set->digits). */8208ae=dn->exponent+dn->digits-1; /* adjusted exponent */8209emax=DECNUMMAXE;8210emin=DECNUMMINE;8211digits=DECNUMMAXP;8212if (ae<emin-(digits-1)) {8213#if DECTRACE || DECVERB8214printf("Adjusted exponent underflow [%ld].\n", (LI)ae);8215decNumberShow(dn);8216#endif8217return 1;}8218if (ae>+emax) {8219#if DECTRACE || DECVERB8220printf("Adjusted exponent overflow [%ld].\n", (LI)ae);8221decNumberShow(dn);8222#endif8223return 1;}8224
8225return 0; /* it's OK */8226} /* decCheckNumber */8227
8228/* ------------------------------------------------------------------ */
8229/* decCheckInexact -- check a normal finite inexact result has digits */
8230/* dn is the number to check */
8231/* set is the context (for status and precision) */
8232/* sets Invalid operation, etc., if some digits are missing */
8233/* [this check is not made for DECSUBSET compilation or when */
8234/* subnormal is not set] */
8235/* ------------------------------------------------------------------ */
8236static void decCheckInexact(const decNumber *dn, decContext *set) {8237#if !DECSUBSET && DECEXTFLAG8238if ((set->status & (DEC_Inexact|DEC_Subnormal))==DEC_Inexact8239&& (set->digits!=dn->digits) && !(dn->bits & DECSPECIAL)) {8240#if DECTRACE || DECVERB8241printf("Insufficient digits [%ld] on normal Inexact result.\n",8242(LI)dn->digits);8243decNumberShow(dn);8244#endif8245decContextSetStatus(set, DEC_Invalid_operation);8246}8247#else8248/* next is a noop for quiet compiler */8249if (dn!=NULL && dn->digits==0) set->status|=DEC_Invalid_operation;8250#endif8251return;8252} /* decCheckInexact */8253#endif8254
8255#if DECALLOC8256#undef malloc8257#undef free8258/* ------------------------------------------------------------------ */
8259/* decMalloc -- accountable allocation routine */
8260/* n is the number of bytes to allocate */
8261/* */
8262/* Semantics is the same as the stdlib malloc routine, but bytes */
8263/* allocated are accounted for globally, and corruption fences are */
8264/* added before and after the 'actual' storage. */
8265/* ------------------------------------------------------------------ */
8266/* This routine allocates storage with an extra twelve bytes; 8 are */
8267/* at the start and hold: */
8268/* 0-3 the original length requested */
8269/* 4-7 buffer corruption detection fence (DECFENCE, x4) */
8270/* The 4 bytes at the end also hold a corruption fence (DECFENCE, x4) */
8271/* ------------------------------------------------------------------ */
8272static void *decMalloc(size_t n) {8273uInt size=n+12; /* true size */8274void *alloc; /* -> allocated storage */8275uInt *j; /* work */8276uByte *b, *b0; /* .. */8277
8278alloc=malloc(size); /* -> allocated storage */8279if (alloc==NULL) return NULL; /* out of strorage */8280b0=(uByte *)alloc; /* as bytes */8281decAllocBytes+=n; /* account for storage */8282j=(uInt *)alloc; /* -> first four bytes */8283*j=n; /* save n */8284/* printf(" alloc ++ dAB: %ld (%d)\n", decAllocBytes, n); */8285for (b=b0+4; b<b0+8; b++) *b=DECFENCE;8286for (b=b0+n+8; b<b0+n+12; b++) *b=DECFENCE;8287return b0+8; /* -> play area */8288} /* decMalloc */8289
8290/* ------------------------------------------------------------------ */
8291/* decFree -- accountable free routine */
8292/* alloc is the storage to free */
8293/* */
8294/* Semantics is the same as the stdlib malloc routine, except that */
8295/* the global storage accounting is updated and the fences are */
8296/* checked to ensure that no routine has written 'out of bounds'. */
8297/* ------------------------------------------------------------------ */
8298/* This routine first checks that the fences have not been corrupted. */
8299/* It then frees the storage using the 'truw' storage address (that */
8300/* is, offset by 8). */
8301/* ------------------------------------------------------------------ */
8302static void decFree(void *alloc) {8303uInt *j, n; /* pointer, original length */8304uByte *b, *b0; /* work */8305
8306if (alloc==NULL) return; /* allowed; it's a nop */8307b0=(uByte *)alloc; /* as bytes */8308b0-=8; /* -> true start of storage */8309j=(uInt *)b0; /* -> first four bytes */8310n=*j; /* lift */8311for (b=b0+4; b<b0+8; b++) if (*b!=DECFENCE)8312printf("=== Corrupt byte [%02x] at offset %d from %ld ===\n", *b,8313b-b0-8, (Int)b0);8314for (b=b0+n+8; b<b0+n+12; b++) if (*b!=DECFENCE)8315printf("=== Corrupt byte [%02x] at offset +%d from %ld, n=%ld ===\n", *b,8316b-b0-8, (Int)b0, n);8317free(b0); /* drop the storage */8318decAllocBytes-=n; /* account for storage */8319/* printf(" free -- dAB: %d (%d)\n", decAllocBytes, -n); */8320} /* decFree */8321#define malloc(a) decMalloc(a)8322#define free(a) decFree(a)8323#endif8324