00001 /* Decimal Number module for the decNumber C Library 00002 Copyright (C) 2005 Free Software Foundation, Inc. 00003 Contributed by IBM Corporation. Author Mike Cowlishaw. 00004 00005 This file is part of GCC. 00006 00007 GCC is free software; you can redistribute it and/or modify it under 00008 the terms of the GNU General Public License as published by the Free 00009 Software Foundation; either version 2, or (at your option) any later 00010 version. 00011 00012 In addition to the permissions in the GNU General Public License, 00013 the Free Software Foundation gives you unlimited permission to link 00014 the compiled version of this file into combinations with other 00015 programs, and to distribute those combinations without any 00016 restriction coming from the use of this file. (The General Public 00017 License restrictions do apply in other respects; for example, they 00018 cover modification of the file, and distribution when not linked 00019 into a combine executable.) 00020 00021 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 00022 WARRANTY; without even the implied warranty of MERCHANTABILITY or 00023 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00024 for more details. 00025 00026 You should have received a copy of the GNU General Public License 00027 along with GCC; see the file COPYING. If not, write to the Free 00028 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 00029 02110-1301, USA. */ 00030 00031 /* ------------------------------------------------------------------ */ 00032 /* This module comprises the routines for Standard Decimal Arithmetic */ 00033 /* as defined in the specification which may be found on the */ 00034 /* http://www2.hursley.ibm.com/decimal web pages. It implements both */ 00035 /* the full ('extended') arithmetic and the simpler ('subset') */ 00036 /* arithmetic. */ 00037 /* */ 00038 /* Usage notes: */ 00039 /* */ 00040 /* 1. This code is ANSI C89 except: */ 00041 /* */ 00042 /* a) Line comments (double forward slash) are used. (Most C */ 00043 /* compilers accept these. If yours does not, a simple script */ 00044 /* can be used to convert them to ANSI C comments.) */ 00045 /* */ 00046 /* b) Types from C99 stdint.h are used. If you do not have this */ 00047 /* header file, see the User's Guide section of the decNumber */ 00048 /* documentation; this lists the necessary definitions. */ 00049 /* */ 00050 /* c) If DECDPUN>4, non-ANSI 64-bit 'long long' types are used. */ 00051 /* To avoid these, set DECDPUN <= 4 (see documentation). */ 00052 /* */ 00053 /* 2. The decNumber format which this library uses is optimized for */ 00054 /* efficient processing of relatively short numbers; in particular */ 00055 /* it allows the use of fixed sized structures and minimizes copy */ 00056 /* and move operations. It does, however, support arbitrary */ 00057 /* precision (up to 999,999,999 digits) and arbitrary exponent */ 00058 /* range (Emax in the range 0 through 999,999,999 and Emin in the */ 00059 /* range -999,999,999 through 0). */ 00060 /* */ 00061 /* 3. Operands to operator functions are never modified unless they */ 00062 /* are also specified to be the result number (which is always */ 00063 /* permitted). Other than that case, operands may not overlap. */ 00064 /* */ 00065 /* 4. Error handling: the type of the error is ORed into the status */ 00066 /* flags in the current context (decContext structure). The */ 00067 /* SIGFPE signal is then raised if the corresponding trap-enabler */ 00068 /* flag in the decContext is set (is 1). */ 00069 /* */ 00070 /* It is the responsibility of the caller to clear the status */ 00071 /* flags as required. */ 00072 /* */ 00073 /* The result of any routine which returns a number will always */ 00074 /* be a valid number (which may be a special value, such as an */ 00075 /* Infinity or NaN). */ 00076 /* */ 00077 /* 5. The decNumber format is not an exchangeable concrete */ 00078 /* representation as it comprises fields which may be machine- */ 00079 /* dependent (big-endian or little-endian, for example). */ 00080 /* Canonical conversions to and from strings are provided; other */ 00081 /* conversions are available in separate modules. */ 00082 /* */ 00083 /* 6. Normally, input operands are assumed to be valid. Set DECCHECK */ 00084 /* to 1 for extended operand checking (including NULL operands). */ 00085 /* Results are undefined if a badly-formed structure (or a NULL */ 00086 /* NULL pointer to a structure) is provided, though with DECCHECK */ 00087 /* enabled the operator routines are protected against exceptions. */ 00088 /* (Except if the result pointer is NULL, which is unrecoverable.) */ 00089 /* */ 00090 /* However, the routines will never cause exceptions if they are */ 00091 /* given well-formed operands, even if the value of the operands */ 00092 /* is inappropriate for the operation and DECCHECK is not set. */ 00093 /* */ 00094 /* 7. Subset arithmetic is available only if DECSUBSET is set to 1. */ 00095 /* ------------------------------------------------------------------ */ 00096 /* Implementation notes for maintenance of this module: */ 00097 /* */ 00098 /* 1. Storage leak protection: Routines which use malloc are not */ 00099 /* permitted to use return for fastpath or error exits (i.e., */ 00100 /* they follow strict structured programming conventions). */ 00101 /* Instead they have a do{}while(0); construct surrounding the */ 00102 /* code which is protected -- break may be used from this. */ 00103 /* Other routines are allowed to use the return statement inline. */ 00104 /* */ 00105 /* Storage leak accounting can be enabled using DECALLOC. */ 00106 /* */ 00107 /* 2. All loops use the for(;;) construct. Any do construct is for */ 00108 /* protection as just described. */ 00109 /* */ 00110 /* 3. Setting status in the context must always be the very last */ 00111 /* action in a routine, as non-0 status may raise a trap and hence */ 00112 /* the call to set status may not return (if the handler uses long */ 00113 /* jump). Therefore all cleanup must be done first. In general, */ 00114 /* to achieve this we accumulate status and only finally apply it */ 00115 /* by calling decContextSetStatus (via decStatus). */ 00116 /* */ 00117 /* Routines which allocate storage cannot, therefore, use the */ 00118 /* 'top level' routines which could cause a non-returning */ 00119 /* transfer of control. The decXxxxOp routines are safe (do not */ 00120 /* call decStatus even if traps are set in the context) and should */ 00121 /* be used instead (they are also a little faster). */ 00122 /* */ 00123 /* 4. Exponent checking is minimized by allowing the exponent to */ 00124 /* grow outside its limits during calculations, provided that */ 00125 /* the decFinalize function is called later. Multiplication and */ 00126 /* division, and intermediate calculations in exponentiation, */ 00127 /* require more careful checks because of the risk of 31-bit */ 00128 /* overflow (the most negative valid exponent is -1999999997, for */ 00129 /* a 999999999-digit number with adjusted exponent of -999999999). */ 00130 /* */ 00131 /* 5. Rounding is deferred until finalization of results, with any */ 00132 /* 'off to the right' data being represented as a single digit */ 00133 /* residue (in the range -1 through 9). This avoids any double- */ 00134 /* rounding when more than one shortening takes place (for */ 00135 /* example, when a result is subnormal). */ 00136 /* */ 00137 /* 6. The digits count is allowed to rise to a multiple of DECDPUN */ 00138 /* during many operations, so whole Units are handled and exact */ 00139 /* accounting of digits is not needed. The correct digits value */ 00140 /* is found by decGetDigits, which accounts for leading zeros. */ 00141 /* This must be called before any rounding if the number of digits */ 00142 /* is not known exactly. */ 00143 /* */ 00144 /* 7. We use the multiply-by-reciprocal 'trick' for partitioning */ 00145 /* numbers up to four digits, using appropriate constants. This */ 00146 /* is not useful for longer numbers because overflow of 32 bits */ 00147 /* would lead to 4 multiplies, which is almost as expensive as */ 00148 /* a divide (unless we assumed floating-point multiply available). */ 00149 /* */ 00150 /* 8. Unusual abbreviations possibly used in the commentary: */ 00151 /* lhs -- left hand side (operand, of an operation) */ 00152 /* lsd -- least significant digit (of coefficient) */ 00153 /* lsu -- least significant Unit (of coefficient) */ 00154 /* msd -- most significant digit (of coefficient) */ 00155 /* msu -- most significant Unit (of coefficient) */ 00156 /* rhs -- right hand side (operand, of an operation) */ 00157 /* +ve -- positive */ 00158 /* -ve -- negative */ 00159 /* ------------------------------------------------------------------ */ 00160 00161 /* Some of glibc's string inlines cause warnings. Plus we'd rather 00162 rely on (and therefore test) GCC's string builtins. */ 00163 #define __NO_STRING_INLINES 00164 00165 #include <stdlib.h> /* for malloc, free, etc. */ 00166 #include <stdio.h> /* for printf [if needed] */ 00167 #include <string.h> /* for strcpy */ 00168 #include <ctype.h> /* for lower */ 00169 #include "config.h" 00170 #include "decNumber.h" /* base number library */ 00171 #include "decNumberLocal.h" /* decNumber local types, etc. */ 00172 00173 /* Constants */ 00174 /* Public constant array: powers of ten (powers[n]==10**n) */ 00175 const uInt powers[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 00176 10000000, 100000000, 1000000000 00177 }; 00178 00179 /* Local constants */ 00180 #define DIVIDE 0x80 /* Divide operators */ 00181 #define REMAINDER 0x40 /* .. */ 00182 #define DIVIDEINT 0x20 /* .. */ 00183 #define REMNEAR 0x10 /* .. */ 00184 #define COMPARE 0x01 /* Compare operators */ 00185 #define COMPMAX 0x02 /* .. */ 00186 #define COMPMIN 0x03 /* .. */ 00187 #define COMPNAN 0x04 /* .. [NaN processing] */ 00188 00189 #define DEC_sNaN 0x40000000 /* local status: sNaN signal */ 00190 #define BADINT (Int)0x80000000 /* most-negative Int; error indicator */ 00191 00192 static Unit one[] = { 1 }; /* Unit array of 1, used for incrementing */ 00193 00194 /* Granularity-dependent code */ 00195 #if DECDPUN<=4 00196 #define eInt Int /* extended integer */ 00197 #define ueInt uInt /* unsigned extended integer */ 00198 /* Constant multipliers for divide-by-power-of five using reciprocal */ 00199 /* multiply, after removing powers of 2 by shifting, and final shift */ 00200 /* of 17 [we only need up to **4] */ 00201 static const uInt multies[] = { 131073, 26215, 5243, 1049, 210 }; 00202 00203 /* QUOT10 -- macro to return the quotient of unit u divided by 10**n */ 00204 #define QUOT10(u, n) ((((uInt)(u)>>(n))*multies[n])>>17) 00205 #else 00206 /* For DECDPUN>4 we currently use non-ANSI 64-bit types. These could */ 00207 /* be replaced by subroutine calls later. */ 00208 #ifdef long 00209 #undef long 00210 #endif 00211 typedef signed long long Long; 00212 typedef unsigned long long uLong; 00213 #define eInt Long /* extended integer */ 00214 #define ueInt uLong /* unsigned extended integer */ 00215 #endif 00216 00217 /* Local routines */ 00218 static decNumber *decAddOp (decNumber *, const decNumber *, 00219 const decNumber *, decContext *, 00220 uByte, uInt *); 00221 static void decApplyRound (decNumber *, decContext *, Int, uInt *); 00222 static Int decCompare (const decNumber * lhs, const decNumber * rhs); 00223 static decNumber *decCompareOp (decNumber *, const decNumber *, const decNumber *, 00224 decContext *, Flag, uInt *); 00225 static void decCopyFit (decNumber *, const decNumber *, decContext *, 00226 Int *, uInt *); 00227 static decNumber *decDivideOp (decNumber *, const decNumber *, const decNumber *, 00228 decContext *, Flag, uInt *); 00229 static void decFinalize (decNumber *, decContext *, Int *, uInt *); 00230 static Int decGetDigits (const Unit *, Int); 00231 #if DECSUBSET 00232 static Int decGetInt (const decNumber *, decContext *); 00233 #else 00234 static Int decGetInt (const decNumber *); 00235 #endif 00236 static decNumber *decMultiplyOp (decNumber *, const decNumber *, 00237 const decNumber *, decContext *, uInt *); 00238 static decNumber *decNaNs (decNumber *, const decNumber *, const decNumber *, uInt *); 00239 static decNumber *decQuantizeOp (decNumber *, const decNumber *, 00240 const decNumber *, decContext *, Flag, uInt *); 00241 static void decSetCoeff (decNumber *, decContext *, const Unit *, 00242 Int, Int *, uInt *); 00243 static void decSetOverflow (decNumber *, decContext *, uInt *); 00244 static void decSetSubnormal (decNumber *, decContext *, Int *, uInt *); 00245 static Int decShiftToLeast (Unit *, Int, Int); 00246 static Int decShiftToMost (Unit *, Int, Int); 00247 static void decStatus (decNumber *, uInt, decContext *); 00248 static Flag decStrEq (const char *, const char *); 00249 static void decToString (const decNumber *, char[], Flag); 00250 static decNumber *decTrim (decNumber *, Flag, Int *); 00251 static Int decUnitAddSub (const Unit *, Int, const Unit *, Int, Int, Unit *, Int); 00252 static Int decUnitCompare (const Unit *, Int, const Unit *, Int, Int); 00253 00254 #if !DECSUBSET 00255 /* decFinish == decFinalize when no subset arithmetic needed */ 00256 #define decFinish(a,b,c,d) decFinalize(a,b,c,d) 00257 #else 00258 static void decFinish (decNumber *, decContext *, Int *, uInt *); 00259 static decNumber *decRoundOperand (const decNumber *, decContext *, uInt *); 00260 #endif 00261 00262 /* Diagnostic macros, etc. */ 00263 #if DECALLOC 00264 /* Handle malloc/free accounting. If enabled, our accountable routines */ 00265 /* are used; otherwise the code just goes straight to the system malloc */ 00266 /* and free routines. */ 00267 #define malloc(a) decMalloc(a) 00268 #define free(a) decFree(a) 00269 #define DECFENCE 0x5a /* corruption detector */ 00270 /* 'Our' malloc and free: */ 00271 static void *decMalloc (size_t); 00272 static void decFree (void *); 00273 uInt decAllocBytes = 0; /* count of bytes allocated */ 00274 /* Note that DECALLOC code only checks for storage buffer overflow. */ 00275 /* To check for memory leaks, the decAllocBytes variable should be */ 00276 /* checked to be 0 at appropriate times (e.g., after the test */ 00277 /* harness completes a set of tests). This checking may be unreliable */ 00278 /* if the testing is done in a multi-thread environment. */ 00279 #endif 00280 00281 #if DECCHECK 00282 /* Optional operand checking routines. Enabling these means that */ 00283 /* decNumber and decContext operands to operator routines are checked */ 00284 /* for correctness. This roughly doubles the execution time of the */ 00285 /* fastest routines (and adds 600+ bytes), so should not normally be */ 00286 /* used in 'production'. */ 00287 #define DECUNUSED (void *)(0xffffffff) 00288 static Flag decCheckOperands (decNumber *, const decNumber *, 00289 const decNumber *, decContext *); 00290 static Flag decCheckNumber (const decNumber *, decContext *); 00291 #endif 00292 00293 #if DECTRACE || DECCHECK 00294 /* Optional trace/debugging routines. */ 00295 void decNumberShow (const decNumber *); /* displays the components of a number */ 00296 static void decDumpAr (char, const Unit *, Int); 00297 #endif 00298 00299 /* ================================================================== */ 00300 /* Conversions */ 00301 /* ================================================================== */ 00302 00303 /* ------------------------------------------------------------------ */ 00304 /* to-scientific-string -- conversion to numeric string */ 00305 /* to-engineering-string -- conversion to numeric string */ 00306 /* */ 00307 /* decNumberToString(dn, string); */ 00308 /* decNumberToEngString(dn, string); */ 00309 /* */ 00310 /* dn is the decNumber to convert */ 00311 /* string is the string where the result will be laid out */ 00312 /* */ 00313 /* string must be at least dn->digits+14 characters long */ 00314 /* */ 00315 /* No error is possible, and no status can be set. */ 00316 /* ------------------------------------------------------------------ */ 00317 char * 00318 decNumberToString (const decNumber * dn, char *string) 00319 { 00320 decToString (dn, string, 0); 00321 return string; 00322 } 00323 00324 char * 00325 decNumberToEngString (const decNumber * dn, char *string) 00326 { 00327 decToString (dn, string, 1); 00328 return string; 00329 } 00330 00331 /* ------------------------------------------------------------------ */ 00332 /* to-number -- conversion from numeric string */ 00333 /* */ 00334 /* decNumberFromString -- convert string to decNumber */ 00335 /* dn -- the number structure to fill */ 00336 /* chars[] -- the string to convert ('\0' terminated) */ 00337 /* set -- the context used for processing any error, */ 00338 /* determining the maximum precision available */ 00339 /* (set.digits), determining the maximum and minimum */ 00340 /* exponent (set.emax and set.emin), determining if */ 00341 /* extended values are allowed, and checking the */ 00342 /* rounding mode if overflow occurs or rounding is */ 00343 /* needed. */ 00344 /* */ 00345 /* The length of the coefficient and the size of the exponent are */ 00346 /* checked by this routine, so the correct error (Underflow or */ 00347 /* Overflow) can be reported or rounding applied, as necessary. */ 00348 /* */ 00349 /* If bad syntax is detected, the result will be a quiet NaN. */ 00350 /* ------------------------------------------------------------------ */ 00351 decNumber * 00352 decNumberFromString (decNumber * dn, const char chars[], decContext * set) 00353 { 00354 Int exponent = 0; /* working exponent [assume 0] */ 00355 uByte bits = 0; /* working flags [assume +ve] */ 00356 Unit *res; /* where result will be built */ 00357 Unit resbuff[D2U (DECBUFFER + 1)]; /* local buffer in case need temporary */ 00358 Unit *allocres = NULL; /* -> allocated result, iff allocated */ 00359 Int need; /* units needed for result */ 00360 Int d = 0; /* count of digits found in decimal part */ 00361 const char *dotchar = NULL; /* where dot was found */ 00362 const char *cfirst; /* -> first character of decimal part */ 00363 const char *last = NULL; /* -> last digit of decimal part */ 00364 const char *firstexp; /* -> first significant exponent digit */ 00365 const char *c; /* work */ 00366 Unit *up; /* .. */ 00367 #if DECDPUN>1 00368 Int i; /* .. */ 00369 #endif 00370 Int residue = 0; /* rounding residue */ 00371 uInt status = 0; /* error code */ 00372 00373 #if DECCHECK 00374 if (decCheckOperands (DECUNUSED, DECUNUSED, DECUNUSED, set)) 00375 return decNumberZero (dn); 00376 #endif 00377 00378 do 00379 { /* status & malloc protection */ 00380 c = chars; /* -> input character */ 00381 if (*c == '-') 00382 { /* handle leading '-' */ 00383 bits = DECNEG; 00384 c++; 00385 } 00386 else if (*c == '+') 00387 c++; /* step over leading '+' */ 00388 /* We're at the start of the number [we think] */ 00389 cfirst = c; /* save */ 00390 for (;; c++) 00391 { 00392 if (*c >= '0' && *c <= '9') 00393 { /* test for Arabic digit */ 00394 last = c; 00395 d++; /* count of real digits */ 00396 continue; /* still in decimal part */ 00397 } 00398 if (*c != '.') 00399 break; /* done with decimal part */ 00400 /* dot: record, check, and ignore */ 00401 if (dotchar != NULL) 00402 { /* two dots */ 00403 last = NULL; /* indicate bad */ 00404 break; 00405 } /* .. and go report */ 00406 dotchar = c; /* offset into decimal part */ 00407 } /* c */ 00408 00409 if (last == NULL) 00410 { /* no decimal digits, or >1 . */ 00411 #if DECSUBSET 00412 /* If subset then infinities and NaNs are not allowed */ 00413 if (!set->extended) 00414 { 00415 status = DEC_Conversion_syntax; 00416 break; /* all done */ 00417 } 00418 else 00419 { 00420 #endif 00421 /* Infinities and NaNs are possible, here */ 00422 decNumberZero (dn); /* be optimistic */ 00423 if (decStrEq (c, "Infinity") || decStrEq (c, "Inf")) 00424 { 00425 dn->bits = bits | DECINF; 00426 break; /* all done */ 00427 } 00428 else 00429 { /* a NaN expected */ 00430 /* 2003.09.10 NaNs are now permitted to have a sign */ 00431 status = DEC_Conversion_syntax; /* assume the worst */ 00432 dn->bits = bits | DECNAN; /* assume simple NaN */ 00433 if (*c == 's' || *c == 'S') 00434 { /* looks like an` sNaN */ 00435 c++; 00436 dn->bits = bits | DECSNAN; 00437 } 00438 if (*c != 'n' && *c != 'N') 00439 break; /* check caseless "NaN" */ 00440 c++; 00441 if (*c != 'a' && *c != 'A') 00442 break; /* .. */ 00443 c++; 00444 if (*c != 'n' && *c != 'N') 00445 break; /* .. */ 00446 c++; 00447 /* now nothing, or nnnn, expected */ 00448 /* -> start of integer and skip leading 0s [including plain 0] */ 00449 for (cfirst = c; *cfirst == '0';) 00450 cfirst++; 00451 if (*cfirst == '\0') 00452 { /* "NaN" or "sNaN", maybe with all 0s */ 00453 status = 0; /* it's good */ 00454 break; /* .. */ 00455 } 00456 /* something other than 0s; setup last and d as usual [no dots] */ 00457 for (c = cfirst;; c++, d++) 00458 { 00459 if (*c < '0' || *c > '9') 00460 break; /* test for Arabic digit */ 00461 last = c; 00462 } 00463 if (*c != '\0') 00464 break; /* not all digits */ 00465 if (d > set->digits) 00466 break; /* too many digits */ 00467 /* good; drop through and convert the integer */ 00468 status = 0; 00469 bits = dn->bits; /* for copy-back */ 00470 } /* NaN expected */ 00471 #if DECSUBSET 00472 } 00473 #endif 00474 } /* last==NULL */ 00475 00476 if (*c != '\0') 00477 { /* more there; exponent expected... */ 00478 Flag nege = 0; /* 1=negative exponent */ 00479 if (*c != 'e' && *c != 'E') 00480 { 00481 status = DEC_Conversion_syntax; 00482 break; 00483 } 00484 00485 /* Found 'e' or 'E' -- now process explicit exponent */ 00486 /* 1998.07.11: sign no longer required */ 00487 c++; /* to (expected) sign */ 00488 if (*c == '-') 00489 { 00490 nege = 1; 00491 c++; 00492 } 00493 else if (*c == '+') 00494 c++; 00495 if (*c == '\0') 00496 { 00497 status = DEC_Conversion_syntax; 00498 break; 00499 } 00500 00501 for (; *c == '0' && *(c + 1) != '\0';) 00502 c++; /* strip insignificant zeros */ 00503 firstexp = c; /* save exponent digit place */ 00504 for (;; c++) 00505 { 00506 if (*c < '0' || *c > '9') 00507 break; /* not a digit */ 00508 exponent = X10 (exponent) + (Int) * c - (Int) '0'; 00509 } /* c */ 00510 /* if we didn't end on '\0' must not be a digit */ 00511 if (*c != '\0') 00512 { 00513 status = DEC_Conversion_syntax; 00514 break; 00515 } 00516 00517 /* (this next test must be after the syntax check) */ 00518 /* if it was too long the exponent may have wrapped, so check */ 00519 /* carefully and set it to a certain overflow if wrap possible */ 00520 if (c >= firstexp + 9 + 1) 00521 { 00522 if (c > firstexp + 9 + 1 || *firstexp > '1') 00523 exponent = DECNUMMAXE * 2; 00524 /* [up to 1999999999 is OK, for example 1E-1000000998] */ 00525 } 00526 if (nege) 00527 exponent = -exponent; /* was negative */ 00528 } /* had exponent */ 00529 /* Here when all inspected; syntax is good */ 00530 00531 /* Handle decimal point... */ 00532 if (dotchar != NULL && dotchar < last) /* embedded . found, so */ 00533 exponent = exponent - (last - dotchar); /* .. adjust exponent */ 00534 /* [we can now ignore the .] */ 00535 00536 /* strip leading zeros/dot (leave final if all 0's) */ 00537 for (c = cfirst; c < last; c++) 00538 { 00539 if (*c == '0') 00540 d--; /* 0 stripped */ 00541 else if (*c != '.') 00542 break; 00543 cfirst++; /* step past leader */ 00544 } /* c */ 00545 00546 #if DECSUBSET 00547 /* We can now make a rapid exit for zeros if !extended */ 00548 if (*cfirst == '0' && !set->extended) 00549 { 00550 decNumberZero (dn); /* clean result */ 00551 break; /* [could be return] */ 00552 } 00553 #endif 00554 00555 /* OK, the digits string is good. Copy to the decNumber, or to 00556 a temporary decNumber if rounding is needed */ 00557 if (d <= set->digits) 00558 res = dn->lsu; /* fits into given decNumber */ 00559 else 00560 { /* rounding needed */ 00561 need = D2U (d); /* units needed */ 00562 res = resbuff; /* assume use local buffer */ 00563 if (need * sizeof (Unit) > sizeof (resbuff)) 00564 { /* too big for local */ 00565 allocres = (Unit *) malloc (need * sizeof (Unit)); 00566 if (allocres == NULL) 00567 { 00568 status |= DEC_Insufficient_storage; 00569 break; 00570 } 00571 res = allocres; 00572 } 00573 } 00574 /* res now -> number lsu, buffer, or allocated storage for Unit array */ 00575 00576 /* Place the coefficient into the selected Unit array */ 00577 #if DECDPUN>1 00578 i = d % DECDPUN; /* digits in top unit */ 00579 if (i == 0) 00580 i = DECDPUN; 00581 up = res + D2U (d) - 1; /* -> msu */ 00582 *up = 0; 00583 for (c = cfirst;; c++) 00584 { /* along the digits */ 00585 if (*c == '.') 00586 { /* ignore . [don't decrement i] */ 00587 if (c != last) 00588 continue; 00589 break; 00590 } 00591 *up = (Unit) (X10 (*up) + (Int) * c - (Int) '0'); 00592 i--; 00593 if (i > 0) 00594 continue; /* more for this unit */ 00595 if (up == res) 00596 break; /* just filled the last unit */ 00597 i = DECDPUN; 00598 up--; 00599 *up = 0; 00600 } /* c */ 00601 #else 00602 /* DECDPUN==1 */ 00603 up = res; /* -> lsu */ 00604 for (c = last; c >= cfirst; c--) 00605 { /* over each character, from least */ 00606 if (*c == '.') 00607 continue; /* ignore . [don't step b] */ 00608 *up = (Unit) ((Int) * c - (Int) '0'); 00609 up++; 00610 } /* c */ 00611 #endif 00612 00613 dn->bits = bits; 00614 dn->exponent = exponent; 00615 dn->digits = d; 00616 00617 /* if not in number (too long) shorten into the number */ 00618 if (d > set->digits) 00619 decSetCoeff (dn, set, res, d, &residue, &status); 00620 00621 /* Finally check for overflow or subnormal and round as needed */ 00622 decFinalize (dn, set, &residue, &status); 00623 /* decNumberShow(dn); */ 00624 } 00625 while (0); /* [for break] */ 00626 00627 if (allocres != NULL) 00628 free (allocres); /* drop any storage we used */ 00629 if (status != 0) 00630 decStatus (dn, status, set); 00631 return dn; 00632 } 00633 00634 /* ================================================================== */ 00635 /* Operators */ 00636 /* ================================================================== */ 00637 00638 /* ------------------------------------------------------------------ */ 00639 /* decNumberAbs -- absolute value operator */ 00640 /* */ 00641 /* This computes C = abs(A) */ 00642 /* */ 00643 /* res is C, the result. C may be A */ 00644 /* rhs is A */ 00645 /* set is the context */ 00646 /* */ 00647 /* C must have space for set->digits digits. */ 00648 /* ------------------------------------------------------------------ */ 00649 /* This has the same effect as decNumberPlus unless A is negative, */ 00650 /* in which case it has the same effect as decNumberMinus. */ 00651 /* ------------------------------------------------------------------ */ 00652 decNumber * 00653 decNumberAbs (decNumber * res, const decNumber * rhs, decContext * set) 00654 { 00655 decNumber dzero; /* for 0 */ 00656 uInt status = 0; /* accumulator */ 00657 00658 #if DECCHECK 00659 if (decCheckOperands (res, DECUNUSED, rhs, set)) 00660 return res; 00661 #endif 00662 00663 decNumberZero (&dzero); /* set 0 */ 00664 dzero.exponent = rhs->exponent; /* [no coefficient expansion] */ 00665 decAddOp (res, &dzero, rhs, set, (uByte) (rhs->bits & DECNEG), &status); 00666 if (status != 0) 00667 decStatus (res, status, set); 00668 return res; 00669 } 00670 00671 /* ------------------------------------------------------------------ */ 00672 /* decNumberAdd -- add two Numbers */ 00673 /* */ 00674 /* This computes C = A + B */ 00675 /* */ 00676 /* res is C, the result. C may be A and/or B (e.g., X=X+X) */ 00677 /* lhs is A */ 00678 /* rhs is B */ 00679 /* set is the context */ 00680 /* */ 00681 /* C must have space for set->digits digits. */ 00682 /* ------------------------------------------------------------------ */ 00683 /* This just calls the routine shared with Subtract */ 00684 decNumber * 00685 decNumberAdd (decNumber * res, const decNumber * lhs, 00686 const decNumber * rhs, decContext * set) 00687 { 00688 uInt status = 0; /* accumulator */ 00689 decAddOp (res, lhs, rhs, set, 0, &status); 00690 if (status != 0) 00691 decStatus (res, status, set); 00692 return res; 00693 } 00694 00695 /* ------------------------------------------------------------------ */ 00696 /* decNumberCompare -- compare two Numbers */ 00697 /* */ 00698 /* This computes C = A ? B */ 00699 /* */ 00700 /* res is C, the result. C may be A and/or B (e.g., X=X?X) */ 00701 /* lhs is A */ 00702 /* rhs is B */ 00703 /* set is the context */ 00704 /* */ 00705 /* C must have space for one digit. */ 00706 /* ------------------------------------------------------------------ */ 00707 decNumber * 00708 decNumberCompare (decNumber * res, const decNumber * lhs, 00709 const decNumber * rhs, decContext * set) 00710 { 00711 uInt status = 0; /* accumulator */ 00712 decCompareOp (res, lhs, rhs, set, COMPARE, &status); 00713 if (status != 0) 00714 decStatus (res, status, set); 00715 return res; 00716 } 00717 00718 /* ------------------------------------------------------------------ */ 00719 /* decNumberDivide -- divide one number by another */ 00720 /* */ 00721 /* This computes C = A / B */ 00722 /* */ 00723 /* res is C, the result. C may be A and/or B (e.g., X=X/X) */ 00724 /* lhs is A */ 00725 /* rhs is B */ 00726 /* set is the context */ 00727 /* */ 00728 /* C must have space for set->digits digits. */ 00729 /* ------------------------------------------------------------------ */ 00730 decNumber * 00731 decNumberDivide (decNumber * res, const decNumber * lhs, 00732 const decNumber * rhs, decContext * set) 00733 { 00734 uInt status = 0; /* accumulator */ 00735 decDivideOp (res, lhs, rhs, set, DIVIDE, &status); 00736 if (status != 0) 00737 decStatus (res, status, set); 00738 return res; 00739 } 00740 00741 /* ------------------------------------------------------------------ */ 00742 /* decNumberDivideInteger -- divide and return integer quotient */ 00743 /* */ 00744 /* This computes C = A # B, where # is the integer divide operator */ 00745 /* */ 00746 /* res is C, the result. C may be A and/or B (e.g., X=X#X) */ 00747 /* lhs is A */ 00748 /* rhs is B */ 00749 /* set is the context */ 00750 /* */ 00751 /* C must have space for set->digits digits. */ 00752 /* ------------------------------------------------------------------ */ 00753 decNumber * 00754 decNumberDivideInteger (decNumber * res, const decNumber * lhs, 00755 const decNumber * rhs, decContext * set) 00756 { 00757 uInt status = 0; /* accumulator */ 00758 decDivideOp (res, lhs, rhs, set, DIVIDEINT, &status); 00759 if (status != 0) 00760 decStatus (res, status, set); 00761 return res; 00762 } 00763 00764 /* ------------------------------------------------------------------ */ 00765 /* decNumberMax -- compare two Numbers and return the maximum */ 00766 /* */ 00767 /* This computes C = A ? B, returning the maximum or A if equal */ 00768 /* */ 00769 /* res is C, the result. C may be A and/or B (e.g., X=X?X) */ 00770 /* lhs is A */ 00771 /* rhs is B */ 00772 /* set is the context */ 00773 /* */ 00774 /* C must have space for set->digits digits. */ 00775 /* ------------------------------------------------------------------ */ 00776 decNumber * 00777 decNumberMax (decNumber * res, const decNumber * lhs, 00778 const decNumber * rhs, decContext * set) 00779 { 00780 uInt status = 0; /* accumulator */ 00781 decCompareOp (res, lhs, rhs, set, COMPMAX, &status); 00782 if (status != 0) 00783 decStatus (res, status, set); 00784 return res; 00785 } 00786 00787 /* ------------------------------------------------------------------ */ 00788 /* decNumberMin -- compare two Numbers and return the minimum */ 00789 /* */ 00790 /* This computes C = A ? B, returning the minimum or A if equal */ 00791 /* */ 00792 /* res is C, the result. C may be A and/or B (e.g., X=X?X) */ 00793 /* lhs is A */ 00794 /* rhs is B */ 00795 /* set is the context */ 00796 /* */ 00797 /* C must have space for set->digits digits. */ 00798 /* ------------------------------------------------------------------ */ 00799 decNumber * 00800 decNumberMin (decNumber * res, const decNumber * lhs, 00801 const decNumber * rhs, decContext * set) 00802 { 00803 uInt status = 0; /* accumulator */ 00804 decCompareOp (res, lhs, rhs, set, COMPMIN, &status); 00805 if (status != 0) 00806 decStatus (res, status, set); 00807 return res; 00808 } 00809 00810 /* ------------------------------------------------------------------ */ 00811 /* decNumberMinus -- prefix minus operator */ 00812 /* */ 00813 /* This computes C = 0 - A */ 00814 /* */ 00815 /* res is C, the result. C may be A */ 00816 /* rhs is A */ 00817 /* set is the context */ 00818 /* */ 00819 /* C must have space for set->digits digits. */ 00820 /* ------------------------------------------------------------------ */ 00821 /* We simply use AddOp for the subtract, which will do the necessary. */ 00822 /* ------------------------------------------------------------------ */ 00823 decNumber * 00824 decNumberMinus (decNumber * res, const decNumber * rhs, decContext * set) 00825 { 00826 decNumber dzero; 00827 uInt status = 0; /* accumulator */ 00828 00829 #if DECCHECK 00830 if (decCheckOperands (res, DECUNUSED, rhs, set)) 00831 return res; 00832 #endif 00833 00834 decNumberZero (&dzero); /* make 0 */ 00835 dzero.exponent = rhs->exponent; /* [no coefficient expansion] */ 00836 decAddOp (res, &dzero, rhs, set, DECNEG, &status); 00837 if (status != 0) 00838 decStatus (res, status, set); 00839 return res; 00840 } 00841 00842 /* ------------------------------------------------------------------ */ 00843 /* decNumberPlus -- prefix plus operator */ 00844 /* */ 00845 /* This computes C = 0 + A */ 00846 /* */ 00847 /* res is C, the result. C may be A */ 00848 /* rhs is A */ 00849 /* set is the context */ 00850 /* */ 00851 /* C must have space for set->digits digits. */ 00852 /* ------------------------------------------------------------------ */ 00853 /* We simply use AddOp; Add will take fast path after preparing A. */ 00854 /* Performance is a concern here, as this routine is often used to */ 00855 /* check operands and apply rounding and overflow/underflow testing. */ 00856 /* ------------------------------------------------------------------ */ 00857 decNumber * 00858 decNumberPlus (decNumber * res, const decNumber * rhs, decContext * set) 00859 { 00860 decNumber dzero; 00861 uInt status = 0; /* accumulator */ 00862 00863 #if DECCHECK 00864 if (decCheckOperands (res, DECUNUSED, rhs, set)) 00865 return res; 00866 #endif 00867 00868 decNumberZero (&dzero); /* make 0 */ 00869 dzero.exponent = rhs->exponent; /* [no coefficient expansion] */ 00870 decAddOp (res, &dzero, rhs, set, 0, &status); 00871 if (status != 0) 00872 decStatus (res, status, set); 00873 return res; 00874 } 00875 00876 /* ------------------------------------------------------------------ */ 00877 /* decNumberMultiply -- multiply two Numbers */ 00878 /* */ 00879 /* This computes C = A x B */ 00880 /* */ 00881 /* res is C, the result. C may be A and/or B (e.g., X=X+X) */ 00882 /* lhs is A */ 00883 /* rhs is B */ 00884 /* set is the context */ 00885 /* */ 00886 /* C must have space for set->digits digits. */ 00887 /* ------------------------------------------------------------------ */ 00888 decNumber * 00889 decNumberMultiply (decNumber * res, const decNumber * lhs, 00890 const decNumber * rhs, decContext * set) 00891 { 00892 uInt status = 0; /* accumulator */ 00893 decMultiplyOp (res, lhs, rhs, set, &status); 00894 if (status != 0) 00895 decStatus (res, status, set); 00896 return res; 00897 } 00898 00899 /* ------------------------------------------------------------------ */ 00900 /* decNumberNormalize -- remove trailing zeros */ 00901 /* */ 00902 /* This computes C = 0 + A, and normalizes the result */ 00903 /* */ 00904 /* res is C, the result. C may be A */ 00905 /* rhs is A */ 00906 /* set is the context */ 00907 /* */ 00908 /* C must have space for set->digits digits. */ 00909 /* ------------------------------------------------------------------ */ 00910 decNumber * 00911 decNumberNormalize (decNumber * res, const decNumber * rhs, decContext * set) 00912 { 00913 decNumber *allocrhs = NULL; /* non-NULL if rounded rhs allocated */ 00914 uInt status = 0; /* as usual */ 00915 Int residue = 0; /* as usual */ 00916 Int dropped; /* work */ 00917 00918 #if DECCHECK 00919 if (decCheckOperands (res, DECUNUSED, rhs, set)) 00920 return res; 00921 #endif 00922 00923 do 00924 { /* protect allocated storage */ 00925 #if DECSUBSET 00926 if (!set->extended) 00927 { 00928 /* reduce operand and set lostDigits status, as needed */ 00929 if (rhs->digits > set->digits) 00930 { 00931 allocrhs = decRoundOperand (rhs, set, &status); 00932 if (allocrhs == NULL) 00933 break; 00934 rhs = allocrhs; 00935 } 00936 } 00937 #endif 00938 /* [following code does not require input rounding] */ 00939 00940 /* specials copy through, except NaNs need care */ 00941 if (decNumberIsNaN (rhs)) 00942 { 00943 decNaNs (res, rhs, NULL, &status); 00944 break; 00945 } 00946 00947 /* reduce result to the requested length and copy to result */ 00948 decCopyFit (res, rhs, set, &residue, &status); /* copy & round */ 00949 decFinish (res, set, &residue, &status); /* cleanup/set flags */ 00950 decTrim (res, 1, &dropped); /* normalize in place */ 00951 } 00952 while (0); /* end protected */ 00953 00954 if (allocrhs != NULL) 00955 free (allocrhs); /* .. */ 00956 if (status != 0) 00957 decStatus (res, status, set); /* then report status */ 00958 return res; 00959 } 00960 00961 /* ------------------------------------------------------------------ */ 00962 /* decNumberPower -- raise a number to an integer power */ 00963 /* */ 00964 /* This computes C = A ** B */ 00965 /* */ 00966 /* res is C, the result. C may be A and/or B (e.g., X=X**X) */ 00967 /* lhs is A */ 00968 /* rhs is B */ 00969 /* set is the context */ 00970 /* */ 00971 /* C must have space for set->digits digits. */ 00972 /* */ 00973 /* Specification restriction: abs(n) must be <=999999999 */ 00974 /* ------------------------------------------------------------------ */ 00975 decNumber * 00976 decNumberPower (decNumber * res, const decNumber * lhs, 00977 const decNumber * rhs, decContext * set) 00978 { 00979 decNumber *alloclhs = NULL; /* non-NULL if rounded lhs allocated */ 00980 decNumber *allocrhs = NULL; /* .., rhs */ 00981 decNumber *allocdac = NULL; /* -> allocated acc buffer, iff used */ 00982 const decNumber *inrhs = rhs; /* save original rhs */ 00983 Int reqdigits = set->digits; /* requested DIGITS */ 00984 Int n; /* RHS in binary */ 00985 Int i; /* work */ 00986 #if DECSUBSET 00987 Int dropped; /* .. */ 00988 #endif 00989 uInt needbytes; /* buffer size needed */ 00990 Flag seenbit; /* seen a bit while powering */ 00991 Int residue = 0; /* rounding residue */ 00992 uInt status = 0; /* accumulator */ 00993 uByte bits = 0; /* result sign if errors */ 00994 decContext workset; /* working context */ 00995 decNumber dnOne; /* work value 1... */ 00996 /* local accumulator buffer [a decNumber, with digits+elength+1 digits] */ 00997 uByte dacbuff[sizeof (decNumber) + D2U (DECBUFFER + 9) * sizeof (Unit)]; 00998 /* same again for possible 1/lhs calculation */ 00999 uByte lhsbuff[sizeof (decNumber) + D2U (DECBUFFER + 9) * sizeof (Unit)]; 01000 decNumber *dac = (decNumber *) dacbuff; /* -> result accumulator */ 01001 01002 #if DECCHECK 01003 if (decCheckOperands (res, lhs, rhs, set)) 01004 return res; 01005 #endif 01006 01007 do 01008 { /* protect allocated storage */ 01009 #if DECSUBSET 01010 if (!set->extended) 01011 { 01012 /* reduce operands and set lostDigits status, as needed */ 01013 if (lhs->digits > reqdigits) 01014 { 01015 alloclhs = decRoundOperand (lhs, set, &status); 01016 if (alloclhs == NULL) 01017 break; 01018 lhs = alloclhs; 01019 } 01020 /* rounding won't affect the result, but we might signal lostDigits */ 01021 /* as well as the error for non-integer [x**y would need this too] */ 01022 if (rhs->digits > reqdigits) 01023 { 01024 allocrhs = decRoundOperand (rhs, set, &status); 01025 if (allocrhs == NULL) 01026 break; 01027 rhs = allocrhs; 01028 } 01029 } 01030 #endif 01031 /* [following code does not require input rounding] */ 01032 01033 /* handle rhs Infinity */ 01034 if (decNumberIsInfinite (rhs)) 01035 { 01036 status |= DEC_Invalid_operation; /* bad */ 01037 break; 01038 } 01039 /* handle NaNs */ 01040 if ((lhs->bits | rhs->bits) & (DECNAN | DECSNAN)) 01041 { 01042 decNaNs (res, lhs, rhs, &status); 01043 break; 01044 } 01045 01046 /* Original rhs must be an integer that fits and is in range */ 01047 #if DECSUBSET 01048 n = decGetInt (inrhs, set); 01049 #else 01050 n = decGetInt (inrhs); 01051 #endif 01052 if (n == BADINT || n > 999999999 || n < -999999999) 01053 { 01054 status |= DEC_Invalid_operation; 01055 break; 01056 } 01057 if (n < 0) 01058 { /* negative */ 01059 n = -n; /* use the absolute value */ 01060 } 01061 if (decNumberIsNegative (lhs) /* -x .. */ 01062 && (n & 0x00000001)) 01063 bits = DECNEG; /* .. to an odd power */ 01064 01065 /* handle LHS infinity */ 01066 if (decNumberIsInfinite (lhs)) 01067 { /* [NaNs already handled] */ 01068 uByte rbits = rhs->bits; /* save */ 01069 decNumberZero (res); 01070 if (n == 0) 01071 *res->lsu = 1; /* [-]Inf**0 => 1 */ 01072 else 01073 { 01074 if (!(rbits & DECNEG)) 01075 bits |= DECINF; /* was not a **-n */ 01076 /* [otherwise will be 0 or -0] */ 01077 res->bits = bits; 01078 } 01079 break; 01080 } 01081 01082 /* clone the context */ 01083 workset = *set; /* copy all fields */ 01084 /* calculate the working DIGITS */ 01085 workset.digits = reqdigits + (inrhs->digits + inrhs->exponent) + 1; 01086 /* it's an error if this is more than we can handle */ 01087 if (workset.digits > DECNUMMAXP) 01088 { 01089 status |= DEC_Invalid_operation; 01090 break; 01091 } 01092 01093 /* workset.digits is the count of digits for the accumulator we need */ 01094 /* if accumulator is too long for local storage, then allocate */ 01095 needbytes = 01096 sizeof (decNumber) + (D2U (workset.digits) - 1) * sizeof (Unit); 01097 /* [needbytes also used below if 1/lhs needed] */ 01098 if (needbytes > sizeof (dacbuff)) 01099 { 01100 allocdac = (decNumber *) malloc (needbytes); 01101 if (allocdac == NULL) 01102 { /* hopeless -- abandon */ 01103 status |= DEC_Insufficient_storage; 01104 break; 01105 } 01106 dac = allocdac; /* use the allocated space */ 01107 } 01108 decNumberZero (dac); /* acc=1 */ 01109 *dac->lsu = 1; /* .. */ 01110 01111 if (n == 0) 01112 { /* x**0 is usually 1 */ 01113 /* 0**0 is bad unless subset, when it becomes 1 */ 01114 if (ISZERO (lhs) 01115 #if DECSUBSET 01116 && set->extended 01117 #endif 01118 ) 01119 status |= DEC_Invalid_operation; 01120 else 01121 decNumberCopy (res, dac); /* copy the 1 */ 01122 break; 01123 } 01124 01125 /* if a negative power we'll need the constant 1, and if not subset */ 01126 /* we'll invert the lhs now rather than inverting the result later */ 01127 if (decNumberIsNegative (rhs)) 01128 { /* was a **-n [hence digits>0] */ 01129 decNumber * newlhs; 01130 decNumberCopy (&dnOne, dac); /* dnOne=1; [needed now or later] */ 01131 #if DECSUBSET 01132 if (set->extended) 01133 { /* need to calculate 1/lhs */ 01134 #endif 01135 /* divide lhs into 1, putting result in dac [dac=1/dac] */ 01136 decDivideOp (dac, &dnOne, lhs, &workset, DIVIDE, &status); 01137 if (alloclhs != NULL) 01138 { 01139 free (alloclhs); /* done with intermediate */ 01140 alloclhs = NULL; /* indicate freed */ 01141 } 01142 /* now locate or allocate space for the inverted lhs */ 01143 if (needbytes > sizeof (lhsbuff)) 01144 { 01145 alloclhs = (decNumber *) malloc (needbytes); 01146 if (alloclhs == NULL) 01147 { /* hopeless -- abandon */ 01148 status |= DEC_Insufficient_storage; 01149 break; 01150 } 01151 newlhs = alloclhs; /* use the allocated space */ 01152 } 01153 else 01154 newlhs = (decNumber *) lhsbuff; /* use stack storage */ 01155 /* [lhs now points to buffer or allocated storage] */ 01156 decNumberCopy (newlhs, dac); /* copy the 1/lhs */ 01157 decNumberCopy (dac, &dnOne); /* restore acc=1 */ 01158 lhs = newlhs; 01159 #if DECSUBSET 01160 } 01161 #endif 01162 } 01163 01164 /* Raise-to-the-power loop... */ 01165 seenbit = 0; /* set once we've seen a 1-bit */ 01166 for (i = 1;; i++) 01167 { /* for each bit [top bit ignored] */ 01168 /* abandon if we have had overflow or terminal underflow */ 01169 if (status & (DEC_Overflow | DEC_Underflow)) 01170 { /* interesting? */ 01171 if (status & DEC_Overflow || ISZERO (dac)) 01172 break; 01173 } 01174 /* [the following two lines revealed an optimizer bug in a C++ */ 01175 /* compiler, with symptom: 5**3 -> 25, when n=n+n was used] */ 01176 n = n << 1; /* move next bit to testable position */ 01177 if (n < 0) 01178 { /* top bit is set */ 01179 seenbit = 1; /* OK, we're off */ 01180 decMultiplyOp (dac, dac, lhs, &workset, &status); /* dac=dac*x */ 01181 } 01182 if (i == 31) 01183 break; /* that was the last bit */ 01184 if (!seenbit) 01185 continue; /* we don't have to square 1 */ 01186 decMultiplyOp (dac, dac, dac, &workset, &status); /* dac=dac*dac [square] */ 01187 } /*i *//* 32 bits */ 01188 01189 /* complete internal overflow or underflow processing */ 01190 if (status & (DEC_Overflow | DEC_Subnormal)) 01191 { 01192 #if DECSUBSET 01193 /* If subset, and power was negative, reverse the kind of -erflow */ 01194 /* [1/x not yet done] */ 01195 if (!set->extended && decNumberIsNegative (rhs)) 01196 { 01197 if (status & DEC_Overflow) 01198 status ^= DEC_Overflow | DEC_Underflow | DEC_Subnormal; 01199 else 01200 { /* trickier -- Underflow may or may not be set */ 01201 status &= ~(DEC_Underflow | DEC_Subnormal); /* [one or both] */ 01202 status |= DEC_Overflow; 01203 } 01204 } 01205 #endif 01206 dac->bits = (dac->bits & ~DECNEG) | bits; /* force correct sign */ 01207 /* round subnormals [to set.digits rather than workset.digits] */ 01208 /* or set overflow result similarly as required */ 01209 decFinalize (dac, set, &residue, &status); 01210 decNumberCopy (res, dac); /* copy to result (is now OK length) */ 01211 break; 01212 } 01213 01214 #if DECSUBSET 01215 if (!set->extended && /* subset math */ 01216 decNumberIsNegative (rhs)) 01217 { /* was a **-n [hence digits>0] */ 01218 /* so divide result into 1 [dac=1/dac] */ 01219 decDivideOp (dac, &dnOne, dac, &workset, DIVIDE, &status); 01220 } 01221 #endif 01222 01223 /* reduce result to the requested length and copy to result */ 01224 decCopyFit (res, dac, set, &residue, &status); 01225 decFinish (res, set, &residue, &status); /* final cleanup */ 01226 #if DECSUBSET 01227 if (!set->extended) 01228 decTrim (res, 0, &dropped); /* trailing zeros */ 01229 #endif 01230 } 01231 while (0); /* end protected */ 01232 01233 if (allocdac != NULL) 01234 free (allocdac); /* drop any storage we used */ 01235 if (allocrhs != NULL) 01236 free (allocrhs); /* .. */ 01237 if (alloclhs != NULL) 01238 free (alloclhs); /* .. */ 01239 if (status != 0) 01240 decStatus (res, status, set); 01241 return res; 01242 } 01243 01244 /* ------------------------------------------------------------------ */ 01245 /* decNumberQuantize -- force exponent to requested value */ 01246 /* */ 01247 /* This computes C = op(A, B), where op adjusts the coefficient */ 01248 /* of C (by rounding or shifting) such that the exponent (-scale) */ 01249 /* of C has exponent of B. The numerical value of C will equal A, */ 01250 /* except for the effects of any rounding that occurred. */ 01251 /* */ 01252 /* res is C, the result. C may be A or B */ 01253 /* lhs is A, the number to adjust */ 01254 /* rhs is B, the number with exponent to match */ 01255 /* set is the context */ 01256 /* */ 01257 /* C must have space for set->digits digits. */ 01258 /* */ 01259 /* Unless there is an error or the result is infinite, the exponent */ 01260 /* after the operation is guaranteed to be equal to that of B. */ 01261 /* ------------------------------------------------------------------ */ 01262 decNumber * 01263 decNumberQuantize (decNumber * res, const decNumber * lhs, 01264 const decNumber * rhs, decContext * set) 01265 { 01266 uInt status = 0; /* accumulator */ 01267 decQuantizeOp (res, lhs, rhs, set, 1, &status); 01268 if (status != 0) 01269 decStatus (res, status, set); 01270 return res; 01271 } 01272 01273 /* ------------------------------------------------------------------ */ 01274 /* decNumberRescale -- force exponent to requested value */ 01275 /* */ 01276 /* This computes C = op(A, B), where op adjusts the coefficient */ 01277 /* of C (by rounding or shifting) such that the exponent (-scale) */ 01278 /* of C has the value B. The numerical value of C will equal A, */ 01279 /* except for the effects of any rounding that occurred. */ 01280 /* */ 01281 /* res is C, the result. C may be A or B */ 01282 /* lhs is A, the number to adjust */ 01283 /* rhs is B, the requested exponent */ 01284 /* set is the context */ 01285 /* */ 01286 /* C must have space for set->digits digits. */ 01287 /* */ 01288 /* Unless there is an error or the result is infinite, the exponent */ 01289 /* after the operation is guaranteed to be equal to B. */ 01290 /* ------------------------------------------------------------------ */ 01291 decNumber * 01292 decNumberRescale (decNumber * res, const decNumber * lhs, 01293 const decNumber * rhs, decContext * set) 01294 { 01295 uInt status = 0; /* accumulator */ 01296 decQuantizeOp (res, lhs, rhs, set, 0, &status); 01297 if (status != 0) 01298 decStatus (res, status, set); 01299 return res; 01300 } 01301 01302 /* ------------------------------------------------------------------ */ 01303 /* decNumberRemainder -- divide and return remainder */ 01304 /* */ 01305 /* This computes C = A % B */ 01306 /* */ 01307 /* res is C, the result. C may be A and/or B (e.g., X=X%X) */ 01308 /* lhs is A */ 01309 /* rhs is B */ 01310 /* set is the context */ 01311 /* */ 01312 /* C must have space for set->digits digits. */ 01313 /* ------------------------------------------------------------------ */ 01314 decNumber * 01315 decNumberRemainder (decNumber * res, const decNumber * lhs, 01316 const decNumber * rhs, decContext * set) 01317 { 01318 uInt status = 0; /* accumulator */ 01319 decDivideOp (res, lhs, rhs, set, REMAINDER, &status); 01320 if (status != 0) 01321 decStatus (res, status, set); 01322 return res; 01323 } 01324 01325 /* ------------------------------------------------------------------ */ 01326 /* decNumberRemainderNear -- divide and return remainder from nearest */ 01327 /* */ 01328 /* This computes C = A % B, where % is the IEEE remainder operator */ 01329 /* */ 01330 /* res is C, the result. C may be A and/or B (e.g., X=X%X) */ 01331 /* lhs is A */ 01332 /* rhs is B */ 01333 /* set is the context */ 01334 /* */ 01335 /* C must have space for set->digits digits. */ 01336 /* ------------------------------------------------------------------ */ 01337 decNumber * 01338 decNumberRemainderNear (decNumber * res, const decNumber * lhs, 01339 const decNumber * rhs, decContext * set) 01340 { 01341 uInt status = 0; /* accumulator */ 01342 decDivideOp (res, lhs, rhs, set, REMNEAR, &status); 01343 if (status != 0) 01344 decStatus (res, status, set); 01345 return res; 01346 } 01347 01348 /* ------------------------------------------------------------------ */ 01349 /* decNumberSameQuantum -- test for equal exponents */ 01350 /* */ 01351 /* res is the result number, which will contain either 0 or 1 */ 01352 /* lhs is a number to test */ 01353 /* rhs is the second (usually a pattern) */ 01354 /* */ 01355 /* No errors are possible and no context is needed. */ 01356 /* ------------------------------------------------------------------ */ 01357 decNumber * 01358 decNumberSameQuantum (decNumber * res, const decNumber * lhs, const decNumber * rhs) 01359 { 01360 uByte merged; /* merged flags */ 01361 Unit ret = 0; /* return value */ 01362 01363 #if DECCHECK 01364 if (decCheckOperands (res, lhs, rhs, DECUNUSED)) 01365 return res; 01366 #endif 01367 01368 merged = (lhs->bits | rhs->bits) & DECSPECIAL; 01369 if (merged) 01370 { 01371 if (decNumberIsNaN (lhs) && decNumberIsNaN (rhs)) 01372 ret = 1; 01373 else if (decNumberIsInfinite (lhs) && decNumberIsInfinite (rhs)) 01374 ret = 1; 01375 /* [anything else with a special gives 0] */ 01376 } 01377 else if (lhs->exponent == rhs->exponent) 01378 ret = 1; 01379 01380 decNumberZero (res); /* OK to overwrite an operand */ 01381 *res->lsu = ret; 01382 return res; 01383 } 01384 01385 /* ------------------------------------------------------------------ */ 01386 /* decNumberSquareRoot -- square root operator */ 01387 /* */ 01388 /* This computes C = squareroot(A) */ 01389 /* */ 01390 /* res is C, the result. C may be A */ 01391 /* rhs is A */ 01392 /* set is the context; note that rounding mode has no effect */ 01393 /* */ 01394 /* C must have space for set->digits digits. */ 01395 /* ------------------------------------------------------------------ */ 01396 /* This uses the following varying-precision algorithm in: */ 01397 /* */ 01398 /* Properly Rounded Variable Precision Square Root, T. E. Hull and */ 01399 /* A. Abrham, ACM Transactions on Mathematical Software, Vol 11 #3, */ 01400 /* pp229-237, ACM, September 1985. */ 01401 /* */ 01402 /* % [Reformatted original Numerical Turing source code follows.] */ 01403 /* function sqrt(x : real) : real */ 01404 /* % sqrt(x) returns the properly rounded approximation to the square */ 01405 /* % root of x, in the precision of the calling environment, or it */ 01406 /* % fails if x < 0. */ 01407 /* % t e hull and a abrham, august, 1984 */ 01408 /* if x <= 0 then */ 01409 /* if x < 0 then */ 01410 /* assert false */ 01411 /* else */ 01412 /* result 0 */ 01413 /* end if */ 01414 /* end if */ 01415 /* var f := setexp(x, 0) % fraction part of x [0.1 <= x < 1] */ 01416 /* var e := getexp(x) % exponent part of x */ 01417 /* var approx : real */ 01418 /* if e mod 2 = 0 then */ 01419 /* approx := .259 + .819 * f % approx to root of f */ 01420 /* else */ 01421 /* f := f/l0 % adjustments */ 01422 /* e := e + 1 % for odd */ 01423 /* approx := .0819 + 2.59 * f % exponent */ 01424 /* end if */ 01425 /* */ 01426 /* var p:= 3 */ 01427 /* const maxp := currentprecision + 2 */ 01428 /* loop */ 01429 /* p := min(2*p - 2, maxp) % p = 4,6,10, . . . , maxp */ 01430 /* precision p */ 01431 /* approx := .5 * (approx + f/approx) */ 01432 /* exit when p = maxp */ 01433 /* end loop */ 01434 /* */ 01435 /* % approx is now within 1 ulp of the properly rounded square root */ 01436 /* % of f; to ensure proper rounding, compare squares of (approx - */ 01437 /* % l/2 ulp) and (approx + l/2 ulp) with f. */ 01438 /* p := currentprecision */ 01439 /* begin */ 01440 /* precision p + 2 */ 01441 /* const approxsubhalf := approx - setexp(.5, -p) */ 01442 /* if mulru(approxsubhalf, approxsubhalf) > f then */ 01443 /* approx := approx - setexp(.l, -p + 1) */ 01444 /* else */ 01445 /* const approxaddhalf := approx + setexp(.5, -p) */ 01446 /* if mulrd(approxaddhalf, approxaddhalf) < f then */ 01447 /* approx := approx + setexp(.l, -p + 1) */ 01448 /* end if */ 01449 /* end if */ 01450 /* end */ 01451 /* result setexp(approx, e div 2) % fix exponent */ 01452 /* end sqrt */ 01453 /* ------------------------------------------------------------------ */ 01454 decNumber * 01455 decNumberSquareRoot (decNumber * res, const decNumber * rhs, decContext * set) 01456 { 01457 decContext workset, approxset; /* work contexts */ 01458 decNumber dzero; /* used for constant zero */ 01459 Int maxp = set->digits + 2; /* largest working precision */ 01460 Int residue = 0; /* rounding residue */ 01461 uInt status = 0, ignore = 0; /* status accumulators */ 01462 Int exp; /* working exponent */ 01463 Int ideal; /* ideal (preferred) exponent */ 01464 uInt needbytes; /* work */ 01465 Int dropped; /* .. */ 01466 01467 decNumber *allocrhs = NULL; /* non-NULL if rounded rhs allocated */ 01468 /* buffer for f [needs +1 in case DECBUFFER 0] */ 01469 uByte buff[sizeof (decNumber) + (D2U (DECBUFFER + 1) - 1) * sizeof (Unit)]; 01470 /* buffer for a [needs +2 to match maxp] */ 01471 uByte bufa[sizeof (decNumber) + (D2U (DECBUFFER + 2) - 1) * sizeof (Unit)]; 01472 /* buffer for temporary, b [must be same size as a] */ 01473 uByte bufb[sizeof (decNumber) + (D2U (DECBUFFER + 2) - 1) * sizeof (Unit)]; 01474 decNumber *allocbuff = NULL; /* -> allocated buff, iff allocated */ 01475 decNumber *allocbufa = NULL; /* -> allocated bufa, iff allocated */ 01476 decNumber *allocbufb = NULL; /* -> allocated bufb, iff allocated */ 01477 decNumber *f = (decNumber *) buff; /* reduced fraction */ 01478 decNumber *a = (decNumber *) bufa; /* approximation to result */ 01479 decNumber *b = (decNumber *) bufb; /* intermediate result */ 01480 /* buffer for temporary variable, up to 3 digits */ 01481 uByte buft[sizeof (decNumber) + (D2U (3) - 1) * sizeof (Unit)]; 01482 decNumber *t = (decNumber *) buft; /* up-to-3-digit constant or work */ 01483 01484 #if DECCHECK 01485 if (decCheckOperands (res, DECUNUSED, rhs, set)) 01486 return res; 01487 #endif 01488 01489 do 01490 { /* protect allocated storage */ 01491 #if DECSUBSET 01492 if (!set->extended) 01493 { 01494 /* reduce operand and set lostDigits status, as needed */ 01495 if (rhs->digits > set->digits) 01496 { 01497 allocrhs = decRoundOperand (rhs, set, &status); 01498 if (allocrhs == NULL) 01499 break; 01500 /* [Note: 'f' allocation below could reuse this buffer if */ 01501 /* used, but as this is rare we keep them separate for clarity.] */ 01502 rhs = allocrhs; 01503 } 01504 } 01505 #endif 01506 /* [following code does not require input rounding] */ 01507 01508 /* handle infinities and NaNs */ 01509 if (rhs->bits & DECSPECIAL) 01510 { 01511 if (decNumberIsInfinite (rhs)) 01512 { /* an infinity */ 01513 if (decNumberIsNegative (rhs)) 01514 status |= DEC_Invalid_operation; 01515 else 01516 decNumberCopy (res, rhs); /* +Infinity */ 01517 } 01518 else 01519 decNaNs (res, rhs, NULL, &status); /* a NaN */ 01520 break; 01521 } 01522 01523 /* calculate the ideal (preferred) exponent [floor(exp/2)] */ 01524 /* [We would like to write: ideal=rhs->exponent>>1, but this */ 01525 /* generates a compiler warning. Generated code is the same.] */ 01526 ideal = (rhs->exponent & ~1) / 2; /* target */ 01527 01528 /* handle zeros */ 01529 if (ISZERO (rhs)) 01530 { 01531 decNumberCopy (res, rhs); /* could be 0 or -0 */ 01532 res->exponent = ideal; /* use the ideal [safe] */ 01533 break; 01534 } 01535 01536 /* any other -x is an oops */ 01537 if (decNumberIsNegative (rhs)) 01538 { 01539 status |= DEC_Invalid_operation; 01540 break; 01541 } 01542 01543 /* we need space for three working variables */ 01544 /* f -- the same precision as the RHS, reduced to 0.01->0.99... */ 01545 /* a -- Hull's approx -- precision, when assigned, is */ 01546 /* currentprecision (we allow +2 for use as temporary) */ 01547 /* b -- intermediate temporary result */ 01548 /* if any is too long for local storage, then allocate */ 01549 needbytes = 01550 sizeof (decNumber) + (D2U (rhs->digits) - 1) * sizeof (Unit); 01551 if (needbytes > sizeof (buff)) 01552 { 01553 allocbuff = (decNumber *) malloc (needbytes); 01554 if (allocbuff == NULL) 01555 { /* hopeless -- abandon */ 01556 status |= DEC_Insufficient_storage; 01557 break; 01558 } 01559 f = allocbuff; /* use the allocated space */ 01560 } 01561 /* a and b both need to be able to hold a maxp-length number */ 01562 needbytes = sizeof (decNumber) + (D2U (maxp) - 1) * sizeof (Unit); 01563 if (needbytes > sizeof (bufa)) 01564 { /* [same applies to b] */ 01565 allocbufa = (decNumber *) malloc (needbytes); 01566 allocbufb = (decNumber *) malloc (needbytes); 01567 if (allocbufa == NULL || allocbufb == NULL) 01568 { /* hopeless */ 01569 status |= DEC_Insufficient_storage; 01570 break; 01571 } 01572 a = allocbufa; /* use the allocated space */ 01573 b = allocbufb; /* .. */ 01574 } 01575 01576 /* copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1 */ 01577 decNumberCopy (f, rhs); 01578 exp = f->exponent + f->digits; /* adjusted to Hull rules */ 01579 f->exponent = -(f->digits); /* to range */ 01580 01581 /* set up working contexts (the second is used for Numerical */ 01582 /* Turing assignment) */ 01583 decContextDefault (&workset, DEC_INIT_DECIMAL64); 01584 decContextDefault (&approxset, DEC_INIT_DECIMAL64); 01585 approxset.digits = set->digits; /* approx's length */ 01586 01587 /* [Until further notice, no error is possible and status bits */ 01588 /* (Rounded, etc.) should be ignored, not accumulated.] */ 01589 01590 /* Calculate initial approximation, and allow for odd exponent */ 01591 workset.digits = set->digits; /* p for initial calculation */ 01592 t->bits = 0; 01593 t->digits = 3; 01594 a->bits = 0; 01595 a->digits = 3; 01596 if ((exp & 1) == 0) 01597 { /* even exponent */ 01598 /* Set t=0.259, a=0.819 */ 01599 t->exponent = -3; 01600 a->exponent = -3; 01601 #if DECDPUN>=3 01602 t->lsu[0] = 259; 01603 a->lsu[0] = 819; 01604 #elif DECDPUN==2 01605 t->lsu[0] = 59; 01606 t->lsu[1] = 2; 01607 a->lsu[0] = 19; 01608 a->lsu[1] = 8; 01609 #else 01610 t->lsu[0] = 9; 01611 t->lsu[1] = 5; 01612 t->lsu[2] = 2; 01613 a->lsu[0] = 9; 01614 a->lsu[1] = 1; 01615 a->lsu[2] = 8; 01616 #endif 01617 } 01618 else 01619 { /* odd exponent */ 01620 /* Set t=0.0819, a=2.59 */ 01621 f->exponent--; /* f=f/10 */ 01622 exp++; /* e=e+1 */ 01623 t->exponent = -4; 01624 a->exponent = -2; 01625 #if DECDPUN>=3 01626 t->lsu[0] = 819; 01627 a->lsu[0] = 259; 01628 #elif DECDPUN==2 01629 t->lsu[0] = 19; 01630 t->lsu[1] = 8; 01631 a->lsu[0] = 59; 01632 a->lsu[1] = 2; 01633 #else 01634 t->lsu[0] = 9; 01635 t->lsu[1] = 1; 01636 t->lsu[2] = 8; 01637 a->lsu[0] = 9; 01638 a->lsu[1] = 5; 01639 a->lsu[2] = 2; 01640 #endif 01641 } 01642 decMultiplyOp (a, a, f, &workset, &ignore); /* a=a*f */ 01643 decAddOp (a, a, t, &workset, 0, &ignore); /* ..+t */ 01644 /* [a is now the initial approximation for sqrt(f), calculated with */ 01645 /* currentprecision, which is also a's precision.] */ 01646 01647 /* the main calculation loop */ 01648 decNumberZero (&dzero); /* make 0 */ 01649 decNumberZero (t); /* set t = 0.5 */ 01650 t->lsu[0] = 5; /* .. */ 01651 t->exponent = -1; /* .. */ 01652 workset.digits = 3; /* initial p */ 01653 for (;;) 01654 { 01655 /* set p to min(2*p - 2, maxp) [hence 3; or: 4, 6, 10, ... , maxp] */ 01656 workset.digits = workset.digits * 2 - 2; 01657 if (workset.digits > maxp) 01658 workset.digits = maxp; 01659 /* a = 0.5 * (a + f/a) */ 01660 /* [calculated at p then rounded to currentprecision] */ 01661 decDivideOp (b, f, a, &workset, DIVIDE, &ignore); /* b=f/a */ 01662 decAddOp (b, b, a, &workset, 0, &ignore); /* b=b+a */ 01663 decMultiplyOp (a, b, t, &workset, &ignore); /* a=b*0.5 */ 01664 /* assign to approx [round to length] */ 01665 decAddOp (a, &dzero, a, &approxset, 0, &ignore); 01666 if (workset.digits == maxp) 01667 break; /* just did final */ 01668 } /* loop */ 01669 01670 /* a is now at currentprecision and within 1 ulp of the properly */ 01671 /* rounded square root of f; to ensure proper rounding, compare */ 01672 /* squares of (a - l/2 ulp) and (a + l/2 ulp) with f. */ 01673 /* Here workset.digits=maxp and t=0.5 */ 01674 workset.digits--; /* maxp-1 is OK now */ 01675 t->exponent = -set->digits - 1; /* make 0.5 ulp */ 01676 decNumberCopy (b, a); 01677 decAddOp (b, b, t, &workset, DECNEG, &ignore); /* b = a - 0.5 ulp */ 01678 workset.round = DEC_ROUND_UP; 01679 decMultiplyOp (b, b, b, &workset, &ignore); /* b = mulru(b, b) */ 01680 decCompareOp (b, f, b, &workset, COMPARE, &ignore); /* b ? f, reversed */ 01681 if (decNumberIsNegative (b)) 01682 { /* f < b [i.e., b > f] */ 01683 /* this is the more common adjustment, though both are rare */ 01684 t->exponent++; /* make 1.0 ulp */ 01685 t->lsu[0] = 1; /* .. */ 01686 decAddOp (a, a, t, &workset, DECNEG, &ignore); /* a = a - 1 ulp */ 01687 /* assign to approx [round to length] */ 01688 decAddOp (a, &dzero, a, &approxset, 0, &ignore); 01689 } 01690 else 01691 { 01692 decNumberCopy (b, a); 01693 decAddOp (b, b, t, &workset, 0, &ignore); /* b = a + 0.5 ulp */ 01694 workset.round = DEC_ROUND_DOWN; 01695 decMultiplyOp (b, b, b, &workset, &ignore); /* b = mulrd(b, b) */ 01696 decCompareOp (b, b, f, &workset, COMPARE, &ignore); /* b ? f */ 01697 if (decNumberIsNegative (b)) 01698 { /* b < f */ 01699 t->exponent++; /* make 1.0 ulp */ 01700 t->lsu[0] = 1; /* .. */ 01701 decAddOp (a, a, t, &workset, 0, &ignore); /* a = a + 1 ulp */ 01702 /* assign to approx [round to length] */ 01703 decAddOp (a, &dzero, a, &approxset, 0, &ignore); 01704 } 01705 } 01706 /* [no errors are possible in the above, and rounding/inexact during */ 01707 /* estimation are irrelevant, so status was not accumulated] */ 01708 01709 /* Here, 0.1 <= a < 1 [Hull] */ 01710 a->exponent += exp / 2; /* set correct exponent */ 01711 01712 /* Process Subnormals */ 01713 decFinalize (a, set, &residue, &status); 01714 01715 /* count dropable zeros [after any subnormal rounding] */ 01716 decNumberCopy (b, a); 01717 decTrim (b, 1, &dropped); /* [drops trailing zeros] */ 01718 01719 /* Finally set Inexact and Rounded. The answer can only be exact if */ 01720 /* it is short enough so that squaring it could fit in set->digits, */ 01721 /* so this is the only (relatively rare) time we have to check */ 01722 /* carefully */ 01723 if (b->digits * 2 - 1 > set->digits) 01724 { /* cannot fit */ 01725 status |= DEC_Inexact | DEC_Rounded; 01726 } 01727 else 01728 { /* could be exact/unrounded */ 01729 uInt mstatus = 0; /* local status */ 01730 decMultiplyOp (b, b, b, &workset, &mstatus); /* try the multiply */ 01731 if (mstatus != 0) 01732 { /* result won't fit */ 01733 status |= DEC_Inexact | DEC_Rounded; 01734 } 01735 else 01736 { /* plausible */ 01737 decCompareOp (t, b, rhs, &workset, COMPARE, &mstatus); /* b ? rhs */ 01738 if (!ISZERO (t)) 01739 { 01740 status |= DEC_Inexact | DEC_Rounded; 01741 } 01742 else 01743 { /* is Exact */ 01744 /* here, dropped is the count of trailing zeros in 'a' */ 01745 /* use closest exponent to ideal... */ 01746 Int todrop = ideal - a->exponent; /* most we can drop */ 01747 01748 if (todrop < 0) 01749 { /* ideally would add 0s */ 01750 status |= DEC_Rounded; 01751 } 01752 else 01753 { /* unrounded */ 01754 if (dropped < todrop) 01755 todrop = dropped; /* clamp to those available */ 01756 if (todrop > 0) 01757 { /* OK, some to drop */ 01758 decShiftToLeast (a->lsu, D2U (a->digits), todrop); 01759 a->exponent += todrop; /* maintain numerical value */ 01760 a->digits -= todrop; /* new length */ 01761 } 01762 } 01763 } 01764 } 01765 } 01766 decNumberCopy (res, a); /* assume this is the result */ 01767 } 01768 while (0); /* end protected */ 01769 01770 if (allocbuff != NULL) 01771 free (allocbuff); /* drop any storage we used */ 01772 if (allocbufa != NULL) 01773 free (allocbufa); /* .. */ 01774 if (allocbufb != NULL) 01775 free (allocbufb); /* .. */ 01776 if (allocrhs != NULL) 01777 free (allocrhs); /* .. */ 01778 if (status != 0) 01779 decStatus (res, status, set); /* then report status */ 01780 return res; 01781 } 01782 01783 /* ------------------------------------------------------------------ */ 01784 /* decNumberSubtract -- subtract two Numbers */ 01785 /* */ 01786 /* This computes C = A - B */ 01787 /* */ 01788 /* res is C, the result. C may be A and/or B (e.g., X=X-X) */ 01789 /* lhs is A */ 01790 /* rhs is B */ 01791 /* set is the context */ 01792 /* */ 01793 /* C must have space for set->digits digits. */ 01794 /* ------------------------------------------------------------------ */ 01795 decNumber * 01796 decNumberSubtract (decNumber * res, const decNumber * lhs, 01797 const decNumber * rhs, decContext * set) 01798 { 01799 uInt status = 0; /* accumulator */ 01800 01801 decAddOp (res, lhs, rhs, set, DECNEG, &status); 01802 if (status != 0) 01803 decStatus (res, status, set); 01804 return res; 01805 } 01806 01807 /* ------------------------------------------------------------------ */ 01808 /* decNumberToIntegralValue -- round-to-integral-value */ 01809 /* */ 01810 /* res is the result */ 01811 /* rhs is input number */ 01812 /* set is the context */ 01813 /* */ 01814 /* res must have space for any value of rhs. */ 01815 /* */ 01816 /* This implements the IEEE special operator and therefore treats */ 01817 /* special values as valid, and also never sets Inexact. For finite */ 01818 /* numbers it returns rescale(rhs, 0) if rhs->exponent is <0. */ 01819 /* Otherwise the result is rhs (so no error is possible). */ 01820 /* */ 01821 /* The context is used for rounding mode and status after sNaN, but */ 01822 /* the digits setting is ignored. */ 01823 /* ------------------------------------------------------------------ */ 01824 decNumber * 01825 decNumberToIntegralValue (decNumber * res, const decNumber * rhs, decContext * set) 01826 { 01827 decNumber dn; 01828 decContext workset; /* working context */ 01829 01830 #if DECCHECK 01831 if (decCheckOperands (res, DECUNUSED, rhs, set)) 01832 return res; 01833 #endif 01834 01835 /* handle infinities and NaNs */ 01836 if (rhs->bits & DECSPECIAL) 01837 { 01838 uInt status = 0; 01839 if (decNumberIsInfinite (rhs)) 01840 decNumberCopy (res, rhs); /* an Infinity */ 01841 else 01842 decNaNs (res, rhs, NULL, &status); /* a NaN */ 01843 if (status != 0) 01844 decStatus (res, status, set); 01845 return res; 01846 } 01847 01848 /* we have a finite number; no error possible */ 01849 if (rhs->exponent >= 0) 01850 return decNumberCopy (res, rhs); 01851 /* that was easy, but if negative exponent we have work to do... */ 01852 workset = *set; /* clone rounding, etc. */ 01853 workset.digits = rhs->digits; /* no length rounding */ 01854 workset.traps = 0; /* no traps */ 01855 decNumberZero (&dn); /* make a number with exponent 0 */ 01856 return decNumberQuantize (res, rhs, &dn, &workset); 01857 } 01858 01859 /* ================================================================== */ 01860 /* Utility routines */ 01861 /* ================================================================== */ 01862 01863 /* ------------------------------------------------------------------ */ 01864 /* decNumberCopy -- copy a number */ 01865 /* */ 01866 /* dest is the target decNumber */ 01867 /* src is the source decNumber */ 01868 /* returns dest */ 01869 /* */ 01870 /* (dest==src is allowed and is a no-op) */ 01871 /* All fields are updated as required. This is a utility operation, */ 01872 /* so special values are unchanged and no error is possible. */ 01873 /* ------------------------------------------------------------------ */ 01874 decNumber * 01875 decNumberCopy (decNumber * dest, const decNumber * src) 01876 { 01877 01878 #if DECCHECK 01879 if (src == NULL) 01880 return decNumberZero (dest); 01881 #endif 01882 01883 if (dest == src) 01884 return dest; /* no copy required */ 01885 01886 /* We use explicit assignments here as structure assignment can copy */ 01887 /* more than just the lsu (for small DECDPUN). This would not affect */ 01888 /* the value of the results, but would disturb test harness spill */ 01889 /* checking. */ 01890 dest->bits = src->bits; 01891 dest->exponent = src->exponent; 01892 dest->digits = src->digits; 01893 dest->lsu[0] = src->lsu[0]; 01894 if (src->digits > DECDPUN) 01895 { /* more Units to come */ 01896 Unit *d; /* work */ 01897 const Unit *s, *smsup; /* work */ 01898 /* memcpy for the remaining Units would be safe as they cannot */ 01899 /* overlap. However, this explicit loop is faster in short cases. */ 01900 d = dest->lsu + 1; /* -> first destination */ 01901 smsup = src->lsu + D2U (src->digits); /* -> source msu+1 */ 01902 for (s = src->lsu + 1; s < smsup; s++, d++) 01903 *d = *s; 01904 } 01905 return dest; 01906 } 01907 01908 /* ------------------------------------------------------------------ */ 01909 /* decNumberTrim -- remove insignificant zeros */ 01910 /* */ 01911 /* dn is the number to trim */ 01912 /* returns dn */ 01913 /* */ 01914 /* All fields are updated as required. This is a utility operation, */ 01915 /* so special values are unchanged and no error is possible. */ 01916 /* ------------------------------------------------------------------ */ 01917 decNumber * 01918 decNumberTrim (decNumber * dn) 01919 { 01920 Int dropped; /* work */ 01921 return decTrim (dn, 0, &dropped); 01922 } 01923 01924 /* ------------------------------------------------------------------ */ 01925 /* decNumberVersion -- return the name and version of this module */ 01926 /* */ 01927 /* No error is possible. */ 01928 /* ------------------------------------------------------------------ */ 01929 const char * 01930 decNumberVersion (void) 01931 { 01932 return DECVERSION; 01933 } 01934 01935 /* ------------------------------------------------------------------ */ 01936 /* decNumberZero -- set a number to 0 */ 01937 /* */ 01938 /* dn is the number to set, with space for one digit */ 01939 /* returns dn */ 01940 /* */ 01941 /* No error is possible. */ 01942 /* ------------------------------------------------------------------ */ 01943 /* Memset is not used as it is much slower in some environments. */ 01944 decNumber * 01945 decNumberZero (decNumber * dn) 01946 { 01947 01948 #if DECCHECK 01949 if (decCheckOperands (dn, DECUNUSED, DECUNUSED, DECUNUSED)) 01950 return dn; 01951 #endif 01952 01953 dn->bits = 0; 01954 dn->exponent = 0; 01955 dn->digits = 1; 01956 dn->lsu[0] = 0; 01957 return dn; 01958 } 01959 01960 /* ================================================================== */ 01961 /* Local routines */ 01962 /* ================================================================== */ 01963 01964 /* ------------------------------------------------------------------ */ 01965 /* decToString -- lay out a number into a string */ 01966 /* */ 01967 /* dn is the number to lay out */ 01968 /* string is where to lay out the number */ 01969 /* eng is 1 if Engineering, 0 if Scientific */ 01970 /* */ 01971 /* str must be at least dn->digits+14 characters long */ 01972 /* No error is possible. */ 01973 /* */ 01974 /* Note that this routine can generate a -0 or 0.000. These are */ 01975 /* never generated in subset to-number or arithmetic, but can occur */ 01976 /* in non-subset arithmetic (e.g., -1*0 or 1.234-1.234). */ 01977 /* ------------------------------------------------------------------ */ 01978 /* If DECCHECK is enabled the string "?" is returned if a number is */ 01979 /* invalid. */ 01980 01981 /* TODIGIT -- macro to remove the leading digit from the unsigned */ 01982 /* integer u at column cut (counting from the right, LSD=0) and place */ 01983 /* it as an ASCII character into the character pointed to by c. Note */ 01984 /* that cut must be <= 9, and the maximum value for u is 2,000,000,000 */ 01985 /* (as is needed for negative exponents of subnormals). The unsigned */ 01986 /* integer pow is used as a temporary variable. */ 01987 #define TODIGIT(u, cut, c) { \ 01988 *(c)='0'; \ 01989 pow=powers[cut]*2; \ 01990 if ((u)>pow) { \ 01991 pow*=4; \ 01992 if ((u)>=pow) {(u)-=pow; *(c)+=8;} \ 01993 pow/=2; \ 01994 if ((u)>=pow) {(u)-=pow; *(c)+=4;} \ 01995 pow/=2; \ 01996 } \ 01997 if ((u)>=pow) {(u)-=pow; *(c)+=2;} \ 01998 pow/=2; \ 01999 if ((u)>=pow) {(u)-=pow; *(c)+=1;} \ 02000 } 02001 02002 static void 02003 decToString (const decNumber * dn, char *string, Flag eng) 02004 { 02005 Int exp = dn->exponent; /* local copy */ 02006 Int e; /* E-part value */ 02007 Int pre; /* digits before the '.' */ 02008 Int cut; /* for counting digits in a Unit */ 02009 char *c = string; /* work [output pointer] */ 02010 const Unit *up = dn->lsu + D2U (dn->digits) - 1; /* -> msu [input pointer] */ 02011 uInt u, pow; /* work */ 02012 02013 #if DECCHECK 02014 if (decCheckOperands (DECUNUSED, dn, DECUNUSED, DECUNUSED)) 02015 { 02016 strcpy (string, "?"); 02017 return; 02018 } 02019 #endif 02020 02021 if (decNumberIsNegative (dn)) 02022 { /* Negatives get a minus (except */ 02023 *c = '-'; /* NaNs, which remove the '-' below) */ 02024 c++; 02025 } 02026 if (dn->bits & DECSPECIAL) 02027 { /* Is a special value */ 02028 if (decNumberIsInfinite (dn)) 02029 { 02030 strcpy (c, "Infinity"); 02031 return; 02032 } 02033 /* a NaN */ 02034 if (dn->bits & DECSNAN) 02035 { /* signalling NaN */ 02036 *c = 's'; 02037 c++; 02038 } 02039 strcpy (c, "NaN"); 02040 c += 3; /* step past */ 02041 /* if not a clean non-zero coefficient, that's all we have in a */ 02042 /* NaN string */ 02043 if (exp != 0 || (*dn->lsu == 0 && dn->digits == 1)) 02044 return; 02045 /* [drop through to add integer] */ 02046 } 02047 02048 /* calculate how many digits in msu, and hence first cut */ 02049 cut = dn->digits % DECDPUN; 02050 if (cut == 0) 02051 cut = DECDPUN; /* msu is full */ 02052 cut--; /* power of ten for digit */ 02053 02054 if (exp == 0) 02055 { /* simple integer [common fastpath, */ 02056 /* used for NaNs, too] */ 02057 for (; up >= dn->lsu; up--) 02058 { /* each Unit from msu */ 02059 u = *up; /* contains DECDPUN digits to lay out */ 02060 for (; cut >= 0; c++, cut--) 02061 TODIGIT (u, cut, c); 02062 cut = DECDPUN - 1; /* next Unit has all digits */ 02063 } 02064 *c = '\0'; /* terminate the string */ 02065 return; 02066 } 02067 02068 /* non-0 exponent -- assume plain form */ 02069 pre = dn->digits + exp; /* digits before '.' */ 02070 e = 0; /* no E */ 02071 if ((exp > 0) || (pre < -5)) 02072 { /* need exponential form */ 02073 e = exp + dn->digits - 1; /* calculate E value */ 02074 pre = 1; /* assume one digit before '.' */ 02075 if (eng && (e != 0)) 02076 { /* may need to adjust */ 02077 Int adj; /* adjustment */ 02078 /* The C remainder operator is undefined for negative numbers, so */ 02079 /* we must use positive remainder calculation here */ 02080 if (e < 0) 02081 { 02082 adj = (-e) % 3; 02083 if (adj != 0) 02084 adj = 3 - adj; 02085 } 02086 else 02087 { /* e>0 */ 02088 adj = e % 3; 02089 } 02090 e = e - adj; 02091 /* if we are dealing with zero we will use exponent which is a */ 02092 /* multiple of three, as expected, but there will only be the */ 02093 /* one zero before the E, still. Otherwise note the padding. */ 02094 if (!ISZERO (dn)) 02095 pre += adj; 02096 else 02097 { /* is zero */ 02098 if (adj != 0) 02099 { /* 0.00Esnn needed */ 02100 e = e + 3; 02101 pre = -(2 - adj); 02102 } 02103 } /* zero */ 02104 } /* eng */ 02105 } 02106 02107 /* lay out the digits of the coefficient, adding 0s and . as needed */ 02108 u = *up; 02109 if (pre > 0) 02110 { /* xxx.xxx or xx00 (engineering) form */ 02111 for (; pre > 0; pre--, c++, cut--) 02112 { 02113 if (cut < 0) 02114 { /* need new Unit */ 02115 if (up == dn->lsu) 02116 break; /* out of input digits (pre>digits) */ 02117 up--; 02118 cut = DECDPUN - 1; 02119 u = *up; 02120 } 02121 TODIGIT (u, cut, c); 02122 } 02123 if (up > dn->lsu || (up == dn->lsu && cut >= 0)) 02124 { /* more to come, after '.' */ 02125 *c = '.'; 02126 c++; 02127 for (;; c++, cut--) 02128 { 02129 if (cut < 0) 02130 { /* need new Unit */ 02131 if (up == dn->lsu) 02132 break; /* out of input digits */ 02133 up--; 02134 cut = DECDPUN - 1; 02135 u = *up; 02136 } 02137 TODIGIT (u, cut, c); 02138 } 02139 } 02140 else 02141 for (; pre > 0; pre--, c++) 02142 *c = '0'; /* 0 padding (for engineering) needed */ 02143 } 02144 else 02145 { /* 0.xxx or 0.000xxx form */ 02146 *c = '0'; 02147 c++; 02148 *c = '.'; 02149 c++; 02150 for (; pre < 0; pre++, c++) 02151 *c = '0'; /* add any 0's after '.' */ 02152 for (;; c++, cut--) 02153 { 02154 if (cut < 0) 02155 { /* need new Unit */ 02156 if (up == dn->lsu) 02157 break; /* out of input digits */ 02158 up--; 02159 cut = DECDPUN - 1; 02160 u = *up; 02161 } 02162 TODIGIT (u, cut, c); 02163 } 02164 } 02165 02166 /* Finally add the E-part, if needed. It will never be 0, has a 02167 base maximum and minimum of +999999999 through -999999999, but 02168 could range down to -1999999998 for subnormal numbers */ 02169 if (e != 0) 02170 { 02171 Flag had = 0; /* 1=had non-zero */ 02172 *c = 'E'; 02173 c++; 02174 *c = '+'; 02175 c++; /* assume positive */ 02176 u = e; /* .. */ 02177 if (e < 0) 02178 { 02179 *(c - 1) = '-'; /* oops, need - */ 02180 u = -e; /* uInt, please */ 02181 } 02182 /* layout the exponent (_itoa is not ANSI C) */ 02183 for (cut = 9; cut >= 0; cut--) 02184 { 02185 TODIGIT (u, cut, c); 02186 if (*c == '0' && !had) 02187 continue; /* skip leading zeros */ 02188 had = 1; /* had non-0 */ 02189 c++; /* step for next */ 02190 } /* cut */ 02191 } 02192 *c = '\0'; /* terminate the string (all paths) */ 02193 return; 02194 } 02195 02196 /* ------------------------------------------------------------------ */ 02197 /* decAddOp -- add/subtract operation */ 02198 /* */ 02199 /* This computes C = A + B */ 02200 /* */ 02201 /* res is C, the result. C may be A and/or B (e.g., X=X+X) */ 02202 /* lhs is A */ 02203 /* rhs is B */ 02204 /* set is the context */ 02205 /* negate is DECNEG if rhs should be negated, or 0 otherwise */ 02206 /* status accumulates status for the caller */ 02207 /* */ 02208 /* C must have space for set->digits digits. */ 02209 /* ------------------------------------------------------------------ */ 02210 /* If possible, we calculate the coefficient directly into C. */ 02211 /* However, if: */ 02212 /* -- we need a digits+1 calculation because numbers are unaligned */ 02213 /* and span more than set->digits digits */ 02214 /* -- a carry to digits+1 digits looks possible */ 02215 /* -- C is the same as A or B, and the result would destructively */ 02216 /* overlap the A or B coefficient */ 02217 /* then we must calculate into a temporary buffer. In this latter */ 02218 /* case we use the local (stack) buffer if possible, and only if too */ 02219 /* long for that do we resort to malloc. */ 02220 /* */ 02221 /* Misalignment is handled as follows: */ 02222 /* Apad: (AExp>BExp) Swap operands and proceed as for BExp>AExp. */ 02223 /* BPad: Apply the padding by a combination of shifting (whole */ 02224 /* units) and multiplication (part units). */ 02225 /* */ 02226 /* Addition, especially x=x+1, is speed-critical, so we take pains */ 02227 /* to make returning as fast as possible, by flagging any allocation. */ 02228 /* ------------------------------------------------------------------ */ 02229 static decNumber * 02230 decAddOp (decNumber * res, const decNumber * lhs, 02231 const decNumber * rhs, decContext * set, uByte negate, uInt * status) 02232 { 02233 decNumber *alloclhs = NULL; /* non-NULL if rounded lhs allocated */ 02234 decNumber *allocrhs = NULL; /* .., rhs */ 02235 Int rhsshift; /* working shift (in Units) */ 02236 Int maxdigits; /* longest logical length */ 02237 Int mult; /* multiplier */ 02238 Int residue; /* rounding accumulator */ 02239 uByte bits; /* result bits */ 02240 Flag diffsign; /* non-0 if arguments have different sign */ 02241 Unit *acc; /* accumulator for result */ 02242 Unit accbuff[D2U (DECBUFFER + 1)]; /* local buffer [+1 is for possible */ 02243 /* final carry digit or DECBUFFER=0] */ 02244 Unit *allocacc = NULL; /* -> allocated acc buffer, iff allocated */ 02245 Flag alloced = 0; /* set non-0 if any allocations */ 02246 Int reqdigits = set->digits; /* local copy; requested DIGITS */ 02247 uByte merged; /* merged flags */ 02248 Int padding; /* work */ 02249 02250 #if DECCHECK 02251 if (decCheckOperands (res, lhs, rhs, set)) 02252 return res; 02253 #endif 02254 02255 do 02256 { /* protect allocated storage */ 02257 #if DECSUBSET 02258 if (!set->extended) 02259 { 02260 /* reduce operands and set lostDigits status, as needed */ 02261 if (lhs->digits > reqdigits) 02262 { 02263 alloclhs = decRoundOperand (lhs, set, status); 02264 if (alloclhs == NULL) 02265 break; 02266 lhs = alloclhs; 02267 alloced = 1; 02268 } 02269 if (rhs->digits > reqdigits) 02270 { 02271 allocrhs = decRoundOperand (rhs, set, status); 02272 if (allocrhs == NULL) 02273 break; 02274 rhs = allocrhs; 02275 alloced = 1; 02276 } 02277 } 02278 #endif 02279 /* [following code does not require input rounding] */ 02280 02281 /* note whether signs differ */ 02282 diffsign = (Flag) ((lhs->bits ^ rhs->bits ^ negate) & DECNEG); 02283 02284 /* handle infinities and NaNs */ 02285 merged = (lhs->bits | rhs->bits) & DECSPECIAL; 02286 if (merged) 02287 { /* a special bit set */ 02288 if (merged & (DECSNAN | DECNAN)) /* a NaN */ 02289 decNaNs (res, lhs, rhs, status); 02290 else 02291 { /* one or two infinities */ 02292 if (decNumberIsInfinite (lhs)) 02293 { /* LHS is infinity */ 02294 /* two infinities with different signs is invalid */ 02295 if (decNumberIsInfinite (rhs) && diffsign) 02296 { 02297 *status |= DEC_Invalid_operation; 02298 break; 02299 } 02300 bits = lhs->bits & DECNEG; /* get sign from LHS */ 02301 } 02302 else 02303 bits = (rhs->bits ^ negate) & DECNEG; /* RHS must be Infinity */ 02304 bits |= DECINF; 02305 decNumberZero (res); 02306 res->bits = bits; /* set +/- infinity */ 02307 } /* an infinity */ 02308 break; 02309 } 02310 02311 /* Quick exit for add 0s; return the non-0, modified as need be */ 02312 if (ISZERO (lhs)) 02313 { 02314 Int adjust; /* work */ 02315 Int lexp = lhs->exponent; /* save in case LHS==RES */ 02316 bits = lhs->bits; /* .. */ 02317 residue = 0; /* clear accumulator */ 02318 decCopyFit (res, rhs, set, &residue, status); /* copy (as needed) */ 02319 res->bits ^= negate; /* flip if rhs was negated */ 02320 #if DECSUBSET 02321 if (set->extended) 02322 { /* exponents on zeros count */ 02323 #endif 02324 /* exponent will be the lower of the two */ 02325 adjust = lexp - res->exponent; /* adjustment needed [if -ve] */ 02326 if (ISZERO (res)) 02327 { /* both 0: special IEEE 854 rules */ 02328 if (adjust < 0) 02329 res->exponent = lexp; /* set exponent */ 02330 /* 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0 */ 02331 if (diffsign) 02332 { 02333 if (set->round != DEC_ROUND_FLOOR) 02334 res->bits = 0; 02335 else 02336 res->bits = DECNEG; /* preserve 0 sign */ 02337 } 02338 } 02339 else 02340 { /* non-0 res */ 02341 if (adjust < 0) 02342 { /* 0-padding needed */ 02343 if ((res->digits - adjust) > set->digits) 02344 { 02345 adjust = res->digits - set->digits; /* to fit exactly */ 02346 *status |= DEC_Rounded; /* [but exact] */ 02347 } 02348 res->digits = 02349 decShiftToMost (res->lsu, res->digits, -adjust); 02350 res->exponent += adjust; /* set the exponent. */ 02351 } 02352 } /* non-0 res */ 02353 #if DECSUBSET 02354 } /* extended */ 02355 #endif 02356 decFinish (res, set, &residue, status); /* clean and finalize */ 02357 break; 02358 } 02359 02360 if (ISZERO (rhs)) 02361 { /* [lhs is non-zero] */ 02362 Int adjust; /* work */ 02363 Int rexp = rhs->exponent; /* save in case RHS==RES */ 02364 bits = rhs->bits; /* be clean */ 02365 residue = 0; /* clear accumulator */ 02366 decCopyFit (res, lhs, set, &residue, status); /* copy (as needed) */ 02367 #if DECSUBSET 02368 if (set->extended) 02369 { /* exponents on zeros count */ 02370 #endif 02371 /* exponent will be the lower of the two */ 02372 /* [0-0 case handled above] */ 02373 adjust = rexp - res->exponent; /* adjustment needed [if -ve] */ 02374 if (adjust < 0) 02375 { /* 0-padding needed */ 02376 if ((res->digits - adjust) > set->digits) 02377 { 02378 adjust = res->digits - set->digits; /* to fit exactly */ 02379 *status |= DEC_Rounded; /* [but exact] */ 02380 } 02381 res->digits = 02382 decShiftToMost (res->lsu, res->digits, -adjust); 02383 res->exponent += adjust; /* set the exponent. */ 02384 } 02385 #if DECSUBSET 02386 } /* extended */ 02387 #endif 02388 decFinish (res, set, &residue, status); /* clean and finalize */ 02389 break; 02390 } 02391 /* [both fastpath and mainpath code below assume these cases */ 02392 /* (notably 0-0) have already been handled] */ 02393 02394 /* calculate the padding needed to align the operands */ 02395 padding = rhs->exponent - lhs->exponent; 02396 02397 /* Fastpath cases where the numbers are aligned and normal, the RHS */ 02398 /* is all in one unit, no operand rounding is needed, and no carry, */ 02399 /* lengthening, or borrow is needed */ 02400 if (rhs->digits <= DECDPUN && padding == 0 && rhs->exponent >= set->emin /* [some normals drop through] */ 02401 && rhs->digits <= reqdigits && lhs->digits <= reqdigits) 02402 { 02403 Int partial = *lhs->lsu; 02404 if (!diffsign) 02405 { /* adding */ 02406 Int maxv = DECDPUNMAX; /* highest no-overflow */ 02407 if (lhs->digits < DECDPUN) 02408 maxv = powers[lhs->digits] - 1; 02409 partial += *rhs->lsu; 02410 if (partial <= maxv) 02411 { /* no carry */ 02412 if (res != lhs) 02413 decNumberCopy (res, lhs); /* not in place */ 02414 *res->lsu = (Unit) partial; /* [copy could have overwritten RHS] */ 02415 break; 02416 } 02417 /* else drop out for careful add */ 02418 } 02419 else 02420 { /* signs differ */ 02421 partial -= *rhs->lsu; 02422 if (partial > 0) 02423 { /* no borrow needed, and non-0 result */ 02424 if (res != lhs) 02425 decNumberCopy (res, lhs); /* not in place */ 02426 *res->lsu = (Unit) partial; 02427 /* this could have reduced digits [but result>0] */ 02428 res->digits = decGetDigits (res->lsu, D2U (res->digits)); 02429 break; 02430 } 02431 /* else drop out for careful subtract */ 02432 } 02433 } 02434 02435 /* Now align (pad) the lhs or rhs so we can add or subtract them, as 02436 necessary. If one number is much larger than the other (that is, 02437 if in plain form there is a least one digit between the lowest 02438 digit or one and the highest of the other) we need to pad with up 02439 to DIGITS-1 trailing zeros, and then apply rounding (as exotic 02440 rounding modes may be affected by the residue). 02441 */ 02442 rhsshift = 0; /* rhs shift to left (padding) in Units */ 02443 bits = lhs->bits; /* assume sign is that of LHS */ 02444 mult = 1; /* likely multiplier */ 02445 02446 /* if padding==0 the operands are aligned; no padding needed */ 02447 if (padding != 0) 02448 { 02449 /* some padding needed */ 02450 /* We always pad the RHS, as we can then effect any required */ 02451 /* padding by a combination of shifts and a multiply */ 02452 Flag swapped = 0; 02453 if (padding < 0) 02454 { /* LHS needs the padding */ 02455 const decNumber *t; 02456 padding = -padding; /* will be +ve */ 02457 bits = (uByte) (rhs->bits ^ negate); /* assumed sign is now that of RHS */ 02458 t = lhs; 02459 lhs = rhs; 02460 rhs = t; 02461 swapped = 1; 02462 } 02463 02464 /* If, after pad, rhs would be longer than lhs by digits+1 or */ 02465 /* more then lhs cannot affect the answer, except as a residue, */ 02466 /* so we only need to pad up to a length of DIGITS+1. */ 02467 if (rhs->digits + padding > lhs->digits + reqdigits + 1) 02468 { 02469 /* The RHS is sufficient */ 02470 /* for residue we use the relative sign indication... */ 02471 Int shift = reqdigits - rhs->digits; /* left shift needed */ 02472 residue = 1; /* residue for rounding */ 02473 if (diffsign) 02474 residue = -residue; /* signs differ */ 02475 /* copy, shortening if necessary */ 02476 decCopyFit (res, rhs, set, &residue, status); 02477 /* if it was already shorter, then need to pad with zeros */ 02478 if (shift > 0) 02479 { 02480 res->digits = decShiftToMost (res->lsu, res->digits, shift); 02481 res->exponent -= shift; /* adjust the exponent. */ 02482 } 02483 /* flip the result sign if unswapped and rhs was negated */ 02484 if (!swapped) 02485 res->bits ^= negate; 02486 decFinish (res, set, &residue, status); /* done */ 02487 break; 02488 } 02489 02490 /* LHS digits may affect result */ 02491 rhsshift = D2U (padding + 1) - 1; /* this much by Unit shift .. */ 02492 mult = powers[padding - (rhsshift * DECDPUN)]; /* .. this by multiplication */ 02493 } /* padding needed */ 02494 02495 if (diffsign) 02496 mult = -mult; /* signs differ */ 02497 02498 /* determine the longer operand */ 02499 maxdigits = rhs->digits + padding; /* virtual length of RHS */ 02500 if (lhs->digits > maxdigits) 02501 maxdigits = lhs->digits; 02502 02503 /* Decide on the result buffer to use; if possible place directly */ 02504 /* into result. */ 02505 acc = res->lsu; /* assume build direct */ 02506 /* If destructive overlap, or the number is too long, or a carry or */ 02507 /* borrow to DIGITS+1 might be possible we must use a buffer. */ 02508 /* [Might be worth more sophisticated tests when maxdigits==reqdigits] */ 02509 if ((maxdigits >= reqdigits) /* is, or could be, too large */ 02510 || (res == rhs && rhsshift > 0)) 02511 { /* destructive overlap */ 02512 /* buffer needed; choose it */ 02513 /* we'll need units for maxdigits digits, +1 Unit for carry or borrow */ 02514 Int need = D2U (maxdigits) + 1; 02515 acc = accbuff; /* assume use local buffer */ 02516 if (need * sizeof (Unit) > sizeof (accbuff)) 02517 { 02518 allocacc = (Unit *) malloc (need * sizeof (Unit)); 02519 if (allocacc == NULL) 02520 { /* hopeless -- abandon */ 02521 *status |= DEC_Insufficient_storage; 02522 break; 02523 } 02524 acc = allocacc; 02525 alloced = 1; 02526 } 02527 } 02528 02529 res->bits = (uByte) (bits & DECNEG); /* it's now safe to overwrite.. */ 02530 res->exponent = lhs->exponent; /* .. operands (even if aliased) */ 02531 02532 #if DECTRACE 02533 decDumpAr ('A', lhs->lsu, D2U (lhs->digits)); 02534 decDumpAr ('B', rhs->lsu, D2U (rhs->digits)); 02535 printf (" :h: %d %d\n", rhsshift, mult); 02536 #endif 02537 02538 /* add [A+B*m] or subtract [A+B*(-m)] */ 02539 res->digits = decUnitAddSub (lhs->lsu, D2U (lhs->digits), rhs->lsu, D2U (rhs->digits), rhsshift, acc, mult) * DECDPUN; /* [units -> digits] */ 02540 if (res->digits < 0) 02541 { /* we borrowed */ 02542 res->digits = -res->digits; 02543 res->bits ^= DECNEG; /* flip the sign */ 02544 } 02545 #if DECTRACE 02546 decDumpAr ('+', acc, D2U (res->digits)); 02547 #endif 02548 02549 /* If we used a buffer we need to copy back, possibly shortening */ 02550 /* (If we didn't use buffer it must have fit, so can't need rounding */ 02551 /* and residue must be 0.) */ 02552 residue = 0; /* clear accumulator */ 02553 if (acc != res->lsu) 02554 { 02555 #if DECSUBSET 02556 if (set->extended) 02557 { /* round from first significant digit */ 02558 #endif 02559 /* remove leading zeros that we added due to rounding up to */ 02560 /* integral Units -- before the test for rounding. */ 02561 if (res->digits > reqdigits) 02562 res->digits = decGetDigits (acc, D2U (res->digits)); 02563 decSetCoeff (res, set, acc, res->digits, &residue, status); 02564 #if DECSUBSET 02565 } 02566 else 02567 { /* subset arithmetic rounds from original significant digit */ 02568 /* We may have an underestimate. This only occurs when both */ 02569 /* numbers fit in DECDPUN digits and we are padding with a */ 02570 /* negative multiple (-10, -100...) and the top digit(s) become */ 02571 /* 0. (This only matters if we are using X3.274 rules where the */ 02572 /* leading zero could be included in the rounding.) */ 02573 if (res->digits < maxdigits) 02574 { 02575 *(acc + D2U (res->digits)) = 0; /* ensure leading 0 is there */ 02576 res->digits = maxdigits; 02577 } 02578 else 02579 { 02580 /* remove leading zeros that we added due to rounding up to */ 02581 /* integral Units (but only those in excess of the original */ 02582 /* maxdigits length, unless extended) before test for rounding. */ 02583 if (res->digits > reqdigits) 02584 { 02585 res->digits = decGetDigits (acc, D2U (res->digits)); 02586 if (res->digits < maxdigits) 02587 res->digits = maxdigits; 02588 } 02589 } 02590 decSetCoeff (res, set, acc, res->digits, &residue, status); 02591 /* Now apply rounding if needed before removing leading zeros. */ 02592 /* This is safe because subnormals are not a possibility */ 02593 if (residue != 0) 02594 { 02595 decApplyRound (res, set, residue, status); 02596 residue = 0; /* we did what we had to do */ 02597 } 02598 } /* subset */ 02599 #endif 02600 } /* used buffer */ 02601 02602 /* strip leading zeros [these were left on in case of subset subtract] */ 02603 res->digits = decGetDigits (res->lsu, D2U (res->digits)); 02604 02605 /* apply checks and rounding */ 02606 decFinish (res, set, &residue, status); 02607 02608 /* "When the sum of two operands with opposite signs is exactly */ 02609 /* zero, the sign of that sum shall be '+' in all rounding modes */ 02610 /* except round toward -Infinity, in which mode that sign shall be */ 02611 /* '-'." [Subset zeros also never have '-', set by decFinish.] */ 02612 if (ISZERO (res) && diffsign 02613 #if DECSUBSET 02614 && set->extended 02615 #endif 02616 && (*status & DEC_Inexact) == 0) 02617 { 02618 if (set->round == DEC_ROUND_FLOOR) 02619 res->bits |= DECNEG; /* sign - */ 02620 else 02621 res->bits &= ~DECNEG; /* sign + */ 02622 } 02623 } 02624 while (0); /* end protected */ 02625 02626 if (alloced) 02627 { 02628 if (allocacc != NULL) 02629 free (allocacc); /* drop any storage we used */ 02630 if (allocrhs != NULL) 02631 free (allocrhs); /* .. */ 02632 if (alloclhs != NULL) 02633 free (alloclhs); /* .. */ 02634 } 02635 return res; 02636 } 02637 02638 /* ------------------------------------------------------------------ */ 02639 /* decDivideOp -- division operation */ 02640 /* */ 02641 /* This routine performs the calculations for all four division */ 02642 /* operators (divide, divideInteger, remainder, remainderNear). */ 02643 /* */ 02644 /* C=A op B */ 02645 /* */ 02646 /* res is C, the result. C may be A and/or B (e.g., X=X/X) */ 02647 /* lhs is A */ 02648 /* rhs is B */ 02649 /* set is the context */ 02650 /* op is DIVIDE, DIVIDEINT, REMAINDER, or REMNEAR respectively. */ 02651 /* status is the usual accumulator */ 02652 /* */ 02653 /* C must have space for set->digits digits. */ 02654 /* */ 02655 /* ------------------------------------------------------------------ */ 02656 /* The underlying algorithm of this routine is the same as in the */ 02657 /* 1981 S/370 implementation, that is, non-restoring long division */ 02658 /* with bi-unit (rather than bi-digit) estimation for each unit */ 02659 /* multiplier. In this pseudocode overview, complications for the */ 02660 /* Remainder operators and division residues for exact rounding are */ 02661 /* omitted for clarity. */ 02662 /* */ 02663 /* Prepare operands and handle special values */ 02664 /* Test for x/0 and then 0/x */ 02665 /* Exp =Exp1 - Exp2 */ 02666 /* Exp =Exp +len(var1) -len(var2) */ 02667 /* Sign=Sign1 * Sign2 */ 02668 /* Pad accumulator (Var1) to double-length with 0's (pad1) */ 02669 /* Pad Var2 to same length as Var1 */ 02670 /* msu2pair/plus=1st 2 or 1 units of var2, +1 to allow for round */ 02671 /* have=0 */ 02672 /* Do until (have=digits+1 OR residue=0) */ 02673 /* if exp<0 then if integer divide/residue then leave */ 02674 /* this_unit=0 */ 02675 /* Do forever */ 02676 /* compare numbers */ 02677 /* if <0 then leave inner_loop */ 02678 /* if =0 then (* quick exit without subtract *) do */ 02679 /* this_unit=this_unit+1; output this_unit */ 02680 /* leave outer_loop; end */ 02681 /* Compare lengths of numbers (mantissae): */ 02682 /* If same then tops2=msu2pair -- {units 1&2 of var2} */ 02683 /* else tops2=msu2plus -- {0, unit 1 of var2} */ 02684 /* tops1=first_unit_of_Var1*10**DECDPUN +second_unit_of_var1 */ 02685 /* mult=tops1/tops2 -- Good and safe guess at divisor */ 02686 /* if mult=0 then mult=1 */ 02687 /* this_unit=this_unit+mult */ 02688 /* subtract */ 02689 /* end inner_loop */ 02690 /* if have\=0 | this_unit\=0 then do */ 02691 /* output this_unit */ 02692 /* have=have+1; end */ 02693 /* var2=var2/10 */ 02694 /* exp=exp-1 */ 02695 /* end outer_loop */ 02696 /* exp=exp+1 -- set the proper exponent */ 02697 /* if have=0 then generate answer=0 */ 02698 /* Return (Result is defined by Var1) */ 02699 /* */ 02700 /* ------------------------------------------------------------------ */ 02701 /* We need two working buffers during the long division; one (digits+ */ 02702 /* 1) to accumulate the result, and the other (up to 2*digits+1) for */ 02703 /* long subtractions. These are acc and var1 respectively. */ 02704 /* var1 is a copy of the lhs coefficient, var2 is the rhs coefficient.*/ 02705 /* ------------------------------------------------------------------ */ 02706 static decNumber * 02707 decDivideOp (decNumber * res, 02708 const decNumber * lhs, const decNumber * rhs, 02709 decContext * set, Flag op, uInt * status) 02710 { 02711 decNumber *alloclhs = NULL; /* non-NULL if rounded lhs allocated */ 02712 decNumber *allocrhs = NULL; /* .., rhs */ 02713 Unit accbuff[D2U (DECBUFFER + DECDPUN)]; /* local buffer */ 02714 Unit *acc = accbuff; /* -> accumulator array for result */ 02715 Unit *allocacc = NULL; /* -> allocated buffer, iff allocated */ 02716 Unit *accnext; /* -> where next digit will go */ 02717 Int acclength; /* length of acc needed [Units] */ 02718 Int accunits; /* count of units accumulated */ 02719 Int accdigits; /* count of digits accumulated */ 02720 02721 Unit varbuff[D2U (DECBUFFER * 2 + DECDPUN) * sizeof (Unit)]; /* buffer for var1 */ 02722 Unit *var1 = varbuff; /* -> var1 array for long subtraction */ 02723 Unit *varalloc = NULL; /* -> allocated buffer, iff used */ 02724 02725 const Unit *var2; /* -> var2 array */ 02726 02727 Int var1units, var2units; /* actual lengths */ 02728 Int var2ulen; /* logical length (units) */ 02729 Int var1initpad = 0; /* var1 initial padding (digits) */ 02730 Unit *msu1; /* -> msu of each var */ 02731 const Unit *msu2; /* -> msu of each var */ 02732 Int msu2plus; /* msu2 plus one [does not vary] */ 02733 eInt msu2pair; /* msu2 pair plus one [does not vary] */ 02734 Int maxdigits; /* longest LHS or required acc length */ 02735 Int mult; /* multiplier for subtraction */ 02736 Unit thisunit; /* current unit being accumulated */ 02737 Int residue; /* for rounding */ 02738 Int reqdigits = set->digits; /* requested DIGITS */ 02739 Int exponent; /* working exponent */ 02740 Int maxexponent = 0; /* DIVIDE maximum exponent if unrounded */ 02741 uByte bits; /* working sign */ 02742 uByte merged; /* merged flags */ 02743 Unit *target; /* work */ 02744 const Unit *source; /* work */ 02745 uInt const *pow; /* .. */ 02746 Int shift, cut; /* .. */ 02747 #if DECSUBSET 02748 Int dropped; /* work */ 02749 #endif 02750 02751 #if DECCHECK 02752 if (decCheckOperands (res, lhs, rhs, set)) 02753 return res; 02754 #endif 02755 02756 do 02757 { /* protect allocated storage */ 02758 #if DECSUBSET 02759 if (!set->extended) 02760 { 02761 /* reduce operands and set lostDigits status, as needed */ 02762 if (lhs->digits > reqdigits) 02763 { 02764 alloclhs = decRoundOperand (lhs, set, status); 02765 if (alloclhs == NULL) 02766 break; 02767 lhs = alloclhs; 02768 } 02769 if (rhs->digits > reqdigits) 02770 { 02771 allocrhs = decRoundOperand (rhs, set, status); 02772 if (allocrhs == NULL) 02773 break; 02774 rhs = allocrhs; 02775 } 02776 } 02777 #endif 02778 /* [following code does not require input rounding] */ 02779 02780 bits = (lhs->bits ^ rhs->bits) & DECNEG; /* assumed sign for divisions */ 02781 02782 /* handle infinities and NaNs */ 02783 merged = (lhs->bits | rhs->bits) & DECSPECIAL; 02784 if (merged) 02785 { /* a special bit set */ 02786 if (merged & (DECSNAN | DECNAN)) 02787 { /* one or two NaNs */ 02788 decNaNs (res, lhs, rhs, status); 02789 break; 02790 } 02791 /* one or two infinities */ 02792 if (decNumberIsInfinite (lhs)) 02793 { /* LHS (dividend) is infinite */ 02794 if (decNumberIsInfinite (rhs) || /* two infinities are invalid .. */ 02795 op & (REMAINDER | REMNEAR)) 02796 { /* as is remainder of infinity */ 02797 *status |= DEC_Invalid_operation; 02798 break; 02799 } 02800 /* [Note that infinity/0 raises no exceptions] */ 02801 decNumberZero (res); 02802 res->bits = bits | DECINF; /* set +/- infinity */ 02803 break; 02804 } 02805 else 02806 { /* RHS (divisor) is infinite */ 02807 residue = 0; 02808 if (op & (REMAINDER | REMNEAR)) 02809 { 02810 /* result is [finished clone of] lhs */ 02811 decCopyFit (res, lhs, set, &residue, status); 02812 } 02813 else 02814 { /* a division */ 02815 decNumberZero (res); 02816 res->bits = bits; /* set +/- zero */ 02817 /* for DIVIDEINT the exponent is always 0. For DIVIDE, result */ 02818 /* is a 0 with infinitely negative exponent, clamped to minimum */ 02819 if (op & DIVIDE) 02820 { 02821 res->exponent = set->emin - set->digits + 1; 02822 *status |= DEC_Clamped; 02823 } 02824 } 02825 decFinish (res, set, &residue, status); 02826 break; 02827 } 02828 } 02829 02830 /* handle 0 rhs (x/0) */ 02831 if (ISZERO (rhs)) 02832 { /* x/0 is always exceptional */ 02833 if (ISZERO (lhs)) 02834 { 02835 decNumberZero (res); /* [after lhs test] */ 02836 *status |= DEC_Division_undefined; /* 0/0 will become NaN */ 02837 } 02838 else 02839 { 02840 decNumberZero (res); 02841 if (op & (REMAINDER | REMNEAR)) 02842 *status |= DEC_Invalid_operation; 02843 else 02844 { 02845 *status |= DEC_Division_by_zero; /* x/0 */ 02846 res->bits = bits | DECINF; /* .. is +/- Infinity */ 02847 } 02848 } 02849 break; 02850 } 02851 02852 /* handle 0 lhs (0/x) */ 02853 if (ISZERO (lhs)) 02854 { /* 0/x [x!=0] */ 02855 #if DECSUBSET 02856 if (!set->extended) 02857 decNumberZero (res); 02858 else 02859 { 02860 #endif 02861 if (op & DIVIDE) 02862 { 02863 residue = 0; 02864 exponent = lhs->exponent - rhs->exponent; /* ideal exponent */ 02865 decNumberCopy (res, lhs); /* [zeros always fit] */ 02866 res->bits = bits; /* sign as computed */ 02867 res->exponent = exponent; /* exponent, too */ 02868 decFinalize (res, set, &residue, status); /* check exponent */ 02869 } 02870 else if (op & DIVIDEINT) 02871 { 02872 decNumberZero (res); /* integer 0 */ 02873 res->bits = bits; /* sign as computed */ 02874 } 02875 else 02876 { /* a remainder */ 02877 exponent = rhs->exponent; /* [save in case overwrite] */ 02878 decNumberCopy (res, lhs); /* [zeros always fit] */ 02879 if (exponent < res->exponent) 02880 res->exponent = exponent; /* use lower */ 02881 } 02882 #if DECSUBSET 02883 } 02884 #endif 02885 break; 02886 } 02887 02888 /* Precalculate exponent. This starts off adjusted (and hence fits */ 02889 /* in 31 bits) and becomes the usual unadjusted exponent as the */ 02890 /* division proceeds. The order of evaluation is important, here, */ 02891 /* to avoid wrap. */ 02892 exponent = 02893 (lhs->exponent + lhs->digits) - (rhs->exponent + rhs->digits); 02894 02895 /* If the working exponent is -ve, then some quick exits are */ 02896 /* possible because the quotient is known to be <1 */ 02897 /* [for REMNEAR, it needs to be < -1, as -0.5 could need work] */ 02898 if (exponent < 0 && !(op == DIVIDE)) 02899 { 02900 if (op & DIVIDEINT) 02901 { 02902 decNumberZero (res); /* integer part is 0 */ 02903 #if DECSUBSET 02904 if (set->extended) 02905 #endif 02906 res->bits = bits; /* set +/- zero */ 02907 break; 02908 } 02909 /* we can fastpath remainders so long as the lhs has the */ 02910 /* smaller (or equal) exponent */ 02911 if (lhs->exponent <= rhs->exponent) 02912 { 02913 if (op & REMAINDER || exponent < -1) 02914 { 02915 /* It is REMAINDER or safe REMNEAR; result is [finished */ 02916 /* clone of] lhs (r = x - 0*y) */ 02917 residue = 0; 02918 decCopyFit (res, lhs, set, &residue, status); 02919 decFinish (res, set, &residue, status); 02920 break; 02921 } 02922 /* [unsafe REMNEAR drops through] */ 02923 } 02924 } /* fastpaths */ 02925 02926 /* We need long (slow) division; roll up the sleeves... */ 02927 02928 /* The accumulator will hold the quotient of the division. */ 02929 /* If it needs to be too long for stack storage, then allocate. */ 02930 acclength = D2U (reqdigits + DECDPUN); /* in Units */ 02931 if (acclength * sizeof (Unit) > sizeof (accbuff)) 02932 { 02933 allocacc = (Unit *) malloc (acclength * sizeof (Unit)); 02934 if (allocacc == NULL) 02935 { /* hopeless -- abandon */ 02936 *status |= DEC_Insufficient_storage; 02937 break; 02938 } 02939 acc = allocacc; /* use the allocated space */ 02940 } 02941 02942 /* var1 is the padded LHS ready for subtractions. */ 02943 /* If it needs to be too long for stack storage, then allocate. */ 02944 /* The maximum units we need for var1 (long subtraction) is: */ 02945 /* Enough for */ 02946 /* (rhs->digits+reqdigits-1) -- to allow full slide to right */ 02947 /* or (lhs->digits) -- to allow for long lhs */ 02948 /* whichever is larger */ 02949 /* +1 -- for rounding of slide to right */ 02950 /* +1 -- for leading 0s */ 02951 /* +1 -- for pre-adjust if a remainder or DIVIDEINT */ 02952 /* [Note: unused units do not participate in decUnitAddSub data] */ 02953 maxdigits = rhs->digits + reqdigits - 1; 02954 if (lhs->digits > maxdigits) 02955 maxdigits = lhs->digits; 02956 var1units = D2U (maxdigits) + 2; 02957 /* allocate a guard unit above msu1 for REMAINDERNEAR */ 02958 if (!(op & DIVIDE)) 02959 var1units++; 02960 if ((var1units + 1) * sizeof (Unit) > sizeof (varbuff)) 02961 { 02962 varalloc = (Unit *) malloc ((var1units + 1) * sizeof (Unit)); 02963 if (varalloc == NULL) 02964 { /* hopeless -- abandon */ 02965 *status |= DEC_Insufficient_storage; 02966 break; 02967 } 02968 var1 = varalloc; /* use the allocated space */ 02969 } 02970 02971 /* Extend the lhs and rhs to full long subtraction length. The lhs */ 02972 /* is truly extended into the var1 buffer, with 0 padding, so we can */ 02973 /* subtract in place. The rhs (var2) has virtual padding */ 02974 /* (implemented by decUnitAddSub). */ 02975 /* We allocated one guard unit above msu1 for rem=rem+rem in REMAINDERNEAR */ 02976 msu1 = var1 + var1units - 1; /* msu of var1 */ 02977 source = lhs->lsu + D2U (lhs->digits) - 1; /* msu of input array */ 02978 for (target = msu1; source >= lhs->lsu; source--, target--) 02979 *target = *source; 02980 for (; target >= var1; target--) 02981 *target = 0; 02982 02983 /* rhs (var2) is left-aligned with var1 at the start */ 02984 var2ulen = var1units; /* rhs logical length (units) */ 02985 var2units = D2U (rhs->digits); /* rhs actual length (units) */ 02986 var2 = rhs->lsu; /* -> rhs array */ 02987 msu2 = var2 + var2units - 1; /* -> msu of var2 [never changes] */ 02988 /* now set up the variables which we'll use for estimating the */ 02989 /* multiplication factor. If these variables are not exact, we add */ 02990 /* 1 to make sure that we never overestimate the multiplier. */ 02991 msu2plus = *msu2; /* it's value .. */ 02992 if (var2units > 1) 02993 msu2plus++; /* .. +1 if any more */ 02994 msu2pair = (eInt) * msu2 * (DECDPUNMAX + 1); /* top two pair .. */ 02995 if (var2units > 1) 02996 { /* .. [else treat 2nd as 0] */ 02997 msu2pair += *(msu2 - 1); /* .. */ 02998 if (var2units > 2) 02999 msu2pair++; /* .. +1 if any more */ 03000 } 03001 03002 /* Since we are working in units, the units may have leading zeros, */ 03003 /* but we calculated the exponent on the assumption that they are */ 03004 /* both left-aligned. Adjust the exponent to compensate: add the */ 03005 /* number of leading zeros in var1 msu and subtract those in var2 msu. */ 03006 /* [We actually do this by counting the digits and negating, as */ 03007 /* lead1=DECDPUN-digits1, and similarly for lead2.] */ 03008 for (pow = &powers[1]; *msu1 >= *pow; pow++) 03009 exponent--; 03010 for (pow = &powers[1]; *msu2 >= *pow; pow++) 03011 exponent++; 03012 03013 /* Now, if doing an integer divide or remainder, we want to ensure */ 03014 /* that the result will be Unit-aligned. To do this, we shift the */ 03015 /* var1 accumulator towards least if need be. (It's much easier to */ 03016 /* do this now than to reassemble the residue afterwards, if we are */ 03017 /* doing a remainder.) Also ensure the exponent is not negative. */ 03018 if (!(op & DIVIDE)) 03019 { 03020 Unit *u; 03021 /* save the initial 'false' padding of var1, in digits */ 03022 var1initpad = (var1units - D2U (lhs->digits)) * DECDPUN; 03023 /* Determine the shift to do. */ 03024 if (exponent < 0) 03025 cut = -exponent; 03026 else 03027 cut = DECDPUN - exponent % DECDPUN; 03028 decShiftToLeast (var1, var1units, cut); 03029 exponent += cut; /* maintain numerical value */ 03030 var1initpad -= cut; /* .. and reduce padding */ 03031 /* clean any most-significant units we just emptied */ 03032 for (u = msu1; cut >= DECDPUN; cut -= DECDPUN, u--) 03033 *u = 0; 03034 } /* align */ 03035 else 03036 { /* is DIVIDE */ 03037 maxexponent = lhs->exponent - rhs->exponent; /* save */ 03038 /* optimization: if the first iteration will just produce 0, */ 03039 /* preadjust to skip it [valid for DIVIDE only] */ 03040 if (*msu1 < *msu2) 03041 { 03042 var2ulen--; /* shift down */ 03043 exponent -= DECDPUN; /* update the exponent */ 03044 } 03045 } 03046 03047 /* ---- start the long-division loops ------------------------------ */ 03048 accunits = 0; /* no units accumulated yet */ 03049 accdigits = 0; /* .. or digits */ 03050 accnext = acc + acclength - 1; /* -> msu of acc [NB: allows digits+1] */ 03051 for (;;) 03052 { /* outer forever loop */ 03053 thisunit = 0; /* current unit assumed 0 */ 03054 /* find the next unit */ 03055 for (;;) 03056 { /* inner forever loop */ 03057 /* strip leading zero units [from either pre-adjust or from */ 03058 /* subtract last time around]. Leave at least one unit. */ 03059 for (; *msu1 == 0 && msu1 > var1; msu1--) 03060 var1units--; 03061 03062 if (var1units < var2ulen) 03063 break; /* var1 too low for subtract */ 03064 if (var1units == var2ulen) 03065 { /* unit-by-unit compare needed */ 03066 /* compare the two numbers, from msu */ 03067 Unit *pv1, v2; /* units to compare */ 03068 const Unit *pv2; /* units to compare */ 03069 pv2 = msu2; /* -> msu */ 03070 for (pv1 = msu1;; pv1--, pv2--) 03071 { 03072 /* v1=*pv1 -- always OK */ 03073 v2 = 0; /* assume in padding */ 03074 if (pv2 >= var2) 03075 v2 = *pv2; /* in range */ 03076 if (*pv1 != v2) 03077 break; /* no longer the same */ 03078 if (pv1 == var1) 03079 break; /* done; leave pv1 as is */ 03080 } 03081 /* here when all inspected or a difference seen */ 03082 if (*pv1 < v2) 03083 break; /* var1 too low to subtract */ 03084 if (*pv1 == v2) 03085 { /* var1 == var2 */ 03086 /* reach here if var1 and var2 are identical; subtraction */ 03087 /* would increase digit by one, and the residue will be 0 so */ 03088 /* we are done; leave the loop with residue set to 0. */ 03089 thisunit++; /* as though subtracted */ 03090 *var1 = 0; /* set var1 to 0 */ 03091 var1units = 1; /* .. */ 03092 break; /* from inner */ 03093 } /* var1 == var2 */ 03094 /* *pv1>v2. Prepare for real subtraction; the lengths are equal */ 03095 /* Estimate the multiplier (there's always a msu1-1)... */ 03096 /* Bring in two units of var2 to provide a good estimate. */ 03097 mult = 03098 (Int) (((eInt) * msu1 * (DECDPUNMAX + 1) + 03099 *(msu1 - 1)) / msu2pair); 03100 } /* lengths the same */ 03101 else 03102 { /* var1units > var2ulen, so subtraction is safe */ 03103 /* The var2 msu is one unit towards the lsu of the var1 msu, */ 03104 /* so we can only use one unit for var2. */ 03105 mult = 03106 (Int) (((eInt) * msu1 * (DECDPUNMAX + 1) + 03107 *(msu1 - 1)) / msu2plus); 03108 } 03109 if (mult == 0) 03110 mult = 1; /* must always be at least 1 */ 03111 /* subtraction needed; var1 is > var2 */ 03112 thisunit = (Unit) (thisunit + mult); /* accumulate */ 03113 /* subtract var1-var2, into var1; only the overlap needs */ 03114 /* processing, as we are in place */ 03115 shift = var2ulen - var2units; 03116 #if DECTRACE 03117 decDumpAr ('1', &var1[shift], var1units - shift); 03118 decDumpAr ('2', var2, var2units); 03119 printf ("m=%d\n", -mult); 03120 #endif 03121 decUnitAddSub (&var1[shift], var1units - shift, 03122 var2, var2units, 0, &var1[shift], -mult); 03123 #if DECTRACE 03124 decDumpAr ('#', &var1[shift], var1units - shift); 03125 #endif 03126 /* var1 now probably has leading zeros; these are removed at the */ 03127 /* top of the inner loop. */ 03128 } /* inner loop */ 03129 03130 /* We have the next unit; unless it's a leading zero, add to acc */ 03131 if (accunits != 0 || thisunit != 0) 03132 { /* put the unit we got */ 03133 *accnext = thisunit; /* store in accumulator */ 03134 /* account exactly for the digits we got */ 03135 if (accunits == 0) 03136 { 03137 accdigits++; /* at least one */ 03138 for (pow = &powers[1]; thisunit >= *pow; pow++) 03139 accdigits++; 03140 } 03141 else 03142 accdigits += DECDPUN; 03143 accunits++; /* update count */ 03144 accnext--; /* ready for next */ 03145 if (accdigits > reqdigits) 03146 break; /* we have all we need */ 03147 } 03148 03149 /* if the residue is zero, we're done (unless divide or */ 03150 /* divideInteger and we haven't got enough digits yet) */ 03151 if (*var1 == 0 && var1units == 1) 03152 { /* residue is 0 */ 03153 if (op & (REMAINDER | REMNEAR)) 03154 break; 03155 if ((op & DIVIDE) && (exponent <= maxexponent)) 03156 break; 03157 /* [drop through if divideInteger] */ 03158 } 03159 /* we've also done enough if calculating remainder or integer */ 03160 /* divide and we just did the last ('units') unit */ 03161 if (exponent == 0 && !(op & DIVIDE)) 03162 break; 03163 03164 /* to get here, var1 is less than var2, so divide var2 by the per- */ 03165 /* Unit power of ten and go for the next digit */ 03166 var2ulen--; /* shift down */ 03167 exponent -= DECDPUN; /* update the exponent */ 03168 } /* outer loop */ 03169 03170 /* ---- division is complete --------------------------------------- */ 03171 /* here: acc has at least reqdigits+1 of good results (or fewer */ 03172 /* if early stop), starting at accnext+1 (its lsu) */ 03173 /* var1 has any residue at the stopping point */ 03174 /* accunits is the number of digits we collected in acc */ 03175 if (accunits == 0) 03176 { /* acc is 0 */ 03177 accunits = 1; /* show we have one .. */ 03178 accdigits = 1; /* .. */ 03179 *accnext = 0; /* .. whose value is 0 */ 03180 } 03181 else 03182 accnext++; /* back to last placed */ 03183 /* accnext now -> lowest unit of result */ 03184 03185 residue = 0; /* assume no residue */ 03186 if (op & DIVIDE) 03187 { 03188 /* record the presence of any residue, for rounding */ 03189 if (*var1 != 0 || var1units > 1) 03190 residue = 1; 03191 else 03192 { /* no residue */ 03193 /* We had an exact division; clean up spurious trailing 0s. */ 03194 /* There will be at most DECDPUN-1, from the final multiply, */ 03195 /* and then only if the result is non-0 (and even) and the */ 03196 /* exponent is 'loose'. */ 03197 #if DECDPUN>1 03198 Unit lsu = *accnext; 03199 if (!(lsu & 0x01) && (lsu != 0)) 03200 { 03201 /* count the trailing zeros */ 03202 Int drop = 0; 03203 for (;; drop++) 03204 { /* [will terminate because lsu!=0] */ 03205 if (exponent >= maxexponent) 03206 break; /* don't chop real 0s */ 03207 #if DECDPUN<=4 03208 if ((lsu - QUOT10 (lsu, drop + 1) 03209 * powers[drop + 1]) != 0) 03210 break; /* found non-0 digit */ 03211 #else 03212 if (lsu % powers[drop + 1] != 0) 03213 break; /* found non-0 digit */ 03214 #endif 03215 exponent++; 03216 } 03217 if (drop > 0) 03218 { 03219 accunits = decShiftToLeast (accnext, accunits, drop); 03220 accdigits = decGetDigits (accnext, accunits); 03221 accunits = D2U (accdigits); 03222 /* [exponent was adjusted in the loop] */ 03223 } 03224 } /* neither odd nor 0 */ 03225 #endif 03226 } /* exact divide */ 03227 } /* divide */ 03228 else /* op!=DIVIDE */ 03229 { 03230 /* check for coefficient overflow */ 03231 if (accdigits + exponent > reqdigits) 03232 { 03233 *status |= DEC_Division_impossible; 03234 break; 03235 } 03236 if (op & (REMAINDER | REMNEAR)) 03237 { 03238 /* [Here, the exponent will be 0, because we adjusted var1 */ 03239 /* appropriately.] */ 03240 Int postshift; /* work */ 03241 Flag wasodd = 0; /* integer was odd */ 03242 Unit *quotlsu; /* for save */ 03243 Int quotdigits; /* .. */ 03244 03245 /* Fastpath when residue is truly 0 is worthwhile [and */ 03246 /* simplifies the code below] */ 03247 if (*var1 == 0 && var1units == 1) 03248 { /* residue is 0 */ 03249 Int exp = lhs->exponent; /* save min(exponents) */ 03250 if (rhs->exponent < exp) 03251 exp = rhs->exponent; 03252 decNumberZero (res); /* 0 coefficient */ 03253 #if DECSUBSET 03254 if (set->extended) 03255 #endif 03256 res->exponent = exp; /* .. with proper exponent */ 03257 break; 03258 } 03259 /* note if the quotient was odd */ 03260 if (*accnext & 0x01) 03261 wasodd = 1; /* acc is odd */ 03262 quotlsu = accnext; /* save in case need to reinspect */ 03263 quotdigits = accdigits; /* .. */ 03264 03265 /* treat the residue, in var1, as the value to return, via acc */ 03266 /* calculate the unused zero digits. This is the smaller of: */ 03267 /* var1 initial padding (saved above) */ 03268 /* var2 residual padding, which happens to be given by: */ 03269 postshift = 03270 var1initpad + exponent - lhs->exponent + rhs->exponent; 03271 /* [the 'exponent' term accounts for the shifts during divide] */ 03272 if (var1initpad < postshift) 03273 postshift = var1initpad; 03274 03275 /* shift var1 the requested amount, and adjust its digits */ 03276 var1units = decShiftToLeast (var1, var1units, postshift); 03277 accnext = var1; 03278 accdigits = decGetDigits (var1, var1units); 03279 accunits = D2U (accdigits); 03280 03281 exponent = lhs->exponent; /* exponent is smaller of lhs & rhs */ 03282 if (rhs->exponent < exponent) 03283 exponent = rhs->exponent; 03284 bits = lhs->bits; /* remainder sign is always as lhs */ 03285 03286 /* Now correct the result if we are doing remainderNear; if it */ 03287 /* (looking just at coefficients) is > rhs/2, or == rhs/2 and */ 03288 /* the integer was odd then the result should be rem-rhs. */ 03289 if (op & REMNEAR) 03290 { 03291 Int compare, tarunits; /* work */ 03292 Unit *up; /* .. */ 03293 03294 03295 /* calculate remainder*2 into the var1 buffer (which has */ 03296 /* 'headroom' of an extra unit and hence enough space) */ 03297 /* [a dedicated 'double' loop would be faster, here] */ 03298 tarunits = 03299 decUnitAddSub (accnext, accunits, accnext, accunits, 0, 03300 accnext, 1); 03301 /* decDumpAr('r', accnext, tarunits); */ 03302 03303 /* Here, accnext (var1) holds tarunits Units with twice the */ 03304 /* remainder's coefficient, which we must now compare to the */ 03305 /* RHS. The remainder's exponent may be smaller than the RHS's. */ 03306 compare = 03307 decUnitCompare (accnext, tarunits, rhs->lsu, 03308 D2U (rhs->digits), 03309 rhs->exponent - exponent); 03310 if (compare == BADINT) 03311 { /* deep trouble */ 03312 *status |= DEC_Insufficient_storage; 03313 break; 03314 } 03315 03316 /* now restore the remainder by dividing by two; we know the */ 03317 /* lsu is even. */ 03318 for (up = accnext; up < accnext + tarunits; up++) 03319 { 03320 Int half; /* half to add to lower unit */ 03321 half = *up & 0x01; 03322 *up /= 2; /* [shift] */ 03323 if (!half) 03324 continue; 03325 *(up - 1) += (DECDPUNMAX + 1) / 2; 03326 } 03327 /* [accunits still describes the original remainder length] */ 03328 03329 if (compare > 0 || (compare == 0 && wasodd)) 03330 { /* adjustment needed */ 03331 Int exp, expunits, exprem; /* work */ 03332 /* This is effectively causing round-up of the quotient, */ 03333 /* so if it was the rare case where it was full and all */ 03334 /* nines, it would overflow and hence division-impossible */ 03335 /* should be raised */ 03336 Flag allnines = 0; /* 1 if quotient all nines */ 03337 if (quotdigits == reqdigits) 03338 { /* could be borderline */ 03339 for (up = quotlsu;; up++) 03340 { 03341 if (quotdigits > DECDPUN) 03342 { 03343 if (*up != DECDPUNMAX) 03344 break; /* non-nines */ 03345 } 03346 else 03347 { /* this is the last Unit */ 03348 if (*up == powers[quotdigits] - 1) 03349 allnines = 1; 03350 break; 03351 } 03352 quotdigits -= DECDPUN; /* checked those digits */ 03353 } /* up */ 03354 } /* borderline check */ 03355 if (allnines) 03356 { 03357 *status |= DEC_Division_impossible; 03358 break; 03359 } 03360 03361 /* we need rem-rhs; the sign will invert. Again we can */ 03362 /* safely use var1 for the working Units array. */ 03363 exp = rhs->exponent - exponent; /* RHS padding needed */ 03364 /* Calculate units and remainder from exponent. */ 03365 expunits = exp / DECDPUN; 03366 exprem = exp % DECDPUN; 03367 /* subtract [A+B*(-m)]; the result will always be negative */ 03368 accunits = -decUnitAddSub (accnext, accunits, 03369 rhs->lsu, D2U (rhs->digits), 03370 expunits, accnext, 03371 -(Int) powers[exprem]); 03372 accdigits = decGetDigits (accnext, accunits); /* count digits exactly */ 03373 accunits = D2U (accdigits); /* and recalculate the units for copy */ 03374 /* [exponent is as for original remainder] */ 03375 bits ^= DECNEG; /* flip the sign */ 03376 } 03377 } /* REMNEAR */ 03378 } /* REMAINDER or REMNEAR */ 03379 } /* not DIVIDE */ 03380 03381 /* Set exponent and bits */ 03382 res->exponent = exponent; 03383 res->bits = (uByte) (bits & DECNEG); /* [cleaned] */ 03384 03385 /* Now the coefficient. */ 03386 decSetCoeff (res, set, accnext, accdigits, &residue, status); 03387 03388 decFinish (res, set, &residue, status); /* final cleanup */ 03389 03390 #if DECSUBSET 03391 /* If a divide then strip trailing zeros if subset [after round] */ 03392 if (!set->extended && (op == DIVIDE)) 03393 decTrim (res, 0, &dropped); 03394 #endif 03395 } 03396 while (0); /* end protected */ 03397 03398 if (varalloc != NULL) 03399 free (varalloc); /* drop any storage we used */ 03400 if (allocacc != NULL) 03401 free (allocacc); /* .. */ 03402 if (allocrhs != NULL) 03403 free (allocrhs); /* .. */ 03404 if (alloclhs != NULL) 03405 free (alloclhs); /* .. */ 03406 return res; 03407 } 03408 03409 /* ------------------------------------------------------------------ */ 03410 /* decMultiplyOp -- multiplication operation */ 03411 /* */ 03412 /* This routine performs the multiplication C=A x B. */ 03413 /* */ 03414 /* res is C, the result. C may be A and/or B (e.g., X=X*X) */ 03415 /* lhs is A */ 03416 /* rhs is B */ 03417 /* set is the context */ 03418 /* status is the usual accumulator */ 03419 /* */ 03420 /* C must have space for set->digits digits. */ 03421 /* */ 03422 /* ------------------------------------------------------------------ */ 03423 /* Note: We use 'long' multiplication rather than Karatsuba, as the */ 03424 /* latter would give only a minor improvement for the short numbers */ 03425 /* we expect to handle most (and uses much more memory). */ 03426 /* */ 03427 /* We always have to use a buffer for the accumulator. */ 03428 /* ------------------------------------------------------------------ */ 03429 static decNumber * 03430 decMultiplyOp (decNumber * res, const decNumber * lhs, 03431 const decNumber * rhs, decContext * set, uInt * status) 03432 { 03433 decNumber *alloclhs = NULL; /* non-NULL if rounded lhs allocated */ 03434 decNumber *allocrhs = NULL; /* .., rhs */ 03435 Unit accbuff[D2U (DECBUFFER * 2 + 1)]; /* local buffer (+1 in case DECBUFFER==0) */ 03436 Unit *acc = accbuff; /* -> accumulator array for exact result */ 03437 Unit *allocacc = NULL; /* -> allocated buffer, iff allocated */ 03438 const Unit *mer, *mermsup; /* work */ 03439 Int accunits; /* Units of accumulator in use */ 03440 Int madlength; /* Units in multiplicand */ 03441 Int shift; /* Units to shift multiplicand by */ 03442 Int need; /* Accumulator units needed */ 03443 Int exponent; /* work */ 03444 Int residue = 0; /* rounding residue */ 03445 uByte bits; /* result sign */ 03446 uByte merged; /* merged flags */ 03447 03448 #if DECCHECK 03449 if (decCheckOperands (res, lhs, rhs, set)) 03450 return res; 03451 #endif 03452 03453 do 03454 { /* protect allocated storage */ 03455 #if DECSUBSET 03456 if (!set->extended) 03457 { 03458 /* reduce operands and set lostDigits status, as needed */ 03459 if (lhs->digits > set->digits) 03460 { 03461 alloclhs = decRoundOperand (lhs, set, status); 03462 if (alloclhs == NULL) 03463 break; 03464 lhs = alloclhs; 03465 } 03466 if (rhs->digits > set->digits) 03467 { 03468 allocrhs = decRoundOperand (rhs, set, status); 03469 if (allocrhs == NULL) 03470 break; 03471 rhs = allocrhs; 03472 } 03473 } 03474 #endif 03475 /* [following code does not require input rounding] */ 03476 03477 /* precalculate result sign */ 03478 bits = (uByte) ((lhs->bits ^ rhs->bits) & DECNEG); 03479 03480 /* handle infinities and NaNs */ 03481 merged = (lhs->bits | rhs->bits) & DECSPECIAL; 03482 if (merged) 03483 { /* a special bit set */ 03484 if (merged & (DECSNAN | DECNAN)) 03485 { /* one or two NaNs */ 03486 decNaNs (res, lhs, rhs, status); 03487 break; 03488 } 03489 /* one or two infinities. Infinity * 0 is invalid */ 03490 if (((lhs->bits & DECSPECIAL) == 0 && ISZERO (lhs)) 03491 || ((rhs->bits & DECSPECIAL) == 0 && ISZERO (rhs))) 03492 { 03493 *status |= DEC_Invalid_operation; 03494 break; 03495 } 03496 decNumberZero (res); 03497 res->bits = bits | DECINF; /* infinity */ 03498 break; 03499 } 03500 03501 /* For best speed, as in DMSRCN, we use the shorter number as the */ 03502 /* multiplier (rhs) and the longer as the multiplicand (lhs) */ 03503 if (lhs->digits < rhs->digits) 03504 { /* swap... */ 03505 const decNumber *hold = lhs; 03506 lhs = rhs; 03507 rhs = hold; 03508 } 03509 03510 /* if accumulator is too long for local storage, then allocate */ 03511 need = D2U (lhs->digits) + D2U (rhs->digits); /* maximum units in result */ 03512 if (need * sizeof (Unit) > sizeof (accbuff)) 03513 { 03514 allocacc = (Unit *) malloc (need * sizeof (Unit)); 03515 if (allocacc == NULL) 03516 { 03517 *status |= DEC_Insufficient_storage; 03518 break; 03519 } 03520 acc = allocacc; /* use the allocated space */ 03521 } 03522 03523 /* Now the main long multiplication loop */ 03524 /* Unlike the equivalent in the IBM Java implementation, there */ 03525 /* is no advantage in calculating from msu to lsu. So we do it */ 03526 /* by the book, as it were. */ 03527 /* Each iteration calculates ACC=ACC+MULTAND*MULT */ 03528 accunits = 1; /* accumulator starts at '0' */ 03529 *acc = 0; /* .. (lsu=0) */ 03530 shift = 0; /* no multiplicand shift at first */ 03531 madlength = D2U (lhs->digits); /* we know this won't change */ 03532 mermsup = rhs->lsu + D2U (rhs->digits); /* -> msu+1 of multiplier */ 03533 03534 for (mer = rhs->lsu; mer < mermsup; mer++) 03535 { 03536 /* Here, *mer is the next Unit in the multiplier to use */ 03537 /* If non-zero [optimization] add it... */ 03538 if (*mer != 0) 03539 { 03540 accunits = 03541 decUnitAddSub (&acc[shift], accunits - shift, lhs->lsu, 03542 madlength, 0, &acc[shift], *mer) + shift; 03543 } 03544 else 03545 { /* extend acc with a 0; we'll use it shortly */ 03546 /* [this avoids length of <=0 later] */ 03547 *(acc + accunits) = 0; 03548 accunits++; 03549 } 03550 /* multiply multiplicand by 10**DECDPUN for next Unit to left */ 03551 shift++; /* add this for 'logical length' */ 03552 } /* n */ 03553 #if DECTRACE 03554 /* Show exact result */ 03555 decDumpAr ('*', acc, accunits); 03556 #endif 03557 03558 /* acc now contains the exact result of the multiplication */ 03559 /* Build a decNumber from it, noting if any residue */ 03560 res->bits = bits; /* set sign */ 03561 res->digits = decGetDigits (acc, accunits); /* count digits exactly */ 03562 03563 /* We might have a 31-bit wrap in calculating the exponent. */ 03564 /* This can only happen if both input exponents are negative and */ 03565 /* both their magnitudes are large. If we did wrap, we set a safe */ 03566 /* very negative exponent, from which decFinalize() will raise a */ 03567 /* hard underflow. */ 03568 exponent = lhs->exponent + rhs->exponent; /* calculate exponent */ 03569 if (lhs->exponent < 0 && rhs->exponent < 0 && exponent > 0) 03570 exponent = -2 * DECNUMMAXE; /* force underflow */ 03571 res->exponent = exponent; /* OK to overwrite now */ 03572 03573 /* Set the coefficient. If any rounding, residue records */ 03574 decSetCoeff (res, set, acc, res->digits, &residue, status); 03575 03576 decFinish (res, set, &residue, status); /* final cleanup */ 03577 } 03578 while (0); /* end protected */ 03579 03580 if (allocacc != NULL) 03581 free (allocacc); /* drop any storage we used */ 03582 if (allocrhs != NULL) 03583 free (allocrhs); /* .. */ 03584 if (alloclhs != NULL) 03585 free (alloclhs); /* .. */ 03586 return res; 03587 } 03588 03589 /* ------------------------------------------------------------------ */ 03590 /* decQuantizeOp -- force exponent to requested value */ 03591 /* */ 03592 /* This computes C = op(A, B), where op adjusts the coefficient */ 03593 /* of C (by rounding or shifting) such that the exponent (-scale) */ 03594 /* of C has the value B or matches the exponent of B. */ 03595 /* The numerical value of C will equal A, except for the effects of */ 03596 /* any rounding that occurred. */ 03597 /* */ 03598 /* res is C, the result. C may be A or B */ 03599 /* lhs is A, the number to adjust */ 03600 /* rhs is B, the requested exponent */ 03601 /* set is the context */ 03602 /* quant is 1 for quantize or 0 for rescale */ 03603 /* status is the status accumulator (this can be called without */ 03604 /* risk of control loss) */ 03605 /* */ 03606 /* C must have space for set->digits digits. */ 03607 /* */ 03608 /* Unless there is an error or the result is infinite, the exponent */ 03609 /* after the operation is guaranteed to be that requested. */ 03610 /* ------------------------------------------------------------------ */ 03611 static decNumber * 03612 decQuantizeOp (decNumber * res, const decNumber * lhs, 03613 const decNumber * rhs, decContext * set, Flag quant, uInt * status) 03614 { 03615 decNumber *alloclhs = NULL; /* non-NULL if rounded lhs allocated */ 03616 decNumber *allocrhs = NULL; /* .., rhs */ 03617 const decNumber *inrhs = rhs; /* save original rhs */ 03618 Int reqdigits = set->digits; /* requested DIGITS */ 03619 Int reqexp; /* requested exponent [-scale] */ 03620 Int residue = 0; /* rounding residue */ 03621 uByte merged; /* merged flags */ 03622 Int etiny = set->emin - (set->digits - 1); 03623 03624 #if DECCHECK 03625 if (decCheckOperands (res, lhs, rhs, set)) 03626 return res; 03627 #endif 03628 03629 do 03630 { /* protect allocated storage */ 03631 #if DECSUBSET 03632 if (!set->extended) 03633 { 03634 /* reduce operands and set lostDigits status, as needed */ 03635 if (lhs->digits > reqdigits) 03636 { 03637 alloclhs = decRoundOperand (lhs, set, status); 03638 if (alloclhs == NULL) 03639 break; 03640 lhs = alloclhs; 03641 } 03642 if (rhs->digits > reqdigits) 03643 { /* [this only checks lostDigits] */ 03644 allocrhs = decRoundOperand (rhs, set, status); 03645 if (allocrhs == NULL) 03646 break; 03647 rhs = allocrhs; 03648 } 03649 } 03650 #endif 03651 /* [following code does not require input rounding] */ 03652 03653 /* Handle special values */ 03654 merged = (lhs->bits | rhs->bits) & DECSPECIAL; 03655 if ((lhs->bits | rhs->bits) & DECSPECIAL) 03656 { 03657 /* NaNs get usual processing */ 03658 if (merged & (DECSNAN | DECNAN)) 03659 decNaNs (res, lhs, rhs, status); 03660 /* one infinity but not both is bad */ 03661 else if ((lhs->bits ^ rhs->bits) & DECINF) 03662 *status |= DEC_Invalid_operation; 03663 /* both infinity: return lhs */ 03664 else 03665 decNumberCopy (res, lhs); /* [nop if in place] */ 03666 break; 03667 } 03668 03669 /* set requested exponent */ 03670 if (quant) 03671 reqexp = inrhs->exponent; /* quantize -- match exponents */ 03672 else 03673 { /* rescale -- use value of rhs */ 03674 /* Original rhs must be an integer that fits and is in range */ 03675 #if DECSUBSET 03676 reqexp = decGetInt (inrhs, set); 03677 #else 03678 reqexp = decGetInt (inrhs); 03679 #endif 03680 } 03681 03682 #if DECSUBSET 03683 if (!set->extended) 03684 etiny = set->emin; /* no subnormals */ 03685 #endif 03686 03687 if (reqexp == BADINT /* bad (rescale only) or .. */ 03688 || (reqexp < etiny) /* < lowest */ 03689 || (reqexp > set->emax)) 03690 { /* > Emax */ 03691 *status |= DEC_Invalid_operation; 03692 break; 03693 } 03694 03695 /* we've processed the RHS, so we can overwrite it now if necessary */ 03696 if (ISZERO (lhs)) 03697 { /* zero coefficient unchanged */ 03698 decNumberCopy (res, lhs); /* [nop if in place] */ 03699 res->exponent = reqexp; /* .. just set exponent */ 03700 #if DECSUBSET 03701 if (!set->extended) 03702 res->bits = 0; /* subset specification; no -0 */ 03703 #endif 03704 } 03705 else 03706 { /* non-zero lhs */ 03707 Int adjust = reqexp - lhs->exponent; /* digit adjustment needed */ 03708 /* if adjusted coefficient will not fit, give up now */ 03709 if ((lhs->digits - adjust) > reqdigits) 03710 { 03711 *status |= DEC_Invalid_operation; 03712 break; 03713 } 03714 03715 if (adjust > 0) 03716 { /* increasing exponent */ 03717 /* this will decrease the length of the coefficient by adjust */ 03718 /* digits, and must round as it does so */ 03719 decContext workset; /* work */ 03720 workset = *set; /* clone rounding, etc. */ 03721 workset.digits = lhs->digits - adjust; /* set requested length */ 03722 /* [note that the latter can be <1, here] */ 03723 decCopyFit (res, lhs, &workset, &residue, status); /* fit to result */ 03724 decApplyRound (res, &workset, residue, status); /* .. and round */ 03725 residue = 0; /* [used] */ 03726 /* If we rounded a 999s case, exponent will be off by one; */ 03727 /* adjust back if so. */ 03728 if (res->exponent > reqexp) 03729 { 03730 res->digits = decShiftToMost (res->lsu, res->digits, 1); /* shift */ 03731 res->exponent--; /* (re)adjust the exponent. */ 03732 } 03733 #if DECSUBSET 03734 if (ISZERO (res) && !set->extended) 03735 res->bits = 0; /* subset; no -0 */ 03736 #endif 03737 } /* increase */ 03738 else /* adjust<=0 */ 03739 { /* decreasing or = exponent */ 03740 /* this will increase the length of the coefficient by -adjust */ 03741 /* digits, by adding trailing zeros. */ 03742 decNumberCopy (res, lhs); /* [it will fit] */ 03743 /* if padding needed (adjust<0), add it now... */ 03744 if (adjust < 0) 03745 { 03746 res->digits = 03747 decShiftToMost (res->lsu, res->digits, -adjust); 03748 res->exponent += adjust; /* adjust the exponent */ 03749 } 03750 } /* decrease */ 03751 } /* non-zero */ 03752 03753 /* Check for overflow [do not use Finalize in this case, as an */ 03754 /* overflow here is a "don't fit" situation] */ 03755 if (res->exponent > set->emax - res->digits + 1) 03756 { /* too big */ 03757 *status |= DEC_Invalid_operation; 03758 break; 03759 } 03760 else 03761 { 03762 decFinalize (res, set, &residue, status); /* set subnormal flags */ 03763 *status &= ~DEC_Underflow; /* suppress Underflow [754r] */ 03764 } 03765 } 03766 while (0); /* end protected */ 03767 03768 if (allocrhs != NULL) 03769 free (allocrhs); /* drop any storage we used */ 03770 if (alloclhs != NULL) 03771 free (alloclhs); /* .. */ 03772 return res; 03773 } 03774 03775 /* ------------------------------------------------------------------ */ 03776 /* decCompareOp -- compare, min, or max two Numbers */ 03777 /* */ 03778 /* This computes C = A ? B and returns the signum (as a Number) */ 03779 /* for COMPARE or the maximum or minimum (for COMPMAX and COMPMIN). */ 03780 /* */ 03781 /* res is C, the result. C may be A and/or B (e.g., X=X?X) */ 03782 /* lhs is A */ 03783 /* rhs is B */ 03784 /* set is the context */ 03785 /* op is the operation flag */ 03786 /* status is the usual accumulator */ 03787 /* */ 03788 /* C must have space for one digit for COMPARE or set->digits for */ 03789 /* COMPMAX and COMPMIN. */ 03790 /* ------------------------------------------------------------------ */ 03791 /* The emphasis here is on speed for common cases, and avoiding */ 03792 /* coefficient comparison if possible. */ 03793 /* ------------------------------------------------------------------ */ 03794 decNumber * 03795 decCompareOp (decNumber * res, const decNumber * lhs, const decNumber * rhs, 03796 decContext * set, Flag op, uInt * status) 03797 { 03798 decNumber *alloclhs = NULL; /* non-NULL if rounded lhs allocated */ 03799 decNumber *allocrhs = NULL; /* .., rhs */ 03800 Int result = 0; /* default result value */ 03801 uByte merged; /* merged flags */ 03802 uByte bits = 0; /* non-0 for NaN */ 03803 03804 #if DECCHECK 03805 if (decCheckOperands (res, lhs, rhs, set)) 03806 return res; 03807 #endif 03808 03809 do 03810 { /* protect allocated storage */ 03811 #if DECSUBSET 03812 if (!set->extended) 03813 { 03814 /* reduce operands and set lostDigits status, as needed */ 03815 if (lhs->digits > set->digits) 03816 { 03817 alloclhs = decRoundOperand (lhs, set, status); 03818 if (alloclhs == NULL) 03819 { 03820 result = BADINT; 03821 break; 03822 } 03823 lhs = alloclhs; 03824 } 03825 if (rhs->digits > set->digits) 03826 { 03827 allocrhs = decRoundOperand (rhs, set, status); 03828 if (allocrhs == NULL) 03829 { 03830 result = BADINT; 03831 break; 03832 } 03833 rhs = allocrhs; 03834 } 03835 } 03836 #endif 03837 /* [following code does not require input rounding] */ 03838 03839 /* handle NaNs now; let infinities drop through */ 03840 /* +++ review sNaN handling with 754r, for now assumes sNaN */ 03841 /* (even just one) leads to NaN. */ 03842 merged = (lhs->bits | rhs->bits) & (DECSNAN | DECNAN); 03843 if (merged) 03844 { /* a NaN bit set */ 03845 if (op == COMPARE); 03846 else if (merged & DECSNAN); 03847 else 03848 { /* 754r rules for MIN and MAX ignore single NaN */ 03849 /* here if MIN or MAX, and one or two quiet NaNs */ 03850 if (lhs->bits & rhs->bits & DECNAN); 03851 else 03852 { /* just one quiet NaN */ 03853 /* force choice to be the non-NaN operand */ 03854 op = COMPMAX; 03855 if (lhs->bits & DECNAN) 03856 result = -1; /* pick rhs */ 03857 else 03858 result = +1; /* pick lhs */ 03859 break; 03860 } 03861 } 03862 op = COMPNAN; /* use special path */ 03863 decNaNs (res, lhs, rhs, status); 03864 break; 03865 } 03866 03867 result = decCompare (lhs, rhs); /* we have numbers */ 03868 } 03869 while (0); /* end protected */ 03870 03871 if (result == BADINT) 03872 *status |= DEC_Insufficient_storage; /* rare */ 03873 else 03874 { 03875 if (op == COMPARE) 03876 { /* return signum */ 03877 decNumberZero (res); /* [always a valid result] */ 03878 if (result == 0) 03879 res->bits = bits; /* (maybe qNaN) */ 03880 else 03881 { 03882 *res->lsu = 1; 03883 if (result < 0) 03884 res->bits = DECNEG; 03885 } 03886 } 03887 else if (op == COMPNAN); /* special, drop through */ 03888 else 03889 { /* MAX or MIN, non-NaN result */ 03890 Int residue = 0; /* rounding accumulator */ 03891 /* choose the operand for the result */ 03892 const decNumber *choice; 03893 if (result == 0) 03894 { /* operands are numerically equal */ 03895 /* choose according to sign then exponent (see 754r) */ 03896 uByte slhs = (lhs->bits & DECNEG); 03897 uByte srhs = (rhs->bits & DECNEG); 03898 #if DECSUBSET 03899 if (!set->extended) 03900 { /* subset: force left-hand */ 03901 op = COMPMAX; 03902 result = +1; 03903 } 03904 else 03905 #endif 03906 if (slhs != srhs) 03907 { /* signs differ */ 03908 if (slhs) 03909 result = -1; /* rhs is max */ 03910 else 03911 result = +1; /* lhs is max */ 03912 } 03913 else if (slhs && srhs) 03914 { /* both negative */ 03915 if (lhs->exponent < rhs->exponent) 03916 result = +1; 03917 else 03918 result = -1; 03919 /* [if equal, we use lhs, technically identical] */ 03920 } 03921 else 03922 { /* both positive */ 03923 if (lhs->exponent > rhs->exponent) 03924 result = +1; 03925 else 03926 result = -1; 03927 /* [ditto] */ 03928 } 03929 } /* numerically equal */ 03930 /* here result will be non-0 */ 03931 if (op == COMPMIN) 03932 result = -result; /* reverse if looking for MIN */ 03933 choice = (result > 0 ? lhs : rhs); /* choose */ 03934 /* copy chosen to result, rounding if need be */ 03935 decCopyFit (res, choice, set, &residue, status); 03936 decFinish (res, set, &residue, status); 03937 } 03938 } 03939 if (allocrhs != NULL) 03940 free (allocrhs); /* free any storage we used */ 03941 if (alloclhs != NULL) 03942 free (alloclhs); /* .. */ 03943 return res; 03944 } 03945 03946 /* ------------------------------------------------------------------ */ 03947 /* decCompare -- compare two decNumbers by numerical value */ 03948 /* */ 03949 /* This routine compares A ? B without altering them. */ 03950 /* */ 03951 /* Arg1 is A, a decNumber which is not a NaN */ 03952 /* Arg2 is B, a decNumber which is not a NaN */ 03953 /* */ 03954 /* returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure */ 03955 /* (the only possible failure is an allocation error) */ 03956 /* ------------------------------------------------------------------ */ 03957 /* This could be merged into decCompareOp */ 03958 static Int 03959 decCompare (const decNumber * lhs, const decNumber * rhs) 03960 { 03961 Int result; /* result value */ 03962 Int sigr; /* rhs signum */ 03963 Int compare; /* work */ 03964 result = 1; /* assume signum(lhs) */ 03965 if (ISZERO (lhs)) 03966 result = 0; 03967 else if (decNumberIsNegative (lhs)) 03968 result = -1; 03969 sigr = 1; /* compute signum(rhs) */ 03970 if (ISZERO (rhs)) 03971 sigr = 0; 03972 else if (decNumberIsNegative (rhs)) 03973 sigr = -1; 03974 if (result > sigr) 03975 return +1; /* L > R, return 1 */ 03976 if (result < sigr) 03977 return -1; /* R < L, return -1 */ 03978 03979 /* signums are the same */ 03980 if (result == 0) 03981 return 0; /* both 0 */ 03982 /* Both non-zero */ 03983 if ((lhs->bits | rhs->bits) & DECINF) 03984 { /* one or more infinities */ 03985 if (lhs->bits == rhs->bits) 03986 result = 0; /* both the same */ 03987 else if (decNumberIsInfinite (rhs)) 03988 result = -result; 03989 return result; 03990 } 03991 03992 /* we must compare the coefficients, allowing for exponents */ 03993 if (lhs->exponent > rhs->exponent) 03994 { /* LHS exponent larger */ 03995 /* swap sides, and sign */ 03996 const decNumber *temp = lhs; 03997 lhs = rhs; 03998 rhs = temp; 03999 result = -result; 04000 } 04001 04002 compare = decUnitCompare (lhs->lsu, D2U (lhs->digits), 04003 rhs->lsu, D2U (rhs->digits), 04004 rhs->exponent - lhs->exponent); 04005 04006 if (compare != BADINT) 04007 compare *= result; /* comparison succeeded */ 04008 return compare; /* what we got */ 04009 } 04010 04011 /* ------------------------------------------------------------------ */ 04012 /* decUnitCompare -- compare two >=0 integers in Unit arrays */ 04013 /* */ 04014 /* This routine compares A ? B*10**E where A and B are unit arrays */ 04015 /* A is a plain integer */ 04016 /* B has an exponent of E (which must be non-negative) */ 04017 /* */ 04018 /* Arg1 is A first Unit (lsu) */ 04019 /* Arg2 is A length in Units */ 04020 /* Arg3 is B first Unit (lsu) */ 04021 /* Arg4 is B length in Units */ 04022 /* Arg5 is E */ 04023 /* */ 04024 /* returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure */ 04025 /* (the only possible failure is an allocation error) */ 04026 /* ------------------------------------------------------------------ */ 04027 static Int 04028 decUnitCompare (const Unit * a, Int alength, const Unit * b, Int blength, Int exp) 04029 { 04030 Unit *acc; /* accumulator for result */ 04031 Unit accbuff[D2U (DECBUFFER + 1)]; /* local buffer */ 04032 Unit *allocacc = NULL; /* -> allocated acc buffer, iff allocated */ 04033 Int accunits, need; /* units in use or needed for acc */ 04034 const Unit *l, *r, *u; /* work */ 04035 Int expunits, exprem, result; /* .. */ 04036 04037 if (exp == 0) 04038 { /* aligned; fastpath */ 04039 if (alength > blength) 04040 return 1; 04041 if (alength < blength) 04042 return -1; 04043 /* same number of units in both -- need unit-by-unit compare */ 04044 l = a + alength - 1; 04045 r = b + alength - 1; 04046 for (; l >= a; l--, r--) 04047 { 04048 if (*l > *r) 04049 return 1; 04050 if (*l < *r) 04051 return -1; 04052 } 04053 return 0; /* all units match */ 04054 } /* aligned */ 04055 04056 /* Unaligned. If one is >1 unit longer than the other, padded */ 04057 /* approximately, then we can return easily */ 04058 if (alength > blength + (Int) D2U (exp)) 04059 return 1; 04060 if (alength + 1 < blength + (Int) D2U (exp)) 04061 return -1; 04062 04063 /* We need to do a real subtract. For this, we need a result buffer */ 04064 /* even though we only are interested in the sign. Its length needs */ 04065 /* to be the larger of alength and padded blength, +2 */ 04066 need = blength + D2U (exp); /* maximum real length of B */ 04067 if (need < alength) 04068 need = alength; 04069 need += 2; 04070 acc = accbuff; /* assume use local buffer */ 04071 if (need * sizeof (Unit) > sizeof (accbuff)) 04072 { 04073 allocacc = (Unit *) malloc (need * sizeof (Unit)); 04074 if (allocacc == NULL) 04075 return BADINT; /* hopeless -- abandon */ 04076 acc = allocacc; 04077 } 04078 /* Calculate units and remainder from exponent. */ 04079 expunits = exp / DECDPUN; 04080 exprem = exp % DECDPUN; 04081 /* subtract [A+B*(-m)] */ 04082 accunits = decUnitAddSub (a, alength, b, blength, expunits, acc, 04083 -(Int) powers[exprem]); 04084 /* [UnitAddSub result may have leading zeros, even on zero] */ 04085 if (accunits < 0) 04086 result = -1; /* negative result */ 04087 else 04088 { /* non-negative result */ 04089 /* check units of the result before freeing any storage */ 04090 for (u = acc; u < acc + accunits - 1 && *u == 0;) 04091 u++; 04092 result = (*u == 0 ? 0 : +1); 04093 } 04094 /* clean up and return the result */ 04095 if (allocacc != NULL) 04096 free (allocacc); /* drop any storage we used */ 04097 return result; 04098 } 04099 04100 /* ------------------------------------------------------------------ */ 04101 /* decUnitAddSub -- add or subtract two >=0 integers in Unit arrays */ 04102 /* */ 04103 /* This routine performs the calculation: */ 04104 /* */ 04105 /* C=A+(B*M) */ 04106 /* */ 04107 /* Where M is in the range -DECDPUNMAX through +DECDPUNMAX. */ 04108 /* */ 04109 /* A may be shorter or longer than B. */ 04110 /* */ 04111 /* Leading zeros are not removed after a calculation. The result is */ 04112 /* either the same length as the longer of A and B (adding any */ 04113 /* shift), or one Unit longer than that (if a Unit carry occurred). */ 04114 /* */ 04115 /* A and B content are not altered unless C is also A or B. */ 04116 /* C may be the same array as A or B, but only if no zero padding is */ 04117 /* requested (that is, C may be B only if bshift==0). */ 04118 /* C is filled from the lsu; only those units necessary to complete */ 04119 /* the calculation are referenced. */ 04120 /* */ 04121 /* Arg1 is A first Unit (lsu) */ 04122 /* Arg2 is A length in Units */ 04123 /* Arg3 is B first Unit (lsu) */ 04124 /* Arg4 is B length in Units */ 04125 /* Arg5 is B shift in Units (>=0; pads with 0 units if positive) */ 04126 /* Arg6 is C first Unit (lsu) */ 04127 /* Arg7 is M, the multiplier */ 04128 /* */ 04129 /* returns the count of Units written to C, which will be non-zero */ 04130 /* and negated if the result is negative. That is, the sign of the */ 04131 /* returned Int is the sign of the result (positive for zero) and */ 04132 /* the absolute value of the Int is the count of Units. */ 04133 /* */ 04134 /* It is the caller's responsibility to make sure that C size is */ 04135 /* safe, allowing space if necessary for a one-Unit carry. */ 04136 /* */ 04137 /* This routine is severely performance-critical; *any* change here */ 04138 /* must be measured (timed) to assure no performance degradation. */ 04139 /* In particular, trickery here tends to be counter-productive, as */ 04140 /* increased complexity of code hurts register optimizations on */ 04141 /* register-poor architectures. Avoiding divisions is nearly */ 04142 /* always a Good Idea, however. */ 04143 /* */ 04144 /* Special thanks to Rick McGuire (IBM Cambridge, MA) and Dave Clark */ 04145 /* (IBM Warwick, UK) for some of the ideas used in this routine. */ 04146 /* ------------------------------------------------------------------ */ 04147 static Int 04148 decUnitAddSub (const Unit * a, Int alength, 04149 const Unit * b, Int blength, Int bshift, Unit * c, Int m) 04150 { 04151 const Unit *alsu = a; /* A lsu [need to remember it] */ 04152 Unit *clsu = c; /* C ditto */ 04153 Unit *minC; /* low water mark for C */ 04154 Unit *maxC; /* high water mark for C */ 04155 eInt carry = 0; /* carry integer (could be Long) */ 04156 Int add; /* work */ 04157 #if DECDPUN==4 /* myriadal */ 04158 Int est; /* estimated quotient */ 04159 #endif 04160 04161 #if DECTRACE 04162 if (alength < 1 || blength < 1) 04163 printf ("decUnitAddSub: alen blen m %d %d [%d]\n", alength, blength, m); 04164 #endif 04165 04166 maxC = c + alength; /* A is usually the longer */ 04167 minC = c + blength; /* .. and B the shorter */ 04168 if (bshift != 0) 04169 { /* B is shifted; low As copy across */ 04170 minC += bshift; 04171 /* if in place [common], skip copy unless there's a gap [rare] */ 04172 if (a == c && bshift <= alength) 04173 { 04174 c += bshift; 04175 a += bshift; 04176 } 04177 else 04178 for (; c < clsu + bshift; a++, c++) 04179 { /* copy needed */ 04180 if (a < alsu + alength) 04181 *c = *a; 04182 else 04183 *c = 0; 04184 } 04185 } 04186 if (minC > maxC) 04187 { /* swap */ 04188 Unit *hold = minC; 04189 minC = maxC; 04190 maxC = hold; 04191 } 04192 04193 /* For speed, we do the addition as two loops; the first where both A */ 04194 /* and B contribute, and the second (if necessary) where only one or */ 04195 /* other of the numbers contribute. */ 04196 /* Carry handling is the same (i.e., duplicated) in each case. */ 04197 for (; c < minC; c++) 04198 { 04199 carry += *a; 04200 a++; 04201 carry += ((eInt) * b) * m; /* [special-casing m=1/-1 */ 04202 b++; /* here is not a win] */ 04203 /* here carry is new Unit of digits; it could be +ve or -ve */ 04204 if ((ueInt) carry <= DECDPUNMAX) 04205 { /* fastpath 0-DECDPUNMAX */ 04206 *c = (Unit) carry; 04207 carry = 0; 04208 continue; 04209 } 04210 /* remainder operator is undefined if negative, so we must test */ 04211 #if DECDPUN==4 /* use divide-by-multiply */ 04212 if (carry >= 0) 04213 { 04214 est = (((ueInt) carry >> 11) * 53687) >> 18; 04215 *c = (Unit) (carry - est * (DECDPUNMAX + 1)); /* remainder */ 04216 carry = est; /* likely quotient [89%] */ 04217 if (*c < DECDPUNMAX + 1) 04218 continue; /* estimate was correct */ 04219 carry++; 04220 *c -= DECDPUNMAX + 1; 04221 continue; 04222 } 04223 /* negative case */ 04224 carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1); /* make positive */ 04225 est = (((ueInt) carry >> 11) * 53687) >> 18; 04226 *c = (Unit) (carry - est * (DECDPUNMAX + 1)); 04227 carry = est - (DECDPUNMAX + 1); /* correctly negative */ 04228 if (*c < DECDPUNMAX + 1) 04229 continue; /* was OK */ 04230 carry++; 04231 *c -= DECDPUNMAX + 1; 04232 #else 04233 if ((ueInt) carry < (DECDPUNMAX + 1) * 2) 04234 { /* fastpath carry +1 */ 04235 *c = (Unit) (carry - (DECDPUNMAX + 1)); /* [helps additions] */ 04236 carry = 1; 04237 continue; 04238 } 04239 if (carry >= 0) 04240 { 04241 *c = (Unit) (carry % (DECDPUNMAX + 1)); 04242 carry = carry / (DECDPUNMAX + 1); 04243 continue; 04244 } 04245 /* negative case */ 04246 carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1); /* make positive */ 04247 *c = (Unit) (carry % (DECDPUNMAX + 1)); 04248 carry = carry / (DECDPUNMAX + 1) - (DECDPUNMAX + 1); 04249 #endif 04250 } /* c */ 04251 04252 /* we now may have one or other to complete */ 04253 /* [pretest to avoid loop setup/shutdown] */ 04254 if (c < maxC) 04255 for (; c < maxC; c++) 04256 { 04257 if (a < alsu + alength) 04258 { /* still in A */ 04259 carry += *a; 04260 a++; 04261 } 04262 else 04263 { /* inside B */ 04264 carry += ((eInt) * b) * m; 04265 b++; 04266 } 04267 /* here carry is new Unit of digits; it could be +ve or -ve and */ 04268 /* magnitude up to DECDPUNMAX squared */ 04269 if ((ueInt) carry <= DECDPUNMAX) 04270 { /* fastpath 0-DECDPUNMAX */ 04271 *c = (Unit) carry; 04272 carry = 0; 04273 continue; 04274 } 04275 /* result for this unit is negative or >DECDPUNMAX */ 04276 #if DECDPUN==4 /* use divide-by-multiply */ 04277 /* remainder is undefined if negative, so we must test */ 04278 if (carry >= 0) 04279 { 04280 est = (((ueInt) carry >> 11) * 53687) >> 18; 04281 *c = (Unit) (carry - est * (DECDPUNMAX + 1)); /* remainder */ 04282 carry = est; /* likely quotient [79.7%] */ 04283 if (*c < DECDPUNMAX + 1) 04284 continue; /* estimate was correct */ 04285 carry++; 04286 *c -= DECDPUNMAX + 1; 04287 continue; 04288 } 04289 /* negative case */ 04290 carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1); /* make positive */ 04291 est = (((ueInt) carry >> 11) * 53687) >> 18; 04292 *c = (Unit) (carry - est * (DECDPUNMAX + 1)); 04293 carry = est - (DECDPUNMAX + 1); /* correctly negative */ 04294 if (*c < DECDPUNMAX + 1) 04295 continue; /* was OK */ 04296 carry++; 04297 *c -= DECDPUNMAX + 1; 04298 #else 04299 if ((ueInt) carry < (DECDPUNMAX + 1) * 2) 04300 { /* fastpath carry 1 */ 04301 *c = (Unit) (carry - (DECDPUNMAX + 1)); 04302 carry = 1; 04303 continue; 04304 } 04305 /* remainder is undefined if negative, so we must test */ 04306 if (carry >= 0) 04307 { 04308 *c = (Unit) (carry % (DECDPUNMAX + 1)); 04309 carry = carry / (DECDPUNMAX + 1); 04310 continue; 04311 } 04312 /* negative case */ 04313 carry = carry + (eInt) (DECDPUNMAX + 1) * (DECDPUNMAX + 1); /* make positive */ 04314 *c = (Unit) (carry % (DECDPUNMAX + 1)); 04315 carry = carry / (DECDPUNMAX + 1) - (DECDPUNMAX + 1); 04316 #endif 04317 } /* c */ 04318 04319 /* OK, all A and B processed; might still have carry or borrow */ 04320 /* return number of Units in the result, negated if a borrow */ 04321 if (carry == 0) 04322 return c - clsu; /* no carry, we're done */ 04323 if (carry > 0) 04324 { /* positive carry */ 04325 *c = (Unit) carry; /* place as new unit */ 04326 c++; /* .. */ 04327 return c - clsu; 04328 } 04329 /* -ve carry: it's a borrow; complement needed */ 04330 add = 1; /* temporary carry... */ 04331 for (c = clsu; c < maxC; c++) 04332 { 04333 add = DECDPUNMAX + add - *c; 04334 if (add <= DECDPUNMAX) 04335 { 04336 *c = (Unit) add; 04337 add = 0; 04338 } 04339 else 04340 { 04341 *c = 0; 04342 add = 1; 04343 } 04344 } 04345 /* add an extra unit iff it would be non-zero */ 04346 #if DECTRACE 04347 printf ("UAS borrow: add %d, carry %d\n", add, carry); 04348 #endif 04349 if ((add - carry - 1) != 0) 04350 { 04351 *c = (Unit) (add - carry - 1); 04352 c++; /* interesting, include it */ 04353 } 04354 return clsu - c; /* -ve result indicates borrowed */ 04355 } 04356 04357 /* ------------------------------------------------------------------ */ 04358 /* decTrim -- trim trailing zeros or normalize */ 04359 /* */ 04360 /* dn is the number to trim or normalize */ 04361 /* all is 1 to remove all trailing zeros, 0 for just fraction ones */ 04362 /* dropped returns the number of discarded trailing zeros */ 04363 /* returns dn */ 04364 /* */ 04365 /* All fields are updated as required. This is a utility operation, */ 04366 /* so special values are unchanged and no error is possible. */ 04367 /* ------------------------------------------------------------------ */ 04368 static decNumber * 04369 decTrim (decNumber * dn, Flag all, Int * dropped) 04370 { 04371 Int d, exp; /* work */ 04372 uInt cut; /* .. */ 04373 Unit *up; /* -> current Unit */ 04374 04375 #if DECCHECK 04376 if (decCheckOperands (dn, DECUNUSED, DECUNUSED, DECUNUSED)) 04377 return dn; 04378 #endif 04379 04380 *dropped = 0; /* assume no zeros dropped */ 04381 if ((dn->bits & DECSPECIAL) /* fast exit if special .. */ 04382 || (*dn->lsu & 0x01)) 04383 return dn; /* .. or odd */ 04384 if (ISZERO (dn)) 04385 { /* .. or 0 */ 04386 dn->exponent = 0; /* (sign is preserved) */ 04387 return dn; 04388 } 04389 04390 /* we have a finite number which is even */ 04391 exp = dn->exponent; 04392 cut = 1; /* digit (1-DECDPUN) in Unit */ 04393 up = dn->lsu; /* -> current Unit */ 04394 for (d = 0; d < dn->digits - 1; d++) 04395 { /* [don't strip the final digit] */ 04396 /* slice by powers */ 04397 #if DECDPUN<=4 04398 uInt quot = QUOT10 (*up, cut); 04399 if ((*up - quot * powers[cut]) != 0) 04400 break; /* found non-0 digit */ 04401 #else 04402 if (*up % powers[cut] != 0) 04403 break; /* found non-0 digit */ 04404 #endif 04405 /* have a trailing 0 */ 04406 if (!all) 04407 { /* trimming */ 04408 /* [if exp>0 then all trailing 0s are significant for trim] */ 04409 if (exp <= 0) 04410 { /* if digit might be significant */ 04411 if (exp == 0) 04412 break; /* then quit */ 04413 exp++; /* next digit might be significant */ 04414 } 04415 } 04416 cut++; /* next power */ 04417 if (cut > DECDPUN) 04418 { /* need new Unit */ 04419 up++; 04420 cut = 1; 04421 } 04422 } /* d */ 04423 if (d == 0) 04424 return dn; /* none dropped */ 04425 04426 /* effect the drop */ 04427 decShiftToLeast (dn->lsu, D2U (dn->digits), d); 04428 dn->exponent += d; /* maintain numerical value */ 04429 dn->digits -= d; /* new length */ 04430 *dropped = d; /* report the count */ 04431 return dn; 04432 } 04433 04434 /* ------------------------------------------------------------------ */ 04435 /* decShiftToMost -- shift digits in array towards most significant */ 04436 /* */ 04437 /* uar is the array */ 04438 /* digits is the count of digits in use in the array */ 04439 /* shift is the number of zeros to pad with (least significant); */ 04440 /* it must be zero or positive */ 04441 /* */ 04442 /* returns the new length of the integer in the array, in digits */ 04443 /* */ 04444 /* No overflow is permitted (that is, the uar array must be known to */ 04445 /* be large enough to hold the result, after shifting). */ 04446 /* ------------------------------------------------------------------ */ 04447 static Int 04448 decShiftToMost (Unit * uar, Int digits, Int shift) 04449 { 04450 Unit *target, *source, *first; /* work */ 04451 uInt rem; /* for division */ 04452 Int cut; /* odd 0's to add */ 04453 uInt next; /* work */ 04454 04455 if (shift == 0) 04456 return digits; /* [fastpath] nothing to do */ 04457 if ((digits + shift) <= DECDPUN) 04458 { /* [fastpath] single-unit case */ 04459 *uar = (Unit) (*uar * powers[shift]); 04460 return digits + shift; 04461 } 04462 04463 cut = (DECDPUN - shift % DECDPUN) % DECDPUN; 04464 source = uar + D2U (digits) - 1; /* where msu comes from */ 04465 first = uar + D2U (digits + shift) - 1; /* where msu of source will end up */ 04466 target = source + D2U (shift); /* where upper part of first cut goes */ 04467 next = 0; 04468 04469 for (; source >= uar; source--, target--) 04470 { 04471 /* split the source Unit and accumulate remainder for next */ 04472 #if DECDPUN<=4 04473 uInt quot = QUOT10 (*source, cut); 04474 rem = *source - quot * powers[cut]; 04475 next += quot; 04476 #else 04477 rem = *source % powers[cut]; 04478 next += *source / powers[cut]; 04479 #endif 04480 if (target <= first) 04481 *target = (Unit) next; /* write to target iff valid */ 04482 next = rem * powers[DECDPUN - cut]; /* save remainder for next Unit */ 04483 } 04484 /* propagate to one below and clear the rest */ 04485 for (; target >= uar; target--) 04486 { 04487 *target = (Unit) next; 04488 next = 0; 04489 } 04490 return digits + shift; 04491 } 04492 04493 /* ------------------------------------------------------------------ */ 04494 /* decShiftToLeast -- shift digits in array towards least significant */ 04495 /* */ 04496 /* uar is the array */ 04497 /* units is length of the array, in units */ 04498 /* shift is the number of digits to remove from the lsu end; it */ 04499 /* must be zero or positive and less than units*DECDPUN. */ 04500 /* */ 04501 /* returns the new length of the integer in the array, in units */ 04502 /* */ 04503 /* Removed digits are discarded (lost). Units not required to hold */ 04504 /* the final result are unchanged. */ 04505 /* ------------------------------------------------------------------ */ 04506 static Int 04507 decShiftToLeast (Unit * uar, Int units, Int shift) 04508 { 04509 Unit *target, *up; /* work */ 04510 Int cut, count; /* work */ 04511 Int quot, rem; /* for division */ 04512 04513 if (shift == 0) 04514 return units; /* [fastpath] nothing to do */ 04515 04516 up = uar + shift / DECDPUN; /* source; allow for whole Units */ 04517 cut = shift % DECDPUN; /* odd 0's to drop */ 04518 target = uar; /* both paths */ 04519 if (cut == 0) 04520 { /* whole units shift */ 04521 for (; up < uar + units; target++, up++) 04522 *target = *up; 04523 return target - uar; 04524 } 04525 /* messier */ 04526 count = units * DECDPUN - shift; /* the maximum new length */ 04527 #if DECDPUN<=4 04528 quot = QUOT10 (*up, cut); 04529 #else 04530 quot = *up / powers[cut]; 04531 #endif 04532 for (;; target++) 04533 { 04534 *target = (Unit) quot; 04535 count -= (DECDPUN - cut); 04536 if (count <= 0) 04537 break; 04538 up++; 04539 quot = *up; 04540 #if DECDPUN<=4 04541 quot = QUOT10 (quot, cut); 04542 rem = *up - quot * powers[cut]; 04543 #else 04544 rem = quot % powers[cut]; 04545 quot = quot / powers[cut]; 04546 #endif 04547 *target = (Unit) (*target + rem * powers[DECDPUN - cut]); 04548 count -= cut; 04549 if (count <= 0) 04550 break; 04551 } 04552 return target - uar + 1; 04553 } 04554 04555 #if DECSUBSET 04556 /* ------------------------------------------------------------------ */ 04557 /* decRoundOperand -- round an operand [used for subset only] */ 04558 /* */ 04559 /* dn is the number to round (dn->digits is > set->digits) */ 04560 /* set is the relevant context */ 04561 /* status is the status accumulator */ 04562 /* */ 04563 /* returns an allocated decNumber with the rounded result. */ 04564 /* */ 04565 /* lostDigits and other status may be set by this. */ 04566 /* */ 04567 /* Since the input is an operand, we are not permitted to modify it. */ 04568 /* We therefore return an allocated decNumber, rounded as required. */ 04569 /* It is the caller's responsibility to free the allocated storage. */ 04570 /* */ 04571 /* If no storage is available then the result cannot be used, so NULL */ 04572 /* is returned. */ 04573 /* ------------------------------------------------------------------ */ 04574 static decNumber * 04575 decRoundOperand (const decNumber * dn, decContext * set, uInt * status) 04576 { 04577 decNumber *res; /* result structure */ 04578 uInt newstatus = 0; /* status from round */ 04579 Int residue = 0; /* rounding accumulator */ 04580 04581 /* Allocate storage for the returned decNumber, big enough for the */ 04582 /* length specified by the context */ 04583 res = (decNumber *) malloc (sizeof (decNumber) 04584 + (D2U (set->digits) - 1) * sizeof (Unit)); 04585 if (res == NULL) 04586 { 04587 *status |= DEC_Insufficient_storage; 04588 return NULL; 04589 } 04590 decCopyFit (res, dn, set, &residue, &newstatus); 04591 decApplyRound (res, set, residue, &newstatus); 04592 04593 /* If that set Inexact then we "lost digits" */ 04594 if (newstatus & DEC_Inexact) 04595 newstatus |= DEC_Lost_digits; 04596 *status |= newstatus; 04597 return res; 04598 } 04599 #endif 04600 04601 /* ------------------------------------------------------------------ */ 04602 /* decCopyFit -- copy a number, shortening the coefficient if needed */ 04603 /* */ 04604 /* dest is the target decNumber */ 04605 /* src is the source decNumber */ 04606 /* set is the context [used for length (digits) and rounding mode] */ 04607 /* residue is the residue accumulator */ 04608 /* status contains the current status to be updated */ 04609 /* */ 04610 /* (dest==src is allowed and will be a no-op if fits) */ 04611 /* All fields are updated as required. */ 04612 /* ------------------------------------------------------------------ */ 04613 static void 04614 decCopyFit (decNumber * dest, const decNumber * src, decContext * set, 04615 Int * residue, uInt * status) 04616 { 04617 dest->bits = src->bits; 04618 dest->exponent = src->exponent; 04619 decSetCoeff (dest, set, src->lsu, src->digits, residue, status); 04620 } 04621 04622 /* ------------------------------------------------------------------ */ 04623 /* decSetCoeff -- set the coefficient of a number */ 04624 /* */ 04625 /* dn is the number whose coefficient array is to be set. */ 04626 /* It must have space for set->digits digits */ 04627 /* set is the context [for size] */ 04628 /* lsu -> lsu of the source coefficient [may be dn->lsu] */ 04629 /* len is digits in the source coefficient [may be dn->digits] */ 04630 /* residue is the residue accumulator. This has values as in */ 04631 /* decApplyRound, and will be unchanged unless the */ 04632 /* target size is less than len. In this case, the */ 04633 /* coefficient is truncated and the residue is updated to */ 04634 /* reflect the previous residue and the dropped digits. */ 04635 /* status is the status accumulator, as usual */ 04636 /* */ 04637 /* The coefficient may already be in the number, or it can be an */ 04638 /* external intermediate array. If it is in the number, lsu must == */ 04639 /* dn->lsu and len must == dn->digits. */ 04640 /* */ 04641 /* Note that the coefficient length (len) may be < set->digits, and */ 04642 /* in this case this merely copies the coefficient (or is a no-op */ 04643 /* if dn->lsu==lsu). */ 04644 /* */ 04645 /* Note also that (only internally, from decNumberRescale and */ 04646 /* decSetSubnormal) the value of set->digits may be less than one, */ 04647 /* indicating a round to left. */ 04648 /* This routine handles that case correctly; caller ensures space. */ 04649 /* */ 04650 /* dn->digits, dn->lsu (and as required), and dn->exponent are */ 04651 /* updated as necessary. dn->bits (sign) is unchanged. */ 04652 /* */ 04653 /* DEC_Rounded status is set if any digits are discarded. */ 04654 /* DEC_Inexact status is set if any non-zero digits are discarded, or */ 04655 /* incoming residue was non-0 (implies rounded) */ 04656 /* ------------------------------------------------------------------ */ 04657 /* mapping array: maps 0-9 to canonical residues, so that we can */ 04658 /* adjust by a residue in range [-1, +1] and achieve correct rounding */ 04659 /* 0 1 2 3 4 5 6 7 8 9 */ 04660 static const uByte resmap[10] = { 0, 3, 3, 3, 3, 5, 7, 7, 7, 7 }; 04661 static void 04662 decSetCoeff (decNumber * dn, decContext * set, const Unit * lsu, 04663 Int len, Int * residue, uInt * status) 04664 { 04665 Int discard; /* number of digits to discard */ 04666 uInt discard1; /* first discarded digit */ 04667 uInt cut; /* cut point in Unit */ 04668 uInt quot, rem; /* for divisions */ 04669 Unit *target; /* work */ 04670 const Unit *up; /* work */ 04671 Int count; /* .. */ 04672 #if DECDPUN<=4 04673 uInt temp; /* .. */ 04674 #endif 04675 04676 discard = len - set->digits; /* digits to discard */ 04677 if (discard <= 0) 04678 { /* no digits are being discarded */ 04679 if (dn->lsu != lsu) 04680 { /* copy needed */ 04681 /* copy the coefficient array to the result number; no shift needed */ 04682 up = lsu; 04683 for (target = dn->lsu; target < dn->lsu + D2U (len); target++, up++) 04684 { 04685 *target = *up; 04686 } 04687 dn->digits = len; /* set the new length */ 04688 } 04689 /* dn->exponent and residue are unchanged */ 04690 if (*residue != 0) 04691 *status |= (DEC_Inexact | DEC_Rounded); /* record inexactitude */ 04692 return; 04693 } 04694 04695 /* we have to discard some digits */ 04696 *status |= DEC_Rounded; /* accumulate Rounded status */ 04697 if (*residue > 1) 04698 *residue = 1; /* previous residue now to right, so -1 to +1 */ 04699 04700 if (discard > len) 04701 { /* everything, +1, is being discarded */ 04702 /* guard digit is 0 */ 04703 /* residue is all the number [NB could be all 0s] */ 04704 if (*residue <= 0) 04705 for (up = lsu + D2U (len) - 1; up >= lsu; up--) 04706 { 04707 if (*up != 0) 04708 { /* found a non-0 */ 04709 *residue = 1; 04710 break; /* no need to check any others */ 04711 } 04712 } 04713 if (*residue != 0) 04714 *status |= DEC_Inexact; /* record inexactitude */ 04715 *dn->lsu = 0; /* coefficient will now be 0 */ 04716 dn->digits = 1; /* .. */ 04717 dn->exponent += discard; /* maintain numerical value */ 04718 return; 04719 } /* total discard */ 04720 04721 /* partial discard [most common case] */ 04722 /* here, at least the first (most significant) discarded digit exists */ 04723 04724 /* spin up the number, noting residue as we pass, until we get to */ 04725 /* the Unit with the first discarded digit. When we get there, */ 04726 /* extract it and remember where we're at */ 04727 count = 0; 04728 for (up = lsu;; up++) 04729 { 04730 count += DECDPUN; 04731 if (count >= discard) 04732 break; /* full ones all checked */ 04733 if (*up != 0) 04734 *residue = 1; 04735 } /* up */ 04736 04737 /* here up -> Unit with discarded digit */ 04738 cut = discard - (count - DECDPUN) - 1; 04739 if (cut == DECDPUN - 1) 04740 { /* discard digit is at top */ 04741 #if DECDPUN<=4 04742 discard1 = QUOT10 (*up, DECDPUN - 1); 04743 rem = *up - discard1 * powers[DECDPUN - 1]; 04744 #else 04745 rem = *up % powers[DECDPUN - 1]; 04746 discard1 = *up / powers[DECDPUN - 1]; 04747 #endif 04748 if (rem != 0) 04749 *residue = 1; 04750 up++; /* move to next */ 04751 cut = 0; /* bottom digit of result */ 04752 quot = 0; /* keep a certain compiler happy */ 04753 } 04754 else 04755 { 04756 /* discard digit is in low digit(s), not top digit */ 04757 if (cut == 0) 04758 quot = *up; 04759 else /* cut>0 */ 04760 { /* it's not at bottom of Unit */ 04761 #if DECDPUN<=4 04762 quot = QUOT10 (*up, cut); 04763 rem = *up - quot * powers[cut]; 04764 #else 04765 rem = *up % powers[cut]; 04766 quot = *up / powers[cut]; 04767 #endif 04768 if (rem != 0) 04769 *residue = 1; 04770 } 04771 /* discard digit is now at bottom of quot */ 04772 #if DECDPUN<=4 04773 temp = (quot * 6554) >> 16; /* fast /10 */ 04774 /* Vowels algorithm here not a win (9 instructions) */ 04775 discard1 = quot - X10 (temp); 04776 quot = temp; 04777 #else 04778 discard1 = quot % 10; 04779 quot = quot / 10; 04780 #endif 04781 cut++; /* update cut */ 04782 } 04783 04784 /* here: up -> Unit of the array with discarded digit */ 04785 /* cut is the division point for each Unit */ 04786 /* quot holds the uncut high-order digits for the current */ 04787 /* Unit, unless cut==0 in which case it's still in *up */ 04788 /* copy the coefficient array to the result number, shifting as we go */ 04789 count = set->digits; /* digits to end up with */ 04790 if (count <= 0) 04791 { /* special for Rescale/Subnormal :-( */ 04792 *dn->lsu = 0; /* .. result is 0 */ 04793 dn->digits = 1; /* .. */ 04794 } 04795 else 04796 { /* shift to least */ 04797 /* [this is similar to decShiftToLeast code, with copy] */ 04798 dn->digits = count; /* set the new length */ 04799 if (cut == 0) 04800 { 04801 /* on unit boundary, so simple shift down copy loop suffices */ 04802 for (target = dn->lsu; target < dn->lsu + D2U (count); 04803 target++, up++) 04804 { 04805 *target = *up; 04806 } 04807 } 04808 else 04809 for (target = dn->lsu;; target++) 04810 { 04811 *target = (Unit) quot; 04812 count -= (DECDPUN - cut); 04813 if (count <= 0) 04814 break; 04815 up++; 04816 quot = *up; 04817 #if DECDPUN<=4 04818 quot = QUOT10 (quot, cut); 04819 rem = *up - quot * powers[cut]; 04820 #else 04821 rem = quot % powers[cut]; 04822 quot = quot / powers[cut]; 04823 #endif 04824 *target = (Unit) (*target + rem * powers[DECDPUN - cut]); 04825 count -= cut; 04826 if (count <= 0) 04827 break; 04828 } 04829 } /* shift to least needed */ 04830 dn->exponent += discard; /* maintain numerical value */ 04831 04832 /* here, discard1 is the guard digit, and residue is everything else */ 04833 /* [use mapping to accumulate residue safely] */ 04834 *residue += resmap[discard1]; 04835 04836 if (*residue != 0) 04837 *status |= DEC_Inexact; /* record inexactitude */ 04838 return; 04839 } 04840 04841 /* ------------------------------------------------------------------ */ 04842 /* decApplyRound -- apply pending rounding to a number */ 04843 /* */ 04844 /* dn is the number, with space for set->digits digits */ 04845 /* set is the context [for size and rounding mode] */ 04846 /* residue indicates pending rounding, being any accumulated */ 04847 /* guard and sticky information. It may be: */ 04848 /* 6-9: rounding digit is >5 */ 04849 /* 5: rounding digit is exactly half-way */ 04850 /* 1-4: rounding digit is <5 and >0 */ 04851 /* 0: the coefficient is exact */ 04852 /* -1: as 1, but the hidden digits are subtractive, that */ 04853 /* is, of the opposite sign to dn. In this case the */ 04854 /* coefficient must be non-0. */ 04855 /* status is the status accumulator, as usual */ 04856 /* */ 04857 /* This routine applies rounding while keeping the length of the */ 04858 /* coefficient constant. The exponent and status are unchanged */ 04859 /* except if: */ 04860 /* */ 04861 /* -- the coefficient was increased and is all nines (in which */ 04862 /* case Overflow could occur, and is handled directly here so */ 04863 /* the caller does not need to re-test for overflow) */ 04864 /* */ 04865 /* -- the coefficient was decreased and becomes all nines (in which */ 04866 /* case Underflow could occur, and is also handled directly). */ 04867 /* */ 04868 /* All fields in dn are updated as required. */ 04869 /* */ 04870 /* ------------------------------------------------------------------ */ 04871 static void 04872 decApplyRound (decNumber * dn, decContext * set, Int residue, uInt * status) 04873 { 04874 Int bump; /* 1 if coefficient needs to be incremented */ 04875 /* -1 if coefficient needs to be decremented */ 04876 04877 if (residue == 0) 04878 return; /* nothing to apply */ 04879 04880 bump = 0; /* assume a smooth ride */ 04881 04882 /* now decide whether, and how, to round, depending on mode */ 04883 switch (set->round) 04884 { 04885 case DEC_ROUND_DOWN: 04886 { 04887 /* no change, except if negative residue */ 04888 if (residue < 0) 04889 bump = -1; 04890 break; 04891 } /* r-d */ 04892 04893 case DEC_ROUND_HALF_DOWN: 04894 { 04895 if (residue > 5) 04896 bump = 1; 04897 break; 04898 } /* r-h-d */ 04899 04900 case DEC_ROUND_HALF_EVEN: 04901 { 04902 if (residue > 5) 04903 bump = 1; /* >0.5 goes up */ 04904 else if (residue == 5) 04905 { /* exactly 0.5000... */ 04906 /* 0.5 goes up iff [new] lsd is odd */ 04907 if (*dn->lsu & 0x01) 04908 bump = 1; 04909 } 04910 break; 04911 } /* r-h-e */ 04912 04913 case DEC_ROUND_HALF_UP: 04914 { 04915 if (residue >= 5) 04916 bump = 1; 04917 break; 04918 } /* r-h-u */ 04919 04920 case DEC_ROUND_UP: 04921 { 04922 if (residue > 0) 04923 bump = 1; 04924 break; 04925 } /* r-u */ 04926 04927 case DEC_ROUND_CEILING: 04928 { 04929 /* same as _UP for positive numbers, and as _DOWN for negatives */ 04930 /* [negative residue cannot occur on 0] */ 04931 if (decNumberIsNegative (dn)) 04932 { 04933 if (residue < 0) 04934 bump = -1; 04935 } 04936 else 04937 { 04938 if (residue > 0) 04939 bump = 1; 04940 } 04941 break; 04942 } /* r-c */ 04943 04944 case DEC_ROUND_FLOOR: 04945 { 04946 /* same as _UP for negative numbers, and as _DOWN for positive */ 04947 /* [negative residue cannot occur on 0] */ 04948 if (!decNumberIsNegative (dn)) 04949 { 04950 if (residue < 0) 04951 bump = -1; 04952 } 04953 else 04954 { 04955 if (residue > 0) 04956 bump = 1; 04957 } 04958 break; 04959 } /* r-f */ 04960 04961 default: 04962 { /* e.g., DEC_ROUND_MAX */ 04963 *status |= DEC_Invalid_context; 04964 #if DECTRACE 04965 printf ("Unknown rounding mode: %d\n", set->round); 04966 #endif 04967 break; 04968 } 04969 } /* switch */ 04970 04971 /* now bump the number, up or down, if need be */ 04972 if (bump == 0) 04973 return; /* no action required */ 04974 04975 /* Simply use decUnitAddSub unless we are bumping up and the number */ 04976 /* is all nines. In this special case we set to 1000... and adjust */ 04977 /* the exponent by one (as otherwise we could overflow the array) */ 04978 /* Similarly handle all-nines result if bumping down. */ 04979 if (bump > 0) 04980 { 04981 Unit *up; /* work */ 04982 uInt count = dn->digits; /* digits to be checked */ 04983 for (up = dn->lsu;; up++) 04984 { 04985 if (count <= DECDPUN) 04986 { 04987 /* this is the last Unit (the msu) */ 04988 if (*up != powers[count] - 1) 04989 break; /* not still 9s */ 04990 /* here if it, too, is all nines */ 04991 *up = (Unit) powers[count - 1]; /* here 999 -> 100 etc. */ 04992 for (up = up - 1; up >= dn->lsu; up--) 04993 *up = 0; /* others all to 0 */ 04994 dn->exponent++; /* and bump exponent */ 04995 /* [which, very rarely, could cause Overflow...] */ 04996 if ((dn->exponent + dn->digits) > set->emax + 1) 04997 { 04998 decSetOverflow (dn, set, status); 04999 } 05000 return; /* done */ 05001 } 05002 /* a full unit to check, with more to come */ 05003 if (*up != DECDPUNMAX) 05004 break; /* not still 9s */ 05005 count -= DECDPUN; 05006 } /* up */ 05007 } /* bump>0 */ 05008 else 05009 { /* -1 */ 05010 /* here we are lookng for a pre-bump of 1000... (leading 1, */ 05011 /* all other digits zero) */ 05012 Unit *up, *sup; /* work */ 05013 uInt count = dn->digits; /* digits to be checked */ 05014 for (up = dn->lsu;; up++) 05015 { 05016 if (count <= DECDPUN) 05017 { 05018 /* this is the last Unit (the msu) */ 05019 if (*up != powers[count - 1]) 05020 break; /* not 100.. */ 05021 /* here if we have the 1000... case */ 05022 sup = up; /* save msu pointer */ 05023 *up = (Unit) powers[count] - 1; /* here 100 in msu -> 999 */ 05024 /* others all to all-nines, too */ 05025 for (up = up - 1; up >= dn->lsu; up--) 05026 *up = (Unit) powers[DECDPUN] - 1; 05027 dn->exponent--; /* and bump exponent */ 05028 05029 /* iff the number was at the subnormal boundary (exponent=etiny) */ 05030 /* then the exponent is now out of range, so it will in fact get */ 05031 /* clamped to etiny and the final 9 dropped. */ 05032 /* printf(">> emin=%d exp=%d sdig=%d\n", set->emin, */ 05033 /* dn->exponent, set->digits); */ 05034 if (dn->exponent + 1 == set->emin - set->digits + 1) 05035 { 05036 if (count == 1 && dn->digits == 1) 05037 *sup = 0; /* here 9 -> 0[.9] */ 05038 else 05039 { 05040 *sup = (Unit) powers[count - 1] - 1; /* here 999.. in msu -> 99.. */ 05041 dn->digits--; 05042 } 05043 dn->exponent++; 05044 *status |= 05045 DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded; 05046 } 05047 return; /* done */ 05048 } 05049 05050 /* a full unit to check, with more to come */ 05051 if (*up != 0) 05052 break; /* not still 0s */ 05053 count -= DECDPUN; 05054 } /* up */ 05055 05056 } /* bump<0 */ 05057 05058 /* Actual bump needed. Do it. */ 05059 decUnitAddSub (dn->lsu, D2U (dn->digits), one, 1, 0, dn->lsu, bump); 05060 } 05061 05062 #if DECSUBSET 05063 /* ------------------------------------------------------------------ */ 05064 /* decFinish -- finish processing a number */ 05065 /* */ 05066 /* dn is the number */ 05067 /* set is the context */ 05068 /* residue is the rounding accumulator (as in decApplyRound) */ 05069 /* status is the accumulator */ 05070 /* */ 05071 /* This finishes off the current number by: */ 05072 /* 1. If not extended: */ 05073 /* a. Converting a zero result to clean '0' */ 05074 /* b. Reducing positive exponents to 0, if would fit in digits */ 05075 /* 2. Checking for overflow and subnormals (always) */ 05076 /* Note this is just Finalize when no subset arithmetic. */ 05077 /* All fields are updated as required. */ 05078 /* ------------------------------------------------------------------ */ 05079 static void 05080 decFinish (decNumber * dn, decContext * set, Int * residue, uInt * status) 05081 { 05082 if (!set->extended) 05083 { 05084 if ISZERO 05085 (dn) 05086 { /* value is zero */ 05087 dn->exponent = 0; /* clean exponent .. */ 05088 dn->bits = 0; /* .. and sign */ 05089 return; /* no error possible */ 05090 } 05091 if (dn->exponent >= 0) 05092 { /* non-negative exponent */ 05093 /* >0; reduce to integer if possible */ 05094 if (set->digits >= (dn->exponent + dn->digits)) 05095 { 05096 dn->digits = decShiftToMost (dn->lsu, dn->digits, dn->exponent); 05097 dn->exponent = 0; 05098 } 05099 } 05100 } /* !extended */ 05101 05102 decFinalize (dn, set, residue, status); 05103 } 05104 #endif 05105 05106 /* ------------------------------------------------------------------ */ 05107 /* decFinalize -- final check, clamp, and round of a number */ 05108 /* */ 05109 /* dn is the number */ 05110 /* set is the context */ 05111 /* residue is the rounding accumulator (as in decApplyRound) */ 05112 /* status is the status accumulator */ 05113 /* */ 05114 /* This finishes off the current number by checking for subnormal */ 05115 /* results, applying any pending rounding, checking for overflow, */ 05116 /* and applying any clamping. */ 05117 /* Underflow and overflow conditions are raised as appropriate. */ 05118 /* All fields are updated as required. */ 05119 /* ------------------------------------------------------------------ */ 05120 static void 05121 decFinalize (decNumber * dn, decContext * set, Int * residue, uInt * status) 05122 { 05123 Int shift; /* shift needed if clamping */ 05124 05125 /* We have to be careful when checking the exponent as the adjusted */ 05126 /* exponent could overflow 31 bits [because it may already be up */ 05127 /* to twice the expected]. */ 05128 05129 /* First test for subnormal. This must be done before any final */ 05130 /* round as the result could be rounded to Nmin or 0. */ 05131 if (dn->exponent < 0 /* negative exponent */ 05132 && (dn->exponent < set->emin - dn->digits + 1)) 05133 { 05134 /* Go handle subnormals; this will apply round if needed. */ 05135 decSetSubnormal (dn, set, residue, status); 05136 return; 05137 } 05138 05139 /* now apply any pending round (this could raise overflow). */ 05140 if (*residue != 0) 05141 decApplyRound (dn, set, *residue, status); 05142 05143 /* Check for overflow [redundant in the 'rare' case] or clamp */ 05144 if (dn->exponent <= set->emax - set->digits + 1) 05145 return; /* neither needed */ 05146 05147 /* here when we might have an overflow or clamp to do */ 05148 if (dn->exponent > set->emax - dn->digits + 1) 05149 { /* too big */ 05150 decSetOverflow (dn, set, status); 05151 return; 05152 } 05153 /* here when the result is normal but in clamp range */ 05154 if (!set->clamp) 05155 return; 05156 05157 /* here when we need to apply the IEEE exponent clamp (fold-down) */ 05158 shift = dn->exponent - (set->emax - set->digits + 1); 05159 05160 /* shift coefficient (if non-zero) */ 05161 if (!ISZERO (dn)) 05162 { 05163 dn->digits = decShiftToMost (dn->lsu, dn->digits, shift); 05164 } 05165 dn->exponent -= shift; /* adjust the exponent to match */ 05166 *status |= DEC_Clamped; /* and record the dirty deed */ 05167 return; 05168 } 05169 05170 /* ------------------------------------------------------------------ */ 05171 /* decSetOverflow -- set number to proper overflow value */ 05172 /* */ 05173 /* dn is the number (used for sign [only] and result) */ 05174 /* set is the context [used for the rounding mode] */ 05175 /* status contains the current status to be updated */ 05176 /* */ 05177 /* This sets the sign of a number and sets its value to either */ 05178 /* Infinity or the maximum finite value, depending on the sign of */ 05179 /* dn and therounding mode, following IEEE 854 rules. */ 05180 /* ------------------------------------------------------------------ */ 05181 static void 05182 decSetOverflow (decNumber * dn, decContext * set, uInt * status) 05183 { 05184 Flag needmax = 0; /* result is maximum finite value */ 05185 uByte sign = dn->bits & DECNEG; /* clean and save sign bit */ 05186 05187 if (ISZERO (dn)) 05188 { /* zero does not overflow magnitude */ 05189 Int emax = set->emax; /* limit value */ 05190 if (set->clamp) 05191 emax -= set->digits - 1; /* lower if clamping */ 05192 if (dn->exponent > emax) 05193 { /* clamp required */ 05194 dn->exponent = emax; 05195 *status |= DEC_Clamped; 05196 } 05197 return; 05198 } 05199 05200 decNumberZero (dn); 05201 switch (set->round) 05202 { 05203 case DEC_ROUND_DOWN: 05204 { 05205 needmax = 1; /* never Infinity */ 05206 break; 05207 } /* r-d */ 05208 case DEC_ROUND_CEILING: 05209 { 05210 if (sign) 05211 needmax = 1; /* Infinity if non-negative */ 05212 break; 05213 } /* r-c */ 05214 case DEC_ROUND_FLOOR: 05215 { 05216 if (!sign) 05217 needmax = 1; /* Infinity if negative */ 05218 break; 05219 } /* r-f */ 05220 default: 05221 break; /* Infinity in all other cases */ 05222 } 05223 if (needmax) 05224 { 05225 Unit *up; /* work */ 05226 Int count = set->digits; /* nines to add */ 05227 dn->digits = count; 05228 /* fill in all nines to set maximum value */ 05229 for (up = dn->lsu;; up++) 05230 { 05231 if (count > DECDPUN) 05232 *up = DECDPUNMAX; /* unit full o'nines */ 05233 else 05234 { /* this is the msu */ 05235 *up = (Unit) (powers[count] - 1); 05236 break; 05237 } 05238 count -= DECDPUN; /* we filled those digits */ 05239 } /* up */ 05240 dn->bits = sign; /* sign */ 05241 dn->exponent = set->emax - set->digits + 1; 05242 } 05243 else 05244 dn->bits = sign | DECINF; /* Value is +/-Infinity */ 05245 *status |= DEC_Overflow | DEC_Inexact | DEC_Rounded; 05246 } 05247 05248 /* ------------------------------------------------------------------ */ 05249 /* decSetSubnormal -- process value whose exponent is <Emin */ 05250 /* */ 05251 /* dn is the number (used as input as well as output; it may have */ 05252 /* an allowed subnormal value, which may need to be rounded) */ 05253 /* set is the context [used for the rounding mode] */ 05254 /* residue is any pending residue */ 05255 /* status contains the current status to be updated */ 05256 /* */ 05257 /* If subset mode, set result to zero and set Underflow flags. */ 05258 /* */ 05259 /* Value may be zero with a low exponent; this does not set Subnormal */ 05260 /* but the exponent will be clamped to Etiny. */ 05261 /* */ 05262 /* Otherwise ensure exponent is not out of range, and round as */ 05263 /* necessary. Underflow is set if the result is Inexact. */ 05264 /* ------------------------------------------------------------------ */ 05265 static void 05266 decSetSubnormal (decNumber * dn, decContext * set, 05267 Int * residue, uInt * status) 05268 { 05269 decContext workset; /* work */ 05270 Int etiny, adjust; /* .. */ 05271 05272 #if DECSUBSET 05273 /* simple set to zero and 'hard underflow' for subset */ 05274 if (!set->extended) 05275 { 05276 decNumberZero (dn); 05277 /* always full overflow */ 05278 *status |= DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded; 05279 return; 05280 } 05281 #endif 05282 05283 /* Full arithmetic -- allow subnormals, rounded to minimum exponent */ 05284 /* (Etiny) if needed */ 05285 etiny = set->emin - (set->digits - 1); /* smallest allowed exponent */ 05286 05287 if ISZERO 05288 (dn) 05289 { /* value is zero */ 05290 /* residue can never be non-zero here */ 05291 #if DECCHECK 05292 if (*residue != 0) 05293 { 05294 printf ("++ Subnormal 0 residue %d\n", *residue); 05295 *status |= DEC_Invalid_operation; 05296 } 05297 #endif 05298 if (dn->exponent < etiny) 05299 { /* clamp required */ 05300 dn->exponent = etiny; 05301 *status |= DEC_Clamped; 05302 } 05303 return; 05304 } 05305 05306 *status |= DEC_Subnormal; /* we have a non-zero subnormal */ 05307 05308 adjust = etiny - dn->exponent; /* calculate digits to remove */ 05309 if (adjust <= 0) 05310 { /* not out of range; unrounded */ 05311 /* residue can never be non-zero here, so fast-path out */ 05312 #if DECCHECK 05313 if (*residue != 0) 05314 { 05315 printf ("++ Subnormal no-adjust residue %d\n", *residue); 05316 *status |= DEC_Invalid_operation; 05317 } 05318 #endif 05319 /* it may already be inexact (from setting the coefficient) */ 05320 if (*status & DEC_Inexact) 05321 *status |= DEC_Underflow; 05322 return; 05323 } 05324 05325 /* adjust>0. we need to rescale the result so exponent becomes Etiny */ 05326 /* [this code is similar to that in rescale] */ 05327 workset = *set; /* clone rounding, etc. */ 05328 workset.digits = dn->digits - adjust; /* set requested length */ 05329 workset.emin -= adjust; /* and adjust emin to match */ 05330 /* [note that the latter can be <1, here, similar to Rescale case] */ 05331 decSetCoeff (dn, &workset, dn->lsu, dn->digits, residue, status); 05332 decApplyRound (dn, &workset, *residue, status); 05333 05334 /* Use 754R/854 default rule: Underflow is set iff Inexact */ 05335 /* [independent of whether trapped] */ 05336 if (*status & DEC_Inexact) 05337 *status |= DEC_Underflow; 05338 05339 /* if we rounded up a 999s case, exponent will be off by one; adjust */ 05340 /* back if so [it will fit, because we shortened] */ 05341 if (dn->exponent > etiny) 05342 { 05343 dn->digits = decShiftToMost (dn->lsu, dn->digits, 1); 05344 dn->exponent--; /* (re)adjust the exponent. */ 05345 } 05346 } 05347 05348 /* ------------------------------------------------------------------ */ 05349 /* decGetInt -- get integer from a number */ 05350 /* */ 05351 /* dn is the number [which will not be altered] */ 05352 /* set is the context [requested digits], subset only */ 05353 /* returns the converted integer, or BADINT if error */ 05354 /* */ 05355 /* This checks and gets a whole number from the input decNumber. */ 05356 /* The magnitude of the integer must be <2^31. */ 05357 /* Any discarded fractional part must be 0. */ 05358 /* If subset it must also fit in set->digits */ 05359 /* ------------------------------------------------------------------ */ 05360 #if DECSUBSET 05361 static Int 05362 decGetInt (const decNumber * dn, decContext * set) 05363 { 05364 #else 05365 static Int 05366 decGetInt (const decNumber * dn) 05367 { 05368 #endif 05369 Int theInt; /* result accumulator */ 05370 const Unit *up; /* work */ 05371 Int got; /* digits (real or not) processed */ 05372 Int ilength = dn->digits + dn->exponent; /* integral length */ 05373 05374 /* The number must be an integer that fits in 10 digits */ 05375 /* Assert, here, that 10 is enough for any rescale Etiny */ 05376 #if DEC_MAX_EMAX > 999999999 05377 #error GetInt may need updating [for Emax] 05378 #endif 05379 #if DEC_MIN_EMIN < -999999999 05380 #error GetInt may need updating [for Emin] 05381 #endif 05382 if (ISZERO (dn)) 05383 return 0; /* zeros are OK, with any exponent */ 05384 if (ilength > 10) 05385 return BADINT; /* always too big */ 05386 #if DECSUBSET 05387 if (!set->extended && ilength > set->digits) 05388 return BADINT; 05389 #endif 05390 05391 up = dn->lsu; /* ready for lsu */ 05392 theInt = 0; /* ready to accumulate */ 05393 if (dn->exponent >= 0) 05394 { /* relatively easy */ 05395 /* no fractional part [usual]; allow for positive exponent */ 05396 got = dn->exponent; 05397 } 05398 else 05399 { /* -ve exponent; some fractional part to check and discard */ 05400 Int count = -dn->exponent; /* digits to discard */ 05401 /* spin up whole units until we get to the Unit with the unit digit */ 05402 for (; count >= DECDPUN; up++) 05403 { 05404 if (*up != 0) 05405 return BADINT; /* non-zero Unit to discard */ 05406 count -= DECDPUN; 05407 } 05408 if (count == 0) 05409 got = 0; /* [a multiple of DECDPUN] */ 05410 else 05411 { /* [not multiple of DECDPUN] */ 05412 Int rem; /* work */ 05413 /* slice off fraction digits and check for non-zero */ 05414 #if DECDPUN<=4 05415 theInt = QUOT10 (*up, count); 05416 rem = *up - theInt * powers[count]; 05417 #else 05418 rem = *up % powers[count]; /* slice off discards */ 05419 theInt = *up / powers[count]; 05420 #endif 05421 if (rem != 0) 05422 return BADINT; /* non-zero fraction */ 05423 /* OK, we're good */ 05424 got = DECDPUN - count; /* number of digits so far */ 05425 up++; /* ready for next */ 05426 } 05427 } 05428 /* collect the rest */ 05429 for (; got < ilength; up++) 05430 { 05431 theInt += *up * powers[got]; 05432 got += DECDPUN; 05433 } 05434 if ((ilength == 10) /* check no wrap */ 05435 && (theInt / (Int) powers[got - DECDPUN] != *(up - 1))) 05436 return BADINT; 05437 /* [that test also disallows the BADINT result case] */ 05438 05439 /* apply any sign and return */ 05440 if (decNumberIsNegative (dn)) 05441 theInt = -theInt; 05442 return theInt; 05443 } 05444 05445 /* ------------------------------------------------------------------ */ 05446 /* decStrEq -- caseless comparison of strings */ 05447 /* */ 05448 /* str1 is one of the strings to compare */ 05449 /* str2 is the other */ 05450 /* */ 05451 /* returns 1 if strings caseless-compare equal, 0 otherwise */ 05452 /* */ 05453 /* Note that the strings must be the same length if they are to */ 05454 /* compare equal; there is no padding. */ 05455 /* ------------------------------------------------------------------ */ 05456 /* [strcmpi is not in ANSI C] */ 05457 static Flag 05458 decStrEq (const char *str1, const char *str2) 05459 { 05460 for (;; str1++, str2++) 05461 { 05462 unsigned char u1 = (unsigned char) *str1; 05463 unsigned char u2 = (unsigned char) *str2; 05464 if (u1 == u2) 05465 { 05466 if (u1 == '\0') 05467 break; 05468 } 05469 else 05470 { 05471 if (tolower (u1) != tolower (u2)) 05472 return 0; 05473 } 05474 } /* stepping */ 05475 return 1; 05476 } 05477 05478 /* ------------------------------------------------------------------ */ 05479 /* decNaNs -- handle NaN operand or operands */ 05480 /* */ 05481 /* res is the result number */ 05482 /* lhs is the first operand */ 05483 /* rhs is the second operand, or NULL if none */ 05484 /* status contains the current status */ 05485 /* returns res in case convenient */ 05486 /* */ 05487 /* Called when one or both operands is a NaN, and propagates the */ 05488 /* appropriate result to res. When an sNaN is found, it is changed */ 05489 /* to a qNaN and Invalid operation is set. */ 05490 /* ------------------------------------------------------------------ */ 05491 static decNumber * 05492 decNaNs (decNumber * res, const decNumber * lhs, const decNumber * rhs, uInt * status) 05493 { 05494 /* This decision tree ends up with LHS being the source pointer, */ 05495 /* and status updated if need be */ 05496 if (lhs->bits & DECSNAN) 05497 *status |= DEC_Invalid_operation | DEC_sNaN; 05498 else if (rhs == NULL); 05499 else if (rhs->bits & DECSNAN) 05500 { 05501 lhs = rhs; 05502 *status |= DEC_Invalid_operation | DEC_sNaN; 05503 } 05504 else if (lhs->bits & DECNAN); 05505 else 05506 lhs = rhs; 05507 05508 decNumberCopy (res, lhs); 05509 res->bits &= ~DECSNAN; /* convert any sNaN to NaN, while */ 05510 res->bits |= DECNAN; /* .. preserving sign */ 05511 res->exponent = 0; /* clean exponent */ 05512 /* [coefficient was copied] */ 05513 return res; 05514 } 05515 05516 /* ------------------------------------------------------------------ */ 05517 /* decStatus -- apply non-zero status */ 05518 /* */ 05519 /* dn is the number to set if error */ 05520 /* status contains the current status (not yet in context) */ 05521 /* set is the context */ 05522 /* */ 05523 /* If the status is an error status, the number is set to a NaN, */ 05524 /* unless the error was an overflow, divide-by-zero, or underflow, */ 05525 /* in which case the number will have already been set. */ 05526 /* */ 05527 /* The context status is then updated with the new status. Note that */ 05528 /* this may raise a signal, so control may never return from this */ 05529 /* routine (hence resources must be recovered before it is called). */ 05530 /* ------------------------------------------------------------------ */ 05531 static void 05532 decStatus (decNumber * dn, uInt status, decContext * set) 05533 { 05534 if (status & DEC_NaNs) 05535 { /* error status -> NaN */ 05536 /* if cause was an sNaN, clear and propagate [NaN is already set up] */ 05537 if (status & DEC_sNaN) 05538 status &= ~DEC_sNaN; 05539 else 05540 { 05541 decNumberZero (dn); /* other error: clean throughout */ 05542 dn->bits = DECNAN; /* and make a quiet NaN */ 05543 } 05544 } 05545 decContextSetStatus (set, status); 05546 return; 05547 } 05548 05549 /* ------------------------------------------------------------------ */ 05550 /* decGetDigits -- count digits in a Units array */ 05551 /* */ 05552 /* uar is the Unit array holding the number [this is often an */ 05553 /* accumulator of some sort] */ 05554 /* len is the length of the array in units */ 05555 /* */ 05556 /* returns the number of (significant) digits in the array */ 05557 /* */ 05558 /* All leading zeros are excluded, except the last if the array has */ 05559 /* only zero Units. */ 05560 /* ------------------------------------------------------------------ */ 05561 /* This may be called twice during some operations. */ 05562 static Int 05563 decGetDigits (const Unit * uar, Int len) 05564 { 05565 const Unit *up = uar + len - 1; /* -> msu */ 05566 Int digits = len * DECDPUN; /* maximum possible digits */ 05567 uInt const *pow; /* work */ 05568 05569 for (; up >= uar; up--) 05570 { 05571 digits -= DECDPUN; 05572 if (*up == 0) 05573 { /* unit is 0 */ 05574 if (digits != 0) 05575 continue; /* more to check */ 05576 /* all units were 0 */ 05577 digits++; /* .. so bump digits to 1 */ 05578 break; 05579 } 05580 /* found the first non-zero Unit */ 05581 digits++; 05582 if (*up < 10) 05583 break; /* fastpath 1-9 */ 05584 digits++; 05585 for (pow = &powers[2]; *up >= *pow; pow++) 05586 digits++; 05587 break; 05588 } /* up */ 05589 05590 return digits; 05591 } 05592 05593 05594 #if DECTRACE | DECCHECK 05595 /* ------------------------------------------------------------------ */ 05596 /* decNumberShow -- display a number [debug aid] */ 05597 /* dn is the number to show */ 05598 /* */ 05599 /* Shows: sign, exponent, coefficient (msu first), digits */ 05600 /* or: sign, special-value */ 05601 /* ------------------------------------------------------------------ */ 05602 /* this is public so other modules can use it */ 05603 void 05604 decNumberShow (const decNumber * dn) 05605 { 05606 const Unit *up; /* work */ 05607 uInt u, d; /* .. */ 05608 Int cut; /* .. */ 05609 char isign = '+'; /* main sign */ 05610 if (dn == NULL) 05611 { 05612 printf ("NULL\n"); 05613 return; 05614 } 05615 if (decNumberIsNegative (dn)) 05616 isign = '-'; 05617 printf (" >> %c ", isign); 05618 if (dn->bits & DECSPECIAL) 05619 { /* Is a special value */ 05620 if (decNumberIsInfinite (dn)) 05621 printf ("Infinity"); 05622 else 05623 { /* a NaN */ 05624 if (dn->bits & DECSNAN) 05625 printf ("sNaN"); /* signalling NaN */ 05626 else 05627 printf ("NaN"); 05628 } 05629 /* if coefficient and exponent are 0, we're done */ 05630 if (dn->exponent == 0 && dn->digits == 1 && *dn->lsu == 0) 05631 { 05632 printf ("\n"); 05633 return; 05634 } 05635 /* drop through to report other information */ 05636 printf (" "); 05637 } 05638 05639 /* now carefully display the coefficient */ 05640 up = dn->lsu + D2U (dn->digits) - 1; /* msu */ 05641 printf ("%d", *up); 05642 for (up = up - 1; up >= dn->lsu; up--) 05643 { 05644 u = *up; 05645 printf (":"); 05646 for (cut = DECDPUN - 1; cut >= 0; cut--) 05647 { 05648 d = u / powers[cut]; 05649 u -= d * powers[cut]; 05650 printf ("%d", d); 05651 } /* cut */ 05652 } /* up */ 05653 if (dn->exponent != 0) 05654 { 05655 char esign = '+'; 05656 if (dn->exponent < 0) 05657 esign = '-'; 05658 printf (" E%c%d", esign, abs (dn->exponent)); 05659 } 05660 printf (" [%d]\n", dn->digits); 05661 } 05662 #endif 05663 05664 #if DECTRACE || DECCHECK 05665 /* ------------------------------------------------------------------ */ 05666 /* decDumpAr -- display a unit array [debug aid] */ 05667 /* name is a single-character tag name */ 05668 /* ar is the array to display */ 05669 /* len is the length of the array in Units */ 05670 /* ------------------------------------------------------------------ */ 05671 static void 05672 decDumpAr (char name, const Unit * ar, Int len) 05673 { 05674 Int i; 05675 #if DECDPUN==4 05676 const char *spec = "%04d "; 05677 #else 05678 const char *spec = "%d "; 05679 #endif 05680 printf (" :%c: ", name); 05681 for (i = len - 1; i >= 0; i--) 05682 { 05683 if (i == len - 1) 05684 printf ("%d ", ar[i]); 05685 else 05686 printf (spec, ar[i]); 05687 } 05688 printf ("\n"); 05689 return; 05690 } 05691 #endif 05692 05693 #if DECCHECK 05694 /* ------------------------------------------------------------------ */ 05695 /* decCheckOperands -- check operand(s) to a routine */ 05696 /* res is the result structure (not checked; it will be set to */ 05697 /* quiet NaN if error found (and it is not NULL)) */ 05698 /* lhs is the first operand (may be DECUNUSED) */ 05699 /* rhs is the second (may be DECUNUSED) */ 05700 /* set is the context (may be DECUNUSED) */ 05701 /* returns 0 if both operands, and the context are clean, or 1 */ 05702 /* otherwise (in which case the context will show an error, */ 05703 /* unless NULL). Note that res is not cleaned; caller should */ 05704 /* handle this so res=NULL case is safe. */ 05705 /* The caller is expected to abandon immediately if 1 is returned. */ 05706 /* ------------------------------------------------------------------ */ 05707 static Flag 05708 decCheckOperands (decNumber * res, const decNumber * lhs, 05709 const decNumber * rhs, decContext * set) 05710 { 05711 Flag bad = 0; 05712 if (set == NULL) 05713 { /* oops; hopeless */ 05714 #if DECTRACE 05715 printf ("Context is NULL.\n"); 05716 #endif 05717 bad = 1; 05718 return 1; 05719 } 05720 else if (set != DECUNUSED 05721 && (set->digits < 1 || set->round < 0 05722 || set->round >= DEC_ROUND_MAX)) 05723 { 05724 bad = 1; 05725 #if DECTRACE 05726 printf ("Bad context [digits=%d round=%d].\n", set->digits, set->round); 05727 #endif 05728 } 05729 else 05730 { 05731 if (res == NULL) 05732 { 05733 bad = 1; 05734 #if DECTRACE 05735 printf ("Bad result [is NULL].\n"); 05736 #endif 05737 } 05738 if (!bad && lhs != DECUNUSED) 05739 bad = (decCheckNumber (lhs, set)); 05740 if (!bad && rhs != DECUNUSED) 05741 bad = (decCheckNumber (rhs, set)); 05742 } 05743 if (bad) 05744 { 05745 if (set != DECUNUSED) 05746 decContextSetStatus (set, DEC_Invalid_operation); 05747 if (res != DECUNUSED && res != NULL) 05748 { 05749 decNumberZero (res); 05750 res->bits = DECNAN; /* qNaN */ 05751 } 05752 } 05753 return bad; 05754 } 05755 05756 /* ------------------------------------------------------------------ */ 05757 /* decCheckNumber -- check a number */ 05758 /* dn is the number to check */ 05759 /* set is the context (may be DECUNUSED) */ 05760 /* returns 0 if the number is clean, or 1 otherwise */ 05761 /* */ 05762 /* The number is considered valid if it could be a result from some */ 05763 /* operation in some valid context (not necessarily the current one). */ 05764 /* ------------------------------------------------------------------ */ 05765 Flag 05766 decCheckNumber (const decNumber * dn, decContext * set) 05767 { 05768 const Unit *up; /* work */ 05769 uInt maxuint; /* .. */ 05770 Int ae, d, digits; /* .. */ 05771 Int emin, emax; /* .. */ 05772 05773 if (dn == NULL) 05774 { /* hopeless */ 05775 #if DECTRACE 05776 printf ("Reference to decNumber is NULL.\n"); 05777 #endif 05778 return 1; 05779 } 05780 05781 /* check special values */ 05782 if (dn->bits & DECSPECIAL) 05783 { 05784 if (dn->exponent != 0) 05785 { 05786 #if DECTRACE 05787 printf ("Exponent %d (not 0) for a special value.\n", dn->exponent); 05788 #endif 05789 return 1; 05790 } 05791 05792 /* 2003.09.08: NaNs may now have coefficients, so next tests Inf only */ 05793 if (decNumberIsInfinite (dn)) 05794 { 05795 if (dn->digits != 1) 05796 { 05797 #if DECTRACE 05798 printf ("Digits %d (not 1) for an infinity.\n", dn->digits); 05799 #endif 05800 return 1; 05801 } 05802 if (*dn->lsu != 0) 05803 { 05804 #if DECTRACE 05805 printf ("LSU %d (not 0) for an infinity.\n", *dn->lsu); 05806 #endif 05807 return 1; 05808 } 05809 } /* Inf */ 05810 /* 2002.12.26: negative NaNs can now appear through proposed IEEE */ 05811 /* concrete formats (decimal64, etc.), though they are */ 05812 /* never visible in strings. */ 05813 return 0; 05814 05815 /* if ((dn->bits & DECINF) || (dn->bits & DECNEG)==0) return 0; */ 05816 /* #if DECTRACE */ 05817 /* printf("Negative NaN in number.\n"); */ 05818 /* #endif */ 05819 /* return 1; */ 05820 } 05821 05822 /* check the coefficient */ 05823 if (dn->digits < 1 || dn->digits > DECNUMMAXP) 05824 { 05825 #if DECTRACE 05826 printf ("Digits %d in number.\n", dn->digits); 05827 #endif 05828 return 1; 05829 } 05830 05831 d = dn->digits; 05832 05833 for (up = dn->lsu; d > 0; up++) 05834 { 05835 if (d > DECDPUN) 05836 maxuint = DECDPUNMAX; 05837 else 05838 { /* we are at the msu */ 05839 maxuint = powers[d] - 1; 05840 if (dn->digits > 1 && *up < powers[d - 1]) 05841 { 05842 #if DECTRACE 05843 printf ("Leading 0 in number.\n"); 05844 decNumberShow (dn); 05845 #endif 05846 return 1; 05847 } 05848 } 05849 if (*up > maxuint) 05850 { 05851 #if DECTRACE 05852 printf ("Bad Unit [%08x] in number at offset %d [maxuint %d].\n", 05853 *up, up - dn->lsu, maxuint); 05854 #endif 05855 return 1; 05856 } 05857 d -= DECDPUN; 05858 } 05859 05860 /* check the exponent. Note that input operands can have exponents */ 05861 /* which are out of the set->emin/set->emax and set->digits range */ 05862 /* (just as they can have more digits than set->digits). */ 05863 ae = dn->exponent + dn->digits - 1; /* adjusted exponent */ 05864 emax = DECNUMMAXE; 05865 emin = DECNUMMINE; 05866 digits = DECNUMMAXP; 05867 if (ae < emin - (digits - 1)) 05868 { 05869 #if DECTRACE 05870 printf ("Adjusted exponent underflow [%d].\n", ae); 05871 decNumberShow (dn); 05872 #endif 05873 return 1; 05874 } 05875 if (ae > +emax) 05876 { 05877 #if DECTRACE 05878 printf ("Adjusted exponent overflow [%d].\n", ae); 05879 decNumberShow (dn); 05880 #endif 05881 return 1; 05882 } 05883 05884 return 0; /* it's OK */ 05885 } 05886 #endif 05887 05888 #if DECALLOC 05889 #undef malloc 05890 #undef free 05891 /* ------------------------------------------------------------------ */ 05892 /* decMalloc -- accountable allocation routine */ 05893 /* n is the number of bytes to allocate */ 05894 /* */ 05895 /* Semantics is the same as the stdlib malloc routine, but bytes */ 05896 /* allocated are accounted for globally, and corruption fences are */ 05897 /* added before and after the 'actual' storage. */ 05898 /* ------------------------------------------------------------------ */ 05899 /* This routine allocates storage with an extra twelve bytes; 8 are */ 05900 /* at the start and hold: */ 05901 /* 0-3 the original length requested */ 05902 /* 4-7 buffer corruption detection fence (DECFENCE, x4) */ 05903 /* The 4 bytes at the end also hold a corruption fence (DECFENCE, x4) */ 05904 /* ------------------------------------------------------------------ */ 05905 static void * 05906 decMalloc (uInt n) 05907 { 05908 uInt size = n + 12; /* true size */ 05909 void *alloc; /* -> allocated storage */ 05910 uInt *j; /* work */ 05911 uByte *b, *b0; /* .. */ 05912 05913 alloc = malloc (size); /* -> allocated storage */ 05914 if (alloc == NULL) 05915 return NULL; /* out of strorage */ 05916 b0 = (uByte *) alloc; /* as bytes */ 05917 decAllocBytes += n; /* account for storage */ 05918 j = (uInt *) alloc; /* -> first four bytes */ 05919 *j = n; /* save n */ 05920 /* printf("++ alloc(%d)\n", n); */ 05921 for (b = b0 + 4; b < b0 + 8; b++) 05922 *b = DECFENCE; 05923 for (b = b0 + n + 8; b < b0 + n + 12; b++) 05924 *b = DECFENCE; 05925 return b0 + 8; /* -> play area */ 05926 } 05927 05928 /* ------------------------------------------------------------------ */ 05929 /* decFree -- accountable free routine */ 05930 /* alloc is the storage to free */ 05931 /* */ 05932 /* Semantics is the same as the stdlib malloc routine, except that */ 05933 /* the global storage accounting is updated and the fences are */ 05934 /* checked to ensure that no routine has written 'out of bounds'. */ 05935 /* ------------------------------------------------------------------ */ 05936 /* This routine first checks that the fences have not been corrupted. */ 05937 /* It then frees the storage using the 'truw' storage address (that */ 05938 /* is, offset by 8). */ 05939 /* ------------------------------------------------------------------ */ 05940 static void 05941 decFree (void *alloc) 05942 { 05943 uInt *j, n; /* pointer, original length */ 05944 uByte *b, *b0; /* work */ 05945 05946 if (alloc == NULL) 05947 return; /* allowed; it's a nop */ 05948 b0 = (uByte *) alloc; /* as bytes */ 05949 b0 -= 8; /* -> true start of storage */ 05950 j = (uInt *) b0; /* -> first four bytes */ 05951 n = *j; /* lift */ 05952 for (b = b0 + 4; b < b0 + 8; b++) 05953 if (*b != DECFENCE) 05954 printf ("=== Corrupt byte [%02x] at offset %d from %d ===\n", *b, 05955 b - b0 - 8, (Int) b0); 05956 for (b = b0 + n + 8; b < b0 + n + 12; b++) 05957 if (*b != DECFENCE) 05958 printf ("=== Corrupt byte [%02x] at offset +%d from %d, n=%d ===\n", *b, 05959 b - b0 - 8, (Int) b0, n); 05960 free (b0); /* drop the storage */ 05961 decAllocBytes -= n; /* account for storage */ 05962 } 05963 #endif
1.5.6