hw/audio/intel-hda: Restrict DMA engine to memories (not MMIO devices)
[qemu/rayw.git] / libdecnumber / decNumber.c
blob31282adafdc9895b7764ad8ae68a398493540f6d
1 /* Decimal number arithmetic module for the decNumber C Library.
2 Copyright (C) 2005, 2007 Free Software Foundation, Inc.
3 Contributed by IBM Corporation. Author Mike Cowlishaw.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 In addition to the permissions in the GNU General Public License,
13 the Free Software Foundation gives you unlimited permission to link
14 the compiled version of this file into combinations with other
15 programs, and to distribute those combinations without any
16 restriction coming from the use of this file. (The General Public
17 License restrictions do apply in other respects; for example, they
18 cover modification of the file, and distribution when not linked
19 into a combine executable.)
21 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
22 WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 for more details.
26 You should have received a copy of the GNU General Public License
27 along with GCC; see the file COPYING. If not, write to the Free
28 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
29 02110-1301, USA. */
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 /* ------------------------------------------------------------------ */
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"
175 /* Constants */
176 /* Public lookup table used by the D2U macro */
177 const uByte d2utable[DECMAXD2U+1]=D2UTABLE;
179 #define DECVERB 1 /* set to 1 for verbose DECCHECK */
180 #define powers DECPOWERS /* old internal name */
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 /* .. */
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)0x80000002
200 #define BIGODD (Int)0x80000003
202 static Unit uarrone[1]={1}; /* Unit array of 1, used for incrementing */
204 /* Granularity-dependent code */
205 #if DECDPUN<=4
206 #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] */
211 static 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 #else
215 /* For DECDPUN>4 non-ANSI-89 64-bit types are needed. */
216 #if !DECUSE64
217 #error decNumber.c: DECUSE64 must be 1 when DECDPUN>4
218 #endif
219 #define eInt Long /* extended integer */
220 #define ueInt uLong /* unsigned extended integer */
221 #endif
223 /* Local routines */
224 static decNumber * decAddOp(decNumber *, const decNumber *, const decNumber *,
225 decContext *, uByte, uInt *);
226 static Flag decBiStr(const char *, const char *, const char *);
227 static uInt decCheckMath(const decNumber *, decContext *, uInt *);
228 static void decApplyRound(decNumber *, decContext *, Int, uInt *);
229 static Int decCompare(const decNumber *lhs, const decNumber *rhs, Flag);
230 static decNumber * decCompareOp(decNumber *, const decNumber *,
231 const decNumber *, decContext *,
232 Flag, uInt *);
233 static void decCopyFit(decNumber *, const decNumber *, decContext *,
234 Int *, uInt *);
235 static decNumber * decDecap(decNumber *, Int);
236 static decNumber * decDivideOp(decNumber *, const decNumber *,
237 const decNumber *, decContext *, Flag, uInt *);
238 static decNumber * decExpOp(decNumber *, const decNumber *,
239 decContext *, uInt *);
240 static void decFinalize(decNumber *, decContext *, Int *, uInt *);
241 static Int decGetDigits(Unit *, Int);
242 static Int decGetInt(const decNumber *);
243 static decNumber * decLnOp(decNumber *, const decNumber *,
244 decContext *, uInt *);
245 static decNumber * decMultiplyOp(decNumber *, const decNumber *,
246 const decNumber *, decContext *,
247 uInt *);
248 static decNumber * decNaNs(decNumber *, const decNumber *,
249 const decNumber *, decContext *, uInt *);
250 static decNumber * decQuantizeOp(decNumber *, const decNumber *,
251 const decNumber *, decContext *, Flag,
252 uInt *);
253 static void decReverse(Unit *, Unit *);
254 static void decSetCoeff(decNumber *, decContext *, const Unit *,
255 Int, Int *, uInt *);
256 static void decSetMaxValue(decNumber *, decContext *);
257 static void decSetOverflow(decNumber *, decContext *, uInt *);
258 static void decSetSubnormal(decNumber *, decContext *, Int *, uInt *);
259 static Int decShiftToLeast(Unit *, Int, Int);
260 static Int decShiftToMost(Unit *, Int, Int);
261 static void decStatus(decNumber *, uInt, decContext *);
262 static void decToString(const decNumber *, char[], Flag);
263 static decNumber * decTrim(decNumber *, decContext *, Flag, Int *);
264 static Int decUnitAddSub(const Unit *, Int, const Unit *, Int, Int,
265 Unit *, Int);
266 static Int decUnitCompare(const Unit *, Int, const Unit *, Int, Int);
267 static bool mulUInt128ByPowOf10(uLong *, uLong *, uInt);
269 #if !DECSUBSET
270 /* decFinish == decFinalize when no subset arithmetic needed */
271 #define decFinish(a,b,c,d) decFinalize(a,b,c,d)
272 #else
273 static void decFinish(decNumber *, decContext *, Int *, uInt *);
274 static decNumber * decRoundOperand(const decNumber *, decContext *, uInt *);
275 #endif
277 /* Local macros */
278 /* masked special-values bits */
279 #define SPECIALARG (rhs->bits & DECSPECIAL)
280 #define SPECIALARGS ((lhs->bits | rhs->bits) & DECSPECIAL)
282 /* Diagnostic macros, etc. */
283 #if DECALLOC
284 /* 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: */
291 static void *decMalloc(size_t);
292 static void decFree(void *);
293 uInt 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 #endif
301 #if DECCHECK
302 /* 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))
313 static Flag decCheckOperands(decNumber *, const decNumber *,
314 const decNumber *, decContext *);
315 static Flag decCheckNumber(const decNumber *);
316 static void decCheckInexact(const decNumber *, decContext *);
317 #endif
319 #if DECTRACE || DECCHECK
320 /* Optional trace/debugging routines (may or may not be used) */
321 void decNumberShow(const decNumber *); /* displays the components of a number */
322 static void decDumpAr(char, const Unit *, Int);
323 #endif
325 /* ================================================================== */
326 /* Conversions */
327 /* ================================================================== */
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 /* ------------------------------------------------------------------ */
338 decNumber * decNumberFromInt32(decNumber *dn, Int in) {
339 uInt unsig;
340 if (in>=0) unsig=in;
341 else { /* negative (possibly BADINT) */
342 if (in==BADINT) unsig=(uInt)1073741824*2; /* special case */
343 else unsig=-in; /* invert */
345 /* in is now positive */
346 decNumberFromUInt32(dn, unsig);
347 if (in<0) dn->bits=DECNEG; /* sign needed */
348 return dn;
349 } /* decNumberFromInt32 */
351 decNumber * decNumberFromUInt32(decNumber *dn, uInt uin) {
352 Unit *up; /* work pointer */
353 decNumberZero(dn); /* clean */
354 if (uin==0) return dn; /* [or decGetDigits bad call] */
355 for (up=dn->lsu; uin>0; up++) {
356 *up=(Unit)(uin%(DECDPUNMAX+1));
357 uin=uin/(DECDPUNMAX+1);
359 dn->digits=decGetDigits(dn->lsu, up-dn->lsu);
360 return dn;
361 } /* decNumberFromUInt32 */
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 /* ------------------------------------------------------------------ */
373 Int decNumberToInt32(const decNumber *dn, decContext *set) {
374 #if DECCHECK
375 if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
376 #endif
378 /* special or too many digits, or bad exponent */
379 if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0) ; /* bad */
380 else { /* is a finite integer with 10 or fewer digits */
381 Int d; /* work */
382 const Unit *up; /* .. */
383 uInt hi=0, lo; /* .. */
384 up=dn->lsu; /* -> lsu */
385 lo=*up; /* get 1 to 9 digits */
386 #if DECDPUN>1 /* split to higher */
387 hi=lo/10;
388 lo=lo%10;
389 #endif
390 up++;
391 /* collect remaining Units, if any, into hi */
392 for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];
393 /* now low has the lsd, hi the remainder */
394 if (hi>214748364 || (hi==214748364 && lo>7)) { /* out of range? */
395 /* most-negative is a reprieve */
396 if (dn->bits&DECNEG && hi==214748364 && lo==8) return 0x80000000;
397 /* bad -- drop through */
399 else { /* in-range always */
400 Int i=X10(hi)+lo;
401 if (dn->bits&DECNEG) return -i;
402 return i;
404 } /* integer */
405 decContextSetStatus(set, DEC_Invalid_operation); /* [may not return] */
406 return 0;
407 } /* decNumberToInt32 */
409 uInt decNumberToUInt32(const decNumber *dn, decContext *set) {
410 #if DECCHECK
411 if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
412 #endif
413 /* special or too many digits, or bad exponent, or negative (<0) */
414 if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0
415 || (dn->bits&DECNEG && !ISZERO(dn))); /* bad */
416 else { /* is a finite integer with 10 or fewer digits */
417 Int d; /* work */
418 const Unit *up; /* .. */
419 uInt hi=0, lo; /* .. */
420 up=dn->lsu; /* -> lsu */
421 lo=*up; /* get 1 to 9 digits */
422 #if DECDPUN>1 /* split to higher */
423 hi=lo/10;
424 lo=lo%10;
425 #endif
426 up++;
427 /* collect remaining Units, if any, into hi */
428 for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];
430 /* now low has the lsd, hi the remainder */
431 if (hi>429496729 || (hi==429496729 && lo>5)) ; /* no reprieve possible */
432 else return X10(hi)+lo;
433 } /* integer */
434 decContextSetStatus(set, DEC_Invalid_operation); /* [may not return] */
435 return 0;
436 } /* decNumberToUInt32 */
438 decNumber *decNumberFromInt64(decNumber *dn, int64_t in)
440 uint64_t unsig = in;
441 if (in < 0) {
442 unsig = -unsig;
445 decNumberFromUInt64(dn, unsig);
446 if (in < 0) {
447 dn->bits = DECNEG; /* sign needed */
449 return dn;
450 } /* decNumberFromInt64 */
452 decNumber *decNumberFromUInt64(decNumber *dn, uint64_t uin)
454 Unit *up; /* work pointer */
455 decNumberZero(dn); /* clean */
456 if (uin == 0) {
457 return dn; /* [or decGetDigits bad call] */
459 for (up = dn->lsu; uin > 0; up++) {
460 *up = (Unit)(uin % (DECDPUNMAX + 1));
461 uin = uin / (DECDPUNMAX + 1);
463 dn->digits = decGetDigits(dn->lsu, up-dn->lsu);
464 return dn;
465 } /* decNumberFromUInt64 */
467 decNumber *decNumberFromInt128(decNumber *dn, uint64_t lo, int64_t hi)
469 uint64_t unsig_hi = hi;
470 if (hi < 0) {
471 if (lo == 0) {
472 unsig_hi = -unsig_hi;
473 } else {
474 unsig_hi = ~unsig_hi;
475 lo = -lo;
479 decNumberFromUInt128(dn, lo, unsig_hi);
480 if (hi < 0) {
481 dn->bits = DECNEG; /* sign needed */
483 return dn;
484 } /* decNumberFromInt128 */
486 decNumber *decNumberFromUInt128(decNumber *dn, uint64_t lo, uint64_t hi)
488 uint64_t rem;
489 Unit *up; /* work pointer */
490 decNumberZero(dn); /* clean */
491 if (lo == 0 && hi == 0) {
492 return dn; /* [or decGetDigits bad call] */
494 for (up = dn->lsu; hi > 0 || lo > 0; up++) {
495 rem = divu128(&lo, &hi, DECDPUNMAX + 1);
496 *up = (Unit)rem;
498 dn->digits = decGetDigits(dn->lsu, up - dn->lsu);
499 return dn;
500 } /* decNumberFromUInt128 */
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 /* ------------------------------------------------------------------ */
514 int64_t decNumberIntegralToInt64(const decNumber *dn, decContext *set)
516 if (decNumberIsSpecial(dn) || (dn->exponent < 0) ||
517 (dn->digits + dn->exponent > 19)) {
518 goto Invalid;
519 } else {
520 int64_t d; /* work */
521 const Unit *up; /* .. */
522 uint64_t hi = 0;
523 up = dn->lsu; /* -> lsu */
525 for (d = 1; d <= dn->digits; up++, d += DECDPUN) {
526 uint64_t prev = hi;
527 hi += *up * powers[d-1];
528 if ((hi < prev) || (hi > INT64_MAX)) {
529 goto Invalid;
533 uint64_t prev = hi;
534 hi *= (uint64_t)powers[dn->exponent];
535 if ((hi < prev) || (hi > INT64_MAX)) {
536 goto Invalid;
538 return (decNumberIsNegative(dn)) ? -((int64_t)hi) : (int64_t)hi;
541 Invalid:
542 decContextSetStatus(set, DEC_Invalid_operation);
543 return 0;
544 } /* decNumberIntegralToInt64 */
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 /* ------------------------------------------------------------------ */
558 void decNumberIntegralToInt128(const decNumber *dn, decContext *set,
559 uint64_t *plow, uint64_t *phigh)
561 int d; /* work */
562 const Unit *up; /* .. */
563 uint64_t lo = 0, hi = 0;
565 if (decNumberIsSpecial(dn) || (dn->exponent < 0) ||
566 (dn->digits + dn->exponent > 39)) {
567 goto Invalid;
570 up = dn->lsu; /* -> lsu */
572 for (d = (dn->digits - 1) / DECDPUN; d >= 0; d--) {
573 if (mulu128(&lo, &hi, DECDPUNMAX + 1)) {
574 /* overflow */
575 goto Invalid;
577 if (uadd64_overflow(lo, up[d], &lo)) {
578 if (uadd64_overflow(hi, 1, &hi)) {
579 /* overflow */
580 goto Invalid;
585 if (mulUInt128ByPowOf10(&lo, &hi, dn->exponent)) {
586 /* overflow */
587 goto Invalid;
590 if (decNumberIsNegative(dn)) {
591 if (lo == 0) {
592 *phigh = -hi;
593 *plow = 0;
594 } else {
595 *phigh = ~hi;
596 *plow = -lo;
598 } else {
599 *plow = lo;
600 *phigh = hi;
603 return;
605 Invalid:
606 decContextSetStatus(set, DEC_Invalid_operation);
607 } /* decNumberIntegralToInt128 */
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 /* ------------------------------------------------------------------ */
623 char * decNumberToString(const decNumber *dn, char *string){
624 decToString(dn, string, 0);
625 return string;
626 } /* DecNumberToString */
628 char * decNumberToEngString(const decNumber *dn, char *string){
629 decToString(dn, string, 1);
630 return string;
631 } /* DecNumberToEngString */
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 /* ------------------------------------------------------------------ */
653 decNumber * decNumberFromString(decNumber *dn, const char chars[],
654 decContext *set) {
655 Int exponent=0; /* working exponent [assume 0] */
656 uByte bits=0; /* working flags [assume +ve] */
657 Unit *res; /* where result will be built */
658 Unit resbuff[SD2U(DECBUFFER+9)];/* local buffer in case need temporary */
659 /* [+9 allows for ln() constants] */
660 Unit *allocres=NULL; /* -> allocated result, iff allocated */
661 Int d=0; /* count of digits found in decimal part */
662 const char *dotchar=NULL; /* where dot was found */
663 const char *cfirst=chars; /* -> first character of decimal part */
664 const char *last=NULL; /* -> last digit of decimal part */
665 const char *c; /* work */
666 Unit *up; /* .. */
667 #if DECDPUN>1
668 Int cut, out; /* .. */
669 #endif
670 Int residue; /* rounding residue */
671 uInt status=0; /* error code */
673 #if DECCHECK
674 if (decCheckOperands(DECUNRESU, DECUNUSED, DECUNUSED, set))
675 return decNumberZero(dn);
676 #endif
678 do { /* status & malloc protection */
679 for (c=chars;; c++) { /* -> input character */
680 if (*c>='0' && *c<='9') { /* test for Arabic digit */
681 last=c;
682 d++; /* count of real digits */
683 continue; /* still in decimal part */
685 if (*c=='.' && dotchar==NULL) { /* first '.' */
686 dotchar=c; /* record offset into decimal part */
687 if (c==cfirst) cfirst++; /* first digit must follow */
688 continue;}
689 if (c==chars) { /* first in string... */
690 if (*c=='-') { /* valid - sign */
691 cfirst++;
692 bits=DECNEG;
693 continue;}
694 if (*c=='+') { /* valid + sign */
695 cfirst++;
696 continue;}
698 /* *c is not a digit, or a valid +, -, or '.' */
699 break;
700 } /* c */
702 if (last==NULL) { /* no digits yet */
703 status=DEC_Conversion_syntax;/* assume the worst */
704 if (*c=='\0') break; /* and no more to come... */
705 #if DECSUBSET
706 /* if subset then infinities and NaNs are not allowed */
707 if (!set->extended) break; /* hopeless */
708 #endif
709 /* Infinities and NaNs are possible, here */
710 if (dotchar!=NULL) break; /* .. unless had a dot */
711 decNumberZero(dn); /* be optimistic */
712 if (decBiStr(c, "infinity", "INFINITY")
713 || decBiStr(c, "inf", "INF")) {
714 dn->bits=bits | DECINF;
715 status=0; /* is OK */
716 break; /* all done */
718 /* a NaN expected */
719 /* 2003.09.10 NaNs are now permitted to have a sign */
720 dn->bits=bits | DECNAN; /* assume simple NaN */
721 if (*c=='s' || *c=='S') { /* looks like an sNaN */
722 c++;
723 dn->bits=bits | DECSNAN;
725 if (*c!='n' && *c!='N') break; /* check caseless "NaN" */
726 c++;
727 if (*c!='a' && *c!='A') break; /* .. */
728 c++;
729 if (*c!='n' && *c!='N') break; /* .. */
730 c++;
731 /* now either nothing, or nnnn payload, expected */
732 /* -> start of integer and skip leading 0s [including plain 0] */
733 for (cfirst=c; *cfirst=='0';) cfirst++;
734 if (*cfirst=='\0') { /* "NaN" or "sNaN", maybe with all 0s */
735 status=0; /* it's good */
736 break; /* .. */
738 /* something other than 0s; setup last and d as usual [no dots] */
739 for (c=cfirst;; c++, d++) {
740 if (*c<'0' || *c>'9') break; /* test for Arabic digit */
741 last=c;
743 if (*c!='\0') break; /* not all digits */
744 if (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] */
747 if (set->clamp) break;
748 if (d>set->digits) break;
749 } /* too many digits? */
750 /* good; drop through to convert the integer to coefficient */
751 status=0; /* syntax is OK */
752 bits=dn->bits; /* for copy-back */
753 } /* last==NULL */
755 else if (*c!='\0') { /* more to process... */
756 /* had some digits; exponent is only valid sequence now */
757 Flag nege; /* 1=negative exponent */
758 const char *firstexp; /* -> first significant exponent digit */
759 status=DEC_Conversion_syntax;/* assume the worst */
760 if (*c!='e' && *c!='E') break;
761 /* Found 'e' or 'E' -- now process explicit exponent */
762 /* 1998.07.11: sign no longer required */
763 nege=0;
764 c++; /* to (possible) sign */
765 if (*c=='-') {nege=1; c++;}
766 else if (*c=='+') c++;
767 if (*c=='\0') break;
769 for (; *c=='0' && *(c+1)!='\0';) c++; /* strip insignificant zeros */
770 firstexp=c; /* save exponent digit place */
771 for (; ;c++) {
772 if (*c<'0' || *c>'9') break; /* not a digit */
773 exponent=X10(exponent)+(Int)*c-(Int)'0';
774 } /* c */
775 /* if not now on a '\0', *c must not be a digit */
776 if (*c!='\0') break;
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 */
781 if (c>=firstexp+9+1) {
782 if (c>firstexp+9+1 || *firstexp>'1') exponent=DECNUMMAXE*2;
783 /* [up to 1999999999 is OK, for example 1E-1000000998] */
785 if (nege) exponent=-exponent; /* was negative */
786 status=0; /* is OK */
787 } /* stuff after digits */
789 /* Here when whole string has been inspected; syntax is good */
790 /* cfirst->first digit (never dot), last->last digit (ditto) */
792 /* strip leading zeros/dot [leave final 0 if all 0's] */
793 if (*cfirst=='0') { /* [cfirst has stepped over .] */
794 for (c=cfirst; c<last; c++, cfirst++) {
795 if (*c=='.') continue; /* ignore dots */
796 if (*c!='0') break; /* non-zero found */
797 d--; /* 0 stripped */
798 } /* c */
799 #if DECSUBSET
800 /* make a rapid exit for easy zeros if !extended */
801 if (*cfirst=='0' && !set->extended) {
802 decNumberZero(dn); /* clean result */
803 break; /* [could be return] */
805 #endif
806 } /* at least one leading 0 */
808 /* Handle decimal point... */
809 if (dotchar!=NULL && dotchar<last) /* non-trailing '.' found? */
810 exponent-=(last-dotchar); /* adjust exponent */
811 /* [we can now ignore the .] */
813 /* OK, the digits string is good. Assemble in the decNumber, or in */
814 /* a temporary units array if rounding is needed */
815 if (d<=set->digits) res=dn->lsu; /* fits into supplied decNumber */
816 else { /* rounding needed */
817 Int needbytes=D2U(d)*sizeof(Unit);/* bytes needed */
818 res=resbuff; /* assume use local buffer */
819 if (needbytes>(Int)sizeof(resbuff)) { /* too big for local */
820 allocres=(Unit *)malloc(needbytes);
821 if (allocres==NULL) {status|=DEC_Insufficient_storage; break;}
822 res=allocres;
825 /* res now -> number lsu, buffer, or allocated storage for Unit array */
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>1
830 out=0; /* accumulator */
831 up=res+D2U(d)-1; /* -> msu */
832 cut=d-(up-res)*DECDPUN; /* digits in top unit */
833 for (c=cfirst;; c++) { /* along the digits */
834 if (*c=='.') continue; /* ignore '.' [don't decrement cut] */
835 out=X10(out)+(Int)*c-(Int)'0';
836 if (c==last) break; /* done [never get to trailing '.'] */
837 cut--;
838 if (cut>0) continue; /* more for this unit */
839 *up=(Unit)out; /* write unit */
840 up--; /* prepare for unit below.. */
841 cut=DECDPUN; /* .. */
842 out=0; /* .. */
843 } /* c */
844 *up=(Unit)out; /* write lsu */
846 #else
847 /* DECDPUN==1 */
848 up=res; /* -> lsu */
849 for (c=last; c>=cfirst; c--) { /* over each character, from least */
850 if (*c=='.') continue; /* ignore . [don't step up] */
851 *up=(Unit)((Int)*c-(Int)'0');
852 up++;
853 } /* c */
854 #endif
856 dn->bits=bits;
857 dn->exponent=exponent;
858 dn->digits=d;
860 /* if not in number (too long) shorten into the number */
861 if (d>set->digits) {
862 residue=0;
863 decSetCoeff(dn, set, res, d, &residue, &status);
864 /* always check for overflow or subnormal and round as needed */
865 decFinalize(dn, set, &residue, &status);
867 else { /* no rounding, but may still have overflow or subnormal */
868 /* [these tests are just for performance; finalize repeats them] */
869 if ((dn->exponent-1<set->emin-dn->digits)
870 || (dn->exponent-1>set->emax-set->digits)) {
871 residue=0;
872 decFinalize(dn, set, &residue, &status);
875 /* decNumberShow(dn); */
876 } while(0); /* [for break] */
878 if (allocres!=NULL) free(allocres); /* drop any storage used */
879 if (status!=0) decStatus(dn, status, set);
880 return dn;
881 } /* decNumberFromString */
883 /* ================================================================== */
884 /* Operators */
885 /* ================================================================== */
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 /* ------------------------------------------------------------------ */
902 decNumber * decNumberAbs(decNumber *res, const decNumber *rhs,
903 decContext *set) {
904 decNumber dzero; /* for 0 */
905 uInt status=0; /* accumulator */
907 #if DECCHECK
908 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
909 #endif
911 decNumberZero(&dzero); /* set 0 */
912 dzero.exponent=rhs->exponent; /* [no coefficient expansion] */
913 decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status);
914 if (status!=0) decStatus(res, status, set);
915 #if DECCHECK
916 decCheckInexact(res, set);
917 #endif
918 return res;
919 } /* decNumberAbs */
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 */
934 decNumber * decNumberAdd(decNumber *res, const decNumber *lhs,
935 const decNumber *rhs, decContext *set) {
936 uInt status=0; /* accumulator */
937 decAddOp(res, lhs, rhs, set, 0, &status);
938 if (status!=0) decStatus(res, status, set);
939 #if DECCHECK
940 decCheckInexact(res, set);
941 #endif
942 return res;
943 } /* decNumberAdd */
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 /* ------------------------------------------------------------------ */
960 decNumber * decNumberAnd(decNumber *res, const decNumber *lhs,
961 const decNumber *rhs, decContext *set) {
962 const Unit *ua, *ub; /* -> operands */
963 const Unit *msua, *msub; /* -> operand msus */
964 Unit *uc, *msuc; /* -> result and its msu */
965 Int msudigs; /* digits in res msu */
966 #if DECCHECK
967 if (decCheckOperands(res, lhs, rhs, set)) return res;
968 #endif
970 if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
971 || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
972 decStatus(res, DEC_Invalid_operation, set);
973 return res;
976 /* operands are valid */
977 ua=lhs->lsu; /* bottom-up */
978 ub=rhs->lsu; /* .. */
979 uc=res->lsu; /* .. */
980 msua=ua+D2U(lhs->digits)-1; /* -> msu of lhs */
981 msub=ub+D2U(rhs->digits)-1; /* -> msu of rhs */
982 msuc=uc+D2U(set->digits)-1; /* -> msu of result */
983 msudigs=MSUDIGITS(set->digits); /* [faster than remainder] */
984 for (; uc<=msuc; ua++, ub++, uc++) { /* Unit loop */
985 Unit a, b; /* extract units */
986 if (ua>msua) a=0;
987 else a=*ua;
988 if (ub>msub) b=0;
989 else b=*ub;
990 *uc=0; /* can now write back */
991 if (a|b) { /* maybe 1 bits to examine */
992 Int i, j;
993 *uc=0; /* can now write back */
994 /* This loop could be unrolled and/or use BIN2BCD tables */
995 for (i=0; i<DECDPUN; i++) {
996 if (a&b&1) *uc=*uc+(Unit)powers[i]; /* effect AND */
997 j=a%10;
998 a=a/10;
999 j|=b%10;
1000 b=b/10;
1001 if (j>1) {
1002 decStatus(res, DEC_Invalid_operation, set);
1003 return res;
1005 if (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] */
1010 res->digits=decGetDigits(res->lsu, uc-res->lsu);
1011 res->exponent=0; /* integer */
1012 res->bits=0; /* sign=0 */
1013 return res; /* [no status to set] */
1014 } /* decNumberAnd */
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 /* ------------------------------------------------------------------ */
1028 decNumber * decNumberCompare(decNumber *res, const decNumber *lhs,
1029 const decNumber *rhs, decContext *set) {
1030 uInt status=0; /* accumulator */
1031 decCompareOp(res, lhs, rhs, set, COMPARE, &status);
1032 if (status!=0) decStatus(res, status, set);
1033 return res;
1034 } /* decNumberCompare */
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 /* ------------------------------------------------------------------ */
1048 decNumber * decNumberCompareSignal(decNumber *res, const decNumber *lhs,
1049 const decNumber *rhs, decContext *set) {
1050 uInt status=0; /* accumulator */
1051 decCompareOp(res, lhs, rhs, set, COMPSIG, &status);
1052 if (status!=0) decStatus(res, status, set);
1053 return res;
1054 } /* decNumberCompareSignal */
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 /* ------------------------------------------------------------------ */
1069 decNumber * decNumberCompareTotal(decNumber *res, const decNumber *lhs,
1070 const decNumber *rhs, decContext *set) {
1071 uInt status=0; /* accumulator */
1072 decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
1073 if (status!=0) decStatus(res, status, set);
1074 return res;
1075 } /* decNumberCompareTotal */
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 /* ------------------------------------------------------------------ */
1090 decNumber * decNumberCompareTotalMag(decNumber *res, const decNumber *lhs,
1091 const decNumber *rhs, decContext *set) {
1092 uInt status=0; /* accumulator */
1093 uInt needbytes; /* for space calculations */
1094 decNumber bufa[D2N(DECBUFFER+1)];/* +1 in case DECBUFFER=0 */
1095 decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */
1096 decNumber bufb[D2N(DECBUFFER+1)];
1097 decNumber *allocbufb=NULL; /* -> allocated bufb, iff allocated */
1098 decNumber *a, *b; /* temporary pointers */
1100 #if DECCHECK
1101 if (decCheckOperands(res, lhs, rhs, set)) return res;
1102 #endif
1104 do { /* protect allocated storage */
1105 /* if either is negative, take a copy and absolute */
1106 if (decNumberIsNegative(lhs)) { /* lhs<0 */
1107 a=bufa;
1108 needbytes=sizeof(decNumber)+(D2U(lhs->digits)-1)*sizeof(Unit);
1109 if (needbytes>sizeof(bufa)) { /* need malloc space */
1110 allocbufa=(decNumber *)malloc(needbytes);
1111 if (allocbufa==NULL) { /* hopeless -- abandon */
1112 status|=DEC_Insufficient_storage;
1113 break;}
1114 a=allocbufa; /* use the allocated space */
1116 decNumberCopy(a, lhs); /* copy content */
1117 a->bits&=~DECNEG; /* .. and clear the sign */
1118 lhs=a; /* use copy from here on */
1120 if (decNumberIsNegative(rhs)) { /* rhs<0 */
1121 b=bufb;
1122 needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
1123 if (needbytes>sizeof(bufb)) { /* need malloc space */
1124 allocbufb=(decNumber *)malloc(needbytes);
1125 if (allocbufb==NULL) { /* hopeless -- abandon */
1126 status|=DEC_Insufficient_storage;
1127 break;}
1128 b=allocbufb; /* use the allocated space */
1130 decNumberCopy(b, rhs); /* copy content */
1131 b->bits&=~DECNEG; /* .. and clear the sign */
1132 rhs=b; /* use copy from here on */
1134 decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
1135 } while(0); /* end protected */
1137 if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */
1138 if (allocbufb!=NULL) free(allocbufb); /* .. */
1139 if (status!=0) decStatus(res, status, set);
1140 return res;
1141 } /* decNumberCompareTotalMag */
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 /* ------------------------------------------------------------------ */
1155 decNumber * decNumberDivide(decNumber *res, const decNumber *lhs,
1156 const decNumber *rhs, decContext *set) {
1157 uInt status=0; /* accumulator */
1158 decDivideOp(res, lhs, rhs, set, DIVIDE, &status);
1159 if (status!=0) decStatus(res, status, set);
1160 #if DECCHECK
1161 decCheckInexact(res, set);
1162 #endif
1163 return res;
1164 } /* decNumberDivide */
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 /* ------------------------------------------------------------------ */
1178 decNumber * decNumberDivideInteger(decNumber *res, const decNumber *lhs,
1179 const decNumber *rhs, decContext *set) {
1180 uInt status=0; /* accumulator */
1181 decDivideOp(res, lhs, rhs, set, DIVIDEINT, &status);
1182 if (status!=0) decStatus(res, status, set);
1183 return res;
1184 } /* decNumberDivideInteger */
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 /* ------------------------------------------------------------------ */
1211 decNumber * decNumberExp(decNumber *res, const decNumber *rhs,
1212 decContext *set) {
1213 uInt status=0; /* accumulator */
1214 #if DECSUBSET
1215 decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */
1216 #endif
1218 #if DECCHECK
1219 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1220 #endif
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. */
1226 if (!decCheckMath(rhs, set, &status)) do { /* protect allocation */
1227 #if DECSUBSET
1228 if (!set->extended) {
1229 /* reduce operand and set lostDigits status, as needed */
1230 if (rhs->digits>set->digits) {
1231 allocrhs=decRoundOperand(rhs, set, &status);
1232 if (allocrhs==NULL) break;
1233 rhs=allocrhs;
1236 #endif
1237 decExpOp(res, rhs, set, &status);
1238 } while(0); /* end protected */
1240 #if DECSUBSET
1241 if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */
1242 #endif
1243 /* apply significant status */
1244 if (status!=0) decStatus(res, status, set);
1245 #if DECCHECK
1246 decCheckInexact(res, set);
1247 #endif
1248 return res;
1249 } /* decNumberExp */
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 /* ------------------------------------------------------------------ */
1267 decNumber * decNumberFMA(decNumber *res, const decNumber *lhs,
1268 const decNumber *rhs, const decNumber *fhs,
1269 decContext *set) {
1270 uInt status=0; /* accumulator */
1271 decContext dcmul; /* context for the multiplication */
1272 uInt needbytes; /* for space calculations */
1273 decNumber bufa[D2N(DECBUFFER*2+1)];
1274 decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */
1275 decNumber *acc; /* accumulator pointer */
1276 decNumber dzero; /* work */
1278 #if DECCHECK
1279 if (decCheckOperands(res, lhs, rhs, set)) return res;
1280 if (decCheckOperands(res, fhs, DECUNUSED, set)) return res;
1281 #endif
1283 do { /* protect allocated storage */
1284 #if DECSUBSET
1285 if (!set->extended) { /* [undefined if subset] */
1286 status|=DEC_Invalid_operation;
1287 break;}
1288 #endif
1289 /* Check math restrictions [these ensure no overflow or underflow] */
1290 if ((!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 */
1294 dcmul=*set;
1295 dcmul.digits=lhs->digits+rhs->digits; /* just enough */
1296 /* [The above may be an over-estimate for subset arithmetic, but that's OK] */
1297 dcmul.emax=DEC_MAX_EMAX; /* effectively unbounded .. */
1298 dcmul.emin=DEC_MIN_EMIN; /* [thanks to Math restrictions] */
1299 /* set up decNumber space to receive the result of the multiply */
1300 acc=bufa; /* may fit */
1301 needbytes=sizeof(decNumber)+(D2U(dcmul.digits)-1)*sizeof(Unit);
1302 if (needbytes>sizeof(bufa)) { /* need malloc space */
1303 allocbufa=(decNumber *)malloc(needbytes);
1304 if (allocbufa==NULL) { /* hopeless -- abandon */
1305 status|=DEC_Insufficient_storage;
1306 break;}
1307 acc=allocbufa; /* use the allocated space */
1309 /* multiply with extended range and necessary precision */
1310 /*printf("emin=%ld\n", dcmul.emin); */
1311 decMultiplyOp(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 */
1318 if ((status&DEC_Invalid_operation)!=0) {
1319 if (!(status&DEC_sNaN)) { /* but be true invalid */
1320 decNumberZero(res); /* acc not yet set */
1321 res->bits=DECNAN;
1322 break;
1324 decNumberZero(&dzero); /* make 0 (any non-NaN would do) */
1325 fhs=&dzero; /* use that */
1327 #if DECCHECK
1328 else { /* multiply was OK */
1329 if (status!=0) printf("Status=%08lx after FMA multiply\n", status);
1331 #endif
1332 /* add the third operand and result -> res, and all is done */
1333 decAddOp(res, acc, fhs, set, 0, &status);
1334 } while(0); /* end protected */
1336 if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */
1337 if (status!=0) decStatus(res, status, set);
1338 #if DECCHECK
1339 decCheckInexact(res, set);
1340 #endif
1341 return res;
1342 } /* decNumberFMA */
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 /* ------------------------------------------------------------------ */
1358 decNumber * decNumberInvert(decNumber *res, const decNumber *rhs,
1359 decContext *set) {
1360 const Unit *ua, *msua; /* -> operand and its msu */
1361 Unit *uc, *msuc; /* -> result and its msu */
1362 Int msudigs; /* digits in res msu */
1363 #if DECCHECK
1364 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1365 #endif
1367 if (rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
1368 decStatus(res, DEC_Invalid_operation, set);
1369 return res;
1371 /* operand is valid */
1372 ua=rhs->lsu; /* bottom-up */
1373 uc=res->lsu; /* .. */
1374 msua=ua+D2U(rhs->digits)-1; /* -> msu of rhs */
1375 msuc=uc+D2U(set->digits)-1; /* -> msu of result */
1376 msudigs=MSUDIGITS(set->digits); /* [faster than remainder] */
1377 for (; uc<=msuc; ua++, uc++) { /* Unit loop */
1378 Unit a; /* extract unit */
1379 Int i, j; /* work */
1380 if (ua>msua) a=0;
1381 else 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 */
1385 for (i=0; i<DECDPUN; i++) {
1386 if ((~a)&1) *uc=*uc+(Unit)powers[i]; /* effect INVERT */
1387 j=a%10;
1388 a=a/10;
1389 if (j>1) {
1390 decStatus(res, DEC_Invalid_operation, set);
1391 return res;
1393 if (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] */
1397 res->digits=decGetDigits(res->lsu, uc-res->lsu);
1398 res->exponent=0; /* integer */
1399 res->bits=0; /* sign=0 */
1400 return res; /* [no status to set] */
1401 } /* decNumberInvert */
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 /* ------------------------------------------------------------------ */
1431 decNumber * decNumberLn(decNumber *res, const decNumber *rhs,
1432 decContext *set) {
1433 uInt status=0; /* accumulator */
1434 #if DECSUBSET
1435 decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */
1436 #endif
1438 #if DECCHECK
1439 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1440 #endif
1442 /* Check restrictions; this is a math function; if not violated */
1443 /* then carry out the operation. */
1444 if (!decCheckMath(rhs, set, &status)) do { /* protect allocation */
1445 #if DECSUBSET
1446 if (!set->extended) {
1447 /* reduce operand and set lostDigits status, as needed */
1448 if (rhs->digits>set->digits) {
1449 allocrhs=decRoundOperand(rhs, set, &status);
1450 if (allocrhs==NULL) break;
1451 rhs=allocrhs;
1453 /* special check in subset for rhs=0 */
1454 if (ISZERO(rhs)) { /* +/- zeros -> error */
1455 status|=DEC_Invalid_operation;
1456 break;}
1457 } /* extended=0 */
1458 #endif
1459 decLnOp(res, rhs, set, &status);
1460 } while(0); /* end protected */
1462 #if DECSUBSET
1463 if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */
1464 #endif
1465 /* apply significant status */
1466 if (status!=0) decStatus(res, status, set);
1467 #if DECCHECK
1468 decCheckInexact(res, set);
1469 #endif
1470 return res;
1471 } /* decNumberLn */
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 /* ------------------------------------------------------------------ */
1497 decNumber * decNumberLogB(decNumber *res, const decNumber *rhs,
1498 decContext *set) {
1499 uInt status=0; /* accumulator */
1501 #if DECCHECK
1502 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1503 #endif
1505 /* NaNs as usual; Infinities return +Infinity; 0->oops */
1506 if (decNumberIsNaN(rhs)) decNaNs(res, rhs, NULL, set, &status);
1507 else if (decNumberIsInfinite(rhs)) decNumberCopyAbs(res, rhs);
1508 else if (decNumberIsZero(rhs)) {
1509 decNumberZero(res); /* prepare for Infinity */
1510 res->bits=DECNEG|DECINF; /* -Infinity */
1511 status|=DEC_Division_by_zero; /* as per 754r */
1513 else { /* finite non-zero */
1514 Int ae=rhs->exponent+rhs->digits-1; /* adjusted exponent */
1515 decNumberFromInt32(res, ae); /* lay it out */
1518 if (status!=0) decStatus(res, status, set);
1519 return res;
1520 } /* decNumberLogB */
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 /* ------------------------------------------------------------------ */
1553 decNumber * decNumberLog10(decNumber *res, const decNumber *rhs,
1554 decContext *set) {
1555 uInt status=0, ignore=0; /* status accumulators */
1556 uInt needbytes; /* for space calculations */
1557 Int p; /* working precision */
1558 Int t; /* digits in exponent of A */
1560 /* buffers for a and b working decimals */
1561 /* (adjustment calculator, same size) */
1562 decNumber bufa[D2N(DECBUFFER+2)];
1563 decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */
1564 decNumber *a=bufa; /* temporary a */
1565 decNumber bufb[D2N(DECBUFFER+2)];
1566 decNumber *allocbufb=NULL; /* -> allocated bufb, iff allocated */
1567 decNumber *b=bufb; /* temporary b */
1568 decNumber bufw[D2N(10)]; /* working 2-10 digit number */
1569 decNumber *w=bufw; /* .. */
1570 #if DECSUBSET
1571 decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */
1572 #endif
1574 decContext aset; /* working context */
1576 #if DECCHECK
1577 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1578 #endif
1580 /* Check restrictions; this is a math function; if not violated */
1581 /* then carry out the operation. */
1582 if (!decCheckMath(rhs, set, &status)) do { /* protect malloc */
1583 #if DECSUBSET
1584 if (!set->extended) {
1585 /* reduce operand and set lostDigits status, as needed */
1586 if (rhs->digits>set->digits) {
1587 allocrhs=decRoundOperand(rhs, set, &status);
1588 if (allocrhs==NULL) break;
1589 rhs=allocrhs;
1591 /* special check in subset for rhs=0 */
1592 if (ISZERO(rhs)) { /* +/- zeros -> error */
1593 status|=DEC_Invalid_operation;
1594 break;}
1595 } /* extended=0 */
1596 #endif
1598 decContextDefault(&aset, DEC_INIT_DECIMAL64); /* clean context */
1600 /* handle exact powers of 10; only check if +ve finite */
1601 if (!(rhs->bits&(DECNEG|DECSPECIAL)) && !ISZERO(rhs)) {
1602 Int residue=0; /* (no residue) */
1603 uInt copystat=0; /* clean status */
1605 /* round to a single digit... */
1606 aset.digits=1;
1607 decCopyFit(w, rhs, &aset, &residue, &copystat); /* copy & shorten */
1608 /* if exact and the digit is 1, rhs is a power of 10 */
1609 if (!(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 */
1614 decNumberFromInt32(w, w->exponent);
1615 residue=0;
1616 decCopyFit(res, w, set, &residue, &status); /* copy & round */
1617 decFinish(res, set, &residue, &status); /* cleanup/set flags */
1618 break;
1619 } /* not a power of 10 */
1620 } /* not a candidate for exact */
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 */
1626 t=6; /* it can never be >6 */
1628 /* allocate space when needed... */
1629 p=(rhs->digits+t>set->digits?rhs->digits+t:set->digits)+3;
1630 needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
1631 if (needbytes>sizeof(bufa)) { /* need malloc space */
1632 allocbufa=(decNumber *)malloc(needbytes);
1633 if (allocbufa==NULL) { /* hopeless -- abandon */
1634 status|=DEC_Insufficient_storage;
1635 break;}
1636 a=allocbufa; /* use the allocated space */
1638 aset.digits=p; /* as calculated */
1639 aset.emax=DEC_MAX_MATH; /* usual bounds */
1640 aset.emin=-DEC_MAX_MATH; /* .. */
1641 aset.clamp=0; /* and no concrete format */
1642 decLnOp(a, rhs, &aset, &status); /* a=ln(rhs) */
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 */
1646 if (status&DEC_NaNs && !(status&DEC_sNaN)) break;
1647 if (a->bits&DECSPECIAL || ISZERO(a)) {
1648 decNumberCopy(res, a); /* [will fit] */
1649 break;}
1651 /* for ln(10) an extra 3 digits of precision are needed */
1652 p=set->digits+3;
1653 needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
1654 if (needbytes>sizeof(bufb)) { /* need malloc space */
1655 allocbufb=(decNumber *)malloc(needbytes);
1656 if (allocbufb==NULL) { /* hopeless -- abandon */
1657 status|=DEC_Insufficient_storage;
1658 break;}
1659 b=allocbufb; /* use the allocated space */
1661 decNumberZero(w); /* set up 10... */
1662 #if DECDPUN==1
1663 w->lsu[1]=1; w->lsu[0]=0; /* .. */
1664 #else
1665 w->lsu[0]=10; /* .. */
1666 #endif
1667 w->digits=2; /* .. */
1669 aset.digits=p;
1670 decLnOp(b, w, &aset, &ignore); /* b=ln(10) */
1672 aset.digits=set->digits; /* for final divide */
1673 decDivideOp(res, a, b, &aset, DIVIDE, &status); /* into result */
1674 } while(0); /* [for break] */
1676 if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */
1677 if (allocbufb!=NULL) free(allocbufb); /* .. */
1678 #if DECSUBSET
1679 if (allocrhs !=NULL) free(allocrhs); /* .. */
1680 #endif
1681 /* apply significant status */
1682 if (status!=0) decStatus(res, status, set);
1683 #if DECCHECK
1684 decCheckInexact(res, set);
1685 #endif
1686 return res;
1687 } /* decNumberLog10 */
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 /* ------------------------------------------------------------------ */
1701 decNumber * decNumberMax(decNumber *res, const decNumber *lhs,
1702 const decNumber *rhs, decContext *set) {
1703 uInt status=0; /* accumulator */
1704 decCompareOp(res, lhs, rhs, set, COMPMAX, &status);
1705 if (status!=0) decStatus(res, status, set);
1706 #if DECCHECK
1707 decCheckInexact(res, set);
1708 #endif
1709 return res;
1710 } /* decNumberMax */
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 /* ------------------------------------------------------------------ */
1724 decNumber * decNumberMaxMag(decNumber *res, const decNumber *lhs,
1725 const decNumber *rhs, decContext *set) {
1726 uInt status=0; /* accumulator */
1727 decCompareOp(res, lhs, rhs, set, COMPMAXMAG, &status);
1728 if (status!=0) decStatus(res, status, set);
1729 #if DECCHECK
1730 decCheckInexact(res, set);
1731 #endif
1732 return res;
1733 } /* decNumberMaxMag */
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 /* ------------------------------------------------------------------ */
1747 decNumber * decNumberMin(decNumber *res, const decNumber *lhs,
1748 const decNumber *rhs, decContext *set) {
1749 uInt status=0; /* accumulator */
1750 decCompareOp(res, lhs, rhs, set, COMPMIN, &status);
1751 if (status!=0) decStatus(res, status, set);
1752 #if DECCHECK
1753 decCheckInexact(res, set);
1754 #endif
1755 return res;
1756 } /* decNumberMin */
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 /* ------------------------------------------------------------------ */
1770 decNumber * decNumberMinMag(decNumber *res, const decNumber *lhs,
1771 const decNumber *rhs, decContext *set) {
1772 uInt status=0; /* accumulator */
1773 decCompareOp(res, lhs, rhs, set, COMPMINMAG, &status);
1774 if (status!=0) decStatus(res, status, set);
1775 #if DECCHECK
1776 decCheckInexact(res, set);
1777 #endif
1778 return res;
1779 } /* decNumberMinMag */
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 /* ------------------------------------------------------------------ */
1795 decNumber * decNumberMinus(decNumber *res, const decNumber *rhs,
1796 decContext *set) {
1797 decNumber dzero;
1798 uInt status=0; /* accumulator */
1800 #if DECCHECK
1801 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1802 #endif
1804 decNumberZero(&dzero); /* make 0 */
1805 dzero.exponent=rhs->exponent; /* [no coefficient expansion] */
1806 decAddOp(res, &dzero, rhs, set, DECNEG, &status);
1807 if (status!=0) decStatus(res, status, set);
1808 #if DECCHECK
1809 decCheckInexact(res, set);
1810 #endif
1811 return res;
1812 } /* decNumberMinus */
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 /* ------------------------------------------------------------------ */
1825 decNumber * decNumberNextMinus(decNumber *res, const decNumber *rhs,
1826 decContext *set) {
1827 decNumber dtiny; /* constant */
1828 decContext workset=*set; /* work */
1829 uInt status=0; /* accumulator */
1830 #if DECCHECK
1831 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1832 #endif
1834 /* +Infinity is the special case */
1835 if ((rhs->bits&(DECINF|DECNEG))==DECINF) {
1836 decSetMaxValue(res, set); /* is +ve */
1837 /* there is no status to set */
1838 return res;
1840 decNumberZero(&dtiny); /* start with 0 */
1841 dtiny.lsu[0]=1; /* make number that is .. */
1842 dtiny.exponent=DEC_MIN_EMIN-1; /* .. smaller than tiniest */
1843 workset.round=DEC_ROUND_FLOOR;
1844 decAddOp(res, rhs, &dtiny, &workset, DECNEG, &status);
1845 status&=DEC_Invalid_operation|DEC_sNaN; /* only sNaN Invalid please */
1846 if (status!=0) decStatus(res, status, set);
1847 return res;
1848 } /* decNumberNextMinus */
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 /* ------------------------------------------------------------------ */
1861 decNumber * decNumberNextPlus(decNumber *res, const decNumber *rhs,
1862 decContext *set) {
1863 decNumber dtiny; /* constant */
1864 decContext workset=*set; /* work */
1865 uInt status=0; /* accumulator */
1866 #if DECCHECK
1867 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
1868 #endif
1870 /* -Infinity is the special case */
1871 if ((rhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
1872 decSetMaxValue(res, set);
1873 res->bits=DECNEG; /* negative */
1874 /* there is no status to set */
1875 return res;
1877 decNumberZero(&dtiny); /* start with 0 */
1878 dtiny.lsu[0]=1; /* make number that is .. */
1879 dtiny.exponent=DEC_MIN_EMIN-1; /* .. smaller than tiniest */
1880 workset.round=DEC_ROUND_CEILING;
1881 decAddOp(res, rhs, &dtiny, &workset, 0, &status);
1882 status&=DEC_Invalid_operation|DEC_sNaN; /* only sNaN Invalid please */
1883 if (status!=0) decStatus(res, status, set);
1884 return res;
1885 } /* decNumberNextPlus */
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 /* ------------------------------------------------------------------ */
1900 decNumber * decNumberNextToward(decNumber *res, const decNumber *lhs,
1901 const decNumber *rhs, decContext *set) {
1902 decNumber dtiny; /* constant */
1903 decContext workset=*set; /* work */
1904 Int result; /* .. */
1905 uInt status=0; /* accumulator */
1906 #if DECCHECK
1907 if (decCheckOperands(res, lhs, rhs, set)) return res;
1908 #endif
1910 if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) {
1911 decNaNs(res, lhs, rhs, set, &status);
1913 else { /* Is numeric, so no chance of sNaN Invalid, etc. */
1914 result=decCompare(lhs, rhs, 0); /* sign matters */
1915 if (result==BADINT) status|=DEC_Insufficient_storage; /* rare */
1916 else { /* valid compare */
1917 if (result==0) decNumberCopySign(res, lhs, rhs); /* easy */
1918 else { /* differ: need NextPlus or NextMinus */
1919 uByte sub; /* add or subtract */
1920 if (result<0) { /* lhs<rhs, do nextplus */
1921 /* -Infinity is the special case */
1922 if ((lhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
1923 decSetMaxValue(res, set);
1924 res->bits=DECNEG; /* negative */
1925 return res; /* there is no status to set */
1927 workset.round=DEC_ROUND_CEILING;
1928 sub=0; /* add, please */
1929 } /* plus */
1930 else { /* lhs>rhs, do nextminus */
1931 /* +Infinity is the special case */
1932 if ((lhs->bits&(DECINF|DECNEG))==DECINF) {
1933 decSetMaxValue(res, set);
1934 return res; /* there is no status to set */
1936 workset.round=DEC_ROUND_FLOOR;
1937 sub=DECNEG; /* subtract, please */
1938 } /* minus */
1939 decNumberZero(&dtiny); /* start with 0 */
1940 dtiny.lsu[0]=1; /* make number that is .. */
1941 dtiny.exponent=DEC_MIN_EMIN-1; /* .. smaller than tiniest */
1942 decAddOp(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 */
1945 if (decNumberIsNormal(res, set)) status=0;
1946 } /* unequal */
1947 } /* compare OK */
1948 } /* numeric */
1949 if (status!=0) decStatus(res, status, set);
1950 return res;
1951 } /* decNumberNextToward */
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 /* ------------------------------------------------------------------ */
1968 decNumber * decNumberOr(decNumber *res, const decNumber *lhs,
1969 const decNumber *rhs, decContext *set) {
1970 const Unit *ua, *ub; /* -> operands */
1971 const Unit *msua, *msub; /* -> operand msus */
1972 Unit *uc, *msuc; /* -> result and its msu */
1973 Int msudigs; /* digits in res msu */
1974 #if DECCHECK
1975 if (decCheckOperands(res, lhs, rhs, set)) return res;
1976 #endif
1978 if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
1979 || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
1980 decStatus(res, DEC_Invalid_operation, set);
1981 return res;
1983 /* operands are valid */
1984 ua=lhs->lsu; /* bottom-up */
1985 ub=rhs->lsu; /* .. */
1986 uc=res->lsu; /* .. */
1987 msua=ua+D2U(lhs->digits)-1; /* -> msu of lhs */
1988 msub=ub+D2U(rhs->digits)-1; /* -> msu of rhs */
1989 msuc=uc+D2U(set->digits)-1; /* -> msu of result */
1990 msudigs=MSUDIGITS(set->digits); /* [faster than remainder] */
1991 for (; uc<=msuc; ua++, ub++, uc++) { /* Unit loop */
1992 Unit a, b; /* extract units */
1993 if (ua>msua) a=0;
1994 else a=*ua;
1995 if (ub>msub) b=0;
1996 else b=*ub;
1997 *uc=0; /* can now write back */
1998 if (a|b) { /* maybe 1 bits to examine */
1999 Int i, j;
2000 /* This loop could be unrolled and/or use BIN2BCD tables */
2001 for (i=0; i<DECDPUN; i++) {
2002 if ((a|b)&1) *uc=*uc+(Unit)powers[i]; /* effect OR */
2003 j=a%10;
2004 a=a/10;
2005 j|=b%10;
2006 b=b/10;
2007 if (j>1) {
2008 decStatus(res, DEC_Invalid_operation, set);
2009 return res;
2011 if (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] */
2016 res->digits=decGetDigits(res->lsu, uc-res->lsu);
2017 res->exponent=0; /* integer */
2018 res->bits=0; /* sign=0 */
2019 return res; /* [no status to set] */
2020 } /* decNumberOr */
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 /* ------------------------------------------------------------------ */
2038 decNumber * decNumberPlus(decNumber *res, const decNumber *rhs,
2039 decContext *set) {
2040 decNumber dzero;
2041 uInt status=0; /* accumulator */
2042 #if DECCHECK
2043 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
2044 #endif
2046 decNumberZero(&dzero); /* make 0 */
2047 dzero.exponent=rhs->exponent; /* [no coefficient expansion] */
2048 decAddOp(res, &dzero, rhs, set, 0, &status);
2049 if (status!=0) decStatus(res, status, set);
2050 #if DECCHECK
2051 decCheckInexact(res, set);
2052 #endif
2053 return res;
2054 } /* decNumberPlus */
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 /* ------------------------------------------------------------------ */
2068 decNumber * decNumberMultiply(decNumber *res, const decNumber *lhs,
2069 const decNumber *rhs, decContext *set) {
2070 uInt status=0; /* accumulator */
2071 decMultiplyOp(res, lhs, rhs, set, &status);
2072 if (status!=0) decStatus(res, status, set);
2073 #if DECCHECK
2074 decCheckInexact(res, set);
2075 #endif
2076 return res;
2077 } /* decNumberMultiply */
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 /* ------------------------------------------------------------------ */
2105 decNumber * decNumberPower(decNumber *res, const decNumber *lhs,
2106 const decNumber *rhs, decContext *set) {
2107 #if DECSUBSET
2108 decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */
2109 decNumber *allocrhs=NULL; /* .., rhs */
2110 #endif
2111 decNumber *allocdac=NULL; /* -> allocated acc buffer, iff used */
2112 decNumber *allocinv=NULL; /* -> allocated 1/x buffer, iff used */
2113 Int reqdigits=set->digits; /* requested DIGITS */
2114 Int n; /* rhs in binary */
2115 Flag rhsint=0; /* 1 if rhs is an integer */
2116 Flag useint=0; /* 1 if can use integer calculation */
2117 Flag isoddint=0; /* 1 if rhs is an integer and odd */
2118 Int i; /* work */
2119 #if DECSUBSET
2120 Int dropped; /* .. */
2121 #endif
2122 uInt needbytes; /* buffer size needed */
2123 Flag seenbit; /* seen a bit while powering */
2124 Int residue=0; /* rounding residue */
2125 uInt status=0; /* accumulators */
2126 uByte bits=0; /* result sign if errors */
2127 decContext aset; /* working context */
2128 decNumber dnOne; /* work value 1... */
2129 /* local accumulator buffer [a decNumber, with digits+elength+1 digits] */
2130 decNumber dacbuff[D2N(DECBUFFER+9)];
2131 decNumber *dac=dacbuff; /* -> result accumulator */
2132 /* same again for possible 1/lhs calculation */
2133 decNumber invbuff[D2N(DECBUFFER+9)];
2135 #if DECCHECK
2136 if (decCheckOperands(res, lhs, rhs, set)) return res;
2137 #endif
2139 do { /* protect allocated storage */
2140 #if DECSUBSET
2141 if (!set->extended) { /* reduce operands and set status, as needed */
2142 if (lhs->digits>reqdigits) {
2143 alloclhs=decRoundOperand(lhs, set, &status);
2144 if (alloclhs==NULL) break;
2145 lhs=alloclhs;
2147 if (rhs->digits>reqdigits) {
2148 allocrhs=decRoundOperand(rhs, set, &status);
2149 if (allocrhs==NULL) break;
2150 rhs=allocrhs;
2153 #endif
2154 /* [following code does not require input rounding] */
2156 /* handle NaNs and rhs Infinity (lhs infinity is harder) */
2157 if (SPECIALARGS) {
2158 if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) { /* NaNs */
2159 decNaNs(res, lhs, rhs, set, &status);
2160 break;}
2161 if (decNumberIsInfinite(rhs)) { /* rhs Infinity */
2162 Flag rhsneg=rhs->bits&DECNEG; /* save rhs sign */
2163 if (decNumberIsNegative(lhs) /* lhs<0 */
2164 && !decNumberIsZero(lhs)) /* .. */
2165 status|=DEC_Invalid_operation;
2166 else { /* lhs >=0 */
2167 decNumberZero(&dnOne); /* set up 1 */
2168 dnOne.lsu[0]=1;
2169 decNumberCompare(dac, lhs, &dnOne, set); /* lhs ? 1 */
2170 decNumberZero(res); /* prepare for 0/1/Infinity */
2171 if (decNumberIsNegative(dac)) { /* lhs<1 */
2172 if (rhsneg) res->bits|=DECINF; /* +Infinity [else is +0] */
2174 else if (dac->lsu[0]==0) { /* lhs=1 */
2175 /* 1**Infinity is inexact, so return fully-padded 1.0000 */
2176 Int shift=set->digits-1;
2177 *res->lsu=1; /* was 0, make int 1 */
2178 res->digits=decShiftToMost(res->lsu, 1, shift);
2179 res->exponent=-shift; /* make 1.0000... */
2180 status|=DEC_Inexact|DEC_Rounded; /* deemed inexact */
2182 else { /* lhs>1 */
2183 if (!rhsneg) res->bits|=DECINF; /* +Infinity [else is +0] */
2185 } /* lhs>=0 */
2186 break;}
2187 /* [lhs infinity drops through] */
2188 } /* specials */
2190 /* Original rhs may be an integer that fits and is in range */
2191 n=decGetInt(rhs);
2192 if (n!=BADINT) { /* it is an integer */
2193 rhsint=1; /* record the fact for 1**n */
2194 isoddint=(Flag)n&1; /* [works even if big] */
2195 if (n!=BIGEVEN && n!=BIGODD) /* can use integer path? */
2196 useint=1; /* looks good */
2199 if (decNumberIsNegative(lhs) /* -x .. */
2200 && isoddint) bits=DECNEG; /* .. to an odd power */
2202 /* handle LHS infinity */
2203 if (decNumberIsInfinite(lhs)) { /* [NaNs already handled] */
2204 uByte rbits=rhs->bits; /* save */
2205 decNumberZero(res); /* prepare */
2206 if (n==0) *res->lsu=1; /* [-]Inf**0 => 1 */
2207 else {
2208 /* -Inf**nonint -> error */
2209 if (!rhsint && decNumberIsNegative(lhs)) {
2210 status|=DEC_Invalid_operation; /* -Inf**nonint is error */
2211 break;}
2212 if (!(rbits & DECNEG)) bits|=DECINF; /* was not a **-n */
2213 /* [otherwise will be 0 or -0] */
2214 res->bits=bits;
2216 break;}
2218 /* similarly handle LHS zero */
2219 if (decNumberIsZero(lhs)) {
2220 if (n==0) { /* 0**0 => Error */
2221 #if DECSUBSET
2222 if (!set->extended) { /* [unless subset] */
2223 decNumberZero(res);
2224 *res->lsu=1; /* return 1 */
2225 break;}
2226 #endif
2227 status|=DEC_Invalid_operation;
2229 else { /* 0**x */
2230 uByte rbits=rhs->bits; /* save */
2231 if (rbits & DECNEG) { /* was a 0**(-n) */
2232 #if DECSUBSET
2233 if (!set->extended) { /* [bad if subset] */
2234 status|=DEC_Invalid_operation;
2235 break;}
2236 #endif
2237 bits|=DECINF;
2239 decNumberZero(res); /* prepare */
2240 /* [otherwise will be 0 or -0] */
2241 res->bits=bits;
2243 break;}
2245 /* here both lhs and rhs are finite; rhs==0 is handled in the */
2246 /* integer path. Next handle the non-integer cases */
2247 if (!useint) { /* non-integral rhs */
2248 /* any -ve lhs is bad, as is either operand or context out of */
2249 /* bounds */
2250 if (decNumberIsNegative(lhs)) {
2251 status|=DEC_Invalid_operation;
2252 break;}
2253 if (decCheckMath(lhs, set, &status)
2254 || decCheckMath(rhs, set, &status)) break; /* variable status */
2256 decContextDefault(&aset, DEC_INIT_DECIMAL64); /* clean context */
2257 aset.emax=DEC_MAX_MATH; /* usual bounds */
2258 aset.emin=-DEC_MAX_MATH; /* .. */
2259 aset.clamp=0; /* and no concrete format */
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) */
2271 aset.digits=MAXI(lhs->digits, set->digits)+6+4;
2272 } /* non-integer rhs */
2274 else { /* rhs is in-range integer */
2275 if (n==0) { /* x**0 = 1 */
2276 /* (0**0 was handled above) */
2277 decNumberZero(res); /* result=1 */
2278 *res->lsu=1; /* .. */
2279 break;}
2280 /* rhs is a non-zero integer */
2281 if (n<0) n=-n; /* use abs(n) */
2283 aset=*set; /* clone the context */
2284 aset.round=DEC_ROUND_HALF_EVEN; /* internally use balanced */
2285 /* calculate the working DIGITS */
2286 aset.digits=reqdigits+(rhs->digits+rhs->exponent)+2;
2287 #if DECSUBSET
2288 if (!set->extended) aset.digits--; /* use classic precision */
2289 #endif
2290 /* it's an error if this is more than can be handled */
2291 if (aset.digits>DECNUMMAXP) {status|=DEC_Invalid_operation; break;}
2292 } /* integer path */
2294 /* aset.digits is the count of digits for the accumulator needed */
2295 /* if accumulator is too long for local storage, then allocate */
2296 needbytes=sizeof(decNumber)+(D2U(aset.digits)-1)*sizeof(Unit);
2297 /* [needbytes also used below if 1/lhs needed] */
2298 if (needbytes>sizeof(dacbuff)) {
2299 allocdac=(decNumber *)malloc(needbytes);
2300 if (allocdac==NULL) { /* hopeless -- abandon */
2301 status|=DEC_Insufficient_storage;
2302 break;}
2303 dac=allocdac; /* use the allocated space */
2305 /* here, aset is set up and accumulator is ready for use */
2307 if (!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 */
2311 decLnOp(dac, lhs, &aset, &status); /* dac=ln(lhs) */
2312 /* [no error possible, as lhs 0 already handled] */
2313 if (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 */
2316 if (!rhsint) { /* add padding */
2317 Int shift=set->digits-1;
2318 dac->digits=decShiftToMost(dac->lsu, 1, shift);
2319 dac->exponent=-shift; /* make 1.0000... */
2320 status|=DEC_Inexact|DEC_Rounded; /* deemed inexact */
2323 else {
2324 decMultiplyOp(dac, dac, rhs, &aset, &status); /* dac=dac*rhs */
2325 decExpOp(dac, dac, &aset, &status); /* dac=exp(dac) */
2327 /* and drop through for final rounding */
2328 } /* non-integer rhs */
2330 else { /* carry on with integer */
2331 decNumberZero(dac); /* acc=1 */
2332 *dac->lsu=1; /* .. */
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 */
2336 if (decNumberIsNegative(rhs)) { /* was a **-n [hence digits>0] */
2337 decNumber *inv=invbuff; /* assume use fixed buffer */
2338 decNumberCopy(&dnOne, dac); /* dnOne=1; [needed now or later] */
2339 #if DECSUBSET
2340 if (set->extended) { /* need to calculate 1/lhs */
2341 #endif
2342 /* divide lhs into 1, putting result in dac [dac=1/dac] */
2343 decDivideOp(dac, &dnOne, lhs, &aset, DIVIDE, &status);
2344 /* now locate or allocate space for the inverted lhs */
2345 if (needbytes>sizeof(invbuff)) {
2346 allocinv=(decNumber *)malloc(needbytes);
2347 if (allocinv==NULL) { /* hopeless -- abandon */
2348 status|=DEC_Insufficient_storage;
2349 break;}
2350 inv=allocinv; /* use the allocated space */
2352 /* [inv now points to big-enough buffer or allocated storage] */
2353 decNumberCopy(inv, dac); /* copy the 1/lhs */
2354 decNumberCopy(dac, &dnOne); /* restore acc=1 */
2355 lhs=inv; /* .. and go forward with new lhs */
2356 #if DECSUBSET
2358 #endif
2361 /* Raise-to-the-power loop... */
2362 seenbit=0; /* set once a 1-bit is encountered */
2363 for (i=1;;i++){ /* for each bit [top bit ignored] */
2364 /* abandon if had overflow or terminal underflow */
2365 if (status & (DEC_Overflow|DEC_Underflow)) { /* interesting? */
2366 if (status&DEC_Overflow || ISZERO(dac)) break;
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] */
2370 n=n<<1; /* move next bit to testable position */
2371 if (n<0) { /* top bit is set */
2372 seenbit=1; /* OK, significant bit seen */
2373 decMultiplyOp(dac, dac, lhs, &aset, &status); /* dac=dac*x */
2375 if (i==31) break; /* that was the last bit */
2376 if (!seenbit) continue; /* no need to square 1 */
2377 decMultiplyOp(dac, dac, dac, &aset, &status); /* dac=dac*dac [square] */
2378 } /*i*/ /* 32 bits */
2380 /* complete internal overflow or underflow processing */
2381 if (status & (DEC_Overflow|DEC_Underflow)) {
2382 #if DECSUBSET
2383 /* If subset, and power was negative, reverse the kind of -erflow */
2384 /* [1/x not yet done] */
2385 if (!set->extended && decNumberIsNegative(rhs)) {
2386 if (status & DEC_Overflow)
2387 status^=DEC_Overflow | DEC_Underflow | DEC_Subnormal;
2388 else { /* trickier -- Underflow may or may not be set */
2389 status&=~(DEC_Underflow | DEC_Subnormal); /* [one or both] */
2390 status|=DEC_Overflow;
2393 #endif
2394 dac->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 */
2397 decFinalize(dac, set, &residue, &status);
2398 decNumberCopy(res, dac); /* copy to result (is now OK length) */
2399 break;
2402 #if DECSUBSET
2403 if (!set->extended && /* subset math */
2404 decNumberIsNegative(rhs)) { /* was a **-n [hence digits>0] */
2405 /* so divide result into 1 [dac=1/dac] */
2406 decDivideOp(dac, &dnOne, dac, &aset, DIVIDE, &status);
2408 #endif
2409 } /* rhs integer path */
2411 /* reduce result to the requested length and copy to result */
2412 decCopyFit(res, dac, set, &residue, &status);
2413 decFinish(res, set, &residue, &status); /* final cleanup */
2414 #if DECSUBSET
2415 if (!set->extended) decTrim(res, set, 0, &dropped); /* trailing zeros */
2416 #endif
2417 } while(0); /* end protected */
2419 if (allocdac!=NULL) free(allocdac); /* drop any storage used */
2420 if (allocinv!=NULL) free(allocinv); /* .. */
2421 #if DECSUBSET
2422 if (alloclhs!=NULL) free(alloclhs); /* .. */
2423 if (allocrhs!=NULL) free(allocrhs); /* .. */
2424 #endif
2425 if (status!=0) decStatus(res, status, set);
2426 #if DECCHECK
2427 decCheckInexact(res, set);
2428 #endif
2429 return res;
2430 } /* decNumberPower */
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 /* ------------------------------------------------------------------ */
2450 decNumber * decNumberQuantize(decNumber *res, const decNumber *lhs,
2451 const decNumber *rhs, decContext *set) {
2452 uInt status=0; /* accumulator */
2453 decQuantizeOp(res, lhs, rhs, set, 1, &status);
2454 if (status!=0) decStatus(res, status, set);
2455 return res;
2456 } /* decNumberQuantize */
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 */
2470 decNumber * decNumberNormalize(decNumber *res, const decNumber *rhs,
2471 decContext *set) {
2472 return decNumberReduce(res, rhs, set);
2473 } /* decNumberNormalize */
2475 decNumber * decNumberReduce(decNumber *res, const decNumber *rhs,
2476 decContext *set) {
2477 #if DECSUBSET
2478 decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */
2479 #endif
2480 uInt status=0; /* as usual */
2481 Int residue=0; /* as usual */
2482 Int dropped; /* work */
2484 #if DECCHECK
2485 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
2486 #endif
2488 do { /* protect allocated storage */
2489 #if DECSUBSET
2490 if (!set->extended) {
2491 /* reduce operand and set lostDigits status, as needed */
2492 if (rhs->digits>set->digits) {
2493 allocrhs=decRoundOperand(rhs, set, &status);
2494 if (allocrhs==NULL) break;
2495 rhs=allocrhs;
2498 #endif
2499 /* [following code does not require input rounding] */
2501 /* Infinities copy through; NaNs need usual treatment */
2502 if (decNumberIsNaN(rhs)) {
2503 decNaNs(res, rhs, NULL, set, &status);
2504 break;
2507 /* reduce result to the requested length and copy to result */
2508 decCopyFit(res, rhs, set, &residue, &status); /* copy & round */
2509 decFinish(res, set, &residue, &status); /* cleanup/set flags */
2510 decTrim(res, set, 1, &dropped); /* normalize in place */
2511 } while(0); /* end protected */
2513 #if DECSUBSET
2514 if (allocrhs !=NULL) free(allocrhs); /* .. */
2515 #endif
2516 if (status!=0) decStatus(res, status, set);/* then report status */
2517 return res;
2518 } /* decNumberReduce */
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 /* ------------------------------------------------------------------ */
2538 decNumber * decNumberRescale(decNumber *res, const decNumber *lhs,
2539 const decNumber *rhs, decContext *set) {
2540 uInt status=0; /* accumulator */
2541 decQuantizeOp(res, lhs, rhs, set, 0, &status);
2542 if (status!=0) decStatus(res, status, set);
2543 return res;
2544 } /* decNumberRescale */
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 /* ------------------------------------------------------------------ */
2558 decNumber * decNumberRemainder(decNumber *res, const decNumber *lhs,
2559 const decNumber *rhs, decContext *set) {
2560 uInt status=0; /* accumulator */
2561 decDivideOp(res, lhs, rhs, set, REMAINDER, &status);
2562 if (status!=0) decStatus(res, status, set);
2563 #if DECCHECK
2564 decCheckInexact(res, set);
2565 #endif
2566 return res;
2567 } /* decNumberRemainder */
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 /* ------------------------------------------------------------------ */
2581 decNumber * decNumberRemainderNear(decNumber *res, const decNumber *lhs,
2582 const decNumber *rhs, decContext *set) {
2583 uInt status=0; /* accumulator */
2584 decDivideOp(res, lhs, rhs, set, REMNEAR, &status);
2585 if (status!=0) decStatus(res, status, set);
2586 #if DECCHECK
2587 decCheckInexact(res, set);
2588 #endif
2589 return res;
2590 } /* decNumberRemainderNear */
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 /* ------------------------------------------------------------------ */
2617 decNumber * decNumberRotate(decNumber *res, const decNumber *lhs,
2618 const decNumber *rhs, decContext *set) {
2619 uInt status=0; /* accumulator */
2620 Int rotate; /* rhs as an Int */
2622 #if DECCHECK
2623 if (decCheckOperands(res, lhs, rhs, set)) return res;
2624 #endif
2626 /* NaNs propagate as normal */
2627 if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
2628 decNaNs(res, lhs, rhs, set, &status);
2629 /* rhs must be an integer */
2630 else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
2631 status=DEC_Invalid_operation;
2632 else { /* both numeric, rhs is an integer */
2633 rotate=decGetInt(rhs); /* [cannot fail] */
2634 if (rotate==BADINT /* something bad .. */
2635 || rotate==BIGODD || rotate==BIGEVEN /* .. very big .. */
2636 || abs(rotate)>set->digits) /* .. or out of range */
2637 status=DEC_Invalid_operation;
2638 else { /* rhs is OK */
2639 decNumberCopy(res, lhs);
2640 /* convert -ve rotate to equivalent positive rotation */
2641 if (rotate<0) rotate=set->digits+rotate;
2642 if (rotate!=0 && rotate!=set->digits /* zero or full rotation */
2643 && !decNumberIsInfinite(res)) { /* lhs was infinite */
2644 /* left-rotate to do; 0 < rotate < set->digits */
2645 uInt units, shift; /* work */
2646 uInt msudigits; /* digits in result msu */
2647 Unit *msu=res->lsu+D2U(res->digits)-1; /* current msu */
2648 Unit *msumax=res->lsu+D2U(set->digits)-1; /* rotation msu */
2649 for (msu++; msu<=msumax; msu++) *msu=0; /* ensure high units=0 */
2650 res->digits=set->digits; /* now full-length */
2651 msudigits=MSUDIGITS(res->digits); /* actual digits in msu */
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 */
2683 /* Step 1: amount to shift is the partial right-rotate count */
2684 rotate=set->digits-rotate; /* make it right-rotate */
2685 units=rotate/DECDPUN; /* whole units to rotate */
2686 shift=rotate%DECDPUN; /* left-over digits count */
2687 if (shift>0) { /* not an exact number of units */
2688 uInt save=res->lsu[0]%powers[shift]; /* save low digit(s) */
2689 decShiftToLeast(res->lsu, D2U(res->digits), shift);
2690 if (shift>msudigits) { /* msumax-1 needs >0 digits */
2691 uInt 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)]); /* .. */
2696 else { /* all fits in msumax */
2697 *msumax=*msumax+(Unit)(save*powers[msudigits-shift]); /* [maybe *1] */
2699 } /* digits shift needed */
2701 /* If whole units to rotate... */
2702 if (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) */
2706 shift=DECDPUN-msudigits;
2707 if (shift>0) { /* not an exact number of units */
2708 uInt save=res->lsu[0]%powers[shift]; /* save low digit(s) */
2709 decShiftToLeast(res->lsu, units, shift);
2710 *msumax=*msumax+(Unit)(save*powers[msudigits]);
2711 } /* partial shift needed */
2713 /* Step 3: rotate the units array using triple reverse */
2714 /* (reversing is easy and fast) */
2715 decReverse(res->lsu+units, msumax); /* left part */
2716 decReverse(res->lsu, res->lsu+units-1); /* right part */
2717 decReverse(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 */
2721 res->digits=decGetDigits(res->lsu, msumax-res->lsu+1);
2722 } /* rotate needed */
2723 } /* rhs OK */
2724 } /* numerics */
2725 if (status!=0) decStatus(res, status, set);
2726 return res;
2727 } /* decNumberRotate */
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 /* ------------------------------------------------------------------ */
2738 decNumber * decNumberSameQuantum(decNumber *res, const decNumber *lhs,
2739 const decNumber *rhs) {
2740 Unit ret=0; /* return value */
2742 #if DECCHECK
2743 if (decCheckOperands(res, lhs, rhs, DECUNCONT)) return res;
2744 #endif
2746 if (SPECIALARGS) {
2747 if (decNumberIsNaN(lhs) && decNumberIsNaN(rhs)) ret=1;
2748 else if (decNumberIsInfinite(lhs) && decNumberIsInfinite(rhs)) ret=1;
2749 /* [anything else with a special gives 0] */
2751 else if (lhs->exponent==rhs->exponent) ret=1;
2753 decNumberZero(res); /* OK to overwrite an operand now */
2754 *res->lsu=ret;
2755 return res;
2756 } /* decNumberSameQuantum */
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 /* ------------------------------------------------------------------ */
2773 decNumber * decNumberScaleB(decNumber *res, const decNumber *lhs,
2774 const decNumber *rhs, decContext *set) {
2775 Int reqexp; /* requested exponent change [B] */
2776 uInt status=0; /* accumulator */
2777 Int residue; /* work */
2779 #if DECCHECK
2780 if (decCheckOperands(res, lhs, rhs, set)) return res;
2781 #endif
2783 /* Handle special values except lhs infinite */
2784 if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
2785 decNaNs(res, lhs, rhs, set, &status);
2786 /* rhs must be an integer */
2787 else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
2788 status=DEC_Invalid_operation;
2789 else {
2790 /* lhs is a number; rhs is a finite with q==0 */
2791 reqexp=decGetInt(rhs); /* [cannot fail] */
2792 if (reqexp==BADINT /* something bad .. */
2793 || reqexp==BIGODD || reqexp==BIGEVEN /* .. very big .. */
2794 || abs(reqexp)>(2*(set->digits+set->emax))) /* .. or out of range */
2795 status=DEC_Invalid_operation;
2796 else { /* rhs is OK */
2797 decNumberCopy(res, lhs); /* all done if infinite lhs */
2798 if (!decNumberIsInfinite(res)) { /* prepare to scale */
2799 res->exponent+=reqexp; /* adjust the exponent */
2800 residue=0;
2801 decFinalize(res, set, &residue, &status); /* .. and check */
2802 } /* finite LHS */
2803 } /* rhs OK */
2804 } /* rhs finite */
2805 if (status!=0) decStatus(res, status, set);
2806 return res;
2807 } /* decNumberScaleB */
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 /* ------------------------------------------------------------------ */
2830 decNumber * decNumberShift(decNumber *res, const decNumber *lhs,
2831 const decNumber *rhs, decContext *set) {
2832 uInt status=0; /* accumulator */
2833 Int shift; /* rhs as an Int */
2835 #if DECCHECK
2836 if (decCheckOperands(res, lhs, rhs, set)) return res;
2837 #endif
2839 /* NaNs propagate as normal */
2840 if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
2841 decNaNs(res, lhs, rhs, set, &status);
2842 /* rhs must be an integer */
2843 else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
2844 status=DEC_Invalid_operation;
2845 else { /* both numeric, rhs is an integer */
2846 shift=decGetInt(rhs); /* [cannot fail] */
2847 if (shift==BADINT /* something bad .. */
2848 || shift==BIGODD || shift==BIGEVEN /* .. very big .. */
2849 || abs(shift)>set->digits) /* .. or out of range */
2850 status=DEC_Invalid_operation;
2851 else { /* rhs is OK */
2852 decNumberCopy(res, lhs);
2853 if (shift!=0 && !decNumberIsInfinite(res)) { /* something to do */
2854 if (shift>0) { /* to left */
2855 if (shift==set->digits) { /* removing all */
2856 *res->lsu=0; /* so place 0 */
2857 res->digits=1; /* .. */
2859 else { /* */
2860 /* first remove leading digits if necessary */
2861 if (res->digits+shift>set->digits) {
2862 decDecap(res, res->digits+shift-set->digits);
2863 /* that updated res->digits; may have gone to 1 (for a */
2864 /* single digit or for zero */
2866 if (res->digits>1 || *res->lsu) /* if non-zero.. */
2867 res->digits=decShiftToMost(res->lsu, res->digits, shift);
2868 } /* partial left */
2869 } /* left */
2870 else { /* to right */
2871 if (-shift>=res->digits) { /* discarding all */
2872 *res->lsu=0; /* so place 0 */
2873 res->digits=1; /* .. */
2875 else {
2876 decShiftToLeast(res->lsu, D2U(res->digits), -shift);
2877 res->digits-=(-shift);
2879 } /* to right */
2880 } /* non-0 non-Inf shift */
2881 } /* rhs OK */
2882 } /* numerics */
2883 if (status!=0) decStatus(res, status, set);
2884 return res;
2885 } /* decNumberShift */
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 /* ------------------------------------------------------------------ */
2959 decNumber * decNumberSquareRoot(decNumber *res, const decNumber *rhs,
2960 decContext *set) {
2961 decContext workset, approxset; /* work contexts */
2962 decNumber dzero; /* used for constant zero */
2963 Int maxp; /* largest working precision */
2964 Int workp; /* working precision */
2965 Int residue=0; /* rounding residue */
2966 uInt status=0, ignore=0; /* status accumulators */
2967 uInt rstatus; /* .. */
2968 Int exp; /* working exponent */
2969 Int ideal; /* ideal (preferred) exponent */
2970 Int needbytes; /* work */
2971 Int dropped; /* .. */
2973 #if DECSUBSET
2974 decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */
2975 #endif
2976 /* buffer for f [needs +1 in case DECBUFFER 0] */
2977 decNumber buff[D2N(DECBUFFER+1)];
2978 /* buffer for a [needs +2 to match likely maxp] */
2979 decNumber bufa[D2N(DECBUFFER+2)];
2980 /* buffer for temporary, b [must be same size as a] */
2981 decNumber bufb[D2N(DECBUFFER+2)];
2982 decNumber *allocbuff=NULL; /* -> allocated buff, iff allocated */
2983 decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */
2984 decNumber *allocbufb=NULL; /* -> allocated bufb, iff allocated */
2985 decNumber *f=buff; /* reduced fraction */
2986 decNumber *a=bufa; /* approximation to result */
2987 decNumber *b=bufb; /* intermediate result */
2988 /* buffer for temporary variable, up to 3 digits */
2989 decNumber buft[D2N(3)];
2990 decNumber *t=buft; /* up-to-3-digit constant or work */
2992 #if DECCHECK
2993 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
2994 #endif
2996 do { /* protect allocated storage */
2997 #if DECSUBSET
2998 if (!set->extended) {
2999 /* reduce operand and set lostDigits status, as needed */
3000 if (rhs->digits>set->digits) {
3001 allocrhs=decRoundOperand(rhs, set, &status);
3002 if (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.] */
3005 rhs=allocrhs;
3008 #endif
3009 /* [following code does not require input rounding] */
3011 /* handle infinities and NaNs */
3012 if (SPECIALARG) {
3013 if (decNumberIsInfinite(rhs)) { /* an infinity */
3014 if (decNumberIsNegative(rhs)) status|=DEC_Invalid_operation;
3015 else decNumberCopy(res, rhs); /* +Infinity */
3017 else decNaNs(res, rhs, NULL, set, &status); /* a NaN */
3018 break;
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.] */
3024 ideal=(rhs->exponent&~1)/2; /* target */
3026 /* handle zeros */
3027 if (ISZERO(rhs)) {
3028 decNumberCopy(res, rhs); /* could be 0 or -0 */
3029 res->exponent=ideal; /* use the ideal [safe] */
3030 /* use decFinish to clamp any out-of-range exponent, etc. */
3031 decFinish(res, set, &residue, &status);
3032 break;
3035 /* any other -x is an oops */
3036 if (decNumberIsNegative(rhs)) {
3037 status|=DEC_Invalid_operation;
3038 break;
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 */
3048 workp=MAXI(set->digits+1, rhs->digits); /* actual rounding precision */
3049 maxp=workp+2; /* largest working precision */
3051 needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
3052 if (needbytes>(Int)sizeof(buff)) {
3053 allocbuff=(decNumber *)malloc(needbytes);
3054 if (allocbuff==NULL) { /* hopeless -- abandon */
3055 status|=DEC_Insufficient_storage;
3056 break;}
3057 f=allocbuff; /* use the allocated space */
3059 /* a and b both need to be able to hold a maxp-length number */
3060 needbytes=sizeof(decNumber)+(D2U(maxp)-1)*sizeof(Unit);
3061 if (needbytes>(Int)sizeof(bufa)) { /* [same applies to b] */
3062 allocbufa=(decNumber *)malloc(needbytes);
3063 allocbufb=(decNumber *)malloc(needbytes);
3064 if (allocbufa==NULL || allocbufb==NULL) { /* hopeless */
3065 status|=DEC_Insufficient_storage;
3066 break;}
3067 a=allocbufa; /* use the allocated spaces */
3068 b=allocbufb; /* .. */
3071 /* copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1 */
3072 decNumberCopy(f, rhs);
3073 exp=f->exponent+f->digits; /* adjusted to Hull rules */
3074 f->exponent=-(f->digits); /* to range */
3076 /* set up working context */
3077 decContextDefault(&workset, DEC_INIT_DECIMAL64);
3079 /* [Until further notice, no error is possible and status bits */
3080 /* (Rounded, etc.) should be ignored, not accumulated.] */
3082 /* Calculate initial approximation, and allow for odd exponent */
3083 workset.digits=workp; /* p for initial calculation */
3084 t->bits=0; t->digits=3;
3085 a->bits=0; a->digits=3;
3086 if ((exp & 1)==0) { /* even exponent */
3087 /* Set t=0.259, a=0.819 */
3088 t->exponent=-3;
3089 a->exponent=-3;
3090 #if DECDPUN>=3
3091 t->lsu[0]=259;
3092 a->lsu[0]=819;
3093 #elif DECDPUN==2
3094 t->lsu[0]=59; t->lsu[1]=2;
3095 a->lsu[0]=19; a->lsu[1]=8;
3096 #else
3097 t->lsu[0]=9; t->lsu[1]=5; t->lsu[2]=2;
3098 a->lsu[0]=9; a->lsu[1]=1; a->lsu[2]=8;
3099 #endif
3101 else { /* odd exponent */
3102 /* Set t=0.0819, a=2.59 */
3103 f->exponent--; /* f=f/10 */
3104 exp++; /* e=e+1 */
3105 t->exponent=-4;
3106 a->exponent=-2;
3107 #if DECDPUN>=3
3108 t->lsu[0]=819;
3109 a->lsu[0]=259;
3110 #elif DECDPUN==2
3111 t->lsu[0]=19; t->lsu[1]=8;
3112 a->lsu[0]=59; a->lsu[1]=2;
3113 #else
3114 t->lsu[0]=9; t->lsu[1]=1; t->lsu[2]=8;
3115 a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;
3116 #endif
3118 decMultiplyOp(a, a, f, &workset, &ignore); /* a=a*f */
3119 decAddOp(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.] */
3123 /* the main calculation loop */
3124 decNumberZero(&dzero); /* make 0 */
3125 decNumberZero(t); /* set t = 0.5 */
3126 t->lsu[0]=5; /* .. */
3127 t->exponent=-1; /* .. */
3128 workset.digits=3; /* initial p */
3129 for (;;) {
3130 /* set p to min(2*p - 2, maxp) [hence 3; or: 4, 6, 10, ... , maxp] */
3131 workset.digits=workset.digits*2-2;
3132 if (workset.digits>maxp) workset.digits=maxp;
3133 /* a = 0.5 * (a + f/a) */
3134 /* [calculated at p then rounded to currentprecision] */
3135 decDivideOp(b, f, a, &workset, DIVIDE, &ignore); /* b=f/a */
3136 decAddOp(b, b, a, &workset, 0, &ignore); /* b=b+a */
3137 decMultiplyOp(a, b, t, &workset, &ignore); /* a=b*0.5 */
3138 if (a->digits==maxp) break; /* have required digits */
3139 } /* loop */
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 */
3145 approxset=*set; /* get emin, emax, etc. */
3146 approxset.round=DEC_ROUND_HALF_EVEN;
3147 a->exponent+=exp/2; /* set correct exponent */
3149 rstatus=0; /* clear status */
3150 residue=0; /* .. and accumulator */
3151 decCopyFit(a, a, &approxset, &residue, &rstatus); /* reduce (if needed) */
3152 decFinish(a, &approxset, &residue, &rstatus); /* clean and finalize */
3154 /* Overflow was possible if the input exponent was out-of-range, */
3155 /* in which case quit */
3156 if (rstatus&DEC_Overflow) {
3157 status=rstatus; /* use the status as-is */
3158 decNumberCopy(res, a); /* copy to result */
3159 break;
3162 /* Preserve status except Inexact/Rounded */
3163 status|=(rstatus & ~(DEC_Rounded|DEC_Inexact));
3165 /* Carry out the Hull correction */
3166 a->exponent-=exp/2; /* back to 0.1->1 */
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 */
3173 workset.digits--; /* maxp-1 is OK now */
3174 t->exponent=-a->digits-1; /* make 0.5 ulp */
3175 decAddOp(b, a, t, &workset, DECNEG, &ignore); /* b = a - 0.5 ulp */
3176 workset.round=DEC_ROUND_UP;
3177 decMultiplyOp(b, b, b, &workset, &ignore); /* b = mulru(b, b) */
3178 decCompareOp(b, f, b, &workset, COMPARE, &ignore); /* b ? f, reversed */
3179 if (decNumberIsNegative(b)) { /* f < b [i.e., b > f] */
3180 /* this is the more common adjustment, though both are rare */
3181 t->exponent++; /* make 1.0 ulp */
3182 t->lsu[0]=1; /* .. */
3183 decAddOp(a, a, t, &workset, DECNEG, &ignore); /* a = a - 1 ulp */
3184 /* assign to approx [round to length] */
3185 approxset.emin-=exp/2; /* adjust to match a */
3186 approxset.emax-=exp/2;
3187 decAddOp(a, &dzero, a, &approxset, 0, &ignore);
3189 else {
3190 decAddOp(b, a, t, &workset, 0, &ignore); /* b = a + 0.5 ulp */
3191 workset.round=DEC_ROUND_DOWN;
3192 decMultiplyOp(b, b, b, &workset, &ignore); /* b = mulrd(b, b) */
3193 decCompareOp(b, b, f, &workset, COMPARE, &ignore); /* b ? f */
3194 if (decNumberIsNegative(b)) { /* b < f */
3195 t->exponent++; /* make 1.0 ulp */
3196 t->lsu[0]=1; /* .. */
3197 decAddOp(a, a, t, &workset, 0, &ignore); /* a = a + 1 ulp */
3198 /* assign to approx [round to length] */
3199 approxset.emin-=exp/2; /* adjust to match a */
3200 approxset.emax-=exp/2;
3201 decAddOp(a, &dzero, a, &approxset, 0, &ignore);
3204 /* [no errors are possible in the above, and rounding/inexact during */
3205 /* estimation are irrelevant, so status was not accumulated] */
3207 /* Here, 0.1 <= a < 1 (still), so adjust back */
3208 a->exponent+=exp/2; /* set correct exponent */
3210 /* count droppable zeros [after any subnormal rounding] by */
3211 /* trimming a copy */
3212 decNumberCopy(b, a);
3213 decTrim(b, set, 1, &dropped); /* [drops trailing zeros] */
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 */
3219 if (b->digits*2-1 > workp && !set->clamp) { /* cannot fit */
3220 status|=DEC_Inexact|DEC_Rounded;
3222 else { /* could be exact/unrounded */
3223 uInt mstatus=0; /* local status */
3224 decMultiplyOp(b, b, b, &workset, &mstatus); /* try the multiply */
3225 if (mstatus&DEC_Overflow) { /* result just won't fit */
3226 status|=DEC_Inexact|DEC_Rounded;
3228 else { /* plausible */
3229 decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); /* b ? rhs */
3230 if (!ISZERO(t)) status|=DEC_Inexact|DEC_Rounded; /* not equal */
3231 else { /* is Exact */
3232 /* here, dropped is the count of trailing zeros in 'a' */
3233 /* use closest exponent to ideal... */
3234 Int todrop=ideal-a->exponent; /* most that can be dropped */
3235 if (todrop<0) status|=DEC_Rounded; /* ideally would add 0s */
3236 else { /* unrounded */
3237 if (dropped<todrop) { /* clamp to those available */
3238 todrop=dropped;
3239 status|=DEC_Clamped;
3241 if (todrop>0) { /* have some to drop */
3242 decShiftToLeast(a->lsu, D2U(a->digits), todrop);
3243 a->exponent+=todrop; /* maintain numerical value */
3244 a->digits-=todrop; /* new length */
3251 /* double-check Underflow, as perhaps the result could not have */
3252 /* been subnormal (initial argument too big), or it is now Exact */
3253 if (status&DEC_Underflow) {
3254 Int ae=rhs->exponent+rhs->digits-1; /* adjusted exponent */
3255 /* check if truly subnormal */
3256 #if DECEXTFLAG /* DEC_Subnormal too */
3257 if (ae>=set->emin*2) status&=~(DEC_Subnormal|DEC_Underflow);
3258 #else
3259 if (ae>=set->emin*2) status&=~DEC_Underflow;
3260 #endif
3261 /* check if truly inexact */
3262 if (!(status&DEC_Inexact)) status&=~DEC_Underflow;
3265 decNumberCopy(res, a); /* a is now the result */
3266 } while(0); /* end protected */
3268 if (allocbuff!=NULL) free(allocbuff); /* drop any storage used */
3269 if (allocbufa!=NULL) free(allocbufa); /* .. */
3270 if (allocbufb!=NULL) free(allocbufb); /* .. */
3271 #if DECSUBSET
3272 if (allocrhs !=NULL) free(allocrhs); /* .. */
3273 #endif
3274 if (status!=0) decStatus(res, status, set);/* then report status */
3275 #if DECCHECK
3276 decCheckInexact(res, set);
3277 #endif
3278 return res;
3279 } /* decNumberSquareRoot */
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 /* ------------------------------------------------------------------ */
3293 decNumber * decNumberSubtract(decNumber *res, const decNumber *lhs,
3294 const decNumber *rhs, decContext *set) {
3295 uInt status=0; /* accumulator */
3297 decAddOp(res, lhs, rhs, set, DECNEG, &status);
3298 if (status!=0) decStatus(res, status, set);
3299 #if DECCHECK
3300 decCheckInexact(res, set);
3301 #endif
3302 return res;
3303 } /* decNumberSubtract */
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 /* ------------------------------------------------------------------ */
3326 decNumber * decNumberToIntegralExact(decNumber *res, const decNumber *rhs,
3327 decContext *set) {
3328 decNumber dn;
3329 decContext workset; /* working context */
3330 uInt status=0; /* accumulator */
3332 #if DECCHECK
3333 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
3334 #endif
3336 /* handle infinities and NaNs */
3337 if (SPECIALARG) {
3338 if (decNumberIsInfinite(rhs)) decNumberCopy(res, rhs); /* an Infinity */
3339 else decNaNs(res, rhs, NULL, set, &status); /* a NaN */
3341 else { /* finite */
3342 /* have a finite number; no error possible (res must be big enough) */
3343 if (rhs->exponent>=0) return decNumberCopy(res, rhs);
3344 /* that was easy, but if negative exponent there is work to do... */
3345 workset=*set; /* clone rounding, etc. */
3346 workset.digits=rhs->digits; /* no length rounding */
3347 workset.traps=0; /* no traps */
3348 decNumberZero(&dn); /* make a number with exponent 0 */
3349 decNumberQuantize(res, rhs, &dn, &workset);
3350 status|=workset.status;
3352 if (status!=0) decStatus(res, status, set);
3353 return res;
3354 } /* decNumberToIntegralExact */
3356 decNumber * decNumberToIntegralValue(decNumber *res, const decNumber *rhs,
3357 decContext *set) {
3358 decContext workset=*set; /* working context */
3359 workset.traps=0; /* no traps */
3360 decNumberToIntegralExact(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 */
3363 set->status|=workset.status&DEC_Invalid_operation;
3364 return res;
3365 } /* decNumberToIntegralValue */
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 /* ------------------------------------------------------------------ */
3382 decNumber * decNumberXor(decNumber *res, const decNumber *lhs,
3383 const decNumber *rhs, decContext *set) {
3384 const Unit *ua, *ub; /* -> operands */
3385 const Unit *msua, *msub; /* -> operand msus */
3386 Unit *uc, *msuc; /* -> result and its msu */
3387 Int msudigs; /* digits in res msu */
3388 #if DECCHECK
3389 if (decCheckOperands(res, lhs, rhs, set)) return res;
3390 #endif
3392 if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
3393 || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
3394 decStatus(res, DEC_Invalid_operation, set);
3395 return res;
3397 /* operands are valid */
3398 ua=lhs->lsu; /* bottom-up */
3399 ub=rhs->lsu; /* .. */
3400 uc=res->lsu; /* .. */
3401 msua=ua+D2U(lhs->digits)-1; /* -> msu of lhs */
3402 msub=ub+D2U(rhs->digits)-1; /* -> msu of rhs */
3403 msuc=uc+D2U(set->digits)-1; /* -> msu of result */
3404 msudigs=MSUDIGITS(set->digits); /* [faster than remainder] */
3405 for (; uc<=msuc; ua++, ub++, uc++) { /* Unit loop */
3406 Unit a, b; /* extract units */
3407 if (ua>msua) a=0;
3408 else a=*ua;
3409 if (ub>msub) b=0;
3410 else b=*ub;
3411 *uc=0; /* can now write back */
3412 if (a|b) { /* maybe 1 bits to examine */
3413 Int i, j;
3414 /* This loop could be unrolled and/or use BIN2BCD tables */
3415 for (i=0; i<DECDPUN; i++) {
3416 if ((a^b)&1) *uc=*uc+(Unit)powers[i]; /* effect XOR */
3417 j=a%10;
3418 a=a/10;
3419 j|=b%10;
3420 b=b/10;
3421 if (j>1) {
3422 decStatus(res, DEC_Invalid_operation, set);
3423 return res;
3425 if (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] */
3430 res->digits=decGetDigits(res->lsu, uc-res->lsu);
3431 res->exponent=0; /* integer */
3432 res->bits=0; /* sign=0 */
3433 return res; /* [no status to set] */
3434 } /* decNumberXor */
3437 /* ================================================================== */
3438 /* Utility routines */
3439 /* ================================================================== */
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 /* ------------------------------------------------------------------ */
3447 enum decClass decNumberClass(const decNumber *dn, decContext *set) {
3448 if (decNumberIsSpecial(dn)) {
3449 if (decNumberIsQNaN(dn)) return DEC_CLASS_QNAN;
3450 if (decNumberIsSNaN(dn)) return DEC_CLASS_SNAN;
3451 /* must be an infinity */
3452 if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_INF;
3453 return DEC_CLASS_POS_INF;
3455 /* is finite */
3456 if (decNumberIsNormal(dn, set)) { /* most common */
3457 if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_NORMAL;
3458 return DEC_CLASS_POS_NORMAL;
3460 /* is subnormal or zero */
3461 if (decNumberIsZero(dn)) { /* most common */
3462 if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_ZERO;
3463 return DEC_CLASS_POS_ZERO;
3465 if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_SUBNORMAL;
3466 return DEC_CLASS_POS_SUBNORMAL;
3467 } /* decNumberClass */
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 /* ------------------------------------------------------------------ */
3475 const char *decNumberClassToString(enum decClass eclass) {
3476 if (eclass==DEC_CLASS_POS_NORMAL) return DEC_ClassString_PN;
3477 if (eclass==DEC_CLASS_NEG_NORMAL) return DEC_ClassString_NN;
3478 if (eclass==DEC_CLASS_POS_ZERO) return DEC_ClassString_PZ;
3479 if (eclass==DEC_CLASS_NEG_ZERO) return DEC_ClassString_NZ;
3480 if (eclass==DEC_CLASS_POS_SUBNORMAL) return DEC_ClassString_PS;
3481 if (eclass==DEC_CLASS_NEG_SUBNORMAL) return DEC_ClassString_NS;
3482 if (eclass==DEC_CLASS_POS_INF) return DEC_ClassString_PI;
3483 if (eclass==DEC_CLASS_NEG_INF) return DEC_ClassString_NI;
3484 if (eclass==DEC_CLASS_QNAN) return DEC_ClassString_QN;
3485 if (eclass==DEC_CLASS_SNAN) return DEC_ClassString_SN;
3486 return DEC_ClassString_UN; /* Unknown */
3487 } /* decNumberClassToString */
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 /* ------------------------------------------------------------------ */
3500 decNumber * decNumberCopy(decNumber *dest, const decNumber *src) {
3502 #if DECCHECK
3503 if (src==NULL) return decNumberZero(dest);
3504 #endif
3506 if (dest==src) return dest; /* no copy required */
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. */
3512 dest->bits=src->bits;
3513 dest->exponent=src->exponent;
3514 dest->digits=src->digits;
3515 dest->lsu[0]=src->lsu[0];
3516 if (src->digits>DECDPUN) { /* more Units to come */
3517 const Unit *smsup, *s; /* work */
3518 Unit *d; /* .. */
3519 /* memcpy for the remaining Units would be safe as they cannot */
3520 /* overlap. However, this explicit loop is faster in short cases. */
3521 d=dest->lsu+1; /* -> first destination */
3522 smsup=src->lsu+D2U(src->digits); /* -> source msu+1 */
3523 for (s=src->lsu+1; s<smsup; s++, d++) *d=*s;
3525 return dest;
3526 } /* decNumberCopy */
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 /* ------------------------------------------------------------------ */
3540 decNumber * decNumberCopyAbs(decNumber *res, const decNumber *rhs) {
3541 #if DECCHECK
3542 if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
3543 #endif
3544 decNumberCopy(res, rhs);
3545 res->bits&=~DECNEG; /* turn off sign */
3546 return res;
3547 } /* decNumberCopyAbs */
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 /* ------------------------------------------------------------------ */
3561 decNumber * decNumberCopyNegate(decNumber *res, const decNumber *rhs) {
3562 #if DECCHECK
3563 if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
3564 #endif
3565 decNumberCopy(res, rhs);
3566 res->bits^=DECNEG; /* invert the sign */
3567 return res;
3568 } /* decNumberCopyNegate */
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 /* ------------------------------------------------------------------ */
3582 decNumber * decNumberCopySign(decNumber *res, const decNumber *lhs,
3583 const decNumber *rhs) {
3584 uByte sign; /* rhs sign */
3585 #if DECCHECK
3586 if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
3587 #endif
3588 sign=rhs->bits & DECNEG; /* save sign bit */
3589 decNumberCopy(res, lhs);
3590 res->bits&=~DECNEG; /* clear the sign */
3591 res->bits|=sign; /* set from rhs */
3592 return res;
3593 } /* decNumberCopySign */
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 /* ------------------------------------------------------------------ */
3605 uByte * decNumberGetBCD(const decNumber *dn, uint8_t *bcd) {
3606 uByte *ub=bcd+dn->digits-1; /* -> lsd */
3607 const Unit *up=dn->lsu; /* Unit pointer, -> lsu */
3609 #if DECDPUN==1 /* trivial simple copy */
3610 for (; ub>=bcd; ub--, up++) *ub=*up;
3611 #else /* chopping needed */
3612 uInt u=*up; /* work */
3613 uInt cut=DECDPUN; /* downcounter through unit */
3614 for (; ub>=bcd; ub--) {
3615 *ub=(uByte)(u%10); /* [*6554 trick inhibits, here] */
3616 u=u/10;
3617 cut--;
3618 if (cut>0) continue; /* more in this unit */
3619 up++;
3620 u=*up;
3621 cut=DECDPUN;
3623 #endif
3624 return bcd;
3625 } /* decNumberGetBCD */
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 /* ------------------------------------------------------------------ */
3639 decNumber * decNumberSetBCD(decNumber *dn, const uByte *bcd, uInt n) {
3640 Unit *up = dn->lsu + D2U(n) - 1; /* -> msu [target pointer] */
3641 const uByte *ub=bcd; /* -> source msd */
3643 #if DECDPUN==1 /* trivial simple copy */
3644 for (; ub<bcd+n; ub++, up--) *up=*ub;
3645 #else /* some assembly needed */
3646 /* calculate how many digits in msu, and hence first cut */
3647 Int cut=MSUDIGITS(n); /* [faster than remainder] */
3648 for (;up>=dn->lsu; up--) { /* each Unit from msu */
3649 *up=0; /* will take <=DECDPUN digits */
3650 for (; cut>0; ub++, cut--) *up=X10(*up)+*ub;
3651 cut=DECDPUN; /* next Unit has all digits */
3653 #endif
3654 dn->digits=n; /* set digit count */
3655 return dn;
3656 } /* decNumberSetBCD */
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 /* ------------------------------------------------------------------ */
3664 Int decNumberIsNormal(const decNumber *dn, decContext *set) {
3665 Int ae; /* adjusted exponent */
3666 #if DECCHECK
3667 if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
3668 #endif
3670 if (decNumberIsSpecial(dn)) return 0; /* not finite */
3671 if (decNumberIsZero(dn)) return 0; /* not non-zero */
3673 ae=dn->exponent+dn->digits-1; /* adjusted exponent */
3674 if (ae<set->emin) return 0; /* is subnormal */
3675 return 1;
3676 } /* decNumberIsNormal */
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 /* ------------------------------------------------------------------ */
3684 Int decNumberIsSubnormal(const decNumber *dn, decContext *set) {
3685 Int ae; /* adjusted exponent */
3686 #if DECCHECK
3687 if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
3688 #endif
3690 if (decNumberIsSpecial(dn)) return 0; /* not finite */
3691 if (decNumberIsZero(dn)) return 0; /* not non-zero */
3693 ae=dn->exponent+dn->digits-1; /* adjusted exponent */
3694 if (ae<set->emin) return 1; /* is subnormal */
3695 return 0;
3696 } /* decNumberIsSubnormal */
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 /* ------------------------------------------------------------------ */
3707 decNumber * decNumberTrim(decNumber *dn) {
3708 Int dropped; /* work */
3709 decContext set; /* .. */
3710 #if DECCHECK
3711 if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn;
3712 #endif
3713 decContextDefault(&set, DEC_INIT_BASE); /* clamp=0 */
3714 return decTrim(dn, &set, 0, &dropped);
3715 } /* decNumberTrim */
3717 /* ------------------------------------------------------------------ */
3718 /* decNumberVersion -- return the name and version of this module */
3719 /* */
3720 /* No error is possible. */
3721 /* ------------------------------------------------------------------ */
3722 const char * decNumberVersion(void) {
3723 return DECVERSION;
3724 } /* decNumberVersion */
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. */
3735 decNumber * decNumberZero(decNumber *dn) {
3737 #if DECCHECK
3738 if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
3739 #endif
3741 dn->bits=0;
3742 dn->exponent=0;
3743 dn->digits=1;
3744 dn->lsu[0]=0;
3745 return dn;
3746 } /* decNumberZero */
3748 /* ================================================================== */
3749 /* Local routines */
3750 /* ================================================================== */
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. */
3768 static void decToString(const decNumber *dn, char *string, Flag eng) {
3769 Int exp=dn->exponent; /* local copy */
3770 Int e; /* E-part value */
3771 Int pre; /* digits before the '.' */
3772 Int cut; /* for counting digits in a Unit */
3773 char *c=string; /* work [output pointer] */
3774 const Unit *up=dn->lsu+D2U(dn->digits)-1; /* -> msu [input pointer] */
3775 uInt u, pow; /* work */
3777 #if DECCHECK
3778 if (decCheckOperands(DECUNRESU, dn, DECUNUSED, DECUNCONT)) {
3779 strcpy(string, "?");
3780 return;}
3781 #endif
3783 if (decNumberIsNegative(dn)) { /* Negatives get a minus */
3784 *c='-';
3785 c++;
3787 if (dn->bits&DECSPECIAL) { /* Is a special value */
3788 if (decNumberIsInfinite(dn)) {
3789 strcpy(c, "Inf");
3790 strcpy(c+3, "inity");
3791 return;}
3792 /* a NaN */
3793 if (dn->bits&DECSNAN) { /* signalling NaN */
3794 *c='s';
3795 c++;
3797 strcpy(c, "NaN");
3798 c+=3; /* step past */
3799 /* if not a clean non-zero coefficient, that's all there is in a */
3800 /* NaN string */
3801 if (exp!=0 || (*dn->lsu==0 && dn->digits==1)) return;
3802 /* [drop through to add integer] */
3805 /* calculate how many digits in msu, and hence first cut */
3806 cut=MSUDIGITS(dn->digits); /* [faster than remainder] */
3807 cut--; /* power of ten for digit */
3809 if (exp==0) { /* simple integer [common fastpath] */
3810 for (;up>=dn->lsu; up--) { /* each Unit from msu */
3811 u=*up; /* contains DECDPUN digits to lay out */
3812 for (; cut>=0; c++, cut--) TODIGIT(u, cut, c, pow);
3813 cut=DECDPUN-1; /* next Unit has all digits */
3815 *c='\0'; /* terminate the string */
3816 return;}
3818 /* non-0 exponent -- assume plain form */
3819 pre=dn->digits+exp; /* digits before '.' */
3820 e=0; /* no E */
3821 if ((exp>0) || (pre<-5)) { /* need exponential form */
3822 e=exp+dn->digits-1; /* calculate E value */
3823 pre=1; /* assume one digit before '.' */
3824 if (eng && (e!=0)) { /* engineering: may need to adjust */
3825 Int adj; /* adjustment */
3826 /* The C remainder operator is undefined for negative numbers, so */
3827 /* a positive remainder calculation must be used here */
3828 if (e<0) {
3829 adj=(-e)%3;
3830 if (adj!=0) adj=3-adj;
3832 else { /* e>0 */
3833 adj=e%3;
3835 e=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. */
3839 if (!ISZERO(dn)) pre+=adj;
3840 else { /* is zero */
3841 if (adj!=0) { /* 0.00Esnn needed */
3842 e=e+3;
3843 pre=-(2-adj);
3845 } /* zero */
3846 } /* eng */
3847 } /* need exponent */
3849 /* lay out the digits of the coefficient, adding 0s and . as needed */
3850 u=*up;
3851 if (pre>0) { /* xxx.xxx or xx00 (engineering) form */
3852 Int n=pre;
3853 for (; pre>0; pre--, c++, cut--) {
3854 if (cut<0) { /* need new Unit */
3855 if (up==dn->lsu) break; /* out of input digits (pre>digits) */
3856 up--;
3857 cut=DECDPUN-1;
3858 u=*up;
3860 TODIGIT(u, cut, c, pow);
3862 if (n<dn->digits) { /* more to come, after '.' */
3863 *c='.'; c++;
3864 for (;; c++, cut--) {
3865 if (cut<0) { /* need new Unit */
3866 if (up==dn->lsu) break; /* out of input digits */
3867 up--;
3868 cut=DECDPUN-1;
3869 u=*up;
3871 TODIGIT(u, cut, c, pow);
3874 else for (; pre>0; pre--, c++) *c='0'; /* 0 padding (for engineering) needed */
3876 else { /* 0.xxx or 0.000xxx form */
3877 *c='0'; c++;
3878 *c='.'; c++;
3879 for (; pre<0; pre++, c++) *c='0'; /* add any 0's after '.' */
3880 for (; ; c++, cut--) {
3881 if (cut<0) { /* need new Unit */
3882 if (up==dn->lsu) break; /* out of input digits */
3883 up--;
3884 cut=DECDPUN-1;
3885 u=*up;
3887 TODIGIT(u, cut, c, pow);
3891 /* Finally add the E-part, if needed. It will never be 0, has a
3892 base maximum and minimum of +999999999 through -999999999, but
3893 could range down to -1999999998 for anormal numbers */
3894 if (e!=0) {
3895 Flag had=0; /* 1=had non-zero */
3896 *c='E'; c++;
3897 *c='+'; c++; /* assume positive */
3898 u=e; /* .. */
3899 if (e<0) {
3900 *(c-1)='-'; /* oops, need - */
3901 u=-e; /* uInt, please */
3903 /* lay out the exponent [_itoa or equivalent is not ANSI C] */
3904 for (cut=9; cut>=0; cut--) {
3905 TODIGIT(u, cut, c, pow);
3906 if (*c=='0' && !had) continue; /* skip leading zeros */
3907 had=1; /* had non-0 */
3908 c++; /* step for next */
3909 } /* cut */
3911 *c='\0'; /* terminate the string (all paths) */
3912 return;
3913 } /* decToString */
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 /* ------------------------------------------------------------------ */
3950 static decNumber * decAddOp(decNumber *res, const decNumber *lhs,
3951 const decNumber *rhs, decContext *set,
3952 uByte negate, uInt *status) {
3953 #if DECSUBSET
3954 decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */
3955 decNumber *allocrhs=NULL; /* .., rhs */
3956 #endif
3957 Int rhsshift; /* working shift (in Units) */
3958 Int maxdigits; /* longest logical length */
3959 Int mult; /* multiplier */
3960 Int residue; /* rounding accumulator */
3961 uByte bits; /* result bits */
3962 Flag diffsign; /* non-0 if arguments have different sign */
3963 Unit *acc; /* accumulator for result */
3964 Unit accbuff[SD2U(DECBUFFER*2+20)]; /* local buffer [*2+20 reduces many */
3965 /* allocations when called from */
3966 /* other operations, notable exp] */
3967 Unit *allocacc=NULL; /* -> allocated acc buffer, iff allocated */
3968 Int reqdigits=set->digits; /* local copy; requested DIGITS */
3969 Int padding; /* work */
3971 #if DECCHECK
3972 if (decCheckOperands(res, lhs, rhs, set)) return res;
3973 #endif
3975 do { /* protect allocated storage */
3976 #if DECSUBSET
3977 if (!set->extended) {
3978 /* reduce operands and set lostDigits status, as needed */
3979 if (lhs->digits>reqdigits) {
3980 alloclhs=decRoundOperand(lhs, set, status);
3981 if (alloclhs==NULL) break;
3982 lhs=alloclhs;
3984 if (rhs->digits>reqdigits) {
3985 allocrhs=decRoundOperand(rhs, set, status);
3986 if (allocrhs==NULL) break;
3987 rhs=allocrhs;
3990 #endif
3991 /* [following code does not require input rounding] */
3993 /* note whether signs differ [used all paths] */
3994 diffsign=(Flag)((lhs->bits^rhs->bits^negate)&DECNEG);
3996 /* handle infinities and NaNs */
3997 if (SPECIALARGS) { /* a special bit set */
3998 if (SPECIALARGS & (DECSNAN | DECNAN)) /* a NaN */
3999 decNaNs(res, lhs, rhs, set, status);
4000 else { /* one or two infinities */
4001 if (decNumberIsInfinite(lhs)) { /* LHS is infinity */
4002 /* two infinities with different signs is invalid */
4003 if (decNumberIsInfinite(rhs) && diffsign) {
4004 *status|=DEC_Invalid_operation;
4005 break;
4007 bits=lhs->bits & DECNEG; /* get sign from LHS */
4009 else bits=(rhs->bits^negate) & DECNEG;/* RHS must be Infinity */
4010 bits|=DECINF;
4011 decNumberZero(res);
4012 res->bits=bits; /* set +/- infinity */
4013 } /* an infinity */
4014 break;
4017 /* Quick exit for add 0s; return the non-0, modified as need be */
4018 if (ISZERO(lhs)) {
4019 Int adjust; /* work */
4020 Int lexp=lhs->exponent; /* save in case LHS==RES */
4021 bits=lhs->bits; /* .. */
4022 residue=0; /* clear accumulator */
4023 decCopyFit(res, rhs, set, &residue, status); /* copy (as needed) */
4024 res->bits^=negate; /* flip if rhs was negated */
4025 #if DECSUBSET
4026 if (set->extended) { /* exponents on zeros count */
4027 #endif
4028 /* exponent will be the lower of the two */
4029 adjust=lexp-res->exponent; /* adjustment needed [if -ve] */
4030 if (ISZERO(res)) { /* both 0: special IEEE 854 rules */
4031 if (adjust<0) res->exponent=lexp; /* set exponent */
4032 /* 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0 */
4033 if (diffsign) {
4034 if (set->round!=DEC_ROUND_FLOOR) res->bits=0;
4035 else res->bits=DECNEG; /* preserve 0 sign */
4038 else { /* non-0 res */
4039 if (adjust<0) { /* 0-padding needed */
4040 if ((res->digits-adjust)>set->digits) {
4041 adjust=res->digits-set->digits; /* to fit exactly */
4042 *status|=DEC_Rounded; /* [but exact] */
4044 res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
4045 res->exponent+=adjust; /* set the exponent. */
4047 } /* non-0 res */
4048 #if DECSUBSET
4049 } /* extended */
4050 #endif
4051 decFinish(res, set, &residue, status); /* clean and finalize */
4052 break;}
4054 if (ISZERO(rhs)) { /* [lhs is non-zero] */
4055 Int adjust; /* work */
4056 Int rexp=rhs->exponent; /* save in case RHS==RES */
4057 bits=rhs->bits; /* be clean */
4058 residue=0; /* clear accumulator */
4059 decCopyFit(res, lhs, set, &residue, status); /* copy (as needed) */
4060 #if DECSUBSET
4061 if (set->extended) { /* exponents on zeros count */
4062 #endif
4063 /* exponent will be the lower of the two */
4064 /* [0-0 case handled above] */
4065 adjust=rexp-res->exponent; /* adjustment needed [if -ve] */
4066 if (adjust<0) { /* 0-padding needed */
4067 if ((res->digits-adjust)>set->digits) {
4068 adjust=res->digits-set->digits; /* to fit exactly */
4069 *status|=DEC_Rounded; /* [but exact] */
4071 res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
4072 res->exponent+=adjust; /* set the exponent. */
4074 #if DECSUBSET
4075 } /* extended */
4076 #endif
4077 decFinish(res, set, &residue, status); /* clean and finalize */
4078 break;}
4080 /* [NB: both fastpath and mainpath code below assume these cases */
4081 /* (notably 0-0) have already been handled] */
4083 /* calculate the padding needed to align the operands */
4084 padding=rhs->exponent-lhs->exponent;
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 */
4089 if (padding==0
4090 && rhs->digits<=DECDPUN
4091 && rhs->exponent>=set->emin /* [some normals drop through] */
4092 && rhs->exponent<=set->emax-set->digits+1 /* [could clamp] */
4093 && rhs->digits<=reqdigits
4094 && lhs->digits<=reqdigits) {
4095 Int partial=*lhs->lsu;
4096 if (!diffsign) { /* adding */
4097 partial+=*rhs->lsu;
4098 if ((partial<=DECDPUNMAX) /* result fits in unit */
4099 && (lhs->digits>=DECDPUN || /* .. and no digits-count change */
4100 partial<(Int)powers[lhs->digits])) { /* .. */
4101 if (res!=lhs) decNumberCopy(res, lhs); /* not in place */
4102 *res->lsu=(Unit)partial; /* [copy could have overwritten RHS] */
4103 break;
4105 /* else drop out for careful add */
4107 else { /* signs differ */
4108 partial-=*rhs->lsu;
4109 if (partial>0) { /* no borrow needed, and non-0 result */
4110 if (res!=lhs) decNumberCopy(res, lhs); /* not in place */
4111 *res->lsu=(Unit)partial;
4112 /* this could have reduced digits [but result>0] */
4113 res->digits=decGetDigits(res->lsu, D2U(res->digits));
4114 break;
4116 /* else drop out for careful subtract */
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). */
4127 rhsshift=0; /* rhs shift to left (padding) in Units */
4128 bits=lhs->bits; /* assume sign is that of LHS */
4129 mult=1; /* likely multiplier */
4131 /* [if padding==0 the operands are aligned; no padding is needed] */
4132 if (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 */
4136 Flag swapped=0;
4137 if (padding<0) { /* LHS needs the padding */
4138 const decNumber *t;
4139 padding=-padding; /* will be +ve */
4140 bits=(uByte)(rhs->bits^negate); /* assumed sign is now that of RHS */
4141 t=lhs; lhs=rhs; rhs=t;
4142 swapped=1;
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. */
4148 if (rhs->digits+padding > lhs->digits+reqdigits+1) {
4149 /* The RHS is sufficient */
4150 /* for residue use the relative sign indication... */
4151 Int shift=reqdigits-rhs->digits; /* left shift needed */
4152 residue=1; /* residue for rounding */
4153 if (diffsign) residue=-residue; /* signs differ */
4154 /* copy, shortening if necessary */
4155 decCopyFit(res, rhs, set, &residue, status);
4156 /* if it was already shorter, then need to pad with zeros */
4157 if (shift>0) {
4158 res->digits=decShiftToMost(res->lsu, res->digits, shift);
4159 res->exponent-=shift; /* adjust the exponent. */
4161 /* flip the result sign if unswapped and rhs was negated */
4162 if (!swapped) res->bits^=negate;
4163 decFinish(res, set, &residue, status); /* done */
4164 break;}
4166 /* LHS digits may affect result */
4167 rhsshift=D2U(padding+1)-1; /* this much by Unit shift .. */
4168 mult=powers[padding-(rhsshift*DECDPUN)]; /* .. this by multiplication */
4169 } /* padding needed */
4171 if (diffsign) mult=-mult; /* signs differ */
4173 /* determine the longer operand */
4174 maxdigits=rhs->digits+padding; /* virtual length of RHS */
4175 if (lhs->digits>maxdigits) maxdigits=lhs->digits;
4177 /* Decide on the result buffer to use; if possible place directly */
4178 /* into result. */
4179 acc=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] */
4183 if ((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 */
4187 Int need=D2U(maxdigits)+1;
4188 acc=accbuff; /* assume use local buffer */
4189 if (need*sizeof(Unit)>sizeof(accbuff)) {
4190 /* printf("malloc add %ld %ld\n", need, sizeof(accbuff)); */
4191 allocacc=(Unit *)malloc(need*sizeof(Unit));
4192 if (allocacc==NULL) { /* hopeless -- abandon */
4193 *status|=DEC_Insufficient_storage;
4194 break;}
4195 acc=allocacc;
4199 res->bits=(uByte)(bits&DECNEG); /* it's now safe to overwrite.. */
4200 res->exponent=lhs->exponent; /* .. operands (even if aliased) */
4202 #if DECTRACE
4203 decDumpAr('A', lhs->lsu, D2U(lhs->digits));
4204 decDumpAr('B', rhs->lsu, D2U(rhs->digits));
4205 printf(" :h: %ld %ld\n", rhsshift, mult);
4206 #endif
4208 /* add [A+B*m] or subtract [A+B*(-m)] */
4209 res->digits=decUnitAddSub(lhs->lsu, D2U(lhs->digits),
4210 rhs->lsu, D2U(rhs->digits),
4211 rhsshift, acc, mult)
4212 *DECDPUN; /* [units -> digits] */
4213 if (res->digits<0) { /* borrowed... */
4214 res->digits=-res->digits;
4215 res->bits^=DECNEG; /* flip the sign */
4217 #if DECTRACE
4218 decDumpAr('+', acc, D2U(res->digits));
4219 #endif
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.) */
4224 residue=0; /* clear accumulator */
4225 if (acc!=res->lsu) {
4226 #if DECSUBSET
4227 if (set->extended) { /* round from first significant digit */
4228 #endif
4229 /* remove leading zeros that were added due to rounding up to */
4230 /* integral Units -- before the test for rounding. */
4231 if (res->digits>reqdigits)
4232 res->digits=decGetDigits(acc, D2U(res->digits));
4233 decSetCoeff(res, set, acc, res->digits, &residue, status);
4234 #if DECSUBSET
4236 else { /* 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.) */
4242 if (res->digits<maxdigits) {
4243 *(acc+D2U(res->digits))=0; /* ensure leading 0 is there */
4244 res->digits=maxdigits;
4246 else {
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. */
4250 if (res->digits>reqdigits) {
4251 res->digits=decGetDigits(acc, D2U(res->digits));
4252 if (res->digits<maxdigits) res->digits=maxdigits;
4255 decSetCoeff(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 */
4258 if (residue!=0) {
4259 decApplyRound(res, set, residue, status);
4260 residue=0; /* did what needed to be done */
4262 } /* subset */
4263 #endif
4264 } /* used buffer */
4266 /* strip leading zeros [these were left on in case of subset subtract] */
4267 res->digits=decGetDigits(res->lsu, D2U(res->digits));
4269 /* apply checks and rounding */
4270 decFinish(res, set, &residue, status);
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.] */
4276 if (ISZERO(res) && diffsign
4277 #if DECSUBSET
4278 && set->extended
4279 #endif
4280 && (*status&DEC_Inexact)==0) {
4281 if (set->round==DEC_ROUND_FLOOR) res->bits|=DECNEG; /* sign - */
4282 else res->bits&=~DECNEG; /* sign + */
4284 } while(0); /* end protected */
4286 if (allocacc!=NULL) free(allocacc); /* drop any storage used */
4287 #if DECSUBSET
4288 if (allocrhs!=NULL) free(allocrhs); /* .. */
4289 if (alloclhs!=NULL) free(alloclhs); /* .. */
4290 #endif
4291 return res;
4292 } /* decAddOp */
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 /* ------------------------------------------------------------------ */
4364 static decNumber * decDivideOp(decNumber *res,
4365 const decNumber *lhs, const decNumber *rhs,
4366 decContext *set, Flag op, uInt *status) {
4367 #if DECSUBSET
4368 decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */
4369 decNumber *allocrhs=NULL; /* .., rhs */
4370 #endif
4371 Unit accbuff[SD2U(DECBUFFER+DECDPUN+10)]; /* local buffer */
4372 Unit *acc=accbuff; /* -> accumulator array for result */
4373 Unit *allocacc=NULL; /* -> allocated buffer, iff allocated */
4374 Unit *accnext; /* -> where next digit will go */
4375 Int acclength; /* length of acc needed [Units] */
4376 Int accunits; /* count of units accumulated */
4377 Int accdigits; /* count of digits accumulated */
4379 Unit varbuff[SD2U(DECBUFFER*2+DECDPUN)*sizeof(Unit)]; /* buffer for var1 */
4380 Unit *var1=varbuff; /* -> var1 array for long subtraction */
4381 Unit *varalloc=NULL; /* -> allocated buffer, iff used */
4382 Unit *msu1; /* -> msu of var1 */
4384 const Unit *var2; /* -> var2 array */
4385 const Unit *msu2; /* -> msu of var2 */
4386 Int msu2plus; /* msu2 plus one [does not vary] */
4387 eInt msu2pair; /* msu2 pair plus one [does not vary] */
4389 Int var1units, var2units; /* actual lengths */
4390 Int var2ulen; /* logical length (units) */
4391 Int var1initpad=0; /* var1 initial padding (digits) */
4392 Int maxdigits; /* longest LHS or required acc length */
4393 Int mult; /* multiplier for subtraction */
4394 Unit thisunit; /* current unit being accumulated */
4395 Int residue; /* for rounding */
4396 Int reqdigits=set->digits; /* requested DIGITS */
4397 Int exponent; /* working exponent */
4398 Int maxexponent=0; /* DIVIDE maximum exponent if unrounded */
4399 uByte bits; /* working sign */
4400 Unit *target; /* work */
4401 const Unit *source; /* .. */
4402 uLong const *pow; /* .. */
4403 Int shift, cut; /* .. */
4404 #if DECSUBSET
4405 Int dropped; /* work */
4406 #endif
4408 #if DECCHECK
4409 if (decCheckOperands(res, lhs, rhs, set)) return res;
4410 #endif
4412 do { /* protect allocated storage */
4413 #if DECSUBSET
4414 if (!set->extended) {
4415 /* reduce operands and set lostDigits status, as needed */
4416 if (lhs->digits>reqdigits) {
4417 alloclhs=decRoundOperand(lhs, set, status);
4418 if (alloclhs==NULL) break;
4419 lhs=alloclhs;
4421 if (rhs->digits>reqdigits) {
4422 allocrhs=decRoundOperand(rhs, set, status);
4423 if (allocrhs==NULL) break;
4424 rhs=allocrhs;
4427 #endif
4428 /* [following code does not require input rounding] */
4430 bits=(lhs->bits^rhs->bits)&DECNEG; /* assumed sign for divisions */
4432 /* handle infinities and NaNs */
4433 if (SPECIALARGS) { /* a special bit set */
4434 if (SPECIALARGS & (DECSNAN | DECNAN)) { /* one or two NaNs */
4435 decNaNs(res, lhs, rhs, set, status);
4436 break;
4438 /* one or two infinities */
4439 if (decNumberIsInfinite(lhs)) { /* LHS (dividend) is infinite */
4440 if (decNumberIsInfinite(rhs) || /* two infinities are invalid .. */
4441 op & (REMAINDER | REMNEAR)) { /* as is remainder of infinity */
4442 *status|=DEC_Invalid_operation;
4443 break;
4445 /* [Note that infinity/0 raises no exceptions] */
4446 decNumberZero(res);
4447 res->bits=bits|DECINF; /* set +/- infinity */
4448 break;
4450 else { /* RHS (divisor) is infinite */
4451 residue=0;
4452 if (op&(REMAINDER|REMNEAR)) {
4453 /* result is [finished clone of] lhs */
4454 decCopyFit(res, lhs, set, &residue, status);
4456 else { /* a division */
4457 decNumberZero(res);
4458 res->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 */
4461 if (op&DIVIDE) {
4462 res->exponent=set->emin-set->digits+1;
4463 *status|=DEC_Clamped;
4466 decFinish(res, set, &residue, status);
4467 break;
4471 /* handle 0 rhs (x/0) */
4472 if (ISZERO(rhs)) { /* x/0 is always exceptional */
4473 if (ISZERO(lhs)) {
4474 decNumberZero(res); /* [after lhs test] */
4475 *status|=DEC_Division_undefined;/* 0/0 will become NaN */
4477 else {
4478 decNumberZero(res);
4479 if (op&(REMAINDER|REMNEAR)) *status|=DEC_Invalid_operation;
4480 else {
4481 *status|=DEC_Division_by_zero; /* x/0 */
4482 res->bits=bits|DECINF; /* .. is +/- Infinity */
4485 break;}
4487 /* handle 0 lhs (0/x) */
4488 if (ISZERO(lhs)) { /* 0/x [x!=0] */
4489 #if DECSUBSET
4490 if (!set->extended) decNumberZero(res);
4491 else {
4492 #endif
4493 if (op&DIVIDE) {
4494 residue=0;
4495 exponent=lhs->exponent-rhs->exponent; /* ideal exponent */
4496 decNumberCopy(res, lhs); /* [zeros always fit] */
4497 res->bits=bits; /* sign as computed */
4498 res->exponent=exponent; /* exponent, too */
4499 decFinalize(res, set, &residue, status); /* check exponent */
4501 else if (op&DIVIDEINT) {
4502 decNumberZero(res); /* integer 0 */
4503 res->bits=bits; /* sign as computed */
4505 else { /* a remainder */
4506 exponent=rhs->exponent; /* [save in case overwrite] */
4507 decNumberCopy(res, lhs); /* [zeros always fit] */
4508 if (exponent<res->exponent) res->exponent=exponent; /* use lower */
4510 #if DECSUBSET
4512 #endif
4513 break;}
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. */
4519 exponent=(lhs->exponent+lhs->digits)-(rhs->exponent+rhs->digits);
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] */
4524 if (exponent<0 && !(op==DIVIDE)) {
4525 if (op&DIVIDEINT) {
4526 decNumberZero(res); /* integer part is 0 */
4527 #if DECSUBSET
4528 if (set->extended)
4529 #endif
4530 res->bits=bits; /* set +/- zero */
4531 break;}
4532 /* fastpath remainders so long as the lhs has the smaller */
4533 /* (or equal) exponent */
4534 if (lhs->exponent<=rhs->exponent) {
4535 if (op&REMAINDER || exponent<-1) {
4536 /* It is REMAINDER or safe REMNEAR; result is [finished */
4537 /* clone of] lhs (r = x - 0*y) */
4538 residue=0;
4539 decCopyFit(res, lhs, set, &residue, status);
4540 decFinish(res, set, &residue, status);
4541 break;
4543 /* [unsafe REMNEAR drops through] */
4545 } /* fastpaths */
4547 /* Long (slow) division is needed; roll up the sleeves... */
4549 /* The accumulator will hold the quotient of the division. */
4550 /* If it needs to be too long for stack storage, then allocate. */
4551 acclength=D2U(reqdigits+DECDPUN); /* in Units */
4552 if (acclength*sizeof(Unit)>sizeof(accbuff)) {
4553 /* printf("malloc dvacc %ld units\n", acclength); */
4554 allocacc=(Unit *)malloc(acclength*sizeof(Unit));
4555 if (allocacc==NULL) { /* hopeless -- abandon */
4556 *status|=DEC_Insufficient_storage;
4557 break;}
4558 acc=allocacc; /* use the allocated space */
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] */
4572 maxdigits=rhs->digits+reqdigits-1;
4573 if (lhs->digits>maxdigits) maxdigits=lhs->digits;
4574 var1units=D2U(maxdigits)+2;
4575 /* allocate a guard unit above msu1 for REMAINDERNEAR */
4576 if (!(op&DIVIDE)) var1units++;
4577 if ((var1units+1)*sizeof(Unit)>sizeof(varbuff)) {
4578 /* printf("malloc dvvar %ld units\n", var1units+1); */
4579 varalloc=(Unit *)malloc((var1units+1)*sizeof(Unit));
4580 if (varalloc==NULL) { /* hopeless -- abandon */
4581 *status|=DEC_Insufficient_storage;
4582 break;}
4583 var1=varalloc; /* use the allocated space */
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. */
4592 msu1=var1+var1units-1; /* msu of var1 */
4593 source=lhs->lsu+D2U(lhs->digits)-1; /* msu of input array */
4594 for (target=msu1; source>=lhs->lsu; source--, target--) *target=*source;
4595 for (; target>=var1; target--) *target=0;
4597 /* rhs (var2) is left-aligned with var1 at the start */
4598 var2ulen=var1units; /* rhs logical length (units) */
4599 var2units=D2U(rhs->digits); /* rhs actual length (units) */
4600 var2=rhs->lsu; /* -> rhs array */
4601 msu2=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. */
4605 msu2plus=*msu2; /* it's value .. */
4606 if (var2units>1) msu2plus++; /* .. +1 if any more */
4607 msu2pair=(eInt)*msu2*(DECDPUNMAX+1);/* top two pair .. */
4608 if (var2units>1) { /* .. [else treat 2nd as 0] */
4609 msu2pair+=*(msu2-1); /* .. */
4610 if (var2units>2) msu2pair++; /* .. +1 if any more */
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.] */
4619 for (pow=&powers[1]; *msu1>=*pow; pow++) exponent--;
4620 for (pow=&powers[1]; *msu2>=*pow; pow++) exponent++;
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. */
4627 if (!(op&DIVIDE)) {
4628 Unit *u; /* work */
4629 /* save the initial 'false' padding of var1, in digits */
4630 var1initpad=(var1units-D2U(lhs->digits))*DECDPUN;
4631 /* Determine the shift to do. */
4632 if (exponent<0) cut=-exponent;
4633 else cut=DECDPUN-exponent%DECDPUN;
4634 decShiftToLeast(var1, var1units, cut);
4635 exponent+=cut; /* maintain numerical value */
4636 var1initpad-=cut; /* .. and reduce padding */
4637 /* clean any most-significant units which were just emptied */
4638 for (u=msu1; cut>=DECDPUN; cut-=DECDPUN, u--) *u=0;
4639 } /* align */
4640 else { /* is DIVIDE */
4641 maxexponent=lhs->exponent-rhs->exponent; /* save */
4642 /* optimization: if the first iteration will just produce 0, */
4643 /* preadjust to skip it [valid for DIVIDE only] */
4644 if (*msu1<*msu2) {
4645 var2ulen--; /* shift down */
4646 exponent-=DECDPUN; /* update the exponent */
4650 /* ---- start the long-division loops ------------------------------ */
4651 accunits=0; /* no units accumulated yet */
4652 accdigits=0; /* .. or digits */
4653 accnext=acc+acclength-1; /* -> msu of acc [NB: allows digits+1] */
4654 for (;;) { /* outer forever loop */
4655 thisunit=0; /* current unit assumed 0 */
4656 /* find the next unit */
4657 for (;;) { /* inner forever loop */
4658 /* strip leading zero units [from either pre-adjust or from */
4659 /* subtract last time around]. Leave at least one unit. */
4660 for (; *msu1==0 && msu1>var1; msu1--) var1units--;
4662 if (var1units<var2ulen) break; /* var1 too low for subtract */
4663 if (var1units==var2ulen) { /* unit-by-unit compare needed */
4664 /* compare the two numbers, from msu */
4665 const Unit *pv1, *pv2;
4666 Unit v2; /* units to compare */
4667 pv2=msu2; /* -> msu */
4668 for (pv1=msu1; ; pv1--, pv2--) {
4669 /* v1=*pv1 -- always OK */
4670 v2=0; /* assume in padding */
4671 if (pv2>=var2) v2=*pv2; /* in range */
4672 if (*pv1!=v2) break; /* no longer the same */
4673 if (pv1==var1) break; /* done; leave pv1 as is */
4675 /* here when all inspected or a difference seen */
4676 if (*pv1<v2) break; /* var1 too low to subtract */
4677 if (*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. */
4681 thisunit++; /* as though subtracted */
4682 *var1=0; /* set var1 to 0 */
4683 var1units=1; /* .. */
4684 break; /* 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. */
4689 mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2pair);
4690 } /* lengths the same */
4691 else { /* 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. */
4694 mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2plus);
4696 if (mult==0) mult=1; /* must always be at least 1 */
4697 /* subtraction needed; var1 is > var2 */
4698 thisunit=(Unit)(thisunit+mult); /* accumulate */
4699 /* subtract var1-var2, into var1; only the overlap needs */
4700 /* processing, as this is an in-place calculation */
4701 shift=var2ulen-var2units;
4702 #if DECTRACE
4703 decDumpAr('1', &var1[shift], var1units-shift);
4704 decDumpAr('2', var2, var2units);
4705 printf("m=%ld\n", -mult);
4706 #endif
4707 decUnitAddSub(&var1[shift], var1units-shift,
4708 var2, var2units, 0,
4709 &var1[shift], -mult);
4710 #if DECTRACE
4711 decDumpAr('#', &var1[shift], var1units-shift);
4712 #endif
4713 /* var1 now probably has leading zeros; these are removed at the */
4714 /* top of the inner loop. */
4715 } /* inner loop */
4717 /* The next unit has been calculated in full; unless it's a */
4718 /* leading zero, add to acc */
4719 if (accunits!=0 || thisunit!=0) { /* is first or non-zero */
4720 *accnext=thisunit; /* store in accumulator */
4721 /* account exactly for the new digits */
4722 if (accunits==0) {
4723 accdigits++; /* at least one */
4724 for (pow=&powers[1]; thisunit>=*pow; pow++) accdigits++;
4726 else accdigits+=DECDPUN;
4727 accunits++; /* update count */
4728 accnext--; /* ready for next */
4729 if (accdigits>reqdigits) break; /* have enough digits */
4732 /* if the residue is zero, the operation is done (unless divide */
4733 /* or divideInteger and still not enough digits yet) */
4734 if (*var1==0 && var1units==1) { /* residue is 0 */
4735 if (op&(REMAINDER|REMNEAR)) break;
4736 if ((op&DIVIDE) && (exponent<=maxexponent)) break;
4737 /* [drop through if divideInteger] */
4739 /* also done enough if calculating remainder or integer */
4740 /* divide and just did the last ('units') unit */
4741 if (exponent==0 && !(op&DIVIDE)) break;
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 */
4745 var2ulen--; /* shift down */
4746 exponent-=DECDPUN; /* update the exponent */
4747 } /* outer loop */
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 */
4754 if (accunits==0) { /* acc is 0 */
4755 accunits=1; /* show have a unit .. */
4756 accdigits=1; /* .. */
4757 *accnext=0; /* .. whose value is 0 */
4759 else accnext++; /* back to last placed */
4760 /* accnext now -> lowest unit of result */
4762 residue=0; /* assume no residue */
4763 if (op&DIVIDE) {
4764 /* record the presence of any residue, for rounding */
4765 if (*var1!=0 || var1units>1) residue=1;
4766 else { /* 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>1
4772 Unit lsu=*accnext;
4773 if (!(lsu&0x01) && (lsu!=0)) {
4774 /* count the trailing zeros */
4775 Int drop=0;
4776 for (;; drop++) { /* [will terminate because lsu!=0] */
4777 if (exponent>=maxexponent) break; /* don't chop real 0s */
4778 #if DECDPUN<=4
4779 if ((lsu-QUOT10(lsu, drop+1)
4780 *powers[drop+1])!=0) break; /* found non-0 digit */
4781 #else
4782 if (lsu%powers[drop+1]!=0) break; /* found non-0 digit */
4783 #endif
4784 exponent++;
4786 if (drop>0) {
4787 accunits=decShiftToLeast(accnext, accunits, drop);
4788 accdigits=decGetDigits(accnext, accunits);
4789 accunits=D2U(accdigits);
4790 /* [exponent was adjusted in the loop] */
4792 } /* neither odd nor 0 */
4793 #endif
4794 } /* exact divide */
4795 } /* divide */
4796 else /* op!=DIVIDE */ {
4797 /* check for coefficient overflow */
4798 if (accdigits+exponent>reqdigits) {
4799 *status|=DEC_Division_impossible;
4800 break;
4802 if (op & (REMAINDER|REMNEAR)) {
4803 /* [Here, the exponent will be 0, because var1 was adjusted */
4804 /* appropriately.] */
4805 Int postshift; /* work */
4806 Flag wasodd=0; /* integer was odd */
4807 Unit *quotlsu; /* for save */
4808 Int quotdigits; /* .. */
4810 bits=lhs->bits; /* remainder sign is always as lhs */
4812 /* Fastpath when residue is truly 0 is worthwhile [and */
4813 /* simplifies the code below] */
4814 if (*var1==0 && var1units==1) { /* residue is 0 */
4815 Int exp=lhs->exponent; /* save min(exponents) */
4816 if (rhs->exponent<exp) exp=rhs->exponent;
4817 decNumberZero(res); /* 0 coefficient */
4818 #if DECSUBSET
4819 if (set->extended)
4820 #endif
4821 res->exponent=exp; /* .. with proper exponent */
4822 res->bits=(uByte)(bits&DECNEG); /* [cleaned] */
4823 decFinish(res, set, &residue, status); /* might clamp */
4824 break;
4826 /* note if the quotient was odd */
4827 if (*accnext & 0x01) wasodd=1; /* acc is odd */
4828 quotlsu=accnext; /* save in case need to reinspect */
4829 quotdigits=accdigits; /* .. */
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: */
4835 postshift=var1initpad+exponent-lhs->exponent+rhs->exponent;
4836 /* [the 'exponent' term accounts for the shifts during divide] */
4837 if (var1initpad<postshift) postshift=var1initpad;
4839 /* shift var1 the requested amount, and adjust its digits */
4840 var1units=decShiftToLeast(var1, var1units, postshift);
4841 accnext=var1;
4842 accdigits=decGetDigits(var1, var1units);
4843 accunits=D2U(accdigits);
4845 exponent=lhs->exponent; /* exponent is smaller of lhs & rhs */
4846 if (rhs->exponent<exponent) exponent=rhs->exponent;
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. */
4851 if (op&REMNEAR) {
4852 Int compare, tarunits; /* work */
4853 Unit *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] */
4857 tarunits=decUnitAddSub(accnext, accunits, accnext, accunits,
4858 0, accnext, 1);
4859 /* decDumpAr('r', accnext, tarunits); */
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. */
4864 compare=decUnitCompare(accnext, tarunits, rhs->lsu, D2U(rhs->digits),
4865 rhs->exponent-exponent);
4866 if (compare==BADINT) { /* deep trouble */
4867 *status|=DEC_Insufficient_storage;
4868 break;}
4870 /* now restore the remainder by dividing by two; the lsu */
4871 /* is known to be even. */
4872 for (up=accnext; up<accnext+tarunits; up++) {
4873 Int half; /* half to add to lower unit */
4874 half=*up & 0x01;
4875 *up/=2; /* [shift] */
4876 if (!half) continue;
4877 *(up-1)+=DIV_ROUND_UP(DECDPUNMAX, 2);
4879 /* [accunits still describes the original remainder length] */
4881 if (compare>0 || (compare==0 && wasodd)) { /* adjustment needed */
4882 Int 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 */
4887 Flag allnines=0; /* 1 if quotient all nines */
4888 if (quotdigits==reqdigits) { /* could be borderline */
4889 for (up=quotlsu; ; up++) {
4890 if (quotdigits>DECDPUN) {
4891 if (*up!=DECDPUNMAX) break;/* non-nines */
4893 else { /* this is the last Unit */
4894 if (*up==powers[quotdigits]-1) allnines=1;
4895 break;
4897 quotdigits-=DECDPUN; /* checked those digits */
4898 } /* up */
4899 } /* borderline check */
4900 if (allnines) {
4901 *status|=DEC_Division_impossible;
4902 break;}
4904 /* rem-rhs is needed; the sign will invert. Again, var1 */
4905 /* can safely be used for the working Units array. */
4906 exp=rhs->exponent-exponent; /* RHS padding needed */
4907 /* Calculate units and remainder from exponent. */
4908 expunits=exp/DECDPUN;
4909 exprem=exp%DECDPUN;
4910 /* subtract [A+B*(-m)]; the result will always be negative */
4911 accunits=-decUnitAddSub(accnext, accunits,
4912 rhs->lsu, D2U(rhs->digits),
4913 expunits, accnext, -(Int)powers[exprem]);
4914 accdigits=decGetDigits(accnext, accunits); /* count digits exactly */
4915 accunits=D2U(accdigits); /* and recalculate the units for copy */
4916 /* [exponent is as for original remainder] */
4917 bits^=DECNEG; /* flip the sign */
4919 } /* REMNEAR */
4920 } /* REMAINDER or REMNEAR */
4921 } /* not DIVIDE */
4923 /* Set exponent and bits */
4924 res->exponent=exponent;
4925 res->bits=(uByte)(bits&DECNEG); /* [cleaned] */
4927 /* Now the coefficient. */
4928 decSetCoeff(res, set, accnext, accdigits, &residue, status);
4930 decFinish(res, set, &residue, status); /* final cleanup */
4932 #if DECSUBSET
4933 /* If a divide then strip trailing zeros if subset [after round] */
4934 if (!set->extended && (op==DIVIDE)) decTrim(res, set, 0, &dropped);
4935 #endif
4936 } while(0); /* end protected */
4938 if (varalloc!=NULL) free(varalloc); /* drop any storage used */
4939 if (allocacc!=NULL) free(allocacc); /* .. */
4940 #if DECSUBSET
4941 if (allocrhs!=NULL) free(allocrhs); /* .. */
4942 if (alloclhs!=NULL) free(alloclhs); /* .. */
4943 #endif
4944 return res;
4945 } /* decDivideOp */
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)
4984 static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs,
4985 const decNumber *rhs, decContext *set,
4986 uInt *status) {
4987 Int accunits; /* Units of accumulator in use */
4988 Int exponent; /* work */
4989 Int residue=0; /* rounding residue */
4990 uByte bits; /* result sign */
4991 Unit *acc; /* -> accumulator Unit array */
4992 Int needbytes; /* size calculator */
4993 void *allocacc=NULL; /* -> allocated accumulator, iff allocated */
4994 Unit accbuff[SD2U(DECBUFFER*4+1)]; /* buffer (+1 for DECBUFFER==0, */
4995 /* *4 for calls from other operations) */
4996 const Unit *mer, *mermsup; /* work */
4997 Int madlength; /* Units in multiplicand */
4998 Int shift; /* Units to shift multiplicand by */
5000 #if FASTMUL
5001 /* 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 #else
5008 #define FASTBASE 100000000
5009 #define FASTDIGS 8
5010 #define FASTLAZY 1844 /* carry resolution point [1->1844] */
5011 #endif
5012 /* 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 */
5015 uInt zlhibuff[(DECBUFFER*2+1)/8+1]; /* buffer (+1 for DECBUFFER==0) */
5016 uInt *zlhi=zlhibuff; /* -> lhs array */
5017 uInt *alloclhi=NULL; /* -> allocated buffer, iff allocated */
5018 uInt zrhibuff[(DECBUFFER*2+1)/8+1]; /* buffer (+1 for DECBUFFER==0) */
5019 uInt *zrhi=zrhibuff; /* -> rhs array */
5020 uInt *allocrhi=NULL; /* -> allocated buffer, iff allocated */
5021 uLong zaccbuff[(DECBUFFER*2+1)/4+2]; /* buffer (+1 for DECBUFFER==0) */
5022 /* [allocacc is shared for both paths, as only one will run] */
5023 uLong *zacc=zaccbuff; /* -> accumulator array for exact result */
5024 #if DECDPUN==1
5025 Int zoff; /* accumulator offset */
5026 #endif
5027 uInt *lip, *rip; /* item pointers */
5028 uInt *lmsi, *rmsi; /* most significant items */
5029 Int ilhs, irhs, iacc; /* item counts in the arrays */
5030 Int lazy; /* lazy carry counter */
5031 uLong lcarry; /* uLong carry */
5032 uInt carry; /* carry (NB not uLong) */
5033 Int count; /* work */
5034 const Unit *cup; /* .. */
5035 Unit *up; /* .. */
5036 uLong *lp; /* .. */
5037 Int p; /* .. */
5038 #endif
5040 #if DECSUBSET
5041 decNumber *alloclhs=NULL; /* -> allocated buffer, iff allocated */
5042 decNumber *allocrhs=NULL; /* -> allocated buffer, iff allocated */
5043 #endif
5045 #if DECCHECK
5046 if (decCheckOperands(res, lhs, rhs, set)) return res;
5047 #endif
5049 /* precalculate result sign */
5050 bits=(uByte)((lhs->bits^rhs->bits)&DECNEG);
5052 /* handle infinities and NaNs */
5053 if (SPECIALARGS) { /* a special bit set */
5054 if (SPECIALARGS & (DECSNAN | DECNAN)) { /* one or two NaNs */
5055 decNaNs(res, lhs, rhs, set, status);
5056 return res;}
5057 /* one or two infinities; Infinity * 0 is invalid */
5058 if (((lhs->bits & DECINF)==0 && ISZERO(lhs))
5059 ||((rhs->bits & DECINF)==0 && ISZERO(rhs))) {
5060 *status|=DEC_Invalid_operation;
5061 return res;}
5062 decNumberZero(res);
5063 res->bits=bits|DECINF; /* infinity */
5064 return res;}
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) */
5070 if (lhs->digits<rhs->digits) { /* swap... */
5071 const decNumber *hold=lhs;
5072 lhs=rhs;
5073 rhs=hold;
5076 do { /* protect allocated storage */
5077 #if DECSUBSET
5078 if (!set->extended) {
5079 /* reduce operands and set lostDigits status, as needed */
5080 if (lhs->digits>set->digits) {
5081 alloclhs=decRoundOperand(lhs, set, status);
5082 if (alloclhs==NULL) break;
5083 lhs=alloclhs;
5085 if (rhs->digits>set->digits) {
5086 allocrhs=decRoundOperand(rhs, set, status);
5087 if (allocrhs==NULL) break;
5088 rhs=allocrhs;
5091 #endif
5092 /* [following code does not require input rounding] */
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 */
5098 if (rhs->digits>NEEDTWO) { /* use fastpath... */
5099 /* calculate the number of elements in each array */
5100 ilhs=(lhs->digits+FASTDIGS-1)/FASTDIGS; /* [ceiling] */
5101 irhs=(rhs->digits+FASTDIGS-1)/FASTDIGS; /* .. */
5102 iacc=ilhs+irhs;
5104 /* allocate buffers if required, as usual */
5105 needbytes=ilhs*sizeof(uInt);
5106 if (needbytes>(Int)sizeof(zlhibuff)) {
5107 alloclhi=(uInt *)malloc(needbytes);
5108 zlhi=alloclhi;}
5109 needbytes=irhs*sizeof(uInt);
5110 if (needbytes>(Int)sizeof(zrhibuff)) {
5111 allocrhi=(uInt *)malloc(needbytes);
5112 zrhi=allocrhi;}
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. */
5121 needbytes=iacc*sizeof(uLong);
5122 #if DECDPUN==1
5123 zoff=(iacc+7)/8; /* items to offset by */
5124 needbytes+=zoff*8;
5125 #endif
5126 if (needbytes>(Int)sizeof(zaccbuff)) {
5127 allocacc=(uLong *)malloc(needbytes);
5128 zacc=(uLong *)allocacc;}
5129 if (zlhi==NULL||zrhi==NULL||zacc==NULL) {
5130 *status|=DEC_Insufficient_storage;
5131 break;}
5133 acc=(Unit *)zacc; /* -> target Unit array */
5134 #if DECDPUN==1
5135 zacc+=zoff; /* start uLong accumulator to right */
5136 #endif
5138 /* assemble the chunked copies of the left and right sides */
5139 for (count=lhs->digits, cup=lhs->lsu, lip=zlhi; count>0; lip++)
5140 for (p=0, *lip=0; p<FASTDIGS && count>0;
5141 p+=DECDPUN, cup++, count-=DECDPUN)
5142 *lip+=*cup*powers[p];
5143 lmsi=lip-1; /* save -> msi */
5144 for (count=rhs->digits, cup=rhs->lsu, rip=zrhi; count>0; rip++)
5145 for (p=0, *rip=0; p<FASTDIGS && count>0;
5146 p+=DECDPUN, cup++, count-=DECDPUN)
5147 *rip+=*cup*powers[p];
5148 rmsi=rip-1; /* save -> msi */
5150 /* zero the accumulator */
5151 for (lp=zacc; lp<zacc+iacc; lp++) *lp=0;
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.) */
5170 lazy=FASTLAZY; /* carry delay count */
5171 for (rip=zrhi; rip<=rmsi; rip++) { /* over each item in rhs */
5172 lp=zacc+(rip-zrhi); /* where to add the lhs */
5173 for (lip=zlhi; lip<=lmsi; lip++, lp++) { /* over each item in lhs */
5174 *lp+=(uLong)(*lip)*(*rip); /* [this should in-line] */
5175 } /* lip loop */
5176 lazy--;
5177 if (lazy>0 && rip!=rmsi) continue;
5178 lazy=FASTLAZY; /* reset delay count */
5179 /* spin up the accumulator resolving overflows */
5180 for (lp=zacc; lp<zacc+iacc; lp++) {
5181 if (*lp<FASTBASE) continue; /* it fits */
5182 lcarry=*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 */
5187 if (lcarry<FASTBASE) carry=(uInt)lcarry; /* [usual] */
5188 else { /* two-place carry [fairly rare] */
5189 uInt carry2=(uInt)(lcarry/FASTBASE); /* top top part */
5190 *(lp+2)+=carry2; /* add to item+2 */
5191 *lp-=((uLong)FASTBASE*FASTBASE*carry2); /* [slow] */
5192 carry=(uInt)(lcarry-((uLong)FASTBASE*carry2)); /* [inline] */
5194 *(lp+1)+=carry; /* add to item above [inline] */
5195 *lp-=((uLong)FASTBASE*carry); /* [inline] */
5196 } /* carry resolution */
5197 } /* rip loop */
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). */
5205 for (lp=zacc, up=acc; lp<zacc+iacc; lp++) {
5206 uInt item=(uInt)*lp; /* decapitate to uInt */
5207 for (p=0; p<FASTDIGS-DECDPUN; p+=DECDPUN, up++) {
5208 uInt part=item/(DECDPUNMAX+1);
5209 *up=(Unit)(item-(part*(DECDPUNMAX+1)));
5210 item=part;
5211 } /* p */
5212 *up=(Unit)item; up++; /* [final needs no division] */
5213 } /* lp */
5214 accunits=up-acc; /* count of units */
5216 else { /* here to use units directly, without chunking ['old code'] */
5217 #endif
5219 /* if accumulator will be too long for local storage, then allocate */
5220 acc=accbuff; /* -> assume buffer for accumulator */
5221 needbytes=(D2U(lhs->digits)+D2U(rhs->digits))*sizeof(Unit);
5222 if (needbytes>(Int)sizeof(accbuff)) {
5223 allocacc=(Unit *)malloc(needbytes);
5224 if (allocacc==NULL) {*status|=DEC_Insufficient_storage; break;}
5225 acc=(Unit *)allocacc; /* use the allocated space */
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 */
5233 accunits=1; /* accumulator starts at '0' */
5234 *acc=0; /* .. (lsu=0) */
5235 shift=0; /* no multiplicand shift at first */
5236 madlength=D2U(lhs->digits); /* this won't change */
5237 mermsup=rhs->lsu+D2U(rhs->digits); /* -> msu+1 of multiplier */
5239 for (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... */
5242 if (*mer!=0) accunits=decUnitAddSub(&acc[shift], accunits-shift,
5243 lhs->lsu, madlength, 0,
5244 &acc[shift], *mer)
5245 + shift;
5246 else { /* extend acc with a 0; it will be used shortly */
5247 *(acc+accunits)=0; /* [this avoids length of <=0 later] */
5248 accunits++;
5250 /* multiply multiplicand by 10**DECDPUN for next Unit to left */
5251 shift++; /* add this for 'logical length' */
5252 } /* n */
5253 #if FASTMUL
5254 } /* unchunked units */
5255 #endif
5256 /* common end-path */
5257 #if DECTRACE
5258 decDumpAr('*', acc, accunits); /* Show exact result */
5259 #endif
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 */
5264 res->bits=bits; /* set sign */
5265 res->digits=decGetDigits(acc, accunits); /* count digits exactly */
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. */
5272 exponent=lhs->exponent+rhs->exponent; /* calculate exponent */
5273 if (lhs->exponent<0 && rhs->exponent<0 && exponent>0)
5274 exponent=-2*DECNUMMAXE; /* force underflow */
5275 res->exponent=exponent; /* OK to overwrite now */
5278 /* Set the coefficient. If any rounding, residue records */
5279 decSetCoeff(res, set, acc, res->digits, &residue, status);
5280 decFinish(res, set, &residue, status); /* final cleanup */
5281 } while(0); /* end protected */
5283 if (allocacc!=NULL) free(allocacc); /* drop any storage used */
5284 #if DECSUBSET
5285 if (allocrhs!=NULL) free(allocrhs); /* .. */
5286 if (alloclhs!=NULL) free(alloclhs); /* .. */
5287 #endif
5288 #if FASTMUL
5289 if (allocrhi!=NULL) free(allocrhi); /* .. */
5290 if (alloclhi!=NULL) free(alloclhi); /* .. */
5291 #endif
5292 return res;
5293 } /* decMultiplyOp */
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 /* ------------------------------------------------------------------ */
5374 static decNumber *decExpOp(decNumber *res, const decNumber *rhs,
5375 decContext *set, uInt *status) {
5376 uInt ignore=0; /* working status */
5377 Int h; /* adjusted exponent for 0.xxxx */
5378 Int p; /* working precision */
5379 Int residue; /* rounding residue */
5380 uInt needbytes; /* for space calculations */
5381 const decNumber *x=rhs; /* (may point to safe copy later) */
5382 decContext aset, tset, dset; /* working contexts */
5383 Int comp; /* work */
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 */
5388 decNumber bufr[D2N(DECBUFFER*2+1)];
5389 decNumber *allocrhs=NULL; /* non-NULL if rhs buffer allocated */
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) */
5395 /* buffer for t, term (working precision plus) */
5396 decNumber buft[D2N(DECBUFFER*2+9+1)];
5397 decNumber *allocbuft=NULL; /* -> allocated buft, iff allocated */
5398 decNumber *t=buft; /* term */
5399 /* buffer for a, accumulator (working precision * 2), at least 9 */
5400 decNumber bufa[D2N(DECBUFFER*4+18+1)];
5401 decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */
5402 decNumber *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] */
5405 decNumber bufd[D2N(16)];
5406 decNumber *d=bufd; /* divisor */
5407 decNumber numone; /* constant 1 */
5409 #if DECCHECK
5410 Int iterations=0; /* for later sanity check */
5411 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
5412 #endif
5414 do { /* protect allocated storage */
5415 if (SPECIALARG) { /* handle infinities and NaNs */
5416 if (decNumberIsInfinite(rhs)) { /* an infinity */
5417 if (decNumberIsNegative(rhs)) /* -Infinity -> +0 */
5418 decNumberZero(res);
5419 else decNumberCopy(res, rhs); /* +Infinity -> self */
5421 else decNaNs(res, rhs, NULL, set, status); /* a NaN */
5422 break;}
5424 if (ISZERO(rhs)) { /* zeros -> exact 1 */
5425 decNumberZero(res); /* make clean 1 */
5426 *res->lsu=1; /* .. */
5427 break;} /* [no status to set] */
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 */
5443 decNumberZero(d); /* clean */
5444 *d->lsu=4; /* set 4 .. */
5445 d->exponent=-set->digits; /* * 10**(-d) */
5446 if (decNumberIsNegative(rhs)) d->exponent--; /* negative case */
5447 comp=decCompare(d, rhs, 1); /* signless compare */
5448 if (comp==BADINT) {
5449 *status|=DEC_Insufficient_storage;
5450 break;}
5451 if (comp>=0) { /* rhs < d */
5452 Int shift=set->digits-1;
5453 decNumberZero(res); /* set 1 */
5454 *res->lsu=1; /* .. */
5455 res->digits=decShiftToMost(res->lsu, 1, shift);
5456 res->exponent=-shift; /* make 1.0000... */
5457 *status|=DEC_Inexact | DEC_Rounded; /* .. inexactly */
5458 break;} /* tiny */
5460 /* set up the context to be used for calculating a, as this is */
5461 /* used on both paths below */
5462 decContextDefault(&aset, DEC_INIT_DECIMAL64);
5463 /* accumulator bounds are as requested (could underflow) */
5464 aset.emax=set->emax; /* usual bounds */
5465 aset.emin=set->emin; /* .. */
5466 aset.clamp=0; /* and no concrete format */
5468 /* calculate the adjusted (Hull & Abrham) exponent (where the */
5469 /* decimal point is just to the left of the coefficient msd) */
5470 h=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 */
5476 if (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] */
5480 decNumberZero(a);
5481 *a->lsu=2; /* not 1 but < exp(1) */
5482 if (decNumberIsNegative(rhs)) a->exponent=-2; /* make 0.02 */
5483 h=8; /* clamp so 10**h computable */
5484 p=9; /* set a working precision */
5486 else { /* h<=8 */
5487 Int maxlever=(rhs->digits>8?1:0);
5488 /* [could/should increase this for precisions >40 or so, too] */
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. */
5498 Int lever=MINI(8-h, maxlever); /* leverage attainable */
5499 Int use=-rhs->digits-lever; /* exponent to use for RHS */
5500 h+=lever; /* apply leverage selected */
5501 if (h<0) { /* clamp */
5502 use+=h; /* [may end up subnormal] */
5503 h=0;
5505 /* Take a copy of RHS if it needs normalization (true whenever x>=1) */
5506 if (rhs->exponent!=use) {
5507 decNumber *newrhs=bufr; /* assume will fit on stack */
5508 needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
5509 if (needbytes>sizeof(bufr)) { /* need malloc space */
5510 allocrhs=(decNumber *)malloc(needbytes);
5511 if (allocrhs==NULL) { /* hopeless -- abandon */
5512 *status|=DEC_Insufficient_storage;
5513 break;}
5514 newrhs=allocrhs; /* use the allocated space */
5516 decNumberCopy(newrhs, rhs); /* copy to safe space */
5517 newrhs->exponent=use; /* normalize; now <1 */
5518 x=newrhs; /* ready for use */
5519 /* decNumberShow(x); */
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. */
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 */
5532 p=MAXI(x->digits, set->digits)+h+2; /* [h<=8] */
5534 /* a and t are variable precision, and depend on p, so space */
5535 /* must be allocated for them if necessary */
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. */
5540 needbytes=sizeof(decNumber)+(D2U(p*2)-1)*sizeof(Unit);
5541 if (needbytes>sizeof(bufa)) { /* need malloc space */
5542 allocbufa=(decNumber *)malloc(needbytes);
5543 if (allocbufa==NULL) { /* hopeless -- abandon */
5544 *status|=DEC_Insufficient_storage;
5545 break;}
5546 a=allocbufa; /* use the allocated space */
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 */
5552 needbytes=sizeof(decNumber)+(D2U(p+2)-1)*sizeof(Unit);
5553 if (needbytes>sizeof(buft)) { /* need malloc space */
5554 allocbuft=(decNumber *)malloc(needbytes);
5555 if (allocbuft==NULL) { /* hopeless -- abandon */
5556 *status|=DEC_Insufficient_storage;
5557 break;}
5558 t=allocbuft; /* use the allocated space */
5561 decNumberCopy(t, x); /* term=x */
5562 decNumberZero(a); *a->lsu=1; /* accumulator=1 */
5563 decNumberZero(d); *d->lsu=2; /* divisor=2 */
5564 decNumberZero(&numone); *numone.lsu=1; /* constant 1 for increment */
5566 /* set up the contexts for calculating a, t, and d */
5567 decContextDefault(&tset, DEC_INIT_DECIMAL64);
5568 dset=tset;
5569 /* accumulator bounds are set above, set precision now */
5570 aset.digits=p*2; /* double */
5571 /* term bounds avoid any underflow or overflow */
5572 tset.digits=p;
5573 tset.emin=DEC_MIN_EMIN; /* [emax is plenty] */
5574 /* [dset.digits=16, etc., are sufficient] */
5576 /* finally ready to roll */
5577 for (;;) {
5578 #if DECCHECK
5579 iterations++;
5580 #endif
5581 /* only the status from the accumulation is interesting */
5582 /* [but it should remain unchanged after first add] */
5583 decAddOp(a, a, t, &aset, 0, status); /* a=a+t */
5584 decMultiplyOp(t, t, x, &tset, &ignore); /* t=t*x */
5585 decDivideOp(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. */
5590 if (((a->digits+a->exponent)>=(t->digits+t->exponent+p+1))
5591 && (a->digits>=p)) break;
5592 decAddOp(d, d, &numone, &dset, 0, &ignore); /* d=d+1 */
5593 } /* iterate */
5595 #if DECCHECK
5596 /* just a sanity check; comment out test to show always */
5597 if (iterations>p+3)
5598 printf("Exp iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
5599 iterations, *status, p, x->digits);
5600 #endif
5601 } /* h<=8 */
5603 /* apply postconditioning: a=a**(10**h) -- this is calculated */
5604 /* at a slightly higher precision than Hull & Abrham suggest */
5605 if (h>0) {
5606 Int seenbit=0; /* set once a 1-bit is seen */
5607 Int i; /* counter */
5608 Int n=powers[h]; /* always positive */
5609 aset.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 */
5613 decNumberZero(t); *t->lsu=1; /* acc=1 */
5614 for (i=1;;i++){ /* for each bit [top bit ignored] */
5615 /* abandon if have had overflow or terminal underflow */
5616 if (*status & (DEC_Overflow|DEC_Underflow)) { /* interesting? */
5617 if (*status&DEC_Overflow || ISZERO(t)) break;}
5618 n=n<<1; /* move next bit to testable position */
5619 if (n<0) { /* top bit is set */
5620 seenbit=1; /* OK, have a significant bit */
5621 decMultiplyOp(t, t, a, &aset, status); /* acc=acc*x */
5623 if (i==31) break; /* that was the last bit */
5624 if (!seenbit) continue; /* no need to square 1 */
5625 decMultiplyOp(t, t, t, &aset, status); /* acc=acc*acc [square] */
5626 } /*i*/ /* 32 bits */
5627 /* decNumberShow(t); */
5628 a=t; /* and carry on using t instead of a */
5631 /* Copy and round the result to res */
5632 residue=1; /* indicate dirt to right .. */
5633 if (ISZERO(a)) residue=0; /* .. unless underflowed to 0 */
5634 aset.digits=set->digits; /* [use default rounding] */
5635 decCopyFit(res, a, &aset, &residue, status); /* copy & shorten */
5636 decFinish(res, set, &residue, status); /* cleanup/set flags */
5637 } while(0); /* end protected */
5639 if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */
5640 if (allocbufa!=NULL) free(allocbufa); /* .. */
5641 if (allocbuft!=NULL) free(allocbuft); /* .. */
5642 /* [status is handled by caller] */
5643 return res;
5644 } /* decExpOp */
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 /* ------------------------------------------------------------------ */
5662 static const uShort LNnn[90] = {
5663 9016, 8652, 8316, 8008, 7724, 7456, 7208,
5664 6972, 6748, 6540, 6340, 6148, 5968, 5792, 5628, 5464, 5312,
5665 5164, 5020, 4884, 4748, 4620, 4496, 4376, 4256, 4144, 4032,
5666 39233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629,
5667 29777, 28945, 28129, 27329, 26545, 25777, 25021, 24281, 23553, 22837,
5668 22137, 21445, 20769, 20101, 19445, 18801, 18165, 17541, 16925, 16321,
5669 15721, 15133, 14553, 13985, 13421, 12865, 12317, 11777, 11241, 10717,
5670 10197, 9685, 9177, 8677, 8185, 7697, 7213, 6737, 6269, 5801,
5671 5341, 4889, 4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254,
5672 10130, 6046, 20055};
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 /* ------------------------------------------------------------------ */
5735 static decNumber *decLnOp(decNumber *res, const decNumber *rhs,
5736 decContext *set, uInt *status) {
5737 uInt ignore=0; /* working status accumulator */
5738 uInt needbytes; /* for space calculations */
5739 Int residue; /* rounding residue */
5740 Int r; /* rhs=f*10**r [see below] */
5741 Int p; /* working precision */
5742 Int pp; /* precision for iteration */
5743 Int t; /* work */
5745 /* buffers for a (accumulator, typically precision+2) and b */
5746 /* (adjustment calculator, same size) */
5747 decNumber bufa[D2N(DECBUFFER+12)];
5748 decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */
5749 decNumber *a=bufa; /* accumulator/work */
5750 decNumber bufb[D2N(DECBUFFER*2+2)];
5751 decNumber *allocbufb=NULL; /* -> allocated bufa, iff allocated */
5752 decNumber *b=bufb; /* adjustment/work */
5754 decNumber numone; /* constant 1 */
5755 decNumber cmp; /* work */
5756 decContext aset, bset; /* working contexts */
5758 #if DECCHECK
5759 Int iterations=0; /* for later sanity check */
5760 if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
5761 #endif
5763 do { /* protect allocated storage */
5764 if (SPECIALARG) { /* handle infinities and NaNs */
5765 if (decNumberIsInfinite(rhs)) { /* an infinity */
5766 if (decNumberIsNegative(rhs)) /* -Infinity -> error */
5767 *status|=DEC_Invalid_operation;
5768 else decNumberCopy(res, rhs); /* +Infinity -> self */
5770 else decNaNs(res, rhs, NULL, set, status); /* a NaN */
5771 break;}
5773 if (ISZERO(rhs)) { /* +/- zeros -> -Infinity */
5774 decNumberZero(res); /* make clean */
5775 res->bits=DECINF|DECNEG; /* set - infinity */
5776 break;} /* [no status to set] */
5778 /* Non-zero negatives are bad... */
5779 if (decNumberIsNegative(rhs)) { /* -x -> error */
5780 *status|=DEC_Invalid_operation;
5781 break;}
5783 /* Here, rhs is positive, finite, and in range */
5785 /* lookaside fastpath code for ln(2) and ln(10) at common lengths */
5786 if (rhs->exponent==0 && set->digits<=40) {
5787 #if DECDPUN==1
5788 if (rhs->lsu[0]==0 && rhs->lsu[1]==1 && rhs->digits==2) { /* ln(10) */
5789 #else
5790 if (rhs->lsu[0]==10 && rhs->digits==2) { /* ln(10) */
5791 #endif
5792 aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
5793 #define LN10 "2.302585092994045684017991454684364207601"
5794 decNumberFromString(res, LN10, &aset);
5795 *status|=(DEC_Inexact | DEC_Rounded); /* is inexact */
5796 break;}
5797 if (rhs->lsu[0]==2 && rhs->digits==1) { /* ln(2) */
5798 aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
5799 #define LN2 "0.6931471805599453094172321214581765680755"
5800 decNumberFromString(res, LN2, &aset);
5801 *status|=(DEC_Inexact | DEC_Rounded);
5802 break;}
5803 } /* integer and short */
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. */
5810 p=MAXI(rhs->digits, MAXI(set->digits, 7))+2;
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. */
5818 needbytes=sizeof(decNumber)+(D2U(MAXI(p,16))-1)*sizeof(Unit);
5819 if (needbytes>sizeof(bufa)) { /* need malloc space */
5820 allocbufa=(decNumber *)malloc(needbytes);
5821 if (allocbufa==NULL) { /* hopeless -- abandon */
5822 *status|=DEC_Insufficient_storage;
5823 break;}
5824 a=allocbufa; /* use the allocated space */
5826 pp=p+rhs->digits;
5827 needbytes=sizeof(decNumber)+(D2U(MAXI(pp,16))-1)*sizeof(Unit);
5828 if (needbytes>sizeof(bufb)) { /* need malloc space */
5829 allocbufb=(decNumber *)malloc(needbytes);
5830 if (allocbufb==NULL) { /* hopeless -- abandon */
5831 *status|=DEC_Insufficient_storage;
5832 break;}
5833 b=allocbufb; /* use the allocated space */
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. */
5845 decContextDefault(&aset, DEC_INIT_DECIMAL64); /* 16-digit extended */
5846 r=rhs->exponent+rhs->digits; /* 'normalised' exponent */
5847 decNumberFromInt32(a, r); /* a=r */
5848 decNumberFromInt32(b, 2302585); /* b=ln(10) (2.302585) */
5849 b->exponent=-6; /* .. */
5850 decMultiplyOp(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 */
5853 residue=0; /* (no residue) */
5854 aset.digits=2; aset.round=DEC_ROUND_DOWN;
5855 decCopyFit(b, rhs, &aset, &residue, &ignore); /* copy & shorten */
5856 b->exponent=0; /* make integer */
5857 t=decGetInt(b); /* [cannot fail] */
5858 if (t<10) t=X10(t); /* adjust single-digit b */
5859 t=LNnn[t-10]; /* look up ln(b) */
5860 decNumberFromInt32(b, t>>2); /* b=ln(b) coefficient */
5861 b->exponent=-(t&3)-3; /* set exponent */
5862 b->bits=DECNEG; /* ln(0.10)->ln(0.99) always -ve */
5863 aset.digits=16; aset.round=DEC_ROUND_HALF_EVEN; /* restore */
5864 decAddOp(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. */
5869 decNumberZero(&numone); *numone.lsu=1; /* constant 1 for adjustment */
5871 /* accumulator bounds are as requested (could underflow, but */
5872 /* cannot overflow) */
5873 aset.emax=set->emax;
5874 aset.emin=set->emin;
5875 aset.clamp=0; /* no concrete format */
5876 /* set up a context to be used for the multiply and subtract */
5877 bset=aset;
5878 bset.emax=DEC_MAX_MATH*2; /* use double bounds for the */
5879 bset.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 */
5883 pp=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] */
5886 aset.digits=pp; /* working context */
5887 bset.digits=pp+rhs->digits; /* wider context */
5888 for (;;) { /* iterate */
5889 #if DECCHECK
5890 iterations++;
5891 if (iterations>24) break; /* consider 9 * 2**24 */
5892 #endif
5893 /* 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. */
5898 a->bits^=DECNEG; /* make -a */
5899 decExpOp(b, a, &bset, &ignore); /* b=exp(-a) */
5900 a->bits^=DECNEG; /* restore sign of a */
5901 /* now multiply by rhs and subtract 1, at the wider precision */
5902 decMultiplyOp(b, b, rhs, &bset, &ignore); /* b=b*rhs */
5903 decAddOp(b, b, &numone, &bset, DECNEG, &ignore); /* b=b-1 */
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). */
5913 if (decNumberIsZero(b) ||
5914 (a->digits+a->exponent)>=(b->digits+b->exponent+set->digits+1)) {
5915 if (a->digits==p) break;
5916 if (decNumberIsZero(a)) {
5917 decCompareOp(&cmp, rhs, &numone, &aset, COMPARE, &ignore); /* rhs=1 ? */
5918 if (cmp.lsu[0]==0) a->exponent=0; /* yes, exact 0 */
5919 else *status|=(DEC_Inexact | DEC_Rounded); /* no, inexact */
5920 break;
5922 /* force padding if adjustment has gone to 0 before full length */
5923 if (decNumberIsZero(b)) b->exponent=a->exponent-p;
5926 /* not done yet ... */
5927 decAddOp(a, a, b, &aset, 0, &ignore); /* a=a+b for next estimate */
5928 if (pp==p) continue; /* precision is at maximum */
5929 /* lengthen the next calculation */
5930 pp=pp*2; /* double precision */
5931 if (pp>p) pp=p; /* clamp to maximum */
5932 aset.digits=pp; /* working context */
5933 bset.digits=pp+rhs->digits; /* wider context */
5934 } /* Newton's iteration */
5936 #if DECCHECK
5937 /* just a sanity check; remove the test to show always */
5938 if (iterations>24)
5939 printf("Ln iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
5940 iterations, *status, p, rhs->digits);
5941 #endif
5943 /* Copy and round the result to res */
5944 residue=1; /* indicate dirt to right */
5945 if (ISZERO(a)) residue=0; /* .. unless underflowed to 0 */
5946 aset.digits=set->digits; /* [use default rounding] */
5947 decCopyFit(res, a, &aset, &residue, status); /* copy & shorten */
5948 decFinish(res, set, &residue, status); /* cleanup/set flags */
5949 } while(0); /* end protected */
5951 if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */
5952 if (allocbufb!=NULL) free(allocbufb); /* .. */
5953 /* [status is handled by caller] */
5954 return res;
5955 } /* decLnOp */
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 /* ------------------------------------------------------------------ */
5979 static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs,
5980 const decNumber *rhs, decContext *set,
5981 Flag quant, uInt *status) {
5982 #if DECSUBSET
5983 decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */
5984 decNumber *allocrhs=NULL; /* .., rhs */
5985 #endif
5986 const decNumber *inrhs=rhs; /* save original rhs */
5987 Int reqdigits=set->digits; /* requested DIGITS */
5988 Int reqexp; /* requested exponent [-scale] */
5989 Int residue=0; /* rounding residue */
5990 Int etiny=set->emin-(reqdigits-1);
5992 #if DECCHECK
5993 if (decCheckOperands(res, lhs, rhs, set)) return res;
5994 #endif
5996 do { /* protect allocated storage */
5997 #if DECSUBSET
5998 if (!set->extended) {
5999 /* reduce operands and set lostDigits status, as needed */
6000 if (lhs->digits>reqdigits) {
6001 alloclhs=decRoundOperand(lhs, set, status);
6002 if (alloclhs==NULL) break;
6003 lhs=alloclhs;
6005 if (rhs->digits>reqdigits) { /* [this only checks lostDigits] */
6006 allocrhs=decRoundOperand(rhs, set, status);
6007 if (allocrhs==NULL) break;
6008 rhs=allocrhs;
6011 #endif
6012 /* [following code does not require input rounding] */
6014 /* Handle special values */
6015 if (SPECIALARGS) {
6016 /* NaNs get usual processing */
6017 if (SPECIALARGS & (DECSNAN | DECNAN))
6018 decNaNs(res, lhs, rhs, set, status);
6019 /* one infinity but not both is bad */
6020 else if ((lhs->bits ^ rhs->bits) & DECINF)
6021 *status|=DEC_Invalid_operation;
6022 /* both infinity: return lhs */
6023 else decNumberCopy(res, lhs); /* [nop if in place] */
6024 break;
6027 /* set requested exponent */
6028 if (quant) reqexp=inrhs->exponent; /* quantize -- match exponents */
6029 else { /* 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 */
6033 reqexp=decGetInt(inrhs); /* [cannot fail] */
6036 #if DECSUBSET
6037 if (!set->extended) etiny=set->emin; /* no subnormals */
6038 #endif
6040 if (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;
6045 break;}
6047 /* the RHS has been processed, so it can be overwritten now if necessary */
6048 if (ISZERO(lhs)) { /* zero coefficient unchanged */
6049 decNumberCopy(res, lhs); /* [nop if in place] */
6050 res->exponent=reqexp; /* .. just set exponent */
6051 #if DECSUBSET
6052 if (!set->extended) res->bits=0; /* subset specification; no -0 */
6053 #endif
6055 else { /* non-zero lhs */
6056 Int adjust=reqexp-lhs->exponent; /* digit adjustment needed */
6057 /* if adjusted coefficient will definitely not fit, give up now */
6058 if ((lhs->digits-adjust)>reqdigits) {
6059 *status|=DEC_Invalid_operation;
6060 break;
6063 if (adjust>0) { /* increasing exponent */
6064 /* this will decrease the length of the coefficient by adjust */
6065 /* digits, and must round as it does so */
6066 decContext workset; /* work */
6067 workset=*set; /* clone rounding, etc. */
6068 workset.digits=lhs->digits-adjust; /* set requested length */
6069 /* [note that the latter can be <1, here] */
6070 decCopyFit(res, lhs, &workset, &residue, status); /* fit to result */
6071 decApplyRound(res, &workset, residue, status); /* .. and round */
6072 residue=0; /* [used] */
6073 /* If just rounded a 999s case, exponent will be off by one; */
6074 /* adjust back (after checking space), if so. */
6075 if (res->exponent>reqexp) {
6076 /* re-check needed, e.g., for quantize(0.9999, 0.001) under */
6077 /* set->digits==3 */
6078 if (res->digits==reqdigits) { /* cannot shift by 1 */
6079 *status&=~(DEC_Inexact | DEC_Rounded); /* [clean these] */
6080 *status|=DEC_Invalid_operation;
6081 break;
6083 res->digits=decShiftToMost(res->lsu, res->digits, 1); /* shift */
6084 res->exponent--; /* (re)adjust the exponent. */
6086 #if DECSUBSET
6087 if (ISZERO(res) && !set->extended) res->bits=0; /* subset; no -0 */
6088 #endif
6089 } /* increase */
6090 else /* 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 */
6094 decNumberCopy(res, lhs); /* [it will fit] */
6095 /* if padding needed (adjust<0), add it now... */
6096 if (adjust<0) {
6097 res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
6098 res->exponent+=adjust; /* adjust the exponent */
6100 } /* decrease */
6101 } /* non-zero */
6103 /* Check for overflow [do not use Finalize in this case, as an */
6104 /* overflow here is a "don't fit" situation] */
6105 if (res->exponent>set->emax-res->digits+1) { /* too big */
6106 *status|=DEC_Invalid_operation;
6107 break;
6109 else {
6110 decFinalize(res, set, &residue, status); /* set subnormal flags */
6111 *status&=~DEC_Underflow; /* suppress Underflow [754r] */
6113 } while(0); /* end protected */
6115 #if DECSUBSET
6116 if (allocrhs!=NULL) free(allocrhs); /* drop any storage used */
6117 if (alloclhs!=NULL) free(alloclhs); /* .. */
6118 #endif
6119 return res;
6120 } /* decQuantizeOp */
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 /* ------------------------------------------------------------------ */
6152 static decNumber *decCompareOp(decNumber *res, const decNumber *lhs,
6153 const decNumber *rhs, decContext *set,
6154 Flag op, uInt *status) {
6155 #if DECSUBSET
6156 decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */
6157 decNumber *allocrhs=NULL; /* .., rhs */
6158 #endif
6159 Int result=0; /* default result value */
6160 uByte merged; /* work */
6162 #if DECCHECK
6163 if (decCheckOperands(res, lhs, rhs, set)) return res;
6164 #endif
6166 do { /* protect allocated storage */
6167 #if DECSUBSET
6168 if (!set->extended) {
6169 /* reduce operands and set lostDigits status, as needed */
6170 if (lhs->digits>set->digits) {
6171 alloclhs=decRoundOperand(lhs, set, status);
6172 if (alloclhs==NULL) {result=BADINT; break;}
6173 lhs=alloclhs;
6175 if (rhs->digits>set->digits) {
6176 allocrhs=decRoundOperand(rhs, set, status);
6177 if (allocrhs==NULL) {result=BADINT; break;}
6178 rhs=allocrhs;
6181 #endif
6182 /* [following code does not require input rounding] */
6184 /* If total ordering then handle differing signs 'up front' */
6185 if (op==COMPTOTAL) { /* total ordering */
6186 if (decNumberIsNegative(lhs) && !decNumberIsNegative(rhs)) {
6187 result=-1;
6188 break;
6190 if (!decNumberIsNegative(lhs) && decNumberIsNegative(rhs)) {
6191 result=+1;
6192 break;
6196 /* handle NaNs specially; let infinities drop through */
6197 /* This assumes sNaN (even just one) leads to NaN. */
6198 merged=(lhs->bits | rhs->bits) & (DECSNAN | DECNAN);
6199 if (merged) { /* a NaN bit set */
6200 if (op==COMPARE); /* result will be NaN */
6201 else if (op==COMPSIG) /* treat qNaN as sNaN */
6202 *status|=DEC_Invalid_operation | DEC_sNaN;
6203 else 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 */
6206 if (!decNumberIsNaN(lhs)) result=-1;
6207 else if (!decNumberIsNaN(rhs)) result=+1;
6208 /* here if both NaNs */
6209 else if (decNumberIsSNaN(lhs) && decNumberIsQNaN(rhs)) result=-1;
6210 else if (decNumberIsQNaN(lhs) && decNumberIsSNaN(rhs)) result=+1;
6211 else { /* both NaN or both sNaN */
6212 /* now it just depends on the payload */
6213 result=decUnitCompare(lhs->lsu, D2U(lhs->digits),
6214 rhs->lsu, D2U(rhs->digits), 0);
6215 /* [Error not possible, as these are 'aligned'] */
6216 } /* both same NaNs */
6217 if (decNumberIsNegative(lhs)) result=-result;
6218 break;
6219 } /* total order */
6221 else if (merged & DECSNAN); /* sNaN -> qNaN */
6222 else { /* here if MIN or MAX and one or two quiet NaNs */
6223 /* min or max -- 754r rules ignore single NaN */
6224 if (!decNumberIsNaN(lhs) || !decNumberIsNaN(rhs)) {
6225 /* just one NaN; force choice to be the non-NaN operand */
6226 op=COMPMAX;
6227 if (lhs->bits & DECNAN) result=-1; /* pick rhs */
6228 else result=+1; /* pick lhs */
6229 break;
6231 } /* max or min */
6232 op=COMPNAN; /* use special path */
6233 decNaNs(res, lhs, rhs, set, status); /* propagate NaN */
6234 break;
6236 /* have numbers */
6237 if (op==COMPMAXMAG || op==COMPMINMAG) result=decCompare(lhs, rhs, 1);
6238 else result=decCompare(lhs, rhs, 0); /* sign matters */
6239 } while(0); /* end protected */
6241 if (result==BADINT) *status|=DEC_Insufficient_storage; /* rare */
6242 else {
6243 if (op==COMPARE || op==COMPSIG ||op==COMPTOTAL) { /* returning signum */
6244 if (op==COMPTOTAL && result==0) {
6245 /* operands are numerically equal or same NaN (and same sign, */
6246 /* tested first); if identical, leave result 0 */
6247 if (lhs->exponent!=rhs->exponent) {
6248 if (lhs->exponent<rhs->exponent) result=-1;
6249 else result=+1;
6250 if (decNumberIsNegative(lhs)) result=-result;
6251 } /* lexp!=rexp */
6252 } /* total-order by exponent */
6253 decNumberZero(res); /* [always a valid result] */
6254 if (result!=0) { /* must be -1 or +1 */
6255 *res->lsu=1;
6256 if (result<0) res->bits=DECNEG;
6259 else if (op==COMPNAN); /* special, drop through */
6260 else { /* MAX or MIN, non-NaN result */
6261 Int residue=0; /* rounding accumulator */
6262 /* choose the operand for the result */
6263 const decNumber *choice;
6264 if (result==0) { /* operands are numerically equal */
6265 /* choose according to sign then exponent (see 754r) */
6266 uByte slhs=(lhs->bits & DECNEG);
6267 uByte srhs=(rhs->bits & DECNEG);
6268 #if DECSUBSET
6269 if (!set->extended) { /* subset: force left-hand */
6270 op=COMPMAX;
6271 result=+1;
6273 else
6274 #endif
6275 if (slhs!=srhs) { /* signs differ */
6276 if (slhs) result=-1; /* rhs is max */
6277 else result=+1; /* lhs is max */
6279 else if (slhs && srhs) { /* both negative */
6280 if (lhs->exponent<rhs->exponent) result=+1;
6281 else result=-1;
6282 /* [if equal, use lhs, technically identical] */
6284 else { /* both positive */
6285 if (lhs->exponent>rhs->exponent) result=+1;
6286 else result=-1;
6287 /* [ditto] */
6289 } /* numerically equal */
6290 /* here result will be non-0; reverse if looking for MIN */
6291 if (op==COMPMIN || op==COMPMINMAG) result=-result;
6292 choice=(result>0 ? lhs : rhs); /* choose */
6293 /* copy chosen to result, rounding if need be */
6294 decCopyFit(res, choice, set, &residue, status);
6295 decFinish(res, set, &residue, status);
6298 #if DECSUBSET
6299 if (allocrhs!=NULL) free(allocrhs); /* free any storage used */
6300 if (alloclhs!=NULL) free(alloclhs); /* .. */
6301 #endif
6302 return res;
6303 } /* decCompareOp */
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 /* ------------------------------------------------------------------ */
6317 static Int decCompare(const decNumber *lhs, const decNumber *rhs,
6318 Flag abs) {
6319 Int result; /* result value */
6320 Int sigr; /* rhs signum */
6321 Int compare; /* work */
6323 result=1; /* assume signum(lhs) */
6324 if (ISZERO(lhs)) result=0;
6325 if (abs) {
6326 if (ISZERO(rhs)) return result; /* LHS wins or both 0 */
6327 /* RHS is non-zero */
6328 if (result==0) return -1; /* LHS is 0; RHS wins */
6329 /* [here, both non-zero, result=1] */
6331 else { /* signs matter */
6332 if (result && decNumberIsNegative(lhs)) result=-1;
6333 sigr=1; /* compute signum(rhs) */
6334 if (ISZERO(rhs)) sigr=0;
6335 else if (decNumberIsNegative(rhs)) sigr=-1;
6336 if (result > sigr) return +1; /* L > R, return 1 */
6337 if (result < sigr) return -1; /* L < R, return -1 */
6338 if (result==0) return 0; /* both 0 */
6341 /* signums are the same; both are non-zero */
6342 if ((lhs->bits | rhs->bits) & DECINF) { /* one or more infinities */
6343 if (decNumberIsInfinite(rhs)) {
6344 if (decNumberIsInfinite(lhs)) result=0;/* both infinite */
6345 else result=-result; /* only rhs infinite */
6347 return result;
6349 /* must compare the coefficients, allowing for exponents */
6350 if (lhs->exponent>rhs->exponent) { /* LHS exponent larger */
6351 /* swap sides, and sign */
6352 const decNumber *temp=lhs;
6353 lhs=rhs;
6354 rhs=temp;
6355 result=-result;
6357 compare=decUnitCompare(lhs->lsu, D2U(lhs->digits),
6358 rhs->lsu, D2U(rhs->digits),
6359 rhs->exponent-lhs->exponent);
6360 if (compare!=BADINT) compare*=result; /* comparison succeeded */
6361 return compare;
6362 } /* decCompare */
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 /* ------------------------------------------------------------------ */
6381 static Int decUnitCompare(const Unit *a, Int alength,
6382 const Unit *b, Int blength, Int exp) {
6383 Unit *acc; /* accumulator for result */
6384 Unit accbuff[SD2U(DECBUFFER*2+1)]; /* local buffer */
6385 Unit *allocacc=NULL; /* -> allocated acc buffer, iff allocated */
6386 Int accunits, need; /* units in use or needed for acc */
6387 const Unit *l, *r, *u; /* work */
6388 Int expunits, exprem, result; /* .. */
6390 if (exp==0) { /* aligned; fastpath */
6391 if (alength>blength) return 1;
6392 if (alength<blength) return -1;
6393 /* same number of units in both -- need unit-by-unit compare */
6394 l=a+alength-1;
6395 r=b+alength-1;
6396 for (;l>=a; l--, r--) {
6397 if (*l>*r) return 1;
6398 if (*l<*r) return -1;
6400 return 0; /* all units match */
6401 } /* aligned */
6403 /* Unaligned. If one is >1 unit longer than the other, padded */
6404 /* approximately, then can return easily */
6405 if (alength>blength+(Int)D2U(exp)) return 1;
6406 if (alength+1<blength+(Int)D2U(exp)) return -1;
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 */
6411 need=blength+D2U(exp); /* maximum real length of B */
6412 if (need<alength) need=alength;
6413 need+=2;
6414 acc=accbuff; /* assume use local buffer */
6415 if (need*sizeof(Unit)>sizeof(accbuff)) {
6416 allocacc=(Unit *)malloc(need*sizeof(Unit));
6417 if (allocacc==NULL) return BADINT; /* hopeless -- abandon */
6418 acc=allocacc;
6420 /* Calculate units and remainder from exponent. */
6421 expunits=exp/DECDPUN;
6422 exprem=exp%DECDPUN;
6423 /* subtract [A+B*(-m)] */
6424 accunits=decUnitAddSub(a, alength, b, blength, expunits, acc,
6425 -(Int)powers[exprem]);
6426 /* [UnitAddSub result may have leading zeros, even on zero] */
6427 if (accunits<0) result=-1; /* negative result */
6428 else { /* non-negative result */
6429 /* check units of the result before freeing any storage */
6430 for (u=acc; u<acc+accunits-1 && *u==0;) u++;
6431 result=(*u==0 ? 0 : +1);
6433 /* clean up and return the result */
6434 if (allocacc!=NULL) free(allocacc); /* drop any storage used */
6435 return result;
6436 } /* decUnitCompare */
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 /* ------------------------------------------------------------------ */
6485 static Int decUnitAddSub(const Unit *a, Int alength,
6486 const Unit *b, Int blength, Int bshift,
6487 Unit *c, Int m) {
6488 const Unit *alsu=a; /* A lsu [need to remember it] */
6489 Unit *clsu=c; /* C ditto */
6490 Unit *minC; /* low water mark for C */
6491 Unit *maxC; /* high water mark for C */
6492 eInt carry=0; /* carry integer (could be Long) */
6493 Int add; /* work */
6494 #if DECDPUN<=4 /* myriadal, millenary, etc. */
6495 Int est; /* estimated quotient */
6496 #endif
6498 #if DECTRACE
6499 if (alength<1 || blength<1)
6500 printf("decUnitAddSub: alen blen m %ld %ld [%ld]\n", alength, blength, m);
6501 #endif
6503 maxC=c+alength; /* A is usually the longer */
6504 minC=c+blength; /* .. and B the shorter */
6505 if (bshift!=0) { /* B is shifted; low As copy across */
6506 minC+=bshift;
6507 /* if in place [common], skip copy unless there's a gap [rare] */
6508 if (a==c && bshift<=alength) {
6509 c+=bshift;
6510 a+=bshift;
6512 else for (; c<clsu+bshift; a++, c++) { /* copy needed */
6513 if (a<alsu+alength) *c=*a;
6514 else *c=0;
6517 if (minC>maxC) { /* swap */
6518 Unit *hold=minC;
6519 minC=maxC;
6520 maxC=hold;
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. */
6527 for (; c<minC; c++) {
6528 carry+=*a;
6529 a++;
6530 carry+=((eInt)*b)*m; /* [special-casing m=1/-1 */
6531 b++; /* here is not a win] */
6532 /* here carry is new Unit of digits; it could be +ve or -ve */
6533 if ((ueInt)carry<=DECDPUNMAX) { /* fastpath 0-DECDPUNMAX */
6534 *c=(Unit)carry;
6535 carry=0;
6536 continue;
6538 #if DECDPUN==4 /* use divide-by-multiply */
6539 if (carry>=0) {
6540 est=(((ueInt)carry>>11)*53687)>>18;
6541 *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */
6542 carry=est; /* likely quotient [89%] */
6543 if (*c<DECDPUNMAX+1) continue; /* estimate was correct */
6544 carry++;
6545 *c-=DECDPUNMAX+1;
6546 continue;
6548 /* negative case */
6549 carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */
6550 est=(((ueInt)carry>>11)*53687)>>18;
6551 *c=(Unit)(carry-est*(DECDPUNMAX+1));
6552 carry=est-(DECDPUNMAX+1); /* correctly negative */
6553 if (*c<DECDPUNMAX+1) continue; /* was OK */
6554 carry++;
6555 *c-=DECDPUNMAX+1;
6556 #elif DECDPUN==3
6557 if (carry>=0) {
6558 est=(((ueInt)carry>>3)*16777)>>21;
6559 *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */
6560 carry=est; /* likely quotient [99%] */
6561 if (*c<DECDPUNMAX+1) continue; /* estimate was correct */
6562 carry++;
6563 *c-=DECDPUNMAX+1;
6564 continue;
6566 /* negative case */
6567 carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */
6568 est=(((ueInt)carry>>3)*16777)>>21;
6569 *c=(Unit)(carry-est*(DECDPUNMAX+1));
6570 carry=est-(DECDPUNMAX+1); /* correctly negative */
6571 if (*c<DECDPUNMAX+1) continue; /* was OK */
6572 carry++;
6573 *c-=DECDPUNMAX+1;
6574 #elif DECDPUN<=2
6575 /* Can use QUOT10 as carry <= 4 digits */
6576 if (carry>=0) {
6577 est=QUOT10(carry, DECDPUN);
6578 *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */
6579 carry=est; /* quotient */
6580 continue;
6582 /* negative case */
6583 carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */
6584 est=QUOT10(carry, DECDPUN);
6585 *c=(Unit)(carry-est*(DECDPUNMAX+1));
6586 carry=est-(DECDPUNMAX+1); /* correctly negative */
6587 #else
6588 /* remainder operator is undefined if negative, so must test */
6589 if ((ueInt)carry<(DECDPUNMAX+1)*2) { /* fastpath carry +1 */
6590 *c=(Unit)(carry-(DECDPUNMAX+1)); /* [helps additions] */
6591 carry=1;
6592 continue;
6594 if (carry>=0) {
6595 *c=(Unit)(carry%(DECDPUNMAX+1));
6596 carry=carry/(DECDPUNMAX+1);
6597 continue;
6599 /* negative case */
6600 carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */
6601 *c=(Unit)(carry%(DECDPUNMAX+1));
6602 carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);
6603 #endif
6604 } /* c */
6606 /* now may have one or other to complete */
6607 /* [pretest to avoid loop setup/shutdown] */
6608 if (c<maxC) for (; c<maxC; c++) {
6609 if (a<alsu+alength) { /* still in A */
6610 carry+=*a;
6611 a++;
6613 else { /* inside B */
6614 carry+=((eInt)*b)*m;
6615 b++;
6617 /* here carry is new Unit of digits; it could be +ve or -ve and */
6618 /* magnitude up to DECDPUNMAX squared */
6619 if ((ueInt)carry<=DECDPUNMAX) { /* fastpath 0-DECDPUNMAX */
6620 *c=(Unit)carry;
6621 carry=0;
6622 continue;
6624 /* result for this unit is negative or >DECDPUNMAX */
6625 #if DECDPUN==4 /* use divide-by-multiply */
6626 if (carry>=0) {
6627 est=(((ueInt)carry>>11)*53687)>>18;
6628 *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */
6629 carry=est; /* likely quotient [79.7%] */
6630 if (*c<DECDPUNMAX+1) continue; /* estimate was correct */
6631 carry++;
6632 *c-=DECDPUNMAX+1;
6633 continue;
6635 /* negative case */
6636 carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */
6637 est=(((ueInt)carry>>11)*53687)>>18;
6638 *c=(Unit)(carry-est*(DECDPUNMAX+1));
6639 carry=est-(DECDPUNMAX+1); /* correctly negative */
6640 if (*c<DECDPUNMAX+1) continue; /* was OK */
6641 carry++;
6642 *c-=DECDPUNMAX+1;
6643 #elif DECDPUN==3
6644 if (carry>=0) {
6645 est=(((ueInt)carry>>3)*16777)>>21;
6646 *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */
6647 carry=est; /* likely quotient [99%] */
6648 if (*c<DECDPUNMAX+1) continue; /* estimate was correct */
6649 carry++;
6650 *c-=DECDPUNMAX+1;
6651 continue;
6653 /* negative case */
6654 carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */
6655 est=(((ueInt)carry>>3)*16777)>>21;
6656 *c=(Unit)(carry-est*(DECDPUNMAX+1));
6657 carry=est-(DECDPUNMAX+1); /* correctly negative */
6658 if (*c<DECDPUNMAX+1) continue; /* was OK */
6659 carry++;
6660 *c-=DECDPUNMAX+1;
6661 #elif DECDPUN<=2
6662 if (carry>=0) {
6663 est=QUOT10(carry, DECDPUN);
6664 *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */
6665 carry=est; /* quotient */
6666 continue;
6668 /* negative case */
6669 carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */
6670 est=QUOT10(carry, DECDPUN);
6671 *c=(Unit)(carry-est*(DECDPUNMAX+1));
6672 carry=est-(DECDPUNMAX+1); /* correctly negative */
6673 #else
6674 if ((ueInt)carry<(DECDPUNMAX+1)*2){ /* fastpath carry 1 */
6675 *c=(Unit)(carry-(DECDPUNMAX+1));
6676 carry=1;
6677 continue;
6679 /* remainder operator is undefined if negative, so must test */
6680 if (carry>=0) {
6681 *c=(Unit)(carry%(DECDPUNMAX+1));
6682 carry=carry/(DECDPUNMAX+1);
6683 continue;
6685 /* negative case */
6686 carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */
6687 *c=(Unit)(carry%(DECDPUNMAX+1));
6688 carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);
6689 #endif
6690 } /* c */
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 */
6694 if (carry==0) return c-clsu; /* no carry, so no more to do */
6695 if (carry>0) { /* positive carry */
6696 *c=(Unit)carry; /* place as new unit */
6697 c++; /* .. */
6698 return c-clsu;
6700 /* -ve carry: it's a borrow; complement needed */
6701 add=1; /* temporary carry... */
6702 for (c=clsu; c<maxC; c++) {
6703 add=DECDPUNMAX+add-*c;
6704 if (add<=DECDPUNMAX) {
6705 *c=(Unit)add;
6706 add=0;
6708 else {
6709 *c=0;
6710 add=1;
6713 /* add an extra unit iff it would be non-zero */
6714 #if DECTRACE
6715 printf("UAS borrow: add %ld, carry %ld\n", add, carry);
6716 #endif
6717 if ((add-carry-1)!=0) {
6718 *c=(Unit)(add-carry-1);
6719 c++; /* interesting, include it */
6721 return clsu-c; /* -ve result indicates borrowed */
6722 } /* decUnitAddSub */
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 /* ------------------------------------------------------------------ */
6738 static decNumber * decTrim(decNumber *dn, decContext *set, Flag all,
6739 Int *dropped) {
6740 Int d, exp; /* work */
6741 uInt cut; /* .. */
6742 Unit *up; /* -> current Unit */
6744 #if DECCHECK
6745 if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
6746 #endif
6748 *dropped=0; /* assume no zeros dropped */
6749 if ((dn->bits & DECSPECIAL) /* fast exit if special .. */
6750 || (*dn->lsu & 0x01)) return dn; /* .. or odd */
6751 if (ISZERO(dn)) { /* .. or 0 */
6752 dn->exponent=0; /* (sign is preserved) */
6753 return dn;
6756 /* have a finite number which is even */
6757 exp=dn->exponent;
6758 cut=1; /* digit (1-DECDPUN) in Unit */
6759 up=dn->lsu; /* -> current Unit */
6760 for (d=0; d<dn->digits-1; d++) { /* [don't strip the final digit] */
6761 /* slice by powers */
6762 #if DECDPUN<=4
6763 uInt quot=QUOT10(*up, cut);
6764 if ((*up-quot*powers[cut])!=0) break; /* found non-0 digit */
6765 #else
6766 if (*up%powers[cut]!=0) break; /* found non-0 digit */
6767 #endif
6768 /* have a trailing 0 */
6769 if (!all) { /* trimming */
6770 /* [if exp>0 then all trailing 0s are significant for trim] */
6771 if (exp<=0) { /* if digit might be significant */
6772 if (exp==0) break; /* then quit */
6773 exp++; /* next digit might be significant */
6776 cut++; /* next power */
6777 if (cut>DECDPUN) { /* need new Unit */
6778 up++;
6779 cut=1;
6781 } /* d */
6782 if (d==0) return dn; /* none to drop */
6784 /* may need to limit drop if clamping */
6785 if (set->clamp) {
6786 Int maxd=set->emax-set->digits+1-dn->exponent;
6787 if (maxd<=0) return dn; /* nothing possible */
6788 if (d>maxd) d=maxd;
6791 /* effect the drop */
6792 decShiftToLeast(dn->lsu, D2U(dn->digits), d);
6793 dn->exponent+=d; /* maintain numerical value */
6794 dn->digits-=d; /* new length */
6795 *dropped=d; /* report the count */
6796 return dn;
6797 } /* decTrim */
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 /* ------------------------------------------------------------------ */
6809 static void decReverse(Unit *ulo, Unit *uhi) {
6810 Unit temp;
6811 for (; ulo<uhi; ulo++, uhi--) {
6812 temp=*ulo;
6813 *ulo=*uhi;
6814 *uhi=temp;
6816 return;
6817 } /* decReverse */
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 /* ------------------------------------------------------------------ */
6832 static Int decShiftToMost(Unit *uar, Int digits, Int shift) {
6833 Unit *target, *source, *first; /* work */
6834 Int cut; /* odd 0's to add */
6835 uInt next; /* work */
6837 if (shift==0) return digits; /* [fastpath] nothing to do */
6838 if ((digits+shift)<=DECDPUN) { /* [fastpath] single-unit case */
6839 *uar=(Unit)(*uar*powers[shift]);
6840 return digits+shift;
6843 next=0; /* all paths */
6844 source=uar+D2U(digits)-1; /* where msu comes from */
6845 target=source+D2U(shift); /* where upper part of first cut goes */
6846 cut=DECDPUN-MSUDIGITS(shift); /* where to slice */
6847 if (cut==0) { /* unit-boundary case */
6848 for (; source>=uar; source--, target--) *target=*source;
6850 else {
6851 first=uar+D2U(digits+shift)-1; /* where msu of source will end up */
6852 for (; source>=uar; source--, target--) {
6853 /* split the source Unit and accumulate remainder for next */
6854 #if DECDPUN<=4
6855 uInt quot=QUOT10(*source, cut);
6856 uInt rem=*source-quot*powers[cut];
6857 next+=quot;
6858 #else
6859 uInt rem=*source%powers[cut];
6860 next+=*source/powers[cut];
6861 #endif
6862 if (target<=first) *target=(Unit)next; /* write to target iff valid */
6863 next=rem*powers[DECDPUN-cut]; /* save remainder for next Unit */
6865 } /* shift-move */
6867 /* propagate any partial unit to one below and clear the rest */
6868 for (; target>=uar; target--) {
6869 *target=(Unit)next;
6870 next=0;
6872 return digits+shift;
6873 } /* decShiftToMost */
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 /* ------------------------------------------------------------------ */
6888 static Int decShiftToLeast(Unit *uar, Int units, Int shift) {
6889 Unit *target, *up; /* work */
6890 Int cut, count; /* work */
6891 Int quot, rem; /* for division */
6893 if (shift==0) return units; /* [fastpath] nothing to do */
6894 if (shift==units*DECDPUN) { /* [fastpath] little to do */
6895 *uar=0; /* all digits cleared gives zero */
6896 return 1; /* leaves just the one */
6899 target=uar; /* both paths */
6900 cut=MSUDIGITS(shift);
6901 if (cut==DECDPUN) { /* unit-boundary case; easy */
6902 up=uar+D2U(shift);
6903 for (; up<uar+units; target++, up++) *target=*up;
6904 return target-uar;
6907 /* messier */
6908 up=uar+D2U(shift-cut); /* source; correct to whole Units */
6909 count=units*DECDPUN-shift; /* the maximum new length */
6910 #if DECDPUN<=4
6911 quot=QUOT10(*up, cut);
6912 #else
6913 quot=*up/powers[cut];
6914 #endif
6915 for (; ; target++) {
6916 *target=(Unit)quot;
6917 count-=(DECDPUN-cut);
6918 if (count<=0) break;
6919 up++;
6920 quot=*up;
6921 #if DECDPUN<=4
6922 quot=QUOT10(quot, cut);
6923 rem=*up-quot*powers[cut];
6924 #else
6925 rem=quot%powers[cut];
6926 quot=quot/powers[cut];
6927 #endif
6928 *target=(Unit)(*target+rem*powers[DECDPUN-cut]);
6929 count-=cut;
6930 if (count<=0) break;
6932 return target-uar+1;
6933 } /* decShiftToLeast */
6935 #if DECSUBSET
6936 /* ------------------------------------------------------------------ */
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 /* ------------------------------------------------------------------ */
6954 static decNumber *decRoundOperand(const decNumber *dn, decContext *set,
6955 uInt *status) {
6956 decNumber *res; /* result structure */
6957 uInt newstatus=0; /* status from round */
6958 Int residue=0; /* rounding accumulator */
6960 /* Allocate storage for the returned decNumber, big enough for the */
6961 /* length specified by the context */
6962 res=(decNumber *)malloc(sizeof(decNumber)
6963 +(D2U(set->digits)-1)*sizeof(Unit));
6964 if (res==NULL) {
6965 *status|=DEC_Insufficient_storage;
6966 return NULL;
6968 decCopyFit(res, dn, set, &residue, &newstatus);
6969 decApplyRound(res, set, residue, &newstatus);
6971 /* If that set Inexact then "lost digits" is raised... */
6972 if (newstatus & DEC_Inexact) newstatus|=DEC_Lost_digits;
6973 *status|=newstatus;
6974 return res;
6975 } /* decRoundOperand */
6976 #endif
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 /* ------------------------------------------------------------------ */
6990 static void decCopyFit(decNumber *dest, const decNumber *src,
6991 decContext *set, Int *residue, uInt *status) {
6992 dest->bits=src->bits;
6993 dest->exponent=src->exponent;
6994 decSetCoeff(dest, set, src->lsu, src->digits, residue, status);
6995 } /* decCopyFit */
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 */
7035 static const uByte resmap[10]={0, 3, 3, 3, 3, 5, 7, 7, 7, 7};
7036 static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu,
7037 Int len, Int *residue, uInt *status) {
7038 Int discard; /* number of digits to discard */
7039 uInt cut; /* cut point in Unit */
7040 const Unit *up; /* work */
7041 Unit *target; /* .. */
7042 Int count; /* .. */
7043 #if DECDPUN<=4
7044 uInt temp; /* .. */
7045 #endif
7047 discard=len-set->digits; /* digits to discard */
7048 if (discard<=0) { /* no digits are being discarded */
7049 if (dn->lsu!=lsu) { /* copy needed */
7050 /* copy the coefficient array to the result number; no shift needed */
7051 count=len; /* avoids D2U */
7052 up=lsu;
7053 for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
7054 *target=*up;
7055 dn->digits=len; /* set the new length */
7057 /* dn->exponent and residue are unchanged, record any inexactitude */
7058 if (*residue!=0) *status|=(DEC_Inexact | DEC_Rounded);
7059 return;
7062 /* some digits must be discarded ... */
7063 dn->exponent+=discard; /* maintain numerical value */
7064 *status|=DEC_Rounded; /* accumulate Rounded status */
7065 if (*residue>1) *residue=1; /* previous residue now to right, so reduce */
7067 if (discard>len) { /* everything, +1, is being discarded */
7068 /* guard digit is 0 */
7069 /* residue is all the number [NB could be all 0s] */
7070 if (*residue<=0) { /* not already positive */
7071 count=len; /* avoids D2U */
7072 for (up=lsu; count>0; up++, count-=DECDPUN) if (*up!=0) { /* found non-0 */
7073 *residue=1;
7074 break; /* no need to check any others */
7077 if (*residue!=0) *status|=DEC_Inexact; /* record inexactitude */
7078 *dn->lsu=0; /* coefficient will now be 0 */
7079 dn->digits=1; /* .. */
7080 return;
7081 } /* total discard */
7083 /* partial discard [most common case] */
7084 /* here, at least the first (most significant) discarded digit exists */
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 */
7089 count=0;
7090 for (up=lsu;; up++) {
7091 count+=DECDPUN;
7092 if (count>=discard) break; /* full ones all checked */
7093 if (*up!=0) *residue=1;
7094 } /* up */
7096 /* here up -> Unit with first discarded digit */
7097 cut=discard-(count-DECDPUN)-1;
7098 if (cut==DECDPUN-1) { /* unit-boundary case (fast) */
7099 Unit half=(Unit)powers[DECDPUN]>>1;
7100 /* set residue directly */
7101 if (*up>=half) {
7102 if (*up>half) *residue=7;
7103 else *residue+=5; /* add sticky bit */
7105 else { /* <half */
7106 if (*up!=0) *residue=3; /* [else is 0, leave as sticky bit] */
7108 if (set->digits<=0) { /* special for Quantize/Subnormal :-( */
7109 *dn->lsu=0; /* .. result is 0 */
7110 dn->digits=1; /* .. */
7112 else { /* shift to least */
7113 count=set->digits; /* now digits to end up with */
7114 dn->digits=count; /* set the new length */
7115 up++; /* move to next */
7116 /* on unit boundary, so shift-down copy loop is simple */
7117 for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
7118 *target=*up;
7120 } /* unit-boundary case */
7122 else { /* discard digit is in low digit(s), and not top digit */
7123 uInt discard1; /* first discarded digit */
7124 uInt quot, rem; /* for divisions */
7125 if (cut==0) quot=*up; /* is at bottom of unit */
7126 else /* cut>0 */ { /* it's not at bottom of unit */
7127 #if DECDPUN<=4
7128 quot=QUOT10(*up, cut);
7129 rem=*up-quot*powers[cut];
7130 #else
7131 rem=*up%powers[cut];
7132 quot=*up/powers[cut];
7133 #endif
7134 if (rem!=0) *residue=1;
7136 /* discard digit is now at bottom of quot */
7137 #if DECDPUN<=4
7138 temp=(quot*6554)>>16; /* fast /10 */
7139 /* Vowels algorithm here not a win (9 instructions) */
7140 discard1=quot-X10(temp);
7141 quot=temp;
7142 #else
7143 discard1=quot%10;
7144 quot=quot/10;
7145 #endif
7146 /* here, discard1 is the guard digit, and residue is everything */
7147 /* else [use mapping array to accumulate residue safely] */
7148 *residue+=resmap[discard1];
7149 cut++; /* 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 */
7153 if (set->digits<=0) { /* special for Quantize/Subnormal :-( */
7154 *dn->lsu=0; /* .. result is 0 */
7155 dn->digits=1; /* .. */
7157 else { /* shift to least needed */
7158 count=set->digits; /* now digits to end up with */
7159 dn->digits=count; /* set the new length */
7160 /* shift-copy the coefficient array to the result number */
7161 for (target=dn->lsu; ; target++) {
7162 *target=(Unit)quot;
7163 count-=(DECDPUN-cut);
7164 if (count<=0) break;
7165 up++;
7166 quot=*up;
7167 #if DECDPUN<=4
7168 quot=QUOT10(quot, cut);
7169 rem=*up-quot*powers[cut];
7170 #else
7171 rem=quot%powers[cut];
7172 quot=quot/powers[cut];
7173 #endif
7174 *target=(Unit)(*target+rem*powers[DECDPUN-cut]);
7175 count-=cut;
7176 if (count<=0) break;
7177 } /* shift-copy loop */
7178 } /* shift to least */
7179 } /* not unit boundary */
7181 if (*residue!=0) *status|=DEC_Inexact; /* record inexactitude */
7182 return;
7183 } /* decSetCoeff */
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 /* ------------------------------------------------------------------ */
7217 static void decApplyRound(decNumber *dn, decContext *set, Int residue,
7218 uInt *status) {
7219 Int bump; /* 1 if coefficient needs to be incremented */
7220 /* -1 if coefficient needs to be decremented */
7222 if (residue==0) return; /* nothing to apply */
7224 bump=0; /* assume a smooth ride */
7226 /* now decide whether, and how, to round, depending on mode */
7227 switch (set->round) {
7228 case 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) */
7234 Int lsd5=*dn->lsu%5; /* get lsd and quintate */
7235 if (residue<0 && lsd5!=1) bump=-1;
7236 else if (residue>0 && lsd5==0) bump=1;
7237 /* [bump==1 could be applied directly; use common path for clarity] */
7238 break;} /* r-05 */
7240 case DEC_ROUND_DOWN: {
7241 /* no change, except if negative residue */
7242 if (residue<0) bump=-1;
7243 break;} /* r-d */
7245 case DEC_ROUND_HALF_DOWN: {
7246 if (residue>5) bump=1;
7247 break;} /* r-h-d */
7249 case DEC_ROUND_HALF_EVEN: {
7250 if (residue>5) bump=1; /* >0.5 goes up */
7251 else if (residue==5) { /* exactly 0.5000... */
7252 /* 0.5 goes up iff [new] lsd is odd */
7253 if (*dn->lsu & 0x01) bump=1;
7255 break;} /* r-h-e */
7257 case DEC_ROUND_HALF_UP: {
7258 if (residue>=5) bump=1;
7259 break;} /* r-h-u */
7261 case DEC_ROUND_UP: {
7262 if (residue>0) bump=1;
7263 break;} /* r-u */
7265 case DEC_ROUND_CEILING: {
7266 /* same as _UP for positive numbers, and as _DOWN for negatives */
7267 /* [negative residue cannot occur on 0] */
7268 if (decNumberIsNegative(dn)) {
7269 if (residue<0) bump=-1;
7271 else {
7272 if (residue>0) bump=1;
7274 break;} /* r-c */
7276 case DEC_ROUND_FLOOR: {
7277 /* same as _UP for negative numbers, and as _DOWN for positive */
7278 /* [negative residue cannot occur on 0] */
7279 if (!decNumberIsNegative(dn)) {
7280 if (residue<0) bump=-1;
7282 else {
7283 if (residue>0) bump=1;
7285 break;} /* r-f */
7287 default: { /* e.g., DEC_ROUND_MAX */
7288 *status|=DEC_Invalid_context;
7289 #if DECTRACE || (DECCHECK && DECVERB)
7290 printf("Unknown rounding mode: %d\n", set->round);
7291 #endif
7292 break;}
7293 } /* switch */
7295 /* now bump the number, up or down, if need be */
7296 if (bump==0) return; /* no action required */
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. */
7303 if (bump>0) {
7304 Unit *up; /* work */
7305 uInt count=dn->digits; /* digits to be checked */
7306 for (up=dn->lsu; ; up++) {
7307 if (count<=DECDPUN) {
7308 /* this is the last Unit (the msu) */
7309 if (*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. */
7312 for (up=up-1; up>=dn->lsu; up--) *up=0; /* others all to 0 */
7313 dn->exponent++; /* and bump exponent */
7314 /* [which, very rarely, could cause Overflow...] */
7315 if ((dn->exponent+dn->digits)>set->emax+1) {
7316 decSetOverflow(dn, set, status);
7318 return; /* done */
7320 /* a full unit to check, with more to come */
7321 if (*up!=DECDPUNMAX) break; /* not still 9s */
7322 count-=DECDPUN;
7323 } /* up */
7324 } /* bump>0 */
7325 else { /* -1 */
7326 /* here checking for a pre-bump of 1000... (leading 1, all */
7327 /* other digits zero) */
7328 Unit *up, *sup; /* work */
7329 uInt count=dn->digits; /* digits to be checked */
7330 for (up=dn->lsu; ; up++) {
7331 if (count<=DECDPUN) {
7332 /* this is the last Unit (the msu) */
7333 if (*up!=powers[count-1]) break; /* not 100.. */
7334 /* here if have the 1000... case */
7335 sup=up; /* save msu pointer */
7336 *up=(Unit)powers[count]-1; /* here 100 in msu -> 999 */
7337 /* others all to all-nines, too */
7338 for (up=up-1; up>=dn->lsu; up--) *up=(Unit)powers[DECDPUN]-1;
7339 dn->exponent--; /* and bump exponent */
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); */
7346 if (dn->exponent+1==set->emin-set->digits+1) {
7347 if (count==1 && dn->digits==1) *sup=0; /* here 9 -> 0[.9] */
7348 else {
7349 *sup=(Unit)powers[count-1]-1; /* here 999.. in msu -> 99.. */
7350 dn->digits--;
7352 dn->exponent++;
7353 *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
7355 return; /* done */
7358 /* a full unit to check, with more to come */
7359 if (*up!=0) break; /* not still 0s */
7360 count-=DECDPUN;
7361 } /* up */
7363 } /* bump<0 */
7365 /* Actual bump needed. Do it. */
7366 decUnitAddSub(dn->lsu, D2U(dn->digits), uarrone, 1, 0, dn->lsu, bump);
7367 } /* decApplyRound */
7369 #if DECSUBSET
7370 /* ------------------------------------------------------------------ */
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 /* ------------------------------------------------------------------ */
7386 static void decFinish(decNumber *dn, decContext *set, Int *residue,
7387 uInt *status) {
7388 if (!set->extended) {
7389 if ISZERO(dn) { /* value is zero */
7390 dn->exponent=0; /* clean exponent .. */
7391 dn->bits=0; /* .. and sign */
7392 return; /* no error possible */
7394 if (dn->exponent>=0) { /* non-negative exponent */
7395 /* >0; reduce to integer if possible */
7396 if (set->digits >= (dn->exponent+dn->digits)) {
7397 dn->digits=decShiftToMost(dn->lsu, dn->digits, dn->exponent);
7398 dn->exponent=0;
7401 } /* !extended */
7403 decFinalize(dn, set, residue, status);
7404 } /* decFinish */
7405 #endif
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 /* ------------------------------------------------------------------ */
7421 static void decFinalize(decNumber *dn, decContext *set, Int *residue,
7422 uInt *status) {
7423 Int shift; /* shift needed if clamping */
7424 Int tinyexp=set->emin-dn->digits+1; /* precalculate subnormal boundary */
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]. */
7430 /* First test for subnormal. This must be done before any final */
7431 /* round as the result could be rounded to Nmin or 0. */
7432 if (dn->exponent<=tinyexp) { /* prefilter */
7433 Int comp;
7434 decNumber nmin;
7435 /* A very nasty case here is dn == Nmin and residue<0 */
7436 if (dn->exponent<tinyexp) {
7437 /* Go handle subnormals; this will apply round if needed. */
7438 decSetSubnormal(dn, set, residue, status);
7439 return;
7441 /* Equals case: only subnormal if dn=Nmin and negative residue */
7442 decNumberZero(&nmin);
7443 nmin.lsu[0]=1;
7444 nmin.exponent=set->emin;
7445 comp=decCompare(dn, &nmin, 1); /* (signless compare) */
7446 if (comp==BADINT) { /* oops */
7447 *status|=DEC_Insufficient_storage; /* abandon... */
7448 return;
7450 if (*residue<0 && comp==0) { /* neg residue and dn==Nmin */
7451 decApplyRound(dn, set, *residue, status); /* might force down */
7452 decSetSubnormal(dn, set, residue, status);
7453 return;
7457 /* now apply any pending round (this could raise overflow). */
7458 if (*residue!=0) decApplyRound(dn, set, *residue, status);
7460 /* Check for overflow [redundant in the 'rare' case] or clamp */
7461 if (dn->exponent<=set->emax-set->digits+1) return; /* neither needed */
7464 /* here when might have an overflow or clamp to do */
7465 if (dn->exponent>set->emax-dn->digits+1) { /* too big */
7466 decSetOverflow(dn, set, status);
7467 return;
7469 /* here when the result is normal but in clamp range */
7470 if (!set->clamp) return;
7472 /* here when need to apply the IEEE exponent clamp (fold-down) */
7473 shift=dn->exponent-(set->emax-set->digits+1);
7475 /* shift coefficient (if non-zero) */
7476 if (!ISZERO(dn)) {
7477 dn->digits=decShiftToMost(dn->lsu, dn->digits, shift);
7479 dn->exponent-=shift; /* adjust the exponent to match */
7480 *status|=DEC_Clamped; /* and record the dirty deed */
7481 return;
7482 } /* decFinalize */
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 /* ------------------------------------------------------------------ */
7495 static void decSetOverflow(decNumber *dn, decContext *set, uInt *status) {
7496 Flag needmax=0; /* result is maximum finite value */
7497 uByte sign=dn->bits&DECNEG; /* clean and save sign bit */
7499 if (ISZERO(dn)) { /* zero does not overflow magnitude */
7500 Int emax=set->emax; /* limit value */
7501 if (set->clamp) emax-=set->digits-1; /* lower if clamping */
7502 if (dn->exponent>emax) { /* clamp required */
7503 dn->exponent=emax;
7504 *status|=DEC_Clamped;
7506 return;
7509 decNumberZero(dn);
7510 switch (set->round) {
7511 case DEC_ROUND_DOWN: {
7512 needmax=1; /* never Infinity */
7513 break;} /* r-d */
7514 case DEC_ROUND_05UP: {
7515 needmax=1; /* never Infinity */
7516 break;} /* r-05 */
7517 case DEC_ROUND_CEILING: {
7518 if (sign) needmax=1; /* Infinity if non-negative */
7519 break;} /* r-c */
7520 case DEC_ROUND_FLOOR: {
7521 if (!sign) needmax=1; /* Infinity if negative */
7522 break;} /* r-f */
7523 default: break; /* Infinity in all other cases */
7525 if (needmax) {
7526 decSetMaxValue(dn, set);
7527 dn->bits=sign; /* set sign */
7529 else dn->bits=sign|DECINF; /* Value is +/-Infinity */
7530 *status|=DEC_Overflow | DEC_Inexact | DEC_Rounded;
7531 } /* decSetOverflow */
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 /* ------------------------------------------------------------------ */
7541 static void decSetMaxValue(decNumber *dn, decContext *set) {
7542 Unit *up; /* work */
7543 Int count=set->digits; /* nines to add */
7544 dn->digits=count;
7545 /* fill in all nines to set maximum value */
7546 for (up=dn->lsu; ; up++) {
7547 if (count>DECDPUN) *up=DECDPUNMAX; /* unit full o'nines */
7548 else { /* this is the msu */
7549 *up=(Unit)(powers[count]-1);
7550 break;
7552 count-=DECDPUN; /* filled those digits */
7553 } /* up */
7554 dn->bits=0; /* + sign */
7555 dn->exponent=set->emax-set->digits+1;
7556 } /* decSetMaxValue */
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 /* ------------------------------------------------------------------ */
7575 static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue,
7576 uInt *status) {
7577 decContext workset; /* work */
7578 Int etiny, adjust; /* .. */
7580 #if DECSUBSET
7581 /* simple set to zero and 'hard underflow' for subset */
7582 if (!set->extended) {
7583 decNumberZero(dn);
7584 /* always full overflow */
7585 *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
7586 return;
7588 #endif
7590 /* Full arithmetic -- allow subnormals, rounded to minimum exponent */
7591 /* (Etiny) if needed */
7592 etiny=set->emin-(set->digits-1); /* smallest allowed exponent */
7594 if ISZERO(dn) { /* value is zero */
7595 /* residue can never be non-zero here */
7596 #if DECCHECK
7597 if (*residue!=0) {
7598 printf("++ Subnormal 0 residue %ld\n", (LI)*residue);
7599 *status|=DEC_Invalid_operation;
7601 #endif
7602 if (dn->exponent<etiny) { /* clamp required */
7603 dn->exponent=etiny;
7604 *status|=DEC_Clamped;
7606 return;
7609 *status|=DEC_Subnormal; /* have a non-zero subnormal */
7610 adjust=etiny-dn->exponent; /* calculate digits to remove */
7611 if (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) */
7615 if (*status&DEC_Inexact) *status|=DEC_Underflow;
7616 return;
7619 /* adjust>0, so need to rescale the result so exponent becomes Etiny */
7620 /* [this code is similar to that in rescale] */
7621 workset=*set; /* clone rounding, etc. */
7622 workset.digits=dn->digits-adjust; /* set requested length */
7623 workset.emin-=adjust; /* and adjust emin to match */
7624 /* [note that the latter can be <1, here, similar to Rescale case] */
7625 decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);
7626 decApplyRound(dn, &workset, *residue, status);
7628 /* Use 754R/854 default rule: Underflow is set iff Inexact */
7629 /* [independent of whether trapped] */
7630 if (*status&DEC_Inexact) *status|=DEC_Underflow;
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] */
7634 if (dn->exponent>etiny) {
7635 dn->digits=decShiftToMost(dn->lsu, dn->digits, 1);
7636 dn->exponent--; /* (re)adjust the exponent. */
7639 /* if rounded to zero, it is by definition clamped... */
7640 if (ISZERO(dn)) *status|=DEC_Clamped;
7641 } /* decSetSubnormal */
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 /* ------------------------------------------------------------------ */
7661 static uInt decCheckMath(const decNumber *rhs, decContext *set,
7662 uInt *status) {
7663 uInt save=*status; /* record */
7664 if (set->digits>DEC_MAX_MATH
7665 || set->emax>DEC_MAX_MATH
7666 || -set->emin>DEC_MAX_MATH) *status|=DEC_Invalid_context;
7667 else if ((rhs->digits>DEC_MAX_MATH
7668 || rhs->exponent+rhs->digits>DEC_MAX_MATH+1
7669 || rhs->exponent+rhs->digits<2*(1-DEC_MAX_MATH))
7670 && !ISZERO(rhs)) *status|=DEC_Invalid_operation;
7671 return (*status!=save);
7672 } /* decCheckMath */
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 /* ------------------------------------------------------------------ */
7689 static Int decGetInt(const decNumber *dn) {
7690 Int theInt; /* result accumulator */
7691 const Unit *up; /* work */
7692 Int got; /* digits (real or not) processed */
7693 Int ilength=dn->digits+dn->exponent; /* integral length */
7694 Flag neg=decNumberIsNegative(dn); /* 1 if -ve */
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 > 999999999
7699 #error GetInt may need updating [for Emax]
7700 #endif
7701 #if DEC_MIN_EMIN < -999999999
7702 #error GetInt may need updating [for Emin]
7703 #endif
7704 if (ISZERO(dn)) return 0; /* zeros are OK, with any exponent */
7706 up=dn->lsu; /* ready for lsu */
7707 theInt=0; /* ready to accumulate */
7708 if (dn->exponent>=0) { /* relatively easy */
7709 /* no fractional part [usual]; allow for positive exponent */
7710 got=dn->exponent;
7712 else { /* -ve exponent; some fractional part to check and discard */
7713 Int count=-dn->exponent; /* digits to discard */
7714 /* spin up whole units until reach the Unit with the unit digit */
7715 for (; count>=DECDPUN; up++) {
7716 if (*up!=0) return BADINT; /* non-zero Unit to discard */
7717 count-=DECDPUN;
7719 if (count==0) got=0; /* [a multiple of DECDPUN] */
7720 else { /* [not multiple of DECDPUN] */
7721 Int rem; /* work */
7722 /* slice off fraction digits and check for non-zero */
7723 #if DECDPUN<=4
7724 theInt=QUOT10(*up, count);
7725 rem=*up-theInt*powers[count];
7726 #else
7727 rem=*up%powers[count]; /* slice off discards */
7728 theInt=*up/powers[count];
7729 #endif
7730 if (rem!=0) return BADINT; /* non-zero fraction */
7731 /* it looks good */
7732 got=DECDPUN-count; /* number of digits so far */
7733 up++; /* ready for next */
7736 /* now it's known there's no fractional part */
7738 /* tricky code now, to accumulate up to 9.3 digits */
7739 if (got==0) {theInt=*up; got+=DECDPUN; up++;} /* ensure lsu is there */
7741 if (ilength<11) {
7742 Int save=theInt;
7743 /* collect any remaining unit(s) */
7744 for (; got<ilength; up++) {
7745 theInt+=*up*powers[got];
7746 got+=DECDPUN;
7748 if (ilength==10) { /* need to check for wrap */
7749 if (theInt/(Int)powers[got-DECDPUN]!=(Int)*(up-1)) ilength=11;
7750 /* [that test also disallows the BADINT result case] */
7751 else if (neg && theInt>1999999997) ilength=11;
7752 else if (!neg && theInt>999999999) ilength=11;
7753 if (ilength==11) theInt=save; /* restore correct low bit */
7757 if (ilength>10) { /* too big */
7758 if (theInt&1) return BIGODD; /* bottom bit 1 */
7759 return BIGEVEN; /* bottom bit 0 */
7762 if (neg) theInt=-theInt; /* apply sign */
7763 return theInt;
7764 } /* decGetInt */
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 /* ------------------------------------------------------------------ */
7778 static decNumber *decDecap(decNumber *dn, Int drop) {
7779 Unit *msu; /* -> target cut point */
7780 Int cut; /* work */
7781 if (drop>=dn->digits) { /* losing the whole thing */
7782 #if DECCHECK
7783 if (drop>dn->digits)
7784 printf("decDecap called with drop>digits [%ld>%ld]\n",
7785 (LI)drop, (LI)dn->digits);
7786 #endif
7787 dn->lsu[0]=0;
7788 dn->digits=1;
7789 return dn;
7791 msu=dn->lsu+D2U(dn->digits-drop)-1; /* -> likely msu */
7792 cut=MSUDIGITS(dn->digits-drop); /* digits to be in use in msu */
7793 if (cut!=DECDPUN) *msu%=powers[cut]; /* clear left digits */
7794 /* that may have left leading zero digits, so do a proper count... */
7795 dn->digits=decGetDigits(dn->lsu, msu-dn->lsu+1);
7796 return dn;
7797 } /* decDecap */
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 /* ------------------------------------------------------------------ */
7814 static Flag decBiStr(const char *targ, const char *str1, const char *str2) {
7815 for (;;targ++, str1++, str2++) {
7816 if (*targ!=*str1 && *targ!=*str2) return 0;
7817 /* *targ has a match in one (or both, if terminator) */
7818 if (*targ=='\0') break;
7819 } /* forever */
7820 return 1;
7821 } /* decBiStr */
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 /* ------------------------------------------------------------------ */
7837 static decNumber * decNaNs(decNumber *res, const decNumber *lhs,
7838 const decNumber *rhs, decContext *set,
7839 uInt *status) {
7840 /* This decision tree ends up with LHS being the source pointer, */
7841 /* and status updated if need be */
7842 if (lhs->bits & DECSNAN)
7843 *status|=DEC_Invalid_operation | DEC_sNaN;
7844 else if (rhs==NULL);
7845 else if (rhs->bits & DECSNAN) {
7846 lhs=rhs;
7847 *status|=DEC_Invalid_operation | DEC_sNaN;
7849 else if (lhs->bits & DECNAN);
7850 else lhs=rhs;
7852 /* propagate the payload */
7853 if (lhs->digits<=set->digits) decNumberCopy(res, lhs); /* easy */
7854 else { /* too long */
7855 const Unit *ul;
7856 Unit *ur, *uresp1;
7857 /* copy safe number of units, then decapitate */
7858 res->bits=lhs->bits; /* need sign etc. */
7859 uresp1=res->lsu+D2U(set->digits);
7860 for (ur=res->lsu, ul=lhs->lsu; ur<uresp1; ur++, ul++) *ur=*ul;
7861 res->digits=D2U(set->digits)*DECDPUN;
7862 /* maybe still too long */
7863 if (res->digits>set->digits) decDecap(res, res->digits-set->digits);
7866 res->bits&=~DECSNAN; /* convert any sNaN to NaN, while */
7867 res->bits|=DECNAN; /* .. preserving sign */
7868 res->exponent=0; /* clean exponent */
7869 /* [coefficient was copied/decapitated] */
7870 return res;
7871 } /* decNaNs */
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 /* ------------------------------------------------------------------ */
7888 static void decStatus(decNumber *dn, uInt status, decContext *set) {
7889 if (status & DEC_NaNs) { /* error status -> NaN */
7890 /* if cause was an sNaN, clear and propagate [NaN is already set up] */
7891 if (status & DEC_sNaN) status&=~DEC_sNaN;
7892 else {
7893 decNumberZero(dn); /* other error: clean throughout */
7894 dn->bits=DECNAN; /* and make a quiet NaN */
7897 decContextSetStatus(set, status); /* [may not return] */
7898 return;
7899 } /* decStatus */
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. */
7914 static Int decGetDigits(Unit *uar, Int len) {
7915 Unit *up=uar+(len-1); /* -> msu */
7916 Int digits=(len-1)*DECDPUN+1; /* possible digits excluding msu */
7917 #if DECDPUN>4
7918 uInt const *pow; /* work */
7919 #endif
7920 /* (at least 1 in final msu) */
7921 #if DECCHECK
7922 if (len<1) printf("decGetDigits called with len<1 [%ld]\n", (LI)len);
7923 #endif
7925 for (; up>=uar; up--) {
7926 if (*up==0) { /* unit is all 0s */
7927 if (digits==1) break; /* a zero has one digit */
7928 digits-=DECDPUN; /* adjust for 0 unit */
7929 continue;}
7930 /* found the first (most significant) non-zero Unit */
7931 #if DECDPUN>1 /* not done yet */
7932 if (*up<10) break; /* is 1-9 */
7933 digits++;
7934 #if DECDPUN>2 /* not done yet */
7935 if (*up<100) break; /* is 10-99 */
7936 digits++;
7937 #if DECDPUN>3 /* not done yet */
7938 if (*up<1000) break; /* is 100-999 */
7939 digits++;
7940 #if DECDPUN>4 /* count the rest ... */
7941 for (pow=&powers[4]; *up>=*pow; pow++) digits++;
7942 #endif
7943 #endif
7944 #endif
7945 #endif
7946 break;
7947 } /* up */
7948 return digits;
7949 } /* decGetDigits */
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 /* ------------------------------------------------------------------ */
7966 static bool mulUInt128ByPowOf10(uLong *plow, uLong *phigh, uInt pow10)
7968 while (pow10 >= ARRAY_SIZE(powers)) {
7969 if (mulu128(plow, phigh, powers[ARRAY_SIZE(powers) - 1])) {
7970 /* Overflow */
7971 return true;
7973 pow10 -= ARRAY_SIZE(powers) - 1;
7976 if (pow10 > 0) {
7977 return mulu128(plow, phigh, powers[pow10]);
7978 } else {
7979 return false;
7983 #if DECTRACE | DECCHECK
7984 /* ------------------------------------------------------------------ */
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 */
7992 void decNumberShow(const decNumber *dn) {
7993 const Unit *up; /* work */
7994 uInt u, d; /* .. */
7995 Int cut; /* .. */
7996 char isign='+'; /* main sign */
7997 if (dn==NULL) {
7998 printf("NULL\n");
7999 return;}
8000 if (decNumberIsNegative(dn)) isign='-';
8001 printf(" >> %c ", isign);
8002 if (dn->bits&DECSPECIAL) { /* Is a special value */
8003 if (decNumberIsInfinite(dn)) printf("Infinity");
8004 else { /* a NaN */
8005 if (dn->bits&DECSNAN) printf("sNaN"); /* signalling NaN */
8006 else printf("NaN");
8008 /* if coefficient and exponent are 0, no more to do */
8009 if (dn->exponent==0 && dn->digits==1 && *dn->lsu==0) {
8010 printf("\n");
8011 return;}
8012 /* drop through to report other information */
8013 printf(" ");
8016 /* now carefully display the coefficient */
8017 up=dn->lsu+D2U(dn->digits)-1; /* msu */
8018 printf("%ld", (LI)*up);
8019 for (up=up-1; up>=dn->lsu; up--) {
8020 u=*up;
8021 printf(":");
8022 for (cut=DECDPUN-1; cut>=0; cut--) {
8023 d=u/powers[cut];
8024 u-=d*powers[cut];
8025 printf("%ld", (LI)d);
8026 } /* cut */
8027 } /* up */
8028 if (dn->exponent!=0) {
8029 char esign='+';
8030 if (dn->exponent<0) esign='-';
8031 printf(" E%c%ld", esign, (LI)abs(dn->exponent));
8033 printf(" [%ld]\n", (LI)dn->digits);
8034 } /* decNumberShow */
8035 #endif
8037 #if DECTRACE || DECCHECK
8038 /* ------------------------------------------------------------------ */
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 /* ------------------------------------------------------------------ */
8044 static void decDumpAr(char name, const Unit *ar, Int len) {
8045 Int i;
8046 const char *spec;
8047 #if DECDPUN==9
8048 spec="%09d ";
8049 #elif DECDPUN==8
8050 spec="%08d ";
8051 #elif DECDPUN==7
8052 spec="%07d ";
8053 #elif DECDPUN==6
8054 spec="%06d ";
8055 #elif DECDPUN==5
8056 spec="%05d ";
8057 #elif DECDPUN==4
8058 spec="%04d ";
8059 #elif DECDPUN==3
8060 spec="%03d ";
8061 #elif DECDPUN==2
8062 spec="%02d ";
8063 #else
8064 spec="%d ";
8065 #endif
8066 printf(" :%c: ", name);
8067 for (i=len-1; i>=0; i--) {
8068 if (i==len-1) printf("%ld ", (LI)ar[i]);
8069 else printf(spec, ar[i]);
8071 printf("\n");
8072 return;}
8073 #endif
8075 #if DECCHECK
8076 /* ------------------------------------------------------------------ */
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 /* ------------------------------------------------------------------ */
8089 static Flag decCheckOperands(decNumber *res, const decNumber *lhs,
8090 const decNumber *rhs, decContext *set) {
8091 Flag bad=0;
8092 if (set==NULL) { /* oops; hopeless */
8093 #if DECTRACE || DECVERB
8094 printf("Reference to context is NULL.\n");
8095 #endif
8096 bad=1;
8097 return 1;}
8098 else if (set!=DECUNCONT
8099 && (set->digits<1 || set->round>=DEC_ROUND_MAX)) {
8100 bad=1;
8101 #if DECTRACE || DECVERB
8102 printf("Bad context [digits=%ld round=%ld].\n",
8103 (LI)set->digits, (LI)set->round);
8104 #endif
8106 else {
8107 if (res==NULL) {
8108 bad=1;
8109 #if DECTRACE
8110 /* this one not DECVERB as standard tests include NULL */
8111 printf("Reference to result is NULL.\n");
8112 #endif
8114 if (!bad && lhs!=DECUNUSED) bad=(decCheckNumber(lhs));
8115 if (!bad && rhs!=DECUNUSED) bad=(decCheckNumber(rhs));
8117 if (bad) {
8118 if (set!=DECUNCONT) decContextSetStatus(set, DEC_Invalid_operation);
8119 if (res!=DECUNRESU && res!=NULL) {
8120 decNumberZero(res);
8121 res->bits=DECNAN; /* qNaN */
8124 return bad;
8125 } /* decCheckOperands */
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 /* ------------------------------------------------------------------ */
8135 static Flag decCheckNumber(const decNumber *dn) {
8136 const Unit *up; /* work */
8137 uInt maxuint; /* .. */
8138 Int ae, d, digits; /* .. */
8139 Int emin, emax; /* .. */
8141 if (dn==NULL) { /* hopeless */
8142 #if DECTRACE
8143 /* this one not DECVERB as standard tests include NULL */
8144 printf("Reference to decNumber is NULL.\n");
8145 #endif
8146 return 1;}
8148 /* check special values */
8149 if (dn->bits & DECSPECIAL) {
8150 if (dn->exponent!=0) {
8151 #if DECTRACE || DECVERB
8152 printf("Exponent %ld (not 0) for a special value [%02x].\n",
8153 (LI)dn->exponent, dn->bits);
8154 #endif
8155 return 1;}
8157 /* 2003.09.08: NaNs may now have coefficients, so next tests Inf only */
8158 if (decNumberIsInfinite(dn)) {
8159 if (dn->digits!=1) {
8160 #if DECTRACE || DECVERB
8161 printf("Digits %ld (not 1) for an infinity.\n", (LI)dn->digits);
8162 #endif
8163 return 1;}
8164 if (*dn->lsu!=0) {
8165 #if DECTRACE || DECVERB
8166 printf("LSU %ld (not 0) for an infinity.\n", (LI)*dn->lsu);
8167 #endif
8168 decDumpAr('I', dn->lsu, D2U(dn->digits));
8169 return 1;}
8170 } /* Inf */
8171 /* 2002.12.26: negative NaNs can now appear through proposed IEEE */
8172 /* concrete formats (decimal64, etc.). */
8173 return 0;
8176 /* check the coefficient */
8177 if (dn->digits<1 || dn->digits>DECNUMMAXP) {
8178 #if DECTRACE || DECVERB
8179 printf("Digits %ld in number.\n", (LI)dn->digits);
8180 #endif
8181 return 1;}
8183 d=dn->digits;
8185 for (up=dn->lsu; d>0; up++) {
8186 if (d>DECDPUN) maxuint=DECDPUNMAX;
8187 else { /* reached the msu */
8188 maxuint=powers[d]-1;
8189 if (dn->digits>1 && *up<powers[d-1]) {
8190 #if DECTRACE || DECVERB
8191 printf("Leading 0 in number.\n");
8192 decNumberShow(dn);
8193 #endif
8194 return 1;}
8196 if (*up>maxuint) {
8197 #if DECTRACE || DECVERB
8198 printf("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 #endif
8201 return 1;}
8202 d-=DECDPUN;
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). */
8208 ae=dn->exponent+dn->digits-1; /* adjusted exponent */
8209 emax=DECNUMMAXE;
8210 emin=DECNUMMINE;
8211 digits=DECNUMMAXP;
8212 if (ae<emin-(digits-1)) {
8213 #if DECTRACE || DECVERB
8214 printf("Adjusted exponent underflow [%ld].\n", (LI)ae);
8215 decNumberShow(dn);
8216 #endif
8217 return 1;}
8218 if (ae>+emax) {
8219 #if DECTRACE || DECVERB
8220 printf("Adjusted exponent overflow [%ld].\n", (LI)ae);
8221 decNumberShow(dn);
8222 #endif
8223 return 1;}
8225 return 0; /* it's OK */
8226 } /* decCheckNumber */
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 /* ------------------------------------------------------------------ */
8236 static void decCheckInexact(const decNumber *dn, decContext *set) {
8237 #if !DECSUBSET && DECEXTFLAG
8238 if ((set->status & (DEC_Inexact|DEC_Subnormal))==DEC_Inexact
8239 && (set->digits!=dn->digits) && !(dn->bits & DECSPECIAL)) {
8240 #if DECTRACE || DECVERB
8241 printf("Insufficient digits [%ld] on normal Inexact result.\n",
8242 (LI)dn->digits);
8243 decNumberShow(dn);
8244 #endif
8245 decContextSetStatus(set, DEC_Invalid_operation);
8247 #else
8248 /* next is a noop for quiet compiler */
8249 if (dn!=NULL && dn->digits==0) set->status|=DEC_Invalid_operation;
8250 #endif
8251 return;
8252 } /* decCheckInexact */
8253 #endif
8255 #if DECALLOC
8256 #undef malloc
8257 #undef free
8258 /* ------------------------------------------------------------------ */
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 /* ------------------------------------------------------------------ */
8272 static void *decMalloc(size_t n) {
8273 uInt size=n+12; /* true size */
8274 void *alloc; /* -> allocated storage */
8275 uInt *j; /* work */
8276 uByte *b, *b0; /* .. */
8278 alloc=malloc(size); /* -> allocated storage */
8279 if (alloc==NULL) return NULL; /* out of strorage */
8280 b0=(uByte *)alloc; /* as bytes */
8281 decAllocBytes+=n; /* account for storage */
8282 j=(uInt *)alloc; /* -> first four bytes */
8283 *j=n; /* save n */
8284 /* printf(" alloc ++ dAB: %ld (%d)\n", decAllocBytes, n); */
8285 for (b=b0+4; b<b0+8; b++) *b=DECFENCE;
8286 for (b=b0+n+8; b<b0+n+12; b++) *b=DECFENCE;
8287 return b0+8; /* -> play area */
8288 } /* decMalloc */
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 /* ------------------------------------------------------------------ */
8302 static void decFree(void *alloc) {
8303 uInt *j, n; /* pointer, original length */
8304 uByte *b, *b0; /* work */
8306 if (alloc==NULL) return; /* allowed; it's a nop */
8307 b0=(uByte *)alloc; /* as bytes */
8308 b0-=8; /* -> true start of storage */
8309 j=(uInt *)b0; /* -> first four bytes */
8310 n=*j; /* lift */
8311 for (b=b0+4; b<b0+8; b++) if (*b!=DECFENCE)
8312 printf("=== Corrupt byte [%02x] at offset %d from %ld ===\n", *b,
8313 b-b0-8, (Int)b0);
8314 for (b=b0+n+8; b<b0+n+12; b++) if (*b!=DECFENCE)
8315 printf("=== Corrupt byte [%02x] at offset +%d from %ld, n=%ld ===\n", *b,
8316 b-b0-8, (Int)b0, n);
8317 free(b0); /* drop the storage */
8318 decAllocBytes-=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 #endif