1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/decNumber.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,8184 @@ 1.4 +/* ------------------------------------------------------------------ */ 1.5 +/* Decimal Number arithmetic module */ 1.6 +/* ------------------------------------------------------------------ */ 1.7 +/* Copyright (c) IBM Corporation, 2000-2012. All rights reserved. */ 1.8 +/* */ 1.9 +/* This software is made available under the terms of the */ 1.10 +/* ICU License -- ICU 1.8.1 and later. */ 1.11 +/* */ 1.12 +/* The description and User's Guide ("The decNumber C Library") for */ 1.13 +/* this software is called decNumber.pdf. This document is */ 1.14 +/* available, together with arithmetic and format specifications, */ 1.15 +/* testcases, and Web links, on the General Decimal Arithmetic page. */ 1.16 +/* */ 1.17 +/* Please send comments, suggestions, and corrections to the author: */ 1.18 +/* mfc@uk.ibm.com */ 1.19 +/* Mike Cowlishaw, IBM Fellow */ 1.20 +/* IBM UK, PO Box 31, Birmingham Road, Warwick CV34 5JL, UK */ 1.21 +/* ------------------------------------------------------------------ */ 1.22 + 1.23 +/* Modified version, for use from within ICU. 1.24 + * Renamed public functions, to avoid an unwanted export of the 1.25 + * standard names from the ICU library. 1.26 + * 1.27 + * Use ICU's uprv_malloc() and uprv_free() 1.28 + * 1.29 + * Revert comment syntax to plain C 1.30 + * 1.31 + * Remove a few compiler warnings. 1.32 + */ 1.33 + 1.34 +/* This module comprises the routines for arbitrary-precision General */ 1.35 +/* Decimal Arithmetic as defined in the specification which may be */ 1.36 +/* found on the General Decimal Arithmetic pages. It implements both */ 1.37 +/* the full ('extended') arithmetic and the simpler ('subset') */ 1.38 +/* arithmetic. */ 1.39 +/* */ 1.40 +/* Usage notes: */ 1.41 +/* */ 1.42 +/* 1. This code is ANSI C89 except: */ 1.43 +/* */ 1.44 +/* a) C99 line comments (double forward slash) are used. (Most C */ 1.45 +/* compilers accept these. If yours does not, a simple script */ 1.46 +/* can be used to convert them to ANSI C comments.) */ 1.47 +/* */ 1.48 +/* b) Types from C99 stdint.h are used. If you do not have this */ 1.49 +/* header file, see the User's Guide section of the decNumber */ 1.50 +/* documentation; this lists the necessary definitions. */ 1.51 +/* */ 1.52 +/* c) If DECDPUN>4 or DECUSE64=1, the C99 64-bit int64_t and */ 1.53 +/* uint64_t types may be used. To avoid these, set DECUSE64=0 */ 1.54 +/* and DECDPUN<=4 (see documentation). */ 1.55 +/* */ 1.56 +/* The code also conforms to C99 restrictions; in particular, */ 1.57 +/* strict aliasing rules are observed. */ 1.58 +/* */ 1.59 +/* 2. The decNumber format which this library uses is optimized for */ 1.60 +/* efficient processing of relatively short numbers; in particular */ 1.61 +/* it allows the use of fixed sized structures and minimizes copy */ 1.62 +/* and move operations. It does, however, support arbitrary */ 1.63 +/* precision (up to 999,999,999 digits) and arbitrary exponent */ 1.64 +/* range (Emax in the range 0 through 999,999,999 and Emin in the */ 1.65 +/* range -999,999,999 through 0). Mathematical functions (for */ 1.66 +/* example decNumberExp) as identified below are restricted more */ 1.67 +/* tightly: digits, emax, and -emin in the context must be <= */ 1.68 +/* DEC_MAX_MATH (999999), and their operand(s) must be within */ 1.69 +/* these bounds. */ 1.70 +/* */ 1.71 +/* 3. Logical functions are further restricted; their operands must */ 1.72 +/* be finite, positive, have an exponent of zero, and all digits */ 1.73 +/* must be either 0 or 1. The result will only contain digits */ 1.74 +/* which are 0 or 1 (and will have exponent=0 and a sign of 0). */ 1.75 +/* */ 1.76 +/* 4. Operands to operator functions are never modified unless they */ 1.77 +/* are also specified to be the result number (which is always */ 1.78 +/* permitted). Other than that case, operands must not overlap. */ 1.79 +/* */ 1.80 +/* 5. Error handling: the type of the error is ORed into the status */ 1.81 +/* flags in the current context (decContext structure). The */ 1.82 +/* SIGFPE signal is then raised if the corresponding trap-enabler */ 1.83 +/* flag in the decContext is set (is 1). */ 1.84 +/* */ 1.85 +/* It is the responsibility of the caller to clear the status */ 1.86 +/* flags as required. */ 1.87 +/* */ 1.88 +/* The result of any routine which returns a number will always */ 1.89 +/* be a valid number (which may be a special value, such as an */ 1.90 +/* Infinity or NaN). */ 1.91 +/* */ 1.92 +/* 6. The decNumber format is not an exchangeable concrete */ 1.93 +/* representation as it comprises fields which may be machine- */ 1.94 +/* dependent (packed or unpacked, or special length, for example). */ 1.95 +/* Canonical conversions to and from strings are provided; other */ 1.96 +/* conversions are available in separate modules. */ 1.97 +/* */ 1.98 +/* 7. Normally, input operands are assumed to be valid. Set DECCHECK */ 1.99 +/* to 1 for extended operand checking (including NULL operands). */ 1.100 +/* Results are undefined if a badly-formed structure (or a NULL */ 1.101 +/* pointer to a structure) is provided, though with DECCHECK */ 1.102 +/* enabled the operator routines are protected against exceptions. */ 1.103 +/* (Except if the result pointer is NULL, which is unrecoverable.) */ 1.104 +/* */ 1.105 +/* However, the routines will never cause exceptions if they are */ 1.106 +/* given well-formed operands, even if the value of the operands */ 1.107 +/* is inappropriate for the operation and DECCHECK is not set. */ 1.108 +/* (Except for SIGFPE, as and where documented.) */ 1.109 +/* */ 1.110 +/* 8. Subset arithmetic is available only if DECSUBSET is set to 1. */ 1.111 +/* ------------------------------------------------------------------ */ 1.112 +/* Implementation notes for maintenance of this module: */ 1.113 +/* */ 1.114 +/* 1. Storage leak protection: Routines which use malloc are not */ 1.115 +/* permitted to use return for fastpath or error exits (i.e., */ 1.116 +/* they follow strict structured programming conventions). */ 1.117 +/* Instead they have a do{}while(0); construct surrounding the */ 1.118 +/* code which is protected -- break may be used to exit this. */ 1.119 +/* Other routines can safely use the return statement inline. */ 1.120 +/* */ 1.121 +/* Storage leak accounting can be enabled using DECALLOC. */ 1.122 +/* */ 1.123 +/* 2. All loops use the for(;;) construct. Any do construct does */ 1.124 +/* not loop; it is for allocation protection as just described. */ 1.125 +/* */ 1.126 +/* 3. Setting status in the context must always be the very last */ 1.127 +/* action in a routine, as non-0 status may raise a trap and hence */ 1.128 +/* the call to set status may not return (if the handler uses long */ 1.129 +/* jump). Therefore all cleanup must be done first. In general, */ 1.130 +/* to achieve this status is accumulated and is only applied just */ 1.131 +/* before return by calling decContextSetStatus (via decStatus). */ 1.132 +/* */ 1.133 +/* Routines which allocate storage cannot, in general, use the */ 1.134 +/* 'top level' routines which could cause a non-returning */ 1.135 +/* transfer of control. The decXxxxOp routines are safe (do not */ 1.136 +/* call decStatus even if traps are set in the context) and should */ 1.137 +/* be used instead (they are also a little faster). */ 1.138 +/* */ 1.139 +/* 4. Exponent checking is minimized by allowing the exponent to */ 1.140 +/* grow outside its limits during calculations, provided that */ 1.141 +/* the decFinalize function is called later. Multiplication and */ 1.142 +/* division, and intermediate calculations in exponentiation, */ 1.143 +/* require more careful checks because of the risk of 31-bit */ 1.144 +/* overflow (the most negative valid exponent is -1999999997, for */ 1.145 +/* a 999999999-digit number with adjusted exponent of -999999999). */ 1.146 +/* */ 1.147 +/* 5. Rounding is deferred until finalization of results, with any */ 1.148 +/* 'off to the right' data being represented as a single digit */ 1.149 +/* residue (in the range -1 through 9). This avoids any double- */ 1.150 +/* rounding when more than one shortening takes place (for */ 1.151 +/* example, when a result is subnormal). */ 1.152 +/* */ 1.153 +/* 6. The digits count is allowed to rise to a multiple of DECDPUN */ 1.154 +/* during many operations, so whole Units are handled and exact */ 1.155 +/* accounting of digits is not needed. The correct digits value */ 1.156 +/* is found by decGetDigits, which accounts for leading zeros. */ 1.157 +/* This must be called before any rounding if the number of digits */ 1.158 +/* is not known exactly. */ 1.159 +/* */ 1.160 +/* 7. The multiply-by-reciprocal 'trick' is used for partitioning */ 1.161 +/* numbers up to four digits, using appropriate constants. This */ 1.162 +/* is not useful for longer numbers because overflow of 32 bits */ 1.163 +/* would lead to 4 multiplies, which is almost as expensive as */ 1.164 +/* a divide (unless a floating-point or 64-bit multiply is */ 1.165 +/* assumed to be available). */ 1.166 +/* */ 1.167 +/* 8. Unusual abbreviations that may be used in the commentary: */ 1.168 +/* lhs -- left hand side (operand, of an operation) */ 1.169 +/* lsd -- least significant digit (of coefficient) */ 1.170 +/* lsu -- least significant Unit (of coefficient) */ 1.171 +/* msd -- most significant digit (of coefficient) */ 1.172 +/* msi -- most significant item (in an array) */ 1.173 +/* msu -- most significant Unit (of coefficient) */ 1.174 +/* rhs -- right hand side (operand, of an operation) */ 1.175 +/* +ve -- positive */ 1.176 +/* -ve -- negative */ 1.177 +/* ** -- raise to the power */ 1.178 +/* ------------------------------------------------------------------ */ 1.179 + 1.180 +#include <stdlib.h> /* for malloc, free, etc. */ 1.181 +/* #include <stdio.h> */ /* for printf [if needed] */ 1.182 +#include <string.h> /* for strcpy */ 1.183 +#include <ctype.h> /* for lower */ 1.184 +#include "cmemory.h" /* for uprv_malloc, etc., in ICU */ 1.185 +#include "decNumber.h" /* base number library */ 1.186 +#include "decNumberLocal.h" /* decNumber local types, etc. */ 1.187 +#include "uassert.h" 1.188 + 1.189 +/* Constants */ 1.190 +/* Public lookup table used by the D2U macro */ 1.191 +static const uByte d2utable[DECMAXD2U+1]=D2UTABLE; 1.192 + 1.193 +#define DECVERB 1 /* set to 1 for verbose DECCHECK */ 1.194 +#define powers DECPOWERS /* old internal name */ 1.195 + 1.196 +/* Local constants */ 1.197 +#define DIVIDE 0x80 /* Divide operators */ 1.198 +#define REMAINDER 0x40 /* .. */ 1.199 +#define DIVIDEINT 0x20 /* .. */ 1.200 +#define REMNEAR 0x10 /* .. */ 1.201 +#define COMPARE 0x01 /* Compare operators */ 1.202 +#define COMPMAX 0x02 /* .. */ 1.203 +#define COMPMIN 0x03 /* .. */ 1.204 +#define COMPTOTAL 0x04 /* .. */ 1.205 +#define COMPNAN 0x05 /* .. [NaN processing] */ 1.206 +#define COMPSIG 0x06 /* .. [signaling COMPARE] */ 1.207 +#define COMPMAXMAG 0x07 /* .. */ 1.208 +#define COMPMINMAG 0x08 /* .. */ 1.209 + 1.210 +#define DEC_sNaN 0x40000000 /* local status: sNaN signal */ 1.211 +#define BADINT (Int)0x80000000 /* most-negative Int; error indicator */ 1.212 +/* Next two indicate an integer >= 10**6, and its parity (bottom bit) */ 1.213 +#define BIGEVEN (Int)0x80000002 1.214 +#define BIGODD (Int)0x80000003 1.215 + 1.216 +static const Unit uarrone[1]={1}; /* Unit array of 1, used for incrementing */ 1.217 + 1.218 +/* ------------------------------------------------------------------ */ 1.219 +/* round-for-reround digits */ 1.220 +/* ------------------------------------------------------------------ */ 1.221 +static const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */ 1.222 + 1.223 +/* ------------------------------------------------------------------ */ 1.224 +/* Powers of ten (powers[n]==10**n, 0<=n<=9) */ 1.225 +/* ------------------------------------------------------------------ */ 1.226 +static const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000, 1.227 + 10000000, 100000000, 1000000000}; 1.228 + 1.229 + 1.230 +/* Granularity-dependent code */ 1.231 +#if DECDPUN<=4 1.232 + #define eInt Int /* extended integer */ 1.233 + #define ueInt uInt /* unsigned extended integer */ 1.234 + /* Constant multipliers for divide-by-power-of five using reciprocal */ 1.235 + /* multiply, after removing powers of 2 by shifting, and final shift */ 1.236 + /* of 17 [we only need up to **4] */ 1.237 + static const uInt multies[]={131073, 26215, 5243, 1049, 210}; 1.238 + /* QUOT10 -- macro to return the quotient of unit u divided by 10**n */ 1.239 + #define QUOT10(u, n) ((((uInt)(u)>>(n))*multies[n])>>17) 1.240 +#else 1.241 + /* For DECDPUN>4 non-ANSI-89 64-bit types are needed. */ 1.242 + #if !DECUSE64 1.243 + #error decNumber.c: DECUSE64 must be 1 when DECDPUN>4 1.244 + #endif 1.245 + #define eInt Long /* extended integer */ 1.246 + #define ueInt uLong /* unsigned extended integer */ 1.247 +#endif 1.248 + 1.249 +/* Local routines */ 1.250 +static decNumber * decAddOp(decNumber *, const decNumber *, const decNumber *, 1.251 + decContext *, uByte, uInt *); 1.252 +static Flag decBiStr(const char *, const char *, const char *); 1.253 +static uInt decCheckMath(const decNumber *, decContext *, uInt *); 1.254 +static void decApplyRound(decNumber *, decContext *, Int, uInt *); 1.255 +static Int decCompare(const decNumber *lhs, const decNumber *rhs, Flag); 1.256 +static decNumber * decCompareOp(decNumber *, const decNumber *, 1.257 + const decNumber *, decContext *, 1.258 + Flag, uInt *); 1.259 +static void decCopyFit(decNumber *, const decNumber *, decContext *, 1.260 + Int *, uInt *); 1.261 +static decNumber * decDecap(decNumber *, Int); 1.262 +static decNumber * decDivideOp(decNumber *, const decNumber *, 1.263 + const decNumber *, decContext *, Flag, uInt *); 1.264 +static decNumber * decExpOp(decNumber *, const decNumber *, 1.265 + decContext *, uInt *); 1.266 +static void decFinalize(decNumber *, decContext *, Int *, uInt *); 1.267 +static Int decGetDigits(Unit *, Int); 1.268 +static Int decGetInt(const decNumber *); 1.269 +static decNumber * decLnOp(decNumber *, const decNumber *, 1.270 + decContext *, uInt *); 1.271 +static decNumber * decMultiplyOp(decNumber *, const decNumber *, 1.272 + const decNumber *, decContext *, 1.273 + uInt *); 1.274 +static decNumber * decNaNs(decNumber *, const decNumber *, 1.275 + const decNumber *, decContext *, uInt *); 1.276 +static decNumber * decQuantizeOp(decNumber *, const decNumber *, 1.277 + const decNumber *, decContext *, Flag, 1.278 + uInt *); 1.279 +static void decReverse(Unit *, Unit *); 1.280 +static void decSetCoeff(decNumber *, decContext *, const Unit *, 1.281 + Int, Int *, uInt *); 1.282 +static void decSetMaxValue(decNumber *, decContext *); 1.283 +static void decSetOverflow(decNumber *, decContext *, uInt *); 1.284 +static void decSetSubnormal(decNumber *, decContext *, Int *, uInt *); 1.285 +static Int decShiftToLeast(Unit *, Int, Int); 1.286 +static Int decShiftToMost(Unit *, Int, Int); 1.287 +static void decStatus(decNumber *, uInt, decContext *); 1.288 +static void decToString(const decNumber *, char[], Flag); 1.289 +static decNumber * decTrim(decNumber *, decContext *, Flag, Flag, Int *); 1.290 +static Int decUnitAddSub(const Unit *, Int, const Unit *, Int, Int, 1.291 + Unit *, Int); 1.292 +static Int decUnitCompare(const Unit *, Int, const Unit *, Int, Int); 1.293 + 1.294 +#if !DECSUBSET 1.295 +/* decFinish == decFinalize when no subset arithmetic needed */ 1.296 +#define decFinish(a,b,c,d) decFinalize(a,b,c,d) 1.297 +#else 1.298 +static void decFinish(decNumber *, decContext *, Int *, uInt *); 1.299 +static decNumber * decRoundOperand(const decNumber *, decContext *, uInt *); 1.300 +#endif 1.301 + 1.302 +/* Local macros */ 1.303 +/* masked special-values bits */ 1.304 +#define SPECIALARG (rhs->bits & DECSPECIAL) 1.305 +#define SPECIALARGS ((lhs->bits | rhs->bits) & DECSPECIAL) 1.306 + 1.307 +/* For use in ICU */ 1.308 +#define malloc(a) uprv_malloc(a) 1.309 +#define free(a) uprv_free(a) 1.310 + 1.311 +/* Diagnostic macros, etc. */ 1.312 +#if DECALLOC 1.313 +/* Handle malloc/free accounting. If enabled, our accountable routines */ 1.314 +/* are used; otherwise the code just goes straight to the system malloc */ 1.315 +/* and free routines. */ 1.316 +#define malloc(a) decMalloc(a) 1.317 +#define free(a) decFree(a) 1.318 +#define DECFENCE 0x5a /* corruption detector */ 1.319 +/* 'Our' malloc and free: */ 1.320 +static void *decMalloc(size_t); 1.321 +static void decFree(void *); 1.322 +uInt decAllocBytes=0; /* count of bytes allocated */ 1.323 +/* Note that DECALLOC code only checks for storage buffer overflow. */ 1.324 +/* To check for memory leaks, the decAllocBytes variable must be */ 1.325 +/* checked to be 0 at appropriate times (e.g., after the test */ 1.326 +/* harness completes a set of tests). This checking may be unreliable */ 1.327 +/* if the testing is done in a multi-thread environment. */ 1.328 +#endif 1.329 + 1.330 +#if DECCHECK 1.331 +/* Optional checking routines. Enabling these means that decNumber */ 1.332 +/* and decContext operands to operator routines are checked for */ 1.333 +/* correctness. This roughly doubles the execution time of the */ 1.334 +/* fastest routines (and adds 600+ bytes), so should not normally be */ 1.335 +/* used in 'production'. */ 1.336 +/* decCheckInexact is used to check that inexact results have a full */ 1.337 +/* complement of digits (where appropriate -- this is not the case */ 1.338 +/* for Quantize, for example) */ 1.339 +#define DECUNRESU ((decNumber *)(void *)0xffffffff) 1.340 +#define DECUNUSED ((const decNumber *)(void *)0xffffffff) 1.341 +#define DECUNCONT ((decContext *)(void *)(0xffffffff)) 1.342 +static Flag decCheckOperands(decNumber *, const decNumber *, 1.343 + const decNumber *, decContext *); 1.344 +static Flag decCheckNumber(const decNumber *); 1.345 +static void decCheckInexact(const decNumber *, decContext *); 1.346 +#endif 1.347 + 1.348 +#if DECTRACE || DECCHECK 1.349 +/* Optional trace/debugging routines (may or may not be used) */ 1.350 +void decNumberShow(const decNumber *); /* displays the components of a number */ 1.351 +static void decDumpAr(char, const Unit *, Int); 1.352 +#endif 1.353 + 1.354 +/* ================================================================== */ 1.355 +/* Conversions */ 1.356 +/* ================================================================== */ 1.357 + 1.358 +/* ------------------------------------------------------------------ */ 1.359 +/* from-int32 -- conversion from Int or uInt */ 1.360 +/* */ 1.361 +/* dn is the decNumber to receive the integer */ 1.362 +/* in or uin is the integer to be converted */ 1.363 +/* returns dn */ 1.364 +/* */ 1.365 +/* No error is possible. */ 1.366 +/* ------------------------------------------------------------------ */ 1.367 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberFromInt32(decNumber *dn, Int in) { 1.368 + uInt unsig; 1.369 + if (in>=0) unsig=in; 1.370 + else { /* negative (possibly BADINT) */ 1.371 + if (in==BADINT) unsig=(uInt)1073741824*2; /* special case */ 1.372 + else unsig=-in; /* invert */ 1.373 + } 1.374 + /* in is now positive */ 1.375 + uprv_decNumberFromUInt32(dn, unsig); 1.376 + if (in<0) dn->bits=DECNEG; /* sign needed */ 1.377 + return dn; 1.378 + } /* decNumberFromInt32 */ 1.379 + 1.380 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberFromUInt32(decNumber *dn, uInt uin) { 1.381 + Unit *up; /* work pointer */ 1.382 + uprv_decNumberZero(dn); /* clean */ 1.383 + if (uin==0) return dn; /* [or decGetDigits bad call] */ 1.384 + for (up=dn->lsu; uin>0; up++) { 1.385 + *up=(Unit)(uin%(DECDPUNMAX+1)); 1.386 + uin=uin/(DECDPUNMAX+1); 1.387 + } 1.388 + dn->digits=decGetDigits(dn->lsu, up-dn->lsu); 1.389 + return dn; 1.390 + } /* decNumberFromUInt32 */ 1.391 + 1.392 +/* ------------------------------------------------------------------ */ 1.393 +/* to-int32 -- conversion to Int or uInt */ 1.394 +/* */ 1.395 +/* dn is the decNumber to convert */ 1.396 +/* set is the context for reporting errors */ 1.397 +/* returns the converted decNumber, or 0 if Invalid is set */ 1.398 +/* */ 1.399 +/* Invalid is set if the decNumber does not have exponent==0 or if */ 1.400 +/* it is a NaN, Infinite, or out-of-range. */ 1.401 +/* ------------------------------------------------------------------ */ 1.402 +U_CAPI Int U_EXPORT2 uprv_decNumberToInt32(const decNumber *dn, decContext *set) { 1.403 + #if DECCHECK 1.404 + if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0; 1.405 + #endif 1.406 + 1.407 + /* special or too many digits, or bad exponent */ 1.408 + if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0) ; /* bad */ 1.409 + else { /* is a finite integer with 10 or fewer digits */ 1.410 + Int d; /* work */ 1.411 + const Unit *up; /* .. */ 1.412 + uInt hi=0, lo; /* .. */ 1.413 + up=dn->lsu; /* -> lsu */ 1.414 + lo=*up; /* get 1 to 9 digits */ 1.415 + #if DECDPUN>1 /* split to higher */ 1.416 + hi=lo/10; 1.417 + lo=lo%10; 1.418 + #endif 1.419 + up++; 1.420 + /* collect remaining Units, if any, into hi */ 1.421 + for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1]; 1.422 + /* now low has the lsd, hi the remainder */ 1.423 + if (hi>214748364 || (hi==214748364 && lo>7)) { /* out of range? */ 1.424 + /* most-negative is a reprieve */ 1.425 + if (dn->bits&DECNEG && hi==214748364 && lo==8) return 0x80000000; 1.426 + /* bad -- drop through */ 1.427 + } 1.428 + else { /* in-range always */ 1.429 + Int i=X10(hi)+lo; 1.430 + if (dn->bits&DECNEG) return -i; 1.431 + return i; 1.432 + } 1.433 + } /* integer */ 1.434 + uprv_decContextSetStatus(set, DEC_Invalid_operation); /* [may not return] */ 1.435 + return 0; 1.436 + } /* decNumberToInt32 */ 1.437 + 1.438 +U_CAPI uInt U_EXPORT2 uprv_decNumberToUInt32(const decNumber *dn, decContext *set) { 1.439 + #if DECCHECK 1.440 + if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0; 1.441 + #endif 1.442 + /* special or too many digits, or bad exponent, or negative (<0) */ 1.443 + if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0 1.444 + || (dn->bits&DECNEG && !ISZERO(dn))); /* bad */ 1.445 + else { /* is a finite integer with 10 or fewer digits */ 1.446 + Int d; /* work */ 1.447 + const Unit *up; /* .. */ 1.448 + uInt hi=0, lo; /* .. */ 1.449 + up=dn->lsu; /* -> lsu */ 1.450 + lo=*up; /* get 1 to 9 digits */ 1.451 + #if DECDPUN>1 /* split to higher */ 1.452 + hi=lo/10; 1.453 + lo=lo%10; 1.454 + #endif 1.455 + up++; 1.456 + /* collect remaining Units, if any, into hi */ 1.457 + for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1]; 1.458 + 1.459 + /* now low has the lsd, hi the remainder */ 1.460 + if (hi>429496729 || (hi==429496729 && lo>5)) ; /* no reprieve possible */ 1.461 + else return X10(hi)+lo; 1.462 + } /* integer */ 1.463 + uprv_decContextSetStatus(set, DEC_Invalid_operation); /* [may not return] */ 1.464 + return 0; 1.465 + } /* decNumberToUInt32 */ 1.466 + 1.467 +/* ------------------------------------------------------------------ */ 1.468 +/* to-scientific-string -- conversion to numeric string */ 1.469 +/* to-engineering-string -- conversion to numeric string */ 1.470 +/* */ 1.471 +/* decNumberToString(dn, string); */ 1.472 +/* decNumberToEngString(dn, string); */ 1.473 +/* */ 1.474 +/* dn is the decNumber to convert */ 1.475 +/* string is the string where the result will be laid out */ 1.476 +/* */ 1.477 +/* string must be at least dn->digits+14 characters long */ 1.478 +/* */ 1.479 +/* No error is possible, and no status can be set. */ 1.480 +/* ------------------------------------------------------------------ */ 1.481 +U_CAPI char * U_EXPORT2 uprv_decNumberToString(const decNumber *dn, char *string){ 1.482 + decToString(dn, string, 0); 1.483 + return string; 1.484 + } /* DecNumberToString */ 1.485 + 1.486 +U_CAPI char * U_EXPORT2 uprv_decNumberToEngString(const decNumber *dn, char *string){ 1.487 + decToString(dn, string, 1); 1.488 + return string; 1.489 + } /* DecNumberToEngString */ 1.490 + 1.491 +/* ------------------------------------------------------------------ */ 1.492 +/* to-number -- conversion from numeric string */ 1.493 +/* */ 1.494 +/* decNumberFromString -- convert string to decNumber */ 1.495 +/* dn -- the number structure to fill */ 1.496 +/* chars[] -- the string to convert ('\0' terminated) */ 1.497 +/* set -- the context used for processing any error, */ 1.498 +/* determining the maximum precision available */ 1.499 +/* (set.digits), determining the maximum and minimum */ 1.500 +/* exponent (set.emax and set.emin), determining if */ 1.501 +/* extended values are allowed, and checking the */ 1.502 +/* rounding mode if overflow occurs or rounding is */ 1.503 +/* needed. */ 1.504 +/* */ 1.505 +/* The length of the coefficient and the size of the exponent are */ 1.506 +/* checked by this routine, so the correct error (Underflow or */ 1.507 +/* Overflow) can be reported or rounding applied, as necessary. */ 1.508 +/* */ 1.509 +/* If bad syntax is detected, the result will be a quiet NaN. */ 1.510 +/* ------------------------------------------------------------------ */ 1.511 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberFromString(decNumber *dn, const char chars[], 1.512 + decContext *set) { 1.513 + Int exponent=0; /* working exponent [assume 0] */ 1.514 + uByte bits=0; /* working flags [assume +ve] */ 1.515 + Unit *res; /* where result will be built */ 1.516 + Unit resbuff[SD2U(DECBUFFER+9)];/* local buffer in case need temporary */ 1.517 + /* [+9 allows for ln() constants] */ 1.518 + Unit *allocres=NULL; /* -> allocated result, iff allocated */ 1.519 + Int d=0; /* count of digits found in decimal part */ 1.520 + const char *dotchar=NULL; /* where dot was found */ 1.521 + const char *cfirst=chars; /* -> first character of decimal part */ 1.522 + const char *last=NULL; /* -> last digit of decimal part */ 1.523 + const char *c; /* work */ 1.524 + Unit *up; /* .. */ 1.525 + #if DECDPUN>1 1.526 + Int cut, out; /* .. */ 1.527 + #endif 1.528 + Int residue; /* rounding residue */ 1.529 + uInt status=0; /* error code */ 1.530 + 1.531 + #if DECCHECK 1.532 + if (decCheckOperands(DECUNRESU, DECUNUSED, DECUNUSED, set)) 1.533 + return uprv_decNumberZero(dn); 1.534 + #endif 1.535 + 1.536 + do { /* status & malloc protection */ 1.537 + for (c=chars;; c++) { /* -> input character */ 1.538 + if (*c>='0' && *c<='9') { /* test for Arabic digit */ 1.539 + last=c; 1.540 + d++; /* count of real digits */ 1.541 + continue; /* still in decimal part */ 1.542 + } 1.543 + if (*c=='.' && dotchar==NULL) { /* first '.' */ 1.544 + dotchar=c; /* record offset into decimal part */ 1.545 + if (c==cfirst) cfirst++; /* first digit must follow */ 1.546 + continue;} 1.547 + if (c==chars) { /* first in string... */ 1.548 + if (*c=='-') { /* valid - sign */ 1.549 + cfirst++; 1.550 + bits=DECNEG; 1.551 + continue;} 1.552 + if (*c=='+') { /* valid + sign */ 1.553 + cfirst++; 1.554 + continue;} 1.555 + } 1.556 + /* *c is not a digit, or a valid +, -, or '.' */ 1.557 + break; 1.558 + } /* c */ 1.559 + 1.560 + if (last==NULL) { /* no digits yet */ 1.561 + status=DEC_Conversion_syntax;/* assume the worst */ 1.562 + if (*c=='\0') break; /* and no more to come... */ 1.563 + #if DECSUBSET 1.564 + /* if subset then infinities and NaNs are not allowed */ 1.565 + if (!set->extended) break; /* hopeless */ 1.566 + #endif 1.567 + /* Infinities and NaNs are possible, here */ 1.568 + if (dotchar!=NULL) break; /* .. unless had a dot */ 1.569 + uprv_decNumberZero(dn); /* be optimistic */ 1.570 + if (decBiStr(c, "infinity", "INFINITY") 1.571 + || decBiStr(c, "inf", "INF")) { 1.572 + dn->bits=bits | DECINF; 1.573 + status=0; /* is OK */ 1.574 + break; /* all done */ 1.575 + } 1.576 + /* a NaN expected */ 1.577 + /* 2003.09.10 NaNs are now permitted to have a sign */ 1.578 + dn->bits=bits | DECNAN; /* assume simple NaN */ 1.579 + if (*c=='s' || *c=='S') { /* looks like an sNaN */ 1.580 + c++; 1.581 + dn->bits=bits | DECSNAN; 1.582 + } 1.583 + if (*c!='n' && *c!='N') break; /* check caseless "NaN" */ 1.584 + c++; 1.585 + if (*c!='a' && *c!='A') break; /* .. */ 1.586 + c++; 1.587 + if (*c!='n' && *c!='N') break; /* .. */ 1.588 + c++; 1.589 + /* now either nothing, or nnnn payload, expected */ 1.590 + /* -> start of integer and skip leading 0s [including plain 0] */ 1.591 + for (cfirst=c; *cfirst=='0';) cfirst++; 1.592 + if (*cfirst=='\0') { /* "NaN" or "sNaN", maybe with all 0s */ 1.593 + status=0; /* it's good */ 1.594 + break; /* .. */ 1.595 + } 1.596 + /* something other than 0s; setup last and d as usual [no dots] */ 1.597 + for (c=cfirst;; c++, d++) { 1.598 + if (*c<'0' || *c>'9') break; /* test for Arabic digit */ 1.599 + last=c; 1.600 + } 1.601 + if (*c!='\0') break; /* not all digits */ 1.602 + if (d>set->digits-1) { 1.603 + /* [NB: payload in a decNumber can be full length unless */ 1.604 + /* clamped, in which case can only be digits-1] */ 1.605 + if (set->clamp) break; 1.606 + if (d>set->digits) break; 1.607 + } /* too many digits? */ 1.608 + /* good; drop through to convert the integer to coefficient */ 1.609 + status=0; /* syntax is OK */ 1.610 + bits=dn->bits; /* for copy-back */ 1.611 + } /* last==NULL */ 1.612 + 1.613 + else if (*c!='\0') { /* more to process... */ 1.614 + /* had some digits; exponent is only valid sequence now */ 1.615 + Flag nege; /* 1=negative exponent */ 1.616 + const char *firstexp; /* -> first significant exponent digit */ 1.617 + status=DEC_Conversion_syntax;/* assume the worst */ 1.618 + if (*c!='e' && *c!='E') break; 1.619 + /* Found 'e' or 'E' -- now process explicit exponent */ 1.620 + /* 1998.07.11: sign no longer required */ 1.621 + nege=0; 1.622 + c++; /* to (possible) sign */ 1.623 + if (*c=='-') {nege=1; c++;} 1.624 + else if (*c=='+') c++; 1.625 + if (*c=='\0') break; 1.626 + 1.627 + for (; *c=='0' && *(c+1)!='\0';) c++; /* strip insignificant zeros */ 1.628 + firstexp=c; /* save exponent digit place */ 1.629 + for (; ;c++) { 1.630 + if (*c<'0' || *c>'9') break; /* not a digit */ 1.631 + exponent=X10(exponent)+(Int)*c-(Int)'0'; 1.632 + } /* c */ 1.633 + /* if not now on a '\0', *c must not be a digit */ 1.634 + if (*c!='\0') break; 1.635 + 1.636 + /* (this next test must be after the syntax checks) */ 1.637 + /* if it was too long the exponent may have wrapped, so check */ 1.638 + /* carefully and set it to a certain overflow if wrap possible */ 1.639 + if (c>=firstexp+9+1) { 1.640 + if (c>firstexp+9+1 || *firstexp>'1') exponent=DECNUMMAXE*2; 1.641 + /* [up to 1999999999 is OK, for example 1E-1000000998] */ 1.642 + } 1.643 + if (nege) exponent=-exponent; /* was negative */ 1.644 + status=0; /* is OK */ 1.645 + } /* stuff after digits */ 1.646 + 1.647 + /* Here when whole string has been inspected; syntax is good */ 1.648 + /* cfirst->first digit (never dot), last->last digit (ditto) */ 1.649 + 1.650 + /* strip leading zeros/dot [leave final 0 if all 0's] */ 1.651 + if (*cfirst=='0') { /* [cfirst has stepped over .] */ 1.652 + for (c=cfirst; c<last; c++, cfirst++) { 1.653 + if (*c=='.') continue; /* ignore dots */ 1.654 + if (*c!='0') break; /* non-zero found */ 1.655 + d--; /* 0 stripped */ 1.656 + } /* c */ 1.657 + #if DECSUBSET 1.658 + /* make a rapid exit for easy zeros if !extended */ 1.659 + if (*cfirst=='0' && !set->extended) { 1.660 + uprv_decNumberZero(dn); /* clean result */ 1.661 + break; /* [could be return] */ 1.662 + } 1.663 + #endif 1.664 + } /* at least one leading 0 */ 1.665 + 1.666 + /* Handle decimal point... */ 1.667 + if (dotchar!=NULL && dotchar<last) /* non-trailing '.' found? */ 1.668 + exponent-=(last-dotchar); /* adjust exponent */ 1.669 + /* [we can now ignore the .] */ 1.670 + 1.671 + /* OK, the digits string is good. Assemble in the decNumber, or in */ 1.672 + /* a temporary units array if rounding is needed */ 1.673 + if (d<=set->digits) res=dn->lsu; /* fits into supplied decNumber */ 1.674 + else { /* rounding needed */ 1.675 + Int needbytes=D2U(d)*sizeof(Unit);/* bytes needed */ 1.676 + res=resbuff; /* assume use local buffer */ 1.677 + if (needbytes>(Int)sizeof(resbuff)) { /* too big for local */ 1.678 + allocres=(Unit *)malloc(needbytes); 1.679 + if (allocres==NULL) {status|=DEC_Insufficient_storage; break;} 1.680 + res=allocres; 1.681 + } 1.682 + } 1.683 + /* res now -> number lsu, buffer, or allocated storage for Unit array */ 1.684 + 1.685 + /* Place the coefficient into the selected Unit array */ 1.686 + /* [this is often 70% of the cost of this function when DECDPUN>1] */ 1.687 + #if DECDPUN>1 1.688 + out=0; /* accumulator */ 1.689 + up=res+D2U(d)-1; /* -> msu */ 1.690 + cut=d-(up-res)*DECDPUN; /* digits in top unit */ 1.691 + for (c=cfirst;; c++) { /* along the digits */ 1.692 + if (*c=='.') continue; /* ignore '.' [don't decrement cut] */ 1.693 + out=X10(out)+(Int)*c-(Int)'0'; 1.694 + if (c==last) break; /* done [never get to trailing '.'] */ 1.695 + cut--; 1.696 + if (cut>0) continue; /* more for this unit */ 1.697 + *up=(Unit)out; /* write unit */ 1.698 + up--; /* prepare for unit below.. */ 1.699 + cut=DECDPUN; /* .. */ 1.700 + out=0; /* .. */ 1.701 + } /* c */ 1.702 + *up=(Unit)out; /* write lsu */ 1.703 + 1.704 + #else 1.705 + /* DECDPUN==1 */ 1.706 + up=res; /* -> lsu */ 1.707 + for (c=last; c>=cfirst; c--) { /* over each character, from least */ 1.708 + if (*c=='.') continue; /* ignore . [don't step up] */ 1.709 + *up=(Unit)((Int)*c-(Int)'0'); 1.710 + up++; 1.711 + } /* c */ 1.712 + #endif 1.713 + 1.714 + dn->bits=bits; 1.715 + dn->exponent=exponent; 1.716 + dn->digits=d; 1.717 + 1.718 + /* if not in number (too long) shorten into the number */ 1.719 + if (d>set->digits) { 1.720 + residue=0; 1.721 + decSetCoeff(dn, set, res, d, &residue, &status); 1.722 + /* always check for overflow or subnormal and round as needed */ 1.723 + decFinalize(dn, set, &residue, &status); 1.724 + } 1.725 + else { /* no rounding, but may still have overflow or subnormal */ 1.726 + /* [these tests are just for performance; finalize repeats them] */ 1.727 + if ((dn->exponent-1<set->emin-dn->digits) 1.728 + || (dn->exponent-1>set->emax-set->digits)) { 1.729 + residue=0; 1.730 + decFinalize(dn, set, &residue, &status); 1.731 + } 1.732 + } 1.733 + /* decNumberShow(dn); */ 1.734 + } while(0); /* [for break] */ 1.735 + 1.736 + if (allocres!=NULL) free(allocres); /* drop any storage used */ 1.737 + if (status!=0) decStatus(dn, status, set); 1.738 + return dn; 1.739 + } /* decNumberFromString */ 1.740 + 1.741 +/* ================================================================== */ 1.742 +/* Operators */ 1.743 +/* ================================================================== */ 1.744 + 1.745 +/* ------------------------------------------------------------------ */ 1.746 +/* decNumberAbs -- absolute value operator */ 1.747 +/* */ 1.748 +/* This computes C = abs(A) */ 1.749 +/* */ 1.750 +/* res is C, the result. C may be A */ 1.751 +/* rhs is A */ 1.752 +/* set is the context */ 1.753 +/* */ 1.754 +/* See also decNumberCopyAbs for a quiet bitwise version of this. */ 1.755 +/* C must have space for set->digits digits. */ 1.756 +/* ------------------------------------------------------------------ */ 1.757 +/* This has the same effect as decNumberPlus unless A is negative, */ 1.758 +/* in which case it has the same effect as decNumberMinus. */ 1.759 +/* ------------------------------------------------------------------ */ 1.760 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberAbs(decNumber *res, const decNumber *rhs, 1.761 + decContext *set) { 1.762 + decNumber dzero; /* for 0 */ 1.763 + uInt status=0; /* accumulator */ 1.764 + 1.765 + #if DECCHECK 1.766 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.767 + #endif 1.768 + 1.769 + uprv_decNumberZero(&dzero); /* set 0 */ 1.770 + dzero.exponent=rhs->exponent; /* [no coefficient expansion] */ 1.771 + decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status); 1.772 + if (status!=0) decStatus(res, status, set); 1.773 + #if DECCHECK 1.774 + decCheckInexact(res, set); 1.775 + #endif 1.776 + return res; 1.777 + } /* decNumberAbs */ 1.778 + 1.779 +/* ------------------------------------------------------------------ */ 1.780 +/* decNumberAdd -- add two Numbers */ 1.781 +/* */ 1.782 +/* This computes C = A + B */ 1.783 +/* */ 1.784 +/* res is C, the result. C may be A and/or B (e.g., X=X+X) */ 1.785 +/* lhs is A */ 1.786 +/* rhs is B */ 1.787 +/* set is the context */ 1.788 +/* */ 1.789 +/* C must have space for set->digits digits. */ 1.790 +/* ------------------------------------------------------------------ */ 1.791 +/* This just calls the routine shared with Subtract */ 1.792 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberAdd(decNumber *res, const decNumber *lhs, 1.793 + const decNumber *rhs, decContext *set) { 1.794 + uInt status=0; /* accumulator */ 1.795 + decAddOp(res, lhs, rhs, set, 0, &status); 1.796 + if (status!=0) decStatus(res, status, set); 1.797 + #if DECCHECK 1.798 + decCheckInexact(res, set); 1.799 + #endif 1.800 + return res; 1.801 + } /* decNumberAdd */ 1.802 + 1.803 +/* ------------------------------------------------------------------ */ 1.804 +/* decNumberAnd -- AND two Numbers, digitwise */ 1.805 +/* */ 1.806 +/* This computes C = A & B */ 1.807 +/* */ 1.808 +/* res is C, the result. C may be A and/or B (e.g., X=X&X) */ 1.809 +/* lhs is A */ 1.810 +/* rhs is B */ 1.811 +/* set is the context (used for result length and error report) */ 1.812 +/* */ 1.813 +/* C must have space for set->digits digits. */ 1.814 +/* */ 1.815 +/* Logical function restrictions apply (see above); a NaN is */ 1.816 +/* returned with Invalid_operation if a restriction is violated. */ 1.817 +/* ------------------------------------------------------------------ */ 1.818 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberAnd(decNumber *res, const decNumber *lhs, 1.819 + const decNumber *rhs, decContext *set) { 1.820 + const Unit *ua, *ub; /* -> operands */ 1.821 + const Unit *msua, *msub; /* -> operand msus */ 1.822 + Unit *uc, *msuc; /* -> result and its msu */ 1.823 + Int msudigs; /* digits in res msu */ 1.824 + #if DECCHECK 1.825 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.826 + #endif 1.827 + 1.828 + if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs) 1.829 + || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) { 1.830 + decStatus(res, DEC_Invalid_operation, set); 1.831 + return res; 1.832 + } 1.833 + 1.834 + /* operands are valid */ 1.835 + ua=lhs->lsu; /* bottom-up */ 1.836 + ub=rhs->lsu; /* .. */ 1.837 + uc=res->lsu; /* .. */ 1.838 + msua=ua+D2U(lhs->digits)-1; /* -> msu of lhs */ 1.839 + msub=ub+D2U(rhs->digits)-1; /* -> msu of rhs */ 1.840 + msuc=uc+D2U(set->digits)-1; /* -> msu of result */ 1.841 + msudigs=MSUDIGITS(set->digits); /* [faster than remainder] */ 1.842 + for (; uc<=msuc; ua++, ub++, uc++) { /* Unit loop */ 1.843 + Unit a, b; /* extract units */ 1.844 + if (ua>msua) a=0; 1.845 + else a=*ua; 1.846 + if (ub>msub) b=0; 1.847 + else b=*ub; 1.848 + *uc=0; /* can now write back */ 1.849 + if (a|b) { /* maybe 1 bits to examine */ 1.850 + Int i, j; 1.851 + *uc=0; /* can now write back */ 1.852 + /* This loop could be unrolled and/or use BIN2BCD tables */ 1.853 + for (i=0; i<DECDPUN; i++) { 1.854 + if (a&b&1) *uc=*uc+(Unit)powers[i]; /* effect AND */ 1.855 + j=a%10; 1.856 + a=a/10; 1.857 + j|=b%10; 1.858 + b=b/10; 1.859 + if (j>1) { 1.860 + decStatus(res, DEC_Invalid_operation, set); 1.861 + return res; 1.862 + } 1.863 + if (uc==msuc && i==msudigs-1) break; /* just did final digit */ 1.864 + } /* each digit */ 1.865 + } /* both OK */ 1.866 + } /* each unit */ 1.867 + /* [here uc-1 is the msu of the result] */ 1.868 + res->digits=decGetDigits(res->lsu, uc-res->lsu); 1.869 + res->exponent=0; /* integer */ 1.870 + res->bits=0; /* sign=0 */ 1.871 + return res; /* [no status to set] */ 1.872 + } /* decNumberAnd */ 1.873 + 1.874 +/* ------------------------------------------------------------------ */ 1.875 +/* decNumberCompare -- compare two Numbers */ 1.876 +/* */ 1.877 +/* This computes C = A ? B */ 1.878 +/* */ 1.879 +/* res is C, the result. C may be A and/or B (e.g., X=X?X) */ 1.880 +/* lhs is A */ 1.881 +/* rhs is B */ 1.882 +/* set is the context */ 1.883 +/* */ 1.884 +/* C must have space for one digit (or NaN). */ 1.885 +/* ------------------------------------------------------------------ */ 1.886 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCompare(decNumber *res, const decNumber *lhs, 1.887 + const decNumber *rhs, decContext *set) { 1.888 + uInt status=0; /* accumulator */ 1.889 + decCompareOp(res, lhs, rhs, set, COMPARE, &status); 1.890 + if (status!=0) decStatus(res, status, set); 1.891 + return res; 1.892 + } /* decNumberCompare */ 1.893 + 1.894 +/* ------------------------------------------------------------------ */ 1.895 +/* decNumberCompareSignal -- compare, signalling on all NaNs */ 1.896 +/* */ 1.897 +/* This computes C = A ? B */ 1.898 +/* */ 1.899 +/* res is C, the result. C may be A and/or B (e.g., X=X?X) */ 1.900 +/* lhs is A */ 1.901 +/* rhs is B */ 1.902 +/* set is the context */ 1.903 +/* */ 1.904 +/* C must have space for one digit (or NaN). */ 1.905 +/* ------------------------------------------------------------------ */ 1.906 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCompareSignal(decNumber *res, const decNumber *lhs, 1.907 + const decNumber *rhs, decContext *set) { 1.908 + uInt status=0; /* accumulator */ 1.909 + decCompareOp(res, lhs, rhs, set, COMPSIG, &status); 1.910 + if (status!=0) decStatus(res, status, set); 1.911 + return res; 1.912 + } /* decNumberCompareSignal */ 1.913 + 1.914 +/* ------------------------------------------------------------------ */ 1.915 +/* decNumberCompareTotal -- compare two Numbers, using total ordering */ 1.916 +/* */ 1.917 +/* This computes C = A ? B, under total ordering */ 1.918 +/* */ 1.919 +/* res is C, the result. C may be A and/or B (e.g., X=X?X) */ 1.920 +/* lhs is A */ 1.921 +/* rhs is B */ 1.922 +/* set is the context */ 1.923 +/* */ 1.924 +/* C must have space for one digit; the result will always be one of */ 1.925 +/* -1, 0, or 1. */ 1.926 +/* ------------------------------------------------------------------ */ 1.927 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCompareTotal(decNumber *res, const decNumber *lhs, 1.928 + const decNumber *rhs, decContext *set) { 1.929 + uInt status=0; /* accumulator */ 1.930 + decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status); 1.931 + if (status!=0) decStatus(res, status, set); 1.932 + return res; 1.933 + } /* decNumberCompareTotal */ 1.934 + 1.935 +/* ------------------------------------------------------------------ */ 1.936 +/* decNumberCompareTotalMag -- compare, total ordering of magnitudes */ 1.937 +/* */ 1.938 +/* This computes C = |A| ? |B|, under total ordering */ 1.939 +/* */ 1.940 +/* res is C, the result. C may be A and/or B (e.g., X=X?X) */ 1.941 +/* lhs is A */ 1.942 +/* rhs is B */ 1.943 +/* set is the context */ 1.944 +/* */ 1.945 +/* C must have space for one digit; the result will always be one of */ 1.946 +/* -1, 0, or 1. */ 1.947 +/* ------------------------------------------------------------------ */ 1.948 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCompareTotalMag(decNumber *res, const decNumber *lhs, 1.949 + const decNumber *rhs, decContext *set) { 1.950 + uInt status=0; /* accumulator */ 1.951 + uInt needbytes; /* for space calculations */ 1.952 + decNumber bufa[D2N(DECBUFFER+1)];/* +1 in case DECBUFFER=0 */ 1.953 + decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */ 1.954 + decNumber bufb[D2N(DECBUFFER+1)]; 1.955 + decNumber *allocbufb=NULL; /* -> allocated bufb, iff allocated */ 1.956 + decNumber *a, *b; /* temporary pointers */ 1.957 + 1.958 + #if DECCHECK 1.959 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.960 + #endif 1.961 + 1.962 + do { /* protect allocated storage */ 1.963 + /* if either is negative, take a copy and absolute */ 1.964 + if (decNumberIsNegative(lhs)) { /* lhs<0 */ 1.965 + a=bufa; 1.966 + needbytes=sizeof(decNumber)+(D2U(lhs->digits)-1)*sizeof(Unit); 1.967 + if (needbytes>sizeof(bufa)) { /* need malloc space */ 1.968 + allocbufa=(decNumber *)malloc(needbytes); 1.969 + if (allocbufa==NULL) { /* hopeless -- abandon */ 1.970 + status|=DEC_Insufficient_storage; 1.971 + break;} 1.972 + a=allocbufa; /* use the allocated space */ 1.973 + } 1.974 + uprv_decNumberCopy(a, lhs); /* copy content */ 1.975 + a->bits&=~DECNEG; /* .. and clear the sign */ 1.976 + lhs=a; /* use copy from here on */ 1.977 + } 1.978 + if (decNumberIsNegative(rhs)) { /* rhs<0 */ 1.979 + b=bufb; 1.980 + needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit); 1.981 + if (needbytes>sizeof(bufb)) { /* need malloc space */ 1.982 + allocbufb=(decNumber *)malloc(needbytes); 1.983 + if (allocbufb==NULL) { /* hopeless -- abandon */ 1.984 + status|=DEC_Insufficient_storage; 1.985 + break;} 1.986 + b=allocbufb; /* use the allocated space */ 1.987 + } 1.988 + uprv_decNumberCopy(b, rhs); /* copy content */ 1.989 + b->bits&=~DECNEG; /* .. and clear the sign */ 1.990 + rhs=b; /* use copy from here on */ 1.991 + } 1.992 + decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status); 1.993 + } while(0); /* end protected */ 1.994 + 1.995 + if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */ 1.996 + if (allocbufb!=NULL) free(allocbufb); /* .. */ 1.997 + if (status!=0) decStatus(res, status, set); 1.998 + return res; 1.999 + } /* decNumberCompareTotalMag */ 1.1000 + 1.1001 +/* ------------------------------------------------------------------ */ 1.1002 +/* decNumberDivide -- divide one number by another */ 1.1003 +/* */ 1.1004 +/* This computes C = A / B */ 1.1005 +/* */ 1.1006 +/* res is C, the result. C may be A and/or B (e.g., X=X/X) */ 1.1007 +/* lhs is A */ 1.1008 +/* rhs is B */ 1.1009 +/* set is the context */ 1.1010 +/* */ 1.1011 +/* C must have space for set->digits digits. */ 1.1012 +/* ------------------------------------------------------------------ */ 1.1013 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberDivide(decNumber *res, const decNumber *lhs, 1.1014 + const decNumber *rhs, decContext *set) { 1.1015 + uInt status=0; /* accumulator */ 1.1016 + decDivideOp(res, lhs, rhs, set, DIVIDE, &status); 1.1017 + if (status!=0) decStatus(res, status, set); 1.1018 + #if DECCHECK 1.1019 + decCheckInexact(res, set); 1.1020 + #endif 1.1021 + return res; 1.1022 + } /* decNumberDivide */ 1.1023 + 1.1024 +/* ------------------------------------------------------------------ */ 1.1025 +/* decNumberDivideInteger -- divide and return integer quotient */ 1.1026 +/* */ 1.1027 +/* This computes C = A # B, where # is the integer divide operator */ 1.1028 +/* */ 1.1029 +/* res is C, the result. C may be A and/or B (e.g., X=X#X) */ 1.1030 +/* lhs is A */ 1.1031 +/* rhs is B */ 1.1032 +/* set is the context */ 1.1033 +/* */ 1.1034 +/* C must have space for set->digits digits. */ 1.1035 +/* ------------------------------------------------------------------ */ 1.1036 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberDivideInteger(decNumber *res, const decNumber *lhs, 1.1037 + const decNumber *rhs, decContext *set) { 1.1038 + uInt status=0; /* accumulator */ 1.1039 + decDivideOp(res, lhs, rhs, set, DIVIDEINT, &status); 1.1040 + if (status!=0) decStatus(res, status, set); 1.1041 + return res; 1.1042 + } /* decNumberDivideInteger */ 1.1043 + 1.1044 +/* ------------------------------------------------------------------ */ 1.1045 +/* decNumberExp -- exponentiation */ 1.1046 +/* */ 1.1047 +/* This computes C = exp(A) */ 1.1048 +/* */ 1.1049 +/* res is C, the result. C may be A */ 1.1050 +/* rhs is A */ 1.1051 +/* set is the context; note that rounding mode has no effect */ 1.1052 +/* */ 1.1053 +/* C must have space for set->digits digits. */ 1.1054 +/* */ 1.1055 +/* Mathematical function restrictions apply (see above); a NaN is */ 1.1056 +/* returned with Invalid_operation if a restriction is violated. */ 1.1057 +/* */ 1.1058 +/* Finite results will always be full precision and Inexact, except */ 1.1059 +/* when A is a zero or -Infinity (giving 1 or 0 respectively). */ 1.1060 +/* */ 1.1061 +/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */ 1.1062 +/* almost always be correctly rounded, but may be up to 1 ulp in */ 1.1063 +/* error in rare cases. */ 1.1064 +/* ------------------------------------------------------------------ */ 1.1065 +/* This is a wrapper for decExpOp which can handle the slightly wider */ 1.1066 +/* (double) range needed by Ln (which has to be able to calculate */ 1.1067 +/* exp(-a) where a can be the tiniest number (Ntiny). */ 1.1068 +/* ------------------------------------------------------------------ */ 1.1069 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberExp(decNumber *res, const decNumber *rhs, 1.1070 + decContext *set) { 1.1071 + uInt status=0; /* accumulator */ 1.1072 + #if DECSUBSET 1.1073 + decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */ 1.1074 + #endif 1.1075 + 1.1076 + #if DECCHECK 1.1077 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.1078 + #endif 1.1079 + 1.1080 + /* Check restrictions; these restrictions ensure that if h=8 (see */ 1.1081 + /* decExpOp) then the result will either overflow or underflow to 0. */ 1.1082 + /* Other math functions restrict the input range, too, for inverses. */ 1.1083 + /* If not violated then carry out the operation. */ 1.1084 + if (!decCheckMath(rhs, set, &status)) do { /* protect allocation */ 1.1085 + #if DECSUBSET 1.1086 + if (!set->extended) { 1.1087 + /* reduce operand and set lostDigits status, as needed */ 1.1088 + if (rhs->digits>set->digits) { 1.1089 + allocrhs=decRoundOperand(rhs, set, &status); 1.1090 + if (allocrhs==NULL) break; 1.1091 + rhs=allocrhs; 1.1092 + } 1.1093 + } 1.1094 + #endif 1.1095 + decExpOp(res, rhs, set, &status); 1.1096 + } while(0); /* end protected */ 1.1097 + 1.1098 + #if DECSUBSET 1.1099 + if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */ 1.1100 + #endif 1.1101 + /* apply significant status */ 1.1102 + if (status!=0) decStatus(res, status, set); 1.1103 + #if DECCHECK 1.1104 + decCheckInexact(res, set); 1.1105 + #endif 1.1106 + return res; 1.1107 + } /* decNumberExp */ 1.1108 + 1.1109 +/* ------------------------------------------------------------------ */ 1.1110 +/* decNumberFMA -- fused multiply add */ 1.1111 +/* */ 1.1112 +/* This computes D = (A * B) + C with only one rounding */ 1.1113 +/* */ 1.1114 +/* res is D, the result. D may be A or B or C (e.g., X=FMA(X,X,X)) */ 1.1115 +/* lhs is A */ 1.1116 +/* rhs is B */ 1.1117 +/* fhs is C [far hand side] */ 1.1118 +/* set is the context */ 1.1119 +/* */ 1.1120 +/* Mathematical function restrictions apply (see above); a NaN is */ 1.1121 +/* returned with Invalid_operation if a restriction is violated. */ 1.1122 +/* */ 1.1123 +/* C must have space for set->digits digits. */ 1.1124 +/* ------------------------------------------------------------------ */ 1.1125 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberFMA(decNumber *res, const decNumber *lhs, 1.1126 + const decNumber *rhs, const decNumber *fhs, 1.1127 + decContext *set) { 1.1128 + uInt status=0; /* accumulator */ 1.1129 + decContext dcmul; /* context for the multiplication */ 1.1130 + uInt needbytes; /* for space calculations */ 1.1131 + decNumber bufa[D2N(DECBUFFER*2+1)]; 1.1132 + decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */ 1.1133 + decNumber *acc; /* accumulator pointer */ 1.1134 + decNumber dzero; /* work */ 1.1135 + 1.1136 + #if DECCHECK 1.1137 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.1138 + if (decCheckOperands(res, fhs, DECUNUSED, set)) return res; 1.1139 + #endif 1.1140 + 1.1141 + do { /* protect allocated storage */ 1.1142 + #if DECSUBSET 1.1143 + if (!set->extended) { /* [undefined if subset] */ 1.1144 + status|=DEC_Invalid_operation; 1.1145 + break;} 1.1146 + #endif 1.1147 + /* Check math restrictions [these ensure no overflow or underflow] */ 1.1148 + if ((!decNumberIsSpecial(lhs) && decCheckMath(lhs, set, &status)) 1.1149 + || (!decNumberIsSpecial(rhs) && decCheckMath(rhs, set, &status)) 1.1150 + || (!decNumberIsSpecial(fhs) && decCheckMath(fhs, set, &status))) break; 1.1151 + /* set up context for multiply */ 1.1152 + dcmul=*set; 1.1153 + dcmul.digits=lhs->digits+rhs->digits; /* just enough */ 1.1154 + /* [The above may be an over-estimate for subset arithmetic, but that's OK] */ 1.1155 + dcmul.emax=DEC_MAX_EMAX; /* effectively unbounded .. */ 1.1156 + dcmul.emin=DEC_MIN_EMIN; /* [thanks to Math restrictions] */ 1.1157 + /* set up decNumber space to receive the result of the multiply */ 1.1158 + acc=bufa; /* may fit */ 1.1159 + needbytes=sizeof(decNumber)+(D2U(dcmul.digits)-1)*sizeof(Unit); 1.1160 + if (needbytes>sizeof(bufa)) { /* need malloc space */ 1.1161 + allocbufa=(decNumber *)malloc(needbytes); 1.1162 + if (allocbufa==NULL) { /* hopeless -- abandon */ 1.1163 + status|=DEC_Insufficient_storage; 1.1164 + break;} 1.1165 + acc=allocbufa; /* use the allocated space */ 1.1166 + } 1.1167 + /* multiply with extended range and necessary precision */ 1.1168 + /*printf("emin=%ld\n", dcmul.emin); */ 1.1169 + decMultiplyOp(acc, lhs, rhs, &dcmul, &status); 1.1170 + /* Only Invalid operation (from sNaN or Inf * 0) is possible in */ 1.1171 + /* status; if either is seen than ignore fhs (in case it is */ 1.1172 + /* another sNaN) and set acc to NaN unless we had an sNaN */ 1.1173 + /* [decMultiplyOp leaves that to caller] */ 1.1174 + /* Note sNaN has to go through addOp to shorten payload if */ 1.1175 + /* necessary */ 1.1176 + if ((status&DEC_Invalid_operation)!=0) { 1.1177 + if (!(status&DEC_sNaN)) { /* but be true invalid */ 1.1178 + uprv_decNumberZero(res); /* acc not yet set */ 1.1179 + res->bits=DECNAN; 1.1180 + break; 1.1181 + } 1.1182 + uprv_decNumberZero(&dzero); /* make 0 (any non-NaN would do) */ 1.1183 + fhs=&dzero; /* use that */ 1.1184 + } 1.1185 + #if DECCHECK 1.1186 + else { /* multiply was OK */ 1.1187 + if (status!=0) printf("Status=%08lx after FMA multiply\n", (LI)status); 1.1188 + } 1.1189 + #endif 1.1190 + /* add the third operand and result -> res, and all is done */ 1.1191 + decAddOp(res, acc, fhs, set, 0, &status); 1.1192 + } while(0); /* end protected */ 1.1193 + 1.1194 + if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */ 1.1195 + if (status!=0) decStatus(res, status, set); 1.1196 + #if DECCHECK 1.1197 + decCheckInexact(res, set); 1.1198 + #endif 1.1199 + return res; 1.1200 + } /* decNumberFMA */ 1.1201 + 1.1202 +/* ------------------------------------------------------------------ */ 1.1203 +/* decNumberInvert -- invert a Number, digitwise */ 1.1204 +/* */ 1.1205 +/* This computes C = ~A */ 1.1206 +/* */ 1.1207 +/* res is C, the result. C may be A (e.g., X=~X) */ 1.1208 +/* rhs is A */ 1.1209 +/* set is the context (used for result length and error report) */ 1.1210 +/* */ 1.1211 +/* C must have space for set->digits digits. */ 1.1212 +/* */ 1.1213 +/* Logical function restrictions apply (see above); a NaN is */ 1.1214 +/* returned with Invalid_operation if a restriction is violated. */ 1.1215 +/* ------------------------------------------------------------------ */ 1.1216 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberInvert(decNumber *res, const decNumber *rhs, 1.1217 + decContext *set) { 1.1218 + const Unit *ua, *msua; /* -> operand and its msu */ 1.1219 + Unit *uc, *msuc; /* -> result and its msu */ 1.1220 + Int msudigs; /* digits in res msu */ 1.1221 + #if DECCHECK 1.1222 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.1223 + #endif 1.1224 + 1.1225 + if (rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) { 1.1226 + decStatus(res, DEC_Invalid_operation, set); 1.1227 + return res; 1.1228 + } 1.1229 + /* operand is valid */ 1.1230 + ua=rhs->lsu; /* bottom-up */ 1.1231 + uc=res->lsu; /* .. */ 1.1232 + msua=ua+D2U(rhs->digits)-1; /* -> msu of rhs */ 1.1233 + msuc=uc+D2U(set->digits)-1; /* -> msu of result */ 1.1234 + msudigs=MSUDIGITS(set->digits); /* [faster than remainder] */ 1.1235 + for (; uc<=msuc; ua++, uc++) { /* Unit loop */ 1.1236 + Unit a; /* extract unit */ 1.1237 + Int i, j; /* work */ 1.1238 + if (ua>msua) a=0; 1.1239 + else a=*ua; 1.1240 + *uc=0; /* can now write back */ 1.1241 + /* always need to examine all bits in rhs */ 1.1242 + /* This loop could be unrolled and/or use BIN2BCD tables */ 1.1243 + for (i=0; i<DECDPUN; i++) { 1.1244 + if ((~a)&1) *uc=*uc+(Unit)powers[i]; /* effect INVERT */ 1.1245 + j=a%10; 1.1246 + a=a/10; 1.1247 + if (j>1) { 1.1248 + decStatus(res, DEC_Invalid_operation, set); 1.1249 + return res; 1.1250 + } 1.1251 + if (uc==msuc && i==msudigs-1) break; /* just did final digit */ 1.1252 + } /* each digit */ 1.1253 + } /* each unit */ 1.1254 + /* [here uc-1 is the msu of the result] */ 1.1255 + res->digits=decGetDigits(res->lsu, uc-res->lsu); 1.1256 + res->exponent=0; /* integer */ 1.1257 + res->bits=0; /* sign=0 */ 1.1258 + return res; /* [no status to set] */ 1.1259 + } /* decNumberInvert */ 1.1260 + 1.1261 +/* ------------------------------------------------------------------ */ 1.1262 +/* decNumberLn -- natural logarithm */ 1.1263 +/* */ 1.1264 +/* This computes C = ln(A) */ 1.1265 +/* */ 1.1266 +/* res is C, the result. C may be A */ 1.1267 +/* rhs is A */ 1.1268 +/* set is the context; note that rounding mode has no effect */ 1.1269 +/* */ 1.1270 +/* C must have space for set->digits digits. */ 1.1271 +/* */ 1.1272 +/* Notable cases: */ 1.1273 +/* A<0 -> Invalid */ 1.1274 +/* A=0 -> -Infinity (Exact) */ 1.1275 +/* A=+Infinity -> +Infinity (Exact) */ 1.1276 +/* A=1 exactly -> 0 (Exact) */ 1.1277 +/* */ 1.1278 +/* Mathematical function restrictions apply (see above); a NaN is */ 1.1279 +/* returned with Invalid_operation if a restriction is violated. */ 1.1280 +/* */ 1.1281 +/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */ 1.1282 +/* almost always be correctly rounded, but may be up to 1 ulp in */ 1.1283 +/* error in rare cases. */ 1.1284 +/* ------------------------------------------------------------------ */ 1.1285 +/* This is a wrapper for decLnOp which can handle the slightly wider */ 1.1286 +/* (+11) range needed by Ln, Log10, etc. (which may have to be able */ 1.1287 +/* to calculate at p+e+2). */ 1.1288 +/* ------------------------------------------------------------------ */ 1.1289 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberLn(decNumber *res, const decNumber *rhs, 1.1290 + decContext *set) { 1.1291 + uInt status=0; /* accumulator */ 1.1292 + #if DECSUBSET 1.1293 + decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */ 1.1294 + #endif 1.1295 + 1.1296 + #if DECCHECK 1.1297 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.1298 + #endif 1.1299 + 1.1300 + /* Check restrictions; this is a math function; if not violated */ 1.1301 + /* then carry out the operation. */ 1.1302 + if (!decCheckMath(rhs, set, &status)) do { /* protect allocation */ 1.1303 + #if DECSUBSET 1.1304 + if (!set->extended) { 1.1305 + /* reduce operand and set lostDigits status, as needed */ 1.1306 + if (rhs->digits>set->digits) { 1.1307 + allocrhs=decRoundOperand(rhs, set, &status); 1.1308 + if (allocrhs==NULL) break; 1.1309 + rhs=allocrhs; 1.1310 + } 1.1311 + /* special check in subset for rhs=0 */ 1.1312 + if (ISZERO(rhs)) { /* +/- zeros -> error */ 1.1313 + status|=DEC_Invalid_operation; 1.1314 + break;} 1.1315 + } /* extended=0 */ 1.1316 + #endif 1.1317 + decLnOp(res, rhs, set, &status); 1.1318 + } while(0); /* end protected */ 1.1319 + 1.1320 + #if DECSUBSET 1.1321 + if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */ 1.1322 + #endif 1.1323 + /* apply significant status */ 1.1324 + if (status!=0) decStatus(res, status, set); 1.1325 + #if DECCHECK 1.1326 + decCheckInexact(res, set); 1.1327 + #endif 1.1328 + return res; 1.1329 + } /* decNumberLn */ 1.1330 + 1.1331 +/* ------------------------------------------------------------------ */ 1.1332 +/* decNumberLogB - get adjusted exponent, by 754 rules */ 1.1333 +/* */ 1.1334 +/* This computes C = adjustedexponent(A) */ 1.1335 +/* */ 1.1336 +/* res is C, the result. C may be A */ 1.1337 +/* rhs is A */ 1.1338 +/* set is the context, used only for digits and status */ 1.1339 +/* */ 1.1340 +/* C must have space for 10 digits (A might have 10**9 digits and */ 1.1341 +/* an exponent of +999999999, or one digit and an exponent of */ 1.1342 +/* -1999999999). */ 1.1343 +/* */ 1.1344 +/* This returns the adjusted exponent of A after (in theory) padding */ 1.1345 +/* with zeros on the right to set->digits digits while keeping the */ 1.1346 +/* same value. The exponent is not limited by emin/emax. */ 1.1347 +/* */ 1.1348 +/* Notable cases: */ 1.1349 +/* A<0 -> Use |A| */ 1.1350 +/* A=0 -> -Infinity (Division by zero) */ 1.1351 +/* A=Infinite -> +Infinity (Exact) */ 1.1352 +/* A=1 exactly -> 0 (Exact) */ 1.1353 +/* NaNs are propagated as usual */ 1.1354 +/* ------------------------------------------------------------------ */ 1.1355 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberLogB(decNumber *res, const decNumber *rhs, 1.1356 + decContext *set) { 1.1357 + uInt status=0; /* accumulator */ 1.1358 + 1.1359 + #if DECCHECK 1.1360 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.1361 + #endif 1.1362 + 1.1363 + /* NaNs as usual; Infinities return +Infinity; 0->oops */ 1.1364 + if (decNumberIsNaN(rhs)) decNaNs(res, rhs, NULL, set, &status); 1.1365 + else if (decNumberIsInfinite(rhs)) uprv_decNumberCopyAbs(res, rhs); 1.1366 + else if (decNumberIsZero(rhs)) { 1.1367 + uprv_decNumberZero(res); /* prepare for Infinity */ 1.1368 + res->bits=DECNEG|DECINF; /* -Infinity */ 1.1369 + status|=DEC_Division_by_zero; /* as per 754 */ 1.1370 + } 1.1371 + else { /* finite non-zero */ 1.1372 + Int ae=rhs->exponent+rhs->digits-1; /* adjusted exponent */ 1.1373 + uprv_decNumberFromInt32(res, ae); /* lay it out */ 1.1374 + } 1.1375 + 1.1376 + if (status!=0) decStatus(res, status, set); 1.1377 + return res; 1.1378 + } /* decNumberLogB */ 1.1379 + 1.1380 +/* ------------------------------------------------------------------ */ 1.1381 +/* decNumberLog10 -- logarithm in base 10 */ 1.1382 +/* */ 1.1383 +/* This computes C = log10(A) */ 1.1384 +/* */ 1.1385 +/* res is C, the result. C may be A */ 1.1386 +/* rhs is A */ 1.1387 +/* set is the context; note that rounding mode has no effect */ 1.1388 +/* */ 1.1389 +/* C must have space for set->digits digits. */ 1.1390 +/* */ 1.1391 +/* Notable cases: */ 1.1392 +/* A<0 -> Invalid */ 1.1393 +/* A=0 -> -Infinity (Exact) */ 1.1394 +/* A=+Infinity -> +Infinity (Exact) */ 1.1395 +/* A=10**n (if n is an integer) -> n (Exact) */ 1.1396 +/* */ 1.1397 +/* Mathematical function restrictions apply (see above); a NaN is */ 1.1398 +/* returned with Invalid_operation if a restriction is violated. */ 1.1399 +/* */ 1.1400 +/* An Inexact result is rounded using DEC_ROUND_HALF_EVEN; it will */ 1.1401 +/* almost always be correctly rounded, but may be up to 1 ulp in */ 1.1402 +/* error in rare cases. */ 1.1403 +/* ------------------------------------------------------------------ */ 1.1404 +/* This calculates ln(A)/ln(10) using appropriate precision. For */ 1.1405 +/* ln(A) this is the max(p, rhs->digits + t) + 3, where p is the */ 1.1406 +/* requested digits and t is the number of digits in the exponent */ 1.1407 +/* (maximum 6). For ln(10) it is p + 3; this is often handled by the */ 1.1408 +/* fastpath in decLnOp. The final division is done to the requested */ 1.1409 +/* precision. */ 1.1410 +/* ------------------------------------------------------------------ */ 1.1411 +#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406 1.1412 +#pragma GCC diagnostic push 1.1413 +#pragma GCC diagnostic ignored "-Warray-bounds" 1.1414 +#endif 1.1415 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberLog10(decNumber *res, const decNumber *rhs, 1.1416 + decContext *set) { 1.1417 + uInt status=0, ignore=0; /* status accumulators */ 1.1418 + uInt needbytes; /* for space calculations */ 1.1419 + Int p; /* working precision */ 1.1420 + Int t; /* digits in exponent of A */ 1.1421 + 1.1422 + /* buffers for a and b working decimals */ 1.1423 + /* (adjustment calculator, same size) */ 1.1424 + decNumber bufa[D2N(DECBUFFER+2)]; 1.1425 + decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */ 1.1426 + decNumber *a=bufa; /* temporary a */ 1.1427 + decNumber bufb[D2N(DECBUFFER+2)]; 1.1428 + decNumber *allocbufb=NULL; /* -> allocated bufb, iff allocated */ 1.1429 + decNumber *b=bufb; /* temporary b */ 1.1430 + decNumber bufw[D2N(10)]; /* working 2-10 digit number */ 1.1431 + decNumber *w=bufw; /* .. */ 1.1432 + #if DECSUBSET 1.1433 + decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */ 1.1434 + #endif 1.1435 + 1.1436 + decContext aset; /* working context */ 1.1437 + 1.1438 + #if DECCHECK 1.1439 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.1440 + #endif 1.1441 + 1.1442 + /* Check restrictions; this is a math function; if not violated */ 1.1443 + /* then carry out the operation. */ 1.1444 + if (!decCheckMath(rhs, set, &status)) do { /* protect malloc */ 1.1445 + #if DECSUBSET 1.1446 + if (!set->extended) { 1.1447 + /* reduce operand and set lostDigits status, as needed */ 1.1448 + if (rhs->digits>set->digits) { 1.1449 + allocrhs=decRoundOperand(rhs, set, &status); 1.1450 + if (allocrhs==NULL) break; 1.1451 + rhs=allocrhs; 1.1452 + } 1.1453 + /* special check in subset for rhs=0 */ 1.1454 + if (ISZERO(rhs)) { /* +/- zeros -> error */ 1.1455 + status|=DEC_Invalid_operation; 1.1456 + break;} 1.1457 + } /* extended=0 */ 1.1458 + #endif 1.1459 + 1.1460 + uprv_decContextDefault(&aset, DEC_INIT_DECIMAL64); /* clean context */ 1.1461 + 1.1462 + /* handle exact powers of 10; only check if +ve finite */ 1.1463 + if (!(rhs->bits&(DECNEG|DECSPECIAL)) && !ISZERO(rhs)) { 1.1464 + Int residue=0; /* (no residue) */ 1.1465 + uInt copystat=0; /* clean status */ 1.1466 + 1.1467 + /* round to a single digit... */ 1.1468 + aset.digits=1; 1.1469 + decCopyFit(w, rhs, &aset, &residue, ©stat); /* copy & shorten */ 1.1470 + /* if exact and the digit is 1, rhs is a power of 10 */ 1.1471 + if (!(copystat&DEC_Inexact) && w->lsu[0]==1) { 1.1472 + /* the exponent, conveniently, is the power of 10; making */ 1.1473 + /* this the result needs a little care as it might not fit, */ 1.1474 + /* so first convert it into the working number, and then move */ 1.1475 + /* to res */ 1.1476 + uprv_decNumberFromInt32(w, w->exponent); 1.1477 + residue=0; 1.1478 + decCopyFit(res, w, set, &residue, &status); /* copy & round */ 1.1479 + decFinish(res, set, &residue, &status); /* cleanup/set flags */ 1.1480 + break; 1.1481 + } /* not a power of 10 */ 1.1482 + } /* not a candidate for exact */ 1.1483 + 1.1484 + /* simplify the information-content calculation to use 'total */ 1.1485 + /* number of digits in a, including exponent' as compared to the */ 1.1486 + /* requested digits, as increasing this will only rarely cost an */ 1.1487 + /* iteration in ln(a) anyway */ 1.1488 + t=6; /* it can never be >6 */ 1.1489 + 1.1490 + /* allocate space when needed... */ 1.1491 + p=(rhs->digits+t>set->digits?rhs->digits+t:set->digits)+3; 1.1492 + needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit); 1.1493 + if (needbytes>sizeof(bufa)) { /* need malloc space */ 1.1494 + allocbufa=(decNumber *)malloc(needbytes); 1.1495 + if (allocbufa==NULL) { /* hopeless -- abandon */ 1.1496 + status|=DEC_Insufficient_storage; 1.1497 + break;} 1.1498 + a=allocbufa; /* use the allocated space */ 1.1499 + } 1.1500 + aset.digits=p; /* as calculated */ 1.1501 + aset.emax=DEC_MAX_MATH; /* usual bounds */ 1.1502 + aset.emin=-DEC_MAX_MATH; /* .. */ 1.1503 + aset.clamp=0; /* and no concrete format */ 1.1504 + decLnOp(a, rhs, &aset, &status); /* a=ln(rhs) */ 1.1505 + 1.1506 + /* skip the division if the result so far is infinite, NaN, or */ 1.1507 + /* zero, or there was an error; note NaN from sNaN needs copy */ 1.1508 + if (status&DEC_NaNs && !(status&DEC_sNaN)) break; 1.1509 + if (a->bits&DECSPECIAL || ISZERO(a)) { 1.1510 + uprv_decNumberCopy(res, a); /* [will fit] */ 1.1511 + break;} 1.1512 + 1.1513 + /* for ln(10) an extra 3 digits of precision are needed */ 1.1514 + p=set->digits+3; 1.1515 + needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit); 1.1516 + if (needbytes>sizeof(bufb)) { /* need malloc space */ 1.1517 + allocbufb=(decNumber *)malloc(needbytes); 1.1518 + if (allocbufb==NULL) { /* hopeless -- abandon */ 1.1519 + status|=DEC_Insufficient_storage; 1.1520 + break;} 1.1521 + b=allocbufb; /* use the allocated space */ 1.1522 + } 1.1523 + uprv_decNumberZero(w); /* set up 10... */ 1.1524 + #if DECDPUN==1 1.1525 + w->lsu[1]=1; w->lsu[0]=0; /* .. */ 1.1526 + #else 1.1527 + w->lsu[0]=10; /* .. */ 1.1528 + #endif 1.1529 + w->digits=2; /* .. */ 1.1530 + 1.1531 + aset.digits=p; 1.1532 + decLnOp(b, w, &aset, &ignore); /* b=ln(10) */ 1.1533 + 1.1534 + aset.digits=set->digits; /* for final divide */ 1.1535 + decDivideOp(res, a, b, &aset, DIVIDE, &status); /* into result */ 1.1536 + } while(0); /* [for break] */ 1.1537 + 1.1538 + if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */ 1.1539 + if (allocbufb!=NULL) free(allocbufb); /* .. */ 1.1540 + #if DECSUBSET 1.1541 + if (allocrhs !=NULL) free(allocrhs); /* .. */ 1.1542 + #endif 1.1543 + /* apply significant status */ 1.1544 + if (status!=0) decStatus(res, status, set); 1.1545 + #if DECCHECK 1.1546 + decCheckInexact(res, set); 1.1547 + #endif 1.1548 + return res; 1.1549 + } /* decNumberLog10 */ 1.1550 +#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406 1.1551 +#pragma GCC diagnostic pop 1.1552 +#endif 1.1553 + 1.1554 +/* ------------------------------------------------------------------ */ 1.1555 +/* decNumberMax -- compare two Numbers and return the maximum */ 1.1556 +/* */ 1.1557 +/* This computes C = A ? B, returning the maximum by 754 rules */ 1.1558 +/* */ 1.1559 +/* res is C, the result. C may be A and/or B (e.g., X=X?X) */ 1.1560 +/* lhs is A */ 1.1561 +/* rhs is B */ 1.1562 +/* set is the context */ 1.1563 +/* */ 1.1564 +/* C must have space for set->digits digits. */ 1.1565 +/* ------------------------------------------------------------------ */ 1.1566 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberMax(decNumber *res, const decNumber *lhs, 1.1567 + const decNumber *rhs, decContext *set) { 1.1568 + uInt status=0; /* accumulator */ 1.1569 + decCompareOp(res, lhs, rhs, set, COMPMAX, &status); 1.1570 + if (status!=0) decStatus(res, status, set); 1.1571 + #if DECCHECK 1.1572 + decCheckInexact(res, set); 1.1573 + #endif 1.1574 + return res; 1.1575 + } /* decNumberMax */ 1.1576 + 1.1577 +/* ------------------------------------------------------------------ */ 1.1578 +/* decNumberMaxMag -- compare and return the maximum by magnitude */ 1.1579 +/* */ 1.1580 +/* This computes C = A ? B, returning the maximum by 754 rules */ 1.1581 +/* */ 1.1582 +/* res is C, the result. C may be A and/or B (e.g., X=X?X) */ 1.1583 +/* lhs is A */ 1.1584 +/* rhs is B */ 1.1585 +/* set is the context */ 1.1586 +/* */ 1.1587 +/* C must have space for set->digits digits. */ 1.1588 +/* ------------------------------------------------------------------ */ 1.1589 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberMaxMag(decNumber *res, const decNumber *lhs, 1.1590 + const decNumber *rhs, decContext *set) { 1.1591 + uInt status=0; /* accumulator */ 1.1592 + decCompareOp(res, lhs, rhs, set, COMPMAXMAG, &status); 1.1593 + if (status!=0) decStatus(res, status, set); 1.1594 + #if DECCHECK 1.1595 + decCheckInexact(res, set); 1.1596 + #endif 1.1597 + return res; 1.1598 + } /* decNumberMaxMag */ 1.1599 + 1.1600 +/* ------------------------------------------------------------------ */ 1.1601 +/* decNumberMin -- compare two Numbers and return the minimum */ 1.1602 +/* */ 1.1603 +/* This computes C = A ? B, returning the minimum by 754 rules */ 1.1604 +/* */ 1.1605 +/* res is C, the result. C may be A and/or B (e.g., X=X?X) */ 1.1606 +/* lhs is A */ 1.1607 +/* rhs is B */ 1.1608 +/* set is the context */ 1.1609 +/* */ 1.1610 +/* C must have space for set->digits digits. */ 1.1611 +/* ------------------------------------------------------------------ */ 1.1612 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberMin(decNumber *res, const decNumber *lhs, 1.1613 + const decNumber *rhs, decContext *set) { 1.1614 + uInt status=0; /* accumulator */ 1.1615 + decCompareOp(res, lhs, rhs, set, COMPMIN, &status); 1.1616 + if (status!=0) decStatus(res, status, set); 1.1617 + #if DECCHECK 1.1618 + decCheckInexact(res, set); 1.1619 + #endif 1.1620 + return res; 1.1621 + } /* decNumberMin */ 1.1622 + 1.1623 +/* ------------------------------------------------------------------ */ 1.1624 +/* decNumberMinMag -- compare and return the minimum by magnitude */ 1.1625 +/* */ 1.1626 +/* This computes C = A ? B, returning the minimum by 754 rules */ 1.1627 +/* */ 1.1628 +/* res is C, the result. C may be A and/or B (e.g., X=X?X) */ 1.1629 +/* lhs is A */ 1.1630 +/* rhs is B */ 1.1631 +/* set is the context */ 1.1632 +/* */ 1.1633 +/* C must have space for set->digits digits. */ 1.1634 +/* ------------------------------------------------------------------ */ 1.1635 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberMinMag(decNumber *res, const decNumber *lhs, 1.1636 + const decNumber *rhs, decContext *set) { 1.1637 + uInt status=0; /* accumulator */ 1.1638 + decCompareOp(res, lhs, rhs, set, COMPMINMAG, &status); 1.1639 + if (status!=0) decStatus(res, status, set); 1.1640 + #if DECCHECK 1.1641 + decCheckInexact(res, set); 1.1642 + #endif 1.1643 + return res; 1.1644 + } /* decNumberMinMag */ 1.1645 + 1.1646 +/* ------------------------------------------------------------------ */ 1.1647 +/* decNumberMinus -- prefix minus operator */ 1.1648 +/* */ 1.1649 +/* This computes C = 0 - A */ 1.1650 +/* */ 1.1651 +/* res is C, the result. C may be A */ 1.1652 +/* rhs is A */ 1.1653 +/* set is the context */ 1.1654 +/* */ 1.1655 +/* See also decNumberCopyNegate for a quiet bitwise version of this. */ 1.1656 +/* C must have space for set->digits digits. */ 1.1657 +/* ------------------------------------------------------------------ */ 1.1658 +/* Simply use AddOp for the subtract, which will do the necessary. */ 1.1659 +/* ------------------------------------------------------------------ */ 1.1660 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberMinus(decNumber *res, const decNumber *rhs, 1.1661 + decContext *set) { 1.1662 + decNumber dzero; 1.1663 + uInt status=0; /* accumulator */ 1.1664 + 1.1665 + #if DECCHECK 1.1666 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.1667 + #endif 1.1668 + 1.1669 + uprv_decNumberZero(&dzero); /* make 0 */ 1.1670 + dzero.exponent=rhs->exponent; /* [no coefficient expansion] */ 1.1671 + decAddOp(res, &dzero, rhs, set, DECNEG, &status); 1.1672 + if (status!=0) decStatus(res, status, set); 1.1673 + #if DECCHECK 1.1674 + decCheckInexact(res, set); 1.1675 + #endif 1.1676 + return res; 1.1677 + } /* decNumberMinus */ 1.1678 + 1.1679 +/* ------------------------------------------------------------------ */ 1.1680 +/* decNumberNextMinus -- next towards -Infinity */ 1.1681 +/* */ 1.1682 +/* This computes C = A - infinitesimal, rounded towards -Infinity */ 1.1683 +/* */ 1.1684 +/* res is C, the result. C may be A */ 1.1685 +/* rhs is A */ 1.1686 +/* set is the context */ 1.1687 +/* */ 1.1688 +/* This is a generalization of 754 NextDown. */ 1.1689 +/* ------------------------------------------------------------------ */ 1.1690 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberNextMinus(decNumber *res, const decNumber *rhs, 1.1691 + decContext *set) { 1.1692 + decNumber dtiny; /* constant */ 1.1693 + decContext workset=*set; /* work */ 1.1694 + uInt status=0; /* accumulator */ 1.1695 + #if DECCHECK 1.1696 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.1697 + #endif 1.1698 + 1.1699 + /* +Infinity is the special case */ 1.1700 + if ((rhs->bits&(DECINF|DECNEG))==DECINF) { 1.1701 + decSetMaxValue(res, set); /* is +ve */ 1.1702 + /* there is no status to set */ 1.1703 + return res; 1.1704 + } 1.1705 + uprv_decNumberZero(&dtiny); /* start with 0 */ 1.1706 + dtiny.lsu[0]=1; /* make number that is .. */ 1.1707 + dtiny.exponent=DEC_MIN_EMIN-1; /* .. smaller than tiniest */ 1.1708 + workset.round=DEC_ROUND_FLOOR; 1.1709 + decAddOp(res, rhs, &dtiny, &workset, DECNEG, &status); 1.1710 + status&=DEC_Invalid_operation|DEC_sNaN; /* only sNaN Invalid please */ 1.1711 + if (status!=0) decStatus(res, status, set); 1.1712 + return res; 1.1713 + } /* decNumberNextMinus */ 1.1714 + 1.1715 +/* ------------------------------------------------------------------ */ 1.1716 +/* decNumberNextPlus -- next towards +Infinity */ 1.1717 +/* */ 1.1718 +/* This computes C = A + infinitesimal, rounded towards +Infinity */ 1.1719 +/* */ 1.1720 +/* res is C, the result. C may be A */ 1.1721 +/* rhs is A */ 1.1722 +/* set is the context */ 1.1723 +/* */ 1.1724 +/* This is a generalization of 754 NextUp. */ 1.1725 +/* ------------------------------------------------------------------ */ 1.1726 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberNextPlus(decNumber *res, const decNumber *rhs, 1.1727 + decContext *set) { 1.1728 + decNumber dtiny; /* constant */ 1.1729 + decContext workset=*set; /* work */ 1.1730 + uInt status=0; /* accumulator */ 1.1731 + #if DECCHECK 1.1732 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.1733 + #endif 1.1734 + 1.1735 + /* -Infinity is the special case */ 1.1736 + if ((rhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) { 1.1737 + decSetMaxValue(res, set); 1.1738 + res->bits=DECNEG; /* negative */ 1.1739 + /* there is no status to set */ 1.1740 + return res; 1.1741 + } 1.1742 + uprv_decNumberZero(&dtiny); /* start with 0 */ 1.1743 + dtiny.lsu[0]=1; /* make number that is .. */ 1.1744 + dtiny.exponent=DEC_MIN_EMIN-1; /* .. smaller than tiniest */ 1.1745 + workset.round=DEC_ROUND_CEILING; 1.1746 + decAddOp(res, rhs, &dtiny, &workset, 0, &status); 1.1747 + status&=DEC_Invalid_operation|DEC_sNaN; /* only sNaN Invalid please */ 1.1748 + if (status!=0) decStatus(res, status, set); 1.1749 + return res; 1.1750 + } /* decNumberNextPlus */ 1.1751 + 1.1752 +/* ------------------------------------------------------------------ */ 1.1753 +/* decNumberNextToward -- next towards rhs */ 1.1754 +/* */ 1.1755 +/* This computes C = A +/- infinitesimal, rounded towards */ 1.1756 +/* +/-Infinity in the direction of B, as per 754-1985 nextafter */ 1.1757 +/* modified during revision but dropped from 754-2008. */ 1.1758 +/* */ 1.1759 +/* res is C, the result. C may be A or B. */ 1.1760 +/* lhs is A */ 1.1761 +/* rhs is B */ 1.1762 +/* set is the context */ 1.1763 +/* */ 1.1764 +/* This is a generalization of 754-1985 NextAfter. */ 1.1765 +/* ------------------------------------------------------------------ */ 1.1766 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberNextToward(decNumber *res, const decNumber *lhs, 1.1767 + const decNumber *rhs, decContext *set) { 1.1768 + decNumber dtiny; /* constant */ 1.1769 + decContext workset=*set; /* work */ 1.1770 + Int result; /* .. */ 1.1771 + uInt status=0; /* accumulator */ 1.1772 + #if DECCHECK 1.1773 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.1774 + #endif 1.1775 + 1.1776 + if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) { 1.1777 + decNaNs(res, lhs, rhs, set, &status); 1.1778 + } 1.1779 + else { /* Is numeric, so no chance of sNaN Invalid, etc. */ 1.1780 + result=decCompare(lhs, rhs, 0); /* sign matters */ 1.1781 + if (result==BADINT) status|=DEC_Insufficient_storage; /* rare */ 1.1782 + else { /* valid compare */ 1.1783 + if (result==0) uprv_decNumberCopySign(res, lhs, rhs); /* easy */ 1.1784 + else { /* differ: need NextPlus or NextMinus */ 1.1785 + uByte sub; /* add or subtract */ 1.1786 + if (result<0) { /* lhs<rhs, do nextplus */ 1.1787 + /* -Infinity is the special case */ 1.1788 + if ((lhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) { 1.1789 + decSetMaxValue(res, set); 1.1790 + res->bits=DECNEG; /* negative */ 1.1791 + return res; /* there is no status to set */ 1.1792 + } 1.1793 + workset.round=DEC_ROUND_CEILING; 1.1794 + sub=0; /* add, please */ 1.1795 + } /* plus */ 1.1796 + else { /* lhs>rhs, do nextminus */ 1.1797 + /* +Infinity is the special case */ 1.1798 + if ((lhs->bits&(DECINF|DECNEG))==DECINF) { 1.1799 + decSetMaxValue(res, set); 1.1800 + return res; /* there is no status to set */ 1.1801 + } 1.1802 + workset.round=DEC_ROUND_FLOOR; 1.1803 + sub=DECNEG; /* subtract, please */ 1.1804 + } /* minus */ 1.1805 + uprv_decNumberZero(&dtiny); /* start with 0 */ 1.1806 + dtiny.lsu[0]=1; /* make number that is .. */ 1.1807 + dtiny.exponent=DEC_MIN_EMIN-1; /* .. smaller than tiniest */ 1.1808 + decAddOp(res, lhs, &dtiny, &workset, sub, &status); /* + or - */ 1.1809 + /* turn off exceptions if the result is a normal number */ 1.1810 + /* (including Nmin), otherwise let all status through */ 1.1811 + if (uprv_decNumberIsNormal(res, set)) status=0; 1.1812 + } /* unequal */ 1.1813 + } /* compare OK */ 1.1814 + } /* numeric */ 1.1815 + if (status!=0) decStatus(res, status, set); 1.1816 + return res; 1.1817 + } /* decNumberNextToward */ 1.1818 + 1.1819 +/* ------------------------------------------------------------------ */ 1.1820 +/* decNumberOr -- OR two Numbers, digitwise */ 1.1821 +/* */ 1.1822 +/* This computes C = A | B */ 1.1823 +/* */ 1.1824 +/* res is C, the result. C may be A and/or B (e.g., X=X|X) */ 1.1825 +/* lhs is A */ 1.1826 +/* rhs is B */ 1.1827 +/* set is the context (used for result length and error report) */ 1.1828 +/* */ 1.1829 +/* C must have space for set->digits digits. */ 1.1830 +/* */ 1.1831 +/* Logical function restrictions apply (see above); a NaN is */ 1.1832 +/* returned with Invalid_operation if a restriction is violated. */ 1.1833 +/* ------------------------------------------------------------------ */ 1.1834 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberOr(decNumber *res, const decNumber *lhs, 1.1835 + const decNumber *rhs, decContext *set) { 1.1836 + const Unit *ua, *ub; /* -> operands */ 1.1837 + const Unit *msua, *msub; /* -> operand msus */ 1.1838 + Unit *uc, *msuc; /* -> result and its msu */ 1.1839 + Int msudigs; /* digits in res msu */ 1.1840 + #if DECCHECK 1.1841 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.1842 + #endif 1.1843 + 1.1844 + if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs) 1.1845 + || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) { 1.1846 + decStatus(res, DEC_Invalid_operation, set); 1.1847 + return res; 1.1848 + } 1.1849 + /* operands are valid */ 1.1850 + ua=lhs->lsu; /* bottom-up */ 1.1851 + ub=rhs->lsu; /* .. */ 1.1852 + uc=res->lsu; /* .. */ 1.1853 + msua=ua+D2U(lhs->digits)-1; /* -> msu of lhs */ 1.1854 + msub=ub+D2U(rhs->digits)-1; /* -> msu of rhs */ 1.1855 + msuc=uc+D2U(set->digits)-1; /* -> msu of result */ 1.1856 + msudigs=MSUDIGITS(set->digits); /* [faster than remainder] */ 1.1857 + for (; uc<=msuc; ua++, ub++, uc++) { /* Unit loop */ 1.1858 + Unit a, b; /* extract units */ 1.1859 + if (ua>msua) a=0; 1.1860 + else a=*ua; 1.1861 + if (ub>msub) b=0; 1.1862 + else b=*ub; 1.1863 + *uc=0; /* can now write back */ 1.1864 + if (a|b) { /* maybe 1 bits to examine */ 1.1865 + Int i, j; 1.1866 + /* This loop could be unrolled and/or use BIN2BCD tables */ 1.1867 + for (i=0; i<DECDPUN; i++) { 1.1868 + if ((a|b)&1) *uc=*uc+(Unit)powers[i]; /* effect OR */ 1.1869 + j=a%10; 1.1870 + a=a/10; 1.1871 + j|=b%10; 1.1872 + b=b/10; 1.1873 + if (j>1) { 1.1874 + decStatus(res, DEC_Invalid_operation, set); 1.1875 + return res; 1.1876 + } 1.1877 + if (uc==msuc && i==msudigs-1) break; /* just did final digit */ 1.1878 + } /* each digit */ 1.1879 + } /* non-zero */ 1.1880 + } /* each unit */ 1.1881 + /* [here uc-1 is the msu of the result] */ 1.1882 + res->digits=decGetDigits(res->lsu, uc-res->lsu); 1.1883 + res->exponent=0; /* integer */ 1.1884 + res->bits=0; /* sign=0 */ 1.1885 + return res; /* [no status to set] */ 1.1886 + } /* decNumberOr */ 1.1887 + 1.1888 +/* ------------------------------------------------------------------ */ 1.1889 +/* decNumberPlus -- prefix plus operator */ 1.1890 +/* */ 1.1891 +/* This computes C = 0 + A */ 1.1892 +/* */ 1.1893 +/* res is C, the result. C may be A */ 1.1894 +/* rhs is A */ 1.1895 +/* set is the context */ 1.1896 +/* */ 1.1897 +/* See also decNumberCopy for a quiet bitwise version of this. */ 1.1898 +/* C must have space for set->digits digits. */ 1.1899 +/* ------------------------------------------------------------------ */ 1.1900 +/* This simply uses AddOp; Add will take fast path after preparing A. */ 1.1901 +/* Performance is a concern here, as this routine is often used to */ 1.1902 +/* check operands and apply rounding and overflow/underflow testing. */ 1.1903 +/* ------------------------------------------------------------------ */ 1.1904 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberPlus(decNumber *res, const decNumber *rhs, 1.1905 + decContext *set) { 1.1906 + decNumber dzero; 1.1907 + uInt status=0; /* accumulator */ 1.1908 + #if DECCHECK 1.1909 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.1910 + #endif 1.1911 + 1.1912 + uprv_decNumberZero(&dzero); /* make 0 */ 1.1913 + dzero.exponent=rhs->exponent; /* [no coefficient expansion] */ 1.1914 + decAddOp(res, &dzero, rhs, set, 0, &status); 1.1915 + if (status!=0) decStatus(res, status, set); 1.1916 + #if DECCHECK 1.1917 + decCheckInexact(res, set); 1.1918 + #endif 1.1919 + return res; 1.1920 + } /* decNumberPlus */ 1.1921 + 1.1922 +/* ------------------------------------------------------------------ */ 1.1923 +/* decNumberMultiply -- multiply two Numbers */ 1.1924 +/* */ 1.1925 +/* This computes C = A x B */ 1.1926 +/* */ 1.1927 +/* res is C, the result. C may be A and/or B (e.g., X=X+X) */ 1.1928 +/* lhs is A */ 1.1929 +/* rhs is B */ 1.1930 +/* set is the context */ 1.1931 +/* */ 1.1932 +/* C must have space for set->digits digits. */ 1.1933 +/* ------------------------------------------------------------------ */ 1.1934 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberMultiply(decNumber *res, const decNumber *lhs, 1.1935 + const decNumber *rhs, decContext *set) { 1.1936 + uInt status=0; /* accumulator */ 1.1937 + decMultiplyOp(res, lhs, rhs, set, &status); 1.1938 + if (status!=0) decStatus(res, status, set); 1.1939 + #if DECCHECK 1.1940 + decCheckInexact(res, set); 1.1941 + #endif 1.1942 + return res; 1.1943 + } /* decNumberMultiply */ 1.1944 + 1.1945 +/* ------------------------------------------------------------------ */ 1.1946 +/* decNumberPower -- raise a number to a power */ 1.1947 +/* */ 1.1948 +/* This computes C = A ** B */ 1.1949 +/* */ 1.1950 +/* res is C, the result. C may be A and/or B (e.g., X=X**X) */ 1.1951 +/* lhs is A */ 1.1952 +/* rhs is B */ 1.1953 +/* set is the context */ 1.1954 +/* */ 1.1955 +/* C must have space for set->digits digits. */ 1.1956 +/* */ 1.1957 +/* Mathematical function restrictions apply (see above); a NaN is */ 1.1958 +/* returned with Invalid_operation if a restriction is violated. */ 1.1959 +/* */ 1.1960 +/* However, if 1999999997<=B<=999999999 and B is an integer then the */ 1.1961 +/* restrictions on A and the context are relaxed to the usual bounds, */ 1.1962 +/* for compatibility with the earlier (integer power only) version */ 1.1963 +/* of this function. */ 1.1964 +/* */ 1.1965 +/* When B is an integer, the result may be exact, even if rounded. */ 1.1966 +/* */ 1.1967 +/* The final result is rounded according to the context; it will */ 1.1968 +/* almost always be correctly rounded, but may be up to 1 ulp in */ 1.1969 +/* error in rare cases. */ 1.1970 +/* ------------------------------------------------------------------ */ 1.1971 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberPower(decNumber *res, const decNumber *lhs, 1.1972 + const decNumber *rhs, decContext *set) { 1.1973 + #if DECSUBSET 1.1974 + decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */ 1.1975 + decNumber *allocrhs=NULL; /* .., rhs */ 1.1976 + #endif 1.1977 + decNumber *allocdac=NULL; /* -> allocated acc buffer, iff used */ 1.1978 + decNumber *allocinv=NULL; /* -> allocated 1/x buffer, iff used */ 1.1979 + Int reqdigits=set->digits; /* requested DIGITS */ 1.1980 + Int n; /* rhs in binary */ 1.1981 + Flag rhsint=0; /* 1 if rhs is an integer */ 1.1982 + Flag useint=0; /* 1 if can use integer calculation */ 1.1983 + Flag isoddint=0; /* 1 if rhs is an integer and odd */ 1.1984 + Int i; /* work */ 1.1985 + #if DECSUBSET 1.1986 + Int dropped; /* .. */ 1.1987 + #endif 1.1988 + uInt needbytes; /* buffer size needed */ 1.1989 + Flag seenbit; /* seen a bit while powering */ 1.1990 + Int residue=0; /* rounding residue */ 1.1991 + uInt status=0; /* accumulators */ 1.1992 + uByte bits=0; /* result sign if errors */ 1.1993 + decContext aset; /* working context */ 1.1994 + decNumber dnOne; /* work value 1... */ 1.1995 + /* local accumulator buffer [a decNumber, with digits+elength+1 digits] */ 1.1996 + decNumber dacbuff[D2N(DECBUFFER+9)]; 1.1997 + decNumber *dac=dacbuff; /* -> result accumulator */ 1.1998 + /* same again for possible 1/lhs calculation */ 1.1999 + decNumber invbuff[D2N(DECBUFFER+9)]; 1.2000 + 1.2001 + #if DECCHECK 1.2002 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.2003 + #endif 1.2004 + 1.2005 + do { /* protect allocated storage */ 1.2006 + #if DECSUBSET 1.2007 + if (!set->extended) { /* reduce operands and set status, as needed */ 1.2008 + if (lhs->digits>reqdigits) { 1.2009 + alloclhs=decRoundOperand(lhs, set, &status); 1.2010 + if (alloclhs==NULL) break; 1.2011 + lhs=alloclhs; 1.2012 + } 1.2013 + if (rhs->digits>reqdigits) { 1.2014 + allocrhs=decRoundOperand(rhs, set, &status); 1.2015 + if (allocrhs==NULL) break; 1.2016 + rhs=allocrhs; 1.2017 + } 1.2018 + } 1.2019 + #endif 1.2020 + /* [following code does not require input rounding] */ 1.2021 + 1.2022 + /* handle NaNs and rhs Infinity (lhs infinity is harder) */ 1.2023 + if (SPECIALARGS) { 1.2024 + if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) { /* NaNs */ 1.2025 + decNaNs(res, lhs, rhs, set, &status); 1.2026 + break;} 1.2027 + if (decNumberIsInfinite(rhs)) { /* rhs Infinity */ 1.2028 + Flag rhsneg=rhs->bits&DECNEG; /* save rhs sign */ 1.2029 + if (decNumberIsNegative(lhs) /* lhs<0 */ 1.2030 + && !decNumberIsZero(lhs)) /* .. */ 1.2031 + status|=DEC_Invalid_operation; 1.2032 + else { /* lhs >=0 */ 1.2033 + uprv_decNumberZero(&dnOne); /* set up 1 */ 1.2034 + dnOne.lsu[0]=1; 1.2035 + uprv_decNumberCompare(dac, lhs, &dnOne, set); /* lhs ? 1 */ 1.2036 + uprv_decNumberZero(res); /* prepare for 0/1/Infinity */ 1.2037 + if (decNumberIsNegative(dac)) { /* lhs<1 */ 1.2038 + if (rhsneg) res->bits|=DECINF; /* +Infinity [else is +0] */ 1.2039 + } 1.2040 + else if (dac->lsu[0]==0) { /* lhs=1 */ 1.2041 + /* 1**Infinity is inexact, so return fully-padded 1.0000 */ 1.2042 + Int shift=set->digits-1; 1.2043 + *res->lsu=1; /* was 0, make int 1 */ 1.2044 + res->digits=decShiftToMost(res->lsu, 1, shift); 1.2045 + res->exponent=-shift; /* make 1.0000... */ 1.2046 + status|=DEC_Inexact|DEC_Rounded; /* deemed inexact */ 1.2047 + } 1.2048 + else { /* lhs>1 */ 1.2049 + if (!rhsneg) res->bits|=DECINF; /* +Infinity [else is +0] */ 1.2050 + } 1.2051 + } /* lhs>=0 */ 1.2052 + break;} 1.2053 + /* [lhs infinity drops through] */ 1.2054 + } /* specials */ 1.2055 + 1.2056 + /* Original rhs may be an integer that fits and is in range */ 1.2057 + n=decGetInt(rhs); 1.2058 + if (n!=BADINT) { /* it is an integer */ 1.2059 + rhsint=1; /* record the fact for 1**n */ 1.2060 + isoddint=(Flag)n&1; /* [works even if big] */ 1.2061 + if (n!=BIGEVEN && n!=BIGODD) /* can use integer path? */ 1.2062 + useint=1; /* looks good */ 1.2063 + } 1.2064 + 1.2065 + if (decNumberIsNegative(lhs) /* -x .. */ 1.2066 + && isoddint) bits=DECNEG; /* .. to an odd power */ 1.2067 + 1.2068 + /* handle LHS infinity */ 1.2069 + if (decNumberIsInfinite(lhs)) { /* [NaNs already handled] */ 1.2070 + uByte rbits=rhs->bits; /* save */ 1.2071 + uprv_decNumberZero(res); /* prepare */ 1.2072 + if (n==0) *res->lsu=1; /* [-]Inf**0 => 1 */ 1.2073 + else { 1.2074 + /* -Inf**nonint -> error */ 1.2075 + if (!rhsint && decNumberIsNegative(lhs)) { 1.2076 + status|=DEC_Invalid_operation; /* -Inf**nonint is error */ 1.2077 + break;} 1.2078 + if (!(rbits & DECNEG)) bits|=DECINF; /* was not a **-n */ 1.2079 + /* [otherwise will be 0 or -0] */ 1.2080 + res->bits=bits; 1.2081 + } 1.2082 + break;} 1.2083 + 1.2084 + /* similarly handle LHS zero */ 1.2085 + if (decNumberIsZero(lhs)) { 1.2086 + if (n==0) { /* 0**0 => Error */ 1.2087 + #if DECSUBSET 1.2088 + if (!set->extended) { /* [unless subset] */ 1.2089 + uprv_decNumberZero(res); 1.2090 + *res->lsu=1; /* return 1 */ 1.2091 + break;} 1.2092 + #endif 1.2093 + status|=DEC_Invalid_operation; 1.2094 + } 1.2095 + else { /* 0**x */ 1.2096 + uByte rbits=rhs->bits; /* save */ 1.2097 + if (rbits & DECNEG) { /* was a 0**(-n) */ 1.2098 + #if DECSUBSET 1.2099 + if (!set->extended) { /* [bad if subset] */ 1.2100 + status|=DEC_Invalid_operation; 1.2101 + break;} 1.2102 + #endif 1.2103 + bits|=DECINF; 1.2104 + } 1.2105 + uprv_decNumberZero(res); /* prepare */ 1.2106 + /* [otherwise will be 0 or -0] */ 1.2107 + res->bits=bits; 1.2108 + } 1.2109 + break;} 1.2110 + 1.2111 + /* here both lhs and rhs are finite; rhs==0 is handled in the */ 1.2112 + /* integer path. Next handle the non-integer cases */ 1.2113 + if (!useint) { /* non-integral rhs */ 1.2114 + /* any -ve lhs is bad, as is either operand or context out of */ 1.2115 + /* bounds */ 1.2116 + if (decNumberIsNegative(lhs)) { 1.2117 + status|=DEC_Invalid_operation; 1.2118 + break;} 1.2119 + if (decCheckMath(lhs, set, &status) 1.2120 + || decCheckMath(rhs, set, &status)) break; /* variable status */ 1.2121 + 1.2122 + uprv_decContextDefault(&aset, DEC_INIT_DECIMAL64); /* clean context */ 1.2123 + aset.emax=DEC_MAX_MATH; /* usual bounds */ 1.2124 + aset.emin=-DEC_MAX_MATH; /* .. */ 1.2125 + aset.clamp=0; /* and no concrete format */ 1.2126 + 1.2127 + /* calculate the result using exp(ln(lhs)*rhs), which can */ 1.2128 + /* all be done into the accumulator, dac. The precision needed */ 1.2129 + /* is enough to contain the full information in the lhs (which */ 1.2130 + /* is the total digits, including exponent), or the requested */ 1.2131 + /* precision, if larger, + 4; 6 is used for the exponent */ 1.2132 + /* maximum length, and this is also used when it is shorter */ 1.2133 + /* than the requested digits as it greatly reduces the >0.5 ulp */ 1.2134 + /* cases at little cost (because Ln doubles digits each */ 1.2135 + /* iteration so a few extra digits rarely causes an extra */ 1.2136 + /* iteration) */ 1.2137 + aset.digits=MAXI(lhs->digits, set->digits)+6+4; 1.2138 + } /* non-integer rhs */ 1.2139 + 1.2140 + else { /* rhs is in-range integer */ 1.2141 + if (n==0) { /* x**0 = 1 */ 1.2142 + /* (0**0 was handled above) */ 1.2143 + uprv_decNumberZero(res); /* result=1 */ 1.2144 + *res->lsu=1; /* .. */ 1.2145 + break;} 1.2146 + /* rhs is a non-zero integer */ 1.2147 + if (n<0) n=-n; /* use abs(n) */ 1.2148 + 1.2149 + aset=*set; /* clone the context */ 1.2150 + aset.round=DEC_ROUND_HALF_EVEN; /* internally use balanced */ 1.2151 + /* calculate the working DIGITS */ 1.2152 + aset.digits=reqdigits+(rhs->digits+rhs->exponent)+2; 1.2153 + #if DECSUBSET 1.2154 + if (!set->extended) aset.digits--; /* use classic precision */ 1.2155 + #endif 1.2156 + /* it's an error if this is more than can be handled */ 1.2157 + if (aset.digits>DECNUMMAXP) {status|=DEC_Invalid_operation; break;} 1.2158 + } /* integer path */ 1.2159 + 1.2160 + /* aset.digits is the count of digits for the accumulator needed */ 1.2161 + /* if accumulator is too long for local storage, then allocate */ 1.2162 + needbytes=sizeof(decNumber)+(D2U(aset.digits)-1)*sizeof(Unit); 1.2163 + /* [needbytes also used below if 1/lhs needed] */ 1.2164 + if (needbytes>sizeof(dacbuff)) { 1.2165 + allocdac=(decNumber *)malloc(needbytes); 1.2166 + if (allocdac==NULL) { /* hopeless -- abandon */ 1.2167 + status|=DEC_Insufficient_storage; 1.2168 + break;} 1.2169 + dac=allocdac; /* use the allocated space */ 1.2170 + } 1.2171 + /* here, aset is set up and accumulator is ready for use */ 1.2172 + 1.2173 + if (!useint) { /* non-integral rhs */ 1.2174 + /* x ** y; special-case x=1 here as it will otherwise always */ 1.2175 + /* reduce to integer 1; decLnOp has a fastpath which detects */ 1.2176 + /* the case of x=1 */ 1.2177 + decLnOp(dac, lhs, &aset, &status); /* dac=ln(lhs) */ 1.2178 + /* [no error possible, as lhs 0 already handled] */ 1.2179 + if (ISZERO(dac)) { /* x==1, 1.0, etc. */ 1.2180 + /* need to return fully-padded 1.0000 etc., but rhsint->1 */ 1.2181 + *dac->lsu=1; /* was 0, make int 1 */ 1.2182 + if (!rhsint) { /* add padding */ 1.2183 + Int shift=set->digits-1; 1.2184 + dac->digits=decShiftToMost(dac->lsu, 1, shift); 1.2185 + dac->exponent=-shift; /* make 1.0000... */ 1.2186 + status|=DEC_Inexact|DEC_Rounded; /* deemed inexact */ 1.2187 + } 1.2188 + } 1.2189 + else { 1.2190 + decMultiplyOp(dac, dac, rhs, &aset, &status); /* dac=dac*rhs */ 1.2191 + decExpOp(dac, dac, &aset, &status); /* dac=exp(dac) */ 1.2192 + } 1.2193 + /* and drop through for final rounding */ 1.2194 + } /* non-integer rhs */ 1.2195 + 1.2196 + else { /* carry on with integer */ 1.2197 + uprv_decNumberZero(dac); /* acc=1 */ 1.2198 + *dac->lsu=1; /* .. */ 1.2199 + 1.2200 + /* if a negative power the constant 1 is needed, and if not subset */ 1.2201 + /* invert the lhs now rather than inverting the result later */ 1.2202 + if (decNumberIsNegative(rhs)) { /* was a **-n [hence digits>0] */ 1.2203 + decNumber *inv=invbuff; /* asssume use fixed buffer */ 1.2204 + uprv_decNumberCopy(&dnOne, dac); /* dnOne=1; [needed now or later] */ 1.2205 + #if DECSUBSET 1.2206 + if (set->extended) { /* need to calculate 1/lhs */ 1.2207 + #endif 1.2208 + /* divide lhs into 1, putting result in dac [dac=1/dac] */ 1.2209 + decDivideOp(dac, &dnOne, lhs, &aset, DIVIDE, &status); 1.2210 + /* now locate or allocate space for the inverted lhs */ 1.2211 + if (needbytes>sizeof(invbuff)) { 1.2212 + allocinv=(decNumber *)malloc(needbytes); 1.2213 + if (allocinv==NULL) { /* hopeless -- abandon */ 1.2214 + status|=DEC_Insufficient_storage; 1.2215 + break;} 1.2216 + inv=allocinv; /* use the allocated space */ 1.2217 + } 1.2218 + /* [inv now points to big-enough buffer or allocated storage] */ 1.2219 + uprv_decNumberCopy(inv, dac); /* copy the 1/lhs */ 1.2220 + uprv_decNumberCopy(dac, &dnOne); /* restore acc=1 */ 1.2221 + lhs=inv; /* .. and go forward with new lhs */ 1.2222 + #if DECSUBSET 1.2223 + } 1.2224 + #endif 1.2225 + } 1.2226 + 1.2227 + /* Raise-to-the-power loop... */ 1.2228 + seenbit=0; /* set once a 1-bit is encountered */ 1.2229 + for (i=1;;i++){ /* for each bit [top bit ignored] */ 1.2230 + /* abandon if had overflow or terminal underflow */ 1.2231 + if (status & (DEC_Overflow|DEC_Underflow)) { /* interesting? */ 1.2232 + if (status&DEC_Overflow || ISZERO(dac)) break; 1.2233 + } 1.2234 + /* [the following two lines revealed an optimizer bug in a C++ */ 1.2235 + /* compiler, with symptom: 5**3 -> 25, when n=n+n was used] */ 1.2236 + n=n<<1; /* move next bit to testable position */ 1.2237 + if (n<0) { /* top bit is set */ 1.2238 + seenbit=1; /* OK, significant bit seen */ 1.2239 + decMultiplyOp(dac, dac, lhs, &aset, &status); /* dac=dac*x */ 1.2240 + } 1.2241 + if (i==31) break; /* that was the last bit */ 1.2242 + if (!seenbit) continue; /* no need to square 1 */ 1.2243 + decMultiplyOp(dac, dac, dac, &aset, &status); /* dac=dac*dac [square] */ 1.2244 + } /*i*/ /* 32 bits */ 1.2245 + 1.2246 + /* complete internal overflow or underflow processing */ 1.2247 + if (status & (DEC_Overflow|DEC_Underflow)) { 1.2248 + #if DECSUBSET 1.2249 + /* If subset, and power was negative, reverse the kind of -erflow */ 1.2250 + /* [1/x not yet done] */ 1.2251 + if (!set->extended && decNumberIsNegative(rhs)) { 1.2252 + if (status & DEC_Overflow) 1.2253 + status^=DEC_Overflow | DEC_Underflow | DEC_Subnormal; 1.2254 + else { /* trickier -- Underflow may or may not be set */ 1.2255 + status&=~(DEC_Underflow | DEC_Subnormal); /* [one or both] */ 1.2256 + status|=DEC_Overflow; 1.2257 + } 1.2258 + } 1.2259 + #endif 1.2260 + dac->bits=(dac->bits & ~DECNEG) | bits; /* force correct sign */ 1.2261 + /* round subnormals [to set.digits rather than aset.digits] */ 1.2262 + /* or set overflow result similarly as required */ 1.2263 + decFinalize(dac, set, &residue, &status); 1.2264 + uprv_decNumberCopy(res, dac); /* copy to result (is now OK length) */ 1.2265 + break; 1.2266 + } 1.2267 + 1.2268 + #if DECSUBSET 1.2269 + if (!set->extended && /* subset math */ 1.2270 + decNumberIsNegative(rhs)) { /* was a **-n [hence digits>0] */ 1.2271 + /* so divide result into 1 [dac=1/dac] */ 1.2272 + decDivideOp(dac, &dnOne, dac, &aset, DIVIDE, &status); 1.2273 + } 1.2274 + #endif 1.2275 + } /* rhs integer path */ 1.2276 + 1.2277 + /* reduce result to the requested length and copy to result */ 1.2278 + decCopyFit(res, dac, set, &residue, &status); 1.2279 + decFinish(res, set, &residue, &status); /* final cleanup */ 1.2280 + #if DECSUBSET 1.2281 + if (!set->extended) decTrim(res, set, 0, 1, &dropped); /* trailing zeros */ 1.2282 + #endif 1.2283 + } while(0); /* end protected */ 1.2284 + 1.2285 + if (allocdac!=NULL) free(allocdac); /* drop any storage used */ 1.2286 + if (allocinv!=NULL) free(allocinv); /* .. */ 1.2287 + #if DECSUBSET 1.2288 + if (alloclhs!=NULL) free(alloclhs); /* .. */ 1.2289 + if (allocrhs!=NULL) free(allocrhs); /* .. */ 1.2290 + #endif 1.2291 + if (status!=0) decStatus(res, status, set); 1.2292 + #if DECCHECK 1.2293 + decCheckInexact(res, set); 1.2294 + #endif 1.2295 + return res; 1.2296 + } /* decNumberPower */ 1.2297 + 1.2298 +/* ------------------------------------------------------------------ */ 1.2299 +/* decNumberQuantize -- force exponent to requested value */ 1.2300 +/* */ 1.2301 +/* This computes C = op(A, B), where op adjusts the coefficient */ 1.2302 +/* of C (by rounding or shifting) such that the exponent (-scale) */ 1.2303 +/* of C has exponent of B. The numerical value of C will equal A, */ 1.2304 +/* except for the effects of any rounding that occurred. */ 1.2305 +/* */ 1.2306 +/* res is C, the result. C may be A or B */ 1.2307 +/* lhs is A, the number to adjust */ 1.2308 +/* rhs is B, the number with exponent to match */ 1.2309 +/* set is the context */ 1.2310 +/* */ 1.2311 +/* C must have space for set->digits digits. */ 1.2312 +/* */ 1.2313 +/* Unless there is an error or the result is infinite, the exponent */ 1.2314 +/* after the operation is guaranteed to be equal to that of B. */ 1.2315 +/* ------------------------------------------------------------------ */ 1.2316 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberQuantize(decNumber *res, const decNumber *lhs, 1.2317 + const decNumber *rhs, decContext *set) { 1.2318 + uInt status=0; /* accumulator */ 1.2319 + decQuantizeOp(res, lhs, rhs, set, 1, &status); 1.2320 + if (status!=0) decStatus(res, status, set); 1.2321 + return res; 1.2322 + } /* decNumberQuantize */ 1.2323 + 1.2324 +/* ------------------------------------------------------------------ */ 1.2325 +/* decNumberReduce -- remove trailing zeros */ 1.2326 +/* */ 1.2327 +/* This computes C = 0 + A, and normalizes the result */ 1.2328 +/* */ 1.2329 +/* res is C, the result. C may be A */ 1.2330 +/* rhs is A */ 1.2331 +/* set is the context */ 1.2332 +/* */ 1.2333 +/* C must have space for set->digits digits. */ 1.2334 +/* ------------------------------------------------------------------ */ 1.2335 +/* Previously known as Normalize */ 1.2336 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberNormalize(decNumber *res, const decNumber *rhs, 1.2337 + decContext *set) { 1.2338 + return uprv_decNumberReduce(res, rhs, set); 1.2339 + } /* decNumberNormalize */ 1.2340 + 1.2341 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberReduce(decNumber *res, const decNumber *rhs, 1.2342 + decContext *set) { 1.2343 + #if DECSUBSET 1.2344 + decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */ 1.2345 + #endif 1.2346 + uInt status=0; /* as usual */ 1.2347 + Int residue=0; /* as usual */ 1.2348 + Int dropped; /* work */ 1.2349 + 1.2350 + #if DECCHECK 1.2351 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.2352 + #endif 1.2353 + 1.2354 + do { /* protect allocated storage */ 1.2355 + #if DECSUBSET 1.2356 + if (!set->extended) { 1.2357 + /* reduce operand and set lostDigits status, as needed */ 1.2358 + if (rhs->digits>set->digits) { 1.2359 + allocrhs=decRoundOperand(rhs, set, &status); 1.2360 + if (allocrhs==NULL) break; 1.2361 + rhs=allocrhs; 1.2362 + } 1.2363 + } 1.2364 + #endif 1.2365 + /* [following code does not require input rounding] */ 1.2366 + 1.2367 + /* Infinities copy through; NaNs need usual treatment */ 1.2368 + if (decNumberIsNaN(rhs)) { 1.2369 + decNaNs(res, rhs, NULL, set, &status); 1.2370 + break; 1.2371 + } 1.2372 + 1.2373 + /* reduce result to the requested length and copy to result */ 1.2374 + decCopyFit(res, rhs, set, &residue, &status); /* copy & round */ 1.2375 + decFinish(res, set, &residue, &status); /* cleanup/set flags */ 1.2376 + decTrim(res, set, 1, 0, &dropped); /* normalize in place */ 1.2377 + /* [may clamp] */ 1.2378 + } while(0); /* end protected */ 1.2379 + 1.2380 + #if DECSUBSET 1.2381 + if (allocrhs !=NULL) free(allocrhs); /* .. */ 1.2382 + #endif 1.2383 + if (status!=0) decStatus(res, status, set);/* then report status */ 1.2384 + return res; 1.2385 + } /* decNumberReduce */ 1.2386 + 1.2387 +/* ------------------------------------------------------------------ */ 1.2388 +/* decNumberRescale -- force exponent to requested value */ 1.2389 +/* */ 1.2390 +/* This computes C = op(A, B), where op adjusts the coefficient */ 1.2391 +/* of C (by rounding or shifting) such that the exponent (-scale) */ 1.2392 +/* of C has the value B. The numerical value of C will equal A, */ 1.2393 +/* except for the effects of any rounding that occurred. */ 1.2394 +/* */ 1.2395 +/* res is C, the result. C may be A or B */ 1.2396 +/* lhs is A, the number to adjust */ 1.2397 +/* rhs is B, the requested exponent */ 1.2398 +/* set is the context */ 1.2399 +/* */ 1.2400 +/* C must have space for set->digits digits. */ 1.2401 +/* */ 1.2402 +/* Unless there is an error or the result is infinite, the exponent */ 1.2403 +/* after the operation is guaranteed to be equal to B. */ 1.2404 +/* ------------------------------------------------------------------ */ 1.2405 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberRescale(decNumber *res, const decNumber *lhs, 1.2406 + const decNumber *rhs, decContext *set) { 1.2407 + uInt status=0; /* accumulator */ 1.2408 + decQuantizeOp(res, lhs, rhs, set, 0, &status); 1.2409 + if (status!=0) decStatus(res, status, set); 1.2410 + return res; 1.2411 + } /* decNumberRescale */ 1.2412 + 1.2413 +/* ------------------------------------------------------------------ */ 1.2414 +/* decNumberRemainder -- divide and return remainder */ 1.2415 +/* */ 1.2416 +/* This computes C = A % B */ 1.2417 +/* */ 1.2418 +/* res is C, the result. C may be A and/or B (e.g., X=X%X) */ 1.2419 +/* lhs is A */ 1.2420 +/* rhs is B */ 1.2421 +/* set is the context */ 1.2422 +/* */ 1.2423 +/* C must have space for set->digits digits. */ 1.2424 +/* ------------------------------------------------------------------ */ 1.2425 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberRemainder(decNumber *res, const decNumber *lhs, 1.2426 + const decNumber *rhs, decContext *set) { 1.2427 + uInt status=0; /* accumulator */ 1.2428 + decDivideOp(res, lhs, rhs, set, REMAINDER, &status); 1.2429 + if (status!=0) decStatus(res, status, set); 1.2430 + #if DECCHECK 1.2431 + decCheckInexact(res, set); 1.2432 + #endif 1.2433 + return res; 1.2434 + } /* decNumberRemainder */ 1.2435 + 1.2436 +/* ------------------------------------------------------------------ */ 1.2437 +/* decNumberRemainderNear -- divide and return remainder from nearest */ 1.2438 +/* */ 1.2439 +/* This computes C = A % B, where % is the IEEE remainder operator */ 1.2440 +/* */ 1.2441 +/* res is C, the result. C may be A and/or B (e.g., X=X%X) */ 1.2442 +/* lhs is A */ 1.2443 +/* rhs is B */ 1.2444 +/* set is the context */ 1.2445 +/* */ 1.2446 +/* C must have space for set->digits digits. */ 1.2447 +/* ------------------------------------------------------------------ */ 1.2448 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberRemainderNear(decNumber *res, const decNumber *lhs, 1.2449 + const decNumber *rhs, decContext *set) { 1.2450 + uInt status=0; /* accumulator */ 1.2451 + decDivideOp(res, lhs, rhs, set, REMNEAR, &status); 1.2452 + if (status!=0) decStatus(res, status, set); 1.2453 + #if DECCHECK 1.2454 + decCheckInexact(res, set); 1.2455 + #endif 1.2456 + return res; 1.2457 + } /* decNumberRemainderNear */ 1.2458 + 1.2459 +/* ------------------------------------------------------------------ */ 1.2460 +/* decNumberRotate -- rotate the coefficient of a Number left/right */ 1.2461 +/* */ 1.2462 +/* This computes C = A rot B (in base ten and rotating set->digits */ 1.2463 +/* digits). */ 1.2464 +/* */ 1.2465 +/* res is C, the result. C may be A and/or B (e.g., X=XrotX) */ 1.2466 +/* lhs is A */ 1.2467 +/* rhs is B, the number of digits to rotate (-ve to right) */ 1.2468 +/* set is the context */ 1.2469 +/* */ 1.2470 +/* The digits of the coefficient of A are rotated to the left (if B */ 1.2471 +/* is positive) or to the right (if B is negative) without adjusting */ 1.2472 +/* the exponent or the sign of A. If lhs->digits is less than */ 1.2473 +/* set->digits the coefficient is padded with zeros on the left */ 1.2474 +/* before the rotate. Any leading zeros in the result are removed */ 1.2475 +/* as usual. */ 1.2476 +/* */ 1.2477 +/* B must be an integer (q=0) and in the range -set->digits through */ 1.2478 +/* +set->digits. */ 1.2479 +/* C must have space for set->digits digits. */ 1.2480 +/* NaNs are propagated as usual. Infinities are unaffected (but */ 1.2481 +/* B must be valid). No status is set unless B is invalid or an */ 1.2482 +/* operand is an sNaN. */ 1.2483 +/* ------------------------------------------------------------------ */ 1.2484 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberRotate(decNumber *res, const decNumber *lhs, 1.2485 + const decNumber *rhs, decContext *set) { 1.2486 + uInt status=0; /* accumulator */ 1.2487 + Int rotate; /* rhs as an Int */ 1.2488 + 1.2489 + #if DECCHECK 1.2490 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.2491 + #endif 1.2492 + 1.2493 + /* NaNs propagate as normal */ 1.2494 + if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) 1.2495 + decNaNs(res, lhs, rhs, set, &status); 1.2496 + /* rhs must be an integer */ 1.2497 + else if (decNumberIsInfinite(rhs) || rhs->exponent!=0) 1.2498 + status=DEC_Invalid_operation; 1.2499 + else { /* both numeric, rhs is an integer */ 1.2500 + rotate=decGetInt(rhs); /* [cannot fail] */ 1.2501 + if (rotate==BADINT /* something bad .. */ 1.2502 + || rotate==BIGODD || rotate==BIGEVEN /* .. very big .. */ 1.2503 + || abs(rotate)>set->digits) /* .. or out of range */ 1.2504 + status=DEC_Invalid_operation; 1.2505 + else { /* rhs is OK */ 1.2506 + uprv_decNumberCopy(res, lhs); 1.2507 + /* convert -ve rotate to equivalent positive rotation */ 1.2508 + if (rotate<0) rotate=set->digits+rotate; 1.2509 + if (rotate!=0 && rotate!=set->digits /* zero or full rotation */ 1.2510 + && !decNumberIsInfinite(res)) { /* lhs was infinite */ 1.2511 + /* left-rotate to do; 0 < rotate < set->digits */ 1.2512 + uInt units, shift; /* work */ 1.2513 + uInt msudigits; /* digits in result msu */ 1.2514 + Unit *msu=res->lsu+D2U(res->digits)-1; /* current msu */ 1.2515 + Unit *msumax=res->lsu+D2U(set->digits)-1; /* rotation msu */ 1.2516 + for (msu++; msu<=msumax; msu++) *msu=0; /* ensure high units=0 */ 1.2517 + res->digits=set->digits; /* now full-length */ 1.2518 + msudigits=MSUDIGITS(res->digits); /* actual digits in msu */ 1.2519 + 1.2520 + /* rotation here is done in-place, in three steps */ 1.2521 + /* 1. shift all to least up to one unit to unit-align final */ 1.2522 + /* lsd [any digits shifted out are rotated to the left, */ 1.2523 + /* abutted to the original msd (which may require split)] */ 1.2524 + /* */ 1.2525 + /* [if there are no whole units left to rotate, the */ 1.2526 + /* rotation is now complete] */ 1.2527 + /* */ 1.2528 + /* 2. shift to least, from below the split point only, so that */ 1.2529 + /* the final msd is in the right place in its Unit [any */ 1.2530 + /* digits shifted out will fit exactly in the current msu, */ 1.2531 + /* left aligned, no split required] */ 1.2532 + /* */ 1.2533 + /* 3. rotate all the units by reversing left part, right */ 1.2534 + /* part, and then whole */ 1.2535 + /* */ 1.2536 + /* example: rotate right 8 digits (2 units + 2), DECDPUN=3. */ 1.2537 + /* */ 1.2538 + /* start: 00a bcd efg hij klm npq */ 1.2539 + /* */ 1.2540 + /* 1a 000 0ab cde fgh|ijk lmn [pq saved] */ 1.2541 + /* 1b 00p qab cde fgh|ijk lmn */ 1.2542 + /* */ 1.2543 + /* 2a 00p qab cde fgh|00i jkl [mn saved] */ 1.2544 + /* 2b mnp qab cde fgh|00i jkl */ 1.2545 + /* */ 1.2546 + /* 3a fgh cde qab mnp|00i jkl */ 1.2547 + /* 3b fgh cde qab mnp|jkl 00i */ 1.2548 + /* 3c 00i jkl mnp qab cde fgh */ 1.2549 + 1.2550 + /* Step 1: amount to shift is the partial right-rotate count */ 1.2551 + rotate=set->digits-rotate; /* make it right-rotate */ 1.2552 + units=rotate/DECDPUN; /* whole units to rotate */ 1.2553 + shift=rotate%DECDPUN; /* left-over digits count */ 1.2554 + if (shift>0) { /* not an exact number of units */ 1.2555 + uInt save=res->lsu[0]%powers[shift]; /* save low digit(s) */ 1.2556 + decShiftToLeast(res->lsu, D2U(res->digits), shift); 1.2557 + if (shift>msudigits) { /* msumax-1 needs >0 digits */ 1.2558 + uInt rem=save%powers[shift-msudigits];/* split save */ 1.2559 + *msumax=(Unit)(save/powers[shift-msudigits]); /* and insert */ 1.2560 + *(msumax-1)=*(msumax-1) 1.2561 + +(Unit)(rem*powers[DECDPUN-(shift-msudigits)]); /* .. */ 1.2562 + } 1.2563 + else { /* all fits in msumax */ 1.2564 + *msumax=*msumax+(Unit)(save*powers[msudigits-shift]); /* [maybe *1] */ 1.2565 + } 1.2566 + } /* digits shift needed */ 1.2567 + 1.2568 + /* If whole units to rotate... */ 1.2569 + if (units>0) { /* some to do */ 1.2570 + /* Step 2: the units to touch are the whole ones in rotate, */ 1.2571 + /* if any, and the shift is DECDPUN-msudigits (which may be */ 1.2572 + /* 0, again) */ 1.2573 + shift=DECDPUN-msudigits; 1.2574 + if (shift>0) { /* not an exact number of units */ 1.2575 + uInt save=res->lsu[0]%powers[shift]; /* save low digit(s) */ 1.2576 + decShiftToLeast(res->lsu, units, shift); 1.2577 + *msumax=*msumax+(Unit)(save*powers[msudigits]); 1.2578 + } /* partial shift needed */ 1.2579 + 1.2580 + /* Step 3: rotate the units array using triple reverse */ 1.2581 + /* (reversing is easy and fast) */ 1.2582 + decReverse(res->lsu+units, msumax); /* left part */ 1.2583 + decReverse(res->lsu, res->lsu+units-1); /* right part */ 1.2584 + decReverse(res->lsu, msumax); /* whole */ 1.2585 + } /* whole units to rotate */ 1.2586 + /* the rotation may have left an undetermined number of zeros */ 1.2587 + /* on the left, so true length needs to be calculated */ 1.2588 + res->digits=decGetDigits(res->lsu, msumax-res->lsu+1); 1.2589 + } /* rotate needed */ 1.2590 + } /* rhs OK */ 1.2591 + } /* numerics */ 1.2592 + if (status!=0) decStatus(res, status, set); 1.2593 + return res; 1.2594 + } /* decNumberRotate */ 1.2595 + 1.2596 +/* ------------------------------------------------------------------ */ 1.2597 +/* decNumberSameQuantum -- test for equal exponents */ 1.2598 +/* */ 1.2599 +/* res is the result number, which will contain either 0 or 1 */ 1.2600 +/* lhs is a number to test */ 1.2601 +/* rhs is the second (usually a pattern) */ 1.2602 +/* */ 1.2603 +/* No errors are possible and no context is needed. */ 1.2604 +/* ------------------------------------------------------------------ */ 1.2605 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberSameQuantum(decNumber *res, const decNumber *lhs, 1.2606 + const decNumber *rhs) { 1.2607 + Unit ret=0; /* return value */ 1.2608 + 1.2609 + #if DECCHECK 1.2610 + if (decCheckOperands(res, lhs, rhs, DECUNCONT)) return res; 1.2611 + #endif 1.2612 + 1.2613 + if (SPECIALARGS) { 1.2614 + if (decNumberIsNaN(lhs) && decNumberIsNaN(rhs)) ret=1; 1.2615 + else if (decNumberIsInfinite(lhs) && decNumberIsInfinite(rhs)) ret=1; 1.2616 + /* [anything else with a special gives 0] */ 1.2617 + } 1.2618 + else if (lhs->exponent==rhs->exponent) ret=1; 1.2619 + 1.2620 + uprv_decNumberZero(res); /* OK to overwrite an operand now */ 1.2621 + *res->lsu=ret; 1.2622 + return res; 1.2623 + } /* decNumberSameQuantum */ 1.2624 + 1.2625 +/* ------------------------------------------------------------------ */ 1.2626 +/* decNumberScaleB -- multiply by a power of 10 */ 1.2627 +/* */ 1.2628 +/* This computes C = A x 10**B where B is an integer (q=0) with */ 1.2629 +/* maximum magnitude 2*(emax+digits) */ 1.2630 +/* */ 1.2631 +/* res is C, the result. C may be A or B */ 1.2632 +/* lhs is A, the number to adjust */ 1.2633 +/* rhs is B, the requested power of ten to use */ 1.2634 +/* set is the context */ 1.2635 +/* */ 1.2636 +/* C must have space for set->digits digits. */ 1.2637 +/* */ 1.2638 +/* The result may underflow or overflow. */ 1.2639 +/* ------------------------------------------------------------------ */ 1.2640 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberScaleB(decNumber *res, const decNumber *lhs, 1.2641 + const decNumber *rhs, decContext *set) { 1.2642 + Int reqexp; /* requested exponent change [B] */ 1.2643 + uInt status=0; /* accumulator */ 1.2644 + Int residue; /* work */ 1.2645 + 1.2646 + #if DECCHECK 1.2647 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.2648 + #endif 1.2649 + 1.2650 + /* Handle special values except lhs infinite */ 1.2651 + if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) 1.2652 + decNaNs(res, lhs, rhs, set, &status); 1.2653 + /* rhs must be an integer */ 1.2654 + else if (decNumberIsInfinite(rhs) || rhs->exponent!=0) 1.2655 + status=DEC_Invalid_operation; 1.2656 + else { 1.2657 + /* lhs is a number; rhs is a finite with q==0 */ 1.2658 + reqexp=decGetInt(rhs); /* [cannot fail] */ 1.2659 + if (reqexp==BADINT /* something bad .. */ 1.2660 + || reqexp==BIGODD || reqexp==BIGEVEN /* .. very big .. */ 1.2661 + || abs(reqexp)>(2*(set->digits+set->emax))) /* .. or out of range */ 1.2662 + status=DEC_Invalid_operation; 1.2663 + else { /* rhs is OK */ 1.2664 + uprv_decNumberCopy(res, lhs); /* all done if infinite lhs */ 1.2665 + if (!decNumberIsInfinite(res)) { /* prepare to scale */ 1.2666 + res->exponent+=reqexp; /* adjust the exponent */ 1.2667 + residue=0; 1.2668 + decFinalize(res, set, &residue, &status); /* .. and check */ 1.2669 + } /* finite LHS */ 1.2670 + } /* rhs OK */ 1.2671 + } /* rhs finite */ 1.2672 + if (status!=0) decStatus(res, status, set); 1.2673 + return res; 1.2674 + } /* decNumberScaleB */ 1.2675 + 1.2676 +/* ------------------------------------------------------------------ */ 1.2677 +/* decNumberShift -- shift the coefficient of a Number left or right */ 1.2678 +/* */ 1.2679 +/* This computes C = A << B or C = A >> -B (in base ten). */ 1.2680 +/* */ 1.2681 +/* res is C, the result. C may be A and/or B (e.g., X=X<<X) */ 1.2682 +/* lhs is A */ 1.2683 +/* rhs is B, the number of digits to shift (-ve to right) */ 1.2684 +/* set is the context */ 1.2685 +/* */ 1.2686 +/* The digits of the coefficient of A are shifted to the left (if B */ 1.2687 +/* is positive) or to the right (if B is negative) without adjusting */ 1.2688 +/* the exponent or the sign of A. */ 1.2689 +/* */ 1.2690 +/* B must be an integer (q=0) and in the range -set->digits through */ 1.2691 +/* +set->digits. */ 1.2692 +/* C must have space for set->digits digits. */ 1.2693 +/* NaNs are propagated as usual. Infinities are unaffected (but */ 1.2694 +/* B must be valid). No status is set unless B is invalid or an */ 1.2695 +/* operand is an sNaN. */ 1.2696 +/* ------------------------------------------------------------------ */ 1.2697 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberShift(decNumber *res, const decNumber *lhs, 1.2698 + const decNumber *rhs, decContext *set) { 1.2699 + uInt status=0; /* accumulator */ 1.2700 + Int shift; /* rhs as an Int */ 1.2701 + 1.2702 + #if DECCHECK 1.2703 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.2704 + #endif 1.2705 + 1.2706 + /* NaNs propagate as normal */ 1.2707 + if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) 1.2708 + decNaNs(res, lhs, rhs, set, &status); 1.2709 + /* rhs must be an integer */ 1.2710 + else if (decNumberIsInfinite(rhs) || rhs->exponent!=0) 1.2711 + status=DEC_Invalid_operation; 1.2712 + else { /* both numeric, rhs is an integer */ 1.2713 + shift=decGetInt(rhs); /* [cannot fail] */ 1.2714 + if (shift==BADINT /* something bad .. */ 1.2715 + || shift==BIGODD || shift==BIGEVEN /* .. very big .. */ 1.2716 + || abs(shift)>set->digits) /* .. or out of range */ 1.2717 + status=DEC_Invalid_operation; 1.2718 + else { /* rhs is OK */ 1.2719 + uprv_decNumberCopy(res, lhs); 1.2720 + if (shift!=0 && !decNumberIsInfinite(res)) { /* something to do */ 1.2721 + if (shift>0) { /* to left */ 1.2722 + if (shift==set->digits) { /* removing all */ 1.2723 + *res->lsu=0; /* so place 0 */ 1.2724 + res->digits=1; /* .. */ 1.2725 + } 1.2726 + else { /* */ 1.2727 + /* first remove leading digits if necessary */ 1.2728 + if (res->digits+shift>set->digits) { 1.2729 + decDecap(res, res->digits+shift-set->digits); 1.2730 + /* that updated res->digits; may have gone to 1 (for a */ 1.2731 + /* single digit or for zero */ 1.2732 + } 1.2733 + if (res->digits>1 || *res->lsu) /* if non-zero.. */ 1.2734 + res->digits=decShiftToMost(res->lsu, res->digits, shift); 1.2735 + } /* partial left */ 1.2736 + } /* left */ 1.2737 + else { /* to right */ 1.2738 + if (-shift>=res->digits) { /* discarding all */ 1.2739 + *res->lsu=0; /* so place 0 */ 1.2740 + res->digits=1; /* .. */ 1.2741 + } 1.2742 + else { 1.2743 + decShiftToLeast(res->lsu, D2U(res->digits), -shift); 1.2744 + res->digits-=(-shift); 1.2745 + } 1.2746 + } /* to right */ 1.2747 + } /* non-0 non-Inf shift */ 1.2748 + } /* rhs OK */ 1.2749 + } /* numerics */ 1.2750 + if (status!=0) decStatus(res, status, set); 1.2751 + return res; 1.2752 + } /* decNumberShift */ 1.2753 + 1.2754 +/* ------------------------------------------------------------------ */ 1.2755 +/* decNumberSquareRoot -- square root operator */ 1.2756 +/* */ 1.2757 +/* This computes C = squareroot(A) */ 1.2758 +/* */ 1.2759 +/* res is C, the result. C may be A */ 1.2760 +/* rhs is A */ 1.2761 +/* set is the context; note that rounding mode has no effect */ 1.2762 +/* */ 1.2763 +/* C must have space for set->digits digits. */ 1.2764 +/* ------------------------------------------------------------------ */ 1.2765 +/* This uses the following varying-precision algorithm in: */ 1.2766 +/* */ 1.2767 +/* Properly Rounded Variable Precision Square Root, T. E. Hull and */ 1.2768 +/* A. Abrham, ACM Transactions on Mathematical Software, Vol 11 #3, */ 1.2769 +/* pp229-237, ACM, September 1985. */ 1.2770 +/* */ 1.2771 +/* The square-root is calculated using Newton's method, after which */ 1.2772 +/* a check is made to ensure the result is correctly rounded. */ 1.2773 +/* */ 1.2774 +/* % [Reformatted original Numerical Turing source code follows.] */ 1.2775 +/* function sqrt(x : real) : real */ 1.2776 +/* % sqrt(x) returns the properly rounded approximation to the square */ 1.2777 +/* % root of x, in the precision of the calling environment, or it */ 1.2778 +/* % fails if x < 0. */ 1.2779 +/* % t e hull and a abrham, august, 1984 */ 1.2780 +/* if x <= 0 then */ 1.2781 +/* if x < 0 then */ 1.2782 +/* assert false */ 1.2783 +/* else */ 1.2784 +/* result 0 */ 1.2785 +/* end if */ 1.2786 +/* end if */ 1.2787 +/* var f := setexp(x, 0) % fraction part of x [0.1 <= x < 1] */ 1.2788 +/* var e := getexp(x) % exponent part of x */ 1.2789 +/* var approx : real */ 1.2790 +/* if e mod 2 = 0 then */ 1.2791 +/* approx := .259 + .819 * f % approx to root of f */ 1.2792 +/* else */ 1.2793 +/* f := f/l0 % adjustments */ 1.2794 +/* e := e + 1 % for odd */ 1.2795 +/* approx := .0819 + 2.59 * f % exponent */ 1.2796 +/* end if */ 1.2797 +/* */ 1.2798 +/* var p:= 3 */ 1.2799 +/* const maxp := currentprecision + 2 */ 1.2800 +/* loop */ 1.2801 +/* p := min(2*p - 2, maxp) % p = 4,6,10, . . . , maxp */ 1.2802 +/* precision p */ 1.2803 +/* approx := .5 * (approx + f/approx) */ 1.2804 +/* exit when p = maxp */ 1.2805 +/* end loop */ 1.2806 +/* */ 1.2807 +/* % approx is now within 1 ulp of the properly rounded square root */ 1.2808 +/* % of f; to ensure proper rounding, compare squares of (approx - */ 1.2809 +/* % l/2 ulp) and (approx + l/2 ulp) with f. */ 1.2810 +/* p := currentprecision */ 1.2811 +/* begin */ 1.2812 +/* precision p + 2 */ 1.2813 +/* const approxsubhalf := approx - setexp(.5, -p) */ 1.2814 +/* if mulru(approxsubhalf, approxsubhalf) > f then */ 1.2815 +/* approx := approx - setexp(.l, -p + 1) */ 1.2816 +/* else */ 1.2817 +/* const approxaddhalf := approx + setexp(.5, -p) */ 1.2818 +/* if mulrd(approxaddhalf, approxaddhalf) < f then */ 1.2819 +/* approx := approx + setexp(.l, -p + 1) */ 1.2820 +/* end if */ 1.2821 +/* end if */ 1.2822 +/* end */ 1.2823 +/* result setexp(approx, e div 2) % fix exponent */ 1.2824 +/* end sqrt */ 1.2825 +/* ------------------------------------------------------------------ */ 1.2826 +#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406 1.2827 +#pragma GCC diagnostic push 1.2828 +#pragma GCC diagnostic ignored "-Warray-bounds" 1.2829 +#endif 1.2830 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberSquareRoot(decNumber *res, const decNumber *rhs, 1.2831 + decContext *set) { 1.2832 + decContext workset, approxset; /* work contexts */ 1.2833 + decNumber dzero; /* used for constant zero */ 1.2834 + Int maxp; /* largest working precision */ 1.2835 + Int workp; /* working precision */ 1.2836 + Int residue=0; /* rounding residue */ 1.2837 + uInt status=0, ignore=0; /* status accumulators */ 1.2838 + uInt rstatus; /* .. */ 1.2839 + Int exp; /* working exponent */ 1.2840 + Int ideal; /* ideal (preferred) exponent */ 1.2841 + Int needbytes; /* work */ 1.2842 + Int dropped; /* .. */ 1.2843 + 1.2844 + #if DECSUBSET 1.2845 + decNumber *allocrhs=NULL; /* non-NULL if rounded rhs allocated */ 1.2846 + #endif 1.2847 + /* buffer for f [needs +1 in case DECBUFFER 0] */ 1.2848 + decNumber buff[D2N(DECBUFFER+1)]; 1.2849 + /* buffer for a [needs +2 to match likely maxp] */ 1.2850 + decNumber bufa[D2N(DECBUFFER+2)]; 1.2851 + /* buffer for temporary, b [must be same size as a] */ 1.2852 + decNumber bufb[D2N(DECBUFFER+2)]; 1.2853 + decNumber *allocbuff=NULL; /* -> allocated buff, iff allocated */ 1.2854 + decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */ 1.2855 + decNumber *allocbufb=NULL; /* -> allocated bufb, iff allocated */ 1.2856 + decNumber *f=buff; /* reduced fraction */ 1.2857 + decNumber *a=bufa; /* approximation to result */ 1.2858 + decNumber *b=bufb; /* intermediate result */ 1.2859 + /* buffer for temporary variable, up to 3 digits */ 1.2860 + decNumber buft[D2N(3)]; 1.2861 + decNumber *t=buft; /* up-to-3-digit constant or work */ 1.2862 + 1.2863 + #if DECCHECK 1.2864 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.2865 + #endif 1.2866 + 1.2867 + do { /* protect allocated storage */ 1.2868 + #if DECSUBSET 1.2869 + if (!set->extended) { 1.2870 + /* reduce operand and set lostDigits status, as needed */ 1.2871 + if (rhs->digits>set->digits) { 1.2872 + allocrhs=decRoundOperand(rhs, set, &status); 1.2873 + if (allocrhs==NULL) break; 1.2874 + /* [Note: 'f' allocation below could reuse this buffer if */ 1.2875 + /* used, but as this is rare they are kept separate for clarity.] */ 1.2876 + rhs=allocrhs; 1.2877 + } 1.2878 + } 1.2879 + #endif 1.2880 + /* [following code does not require input rounding] */ 1.2881 + 1.2882 + /* handle infinities and NaNs */ 1.2883 + if (SPECIALARG) { 1.2884 + if (decNumberIsInfinite(rhs)) { /* an infinity */ 1.2885 + if (decNumberIsNegative(rhs)) status|=DEC_Invalid_operation; 1.2886 + else uprv_decNumberCopy(res, rhs); /* +Infinity */ 1.2887 + } 1.2888 + else decNaNs(res, rhs, NULL, set, &status); /* a NaN */ 1.2889 + break; 1.2890 + } 1.2891 + 1.2892 + /* calculate the ideal (preferred) exponent [floor(exp/2)] */ 1.2893 + /* [It would be nicer to write: ideal=rhs->exponent>>1, but this */ 1.2894 + /* generates a compiler warning. Generated code is the same.] */ 1.2895 + ideal=(rhs->exponent&~1)/2; /* target */ 1.2896 + 1.2897 + /* handle zeros */ 1.2898 + if (ISZERO(rhs)) { 1.2899 + uprv_decNumberCopy(res, rhs); /* could be 0 or -0 */ 1.2900 + res->exponent=ideal; /* use the ideal [safe] */ 1.2901 + /* use decFinish to clamp any out-of-range exponent, etc. */ 1.2902 + decFinish(res, set, &residue, &status); 1.2903 + break; 1.2904 + } 1.2905 + 1.2906 + /* any other -x is an oops */ 1.2907 + if (decNumberIsNegative(rhs)) { 1.2908 + status|=DEC_Invalid_operation; 1.2909 + break; 1.2910 + } 1.2911 + 1.2912 + /* space is needed for three working variables */ 1.2913 + /* f -- the same precision as the RHS, reduced to 0.01->0.99... */ 1.2914 + /* a -- Hull's approximation -- precision, when assigned, is */ 1.2915 + /* currentprecision+1 or the input argument precision, */ 1.2916 + /* whichever is larger (+2 for use as temporary) */ 1.2917 + /* b -- intermediate temporary result (same size as a) */ 1.2918 + /* if any is too long for local storage, then allocate */ 1.2919 + workp=MAXI(set->digits+1, rhs->digits); /* actual rounding precision */ 1.2920 + workp=MAXI(workp, 7); /* at least 7 for low cases */ 1.2921 + maxp=workp+2; /* largest working precision */ 1.2922 + 1.2923 + needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit); 1.2924 + if (needbytes>(Int)sizeof(buff)) { 1.2925 + allocbuff=(decNumber *)malloc(needbytes); 1.2926 + if (allocbuff==NULL) { /* hopeless -- abandon */ 1.2927 + status|=DEC_Insufficient_storage; 1.2928 + break;} 1.2929 + f=allocbuff; /* use the allocated space */ 1.2930 + } 1.2931 + /* a and b both need to be able to hold a maxp-length number */ 1.2932 + needbytes=sizeof(decNumber)+(D2U(maxp)-1)*sizeof(Unit); 1.2933 + if (needbytes>(Int)sizeof(bufa)) { /* [same applies to b] */ 1.2934 + allocbufa=(decNumber *)malloc(needbytes); 1.2935 + allocbufb=(decNumber *)malloc(needbytes); 1.2936 + if (allocbufa==NULL || allocbufb==NULL) { /* hopeless */ 1.2937 + status|=DEC_Insufficient_storage; 1.2938 + break;} 1.2939 + a=allocbufa; /* use the allocated spaces */ 1.2940 + b=allocbufb; /* .. */ 1.2941 + } 1.2942 + 1.2943 + /* copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1 */ 1.2944 + uprv_decNumberCopy(f, rhs); 1.2945 + exp=f->exponent+f->digits; /* adjusted to Hull rules */ 1.2946 + f->exponent=-(f->digits); /* to range */ 1.2947 + 1.2948 + /* set up working context */ 1.2949 + uprv_decContextDefault(&workset, DEC_INIT_DECIMAL64); 1.2950 + workset.emax=DEC_MAX_EMAX; 1.2951 + workset.emin=DEC_MIN_EMIN; 1.2952 + 1.2953 + /* [Until further notice, no error is possible and status bits */ 1.2954 + /* (Rounded, etc.) should be ignored, not accumulated.] */ 1.2955 + 1.2956 + /* Calculate initial approximation, and allow for odd exponent */ 1.2957 + workset.digits=workp; /* p for initial calculation */ 1.2958 + t->bits=0; t->digits=3; 1.2959 + a->bits=0; a->digits=3; 1.2960 + if ((exp & 1)==0) { /* even exponent */ 1.2961 + /* Set t=0.259, a=0.819 */ 1.2962 + t->exponent=-3; 1.2963 + a->exponent=-3; 1.2964 + #if DECDPUN>=3 1.2965 + t->lsu[0]=259; 1.2966 + a->lsu[0]=819; 1.2967 + #elif DECDPUN==2 1.2968 + t->lsu[0]=59; t->lsu[1]=2; 1.2969 + a->lsu[0]=19; a->lsu[1]=8; 1.2970 + #else 1.2971 + t->lsu[0]=9; t->lsu[1]=5; t->lsu[2]=2; 1.2972 + a->lsu[0]=9; a->lsu[1]=1; a->lsu[2]=8; 1.2973 + #endif 1.2974 + } 1.2975 + else { /* odd exponent */ 1.2976 + /* Set t=0.0819, a=2.59 */ 1.2977 + f->exponent--; /* f=f/10 */ 1.2978 + exp++; /* e=e+1 */ 1.2979 + t->exponent=-4; 1.2980 + a->exponent=-2; 1.2981 + #if DECDPUN>=3 1.2982 + t->lsu[0]=819; 1.2983 + a->lsu[0]=259; 1.2984 + #elif DECDPUN==2 1.2985 + t->lsu[0]=19; t->lsu[1]=8; 1.2986 + a->lsu[0]=59; a->lsu[1]=2; 1.2987 + #else 1.2988 + t->lsu[0]=9; t->lsu[1]=1; t->lsu[2]=8; 1.2989 + a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2; 1.2990 + #endif 1.2991 + } 1.2992 + 1.2993 + decMultiplyOp(a, a, f, &workset, &ignore); /* a=a*f */ 1.2994 + decAddOp(a, a, t, &workset, 0, &ignore); /* ..+t */ 1.2995 + /* [a is now the initial approximation for sqrt(f), calculated with */ 1.2996 + /* currentprecision, which is also a's precision.] */ 1.2997 + 1.2998 + /* the main calculation loop */ 1.2999 + uprv_decNumberZero(&dzero); /* make 0 */ 1.3000 + uprv_decNumberZero(t); /* set t = 0.5 */ 1.3001 + t->lsu[0]=5; /* .. */ 1.3002 + t->exponent=-1; /* .. */ 1.3003 + workset.digits=3; /* initial p */ 1.3004 + for (; workset.digits<maxp;) { 1.3005 + /* set p to min(2*p - 2, maxp) [hence 3; or: 4, 6, 10, ... , maxp] */ 1.3006 + workset.digits=MINI(workset.digits*2-2, maxp); 1.3007 + /* a = 0.5 * (a + f/a) */ 1.3008 + /* [calculated at p then rounded to currentprecision] */ 1.3009 + decDivideOp(b, f, a, &workset, DIVIDE, &ignore); /* b=f/a */ 1.3010 + decAddOp(b, b, a, &workset, 0, &ignore); /* b=b+a */ 1.3011 + decMultiplyOp(a, b, t, &workset, &ignore); /* a=b*0.5 */ 1.3012 + } /* loop */ 1.3013 + 1.3014 + /* Here, 0.1 <= a < 1 [Hull], and a has maxp digits */ 1.3015 + /* now reduce to length, etc.; this needs to be done with a */ 1.3016 + /* having the correct exponent so as to handle subnormals */ 1.3017 + /* correctly */ 1.3018 + approxset=*set; /* get emin, emax, etc. */ 1.3019 + approxset.round=DEC_ROUND_HALF_EVEN; 1.3020 + a->exponent+=exp/2; /* set correct exponent */ 1.3021 + rstatus=0; /* clear status */ 1.3022 + residue=0; /* .. and accumulator */ 1.3023 + decCopyFit(a, a, &approxset, &residue, &rstatus); /* reduce (if needed) */ 1.3024 + decFinish(a, &approxset, &residue, &rstatus); /* clean and finalize */ 1.3025 + 1.3026 + /* Overflow was possible if the input exponent was out-of-range, */ 1.3027 + /* in which case quit */ 1.3028 + if (rstatus&DEC_Overflow) { 1.3029 + status=rstatus; /* use the status as-is */ 1.3030 + uprv_decNumberCopy(res, a); /* copy to result */ 1.3031 + break; 1.3032 + } 1.3033 + 1.3034 + /* Preserve status except Inexact/Rounded */ 1.3035 + status|=(rstatus & ~(DEC_Rounded|DEC_Inexact)); 1.3036 + 1.3037 + /* Carry out the Hull correction */ 1.3038 + a->exponent-=exp/2; /* back to 0.1->1 */ 1.3039 + 1.3040 + /* a is now at final precision and within 1 ulp of the properly */ 1.3041 + /* rounded square root of f; to ensure proper rounding, compare */ 1.3042 + /* squares of (a - l/2 ulp) and (a + l/2 ulp) with f. */ 1.3043 + /* Here workset.digits=maxp and t=0.5, and a->digits determines */ 1.3044 + /* the ulp */ 1.3045 + workset.digits--; /* maxp-1 is OK now */ 1.3046 + t->exponent=-a->digits-1; /* make 0.5 ulp */ 1.3047 + decAddOp(b, a, t, &workset, DECNEG, &ignore); /* b = a - 0.5 ulp */ 1.3048 + workset.round=DEC_ROUND_UP; 1.3049 + decMultiplyOp(b, b, b, &workset, &ignore); /* b = mulru(b, b) */ 1.3050 + decCompareOp(b, f, b, &workset, COMPARE, &ignore); /* b ? f, reversed */ 1.3051 + if (decNumberIsNegative(b)) { /* f < b [i.e., b > f] */ 1.3052 + /* this is the more common adjustment, though both are rare */ 1.3053 + t->exponent++; /* make 1.0 ulp */ 1.3054 + t->lsu[0]=1; /* .. */ 1.3055 + decAddOp(a, a, t, &workset, DECNEG, &ignore); /* a = a - 1 ulp */ 1.3056 + /* assign to approx [round to length] */ 1.3057 + approxset.emin-=exp/2; /* adjust to match a */ 1.3058 + approxset.emax-=exp/2; 1.3059 + decAddOp(a, &dzero, a, &approxset, 0, &ignore); 1.3060 + } 1.3061 + else { 1.3062 + decAddOp(b, a, t, &workset, 0, &ignore); /* b = a + 0.5 ulp */ 1.3063 + workset.round=DEC_ROUND_DOWN; 1.3064 + decMultiplyOp(b, b, b, &workset, &ignore); /* b = mulrd(b, b) */ 1.3065 + decCompareOp(b, b, f, &workset, COMPARE, &ignore); /* b ? f */ 1.3066 + if (decNumberIsNegative(b)) { /* b < f */ 1.3067 + t->exponent++; /* make 1.0 ulp */ 1.3068 + t->lsu[0]=1; /* .. */ 1.3069 + decAddOp(a, a, t, &workset, 0, &ignore); /* a = a + 1 ulp */ 1.3070 + /* assign to approx [round to length] */ 1.3071 + approxset.emin-=exp/2; /* adjust to match a */ 1.3072 + approxset.emax-=exp/2; 1.3073 + decAddOp(a, &dzero, a, &approxset, 0, &ignore); 1.3074 + } 1.3075 + } 1.3076 + /* [no errors are possible in the above, and rounding/inexact during */ 1.3077 + /* estimation are irrelevant, so status was not accumulated] */ 1.3078 + 1.3079 + /* Here, 0.1 <= a < 1 (still), so adjust back */ 1.3080 + a->exponent+=exp/2; /* set correct exponent */ 1.3081 + 1.3082 + /* count droppable zeros [after any subnormal rounding] by */ 1.3083 + /* trimming a copy */ 1.3084 + uprv_decNumberCopy(b, a); 1.3085 + decTrim(b, set, 1, 1, &dropped); /* [drops trailing zeros] */ 1.3086 + 1.3087 + /* Set Inexact and Rounded. The answer can only be exact if */ 1.3088 + /* it is short enough so that squaring it could fit in workp */ 1.3089 + /* digits, so this is the only (relatively rare) condition that */ 1.3090 + /* a careful check is needed */ 1.3091 + if (b->digits*2-1 > workp) { /* cannot fit */ 1.3092 + status|=DEC_Inexact|DEC_Rounded; 1.3093 + } 1.3094 + else { /* could be exact/unrounded */ 1.3095 + uInt mstatus=0; /* local status */ 1.3096 + decMultiplyOp(b, b, b, &workset, &mstatus); /* try the multiply */ 1.3097 + if (mstatus&DEC_Overflow) { /* result just won't fit */ 1.3098 + status|=DEC_Inexact|DEC_Rounded; 1.3099 + } 1.3100 + else { /* plausible */ 1.3101 + decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); /* b ? rhs */ 1.3102 + if (!ISZERO(t)) status|=DEC_Inexact|DEC_Rounded; /* not equal */ 1.3103 + else { /* is Exact */ 1.3104 + /* here, dropped is the count of trailing zeros in 'a' */ 1.3105 + /* use closest exponent to ideal... */ 1.3106 + Int todrop=ideal-a->exponent; /* most that can be dropped */ 1.3107 + if (todrop<0) status|=DEC_Rounded; /* ideally would add 0s */ 1.3108 + else { /* unrounded */ 1.3109 + /* there are some to drop, but emax may not allow all */ 1.3110 + Int maxexp=set->emax-set->digits+1; 1.3111 + Int maxdrop=maxexp-a->exponent; 1.3112 + if (todrop>maxdrop && set->clamp) { /* apply clamping */ 1.3113 + todrop=maxdrop; 1.3114 + status|=DEC_Clamped; 1.3115 + } 1.3116 + if (dropped<todrop) { /* clamp to those available */ 1.3117 + todrop=dropped; 1.3118 + status|=DEC_Clamped; 1.3119 + } 1.3120 + if (todrop>0) { /* have some to drop */ 1.3121 + decShiftToLeast(a->lsu, D2U(a->digits), todrop); 1.3122 + a->exponent+=todrop; /* maintain numerical value */ 1.3123 + a->digits-=todrop; /* new length */ 1.3124 + } 1.3125 + } 1.3126 + } 1.3127 + } 1.3128 + } 1.3129 + 1.3130 + /* double-check Underflow, as perhaps the result could not have */ 1.3131 + /* been subnormal (initial argument too big), or it is now Exact */ 1.3132 + if (status&DEC_Underflow) { 1.3133 + Int ae=rhs->exponent+rhs->digits-1; /* adjusted exponent */ 1.3134 + /* check if truly subnormal */ 1.3135 + #if DECEXTFLAG /* DEC_Subnormal too */ 1.3136 + if (ae>=set->emin*2) status&=~(DEC_Subnormal|DEC_Underflow); 1.3137 + #else 1.3138 + if (ae>=set->emin*2) status&=~DEC_Underflow; 1.3139 + #endif 1.3140 + /* check if truly inexact */ 1.3141 + if (!(status&DEC_Inexact)) status&=~DEC_Underflow; 1.3142 + } 1.3143 + 1.3144 + uprv_decNumberCopy(res, a); /* a is now the result */ 1.3145 + } while(0); /* end protected */ 1.3146 + 1.3147 + if (allocbuff!=NULL) free(allocbuff); /* drop any storage used */ 1.3148 + if (allocbufa!=NULL) free(allocbufa); /* .. */ 1.3149 + if (allocbufb!=NULL) free(allocbufb); /* .. */ 1.3150 + #if DECSUBSET 1.3151 + if (allocrhs !=NULL) free(allocrhs); /* .. */ 1.3152 + #endif 1.3153 + if (status!=0) decStatus(res, status, set);/* then report status */ 1.3154 + #if DECCHECK 1.3155 + decCheckInexact(res, set); 1.3156 + #endif 1.3157 + return res; 1.3158 + } /* decNumberSquareRoot */ 1.3159 +#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406 1.3160 +#pragma GCC diagnostic pop 1.3161 +#endif 1.3162 + 1.3163 +/* ------------------------------------------------------------------ */ 1.3164 +/* decNumberSubtract -- subtract two Numbers */ 1.3165 +/* */ 1.3166 +/* This computes C = A - B */ 1.3167 +/* */ 1.3168 +/* res is C, the result. C may be A and/or B (e.g., X=X-X) */ 1.3169 +/* lhs is A */ 1.3170 +/* rhs is B */ 1.3171 +/* set is the context */ 1.3172 +/* */ 1.3173 +/* C must have space for set->digits digits. */ 1.3174 +/* ------------------------------------------------------------------ */ 1.3175 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberSubtract(decNumber *res, const decNumber *lhs, 1.3176 + const decNumber *rhs, decContext *set) { 1.3177 + uInt status=0; /* accumulator */ 1.3178 + 1.3179 + decAddOp(res, lhs, rhs, set, DECNEG, &status); 1.3180 + if (status!=0) decStatus(res, status, set); 1.3181 + #if DECCHECK 1.3182 + decCheckInexact(res, set); 1.3183 + #endif 1.3184 + return res; 1.3185 + } /* decNumberSubtract */ 1.3186 + 1.3187 +/* ------------------------------------------------------------------ */ 1.3188 +/* decNumberToIntegralExact -- round-to-integral-value with InExact */ 1.3189 +/* decNumberToIntegralValue -- round-to-integral-value */ 1.3190 +/* */ 1.3191 +/* res is the result */ 1.3192 +/* rhs is input number */ 1.3193 +/* set is the context */ 1.3194 +/* */ 1.3195 +/* res must have space for any value of rhs. */ 1.3196 +/* */ 1.3197 +/* This implements the IEEE special operators and therefore treats */ 1.3198 +/* special values as valid. For finite numbers it returns */ 1.3199 +/* rescale(rhs, 0) if rhs->exponent is <0. */ 1.3200 +/* Otherwise the result is rhs (so no error is possible, except for */ 1.3201 +/* sNaN). */ 1.3202 +/* */ 1.3203 +/* The context is used for rounding mode and status after sNaN, but */ 1.3204 +/* the digits setting is ignored. The Exact version will signal */ 1.3205 +/* Inexact if the result differs numerically from rhs; the other */ 1.3206 +/* never signals Inexact. */ 1.3207 +/* ------------------------------------------------------------------ */ 1.3208 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberToIntegralExact(decNumber *res, const decNumber *rhs, 1.3209 + decContext *set) { 1.3210 + decNumber dn; 1.3211 + decContext workset; /* working context */ 1.3212 + uInt status=0; /* accumulator */ 1.3213 + 1.3214 + #if DECCHECK 1.3215 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.3216 + #endif 1.3217 + 1.3218 + /* handle infinities and NaNs */ 1.3219 + if (SPECIALARG) { 1.3220 + if (decNumberIsInfinite(rhs)) uprv_decNumberCopy(res, rhs); /* an Infinity */ 1.3221 + else decNaNs(res, rhs, NULL, set, &status); /* a NaN */ 1.3222 + } 1.3223 + else { /* finite */ 1.3224 + /* have a finite number; no error possible (res must be big enough) */ 1.3225 + if (rhs->exponent>=0) return uprv_decNumberCopy(res, rhs); 1.3226 + /* that was easy, but if negative exponent there is work to do... */ 1.3227 + workset=*set; /* clone rounding, etc. */ 1.3228 + workset.digits=rhs->digits; /* no length rounding */ 1.3229 + workset.traps=0; /* no traps */ 1.3230 + uprv_decNumberZero(&dn); /* make a number with exponent 0 */ 1.3231 + uprv_decNumberQuantize(res, rhs, &dn, &workset); 1.3232 + status|=workset.status; 1.3233 + } 1.3234 + if (status!=0) decStatus(res, status, set); 1.3235 + return res; 1.3236 + } /* decNumberToIntegralExact */ 1.3237 + 1.3238 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberToIntegralValue(decNumber *res, const decNumber *rhs, 1.3239 + decContext *set) { 1.3240 + decContext workset=*set; /* working context */ 1.3241 + workset.traps=0; /* no traps */ 1.3242 + uprv_decNumberToIntegralExact(res, rhs, &workset); 1.3243 + /* this never affects set, except for sNaNs; NaN will have been set */ 1.3244 + /* or propagated already, so no need to call decStatus */ 1.3245 + set->status|=workset.status&DEC_Invalid_operation; 1.3246 + return res; 1.3247 + } /* decNumberToIntegralValue */ 1.3248 + 1.3249 +/* ------------------------------------------------------------------ */ 1.3250 +/* decNumberXor -- XOR two Numbers, digitwise */ 1.3251 +/* */ 1.3252 +/* This computes C = A ^ B */ 1.3253 +/* */ 1.3254 +/* res is C, the result. C may be A and/or B (e.g., X=X^X) */ 1.3255 +/* lhs is A */ 1.3256 +/* rhs is B */ 1.3257 +/* set is the context (used for result length and error report) */ 1.3258 +/* */ 1.3259 +/* C must have space for set->digits digits. */ 1.3260 +/* */ 1.3261 +/* Logical function restrictions apply (see above); a NaN is */ 1.3262 +/* returned with Invalid_operation if a restriction is violated. */ 1.3263 +/* ------------------------------------------------------------------ */ 1.3264 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberXor(decNumber *res, const decNumber *lhs, 1.3265 + const decNumber *rhs, decContext *set) { 1.3266 + const Unit *ua, *ub; /* -> operands */ 1.3267 + const Unit *msua, *msub; /* -> operand msus */ 1.3268 + Unit *uc, *msuc; /* -> result and its msu */ 1.3269 + Int msudigs; /* digits in res msu */ 1.3270 + #if DECCHECK 1.3271 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.3272 + #endif 1.3273 + 1.3274 + if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs) 1.3275 + || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) { 1.3276 + decStatus(res, DEC_Invalid_operation, set); 1.3277 + return res; 1.3278 + } 1.3279 + /* operands are valid */ 1.3280 + ua=lhs->lsu; /* bottom-up */ 1.3281 + ub=rhs->lsu; /* .. */ 1.3282 + uc=res->lsu; /* .. */ 1.3283 + msua=ua+D2U(lhs->digits)-1; /* -> msu of lhs */ 1.3284 + msub=ub+D2U(rhs->digits)-1; /* -> msu of rhs */ 1.3285 + msuc=uc+D2U(set->digits)-1; /* -> msu of result */ 1.3286 + msudigs=MSUDIGITS(set->digits); /* [faster than remainder] */ 1.3287 + for (; uc<=msuc; ua++, ub++, uc++) { /* Unit loop */ 1.3288 + Unit a, b; /* extract units */ 1.3289 + if (ua>msua) a=0; 1.3290 + else a=*ua; 1.3291 + if (ub>msub) b=0; 1.3292 + else b=*ub; 1.3293 + *uc=0; /* can now write back */ 1.3294 + if (a|b) { /* maybe 1 bits to examine */ 1.3295 + Int i, j; 1.3296 + /* This loop could be unrolled and/or use BIN2BCD tables */ 1.3297 + for (i=0; i<DECDPUN; i++) { 1.3298 + if ((a^b)&1) *uc=*uc+(Unit)powers[i]; /* effect XOR */ 1.3299 + j=a%10; 1.3300 + a=a/10; 1.3301 + j|=b%10; 1.3302 + b=b/10; 1.3303 + if (j>1) { 1.3304 + decStatus(res, DEC_Invalid_operation, set); 1.3305 + return res; 1.3306 + } 1.3307 + if (uc==msuc && i==msudigs-1) break; /* just did final digit */ 1.3308 + } /* each digit */ 1.3309 + } /* non-zero */ 1.3310 + } /* each unit */ 1.3311 + /* [here uc-1 is the msu of the result] */ 1.3312 + res->digits=decGetDigits(res->lsu, uc-res->lsu); 1.3313 + res->exponent=0; /* integer */ 1.3314 + res->bits=0; /* sign=0 */ 1.3315 + return res; /* [no status to set] */ 1.3316 + } /* decNumberXor */ 1.3317 + 1.3318 + 1.3319 +/* ================================================================== */ 1.3320 +/* Utility routines */ 1.3321 +/* ================================================================== */ 1.3322 + 1.3323 +/* ------------------------------------------------------------------ */ 1.3324 +/* decNumberClass -- return the decClass of a decNumber */ 1.3325 +/* dn -- the decNumber to test */ 1.3326 +/* set -- the context to use for Emin */ 1.3327 +/* returns the decClass enum */ 1.3328 +/* ------------------------------------------------------------------ */ 1.3329 +enum decClass uprv_decNumberClass(const decNumber *dn, decContext *set) { 1.3330 + if (decNumberIsSpecial(dn)) { 1.3331 + if (decNumberIsQNaN(dn)) return DEC_CLASS_QNAN; 1.3332 + if (decNumberIsSNaN(dn)) return DEC_CLASS_SNAN; 1.3333 + /* must be an infinity */ 1.3334 + if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_INF; 1.3335 + return DEC_CLASS_POS_INF; 1.3336 + } 1.3337 + /* is finite */ 1.3338 + if (uprv_decNumberIsNormal(dn, set)) { /* most common */ 1.3339 + if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_NORMAL; 1.3340 + return DEC_CLASS_POS_NORMAL; 1.3341 + } 1.3342 + /* is subnormal or zero */ 1.3343 + if (decNumberIsZero(dn)) { /* most common */ 1.3344 + if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_ZERO; 1.3345 + return DEC_CLASS_POS_ZERO; 1.3346 + } 1.3347 + if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_SUBNORMAL; 1.3348 + return DEC_CLASS_POS_SUBNORMAL; 1.3349 + } /* decNumberClass */ 1.3350 + 1.3351 +/* ------------------------------------------------------------------ */ 1.3352 +/* decNumberClassToString -- convert decClass to a string */ 1.3353 +/* */ 1.3354 +/* eclass is a valid decClass */ 1.3355 +/* returns a constant string describing the class (max 13+1 chars) */ 1.3356 +/* ------------------------------------------------------------------ */ 1.3357 +const char *uprv_decNumberClassToString(enum decClass eclass) { 1.3358 + if (eclass==DEC_CLASS_POS_NORMAL) return DEC_ClassString_PN; 1.3359 + if (eclass==DEC_CLASS_NEG_NORMAL) return DEC_ClassString_NN; 1.3360 + if (eclass==DEC_CLASS_POS_ZERO) return DEC_ClassString_PZ; 1.3361 + if (eclass==DEC_CLASS_NEG_ZERO) return DEC_ClassString_NZ; 1.3362 + if (eclass==DEC_CLASS_POS_SUBNORMAL) return DEC_ClassString_PS; 1.3363 + if (eclass==DEC_CLASS_NEG_SUBNORMAL) return DEC_ClassString_NS; 1.3364 + if (eclass==DEC_CLASS_POS_INF) return DEC_ClassString_PI; 1.3365 + if (eclass==DEC_CLASS_NEG_INF) return DEC_ClassString_NI; 1.3366 + if (eclass==DEC_CLASS_QNAN) return DEC_ClassString_QN; 1.3367 + if (eclass==DEC_CLASS_SNAN) return DEC_ClassString_SN; 1.3368 + return DEC_ClassString_UN; /* Unknown */ 1.3369 + } /* decNumberClassToString */ 1.3370 + 1.3371 +/* ------------------------------------------------------------------ */ 1.3372 +/* decNumberCopy -- copy a number */ 1.3373 +/* */ 1.3374 +/* dest is the target decNumber */ 1.3375 +/* src is the source decNumber */ 1.3376 +/* returns dest */ 1.3377 +/* */ 1.3378 +/* (dest==src is allowed and is a no-op) */ 1.3379 +/* All fields are updated as required. This is a utility operation, */ 1.3380 +/* so special values are unchanged and no error is possible. */ 1.3381 +/* ------------------------------------------------------------------ */ 1.3382 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCopy(decNumber *dest, const decNumber *src) { 1.3383 + 1.3384 + #if DECCHECK 1.3385 + if (src==NULL) return uprv_decNumberZero(dest); 1.3386 + #endif 1.3387 + 1.3388 + if (dest==src) return dest; /* no copy required */ 1.3389 + 1.3390 + /* Use explicit assignments here as structure assignment could copy */ 1.3391 + /* more than just the lsu (for small DECDPUN). This would not affect */ 1.3392 + /* the value of the results, but could disturb test harness spill */ 1.3393 + /* checking. */ 1.3394 + dest->bits=src->bits; 1.3395 + dest->exponent=src->exponent; 1.3396 + dest->digits=src->digits; 1.3397 + dest->lsu[0]=src->lsu[0]; 1.3398 + if (src->digits>DECDPUN) { /* more Units to come */ 1.3399 + const Unit *smsup, *s; /* work */ 1.3400 + Unit *d; /* .. */ 1.3401 + /* memcpy for the remaining Units would be safe as they cannot */ 1.3402 + /* overlap. However, this explicit loop is faster in short cases. */ 1.3403 + d=dest->lsu+1; /* -> first destination */ 1.3404 + smsup=src->lsu+D2U(src->digits); /* -> source msu+1 */ 1.3405 + for (s=src->lsu+1; s<smsup; s++, d++) *d=*s; 1.3406 + } 1.3407 + return dest; 1.3408 + } /* decNumberCopy */ 1.3409 + 1.3410 +/* ------------------------------------------------------------------ */ 1.3411 +/* decNumberCopyAbs -- quiet absolute value operator */ 1.3412 +/* */ 1.3413 +/* This sets C = abs(A) */ 1.3414 +/* */ 1.3415 +/* res is C, the result. C may be A */ 1.3416 +/* rhs is A */ 1.3417 +/* */ 1.3418 +/* C must have space for set->digits digits. */ 1.3419 +/* No exception or error can occur; this is a quiet bitwise operation.*/ 1.3420 +/* See also decNumberAbs for a checking version of this. */ 1.3421 +/* ------------------------------------------------------------------ */ 1.3422 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCopyAbs(decNumber *res, const decNumber *rhs) { 1.3423 + #if DECCHECK 1.3424 + if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res; 1.3425 + #endif 1.3426 + uprv_decNumberCopy(res, rhs); 1.3427 + res->bits&=~DECNEG; /* turn off sign */ 1.3428 + return res; 1.3429 + } /* decNumberCopyAbs */ 1.3430 + 1.3431 +/* ------------------------------------------------------------------ */ 1.3432 +/* decNumberCopyNegate -- quiet negate value operator */ 1.3433 +/* */ 1.3434 +/* This sets C = negate(A) */ 1.3435 +/* */ 1.3436 +/* res is C, the result. C may be A */ 1.3437 +/* rhs is A */ 1.3438 +/* */ 1.3439 +/* C must have space for set->digits digits. */ 1.3440 +/* No exception or error can occur; this is a quiet bitwise operation.*/ 1.3441 +/* See also decNumberMinus for a checking version of this. */ 1.3442 +/* ------------------------------------------------------------------ */ 1.3443 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCopyNegate(decNumber *res, const decNumber *rhs) { 1.3444 + #if DECCHECK 1.3445 + if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res; 1.3446 + #endif 1.3447 + uprv_decNumberCopy(res, rhs); 1.3448 + res->bits^=DECNEG; /* invert the sign */ 1.3449 + return res; 1.3450 + } /* decNumberCopyNegate */ 1.3451 + 1.3452 +/* ------------------------------------------------------------------ */ 1.3453 +/* decNumberCopySign -- quiet copy and set sign operator */ 1.3454 +/* */ 1.3455 +/* This sets C = A with the sign of B */ 1.3456 +/* */ 1.3457 +/* res is C, the result. C may be A */ 1.3458 +/* lhs is A */ 1.3459 +/* rhs is B */ 1.3460 +/* */ 1.3461 +/* C must have space for set->digits digits. */ 1.3462 +/* No exception or error can occur; this is a quiet bitwise operation.*/ 1.3463 +/* ------------------------------------------------------------------ */ 1.3464 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberCopySign(decNumber *res, const decNumber *lhs, 1.3465 + const decNumber *rhs) { 1.3466 + uByte sign; /* rhs sign */ 1.3467 + #if DECCHECK 1.3468 + if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res; 1.3469 + #endif 1.3470 + sign=rhs->bits & DECNEG; /* save sign bit */ 1.3471 + uprv_decNumberCopy(res, lhs); 1.3472 + res->bits&=~DECNEG; /* clear the sign */ 1.3473 + res->bits|=sign; /* set from rhs */ 1.3474 + return res; 1.3475 + } /* decNumberCopySign */ 1.3476 + 1.3477 +/* ------------------------------------------------------------------ */ 1.3478 +/* decNumberGetBCD -- get the coefficient in BCD8 */ 1.3479 +/* dn is the source decNumber */ 1.3480 +/* bcd is the uInt array that will receive dn->digits BCD bytes, */ 1.3481 +/* most-significant at offset 0 */ 1.3482 +/* returns bcd */ 1.3483 +/* */ 1.3484 +/* bcd must have at least dn->digits bytes. No error is possible; if */ 1.3485 +/* dn is a NaN or Infinite, digits must be 1 and the coefficient 0. */ 1.3486 +/* ------------------------------------------------------------------ */ 1.3487 +U_CAPI uByte * U_EXPORT2 uprv_decNumberGetBCD(const decNumber *dn, uByte *bcd) { 1.3488 + uByte *ub=bcd+dn->digits-1; /* -> lsd */ 1.3489 + const Unit *up=dn->lsu; /* Unit pointer, -> lsu */ 1.3490 + 1.3491 + #if DECDPUN==1 /* trivial simple copy */ 1.3492 + for (; ub>=bcd; ub--, up++) *ub=*up; 1.3493 + #else /* chopping needed */ 1.3494 + uInt u=*up; /* work */ 1.3495 + uInt cut=DECDPUN; /* downcounter through unit */ 1.3496 + for (; ub>=bcd; ub--) { 1.3497 + *ub=(uByte)(u%10); /* [*6554 trick inhibits, here] */ 1.3498 + u=u/10; 1.3499 + cut--; 1.3500 + if (cut>0) continue; /* more in this unit */ 1.3501 + up++; 1.3502 + u=*up; 1.3503 + cut=DECDPUN; 1.3504 + } 1.3505 + #endif 1.3506 + return bcd; 1.3507 + } /* decNumberGetBCD */ 1.3508 + 1.3509 +/* ------------------------------------------------------------------ */ 1.3510 +/* decNumberSetBCD -- set (replace) the coefficient from BCD8 */ 1.3511 +/* dn is the target decNumber */ 1.3512 +/* bcd is the uInt array that will source n BCD bytes, most- */ 1.3513 +/* significant at offset 0 */ 1.3514 +/* n is the number of digits in the source BCD array (bcd) */ 1.3515 +/* returns dn */ 1.3516 +/* */ 1.3517 +/* dn must have space for at least n digits. No error is possible; */ 1.3518 +/* if dn is a NaN, or Infinite, or is to become a zero, n must be 1 */ 1.3519 +/* and bcd[0] zero. */ 1.3520 +/* ------------------------------------------------------------------ */ 1.3521 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberSetBCD(decNumber *dn, const uByte *bcd, uInt n) { 1.3522 + Unit *up=dn->lsu+D2U(dn->digits)-1; /* -> msu [target pointer] */ 1.3523 + const uByte *ub=bcd; /* -> source msd */ 1.3524 + 1.3525 + #if DECDPUN==1 /* trivial simple copy */ 1.3526 + for (; ub<bcd+n; ub++, up--) *up=*ub; 1.3527 + #else /* some assembly needed */ 1.3528 + /* calculate how many digits in msu, and hence first cut */ 1.3529 + Int cut=MSUDIGITS(n); /* [faster than remainder] */ 1.3530 + for (;up>=dn->lsu; up--) { /* each Unit from msu */ 1.3531 + *up=0; /* will take <=DECDPUN digits */ 1.3532 + for (; cut>0; ub++, cut--) *up=X10(*up)+*ub; 1.3533 + cut=DECDPUN; /* next Unit has all digits */ 1.3534 + } 1.3535 + #endif 1.3536 + dn->digits=n; /* set digit count */ 1.3537 + return dn; 1.3538 + } /* decNumberSetBCD */ 1.3539 + 1.3540 +/* ------------------------------------------------------------------ */ 1.3541 +/* decNumberIsNormal -- test normality of a decNumber */ 1.3542 +/* dn is the decNumber to test */ 1.3543 +/* set is the context to use for Emin */ 1.3544 +/* returns 1 if |dn| is finite and >=Nmin, 0 otherwise */ 1.3545 +/* ------------------------------------------------------------------ */ 1.3546 +Int uprv_decNumberIsNormal(const decNumber *dn, decContext *set) { 1.3547 + Int ae; /* adjusted exponent */ 1.3548 + #if DECCHECK 1.3549 + if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0; 1.3550 + #endif 1.3551 + 1.3552 + if (decNumberIsSpecial(dn)) return 0; /* not finite */ 1.3553 + if (decNumberIsZero(dn)) return 0; /* not non-zero */ 1.3554 + 1.3555 + ae=dn->exponent+dn->digits-1; /* adjusted exponent */ 1.3556 + if (ae<set->emin) return 0; /* is subnormal */ 1.3557 + return 1; 1.3558 + } /* decNumberIsNormal */ 1.3559 + 1.3560 +/* ------------------------------------------------------------------ */ 1.3561 +/* decNumberIsSubnormal -- test subnormality of a decNumber */ 1.3562 +/* dn is the decNumber to test */ 1.3563 +/* set is the context to use for Emin */ 1.3564 +/* returns 1 if |dn| is finite, non-zero, and <Nmin, 0 otherwise */ 1.3565 +/* ------------------------------------------------------------------ */ 1.3566 +Int uprv_decNumberIsSubnormal(const decNumber *dn, decContext *set) { 1.3567 + Int ae; /* adjusted exponent */ 1.3568 + #if DECCHECK 1.3569 + if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0; 1.3570 + #endif 1.3571 + 1.3572 + if (decNumberIsSpecial(dn)) return 0; /* not finite */ 1.3573 + if (decNumberIsZero(dn)) return 0; /* not non-zero */ 1.3574 + 1.3575 + ae=dn->exponent+dn->digits-1; /* adjusted exponent */ 1.3576 + if (ae<set->emin) return 1; /* is subnormal */ 1.3577 + return 0; 1.3578 + } /* decNumberIsSubnormal */ 1.3579 + 1.3580 +/* ------------------------------------------------------------------ */ 1.3581 +/* decNumberTrim -- remove insignificant zeros */ 1.3582 +/* */ 1.3583 +/* dn is the number to trim */ 1.3584 +/* returns dn */ 1.3585 +/* */ 1.3586 +/* All fields are updated as required. This is a utility operation, */ 1.3587 +/* so special values are unchanged and no error is possible. The */ 1.3588 +/* zeros are removed unconditionally. */ 1.3589 +/* ------------------------------------------------------------------ */ 1.3590 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberTrim(decNumber *dn) { 1.3591 + Int dropped; /* work */ 1.3592 + decContext set; /* .. */ 1.3593 + #if DECCHECK 1.3594 + if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn; 1.3595 + #endif 1.3596 + uprv_decContextDefault(&set, DEC_INIT_BASE); /* clamp=0 */ 1.3597 + return decTrim(dn, &set, 0, 1, &dropped); 1.3598 + } /* decNumberTrim */ 1.3599 + 1.3600 +/* ------------------------------------------------------------------ */ 1.3601 +/* decNumberVersion -- return the name and version of this module */ 1.3602 +/* */ 1.3603 +/* No error is possible. */ 1.3604 +/* ------------------------------------------------------------------ */ 1.3605 +const char * uprv_decNumberVersion(void) { 1.3606 + return DECVERSION; 1.3607 + } /* decNumberVersion */ 1.3608 + 1.3609 +/* ------------------------------------------------------------------ */ 1.3610 +/* decNumberZero -- set a number to 0 */ 1.3611 +/* */ 1.3612 +/* dn is the number to set, with space for one digit */ 1.3613 +/* returns dn */ 1.3614 +/* */ 1.3615 +/* No error is possible. */ 1.3616 +/* ------------------------------------------------------------------ */ 1.3617 +/* Memset is not used as it is much slower in some environments. */ 1.3618 +U_CAPI decNumber * U_EXPORT2 uprv_decNumberZero(decNumber *dn) { 1.3619 + 1.3620 + #if DECCHECK 1.3621 + if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn; 1.3622 + #endif 1.3623 + 1.3624 + dn->bits=0; 1.3625 + dn->exponent=0; 1.3626 + dn->digits=1; 1.3627 + dn->lsu[0]=0; 1.3628 + return dn; 1.3629 + } /* decNumberZero */ 1.3630 + 1.3631 +/* ================================================================== */ 1.3632 +/* Local routines */ 1.3633 +/* ================================================================== */ 1.3634 + 1.3635 +/* ------------------------------------------------------------------ */ 1.3636 +/* decToString -- lay out a number into a string */ 1.3637 +/* */ 1.3638 +/* dn is the number to lay out */ 1.3639 +/* string is where to lay out the number */ 1.3640 +/* eng is 1 if Engineering, 0 if Scientific */ 1.3641 +/* */ 1.3642 +/* string must be at least dn->digits+14 characters long */ 1.3643 +/* No error is possible. */ 1.3644 +/* */ 1.3645 +/* Note that this routine can generate a -0 or 0.000. These are */ 1.3646 +/* never generated in subset to-number or arithmetic, but can occur */ 1.3647 +/* in non-subset arithmetic (e.g., -1*0 or 1.234-1.234). */ 1.3648 +/* ------------------------------------------------------------------ */ 1.3649 +/* If DECCHECK is enabled the string "?" is returned if a number is */ 1.3650 +/* invalid. */ 1.3651 +static void decToString(const decNumber *dn, char *string, Flag eng) { 1.3652 + Int exp=dn->exponent; /* local copy */ 1.3653 + Int e; /* E-part value */ 1.3654 + Int pre; /* digits before the '.' */ 1.3655 + Int cut; /* for counting digits in a Unit */ 1.3656 + char *c=string; /* work [output pointer] */ 1.3657 + const Unit *up=dn->lsu+D2U(dn->digits)-1; /* -> msu [input pointer] */ 1.3658 + uInt u, pow; /* work */ 1.3659 + 1.3660 + #if DECCHECK 1.3661 + if (decCheckOperands(DECUNRESU, dn, DECUNUSED, DECUNCONT)) { 1.3662 + strcpy(string, "?"); 1.3663 + return;} 1.3664 + #endif 1.3665 + 1.3666 + if (decNumberIsNegative(dn)) { /* Negatives get a minus */ 1.3667 + *c='-'; 1.3668 + c++; 1.3669 + } 1.3670 + if (dn->bits&DECSPECIAL) { /* Is a special value */ 1.3671 + if (decNumberIsInfinite(dn)) { 1.3672 + strcpy(c, "Inf"); 1.3673 + strcpy(c+3, "inity"); 1.3674 + return;} 1.3675 + /* a NaN */ 1.3676 + if (dn->bits&DECSNAN) { /* signalling NaN */ 1.3677 + *c='s'; 1.3678 + c++; 1.3679 + } 1.3680 + strcpy(c, "NaN"); 1.3681 + c+=3; /* step past */ 1.3682 + /* if not a clean non-zero coefficient, that's all there is in a */ 1.3683 + /* NaN string */ 1.3684 + if (exp!=0 || (*dn->lsu==0 && dn->digits==1)) return; 1.3685 + /* [drop through to add integer] */ 1.3686 + } 1.3687 + 1.3688 + /* calculate how many digits in msu, and hence first cut */ 1.3689 + cut=MSUDIGITS(dn->digits); /* [faster than remainder] */ 1.3690 + cut--; /* power of ten for digit */ 1.3691 + 1.3692 + if (exp==0) { /* simple integer [common fastpath] */ 1.3693 + for (;up>=dn->lsu; up--) { /* each Unit from msu */ 1.3694 + u=*up; /* contains DECDPUN digits to lay out */ 1.3695 + for (; cut>=0; c++, cut--) TODIGIT(u, cut, c, pow); 1.3696 + cut=DECDPUN-1; /* next Unit has all digits */ 1.3697 + } 1.3698 + *c='\0'; /* terminate the string */ 1.3699 + return;} 1.3700 + 1.3701 + /* non-0 exponent -- assume plain form */ 1.3702 + pre=dn->digits+exp; /* digits before '.' */ 1.3703 + e=0; /* no E */ 1.3704 + if ((exp>0) || (pre<-5)) { /* need exponential form */ 1.3705 + e=exp+dn->digits-1; /* calculate E value */ 1.3706 + pre=1; /* assume one digit before '.' */ 1.3707 + if (eng && (e!=0)) { /* engineering: may need to adjust */ 1.3708 + Int adj; /* adjustment */ 1.3709 + /* The C remainder operator is undefined for negative numbers, so */ 1.3710 + /* a positive remainder calculation must be used here */ 1.3711 + if (e<0) { 1.3712 + adj=(-e)%3; 1.3713 + if (adj!=0) adj=3-adj; 1.3714 + } 1.3715 + else { /* e>0 */ 1.3716 + adj=e%3; 1.3717 + } 1.3718 + e=e-adj; 1.3719 + /* if dealing with zero still produce an exponent which is a */ 1.3720 + /* multiple of three, as expected, but there will only be the */ 1.3721 + /* one zero before the E, still. Otherwise note the padding. */ 1.3722 + if (!ISZERO(dn)) pre+=adj; 1.3723 + else { /* is zero */ 1.3724 + if (adj!=0) { /* 0.00Esnn needed */ 1.3725 + e=e+3; 1.3726 + pre=-(2-adj); 1.3727 + } 1.3728 + } /* zero */ 1.3729 + } /* eng */ 1.3730 + } /* need exponent */ 1.3731 + 1.3732 + /* lay out the digits of the coefficient, adding 0s and . as needed */ 1.3733 + u=*up; 1.3734 + if (pre>0) { /* xxx.xxx or xx00 (engineering) form */ 1.3735 + Int n=pre; 1.3736 + for (; pre>0; pre--, c++, cut--) { 1.3737 + if (cut<0) { /* need new Unit */ 1.3738 + if (up==dn->lsu) break; /* out of input digits (pre>digits) */ 1.3739 + up--; 1.3740 + cut=DECDPUN-1; 1.3741 + u=*up; 1.3742 + } 1.3743 + TODIGIT(u, cut, c, pow); 1.3744 + } 1.3745 + if (n<dn->digits) { /* more to come, after '.' */ 1.3746 + *c='.'; c++; 1.3747 + for (;; c++, cut--) { 1.3748 + if (cut<0) { /* need new Unit */ 1.3749 + if (up==dn->lsu) break; /* out of input digits */ 1.3750 + up--; 1.3751 + cut=DECDPUN-1; 1.3752 + u=*up; 1.3753 + } 1.3754 + TODIGIT(u, cut, c, pow); 1.3755 + } 1.3756 + } 1.3757 + else for (; pre>0; pre--, c++) *c='0'; /* 0 padding (for engineering) needed */ 1.3758 + } 1.3759 + else { /* 0.xxx or 0.000xxx form */ 1.3760 + *c='0'; c++; 1.3761 + *c='.'; c++; 1.3762 + for (; pre<0; pre++, c++) *c='0'; /* add any 0's after '.' */ 1.3763 + for (; ; c++, cut--) { 1.3764 + if (cut<0) { /* need new Unit */ 1.3765 + if (up==dn->lsu) break; /* out of input digits */ 1.3766 + up--; 1.3767 + cut=DECDPUN-1; 1.3768 + u=*up; 1.3769 + } 1.3770 + TODIGIT(u, cut, c, pow); 1.3771 + } 1.3772 + } 1.3773 + 1.3774 + /* Finally add the E-part, if needed. It will never be 0, has a 1.3775 + base maximum and minimum of +999999999 through -999999999, but 1.3776 + could range down to -1999999998 for anormal numbers */ 1.3777 + if (e!=0) { 1.3778 + Flag had=0; /* 1=had non-zero */ 1.3779 + *c='E'; c++; 1.3780 + *c='+'; c++; /* assume positive */ 1.3781 + u=e; /* .. */ 1.3782 + if (e<0) { 1.3783 + *(c-1)='-'; /* oops, need - */ 1.3784 + u=-e; /* uInt, please */ 1.3785 + } 1.3786 + /* lay out the exponent [_itoa or equivalent is not ANSI C] */ 1.3787 + for (cut=9; cut>=0; cut--) { 1.3788 + TODIGIT(u, cut, c, pow); 1.3789 + if (*c=='0' && !had) continue; /* skip leading zeros */ 1.3790 + had=1; /* had non-0 */ 1.3791 + c++; /* step for next */ 1.3792 + } /* cut */ 1.3793 + } 1.3794 + *c='\0'; /* terminate the string (all paths) */ 1.3795 + return; 1.3796 + } /* decToString */ 1.3797 + 1.3798 +/* ------------------------------------------------------------------ */ 1.3799 +/* decAddOp -- add/subtract operation */ 1.3800 +/* */ 1.3801 +/* This computes C = A + B */ 1.3802 +/* */ 1.3803 +/* res is C, the result. C may be A and/or B (e.g., X=X+X) */ 1.3804 +/* lhs is A */ 1.3805 +/* rhs is B */ 1.3806 +/* set is the context */ 1.3807 +/* negate is DECNEG if rhs should be negated, or 0 otherwise */ 1.3808 +/* status accumulates status for the caller */ 1.3809 +/* */ 1.3810 +/* C must have space for set->digits digits. */ 1.3811 +/* Inexact in status must be 0 for correct Exact zero sign in result */ 1.3812 +/* ------------------------------------------------------------------ */ 1.3813 +/* If possible, the coefficient is calculated directly into C. */ 1.3814 +/* However, if: */ 1.3815 +/* -- a digits+1 calculation is needed because the numbers are */ 1.3816 +/* unaligned and span more than set->digits digits */ 1.3817 +/* -- a carry to digits+1 digits looks possible */ 1.3818 +/* -- C is the same as A or B, and the result would destructively */ 1.3819 +/* overlap the A or B coefficient */ 1.3820 +/* then the result must be calculated into a temporary buffer. In */ 1.3821 +/* this case a local (stack) buffer is used if possible, and only if */ 1.3822 +/* too long for that does malloc become the final resort. */ 1.3823 +/* */ 1.3824 +/* Misalignment is handled as follows: */ 1.3825 +/* Apad: (AExp>BExp) Swap operands and proceed as for BExp>AExp. */ 1.3826 +/* BPad: Apply the padding by a combination of shifting (whole */ 1.3827 +/* units) and multiplication (part units). */ 1.3828 +/* */ 1.3829 +/* Addition, especially x=x+1, is speed-critical. */ 1.3830 +/* The static buffer is larger than might be expected to allow for */ 1.3831 +/* calls from higher-level funtions (notable exp). */ 1.3832 +/* ------------------------------------------------------------------ */ 1.3833 +static decNumber * decAddOp(decNumber *res, const decNumber *lhs, 1.3834 + const decNumber *rhs, decContext *set, 1.3835 + uByte negate, uInt *status) { 1.3836 + #if DECSUBSET 1.3837 + decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */ 1.3838 + decNumber *allocrhs=NULL; /* .., rhs */ 1.3839 + #endif 1.3840 + Int rhsshift; /* working shift (in Units) */ 1.3841 + Int maxdigits; /* longest logical length */ 1.3842 + Int mult; /* multiplier */ 1.3843 + Int residue; /* rounding accumulator */ 1.3844 + uByte bits; /* result bits */ 1.3845 + Flag diffsign; /* non-0 if arguments have different sign */ 1.3846 + Unit *acc; /* accumulator for result */ 1.3847 + Unit accbuff[SD2U(DECBUFFER*2+20)]; /* local buffer [*2+20 reduces many */ 1.3848 + /* allocations when called from */ 1.3849 + /* other operations, notable exp] */ 1.3850 + Unit *allocacc=NULL; /* -> allocated acc buffer, iff allocated */ 1.3851 + Int reqdigits=set->digits; /* local copy; requested DIGITS */ 1.3852 + Int padding; /* work */ 1.3853 + 1.3854 + #if DECCHECK 1.3855 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.3856 + #endif 1.3857 + 1.3858 + do { /* protect allocated storage */ 1.3859 + #if DECSUBSET 1.3860 + if (!set->extended) { 1.3861 + /* reduce operands and set lostDigits status, as needed */ 1.3862 + if (lhs->digits>reqdigits) { 1.3863 + alloclhs=decRoundOperand(lhs, set, status); 1.3864 + if (alloclhs==NULL) break; 1.3865 + lhs=alloclhs; 1.3866 + } 1.3867 + if (rhs->digits>reqdigits) { 1.3868 + allocrhs=decRoundOperand(rhs, set, status); 1.3869 + if (allocrhs==NULL) break; 1.3870 + rhs=allocrhs; 1.3871 + } 1.3872 + } 1.3873 + #endif 1.3874 + /* [following code does not require input rounding] */ 1.3875 + 1.3876 + /* note whether signs differ [used all paths] */ 1.3877 + diffsign=(Flag)((lhs->bits^rhs->bits^negate)&DECNEG); 1.3878 + 1.3879 + /* handle infinities and NaNs */ 1.3880 + if (SPECIALARGS) { /* a special bit set */ 1.3881 + if (SPECIALARGS & (DECSNAN | DECNAN)) /* a NaN */ 1.3882 + decNaNs(res, lhs, rhs, set, status); 1.3883 + else { /* one or two infinities */ 1.3884 + if (decNumberIsInfinite(lhs)) { /* LHS is infinity */ 1.3885 + /* two infinities with different signs is invalid */ 1.3886 + if (decNumberIsInfinite(rhs) && diffsign) { 1.3887 + *status|=DEC_Invalid_operation; 1.3888 + break; 1.3889 + } 1.3890 + bits=lhs->bits & DECNEG; /* get sign from LHS */ 1.3891 + } 1.3892 + else bits=(rhs->bits^negate) & DECNEG;/* RHS must be Infinity */ 1.3893 + bits|=DECINF; 1.3894 + uprv_decNumberZero(res); 1.3895 + res->bits=bits; /* set +/- infinity */ 1.3896 + } /* an infinity */ 1.3897 + break; 1.3898 + } 1.3899 + 1.3900 + /* Quick exit for add 0s; return the non-0, modified as need be */ 1.3901 + if (ISZERO(lhs)) { 1.3902 + Int adjust; /* work */ 1.3903 + Int lexp=lhs->exponent; /* save in case LHS==RES */ 1.3904 + bits=lhs->bits; /* .. */ 1.3905 + residue=0; /* clear accumulator */ 1.3906 + decCopyFit(res, rhs, set, &residue, status); /* copy (as needed) */ 1.3907 + res->bits^=negate; /* flip if rhs was negated */ 1.3908 + #if DECSUBSET 1.3909 + if (set->extended) { /* exponents on zeros count */ 1.3910 + #endif 1.3911 + /* exponent will be the lower of the two */ 1.3912 + adjust=lexp-res->exponent; /* adjustment needed [if -ve] */ 1.3913 + if (ISZERO(res)) { /* both 0: special IEEE 754 rules */ 1.3914 + if (adjust<0) res->exponent=lexp; /* set exponent */ 1.3915 + /* 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0 */ 1.3916 + if (diffsign) { 1.3917 + if (set->round!=DEC_ROUND_FLOOR) res->bits=0; 1.3918 + else res->bits=DECNEG; /* preserve 0 sign */ 1.3919 + } 1.3920 + } 1.3921 + else { /* non-0 res */ 1.3922 + if (adjust<0) { /* 0-padding needed */ 1.3923 + if ((res->digits-adjust)>set->digits) { 1.3924 + adjust=res->digits-set->digits; /* to fit exactly */ 1.3925 + *status|=DEC_Rounded; /* [but exact] */ 1.3926 + } 1.3927 + res->digits=decShiftToMost(res->lsu, res->digits, -adjust); 1.3928 + res->exponent+=adjust; /* set the exponent. */ 1.3929 + } 1.3930 + } /* non-0 res */ 1.3931 + #if DECSUBSET 1.3932 + } /* extended */ 1.3933 + #endif 1.3934 + decFinish(res, set, &residue, status); /* clean and finalize */ 1.3935 + break;} 1.3936 + 1.3937 + if (ISZERO(rhs)) { /* [lhs is non-zero] */ 1.3938 + Int adjust; /* work */ 1.3939 + Int rexp=rhs->exponent; /* save in case RHS==RES */ 1.3940 + bits=rhs->bits; /* be clean */ 1.3941 + residue=0; /* clear accumulator */ 1.3942 + decCopyFit(res, lhs, set, &residue, status); /* copy (as needed) */ 1.3943 + #if DECSUBSET 1.3944 + if (set->extended) { /* exponents on zeros count */ 1.3945 + #endif 1.3946 + /* exponent will be the lower of the two */ 1.3947 + /* [0-0 case handled above] */ 1.3948 + adjust=rexp-res->exponent; /* adjustment needed [if -ve] */ 1.3949 + if (adjust<0) { /* 0-padding needed */ 1.3950 + if ((res->digits-adjust)>set->digits) { 1.3951 + adjust=res->digits-set->digits; /* to fit exactly */ 1.3952 + *status|=DEC_Rounded; /* [but exact] */ 1.3953 + } 1.3954 + res->digits=decShiftToMost(res->lsu, res->digits, -adjust); 1.3955 + res->exponent+=adjust; /* set the exponent. */ 1.3956 + } 1.3957 + #if DECSUBSET 1.3958 + } /* extended */ 1.3959 + #endif 1.3960 + decFinish(res, set, &residue, status); /* clean and finalize */ 1.3961 + break;} 1.3962 + 1.3963 + /* [NB: both fastpath and mainpath code below assume these cases */ 1.3964 + /* (notably 0-0) have already been handled] */ 1.3965 + 1.3966 + /* calculate the padding needed to align the operands */ 1.3967 + padding=rhs->exponent-lhs->exponent; 1.3968 + 1.3969 + /* Fastpath cases where the numbers are aligned and normal, the RHS */ 1.3970 + /* is all in one unit, no operand rounding is needed, and no carry, */ 1.3971 + /* lengthening, or borrow is needed */ 1.3972 + if (padding==0 1.3973 + && rhs->digits<=DECDPUN 1.3974 + && rhs->exponent>=set->emin /* [some normals drop through] */ 1.3975 + && rhs->exponent<=set->emax-set->digits+1 /* [could clamp] */ 1.3976 + && rhs->digits<=reqdigits 1.3977 + && lhs->digits<=reqdigits) { 1.3978 + Int partial=*lhs->lsu; 1.3979 + if (!diffsign) { /* adding */ 1.3980 + partial+=*rhs->lsu; 1.3981 + if ((partial<=DECDPUNMAX) /* result fits in unit */ 1.3982 + && (lhs->digits>=DECDPUN || /* .. and no digits-count change */ 1.3983 + partial<(Int)powers[lhs->digits])) { /* .. */ 1.3984 + if (res!=lhs) uprv_decNumberCopy(res, lhs); /* not in place */ 1.3985 + *res->lsu=(Unit)partial; /* [copy could have overwritten RHS] */ 1.3986 + break; 1.3987 + } 1.3988 + /* else drop out for careful add */ 1.3989 + } 1.3990 + else { /* signs differ */ 1.3991 + partial-=*rhs->lsu; 1.3992 + if (partial>0) { /* no borrow needed, and non-0 result */ 1.3993 + if (res!=lhs) uprv_decNumberCopy(res, lhs); /* not in place */ 1.3994 + *res->lsu=(Unit)partial; 1.3995 + /* this could have reduced digits [but result>0] */ 1.3996 + res->digits=decGetDigits(res->lsu, D2U(res->digits)); 1.3997 + break; 1.3998 + } 1.3999 + /* else drop out for careful subtract */ 1.4000 + } 1.4001 + } 1.4002 + 1.4003 + /* Now align (pad) the lhs or rhs so they can be added or */ 1.4004 + /* subtracted, as necessary. If one number is much larger than */ 1.4005 + /* the other (that is, if in plain form there is a least one */ 1.4006 + /* digit between the lowest digit of one and the highest of the */ 1.4007 + /* other) padding with up to DIGITS-1 trailing zeros may be */ 1.4008 + /* needed; then apply rounding (as exotic rounding modes may be */ 1.4009 + /* affected by the residue). */ 1.4010 + rhsshift=0; /* rhs shift to left (padding) in Units */ 1.4011 + bits=lhs->bits; /* assume sign is that of LHS */ 1.4012 + mult=1; /* likely multiplier */ 1.4013 + 1.4014 + /* [if padding==0 the operands are aligned; no padding is needed] */ 1.4015 + if (padding!=0) { 1.4016 + /* some padding needed; always pad the RHS, as any required */ 1.4017 + /* padding can then be effected by a simple combination of */ 1.4018 + /* shifts and a multiply */ 1.4019 + Flag swapped=0; 1.4020 + if (padding<0) { /* LHS needs the padding */ 1.4021 + const decNumber *t; 1.4022 + padding=-padding; /* will be +ve */ 1.4023 + bits=(uByte)(rhs->bits^negate); /* assumed sign is now that of RHS */ 1.4024 + t=lhs; lhs=rhs; rhs=t; 1.4025 + swapped=1; 1.4026 + } 1.4027 + 1.4028 + /* If, after pad, rhs would be longer than lhs by digits+1 or */ 1.4029 + /* more then lhs cannot affect the answer, except as a residue, */ 1.4030 + /* so only need to pad up to a length of DIGITS+1. */ 1.4031 + if (rhs->digits+padding > lhs->digits+reqdigits+1) { 1.4032 + /* The RHS is sufficient */ 1.4033 + /* for residue use the relative sign indication... */ 1.4034 + Int shift=reqdigits-rhs->digits; /* left shift needed */ 1.4035 + residue=1; /* residue for rounding */ 1.4036 + if (diffsign) residue=-residue; /* signs differ */ 1.4037 + /* copy, shortening if necessary */ 1.4038 + decCopyFit(res, rhs, set, &residue, status); 1.4039 + /* if it was already shorter, then need to pad with zeros */ 1.4040 + if (shift>0) { 1.4041 + res->digits=decShiftToMost(res->lsu, res->digits, shift); 1.4042 + res->exponent-=shift; /* adjust the exponent. */ 1.4043 + } 1.4044 + /* flip the result sign if unswapped and rhs was negated */ 1.4045 + if (!swapped) res->bits^=negate; 1.4046 + decFinish(res, set, &residue, status); /* done */ 1.4047 + break;} 1.4048 + 1.4049 + /* LHS digits may affect result */ 1.4050 + rhsshift=D2U(padding+1)-1; /* this much by Unit shift .. */ 1.4051 + mult=powers[padding-(rhsshift*DECDPUN)]; /* .. this by multiplication */ 1.4052 + } /* padding needed */ 1.4053 + 1.4054 + if (diffsign) mult=-mult; /* signs differ */ 1.4055 + 1.4056 + /* determine the longer operand */ 1.4057 + maxdigits=rhs->digits+padding; /* virtual length of RHS */ 1.4058 + if (lhs->digits>maxdigits) maxdigits=lhs->digits; 1.4059 + 1.4060 + /* Decide on the result buffer to use; if possible place directly */ 1.4061 + /* into result. */ 1.4062 + acc=res->lsu; /* assume add direct to result */ 1.4063 + /* If destructive overlap, or the number is too long, or a carry or */ 1.4064 + /* borrow to DIGITS+1 might be possible, a buffer must be used. */ 1.4065 + /* [Might be worth more sophisticated tests when maxdigits==reqdigits] */ 1.4066 + if ((maxdigits>=reqdigits) /* is, or could be, too large */ 1.4067 + || (res==rhs && rhsshift>0)) { /* destructive overlap */ 1.4068 + /* buffer needed, choose it; units for maxdigits digits will be */ 1.4069 + /* needed, +1 Unit for carry or borrow */ 1.4070 + Int need=D2U(maxdigits)+1; 1.4071 + acc=accbuff; /* assume use local buffer */ 1.4072 + if (need*sizeof(Unit)>sizeof(accbuff)) { 1.4073 + /* printf("malloc add %ld %ld\n", need, sizeof(accbuff)); */ 1.4074 + allocacc=(Unit *)malloc(need*sizeof(Unit)); 1.4075 + if (allocacc==NULL) { /* hopeless -- abandon */ 1.4076 + *status|=DEC_Insufficient_storage; 1.4077 + break;} 1.4078 + acc=allocacc; 1.4079 + } 1.4080 + } 1.4081 + 1.4082 + res->bits=(uByte)(bits&DECNEG); /* it's now safe to overwrite.. */ 1.4083 + res->exponent=lhs->exponent; /* .. operands (even if aliased) */ 1.4084 + 1.4085 + #if DECTRACE 1.4086 + decDumpAr('A', lhs->lsu, D2U(lhs->digits)); 1.4087 + decDumpAr('B', rhs->lsu, D2U(rhs->digits)); 1.4088 + printf(" :h: %ld %ld\n", rhsshift, mult); 1.4089 + #endif 1.4090 + 1.4091 + /* add [A+B*m] or subtract [A+B*(-m)] */ 1.4092 + U_ASSERT(rhs->digits > 0); 1.4093 + U_ASSERT(lhs->digits > 0); 1.4094 + res->digits=decUnitAddSub(lhs->lsu, D2U(lhs->digits), 1.4095 + rhs->lsu, D2U(rhs->digits), 1.4096 + rhsshift, acc, mult) 1.4097 + *DECDPUN; /* [units -> digits] */ 1.4098 + if (res->digits<0) { /* borrowed... */ 1.4099 + res->digits=-res->digits; 1.4100 + res->bits^=DECNEG; /* flip the sign */ 1.4101 + } 1.4102 + #if DECTRACE 1.4103 + decDumpAr('+', acc, D2U(res->digits)); 1.4104 + #endif 1.4105 + 1.4106 + /* If a buffer was used the result must be copied back, possibly */ 1.4107 + /* shortening. (If no buffer was used then the result must have */ 1.4108 + /* fit, so can't need rounding and residue must be 0.) */ 1.4109 + residue=0; /* clear accumulator */ 1.4110 + if (acc!=res->lsu) { 1.4111 + #if DECSUBSET 1.4112 + if (set->extended) { /* round from first significant digit */ 1.4113 + #endif 1.4114 + /* remove leading zeros that were added due to rounding up to */ 1.4115 + /* integral Units -- before the test for rounding. */ 1.4116 + if (res->digits>reqdigits) 1.4117 + res->digits=decGetDigits(acc, D2U(res->digits)); 1.4118 + decSetCoeff(res, set, acc, res->digits, &residue, status); 1.4119 + #if DECSUBSET 1.4120 + } 1.4121 + else { /* subset arithmetic rounds from original significant digit */ 1.4122 + /* May have an underestimate. This only occurs when both */ 1.4123 + /* numbers fit in DECDPUN digits and are padding with a */ 1.4124 + /* negative multiple (-10, -100...) and the top digit(s) become */ 1.4125 + /* 0. (This only matters when using X3.274 rules where the */ 1.4126 + /* leading zero could be included in the rounding.) */ 1.4127 + if (res->digits<maxdigits) { 1.4128 + *(acc+D2U(res->digits))=0; /* ensure leading 0 is there */ 1.4129 + res->digits=maxdigits; 1.4130 + } 1.4131 + else { 1.4132 + /* remove leading zeros that added due to rounding up to */ 1.4133 + /* integral Units (but only those in excess of the original */ 1.4134 + /* maxdigits length, unless extended) before test for rounding. */ 1.4135 + if (res->digits>reqdigits) { 1.4136 + res->digits=decGetDigits(acc, D2U(res->digits)); 1.4137 + if (res->digits<maxdigits) res->digits=maxdigits; 1.4138 + } 1.4139 + } 1.4140 + decSetCoeff(res, set, acc, res->digits, &residue, status); 1.4141 + /* Now apply rounding if needed before removing leading zeros. */ 1.4142 + /* This is safe because subnormals are not a possibility */ 1.4143 + if (residue!=0) { 1.4144 + decApplyRound(res, set, residue, status); 1.4145 + residue=0; /* did what needed to be done */ 1.4146 + } 1.4147 + } /* subset */ 1.4148 + #endif 1.4149 + } /* used buffer */ 1.4150 + 1.4151 + /* strip leading zeros [these were left on in case of subset subtract] */ 1.4152 + res->digits=decGetDigits(res->lsu, D2U(res->digits)); 1.4153 + 1.4154 + /* apply checks and rounding */ 1.4155 + decFinish(res, set, &residue, status); 1.4156 + 1.4157 + /* "When the sum of two operands with opposite signs is exactly */ 1.4158 + /* zero, the sign of that sum shall be '+' in all rounding modes */ 1.4159 + /* except round toward -Infinity, in which mode that sign shall be */ 1.4160 + /* '-'." [Subset zeros also never have '-', set by decFinish.] */ 1.4161 + if (ISZERO(res) && diffsign 1.4162 + #if DECSUBSET 1.4163 + && set->extended 1.4164 + #endif 1.4165 + && (*status&DEC_Inexact)==0) { 1.4166 + if (set->round==DEC_ROUND_FLOOR) res->bits|=DECNEG; /* sign - */ 1.4167 + else res->bits&=~DECNEG; /* sign + */ 1.4168 + } 1.4169 + } while(0); /* end protected */ 1.4170 + 1.4171 + if (allocacc!=NULL) free(allocacc); /* drop any storage used */ 1.4172 + #if DECSUBSET 1.4173 + if (allocrhs!=NULL) free(allocrhs); /* .. */ 1.4174 + if (alloclhs!=NULL) free(alloclhs); /* .. */ 1.4175 + #endif 1.4176 + return res; 1.4177 + } /* decAddOp */ 1.4178 + 1.4179 +/* ------------------------------------------------------------------ */ 1.4180 +/* decDivideOp -- division operation */ 1.4181 +/* */ 1.4182 +/* This routine performs the calculations for all four division */ 1.4183 +/* operators (divide, divideInteger, remainder, remainderNear). */ 1.4184 +/* */ 1.4185 +/* C=A op B */ 1.4186 +/* */ 1.4187 +/* res is C, the result. C may be A and/or B (e.g., X=X/X) */ 1.4188 +/* lhs is A */ 1.4189 +/* rhs is B */ 1.4190 +/* set is the context */ 1.4191 +/* op is DIVIDE, DIVIDEINT, REMAINDER, or REMNEAR respectively. */ 1.4192 +/* status is the usual accumulator */ 1.4193 +/* */ 1.4194 +/* C must have space for set->digits digits. */ 1.4195 +/* */ 1.4196 +/* ------------------------------------------------------------------ */ 1.4197 +/* The underlying algorithm of this routine is the same as in the */ 1.4198 +/* 1981 S/370 implementation, that is, non-restoring long division */ 1.4199 +/* with bi-unit (rather than bi-digit) estimation for each unit */ 1.4200 +/* multiplier. In this pseudocode overview, complications for the */ 1.4201 +/* Remainder operators and division residues for exact rounding are */ 1.4202 +/* omitted for clarity. */ 1.4203 +/* */ 1.4204 +/* Prepare operands and handle special values */ 1.4205 +/* Test for x/0 and then 0/x */ 1.4206 +/* Exp =Exp1 - Exp2 */ 1.4207 +/* Exp =Exp +len(var1) -len(var2) */ 1.4208 +/* Sign=Sign1 * Sign2 */ 1.4209 +/* Pad accumulator (Var1) to double-length with 0's (pad1) */ 1.4210 +/* Pad Var2 to same length as Var1 */ 1.4211 +/* msu2pair/plus=1st 2 or 1 units of var2, +1 to allow for round */ 1.4212 +/* have=0 */ 1.4213 +/* Do until (have=digits+1 OR residue=0) */ 1.4214 +/* if exp<0 then if integer divide/residue then leave */ 1.4215 +/* this_unit=0 */ 1.4216 +/* Do forever */ 1.4217 +/* compare numbers */ 1.4218 +/* if <0 then leave inner_loop */ 1.4219 +/* if =0 then (* quick exit without subtract *) do */ 1.4220 +/* this_unit=this_unit+1; output this_unit */ 1.4221 +/* leave outer_loop; end */ 1.4222 +/* Compare lengths of numbers (mantissae): */ 1.4223 +/* If same then tops2=msu2pair -- {units 1&2 of var2} */ 1.4224 +/* else tops2=msu2plus -- {0, unit 1 of var2} */ 1.4225 +/* tops1=first_unit_of_Var1*10**DECDPUN +second_unit_of_var1 */ 1.4226 +/* mult=tops1/tops2 -- Good and safe guess at divisor */ 1.4227 +/* if mult=0 then mult=1 */ 1.4228 +/* this_unit=this_unit+mult */ 1.4229 +/* subtract */ 1.4230 +/* end inner_loop */ 1.4231 +/* if have\=0 | this_unit\=0 then do */ 1.4232 +/* output this_unit */ 1.4233 +/* have=have+1; end */ 1.4234 +/* var2=var2/10 */ 1.4235 +/* exp=exp-1 */ 1.4236 +/* end outer_loop */ 1.4237 +/* exp=exp+1 -- set the proper exponent */ 1.4238 +/* if have=0 then generate answer=0 */ 1.4239 +/* Return (Result is defined by Var1) */ 1.4240 +/* */ 1.4241 +/* ------------------------------------------------------------------ */ 1.4242 +/* Two working buffers are needed during the division; one (digits+ */ 1.4243 +/* 1) to accumulate the result, and the other (up to 2*digits+1) for */ 1.4244 +/* long subtractions. These are acc and var1 respectively. */ 1.4245 +/* var1 is a copy of the lhs coefficient, var2 is the rhs coefficient.*/ 1.4246 +/* The static buffers may be larger than might be expected to allow */ 1.4247 +/* for calls from higher-level funtions (notable exp). */ 1.4248 +/* ------------------------------------------------------------------ */ 1.4249 +static decNumber * decDivideOp(decNumber *res, 1.4250 + const decNumber *lhs, const decNumber *rhs, 1.4251 + decContext *set, Flag op, uInt *status) { 1.4252 + #if DECSUBSET 1.4253 + decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */ 1.4254 + decNumber *allocrhs=NULL; /* .., rhs */ 1.4255 + #endif 1.4256 + Unit accbuff[SD2U(DECBUFFER+DECDPUN+10)]; /* local buffer */ 1.4257 + Unit *acc=accbuff; /* -> accumulator array for result */ 1.4258 + Unit *allocacc=NULL; /* -> allocated buffer, iff allocated */ 1.4259 + Unit *accnext; /* -> where next digit will go */ 1.4260 + Int acclength; /* length of acc needed [Units] */ 1.4261 + Int accunits; /* count of units accumulated */ 1.4262 + Int accdigits; /* count of digits accumulated */ 1.4263 + 1.4264 + Unit varbuff[SD2U(DECBUFFER*2+DECDPUN)]; /* buffer for var1 */ 1.4265 + Unit *var1=varbuff; /* -> var1 array for long subtraction */ 1.4266 + Unit *varalloc=NULL; /* -> allocated buffer, iff used */ 1.4267 + Unit *msu1; /* -> msu of var1 */ 1.4268 + 1.4269 + const Unit *var2; /* -> var2 array */ 1.4270 + const Unit *msu2; /* -> msu of var2 */ 1.4271 + Int msu2plus; /* msu2 plus one [does not vary] */ 1.4272 + eInt msu2pair; /* msu2 pair plus one [does not vary] */ 1.4273 + 1.4274 + Int var1units, var2units; /* actual lengths */ 1.4275 + Int var2ulen; /* logical length (units) */ 1.4276 + Int var1initpad=0; /* var1 initial padding (digits) */ 1.4277 + Int maxdigits; /* longest LHS or required acc length */ 1.4278 + Int mult; /* multiplier for subtraction */ 1.4279 + Unit thisunit; /* current unit being accumulated */ 1.4280 + Int residue; /* for rounding */ 1.4281 + Int reqdigits=set->digits; /* requested DIGITS */ 1.4282 + Int exponent; /* working exponent */ 1.4283 + Int maxexponent=0; /* DIVIDE maximum exponent if unrounded */ 1.4284 + uByte bits; /* working sign */ 1.4285 + Unit *target; /* work */ 1.4286 + const Unit *source; /* .. */ 1.4287 + uInt const *pow; /* .. */ 1.4288 + Int shift, cut; /* .. */ 1.4289 + #if DECSUBSET 1.4290 + Int dropped; /* work */ 1.4291 + #endif 1.4292 + 1.4293 + #if DECCHECK 1.4294 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.4295 + #endif 1.4296 + 1.4297 + do { /* protect allocated storage */ 1.4298 + #if DECSUBSET 1.4299 + if (!set->extended) { 1.4300 + /* reduce operands and set lostDigits status, as needed */ 1.4301 + if (lhs->digits>reqdigits) { 1.4302 + alloclhs=decRoundOperand(lhs, set, status); 1.4303 + if (alloclhs==NULL) break; 1.4304 + lhs=alloclhs; 1.4305 + } 1.4306 + if (rhs->digits>reqdigits) { 1.4307 + allocrhs=decRoundOperand(rhs, set, status); 1.4308 + if (allocrhs==NULL) break; 1.4309 + rhs=allocrhs; 1.4310 + } 1.4311 + } 1.4312 + #endif 1.4313 + /* [following code does not require input rounding] */ 1.4314 + 1.4315 + bits=(lhs->bits^rhs->bits)&DECNEG; /* assumed sign for divisions */ 1.4316 + 1.4317 + /* handle infinities and NaNs */ 1.4318 + if (SPECIALARGS) { /* a special bit set */ 1.4319 + if (SPECIALARGS & (DECSNAN | DECNAN)) { /* one or two NaNs */ 1.4320 + decNaNs(res, lhs, rhs, set, status); 1.4321 + break; 1.4322 + } 1.4323 + /* one or two infinities */ 1.4324 + if (decNumberIsInfinite(lhs)) { /* LHS (dividend) is infinite */ 1.4325 + if (decNumberIsInfinite(rhs) || /* two infinities are invalid .. */ 1.4326 + op & (REMAINDER | REMNEAR)) { /* as is remainder of infinity */ 1.4327 + *status|=DEC_Invalid_operation; 1.4328 + break; 1.4329 + } 1.4330 + /* [Note that infinity/0 raises no exceptions] */ 1.4331 + uprv_decNumberZero(res); 1.4332 + res->bits=bits|DECINF; /* set +/- infinity */ 1.4333 + break; 1.4334 + } 1.4335 + else { /* RHS (divisor) is infinite */ 1.4336 + residue=0; 1.4337 + if (op&(REMAINDER|REMNEAR)) { 1.4338 + /* result is [finished clone of] lhs */ 1.4339 + decCopyFit(res, lhs, set, &residue, status); 1.4340 + } 1.4341 + else { /* a division */ 1.4342 + uprv_decNumberZero(res); 1.4343 + res->bits=bits; /* set +/- zero */ 1.4344 + /* for DIVIDEINT the exponent is always 0. For DIVIDE, result */ 1.4345 + /* is a 0 with infinitely negative exponent, clamped to minimum */ 1.4346 + if (op&DIVIDE) { 1.4347 + res->exponent=set->emin-set->digits+1; 1.4348 + *status|=DEC_Clamped; 1.4349 + } 1.4350 + } 1.4351 + decFinish(res, set, &residue, status); 1.4352 + break; 1.4353 + } 1.4354 + } 1.4355 + 1.4356 + /* handle 0 rhs (x/0) */ 1.4357 + if (ISZERO(rhs)) { /* x/0 is always exceptional */ 1.4358 + if (ISZERO(lhs)) { 1.4359 + uprv_decNumberZero(res); /* [after lhs test] */ 1.4360 + *status|=DEC_Division_undefined;/* 0/0 will become NaN */ 1.4361 + } 1.4362 + else { 1.4363 + uprv_decNumberZero(res); 1.4364 + if (op&(REMAINDER|REMNEAR)) *status|=DEC_Invalid_operation; 1.4365 + else { 1.4366 + *status|=DEC_Division_by_zero; /* x/0 */ 1.4367 + res->bits=bits|DECINF; /* .. is +/- Infinity */ 1.4368 + } 1.4369 + } 1.4370 + break;} 1.4371 + 1.4372 + /* handle 0 lhs (0/x) */ 1.4373 + if (ISZERO(lhs)) { /* 0/x [x!=0] */ 1.4374 + #if DECSUBSET 1.4375 + if (!set->extended) uprv_decNumberZero(res); 1.4376 + else { 1.4377 + #endif 1.4378 + if (op&DIVIDE) { 1.4379 + residue=0; 1.4380 + exponent=lhs->exponent-rhs->exponent; /* ideal exponent */ 1.4381 + uprv_decNumberCopy(res, lhs); /* [zeros always fit] */ 1.4382 + res->bits=bits; /* sign as computed */ 1.4383 + res->exponent=exponent; /* exponent, too */ 1.4384 + decFinalize(res, set, &residue, status); /* check exponent */ 1.4385 + } 1.4386 + else if (op&DIVIDEINT) { 1.4387 + uprv_decNumberZero(res); /* integer 0 */ 1.4388 + res->bits=bits; /* sign as computed */ 1.4389 + } 1.4390 + else { /* a remainder */ 1.4391 + exponent=rhs->exponent; /* [save in case overwrite] */ 1.4392 + uprv_decNumberCopy(res, lhs); /* [zeros always fit] */ 1.4393 + if (exponent<res->exponent) res->exponent=exponent; /* use lower */ 1.4394 + } 1.4395 + #if DECSUBSET 1.4396 + } 1.4397 + #endif 1.4398 + break;} 1.4399 + 1.4400 + /* Precalculate exponent. This starts off adjusted (and hence fits */ 1.4401 + /* in 31 bits) and becomes the usual unadjusted exponent as the */ 1.4402 + /* division proceeds. The order of evaluation is important, here, */ 1.4403 + /* to avoid wrap. */ 1.4404 + exponent=(lhs->exponent+lhs->digits)-(rhs->exponent+rhs->digits); 1.4405 + 1.4406 + /* If the working exponent is -ve, then some quick exits are */ 1.4407 + /* possible because the quotient is known to be <1 */ 1.4408 + /* [for REMNEAR, it needs to be < -1, as -0.5 could need work] */ 1.4409 + if (exponent<0 && !(op==DIVIDE)) { 1.4410 + if (op&DIVIDEINT) { 1.4411 + uprv_decNumberZero(res); /* integer part is 0 */ 1.4412 + #if DECSUBSET 1.4413 + if (set->extended) 1.4414 + #endif 1.4415 + res->bits=bits; /* set +/- zero */ 1.4416 + break;} 1.4417 + /* fastpath remainders so long as the lhs has the smaller */ 1.4418 + /* (or equal) exponent */ 1.4419 + if (lhs->exponent<=rhs->exponent) { 1.4420 + if (op&REMAINDER || exponent<-1) { 1.4421 + /* It is REMAINDER or safe REMNEAR; result is [finished */ 1.4422 + /* clone of] lhs (r = x - 0*y) */ 1.4423 + residue=0; 1.4424 + decCopyFit(res, lhs, set, &residue, status); 1.4425 + decFinish(res, set, &residue, status); 1.4426 + break; 1.4427 + } 1.4428 + /* [unsafe REMNEAR drops through] */ 1.4429 + } 1.4430 + } /* fastpaths */ 1.4431 + 1.4432 + /* Long (slow) division is needed; roll up the sleeves... */ 1.4433 + 1.4434 + /* The accumulator will hold the quotient of the division. */ 1.4435 + /* If it needs to be too long for stack storage, then allocate. */ 1.4436 + acclength=D2U(reqdigits+DECDPUN); /* in Units */ 1.4437 + if (acclength*sizeof(Unit)>sizeof(accbuff)) { 1.4438 + /* printf("malloc dvacc %ld units\n", acclength); */ 1.4439 + allocacc=(Unit *)malloc(acclength*sizeof(Unit)); 1.4440 + if (allocacc==NULL) { /* hopeless -- abandon */ 1.4441 + *status|=DEC_Insufficient_storage; 1.4442 + break;} 1.4443 + acc=allocacc; /* use the allocated space */ 1.4444 + } 1.4445 + 1.4446 + /* var1 is the padded LHS ready for subtractions. */ 1.4447 + /* If it needs to be too long for stack storage, then allocate. */ 1.4448 + /* The maximum units needed for var1 (long subtraction) is: */ 1.4449 + /* Enough for */ 1.4450 + /* (rhs->digits+reqdigits-1) -- to allow full slide to right */ 1.4451 + /* or (lhs->digits) -- to allow for long lhs */ 1.4452 + /* whichever is larger */ 1.4453 + /* +1 -- for rounding of slide to right */ 1.4454 + /* +1 -- for leading 0s */ 1.4455 + /* +1 -- for pre-adjust if a remainder or DIVIDEINT */ 1.4456 + /* [Note: unused units do not participate in decUnitAddSub data] */ 1.4457 + maxdigits=rhs->digits+reqdigits-1; 1.4458 + if (lhs->digits>maxdigits) maxdigits=lhs->digits; 1.4459 + var1units=D2U(maxdigits)+2; 1.4460 + /* allocate a guard unit above msu1 for REMAINDERNEAR */ 1.4461 + if (!(op&DIVIDE)) var1units++; 1.4462 + if ((var1units+1)*sizeof(Unit)>sizeof(varbuff)) { 1.4463 + /* printf("malloc dvvar %ld units\n", var1units+1); */ 1.4464 + varalloc=(Unit *)malloc((var1units+1)*sizeof(Unit)); 1.4465 + if (varalloc==NULL) { /* hopeless -- abandon */ 1.4466 + *status|=DEC_Insufficient_storage; 1.4467 + break;} 1.4468 + var1=varalloc; /* use the allocated space */ 1.4469 + } 1.4470 + 1.4471 + /* Extend the lhs and rhs to full long subtraction length. The lhs */ 1.4472 + /* is truly extended into the var1 buffer, with 0 padding, so a */ 1.4473 + /* subtract in place is always possible. The rhs (var2) has */ 1.4474 + /* virtual padding (implemented by decUnitAddSub). */ 1.4475 + /* One guard unit was allocated above msu1 for rem=rem+rem in */ 1.4476 + /* REMAINDERNEAR. */ 1.4477 + msu1=var1+var1units-1; /* msu of var1 */ 1.4478 + source=lhs->lsu+D2U(lhs->digits)-1; /* msu of input array */ 1.4479 + for (target=msu1; source>=lhs->lsu; source--, target--) *target=*source; 1.4480 + for (; target>=var1; target--) *target=0; 1.4481 + 1.4482 + /* rhs (var2) is left-aligned with var1 at the start */ 1.4483 + var2ulen=var1units; /* rhs logical length (units) */ 1.4484 + var2units=D2U(rhs->digits); /* rhs actual length (units) */ 1.4485 + var2=rhs->lsu; /* -> rhs array */ 1.4486 + msu2=var2+var2units-1; /* -> msu of var2 [never changes] */ 1.4487 + /* now set up the variables which will be used for estimating the */ 1.4488 + /* multiplication factor. If these variables are not exact, add */ 1.4489 + /* 1 to make sure that the multiplier is never overestimated. */ 1.4490 + msu2plus=*msu2; /* it's value .. */ 1.4491 + if (var2units>1) msu2plus++; /* .. +1 if any more */ 1.4492 + msu2pair=(eInt)*msu2*(DECDPUNMAX+1);/* top two pair .. */ 1.4493 + if (var2units>1) { /* .. [else treat 2nd as 0] */ 1.4494 + msu2pair+=*(msu2-1); /* .. */ 1.4495 + if (var2units>2) msu2pair++; /* .. +1 if any more */ 1.4496 + } 1.4497 + 1.4498 + /* The calculation is working in units, which may have leading zeros, */ 1.4499 + /* but the exponent was calculated on the assumption that they are */ 1.4500 + /* both left-aligned. Adjust the exponent to compensate: add the */ 1.4501 + /* number of leading zeros in var1 msu and subtract those in var2 msu. */ 1.4502 + /* [This is actually done by counting the digits and negating, as */ 1.4503 + /* lead1=DECDPUN-digits1, and similarly for lead2.] */ 1.4504 + for (pow=&powers[1]; *msu1>=*pow; pow++) exponent--; 1.4505 + for (pow=&powers[1]; *msu2>=*pow; pow++) exponent++; 1.4506 + 1.4507 + /* Now, if doing an integer divide or remainder, ensure that */ 1.4508 + /* the result will be Unit-aligned. To do this, shift the var1 */ 1.4509 + /* accumulator towards least if need be. (It's much easier to */ 1.4510 + /* do this now than to reassemble the residue afterwards, if */ 1.4511 + /* doing a remainder.) Also ensure the exponent is not negative. */ 1.4512 + if (!(op&DIVIDE)) { 1.4513 + Unit *u; /* work */ 1.4514 + /* save the initial 'false' padding of var1, in digits */ 1.4515 + var1initpad=(var1units-D2U(lhs->digits))*DECDPUN; 1.4516 + /* Determine the shift to do. */ 1.4517 + if (exponent<0) cut=-exponent; 1.4518 + else cut=DECDPUN-exponent%DECDPUN; 1.4519 + decShiftToLeast(var1, var1units, cut); 1.4520 + exponent+=cut; /* maintain numerical value */ 1.4521 + var1initpad-=cut; /* .. and reduce padding */ 1.4522 + /* clean any most-significant units which were just emptied */ 1.4523 + for (u=msu1; cut>=DECDPUN; cut-=DECDPUN, u--) *u=0; 1.4524 + } /* align */ 1.4525 + else { /* is DIVIDE */ 1.4526 + maxexponent=lhs->exponent-rhs->exponent; /* save */ 1.4527 + /* optimization: if the first iteration will just produce 0, */ 1.4528 + /* preadjust to skip it [valid for DIVIDE only] */ 1.4529 + if (*msu1<*msu2) { 1.4530 + var2ulen--; /* shift down */ 1.4531 + exponent-=DECDPUN; /* update the exponent */ 1.4532 + } 1.4533 + } 1.4534 + 1.4535 + /* ---- start the long-division loops ------------------------------ */ 1.4536 + accunits=0; /* no units accumulated yet */ 1.4537 + accdigits=0; /* .. or digits */ 1.4538 + accnext=acc+acclength-1; /* -> msu of acc [NB: allows digits+1] */ 1.4539 + for (;;) { /* outer forever loop */ 1.4540 + thisunit=0; /* current unit assumed 0 */ 1.4541 + /* find the next unit */ 1.4542 + for (;;) { /* inner forever loop */ 1.4543 + /* strip leading zero units [from either pre-adjust or from */ 1.4544 + /* subtract last time around]. Leave at least one unit. */ 1.4545 + for (; *msu1==0 && msu1>var1; msu1--) var1units--; 1.4546 + 1.4547 + if (var1units<var2ulen) break; /* var1 too low for subtract */ 1.4548 + if (var1units==var2ulen) { /* unit-by-unit compare needed */ 1.4549 + /* compare the two numbers, from msu */ 1.4550 + const Unit *pv1, *pv2; 1.4551 + Unit v2; /* units to compare */ 1.4552 + pv2=msu2; /* -> msu */ 1.4553 + for (pv1=msu1; ; pv1--, pv2--) { 1.4554 + /* v1=*pv1 -- always OK */ 1.4555 + v2=0; /* assume in padding */ 1.4556 + if (pv2>=var2) v2=*pv2; /* in range */ 1.4557 + if (*pv1!=v2) break; /* no longer the same */ 1.4558 + if (pv1==var1) break; /* done; leave pv1 as is */ 1.4559 + } 1.4560 + /* here when all inspected or a difference seen */ 1.4561 + if (*pv1<v2) break; /* var1 too low to subtract */ 1.4562 + if (*pv1==v2) { /* var1 == var2 */ 1.4563 + /* reach here if var1 and var2 are identical; subtraction */ 1.4564 + /* would increase digit by one, and the residue will be 0 so */ 1.4565 + /* the calculation is done; leave the loop with residue=0. */ 1.4566 + thisunit++; /* as though subtracted */ 1.4567 + *var1=0; /* set var1 to 0 */ 1.4568 + var1units=1; /* .. */ 1.4569 + break; /* from inner */ 1.4570 + } /* var1 == var2 */ 1.4571 + /* *pv1>v2. Prepare for real subtraction; the lengths are equal */ 1.4572 + /* Estimate the multiplier (there's always a msu1-1)... */ 1.4573 + /* Bring in two units of var2 to provide a good estimate. */ 1.4574 + mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2pair); 1.4575 + } /* lengths the same */ 1.4576 + else { /* var1units > var2ulen, so subtraction is safe */ 1.4577 + /* The var2 msu is one unit towards the lsu of the var1 msu, */ 1.4578 + /* so only one unit for var2 can be used. */ 1.4579 + mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2plus); 1.4580 + } 1.4581 + if (mult==0) mult=1; /* must always be at least 1 */ 1.4582 + /* subtraction needed; var1 is > var2 */ 1.4583 + thisunit=(Unit)(thisunit+mult); /* accumulate */ 1.4584 + /* subtract var1-var2, into var1; only the overlap needs */ 1.4585 + /* processing, as this is an in-place calculation */ 1.4586 + shift=var2ulen-var2units; 1.4587 + #if DECTRACE 1.4588 + decDumpAr('1', &var1[shift], var1units-shift); 1.4589 + decDumpAr('2', var2, var2units); 1.4590 + printf("m=%ld\n", -mult); 1.4591 + #endif 1.4592 + decUnitAddSub(&var1[shift], var1units-shift, 1.4593 + var2, var2units, 0, 1.4594 + &var1[shift], -mult); 1.4595 + #if DECTRACE 1.4596 + decDumpAr('#', &var1[shift], var1units-shift); 1.4597 + #endif 1.4598 + /* var1 now probably has leading zeros; these are removed at the */ 1.4599 + /* top of the inner loop. */ 1.4600 + } /* inner loop */ 1.4601 + 1.4602 + /* The next unit has been calculated in full; unless it's a */ 1.4603 + /* leading zero, add to acc */ 1.4604 + if (accunits!=0 || thisunit!=0) { /* is first or non-zero */ 1.4605 + *accnext=thisunit; /* store in accumulator */ 1.4606 + /* account exactly for the new digits */ 1.4607 + if (accunits==0) { 1.4608 + accdigits++; /* at least one */ 1.4609 + for (pow=&powers[1]; thisunit>=*pow; pow++) accdigits++; 1.4610 + } 1.4611 + else accdigits+=DECDPUN; 1.4612 + accunits++; /* update count */ 1.4613 + accnext--; /* ready for next */ 1.4614 + if (accdigits>reqdigits) break; /* have enough digits */ 1.4615 + } 1.4616 + 1.4617 + /* if the residue is zero, the operation is done (unless divide */ 1.4618 + /* or divideInteger and still not enough digits yet) */ 1.4619 + if (*var1==0 && var1units==1) { /* residue is 0 */ 1.4620 + if (op&(REMAINDER|REMNEAR)) break; 1.4621 + if ((op&DIVIDE) && (exponent<=maxexponent)) break; 1.4622 + /* [drop through if divideInteger] */ 1.4623 + } 1.4624 + /* also done enough if calculating remainder or integer */ 1.4625 + /* divide and just did the last ('units') unit */ 1.4626 + if (exponent==0 && !(op&DIVIDE)) break; 1.4627 + 1.4628 + /* to get here, var1 is less than var2, so divide var2 by the per- */ 1.4629 + /* Unit power of ten and go for the next digit */ 1.4630 + var2ulen--; /* shift down */ 1.4631 + exponent-=DECDPUN; /* update the exponent */ 1.4632 + } /* outer loop */ 1.4633 + 1.4634 + /* ---- division is complete --------------------------------------- */ 1.4635 + /* here: acc has at least reqdigits+1 of good results (or fewer */ 1.4636 + /* if early stop), starting at accnext+1 (its lsu) */ 1.4637 + /* var1 has any residue at the stopping point */ 1.4638 + /* accunits is the number of digits collected in acc */ 1.4639 + if (accunits==0) { /* acc is 0 */ 1.4640 + accunits=1; /* show have a unit .. */ 1.4641 + accdigits=1; /* .. */ 1.4642 + *accnext=0; /* .. whose value is 0 */ 1.4643 + } 1.4644 + else accnext++; /* back to last placed */ 1.4645 + /* accnext now -> lowest unit of result */ 1.4646 + 1.4647 + residue=0; /* assume no residue */ 1.4648 + if (op&DIVIDE) { 1.4649 + /* record the presence of any residue, for rounding */ 1.4650 + if (*var1!=0 || var1units>1) residue=1; 1.4651 + else { /* no residue */ 1.4652 + /* Had an exact division; clean up spurious trailing 0s. */ 1.4653 + /* There will be at most DECDPUN-1, from the final multiply, */ 1.4654 + /* and then only if the result is non-0 (and even) and the */ 1.4655 + /* exponent is 'loose'. */ 1.4656 + #if DECDPUN>1 1.4657 + Unit lsu=*accnext; 1.4658 + if (!(lsu&0x01) && (lsu!=0)) { 1.4659 + /* count the trailing zeros */ 1.4660 + Int drop=0; 1.4661 + for (;; drop++) { /* [will terminate because lsu!=0] */ 1.4662 + if (exponent>=maxexponent) break; /* don't chop real 0s */ 1.4663 + #if DECDPUN<=4 1.4664 + if ((lsu-QUOT10(lsu, drop+1) 1.4665 + *powers[drop+1])!=0) break; /* found non-0 digit */ 1.4666 + #else 1.4667 + if (lsu%powers[drop+1]!=0) break; /* found non-0 digit */ 1.4668 + #endif 1.4669 + exponent++; 1.4670 + } 1.4671 + if (drop>0) { 1.4672 + accunits=decShiftToLeast(accnext, accunits, drop); 1.4673 + accdigits=decGetDigits(accnext, accunits); 1.4674 + accunits=D2U(accdigits); 1.4675 + /* [exponent was adjusted in the loop] */ 1.4676 + } 1.4677 + } /* neither odd nor 0 */ 1.4678 + #endif 1.4679 + } /* exact divide */ 1.4680 + } /* divide */ 1.4681 + else /* op!=DIVIDE */ { 1.4682 + /* check for coefficient overflow */ 1.4683 + if (accdigits+exponent>reqdigits) { 1.4684 + *status|=DEC_Division_impossible; 1.4685 + break; 1.4686 + } 1.4687 + if (op & (REMAINDER|REMNEAR)) { 1.4688 + /* [Here, the exponent will be 0, because var1 was adjusted */ 1.4689 + /* appropriately.] */ 1.4690 + Int postshift; /* work */ 1.4691 + Flag wasodd=0; /* integer was odd */ 1.4692 + Unit *quotlsu; /* for save */ 1.4693 + Int quotdigits; /* .. */ 1.4694 + 1.4695 + bits=lhs->bits; /* remainder sign is always as lhs */ 1.4696 + 1.4697 + /* Fastpath when residue is truly 0 is worthwhile [and */ 1.4698 + /* simplifies the code below] */ 1.4699 + if (*var1==0 && var1units==1) { /* residue is 0 */ 1.4700 + Int exp=lhs->exponent; /* save min(exponents) */ 1.4701 + if (rhs->exponent<exp) exp=rhs->exponent; 1.4702 + uprv_decNumberZero(res); /* 0 coefficient */ 1.4703 + #if DECSUBSET 1.4704 + if (set->extended) 1.4705 + #endif 1.4706 + res->exponent=exp; /* .. with proper exponent */ 1.4707 + res->bits=(uByte)(bits&DECNEG); /* [cleaned] */ 1.4708 + decFinish(res, set, &residue, status); /* might clamp */ 1.4709 + break; 1.4710 + } 1.4711 + /* note if the quotient was odd */ 1.4712 + if (*accnext & 0x01) wasodd=1; /* acc is odd */ 1.4713 + quotlsu=accnext; /* save in case need to reinspect */ 1.4714 + quotdigits=accdigits; /* .. */ 1.4715 + 1.4716 + /* treat the residue, in var1, as the value to return, via acc */ 1.4717 + /* calculate the unused zero digits. This is the smaller of: */ 1.4718 + /* var1 initial padding (saved above) */ 1.4719 + /* var2 residual padding, which happens to be given by: */ 1.4720 + postshift=var1initpad+exponent-lhs->exponent+rhs->exponent; 1.4721 + /* [the 'exponent' term accounts for the shifts during divide] */ 1.4722 + if (var1initpad<postshift) postshift=var1initpad; 1.4723 + 1.4724 + /* shift var1 the requested amount, and adjust its digits */ 1.4725 + var1units=decShiftToLeast(var1, var1units, postshift); 1.4726 + accnext=var1; 1.4727 + accdigits=decGetDigits(var1, var1units); 1.4728 + accunits=D2U(accdigits); 1.4729 + 1.4730 + exponent=lhs->exponent; /* exponent is smaller of lhs & rhs */ 1.4731 + if (rhs->exponent<exponent) exponent=rhs->exponent; 1.4732 + 1.4733 + /* Now correct the result if doing remainderNear; if it */ 1.4734 + /* (looking just at coefficients) is > rhs/2, or == rhs/2 and */ 1.4735 + /* the integer was odd then the result should be rem-rhs. */ 1.4736 + if (op&REMNEAR) { 1.4737 + Int compare, tarunits; /* work */ 1.4738 + Unit *up; /* .. */ 1.4739 + /* calculate remainder*2 into the var1 buffer (which has */ 1.4740 + /* 'headroom' of an extra unit and hence enough space) */ 1.4741 + /* [a dedicated 'double' loop would be faster, here] */ 1.4742 + tarunits=decUnitAddSub(accnext, accunits, accnext, accunits, 1.4743 + 0, accnext, 1); 1.4744 + /* decDumpAr('r', accnext, tarunits); */ 1.4745 + 1.4746 + /* Here, accnext (var1) holds tarunits Units with twice the */ 1.4747 + /* remainder's coefficient, which must now be compared to the */ 1.4748 + /* RHS. The remainder's exponent may be smaller than the RHS's. */ 1.4749 + compare=decUnitCompare(accnext, tarunits, rhs->lsu, D2U(rhs->digits), 1.4750 + rhs->exponent-exponent); 1.4751 + if (compare==BADINT) { /* deep trouble */ 1.4752 + *status|=DEC_Insufficient_storage; 1.4753 + break;} 1.4754 + 1.4755 + /* now restore the remainder by dividing by two; the lsu */ 1.4756 + /* is known to be even. */ 1.4757 + for (up=accnext; up<accnext+tarunits; up++) { 1.4758 + Int half; /* half to add to lower unit */ 1.4759 + half=*up & 0x01; 1.4760 + *up/=2; /* [shift] */ 1.4761 + if (!half) continue; 1.4762 + *(up-1)+=(DECDPUNMAX+1)/2; 1.4763 + } 1.4764 + /* [accunits still describes the original remainder length] */ 1.4765 + 1.4766 + if (compare>0 || (compare==0 && wasodd)) { /* adjustment needed */ 1.4767 + Int exp, expunits, exprem; /* work */ 1.4768 + /* This is effectively causing round-up of the quotient, */ 1.4769 + /* so if it was the rare case where it was full and all */ 1.4770 + /* nines, it would overflow and hence division-impossible */ 1.4771 + /* should be raised */ 1.4772 + Flag allnines=0; /* 1 if quotient all nines */ 1.4773 + if (quotdigits==reqdigits) { /* could be borderline */ 1.4774 + for (up=quotlsu; ; up++) { 1.4775 + if (quotdigits>DECDPUN) { 1.4776 + if (*up!=DECDPUNMAX) break;/* non-nines */ 1.4777 + } 1.4778 + else { /* this is the last Unit */ 1.4779 + if (*up==powers[quotdigits]-1) allnines=1; 1.4780 + break; 1.4781 + } 1.4782 + quotdigits-=DECDPUN; /* checked those digits */ 1.4783 + } /* up */ 1.4784 + } /* borderline check */ 1.4785 + if (allnines) { 1.4786 + *status|=DEC_Division_impossible; 1.4787 + break;} 1.4788 + 1.4789 + /* rem-rhs is needed; the sign will invert. Again, var1 */ 1.4790 + /* can safely be used for the working Units array. */ 1.4791 + exp=rhs->exponent-exponent; /* RHS padding needed */ 1.4792 + /* Calculate units and remainder from exponent. */ 1.4793 + expunits=exp/DECDPUN; 1.4794 + exprem=exp%DECDPUN; 1.4795 + /* subtract [A+B*(-m)]; the result will always be negative */ 1.4796 + accunits=-decUnitAddSub(accnext, accunits, 1.4797 + rhs->lsu, D2U(rhs->digits), 1.4798 + expunits, accnext, -(Int)powers[exprem]); 1.4799 + accdigits=decGetDigits(accnext, accunits); /* count digits exactly */ 1.4800 + accunits=D2U(accdigits); /* and recalculate the units for copy */ 1.4801 + /* [exponent is as for original remainder] */ 1.4802 + bits^=DECNEG; /* flip the sign */ 1.4803 + } 1.4804 + } /* REMNEAR */ 1.4805 + } /* REMAINDER or REMNEAR */ 1.4806 + } /* not DIVIDE */ 1.4807 + 1.4808 + /* Set exponent and bits */ 1.4809 + res->exponent=exponent; 1.4810 + res->bits=(uByte)(bits&DECNEG); /* [cleaned] */ 1.4811 + 1.4812 + /* Now the coefficient. */ 1.4813 + decSetCoeff(res, set, accnext, accdigits, &residue, status); 1.4814 + 1.4815 + decFinish(res, set, &residue, status); /* final cleanup */ 1.4816 + 1.4817 + #if DECSUBSET 1.4818 + /* If a divide then strip trailing zeros if subset [after round] */ 1.4819 + if (!set->extended && (op==DIVIDE)) decTrim(res, set, 0, 1, &dropped); 1.4820 + #endif 1.4821 + } while(0); /* end protected */ 1.4822 + 1.4823 + if (varalloc!=NULL) free(varalloc); /* drop any storage used */ 1.4824 + if (allocacc!=NULL) free(allocacc); /* .. */ 1.4825 + #if DECSUBSET 1.4826 + if (allocrhs!=NULL) free(allocrhs); /* .. */ 1.4827 + if (alloclhs!=NULL) free(alloclhs); /* .. */ 1.4828 + #endif 1.4829 + return res; 1.4830 + } /* decDivideOp */ 1.4831 + 1.4832 +/* ------------------------------------------------------------------ */ 1.4833 +/* decMultiplyOp -- multiplication operation */ 1.4834 +/* */ 1.4835 +/* This routine performs the multiplication C=A x B. */ 1.4836 +/* */ 1.4837 +/* res is C, the result. C may be A and/or B (e.g., X=X*X) */ 1.4838 +/* lhs is A */ 1.4839 +/* rhs is B */ 1.4840 +/* set is the context */ 1.4841 +/* status is the usual accumulator */ 1.4842 +/* */ 1.4843 +/* C must have space for set->digits digits. */ 1.4844 +/* */ 1.4845 +/* ------------------------------------------------------------------ */ 1.4846 +/* 'Classic' multiplication is used rather than Karatsuba, as the */ 1.4847 +/* latter would give only a minor improvement for the short numbers */ 1.4848 +/* expected to be handled most (and uses much more memory). */ 1.4849 +/* */ 1.4850 +/* There are two major paths here: the general-purpose ('old code') */ 1.4851 +/* path which handles all DECDPUN values, and a fastpath version */ 1.4852 +/* which is used if 64-bit ints are available, DECDPUN<=4, and more */ 1.4853 +/* than two calls to decUnitAddSub would be made. */ 1.4854 +/* */ 1.4855 +/* The fastpath version lumps units together into 8-digit or 9-digit */ 1.4856 +/* chunks, and also uses a lazy carry strategy to minimise expensive */ 1.4857 +/* 64-bit divisions. The chunks are then broken apart again into */ 1.4858 +/* units for continuing processing. Despite this overhead, the */ 1.4859 +/* fastpath can speed up some 16-digit operations by 10x (and much */ 1.4860 +/* more for higher-precision calculations). */ 1.4861 +/* */ 1.4862 +/* A buffer always has to be used for the accumulator; in the */ 1.4863 +/* fastpath, buffers are also always needed for the chunked copies of */ 1.4864 +/* of the operand coefficients. */ 1.4865 +/* Static buffers are larger than needed just for multiply, to allow */ 1.4866 +/* for calls from other operations (notably exp). */ 1.4867 +/* ------------------------------------------------------------------ */ 1.4868 +#define FASTMUL (DECUSE64 && DECDPUN<5) 1.4869 +static decNumber * decMultiplyOp(decNumber *res, const decNumber *lhs, 1.4870 + const decNumber *rhs, decContext *set, 1.4871 + uInt *status) { 1.4872 + Int accunits; /* Units of accumulator in use */ 1.4873 + Int exponent; /* work */ 1.4874 + Int residue=0; /* rounding residue */ 1.4875 + uByte bits; /* result sign */ 1.4876 + Unit *acc; /* -> accumulator Unit array */ 1.4877 + Int needbytes; /* size calculator */ 1.4878 + void *allocacc=NULL; /* -> allocated accumulator, iff allocated */ 1.4879 + Unit accbuff[SD2U(DECBUFFER*4+1)]; /* buffer (+1 for DECBUFFER==0, */ 1.4880 + /* *4 for calls from other operations) */ 1.4881 + const Unit *mer, *mermsup; /* work */ 1.4882 + Int madlength; /* Units in multiplicand */ 1.4883 + Int shift; /* Units to shift multiplicand by */ 1.4884 + 1.4885 + #if FASTMUL 1.4886 + /* if DECDPUN is 1 or 3 work in base 10**9, otherwise */ 1.4887 + /* (DECDPUN is 2 or 4) then work in base 10**8 */ 1.4888 + #if DECDPUN & 1 /* odd */ 1.4889 + #define FASTBASE 1000000000 /* base */ 1.4890 + #define FASTDIGS 9 /* digits in base */ 1.4891 + #define FASTLAZY 18 /* carry resolution point [1->18] */ 1.4892 + #else 1.4893 + #define FASTBASE 100000000 1.4894 + #define FASTDIGS 8 1.4895 + #define FASTLAZY 1844 /* carry resolution point [1->1844] */ 1.4896 + #endif 1.4897 + /* three buffers are used, two for chunked copies of the operands */ 1.4898 + /* (base 10**8 or base 10**9) and one base 2**64 accumulator with */ 1.4899 + /* lazy carry evaluation */ 1.4900 + uInt zlhibuff[(DECBUFFER*2+1)/8+1]; /* buffer (+1 for DECBUFFER==0) */ 1.4901 + uInt *zlhi=zlhibuff; /* -> lhs array */ 1.4902 + uInt *alloclhi=NULL; /* -> allocated buffer, iff allocated */ 1.4903 + uInt zrhibuff[(DECBUFFER*2+1)/8+1]; /* buffer (+1 for DECBUFFER==0) */ 1.4904 + uInt *zrhi=zrhibuff; /* -> rhs array */ 1.4905 + uInt *allocrhi=NULL; /* -> allocated buffer, iff allocated */ 1.4906 + uLong zaccbuff[(DECBUFFER*2+1)/4+2]; /* buffer (+1 for DECBUFFER==0) */ 1.4907 + /* [allocacc is shared for both paths, as only one will run] */ 1.4908 + uLong *zacc=zaccbuff; /* -> accumulator array for exact result */ 1.4909 + #if DECDPUN==1 1.4910 + Int zoff; /* accumulator offset */ 1.4911 + #endif 1.4912 + uInt *lip, *rip; /* item pointers */ 1.4913 + uInt *lmsi, *rmsi; /* most significant items */ 1.4914 + Int ilhs, irhs, iacc; /* item counts in the arrays */ 1.4915 + Int lazy; /* lazy carry counter */ 1.4916 + uLong lcarry; /* uLong carry */ 1.4917 + uInt carry; /* carry (NB not uLong) */ 1.4918 + Int count; /* work */ 1.4919 + const Unit *cup; /* .. */ 1.4920 + Unit *up; /* .. */ 1.4921 + uLong *lp; /* .. */ 1.4922 + Int p; /* .. */ 1.4923 + #endif 1.4924 + 1.4925 + #if DECSUBSET 1.4926 + decNumber *alloclhs=NULL; /* -> allocated buffer, iff allocated */ 1.4927 + decNumber *allocrhs=NULL; /* -> allocated buffer, iff allocated */ 1.4928 + #endif 1.4929 + 1.4930 + #if DECCHECK 1.4931 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.4932 + #endif 1.4933 + 1.4934 + /* precalculate result sign */ 1.4935 + bits=(uByte)((lhs->bits^rhs->bits)&DECNEG); 1.4936 + 1.4937 + /* handle infinities and NaNs */ 1.4938 + if (SPECIALARGS) { /* a special bit set */ 1.4939 + if (SPECIALARGS & (DECSNAN | DECNAN)) { /* one or two NaNs */ 1.4940 + decNaNs(res, lhs, rhs, set, status); 1.4941 + return res;} 1.4942 + /* one or two infinities; Infinity * 0 is invalid */ 1.4943 + if (((lhs->bits & DECINF)==0 && ISZERO(lhs)) 1.4944 + ||((rhs->bits & DECINF)==0 && ISZERO(rhs))) { 1.4945 + *status|=DEC_Invalid_operation; 1.4946 + return res;} 1.4947 + uprv_decNumberZero(res); 1.4948 + res->bits=bits|DECINF; /* infinity */ 1.4949 + return res;} 1.4950 + 1.4951 + /* For best speed, as in DMSRCN [the original Rexx numerics */ 1.4952 + /* module], use the shorter number as the multiplier (rhs) and */ 1.4953 + /* the longer as the multiplicand (lhs) to minimise the number of */ 1.4954 + /* adds (partial products) */ 1.4955 + if (lhs->digits<rhs->digits) { /* swap... */ 1.4956 + const decNumber *hold=lhs; 1.4957 + lhs=rhs; 1.4958 + rhs=hold; 1.4959 + } 1.4960 + 1.4961 + do { /* protect allocated storage */ 1.4962 + #if DECSUBSET 1.4963 + if (!set->extended) { 1.4964 + /* reduce operands and set lostDigits status, as needed */ 1.4965 + if (lhs->digits>set->digits) { 1.4966 + alloclhs=decRoundOperand(lhs, set, status); 1.4967 + if (alloclhs==NULL) break; 1.4968 + lhs=alloclhs; 1.4969 + } 1.4970 + if (rhs->digits>set->digits) { 1.4971 + allocrhs=decRoundOperand(rhs, set, status); 1.4972 + if (allocrhs==NULL) break; 1.4973 + rhs=allocrhs; 1.4974 + } 1.4975 + } 1.4976 + #endif 1.4977 + /* [following code does not require input rounding] */ 1.4978 + 1.4979 + #if FASTMUL /* fastpath can be used */ 1.4980 + /* use the fast path if there are enough digits in the shorter */ 1.4981 + /* operand to make the setup and takedown worthwhile */ 1.4982 + #define NEEDTWO (DECDPUN*2) /* within two decUnitAddSub calls */ 1.4983 + if (rhs->digits>NEEDTWO) { /* use fastpath... */ 1.4984 + /* calculate the number of elements in each array */ 1.4985 + ilhs=(lhs->digits+FASTDIGS-1)/FASTDIGS; /* [ceiling] */ 1.4986 + irhs=(rhs->digits+FASTDIGS-1)/FASTDIGS; /* .. */ 1.4987 + iacc=ilhs+irhs; 1.4988 + 1.4989 + /* allocate buffers if required, as usual */ 1.4990 + needbytes=ilhs*sizeof(uInt); 1.4991 + if (needbytes>(Int)sizeof(zlhibuff)) { 1.4992 + alloclhi=(uInt *)malloc(needbytes); 1.4993 + zlhi=alloclhi;} 1.4994 + needbytes=irhs*sizeof(uInt); 1.4995 + if (needbytes>(Int)sizeof(zrhibuff)) { 1.4996 + allocrhi=(uInt *)malloc(needbytes); 1.4997 + zrhi=allocrhi;} 1.4998 + 1.4999 + /* Allocating the accumulator space needs a special case when */ 1.5000 + /* DECDPUN=1 because when converting the accumulator to Units */ 1.5001 + /* after the multiplication each 8-byte item becomes 9 1-byte */ 1.5002 + /* units. Therefore iacc extra bytes are needed at the front */ 1.5003 + /* (rounded up to a multiple of 8 bytes), and the uLong */ 1.5004 + /* accumulator starts offset the appropriate number of units */ 1.5005 + /* to the right to avoid overwrite during the unchunking. */ 1.5006 + 1.5007 + /* Make sure no signed int overflow below. This is always true */ 1.5008 + /* if the given numbers have less digits than DEC_MAX_DIGITS. */ 1.5009 + U_ASSERT(iacc <= INT32_MAX/sizeof(uLong)); 1.5010 + needbytes=iacc*sizeof(uLong); 1.5011 + #if DECDPUN==1 1.5012 + zoff=(iacc+7)/8; /* items to offset by */ 1.5013 + needbytes+=zoff*8; 1.5014 + #endif 1.5015 + if (needbytes>(Int)sizeof(zaccbuff)) { 1.5016 + allocacc=(uLong *)malloc(needbytes); 1.5017 + zacc=(uLong *)allocacc;} 1.5018 + if (zlhi==NULL||zrhi==NULL||zacc==NULL) { 1.5019 + *status|=DEC_Insufficient_storage; 1.5020 + break;} 1.5021 + 1.5022 + acc=(Unit *)zacc; /* -> target Unit array */ 1.5023 + #if DECDPUN==1 1.5024 + zacc+=zoff; /* start uLong accumulator to right */ 1.5025 + #endif 1.5026 + 1.5027 + /* assemble the chunked copies of the left and right sides */ 1.5028 + for (count=lhs->digits, cup=lhs->lsu, lip=zlhi; count>0; lip++) 1.5029 + for (p=0, *lip=0; p<FASTDIGS && count>0; 1.5030 + p+=DECDPUN, cup++, count-=DECDPUN) 1.5031 + *lip+=*cup*powers[p]; 1.5032 + lmsi=lip-1; /* save -> msi */ 1.5033 + for (count=rhs->digits, cup=rhs->lsu, rip=zrhi; count>0; rip++) 1.5034 + for (p=0, *rip=0; p<FASTDIGS && count>0; 1.5035 + p+=DECDPUN, cup++, count-=DECDPUN) 1.5036 + *rip+=*cup*powers[p]; 1.5037 + rmsi=rip-1; /* save -> msi */ 1.5038 + 1.5039 + /* zero the accumulator */ 1.5040 + for (lp=zacc; lp<zacc+iacc; lp++) *lp=0; 1.5041 + 1.5042 + /* Start the multiplication */ 1.5043 + /* Resolving carries can dominate the cost of accumulating the */ 1.5044 + /* partial products, so this is only done when necessary. */ 1.5045 + /* Each uLong item in the accumulator can hold values up to */ 1.5046 + /* 2**64-1, and each partial product can be as large as */ 1.5047 + /* (10**FASTDIGS-1)**2. When FASTDIGS=9, this can be added to */ 1.5048 + /* itself 18.4 times in a uLong without overflowing, so during */ 1.5049 + /* the main calculation resolution is carried out every 18th */ 1.5050 + /* add -- every 162 digits. Similarly, when FASTDIGS=8, the */ 1.5051 + /* partial products can be added to themselves 1844.6 times in */ 1.5052 + /* a uLong without overflowing, so intermediate carry */ 1.5053 + /* resolution occurs only every 14752 digits. Hence for common */ 1.5054 + /* short numbers usually only the one final carry resolution */ 1.5055 + /* occurs. */ 1.5056 + /* (The count is set via FASTLAZY to simplify experiments to */ 1.5057 + /* measure the value of this approach: a 35% improvement on a */ 1.5058 + /* [34x34] multiply.) */ 1.5059 + lazy=FASTLAZY; /* carry delay count */ 1.5060 + for (rip=zrhi; rip<=rmsi; rip++) { /* over each item in rhs */ 1.5061 + lp=zacc+(rip-zrhi); /* where to add the lhs */ 1.5062 + for (lip=zlhi; lip<=lmsi; lip++, lp++) { /* over each item in lhs */ 1.5063 + *lp+=(uLong)(*lip)*(*rip); /* [this should in-line] */ 1.5064 + } /* lip loop */ 1.5065 + lazy--; 1.5066 + if (lazy>0 && rip!=rmsi) continue; 1.5067 + lazy=FASTLAZY; /* reset delay count */ 1.5068 + /* spin up the accumulator resolving overflows */ 1.5069 + for (lp=zacc; lp<zacc+iacc; lp++) { 1.5070 + if (*lp<FASTBASE) continue; /* it fits */ 1.5071 + lcarry=*lp/FASTBASE; /* top part [slow divide] */ 1.5072 + /* lcarry can exceed 2**32-1, so check again; this check */ 1.5073 + /* and occasional extra divide (slow) is well worth it, as */ 1.5074 + /* it allows FASTLAZY to be increased to 18 rather than 4 */ 1.5075 + /* in the FASTDIGS=9 case */ 1.5076 + if (lcarry<FASTBASE) carry=(uInt)lcarry; /* [usual] */ 1.5077 + else { /* two-place carry [fairly rare] */ 1.5078 + uInt carry2=(uInt)(lcarry/FASTBASE); /* top top part */ 1.5079 + *(lp+2)+=carry2; /* add to item+2 */ 1.5080 + *lp-=((uLong)FASTBASE*FASTBASE*carry2); /* [slow] */ 1.5081 + carry=(uInt)(lcarry-((uLong)FASTBASE*carry2)); /* [inline] */ 1.5082 + } 1.5083 + *(lp+1)+=carry; /* add to item above [inline] */ 1.5084 + *lp-=((uLong)FASTBASE*carry); /* [inline] */ 1.5085 + } /* carry resolution */ 1.5086 + } /* rip loop */ 1.5087 + 1.5088 + /* The multiplication is complete; time to convert back into */ 1.5089 + /* units. This can be done in-place in the accumulator and in */ 1.5090 + /* 32-bit operations, because carries were resolved after the */ 1.5091 + /* final add. This needs N-1 divides and multiplies for */ 1.5092 + /* each item in the accumulator (which will become up to N */ 1.5093 + /* units, where 2<=N<=9). */ 1.5094 + for (lp=zacc, up=acc; lp<zacc+iacc; lp++) { 1.5095 + uInt item=(uInt)*lp; /* decapitate to uInt */ 1.5096 + for (p=0; p<FASTDIGS-DECDPUN; p+=DECDPUN, up++) { 1.5097 + uInt part=item/(DECDPUNMAX+1); 1.5098 + *up=(Unit)(item-(part*(DECDPUNMAX+1))); 1.5099 + item=part; 1.5100 + } /* p */ 1.5101 + *up=(Unit)item; up++; /* [final needs no division] */ 1.5102 + } /* lp */ 1.5103 + accunits=up-acc; /* count of units */ 1.5104 + } 1.5105 + else { /* here to use units directly, without chunking ['old code'] */ 1.5106 + #endif 1.5107 + 1.5108 + /* if accumulator will be too long for local storage, then allocate */ 1.5109 + acc=accbuff; /* -> assume buffer for accumulator */ 1.5110 + needbytes=(D2U(lhs->digits)+D2U(rhs->digits))*sizeof(Unit); 1.5111 + if (needbytes>(Int)sizeof(accbuff)) { 1.5112 + allocacc=(Unit *)malloc(needbytes); 1.5113 + if (allocacc==NULL) {*status|=DEC_Insufficient_storage; break;} 1.5114 + acc=(Unit *)allocacc; /* use the allocated space */ 1.5115 + } 1.5116 + 1.5117 + /* Now the main long multiplication loop */ 1.5118 + /* Unlike the equivalent in the IBM Java implementation, there */ 1.5119 + /* is no advantage in calculating from msu to lsu. So, do it */ 1.5120 + /* by the book, as it were. */ 1.5121 + /* Each iteration calculates ACC=ACC+MULTAND*MULT */ 1.5122 + accunits=1; /* accumulator starts at '0' */ 1.5123 + *acc=0; /* .. (lsu=0) */ 1.5124 + shift=0; /* no multiplicand shift at first */ 1.5125 + madlength=D2U(lhs->digits); /* this won't change */ 1.5126 + mermsup=rhs->lsu+D2U(rhs->digits); /* -> msu+1 of multiplier */ 1.5127 + 1.5128 + for (mer=rhs->lsu; mer<mermsup; mer++) { 1.5129 + /* Here, *mer is the next Unit in the multiplier to use */ 1.5130 + /* If non-zero [optimization] add it... */ 1.5131 + if (*mer!=0) accunits=decUnitAddSub(&acc[shift], accunits-shift, 1.5132 + lhs->lsu, madlength, 0, 1.5133 + &acc[shift], *mer) 1.5134 + + shift; 1.5135 + else { /* extend acc with a 0; it will be used shortly */ 1.5136 + *(acc+accunits)=0; /* [this avoids length of <=0 later] */ 1.5137 + accunits++; 1.5138 + } 1.5139 + /* multiply multiplicand by 10**DECDPUN for next Unit to left */ 1.5140 + shift++; /* add this for 'logical length' */ 1.5141 + } /* n */ 1.5142 + #if FASTMUL 1.5143 + } /* unchunked units */ 1.5144 + #endif 1.5145 + /* common end-path */ 1.5146 + #if DECTRACE 1.5147 + decDumpAr('*', acc, accunits); /* Show exact result */ 1.5148 + #endif 1.5149 + 1.5150 + /* acc now contains the exact result of the multiplication, */ 1.5151 + /* possibly with a leading zero unit; build the decNumber from */ 1.5152 + /* it, noting if any residue */ 1.5153 + res->bits=bits; /* set sign */ 1.5154 + res->digits=decGetDigits(acc, accunits); /* count digits exactly */ 1.5155 + 1.5156 + /* There can be a 31-bit wrap in calculating the exponent. */ 1.5157 + /* This can only happen if both input exponents are negative and */ 1.5158 + /* both their magnitudes are large. If there was a wrap, set a */ 1.5159 + /* safe very negative exponent, from which decFinalize() will */ 1.5160 + /* raise a hard underflow shortly. */ 1.5161 + exponent=lhs->exponent+rhs->exponent; /* calculate exponent */ 1.5162 + if (lhs->exponent<0 && rhs->exponent<0 && exponent>0) 1.5163 + exponent=-2*DECNUMMAXE; /* force underflow */ 1.5164 + res->exponent=exponent; /* OK to overwrite now */ 1.5165 + 1.5166 + 1.5167 + /* Set the coefficient. If any rounding, residue records */ 1.5168 + decSetCoeff(res, set, acc, res->digits, &residue, status); 1.5169 + decFinish(res, set, &residue, status); /* final cleanup */ 1.5170 + } while(0); /* end protected */ 1.5171 + 1.5172 + if (allocacc!=NULL) free(allocacc); /* drop any storage used */ 1.5173 + #if DECSUBSET 1.5174 + if (allocrhs!=NULL) free(allocrhs); /* .. */ 1.5175 + if (alloclhs!=NULL) free(alloclhs); /* .. */ 1.5176 + #endif 1.5177 + #if FASTMUL 1.5178 + if (allocrhi!=NULL) free(allocrhi); /* .. */ 1.5179 + if (alloclhi!=NULL) free(alloclhi); /* .. */ 1.5180 + #endif 1.5181 + return res; 1.5182 + } /* decMultiplyOp */ 1.5183 + 1.5184 +/* ------------------------------------------------------------------ */ 1.5185 +/* decExpOp -- effect exponentiation */ 1.5186 +/* */ 1.5187 +/* This computes C = exp(A) */ 1.5188 +/* */ 1.5189 +/* res is C, the result. C may be A */ 1.5190 +/* rhs is A */ 1.5191 +/* set is the context; note that rounding mode has no effect */ 1.5192 +/* */ 1.5193 +/* C must have space for set->digits digits. status is updated but */ 1.5194 +/* not set. */ 1.5195 +/* */ 1.5196 +/* Restrictions: */ 1.5197 +/* */ 1.5198 +/* digits, emax, and -emin in the context must be less than */ 1.5199 +/* 2*DEC_MAX_MATH (1999998), and the rhs must be within these */ 1.5200 +/* bounds or a zero. This is an internal routine, so these */ 1.5201 +/* restrictions are contractual and not enforced. */ 1.5202 +/* */ 1.5203 +/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will */ 1.5204 +/* almost always be correctly rounded, but may be up to 1 ulp in */ 1.5205 +/* error in rare cases. */ 1.5206 +/* */ 1.5207 +/* Finite results will always be full precision and Inexact, except */ 1.5208 +/* when A is a zero or -Infinity (giving 1 or 0 respectively). */ 1.5209 +/* ------------------------------------------------------------------ */ 1.5210 +/* This approach used here is similar to the algorithm described in */ 1.5211 +/* */ 1.5212 +/* Variable Precision Exponential Function, T. E. Hull and */ 1.5213 +/* A. Abrham, ACM Transactions on Mathematical Software, Vol 12 #2, */ 1.5214 +/* pp79-91, ACM, June 1986. */ 1.5215 +/* */ 1.5216 +/* with the main difference being that the iterations in the series */ 1.5217 +/* evaluation are terminated dynamically (which does not require the */ 1.5218 +/* extra variable-precision variables which are expensive in this */ 1.5219 +/* context). */ 1.5220 +/* */ 1.5221 +/* The error analysis in Hull & Abrham's paper applies except for the */ 1.5222 +/* round-off error accumulation during the series evaluation. This */ 1.5223 +/* code does not precalculate the number of iterations and so cannot */ 1.5224 +/* use Horner's scheme. Instead, the accumulation is done at double- */ 1.5225 +/* precision, which ensures that the additions of the terms are exact */ 1.5226 +/* and do not accumulate round-off (and any round-off errors in the */ 1.5227 +/* terms themselves move 'to the right' faster than they can */ 1.5228 +/* accumulate). This code also extends the calculation by allowing, */ 1.5229 +/* in the spirit of other decNumber operators, the input to be more */ 1.5230 +/* precise than the result (the precision used is based on the more */ 1.5231 +/* precise of the input or requested result). */ 1.5232 +/* */ 1.5233 +/* Implementation notes: */ 1.5234 +/* */ 1.5235 +/* 1. This is separated out as decExpOp so it can be called from */ 1.5236 +/* other Mathematical functions (notably Ln) with a wider range */ 1.5237 +/* than normal. In particular, it can handle the slightly wider */ 1.5238 +/* (double) range needed by Ln (which has to be able to calculate */ 1.5239 +/* exp(-x) where x can be the tiniest number (Ntiny). */ 1.5240 +/* */ 1.5241 +/* 2. Normalizing x to be <=0.1 (instead of <=1) reduces loop */ 1.5242 +/* iterations by appoximately a third with additional (although */ 1.5243 +/* diminishing) returns as the range is reduced to even smaller */ 1.5244 +/* fractions. However, h (the power of 10 used to correct the */ 1.5245 +/* result at the end, see below) must be kept <=8 as otherwise */ 1.5246 +/* the final result cannot be computed. Hence the leverage is a */ 1.5247 +/* sliding value (8-h), where potentially the range is reduced */ 1.5248 +/* more for smaller values. */ 1.5249 +/* */ 1.5250 +/* The leverage that can be applied in this way is severely */ 1.5251 +/* limited by the cost of the raise-to-the power at the end, */ 1.5252 +/* which dominates when the number of iterations is small (less */ 1.5253 +/* than ten) or when rhs is short. As an example, the adjustment */ 1.5254 +/* x**10,000,000 needs 31 multiplications, all but one full-width. */ 1.5255 +/* */ 1.5256 +/* 3. The restrictions (especially precision) could be raised with */ 1.5257 +/* care, but the full decNumber range seems very hard within the */ 1.5258 +/* 32-bit limits. */ 1.5259 +/* */ 1.5260 +/* 4. The working precisions for the static buffers are twice the */ 1.5261 +/* obvious size to allow for calls from decNumberPower. */ 1.5262 +/* ------------------------------------------------------------------ */ 1.5263 +decNumber * decExpOp(decNumber *res, const decNumber *rhs, 1.5264 + decContext *set, uInt *status) { 1.5265 + uInt ignore=0; /* working status */ 1.5266 + Int h; /* adjusted exponent for 0.xxxx */ 1.5267 + Int p; /* working precision */ 1.5268 + Int residue; /* rounding residue */ 1.5269 + uInt needbytes; /* for space calculations */ 1.5270 + const decNumber *x=rhs; /* (may point to safe copy later) */ 1.5271 + decContext aset, tset, dset; /* working contexts */ 1.5272 + Int comp; /* work */ 1.5273 + 1.5274 + /* the argument is often copied to normalize it, so (unusually) it */ 1.5275 + /* is treated like other buffers, using DECBUFFER, +1 in case */ 1.5276 + /* DECBUFFER is 0 */ 1.5277 + decNumber bufr[D2N(DECBUFFER*2+1)]; 1.5278 + decNumber *allocrhs=NULL; /* non-NULL if rhs buffer allocated */ 1.5279 + 1.5280 + /* the working precision will be no more than set->digits+8+1 */ 1.5281 + /* so for on-stack buffers DECBUFFER+9 is used, +1 in case DECBUFFER */ 1.5282 + /* is 0 (and twice that for the accumulator) */ 1.5283 + 1.5284 + /* buffer for t, term (working precision plus) */ 1.5285 + decNumber buft[D2N(DECBUFFER*2+9+1)]; 1.5286 + decNumber *allocbuft=NULL; /* -> allocated buft, iff allocated */ 1.5287 + decNumber *t=buft; /* term */ 1.5288 + /* buffer for a, accumulator (working precision * 2), at least 9 */ 1.5289 + decNumber bufa[D2N(DECBUFFER*4+18+1)]; 1.5290 + decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */ 1.5291 + decNumber *a=bufa; /* accumulator */ 1.5292 + /* decNumber for the divisor term; this needs at most 9 digits */ 1.5293 + /* and so can be fixed size [16 so can use standard context] */ 1.5294 + decNumber bufd[D2N(16)]; 1.5295 + decNumber *d=bufd; /* divisor */ 1.5296 + decNumber numone; /* constant 1 */ 1.5297 + 1.5298 + #if DECCHECK 1.5299 + Int iterations=0; /* for later sanity check */ 1.5300 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.5301 + #endif 1.5302 + 1.5303 + do { /* protect allocated storage */ 1.5304 + if (SPECIALARG) { /* handle infinities and NaNs */ 1.5305 + if (decNumberIsInfinite(rhs)) { /* an infinity */ 1.5306 + if (decNumberIsNegative(rhs)) /* -Infinity -> +0 */ 1.5307 + uprv_decNumberZero(res); 1.5308 + else uprv_decNumberCopy(res, rhs); /* +Infinity -> self */ 1.5309 + } 1.5310 + else decNaNs(res, rhs, NULL, set, status); /* a NaN */ 1.5311 + break;} 1.5312 + 1.5313 + if (ISZERO(rhs)) { /* zeros -> exact 1 */ 1.5314 + uprv_decNumberZero(res); /* make clean 1 */ 1.5315 + *res->lsu=1; /* .. */ 1.5316 + break;} /* [no status to set] */ 1.5317 + 1.5318 + /* e**x when 0 < x < 0.66 is < 1+3x/2, hence can fast-path */ 1.5319 + /* positive and negative tiny cases which will result in inexact */ 1.5320 + /* 1. This also allows the later add-accumulate to always be */ 1.5321 + /* exact (because its length will never be more than twice the */ 1.5322 + /* working precision). */ 1.5323 + /* The comparator (tiny) needs just one digit, so use the */ 1.5324 + /* decNumber d for it (reused as the divisor, etc., below); its */ 1.5325 + /* exponent is such that if x is positive it will have */ 1.5326 + /* set->digits-1 zeros between the decimal point and the digit, */ 1.5327 + /* which is 4, and if x is negative one more zero there as the */ 1.5328 + /* more precise result will be of the form 0.9999999 rather than */ 1.5329 + /* 1.0000001. Hence, tiny will be 0.0000004 if digits=7 and x>0 */ 1.5330 + /* or 0.00000004 if digits=7 and x<0. If RHS not larger than */ 1.5331 + /* this then the result will be 1.000000 */ 1.5332 + uprv_decNumberZero(d); /* clean */ 1.5333 + *d->lsu=4; /* set 4 .. */ 1.5334 + d->exponent=-set->digits; /* * 10**(-d) */ 1.5335 + if (decNumberIsNegative(rhs)) d->exponent--; /* negative case */ 1.5336 + comp=decCompare(d, rhs, 1); /* signless compare */ 1.5337 + if (comp==BADINT) { 1.5338 + *status|=DEC_Insufficient_storage; 1.5339 + break;} 1.5340 + if (comp>=0) { /* rhs < d */ 1.5341 + Int shift=set->digits-1; 1.5342 + uprv_decNumberZero(res); /* set 1 */ 1.5343 + *res->lsu=1; /* .. */ 1.5344 + res->digits=decShiftToMost(res->lsu, 1, shift); 1.5345 + res->exponent=-shift; /* make 1.0000... */ 1.5346 + *status|=DEC_Inexact | DEC_Rounded; /* .. inexactly */ 1.5347 + break;} /* tiny */ 1.5348 + 1.5349 + /* set up the context to be used for calculating a, as this is */ 1.5350 + /* used on both paths below */ 1.5351 + uprv_decContextDefault(&aset, DEC_INIT_DECIMAL64); 1.5352 + /* accumulator bounds are as requested (could underflow) */ 1.5353 + aset.emax=set->emax; /* usual bounds */ 1.5354 + aset.emin=set->emin; /* .. */ 1.5355 + aset.clamp=0; /* and no concrete format */ 1.5356 + 1.5357 + /* calculate the adjusted (Hull & Abrham) exponent (where the */ 1.5358 + /* decimal point is just to the left of the coefficient msd) */ 1.5359 + h=rhs->exponent+rhs->digits; 1.5360 + /* if h>8 then 10**h cannot be calculated safely; however, when */ 1.5361 + /* h=8 then exp(|rhs|) will be at least exp(1E+7) which is at */ 1.5362 + /* least 6.59E+4342944, so (due to the restriction on Emax/Emin) */ 1.5363 + /* overflow (or underflow to 0) is guaranteed -- so this case can */ 1.5364 + /* be handled by simply forcing the appropriate excess */ 1.5365 + if (h>8) { /* overflow/underflow */ 1.5366 + /* set up here so Power call below will over or underflow to */ 1.5367 + /* zero; set accumulator to either 2 or 0.02 */ 1.5368 + /* [stack buffer for a is always big enough for this] */ 1.5369 + uprv_decNumberZero(a); 1.5370 + *a->lsu=2; /* not 1 but < exp(1) */ 1.5371 + if (decNumberIsNegative(rhs)) a->exponent=-2; /* make 0.02 */ 1.5372 + h=8; /* clamp so 10**h computable */ 1.5373 + p=9; /* set a working precision */ 1.5374 + } 1.5375 + else { /* h<=8 */ 1.5376 + Int maxlever=(rhs->digits>8?1:0); 1.5377 + /* [could/should increase this for precisions >40 or so, too] */ 1.5378 + 1.5379 + /* if h is 8, cannot normalize to a lower upper limit because */ 1.5380 + /* the final result will not be computable (see notes above), */ 1.5381 + /* but leverage can be applied whenever h is less than 8. */ 1.5382 + /* Apply as much as possible, up to a MAXLEVER digits, which */ 1.5383 + /* sets the tradeoff against the cost of the later a**(10**h). */ 1.5384 + /* As h is increased, the working precision below also */ 1.5385 + /* increases to compensate for the "constant digits at the */ 1.5386 + /* front" effect. */ 1.5387 + Int lever=MINI(8-h, maxlever); /* leverage attainable */ 1.5388 + Int use=-rhs->digits-lever; /* exponent to use for RHS */ 1.5389 + h+=lever; /* apply leverage selected */ 1.5390 + if (h<0) { /* clamp */ 1.5391 + use+=h; /* [may end up subnormal] */ 1.5392 + h=0; 1.5393 + } 1.5394 + /* Take a copy of RHS if it needs normalization (true whenever x>=1) */ 1.5395 + if (rhs->exponent!=use) { 1.5396 + decNumber *newrhs=bufr; /* assume will fit on stack */ 1.5397 + needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit); 1.5398 + if (needbytes>sizeof(bufr)) { /* need malloc space */ 1.5399 + allocrhs=(decNumber *)malloc(needbytes); 1.5400 + if (allocrhs==NULL) { /* hopeless -- abandon */ 1.5401 + *status|=DEC_Insufficient_storage; 1.5402 + break;} 1.5403 + newrhs=allocrhs; /* use the allocated space */ 1.5404 + } 1.5405 + uprv_decNumberCopy(newrhs, rhs); /* copy to safe space */ 1.5406 + newrhs->exponent=use; /* normalize; now <1 */ 1.5407 + x=newrhs; /* ready for use */ 1.5408 + /* decNumberShow(x); */ 1.5409 + } 1.5410 + 1.5411 + /* Now use the usual power series to evaluate exp(x). The */ 1.5412 + /* series starts as 1 + x + x^2/2 ... so prime ready for the */ 1.5413 + /* third term by setting the term variable t=x, the accumulator */ 1.5414 + /* a=1, and the divisor d=2. */ 1.5415 + 1.5416 + /* First determine the working precision. From Hull & Abrham */ 1.5417 + /* this is set->digits+h+2. However, if x is 'over-precise' we */ 1.5418 + /* need to allow for all its digits to potentially participate */ 1.5419 + /* (consider an x where all the excess digits are 9s) so in */ 1.5420 + /* this case use x->digits+h+2 */ 1.5421 + p=MAXI(x->digits, set->digits)+h+2; /* [h<=8] */ 1.5422 + 1.5423 + /* a and t are variable precision, and depend on p, so space */ 1.5424 + /* must be allocated for them if necessary */ 1.5425 + 1.5426 + /* the accumulator needs to be able to hold 2p digits so that */ 1.5427 + /* the additions on the second and subsequent iterations are */ 1.5428 + /* sufficiently exact. */ 1.5429 + needbytes=sizeof(decNumber)+(D2U(p*2)-1)*sizeof(Unit); 1.5430 + if (needbytes>sizeof(bufa)) { /* need malloc space */ 1.5431 + allocbufa=(decNumber *)malloc(needbytes); 1.5432 + if (allocbufa==NULL) { /* hopeless -- abandon */ 1.5433 + *status|=DEC_Insufficient_storage; 1.5434 + break;} 1.5435 + a=allocbufa; /* use the allocated space */ 1.5436 + } 1.5437 + /* the term needs to be able to hold p digits (which is */ 1.5438 + /* guaranteed to be larger than x->digits, so the initial copy */ 1.5439 + /* is safe); it may also be used for the raise-to-power */ 1.5440 + /* calculation below, which needs an extra two digits */ 1.5441 + needbytes=sizeof(decNumber)+(D2U(p+2)-1)*sizeof(Unit); 1.5442 + if (needbytes>sizeof(buft)) { /* need malloc space */ 1.5443 + allocbuft=(decNumber *)malloc(needbytes); 1.5444 + if (allocbuft==NULL) { /* hopeless -- abandon */ 1.5445 + *status|=DEC_Insufficient_storage; 1.5446 + break;} 1.5447 + t=allocbuft; /* use the allocated space */ 1.5448 + } 1.5449 + 1.5450 + uprv_decNumberCopy(t, x); /* term=x */ 1.5451 + uprv_decNumberZero(a); *a->lsu=1; /* accumulator=1 */ 1.5452 + uprv_decNumberZero(d); *d->lsu=2; /* divisor=2 */ 1.5453 + uprv_decNumberZero(&numone); *numone.lsu=1; /* constant 1 for increment */ 1.5454 + 1.5455 + /* set up the contexts for calculating a, t, and d */ 1.5456 + uprv_decContextDefault(&tset, DEC_INIT_DECIMAL64); 1.5457 + dset=tset; 1.5458 + /* accumulator bounds are set above, set precision now */ 1.5459 + aset.digits=p*2; /* double */ 1.5460 + /* term bounds avoid any underflow or overflow */ 1.5461 + tset.digits=p; 1.5462 + tset.emin=DEC_MIN_EMIN; /* [emax is plenty] */ 1.5463 + /* [dset.digits=16, etc., are sufficient] */ 1.5464 + 1.5465 + /* finally ready to roll */ 1.5466 + for (;;) { 1.5467 + #if DECCHECK 1.5468 + iterations++; 1.5469 + #endif 1.5470 + /* only the status from the accumulation is interesting */ 1.5471 + /* [but it should remain unchanged after first add] */ 1.5472 + decAddOp(a, a, t, &aset, 0, status); /* a=a+t */ 1.5473 + decMultiplyOp(t, t, x, &tset, &ignore); /* t=t*x */ 1.5474 + decDivideOp(t, t, d, &tset, DIVIDE, &ignore); /* t=t/d */ 1.5475 + /* the iteration ends when the term cannot affect the result, */ 1.5476 + /* if rounded to p digits, which is when its value is smaller */ 1.5477 + /* than the accumulator by p+1 digits. There must also be */ 1.5478 + /* full precision in a. */ 1.5479 + if (((a->digits+a->exponent)>=(t->digits+t->exponent+p+1)) 1.5480 + && (a->digits>=p)) break; 1.5481 + decAddOp(d, d, &numone, &dset, 0, &ignore); /* d=d+1 */ 1.5482 + } /* iterate */ 1.5483 + 1.5484 + #if DECCHECK 1.5485 + /* just a sanity check; comment out test to show always */ 1.5486 + if (iterations>p+3) 1.5487 + printf("Exp iterations=%ld, status=%08lx, p=%ld, d=%ld\n", 1.5488 + (LI)iterations, (LI)*status, (LI)p, (LI)x->digits); 1.5489 + #endif 1.5490 + } /* h<=8 */ 1.5491 + 1.5492 + /* apply postconditioning: a=a**(10**h) -- this is calculated */ 1.5493 + /* at a slightly higher precision than Hull & Abrham suggest */ 1.5494 + if (h>0) { 1.5495 + Int seenbit=0; /* set once a 1-bit is seen */ 1.5496 + Int i; /* counter */ 1.5497 + Int n=powers[h]; /* always positive */ 1.5498 + aset.digits=p+2; /* sufficient precision */ 1.5499 + /* avoid the overhead and many extra digits of decNumberPower */ 1.5500 + /* as all that is needed is the short 'multipliers' loop; here */ 1.5501 + /* accumulate the answer into t */ 1.5502 + uprv_decNumberZero(t); *t->lsu=1; /* acc=1 */ 1.5503 + for (i=1;;i++){ /* for each bit [top bit ignored] */ 1.5504 + /* abandon if have had overflow or terminal underflow */ 1.5505 + if (*status & (DEC_Overflow|DEC_Underflow)) { /* interesting? */ 1.5506 + if (*status&DEC_Overflow || ISZERO(t)) break;} 1.5507 + n=n<<1; /* move next bit to testable position */ 1.5508 + if (n<0) { /* top bit is set */ 1.5509 + seenbit=1; /* OK, have a significant bit */ 1.5510 + decMultiplyOp(t, t, a, &aset, status); /* acc=acc*x */ 1.5511 + } 1.5512 + if (i==31) break; /* that was the last bit */ 1.5513 + if (!seenbit) continue; /* no need to square 1 */ 1.5514 + decMultiplyOp(t, t, t, &aset, status); /* acc=acc*acc [square] */ 1.5515 + } /*i*/ /* 32 bits */ 1.5516 + /* decNumberShow(t); */ 1.5517 + a=t; /* and carry on using t instead of a */ 1.5518 + } 1.5519 + 1.5520 + /* Copy and round the result to res */ 1.5521 + residue=1; /* indicate dirt to right .. */ 1.5522 + if (ISZERO(a)) residue=0; /* .. unless underflowed to 0 */ 1.5523 + aset.digits=set->digits; /* [use default rounding] */ 1.5524 + decCopyFit(res, a, &aset, &residue, status); /* copy & shorten */ 1.5525 + decFinish(res, set, &residue, status); /* cleanup/set flags */ 1.5526 + } while(0); /* end protected */ 1.5527 + 1.5528 + if (allocrhs !=NULL) free(allocrhs); /* drop any storage used */ 1.5529 + if (allocbufa!=NULL) free(allocbufa); /* .. */ 1.5530 + if (allocbuft!=NULL) free(allocbuft); /* .. */ 1.5531 + /* [status is handled by caller] */ 1.5532 + return res; 1.5533 + } /* decExpOp */ 1.5534 + 1.5535 +/* ------------------------------------------------------------------ */ 1.5536 +/* Initial-estimate natural logarithm table */ 1.5537 +/* */ 1.5538 +/* LNnn -- 90-entry 16-bit table for values from .10 through .99. */ 1.5539 +/* The result is a 4-digit encode of the coefficient (c=the */ 1.5540 +/* top 14 bits encoding 0-9999) and a 2-digit encode of the */ 1.5541 +/* exponent (e=the bottom 2 bits encoding 0-3) */ 1.5542 +/* */ 1.5543 +/* The resulting value is given by: */ 1.5544 +/* */ 1.5545 +/* v = -c * 10**(-e-3) */ 1.5546 +/* */ 1.5547 +/* where e and c are extracted from entry k = LNnn[x-10] */ 1.5548 +/* where x is truncated (NB) into the range 10 through 99, */ 1.5549 +/* and then c = k>>2 and e = k&3. */ 1.5550 +/* ------------------------------------------------------------------ */ 1.5551 +static const uShort LNnn[90]={9016, 8652, 8316, 8008, 7724, 7456, 7208, 1.5552 + 6972, 6748, 6540, 6340, 6148, 5968, 5792, 5628, 5464, 5312, 1.5553 + 5164, 5020, 4884, 4748, 4620, 4496, 4376, 4256, 4144, 4032, 1.5554 + 39233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629, 1.5555 + 29777, 28945, 28129, 27329, 26545, 25777, 25021, 24281, 23553, 22837, 1.5556 + 22137, 21445, 20769, 20101, 19445, 18801, 18165, 17541, 16925, 16321, 1.5557 + 15721, 15133, 14553, 13985, 13421, 12865, 12317, 11777, 11241, 10717, 1.5558 + 10197, 9685, 9177, 8677, 8185, 7697, 7213, 6737, 6269, 5801, 1.5559 + 5341, 4889, 4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254, 1.5560 + 10130, 6046, 20055}; 1.5561 + 1.5562 +/* ------------------------------------------------------------------ */ 1.5563 +/* decLnOp -- effect natural logarithm */ 1.5564 +/* */ 1.5565 +/* This computes C = ln(A) */ 1.5566 +/* */ 1.5567 +/* res is C, the result. C may be A */ 1.5568 +/* rhs is A */ 1.5569 +/* set is the context; note that rounding mode has no effect */ 1.5570 +/* */ 1.5571 +/* C must have space for set->digits digits. */ 1.5572 +/* */ 1.5573 +/* Notable cases: */ 1.5574 +/* A<0 -> Invalid */ 1.5575 +/* A=0 -> -Infinity (Exact) */ 1.5576 +/* A=+Infinity -> +Infinity (Exact) */ 1.5577 +/* A=1 exactly -> 0 (Exact) */ 1.5578 +/* */ 1.5579 +/* Restrictions (as for Exp): */ 1.5580 +/* */ 1.5581 +/* digits, emax, and -emin in the context must be less than */ 1.5582 +/* DEC_MAX_MATH+11 (1000010), and the rhs must be within these */ 1.5583 +/* bounds or a zero. This is an internal routine, so these */ 1.5584 +/* restrictions are contractual and not enforced. */ 1.5585 +/* */ 1.5586 +/* A finite result is rounded using DEC_ROUND_HALF_EVEN; it will */ 1.5587 +/* almost always be correctly rounded, but may be up to 1 ulp in */ 1.5588 +/* error in rare cases. */ 1.5589 +/* ------------------------------------------------------------------ */ 1.5590 +/* The result is calculated using Newton's method, with each */ 1.5591 +/* iteration calculating a' = a + x * exp(-a) - 1. See, for example, */ 1.5592 +/* Epperson 1989. */ 1.5593 +/* */ 1.5594 +/* The iteration ends when the adjustment x*exp(-a)-1 is tiny enough. */ 1.5595 +/* This has to be calculated at the sum of the precision of x and the */ 1.5596 +/* working precision. */ 1.5597 +/* */ 1.5598 +/* Implementation notes: */ 1.5599 +/* */ 1.5600 +/* 1. This is separated out as decLnOp so it can be called from */ 1.5601 +/* other Mathematical functions (e.g., Log 10) with a wider range */ 1.5602 +/* than normal. In particular, it can handle the slightly wider */ 1.5603 +/* (+9+2) range needed by a power function. */ 1.5604 +/* */ 1.5605 +/* 2. The speed of this function is about 10x slower than exp, as */ 1.5606 +/* it typically needs 4-6 iterations for short numbers, and the */ 1.5607 +/* extra precision needed adds a squaring effect, twice. */ 1.5608 +/* */ 1.5609 +/* 3. Fastpaths are included for ln(10) and ln(2), up to length 40, */ 1.5610 +/* as these are common requests. ln(10) is used by log10(x). */ 1.5611 +/* */ 1.5612 +/* 4. An iteration might be saved by widening the LNnn table, and */ 1.5613 +/* would certainly save at least one if it were made ten times */ 1.5614 +/* bigger, too (for truncated fractions 0.100 through 0.999). */ 1.5615 +/* However, for most practical evaluations, at least four or five */ 1.5616 +/* iterations will be neede -- so this would only speed up by */ 1.5617 +/* 20-25% and that probably does not justify increasing the table */ 1.5618 +/* size. */ 1.5619 +/* */ 1.5620 +/* 5. The static buffers are larger than might be expected to allow */ 1.5621 +/* for calls from decNumberPower. */ 1.5622 +/* ------------------------------------------------------------------ */ 1.5623 +#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406 1.5624 +#pragma GCC diagnostic push 1.5625 +#pragma GCC diagnostic ignored "-Warray-bounds" 1.5626 +#endif 1.5627 +decNumber * decLnOp(decNumber *res, const decNumber *rhs, 1.5628 + decContext *set, uInt *status) { 1.5629 + uInt ignore=0; /* working status accumulator */ 1.5630 + uInt needbytes; /* for space calculations */ 1.5631 + Int residue; /* rounding residue */ 1.5632 + Int r; /* rhs=f*10**r [see below] */ 1.5633 + Int p; /* working precision */ 1.5634 + Int pp; /* precision for iteration */ 1.5635 + Int t; /* work */ 1.5636 + 1.5637 + /* buffers for a (accumulator, typically precision+2) and b */ 1.5638 + /* (adjustment calculator, same size) */ 1.5639 + decNumber bufa[D2N(DECBUFFER+12)]; 1.5640 + decNumber *allocbufa=NULL; /* -> allocated bufa, iff allocated */ 1.5641 + decNumber *a=bufa; /* accumulator/work */ 1.5642 + decNumber bufb[D2N(DECBUFFER*2+2)]; 1.5643 + decNumber *allocbufb=NULL; /* -> allocated bufa, iff allocated */ 1.5644 + decNumber *b=bufb; /* adjustment/work */ 1.5645 + 1.5646 + decNumber numone; /* constant 1 */ 1.5647 + decNumber cmp; /* work */ 1.5648 + decContext aset, bset; /* working contexts */ 1.5649 + 1.5650 + #if DECCHECK 1.5651 + Int iterations=0; /* for later sanity check */ 1.5652 + if (decCheckOperands(res, DECUNUSED, rhs, set)) return res; 1.5653 + #endif 1.5654 + 1.5655 + do { /* protect allocated storage */ 1.5656 + if (SPECIALARG) { /* handle infinities and NaNs */ 1.5657 + if (decNumberIsInfinite(rhs)) { /* an infinity */ 1.5658 + if (decNumberIsNegative(rhs)) /* -Infinity -> error */ 1.5659 + *status|=DEC_Invalid_operation; 1.5660 + else uprv_decNumberCopy(res, rhs); /* +Infinity -> self */ 1.5661 + } 1.5662 + else decNaNs(res, rhs, NULL, set, status); /* a NaN */ 1.5663 + break;} 1.5664 + 1.5665 + if (ISZERO(rhs)) { /* +/- zeros -> -Infinity */ 1.5666 + uprv_decNumberZero(res); /* make clean */ 1.5667 + res->bits=DECINF|DECNEG; /* set - infinity */ 1.5668 + break;} /* [no status to set] */ 1.5669 + 1.5670 + /* Non-zero negatives are bad... */ 1.5671 + if (decNumberIsNegative(rhs)) { /* -x -> error */ 1.5672 + *status|=DEC_Invalid_operation; 1.5673 + break;} 1.5674 + 1.5675 + /* Here, rhs is positive, finite, and in range */ 1.5676 + 1.5677 + /* lookaside fastpath code for ln(2) and ln(10) at common lengths */ 1.5678 + if (rhs->exponent==0 && set->digits<=40) { 1.5679 + #if DECDPUN==1 1.5680 + if (rhs->lsu[0]==0 && rhs->lsu[1]==1 && rhs->digits==2) { /* ln(10) */ 1.5681 + #else 1.5682 + if (rhs->lsu[0]==10 && rhs->digits==2) { /* ln(10) */ 1.5683 + #endif 1.5684 + aset=*set; aset.round=DEC_ROUND_HALF_EVEN; 1.5685 + #define LN10 "2.302585092994045684017991454684364207601" 1.5686 + uprv_decNumberFromString(res, LN10, &aset); 1.5687 + *status|=(DEC_Inexact | DEC_Rounded); /* is inexact */ 1.5688 + break;} 1.5689 + if (rhs->lsu[0]==2 && rhs->digits==1) { /* ln(2) */ 1.5690 + aset=*set; aset.round=DEC_ROUND_HALF_EVEN; 1.5691 + #define LN2 "0.6931471805599453094172321214581765680755" 1.5692 + uprv_decNumberFromString(res, LN2, &aset); 1.5693 + *status|=(DEC_Inexact | DEC_Rounded); 1.5694 + break;} 1.5695 + } /* integer and short */ 1.5696 + 1.5697 + /* Determine the working precision. This is normally the */ 1.5698 + /* requested precision + 2, with a minimum of 9. However, if */ 1.5699 + /* the rhs is 'over-precise' then allow for all its digits to */ 1.5700 + /* potentially participate (consider an rhs where all the excess */ 1.5701 + /* digits are 9s) so in this case use rhs->digits+2. */ 1.5702 + p=MAXI(rhs->digits, MAXI(set->digits, 7))+2; 1.5703 + 1.5704 + /* Allocate space for the accumulator and the high-precision */ 1.5705 + /* adjustment calculator, if necessary. The accumulator must */ 1.5706 + /* be able to hold p digits, and the adjustment up to */ 1.5707 + /* rhs->digits+p digits. They are also made big enough for 16 */ 1.5708 + /* digits so that they can be used for calculating the initial */ 1.5709 + /* estimate. */ 1.5710 + needbytes=sizeof(decNumber)+(D2U(MAXI(p,16))-1)*sizeof(Unit); 1.5711 + if (needbytes>sizeof(bufa)) { /* need malloc space */ 1.5712 + allocbufa=(decNumber *)malloc(needbytes); 1.5713 + if (allocbufa==NULL) { /* hopeless -- abandon */ 1.5714 + *status|=DEC_Insufficient_storage; 1.5715 + break;} 1.5716 + a=allocbufa; /* use the allocated space */ 1.5717 + } 1.5718 + pp=p+rhs->digits; 1.5719 + needbytes=sizeof(decNumber)+(D2U(MAXI(pp,16))-1)*sizeof(Unit); 1.5720 + if (needbytes>sizeof(bufb)) { /* need malloc space */ 1.5721 + allocbufb=(decNumber *)malloc(needbytes); 1.5722 + if (allocbufb==NULL) { /* hopeless -- abandon */ 1.5723 + *status|=DEC_Insufficient_storage; 1.5724 + break;} 1.5725 + b=allocbufb; /* use the allocated space */ 1.5726 + } 1.5727 + 1.5728 + /* Prepare an initial estimate in acc. Calculate this by */ 1.5729 + /* considering the coefficient of x to be a normalized fraction, */ 1.5730 + /* f, with the decimal point at far left and multiplied by */ 1.5731 + /* 10**r. Then, rhs=f*10**r and 0.1<=f<1, and */ 1.5732 + /* ln(x) = ln(f) + ln(10)*r */ 1.5733 + /* Get the initial estimate for ln(f) from a small lookup */ 1.5734 + /* table (see above) indexed by the first two digits of f, */ 1.5735 + /* truncated. */ 1.5736 + 1.5737 + uprv_decContextDefault(&aset, DEC_INIT_DECIMAL64); /* 16-digit extended */ 1.5738 + r=rhs->exponent+rhs->digits; /* 'normalised' exponent */ 1.5739 + uprv_decNumberFromInt32(a, r); /* a=r */ 1.5740 + uprv_decNumberFromInt32(b, 2302585); /* b=ln(10) (2.302585) */ 1.5741 + b->exponent=-6; /* .. */ 1.5742 + decMultiplyOp(a, a, b, &aset, &ignore); /* a=a*b */ 1.5743 + /* now get top two digits of rhs into b by simple truncate and */ 1.5744 + /* force to integer */ 1.5745 + residue=0; /* (no residue) */ 1.5746 + aset.digits=2; aset.round=DEC_ROUND_DOWN; 1.5747 + decCopyFit(b, rhs, &aset, &residue, &ignore); /* copy & shorten */ 1.5748 + b->exponent=0; /* make integer */ 1.5749 + t=decGetInt(b); /* [cannot fail] */ 1.5750 + if (t<10) t=X10(t); /* adjust single-digit b */ 1.5751 + t=LNnn[t-10]; /* look up ln(b) */ 1.5752 + uprv_decNumberFromInt32(b, t>>2); /* b=ln(b) coefficient */ 1.5753 + b->exponent=-(t&3)-3; /* set exponent */ 1.5754 + b->bits=DECNEG; /* ln(0.10)->ln(0.99) always -ve */ 1.5755 + aset.digits=16; aset.round=DEC_ROUND_HALF_EVEN; /* restore */ 1.5756 + decAddOp(a, a, b, &aset, 0, &ignore); /* acc=a+b */ 1.5757 + /* the initial estimate is now in a, with up to 4 digits correct. */ 1.5758 + /* When rhs is at or near Nmax the estimate will be low, so we */ 1.5759 + /* will approach it from below, avoiding overflow when calling exp. */ 1.5760 + 1.5761 + uprv_decNumberZero(&numone); *numone.lsu=1; /* constant 1 for adjustment */ 1.5762 + 1.5763 + /* accumulator bounds are as requested (could underflow, but */ 1.5764 + /* cannot overflow) */ 1.5765 + aset.emax=set->emax; 1.5766 + aset.emin=set->emin; 1.5767 + aset.clamp=0; /* no concrete format */ 1.5768 + /* set up a context to be used for the multiply and subtract */ 1.5769 + bset=aset; 1.5770 + bset.emax=DEC_MAX_MATH*2; /* use double bounds for the */ 1.5771 + bset.emin=-DEC_MAX_MATH*2; /* adjustment calculation */ 1.5772 + /* [see decExpOp call below] */ 1.5773 + /* for each iteration double the number of digits to calculate, */ 1.5774 + /* up to a maximum of p */ 1.5775 + pp=9; /* initial precision */ 1.5776 + /* [initially 9 as then the sequence starts 7+2, 16+2, and */ 1.5777 + /* 34+2, which is ideal for standard-sized numbers] */ 1.5778 + aset.digits=pp; /* working context */ 1.5779 + bset.digits=pp+rhs->digits; /* wider context */ 1.5780 + for (;;) { /* iterate */ 1.5781 + #if DECCHECK 1.5782 + iterations++; 1.5783 + if (iterations>24) break; /* consider 9 * 2**24 */ 1.5784 + #endif 1.5785 + /* calculate the adjustment (exp(-a)*x-1) into b. This is a */ 1.5786 + /* catastrophic subtraction but it really is the difference */ 1.5787 + /* from 1 that is of interest. */ 1.5788 + /* Use the internal entry point to Exp as it allows the double */ 1.5789 + /* range for calculating exp(-a) when a is the tiniest subnormal. */ 1.5790 + a->bits^=DECNEG; /* make -a */ 1.5791 + decExpOp(b, a, &bset, &ignore); /* b=exp(-a) */ 1.5792 + a->bits^=DECNEG; /* restore sign of a */ 1.5793 + /* now multiply by rhs and subtract 1, at the wider precision */ 1.5794 + decMultiplyOp(b, b, rhs, &bset, &ignore); /* b=b*rhs */ 1.5795 + decAddOp(b, b, &numone, &bset, DECNEG, &ignore); /* b=b-1 */ 1.5796 + 1.5797 + /* the iteration ends when the adjustment cannot affect the */ 1.5798 + /* result by >=0.5 ulp (at the requested digits), which */ 1.5799 + /* is when its value is smaller than the accumulator by */ 1.5800 + /* set->digits+1 digits (or it is zero) -- this is a looser */ 1.5801 + /* requirement than for Exp because all that happens to the */ 1.5802 + /* accumulator after this is the final rounding (but note that */ 1.5803 + /* there must also be full precision in a, or a=0). */ 1.5804 + 1.5805 + if (decNumberIsZero(b) || 1.5806 + (a->digits+a->exponent)>=(b->digits+b->exponent+set->digits+1)) { 1.5807 + if (a->digits==p) break; 1.5808 + if (decNumberIsZero(a)) { 1.5809 + decCompareOp(&cmp, rhs, &numone, &aset, COMPARE, &ignore); /* rhs=1 ? */ 1.5810 + if (cmp.lsu[0]==0) a->exponent=0; /* yes, exact 0 */ 1.5811 + else *status|=(DEC_Inexact | DEC_Rounded); /* no, inexact */ 1.5812 + break; 1.5813 + } 1.5814 + /* force padding if adjustment has gone to 0 before full length */ 1.5815 + if (decNumberIsZero(b)) b->exponent=a->exponent-p; 1.5816 + } 1.5817 + 1.5818 + /* not done yet ... */ 1.5819 + decAddOp(a, a, b, &aset, 0, &ignore); /* a=a+b for next estimate */ 1.5820 + if (pp==p) continue; /* precision is at maximum */ 1.5821 + /* lengthen the next calculation */ 1.5822 + pp=pp*2; /* double precision */ 1.5823 + if (pp>p) pp=p; /* clamp to maximum */ 1.5824 + aset.digits=pp; /* working context */ 1.5825 + bset.digits=pp+rhs->digits; /* wider context */ 1.5826 + } /* Newton's iteration */ 1.5827 + 1.5828 + #if DECCHECK 1.5829 + /* just a sanity check; remove the test to show always */ 1.5830 + if (iterations>24) 1.5831 + printf("Ln iterations=%ld, status=%08lx, p=%ld, d=%ld\n", 1.5832 + (LI)iterations, (LI)*status, (LI)p, (LI)rhs->digits); 1.5833 + #endif 1.5834 + 1.5835 + /* Copy and round the result to res */ 1.5836 + residue=1; /* indicate dirt to right */ 1.5837 + if (ISZERO(a)) residue=0; /* .. unless underflowed to 0 */ 1.5838 + aset.digits=set->digits; /* [use default rounding] */ 1.5839 + decCopyFit(res, a, &aset, &residue, status); /* copy & shorten */ 1.5840 + decFinish(res, set, &residue, status); /* cleanup/set flags */ 1.5841 + } while(0); /* end protected */ 1.5842 + 1.5843 + if (allocbufa!=NULL) free(allocbufa); /* drop any storage used */ 1.5844 + if (allocbufb!=NULL) free(allocbufb); /* .. */ 1.5845 + /* [status is handled by caller] */ 1.5846 + return res; 1.5847 + } /* decLnOp */ 1.5848 +#if defined(__clang__) || U_GCC_MAJOR_MINOR >= 406 1.5849 +#pragma GCC diagnostic pop 1.5850 +#endif 1.5851 + 1.5852 +/* ------------------------------------------------------------------ */ 1.5853 +/* decQuantizeOp -- force exponent to requested value */ 1.5854 +/* */ 1.5855 +/* This computes C = op(A, B), where op adjusts the coefficient */ 1.5856 +/* of C (by rounding or shifting) such that the exponent (-scale) */ 1.5857 +/* of C has the value B or matches the exponent of B. */ 1.5858 +/* The numerical value of C will equal A, except for the effects of */ 1.5859 +/* any rounding that occurred. */ 1.5860 +/* */ 1.5861 +/* res is C, the result. C may be A or B */ 1.5862 +/* lhs is A, the number to adjust */ 1.5863 +/* rhs is B, the requested exponent */ 1.5864 +/* set is the context */ 1.5865 +/* quant is 1 for quantize or 0 for rescale */ 1.5866 +/* status is the status accumulator (this can be called without */ 1.5867 +/* risk of control loss) */ 1.5868 +/* */ 1.5869 +/* C must have space for set->digits digits. */ 1.5870 +/* */ 1.5871 +/* Unless there is an error or the result is infinite, the exponent */ 1.5872 +/* after the operation is guaranteed to be that requested. */ 1.5873 +/* ------------------------------------------------------------------ */ 1.5874 +static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs, 1.5875 + const decNumber *rhs, decContext *set, 1.5876 + Flag quant, uInt *status) { 1.5877 + #if DECSUBSET 1.5878 + decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */ 1.5879 + decNumber *allocrhs=NULL; /* .., rhs */ 1.5880 + #endif 1.5881 + const decNumber *inrhs=rhs; /* save original rhs */ 1.5882 + Int reqdigits=set->digits; /* requested DIGITS */ 1.5883 + Int reqexp; /* requested exponent [-scale] */ 1.5884 + Int residue=0; /* rounding residue */ 1.5885 + Int etiny=set->emin-(reqdigits-1); 1.5886 + 1.5887 + #if DECCHECK 1.5888 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.5889 + #endif 1.5890 + 1.5891 + do { /* protect allocated storage */ 1.5892 + #if DECSUBSET 1.5893 + if (!set->extended) { 1.5894 + /* reduce operands and set lostDigits status, as needed */ 1.5895 + if (lhs->digits>reqdigits) { 1.5896 + alloclhs=decRoundOperand(lhs, set, status); 1.5897 + if (alloclhs==NULL) break; 1.5898 + lhs=alloclhs; 1.5899 + } 1.5900 + if (rhs->digits>reqdigits) { /* [this only checks lostDigits] */ 1.5901 + allocrhs=decRoundOperand(rhs, set, status); 1.5902 + if (allocrhs==NULL) break; 1.5903 + rhs=allocrhs; 1.5904 + } 1.5905 + } 1.5906 + #endif 1.5907 + /* [following code does not require input rounding] */ 1.5908 + 1.5909 + /* Handle special values */ 1.5910 + if (SPECIALARGS) { 1.5911 + /* NaNs get usual processing */ 1.5912 + if (SPECIALARGS & (DECSNAN | DECNAN)) 1.5913 + decNaNs(res, lhs, rhs, set, status); 1.5914 + /* one infinity but not both is bad */ 1.5915 + else if ((lhs->bits ^ rhs->bits) & DECINF) 1.5916 + *status|=DEC_Invalid_operation; 1.5917 + /* both infinity: return lhs */ 1.5918 + else uprv_decNumberCopy(res, lhs); /* [nop if in place] */ 1.5919 + break; 1.5920 + } 1.5921 + 1.5922 + /* set requested exponent */ 1.5923 + if (quant) reqexp=inrhs->exponent; /* quantize -- match exponents */ 1.5924 + else { /* rescale -- use value of rhs */ 1.5925 + /* Original rhs must be an integer that fits and is in range, */ 1.5926 + /* which could be from -1999999997 to +999999999, thanks to */ 1.5927 + /* subnormals */ 1.5928 + reqexp=decGetInt(inrhs); /* [cannot fail] */ 1.5929 + } 1.5930 + 1.5931 + #if DECSUBSET 1.5932 + if (!set->extended) etiny=set->emin; /* no subnormals */ 1.5933 + #endif 1.5934 + 1.5935 + if (reqexp==BADINT /* bad (rescale only) or .. */ 1.5936 + || reqexp==BIGODD || reqexp==BIGEVEN /* very big (ditto) or .. */ 1.5937 + || (reqexp<etiny) /* < lowest */ 1.5938 + || (reqexp>set->emax)) { /* > emax */ 1.5939 + *status|=DEC_Invalid_operation; 1.5940 + break;} 1.5941 + 1.5942 + /* the RHS has been processed, so it can be overwritten now if necessary */ 1.5943 + if (ISZERO(lhs)) { /* zero coefficient unchanged */ 1.5944 + uprv_decNumberCopy(res, lhs); /* [nop if in place] */ 1.5945 + res->exponent=reqexp; /* .. just set exponent */ 1.5946 + #if DECSUBSET 1.5947 + if (!set->extended) res->bits=0; /* subset specification; no -0 */ 1.5948 + #endif 1.5949 + } 1.5950 + else { /* non-zero lhs */ 1.5951 + Int adjust=reqexp-lhs->exponent; /* digit adjustment needed */ 1.5952 + /* if adjusted coefficient will definitely not fit, give up now */ 1.5953 + if ((lhs->digits-adjust)>reqdigits) { 1.5954 + *status|=DEC_Invalid_operation; 1.5955 + break; 1.5956 + } 1.5957 + 1.5958 + if (adjust>0) { /* increasing exponent */ 1.5959 + /* this will decrease the length of the coefficient by adjust */ 1.5960 + /* digits, and must round as it does so */ 1.5961 + decContext workset; /* work */ 1.5962 + workset=*set; /* clone rounding, etc. */ 1.5963 + workset.digits=lhs->digits-adjust; /* set requested length */ 1.5964 + /* [note that the latter can be <1, here] */ 1.5965 + decCopyFit(res, lhs, &workset, &residue, status); /* fit to result */ 1.5966 + decApplyRound(res, &workset, residue, status); /* .. and round */ 1.5967 + residue=0; /* [used] */ 1.5968 + /* If just rounded a 999s case, exponent will be off by one; */ 1.5969 + /* adjust back (after checking space), if so. */ 1.5970 + if (res->exponent>reqexp) { 1.5971 + /* re-check needed, e.g., for quantize(0.9999, 0.001) under */ 1.5972 + /* set->digits==3 */ 1.5973 + if (res->digits==reqdigits) { /* cannot shift by 1 */ 1.5974 + *status&=~(DEC_Inexact | DEC_Rounded); /* [clean these] */ 1.5975 + *status|=DEC_Invalid_operation; 1.5976 + break; 1.5977 + } 1.5978 + res->digits=decShiftToMost(res->lsu, res->digits, 1); /* shift */ 1.5979 + res->exponent--; /* (re)adjust the exponent. */ 1.5980 + } 1.5981 + #if DECSUBSET 1.5982 + if (ISZERO(res) && !set->extended) res->bits=0; /* subset; no -0 */ 1.5983 + #endif 1.5984 + } /* increase */ 1.5985 + else /* adjust<=0 */ { /* decreasing or = exponent */ 1.5986 + /* this will increase the length of the coefficient by -adjust */ 1.5987 + /* digits, by adding zero or more trailing zeros; this is */ 1.5988 + /* already checked for fit, above */ 1.5989 + uprv_decNumberCopy(res, lhs); /* [it will fit] */ 1.5990 + /* if padding needed (adjust<0), add it now... */ 1.5991 + if (adjust<0) { 1.5992 + res->digits=decShiftToMost(res->lsu, res->digits, -adjust); 1.5993 + res->exponent+=adjust; /* adjust the exponent */ 1.5994 + } 1.5995 + } /* decrease */ 1.5996 + } /* non-zero */ 1.5997 + 1.5998 + /* Check for overflow [do not use Finalize in this case, as an */ 1.5999 + /* overflow here is a "don't fit" situation] */ 1.6000 + if (res->exponent>set->emax-res->digits+1) { /* too big */ 1.6001 + *status|=DEC_Invalid_operation; 1.6002 + break; 1.6003 + } 1.6004 + else { 1.6005 + decFinalize(res, set, &residue, status); /* set subnormal flags */ 1.6006 + *status&=~DEC_Underflow; /* suppress Underflow [as per 754] */ 1.6007 + } 1.6008 + } while(0); /* end protected */ 1.6009 + 1.6010 + #if DECSUBSET 1.6011 + if (allocrhs!=NULL) free(allocrhs); /* drop any storage used */ 1.6012 + if (alloclhs!=NULL) free(alloclhs); /* .. */ 1.6013 + #endif 1.6014 + return res; 1.6015 + } /* decQuantizeOp */ 1.6016 + 1.6017 +/* ------------------------------------------------------------------ */ 1.6018 +/* decCompareOp -- compare, min, or max two Numbers */ 1.6019 +/* */ 1.6020 +/* This computes C = A ? B and carries out one of four operations: */ 1.6021 +/* COMPARE -- returns the signum (as a number) giving the */ 1.6022 +/* result of a comparison unless one or both */ 1.6023 +/* operands is a NaN (in which case a NaN results) */ 1.6024 +/* COMPSIG -- as COMPARE except that a quiet NaN raises */ 1.6025 +/* Invalid operation. */ 1.6026 +/* COMPMAX -- returns the larger of the operands, using the */ 1.6027 +/* 754 maxnum operation */ 1.6028 +/* COMPMAXMAG -- ditto, comparing absolute values */ 1.6029 +/* COMPMIN -- the 754 minnum operation */ 1.6030 +/* COMPMINMAG -- ditto, comparing absolute values */ 1.6031 +/* COMTOTAL -- returns the signum (as a number) giving the */ 1.6032 +/* result of a comparison using 754 total ordering */ 1.6033 +/* */ 1.6034 +/* res is C, the result. C may be A and/or B (e.g., X=X?X) */ 1.6035 +/* lhs is A */ 1.6036 +/* rhs is B */ 1.6037 +/* set is the context */ 1.6038 +/* op is the operation flag */ 1.6039 +/* status is the usual accumulator */ 1.6040 +/* */ 1.6041 +/* C must have space for one digit for COMPARE or set->digits for */ 1.6042 +/* COMPMAX, COMPMIN, COMPMAXMAG, or COMPMINMAG. */ 1.6043 +/* ------------------------------------------------------------------ */ 1.6044 +/* The emphasis here is on speed for common cases, and avoiding */ 1.6045 +/* coefficient comparison if possible. */ 1.6046 +/* ------------------------------------------------------------------ */ 1.6047 +static decNumber * decCompareOp(decNumber *res, const decNumber *lhs, 1.6048 + const decNumber *rhs, decContext *set, 1.6049 + Flag op, uInt *status) { 1.6050 + #if DECSUBSET 1.6051 + decNumber *alloclhs=NULL; /* non-NULL if rounded lhs allocated */ 1.6052 + decNumber *allocrhs=NULL; /* .., rhs */ 1.6053 + #endif 1.6054 + Int result=0; /* default result value */ 1.6055 + uByte merged; /* work */ 1.6056 + 1.6057 + #if DECCHECK 1.6058 + if (decCheckOperands(res, lhs, rhs, set)) return res; 1.6059 + #endif 1.6060 + 1.6061 + do { /* protect allocated storage */ 1.6062 + #if DECSUBSET 1.6063 + if (!set->extended) { 1.6064 + /* reduce operands and set lostDigits status, as needed */ 1.6065 + if (lhs->digits>set->digits) { 1.6066 + alloclhs=decRoundOperand(lhs, set, status); 1.6067 + if (alloclhs==NULL) {result=BADINT; break;} 1.6068 + lhs=alloclhs; 1.6069 + } 1.6070 + if (rhs->digits>set->digits) { 1.6071 + allocrhs=decRoundOperand(rhs, set, status); 1.6072 + if (allocrhs==NULL) {result=BADINT; break;} 1.6073 + rhs=allocrhs; 1.6074 + } 1.6075 + } 1.6076 + #endif 1.6077 + /* [following code does not require input rounding] */ 1.6078 + 1.6079 + /* If total ordering then handle differing signs 'up front' */ 1.6080 + if (op==COMPTOTAL) { /* total ordering */ 1.6081 + if (decNumberIsNegative(lhs) && !decNumberIsNegative(rhs)) { 1.6082 + result=-1; 1.6083 + break; 1.6084 + } 1.6085 + if (!decNumberIsNegative(lhs) && decNumberIsNegative(rhs)) { 1.6086 + result=+1; 1.6087 + break; 1.6088 + } 1.6089 + } 1.6090 + 1.6091 + /* handle NaNs specially; let infinities drop through */ 1.6092 + /* This assumes sNaN (even just one) leads to NaN. */ 1.6093 + merged=(lhs->bits | rhs->bits) & (DECSNAN | DECNAN); 1.6094 + if (merged) { /* a NaN bit set */ 1.6095 + if (op==COMPARE); /* result will be NaN */ 1.6096 + else if (op==COMPSIG) /* treat qNaN as sNaN */ 1.6097 + *status|=DEC_Invalid_operation | DEC_sNaN; 1.6098 + else if (op==COMPTOTAL) { /* total ordering, always finite */ 1.6099 + /* signs are known to be the same; compute the ordering here */ 1.6100 + /* as if the signs are both positive, then invert for negatives */ 1.6101 + if (!decNumberIsNaN(lhs)) result=-1; 1.6102 + else if (!decNumberIsNaN(rhs)) result=+1; 1.6103 + /* here if both NaNs */ 1.6104 + else if (decNumberIsSNaN(lhs) && decNumberIsQNaN(rhs)) result=-1; 1.6105 + else if (decNumberIsQNaN(lhs) && decNumberIsSNaN(rhs)) result=+1; 1.6106 + else { /* both NaN or both sNaN */ 1.6107 + /* now it just depends on the payload */ 1.6108 + result=decUnitCompare(lhs->lsu, D2U(lhs->digits), 1.6109 + rhs->lsu, D2U(rhs->digits), 0); 1.6110 + /* [Error not possible, as these are 'aligned'] */ 1.6111 + } /* both same NaNs */ 1.6112 + if (decNumberIsNegative(lhs)) result=-result; 1.6113 + break; 1.6114 + } /* total order */ 1.6115 + 1.6116 + else if (merged & DECSNAN); /* sNaN -> qNaN */ 1.6117 + else { /* here if MIN or MAX and one or two quiet NaNs */ 1.6118 + /* min or max -- 754 rules ignore single NaN */ 1.6119 + if (!decNumberIsNaN(lhs) || !decNumberIsNaN(rhs)) { 1.6120 + /* just one NaN; force choice to be the non-NaN operand */ 1.6121 + op=COMPMAX; 1.6122 + if (lhs->bits & DECNAN) result=-1; /* pick rhs */ 1.6123 + else result=+1; /* pick lhs */ 1.6124 + break; 1.6125 + } 1.6126 + } /* max or min */ 1.6127 + op=COMPNAN; /* use special path */ 1.6128 + decNaNs(res, lhs, rhs, set, status); /* propagate NaN */ 1.6129 + break; 1.6130 + } 1.6131 + /* have numbers */ 1.6132 + if (op==COMPMAXMAG || op==COMPMINMAG) result=decCompare(lhs, rhs, 1); 1.6133 + else result=decCompare(lhs, rhs, 0); /* sign matters */ 1.6134 + } while(0); /* end protected */ 1.6135 + 1.6136 + if (result==BADINT) *status|=DEC_Insufficient_storage; /* rare */ 1.6137 + else { 1.6138 + if (op==COMPARE || op==COMPSIG ||op==COMPTOTAL) { /* returning signum */ 1.6139 + if (op==COMPTOTAL && result==0) { 1.6140 + /* operands are numerically equal or same NaN (and same sign, */ 1.6141 + /* tested first); if identical, leave result 0 */ 1.6142 + if (lhs->exponent!=rhs->exponent) { 1.6143 + if (lhs->exponent<rhs->exponent) result=-1; 1.6144 + else result=+1; 1.6145 + if (decNumberIsNegative(lhs)) result=-result; 1.6146 + } /* lexp!=rexp */ 1.6147 + } /* total-order by exponent */ 1.6148 + uprv_decNumberZero(res); /* [always a valid result] */ 1.6149 + if (result!=0) { /* must be -1 or +1 */ 1.6150 + *res->lsu=1; 1.6151 + if (result<0) res->bits=DECNEG; 1.6152 + } 1.6153 + } 1.6154 + else if (op==COMPNAN); /* special, drop through */ 1.6155 + else { /* MAX or MIN, non-NaN result */ 1.6156 + Int residue=0; /* rounding accumulator */ 1.6157 + /* choose the operand for the result */ 1.6158 + const decNumber *choice; 1.6159 + if (result==0) { /* operands are numerically equal */ 1.6160 + /* choose according to sign then exponent (see 754) */ 1.6161 + uByte slhs=(lhs->bits & DECNEG); 1.6162 + uByte srhs=(rhs->bits & DECNEG); 1.6163 + #if DECSUBSET 1.6164 + if (!set->extended) { /* subset: force left-hand */ 1.6165 + op=COMPMAX; 1.6166 + result=+1; 1.6167 + } 1.6168 + else 1.6169 + #endif 1.6170 + if (slhs!=srhs) { /* signs differ */ 1.6171 + if (slhs) result=-1; /* rhs is max */ 1.6172 + else result=+1; /* lhs is max */ 1.6173 + } 1.6174 + else if (slhs && srhs) { /* both negative */ 1.6175 + if (lhs->exponent<rhs->exponent) result=+1; 1.6176 + else result=-1; 1.6177 + /* [if equal, use lhs, technically identical] */ 1.6178 + } 1.6179 + else { /* both positive */ 1.6180 + if (lhs->exponent>rhs->exponent) result=+1; 1.6181 + else result=-1; 1.6182 + /* [ditto] */ 1.6183 + } 1.6184 + } /* numerically equal */ 1.6185 + /* here result will be non-0; reverse if looking for MIN */ 1.6186 + if (op==COMPMIN || op==COMPMINMAG) result=-result; 1.6187 + choice=(result>0 ? lhs : rhs); /* choose */ 1.6188 + /* copy chosen to result, rounding if need be */ 1.6189 + decCopyFit(res, choice, set, &residue, status); 1.6190 + decFinish(res, set, &residue, status); 1.6191 + } 1.6192 + } 1.6193 + #if DECSUBSET 1.6194 + if (allocrhs!=NULL) free(allocrhs); /* free any storage used */ 1.6195 + if (alloclhs!=NULL) free(alloclhs); /* .. */ 1.6196 + #endif 1.6197 + return res; 1.6198 + } /* decCompareOp */ 1.6199 + 1.6200 +/* ------------------------------------------------------------------ */ 1.6201 +/* decCompare -- compare two decNumbers by numerical value */ 1.6202 +/* */ 1.6203 +/* This routine compares A ? B without altering them. */ 1.6204 +/* */ 1.6205 +/* Arg1 is A, a decNumber which is not a NaN */ 1.6206 +/* Arg2 is B, a decNumber which is not a NaN */ 1.6207 +/* Arg3 is 1 for a sign-independent compare, 0 otherwise */ 1.6208 +/* */ 1.6209 +/* returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure */ 1.6210 +/* (the only possible failure is an allocation error) */ 1.6211 +/* ------------------------------------------------------------------ */ 1.6212 +static Int decCompare(const decNumber *lhs, const decNumber *rhs, 1.6213 + Flag abs_c) { 1.6214 + Int result; /* result value */ 1.6215 + Int sigr; /* rhs signum */ 1.6216 + Int compare; /* work */ 1.6217 + 1.6218 + result=1; /* assume signum(lhs) */ 1.6219 + if (ISZERO(lhs)) result=0; 1.6220 + if (abs_c) { 1.6221 + if (ISZERO(rhs)) return result; /* LHS wins or both 0 */ 1.6222 + /* RHS is non-zero */ 1.6223 + if (result==0) return -1; /* LHS is 0; RHS wins */ 1.6224 + /* [here, both non-zero, result=1] */ 1.6225 + } 1.6226 + else { /* signs matter */ 1.6227 + if (result && decNumberIsNegative(lhs)) result=-1; 1.6228 + sigr=1; /* compute signum(rhs) */ 1.6229 + if (ISZERO(rhs)) sigr=0; 1.6230 + else if (decNumberIsNegative(rhs)) sigr=-1; 1.6231 + if (result > sigr) return +1; /* L > R, return 1 */ 1.6232 + if (result < sigr) return -1; /* L < R, return -1 */ 1.6233 + if (result==0) return 0; /* both 0 */ 1.6234 + } 1.6235 + 1.6236 + /* signums are the same; both are non-zero */ 1.6237 + if ((lhs->bits | rhs->bits) & DECINF) { /* one or more infinities */ 1.6238 + if (decNumberIsInfinite(rhs)) { 1.6239 + if (decNumberIsInfinite(lhs)) result=0;/* both infinite */ 1.6240 + else result=-result; /* only rhs infinite */ 1.6241 + } 1.6242 + return result; 1.6243 + } 1.6244 + /* must compare the coefficients, allowing for exponents */ 1.6245 + if (lhs->exponent>rhs->exponent) { /* LHS exponent larger */ 1.6246 + /* swap sides, and sign */ 1.6247 + const decNumber *temp=lhs; 1.6248 + lhs=rhs; 1.6249 + rhs=temp; 1.6250 + result=-result; 1.6251 + } 1.6252 + compare=decUnitCompare(lhs->lsu, D2U(lhs->digits), 1.6253 + rhs->lsu, D2U(rhs->digits), 1.6254 + rhs->exponent-lhs->exponent); 1.6255 + if (compare!=BADINT) compare*=result; /* comparison succeeded */ 1.6256 + return compare; 1.6257 + } /* decCompare */ 1.6258 + 1.6259 +/* ------------------------------------------------------------------ */ 1.6260 +/* decUnitCompare -- compare two >=0 integers in Unit arrays */ 1.6261 +/* */ 1.6262 +/* This routine compares A ? B*10**E where A and B are unit arrays */ 1.6263 +/* A is a plain integer */ 1.6264 +/* B has an exponent of E (which must be non-negative) */ 1.6265 +/* */ 1.6266 +/* Arg1 is A first Unit (lsu) */ 1.6267 +/* Arg2 is A length in Units */ 1.6268 +/* Arg3 is B first Unit (lsu) */ 1.6269 +/* Arg4 is B length in Units */ 1.6270 +/* Arg5 is E (0 if the units are aligned) */ 1.6271 +/* */ 1.6272 +/* returns -1, 0, or 1 for A<B, A==B, or A>B, or BADINT if failure */ 1.6273 +/* (the only possible failure is an allocation error, which can */ 1.6274 +/* only occur if E!=0) */ 1.6275 +/* ------------------------------------------------------------------ */ 1.6276 +static Int decUnitCompare(const Unit *a, Int alength, 1.6277 + const Unit *b, Int blength, Int exp) { 1.6278 + Unit *acc; /* accumulator for result */ 1.6279 + Unit accbuff[SD2U(DECBUFFER*2+1)]; /* local buffer */ 1.6280 + Unit *allocacc=NULL; /* -> allocated acc buffer, iff allocated */ 1.6281 + Int accunits, need; /* units in use or needed for acc */ 1.6282 + const Unit *l, *r, *u; /* work */ 1.6283 + Int expunits, exprem, result; /* .. */ 1.6284 + 1.6285 + if (exp==0) { /* aligned; fastpath */ 1.6286 + if (alength>blength) return 1; 1.6287 + if (alength<blength) return -1; 1.6288 + /* same number of units in both -- need unit-by-unit compare */ 1.6289 + l=a+alength-1; 1.6290 + r=b+alength-1; 1.6291 + for (;l>=a; l--, r--) { 1.6292 + if (*l>*r) return 1; 1.6293 + if (*l<*r) return -1; 1.6294 + } 1.6295 + return 0; /* all units match */ 1.6296 + } /* aligned */ 1.6297 + 1.6298 + /* Unaligned. If one is >1 unit longer than the other, padded */ 1.6299 + /* approximately, then can return easily */ 1.6300 + if (alength>blength+(Int)D2U(exp)) return 1; 1.6301 + if (alength+1<blength+(Int)D2U(exp)) return -1; 1.6302 + 1.6303 + /* Need to do a real subtract. For this, a result buffer is needed */ 1.6304 + /* even though only the sign is of interest. Its length needs */ 1.6305 + /* to be the larger of alength and padded blength, +2 */ 1.6306 + need=blength+D2U(exp); /* maximum real length of B */ 1.6307 + if (need<alength) need=alength; 1.6308 + need+=2; 1.6309 + acc=accbuff; /* assume use local buffer */ 1.6310 + if (need*sizeof(Unit)>sizeof(accbuff)) { 1.6311 + allocacc=(Unit *)malloc(need*sizeof(Unit)); 1.6312 + if (allocacc==NULL) return BADINT; /* hopeless -- abandon */ 1.6313 + acc=allocacc; 1.6314 + } 1.6315 + /* Calculate units and remainder from exponent. */ 1.6316 + expunits=exp/DECDPUN; 1.6317 + exprem=exp%DECDPUN; 1.6318 + /* subtract [A+B*(-m)] */ 1.6319 + accunits=decUnitAddSub(a, alength, b, blength, expunits, acc, 1.6320 + -(Int)powers[exprem]); 1.6321 + /* [UnitAddSub result may have leading zeros, even on zero] */ 1.6322 + if (accunits<0) result=-1; /* negative result */ 1.6323 + else { /* non-negative result */ 1.6324 + /* check units of the result before freeing any storage */ 1.6325 + for (u=acc; u<acc+accunits-1 && *u==0;) u++; 1.6326 + result=(*u==0 ? 0 : +1); 1.6327 + } 1.6328 + /* clean up and return the result */ 1.6329 + if (allocacc!=NULL) free(allocacc); /* drop any storage used */ 1.6330 + return result; 1.6331 + } /* decUnitCompare */ 1.6332 + 1.6333 +/* ------------------------------------------------------------------ */ 1.6334 +/* decUnitAddSub -- add or subtract two >=0 integers in Unit arrays */ 1.6335 +/* */ 1.6336 +/* This routine performs the calculation: */ 1.6337 +/* */ 1.6338 +/* C=A+(B*M) */ 1.6339 +/* */ 1.6340 +/* Where M is in the range -DECDPUNMAX through +DECDPUNMAX. */ 1.6341 +/* */ 1.6342 +/* A may be shorter or longer than B. */ 1.6343 +/* */ 1.6344 +/* Leading zeros are not removed after a calculation. The result is */ 1.6345 +/* either the same length as the longer of A and B (adding any */ 1.6346 +/* shift), or one Unit longer than that (if a Unit carry occurred). */ 1.6347 +/* */ 1.6348 +/* A and B content are not altered unless C is also A or B. */ 1.6349 +/* C may be the same array as A or B, but only if no zero padding is */ 1.6350 +/* requested (that is, C may be B only if bshift==0). */ 1.6351 +/* C is filled from the lsu; only those units necessary to complete */ 1.6352 +/* the calculation are referenced. */ 1.6353 +/* */ 1.6354 +/* Arg1 is A first Unit (lsu) */ 1.6355 +/* Arg2 is A length in Units */ 1.6356 +/* Arg3 is B first Unit (lsu) */ 1.6357 +/* Arg4 is B length in Units */ 1.6358 +/* Arg5 is B shift in Units (>=0; pads with 0 units if positive) */ 1.6359 +/* Arg6 is C first Unit (lsu) */ 1.6360 +/* Arg7 is M, the multiplier */ 1.6361 +/* */ 1.6362 +/* returns the count of Units written to C, which will be non-zero */ 1.6363 +/* and negated if the result is negative. That is, the sign of the */ 1.6364 +/* returned Int is the sign of the result (positive for zero) and */ 1.6365 +/* the absolute value of the Int is the count of Units. */ 1.6366 +/* */ 1.6367 +/* It is the caller's responsibility to make sure that C size is */ 1.6368 +/* safe, allowing space if necessary for a one-Unit carry. */ 1.6369 +/* */ 1.6370 +/* This routine is severely performance-critical; *any* change here */ 1.6371 +/* must be measured (timed) to assure no performance degradation. */ 1.6372 +/* In particular, trickery here tends to be counter-productive, as */ 1.6373 +/* increased complexity of code hurts register optimizations on */ 1.6374 +/* register-poor architectures. Avoiding divisions is nearly */ 1.6375 +/* always a Good Idea, however. */ 1.6376 +/* */ 1.6377 +/* Special thanks to Rick McGuire (IBM Cambridge, MA) and Dave Clark */ 1.6378 +/* (IBM Warwick, UK) for some of the ideas used in this routine. */ 1.6379 +/* ------------------------------------------------------------------ */ 1.6380 +static Int decUnitAddSub(const Unit *a, Int alength, 1.6381 + const Unit *b, Int blength, Int bshift, 1.6382 + Unit *c, Int m) { 1.6383 + const Unit *alsu=a; /* A lsu [need to remember it] */ 1.6384 + Unit *clsu=c; /* C ditto */ 1.6385 + Unit *minC; /* low water mark for C */ 1.6386 + Unit *maxC; /* high water mark for C */ 1.6387 + eInt carry=0; /* carry integer (could be Long) */ 1.6388 + Int add; /* work */ 1.6389 + #if DECDPUN<=4 /* myriadal, millenary, etc. */ 1.6390 + Int est; /* estimated quotient */ 1.6391 + #endif 1.6392 + 1.6393 + #if DECTRACE 1.6394 + if (alength<1 || blength<1) 1.6395 + printf("decUnitAddSub: alen blen m %ld %ld [%ld]\n", alength, blength, m); 1.6396 + #endif 1.6397 + 1.6398 + maxC=c+alength; /* A is usually the longer */ 1.6399 + minC=c+blength; /* .. and B the shorter */ 1.6400 + if (bshift!=0) { /* B is shifted; low As copy across */ 1.6401 + minC+=bshift; 1.6402 + /* if in place [common], skip copy unless there's a gap [rare] */ 1.6403 + if (a==c && bshift<=alength) { 1.6404 + c+=bshift; 1.6405 + a+=bshift; 1.6406 + } 1.6407 + else for (; c<clsu+bshift; a++, c++) { /* copy needed */ 1.6408 + if (a<alsu+alength) *c=*a; 1.6409 + else *c=0; 1.6410 + } 1.6411 + } 1.6412 + if (minC>maxC) { /* swap */ 1.6413 + Unit *hold=minC; 1.6414 + minC=maxC; 1.6415 + maxC=hold; 1.6416 + } 1.6417 + 1.6418 + /* For speed, do the addition as two loops; the first where both A */ 1.6419 + /* and B contribute, and the second (if necessary) where only one or */ 1.6420 + /* other of the numbers contribute. */ 1.6421 + /* Carry handling is the same (i.e., duplicated) in each case. */ 1.6422 + for (; c<minC; c++) { 1.6423 + carry+=*a; 1.6424 + a++; 1.6425 + carry+=((eInt)*b)*m; /* [special-casing m=1/-1 */ 1.6426 + b++; /* here is not a win] */ 1.6427 + /* here carry is new Unit of digits; it could be +ve or -ve */ 1.6428 + if ((ueInt)carry<=DECDPUNMAX) { /* fastpath 0-DECDPUNMAX */ 1.6429 + *c=(Unit)carry; 1.6430 + carry=0; 1.6431 + continue; 1.6432 + } 1.6433 + #if DECDPUN==4 /* use divide-by-multiply */ 1.6434 + if (carry>=0) { 1.6435 + est=(((ueInt)carry>>11)*53687)>>18; 1.6436 + *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */ 1.6437 + carry=est; /* likely quotient [89%] */ 1.6438 + if (*c<DECDPUNMAX+1) continue; /* estimate was correct */ 1.6439 + carry++; 1.6440 + *c-=DECDPUNMAX+1; 1.6441 + continue; 1.6442 + } 1.6443 + /* negative case */ 1.6444 + carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */ 1.6445 + est=(((ueInt)carry>>11)*53687)>>18; 1.6446 + *c=(Unit)(carry-est*(DECDPUNMAX+1)); 1.6447 + carry=est-(DECDPUNMAX+1); /* correctly negative */ 1.6448 + if (*c<DECDPUNMAX+1) continue; /* was OK */ 1.6449 + carry++; 1.6450 + *c-=DECDPUNMAX+1; 1.6451 + #elif DECDPUN==3 1.6452 + if (carry>=0) { 1.6453 + est=(((ueInt)carry>>3)*16777)>>21; 1.6454 + *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */ 1.6455 + carry=est; /* likely quotient [99%] */ 1.6456 + if (*c<DECDPUNMAX+1) continue; /* estimate was correct */ 1.6457 + carry++; 1.6458 + *c-=DECDPUNMAX+1; 1.6459 + continue; 1.6460 + } 1.6461 + /* negative case */ 1.6462 + carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */ 1.6463 + est=(((ueInt)carry>>3)*16777)>>21; 1.6464 + *c=(Unit)(carry-est*(DECDPUNMAX+1)); 1.6465 + carry=est-(DECDPUNMAX+1); /* correctly negative */ 1.6466 + if (*c<DECDPUNMAX+1) continue; /* was OK */ 1.6467 + carry++; 1.6468 + *c-=DECDPUNMAX+1; 1.6469 + #elif DECDPUN<=2 1.6470 + /* Can use QUOT10 as carry <= 4 digits */ 1.6471 + if (carry>=0) { 1.6472 + est=QUOT10(carry, DECDPUN); 1.6473 + *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */ 1.6474 + carry=est; /* quotient */ 1.6475 + continue; 1.6476 + } 1.6477 + /* negative case */ 1.6478 + carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */ 1.6479 + est=QUOT10(carry, DECDPUN); 1.6480 + *c=(Unit)(carry-est*(DECDPUNMAX+1)); 1.6481 + carry=est-(DECDPUNMAX+1); /* correctly negative */ 1.6482 + #else 1.6483 + /* remainder operator is undefined if negative, so must test */ 1.6484 + if ((ueInt)carry<(DECDPUNMAX+1)*2) { /* fastpath carry +1 */ 1.6485 + *c=(Unit)(carry-(DECDPUNMAX+1)); /* [helps additions] */ 1.6486 + carry=1; 1.6487 + continue; 1.6488 + } 1.6489 + if (carry>=0) { 1.6490 + *c=(Unit)(carry%(DECDPUNMAX+1)); 1.6491 + carry=carry/(DECDPUNMAX+1); 1.6492 + continue; 1.6493 + } 1.6494 + /* negative case */ 1.6495 + carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */ 1.6496 + *c=(Unit)(carry%(DECDPUNMAX+1)); 1.6497 + carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1); 1.6498 + #endif 1.6499 + } /* c */ 1.6500 + 1.6501 + /* now may have one or other to complete */ 1.6502 + /* [pretest to avoid loop setup/shutdown] */ 1.6503 + if (c<maxC) for (; c<maxC; c++) { 1.6504 + if (a<alsu+alength) { /* still in A */ 1.6505 + carry+=*a; 1.6506 + a++; 1.6507 + } 1.6508 + else { /* inside B */ 1.6509 + carry+=((eInt)*b)*m; 1.6510 + b++; 1.6511 + } 1.6512 + /* here carry is new Unit of digits; it could be +ve or -ve and */ 1.6513 + /* magnitude up to DECDPUNMAX squared */ 1.6514 + if ((ueInt)carry<=DECDPUNMAX) { /* fastpath 0-DECDPUNMAX */ 1.6515 + *c=(Unit)carry; 1.6516 + carry=0; 1.6517 + continue; 1.6518 + } 1.6519 + /* result for this unit is negative or >DECDPUNMAX */ 1.6520 + #if DECDPUN==4 /* use divide-by-multiply */ 1.6521 + if (carry>=0) { 1.6522 + est=(((ueInt)carry>>11)*53687)>>18; 1.6523 + *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */ 1.6524 + carry=est; /* likely quotient [79.7%] */ 1.6525 + if (*c<DECDPUNMAX+1) continue; /* estimate was correct */ 1.6526 + carry++; 1.6527 + *c-=DECDPUNMAX+1; 1.6528 + continue; 1.6529 + } 1.6530 + /* negative case */ 1.6531 + carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */ 1.6532 + est=(((ueInt)carry>>11)*53687)>>18; 1.6533 + *c=(Unit)(carry-est*(DECDPUNMAX+1)); 1.6534 + carry=est-(DECDPUNMAX+1); /* correctly negative */ 1.6535 + if (*c<DECDPUNMAX+1) continue; /* was OK */ 1.6536 + carry++; 1.6537 + *c-=DECDPUNMAX+1; 1.6538 + #elif DECDPUN==3 1.6539 + if (carry>=0) { 1.6540 + est=(((ueInt)carry>>3)*16777)>>21; 1.6541 + *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */ 1.6542 + carry=est; /* likely quotient [99%] */ 1.6543 + if (*c<DECDPUNMAX+1) continue; /* estimate was correct */ 1.6544 + carry++; 1.6545 + *c-=DECDPUNMAX+1; 1.6546 + continue; 1.6547 + } 1.6548 + /* negative case */ 1.6549 + carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */ 1.6550 + est=(((ueInt)carry>>3)*16777)>>21; 1.6551 + *c=(Unit)(carry-est*(DECDPUNMAX+1)); 1.6552 + carry=est-(DECDPUNMAX+1); /* correctly negative */ 1.6553 + if (*c<DECDPUNMAX+1) continue; /* was OK */ 1.6554 + carry++; 1.6555 + *c-=DECDPUNMAX+1; 1.6556 + #elif DECDPUN<=2 1.6557 + if (carry>=0) { 1.6558 + est=QUOT10(carry, DECDPUN); 1.6559 + *c=(Unit)(carry-est*(DECDPUNMAX+1)); /* remainder */ 1.6560 + carry=est; /* quotient */ 1.6561 + continue; 1.6562 + } 1.6563 + /* negative case */ 1.6564 + carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */ 1.6565 + est=QUOT10(carry, DECDPUN); 1.6566 + *c=(Unit)(carry-est*(DECDPUNMAX+1)); 1.6567 + carry=est-(DECDPUNMAX+1); /* correctly negative */ 1.6568 + #else 1.6569 + if ((ueInt)carry<(DECDPUNMAX+1)*2){ /* fastpath carry 1 */ 1.6570 + *c=(Unit)(carry-(DECDPUNMAX+1)); 1.6571 + carry=1; 1.6572 + continue; 1.6573 + } 1.6574 + /* remainder operator is undefined if negative, so must test */ 1.6575 + if (carry>=0) { 1.6576 + *c=(Unit)(carry%(DECDPUNMAX+1)); 1.6577 + carry=carry/(DECDPUNMAX+1); 1.6578 + continue; 1.6579 + } 1.6580 + /* negative case */ 1.6581 + carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); /* make positive */ 1.6582 + *c=(Unit)(carry%(DECDPUNMAX+1)); 1.6583 + carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1); 1.6584 + #endif 1.6585 + } /* c */ 1.6586 + 1.6587 + /* OK, all A and B processed; might still have carry or borrow */ 1.6588 + /* return number of Units in the result, negated if a borrow */ 1.6589 + if (carry==0) return c-clsu; /* no carry, so no more to do */ 1.6590 + if (carry>0) { /* positive carry */ 1.6591 + *c=(Unit)carry; /* place as new unit */ 1.6592 + c++; /* .. */ 1.6593 + return c-clsu; 1.6594 + } 1.6595 + /* -ve carry: it's a borrow; complement needed */ 1.6596 + add=1; /* temporary carry... */ 1.6597 + for (c=clsu; c<maxC; c++) { 1.6598 + add=DECDPUNMAX+add-*c; 1.6599 + if (add<=DECDPUNMAX) { 1.6600 + *c=(Unit)add; 1.6601 + add=0; 1.6602 + } 1.6603 + else { 1.6604 + *c=0; 1.6605 + add=1; 1.6606 + } 1.6607 + } 1.6608 + /* add an extra unit iff it would be non-zero */ 1.6609 + #if DECTRACE 1.6610 + printf("UAS borrow: add %ld, carry %ld\n", add, carry); 1.6611 + #endif 1.6612 + if ((add-carry-1)!=0) { 1.6613 + *c=(Unit)(add-carry-1); 1.6614 + c++; /* interesting, include it */ 1.6615 + } 1.6616 + return clsu-c; /* -ve result indicates borrowed */ 1.6617 + } /* decUnitAddSub */ 1.6618 + 1.6619 +/* ------------------------------------------------------------------ */ 1.6620 +/* decTrim -- trim trailing zeros or normalize */ 1.6621 +/* */ 1.6622 +/* dn is the number to trim or normalize */ 1.6623 +/* set is the context to use to check for clamp */ 1.6624 +/* all is 1 to remove all trailing zeros, 0 for just fraction ones */ 1.6625 +/* noclamp is 1 to unconditional (unclamped) trim */ 1.6626 +/* dropped returns the number of discarded trailing zeros */ 1.6627 +/* returns dn */ 1.6628 +/* */ 1.6629 +/* If clamp is set in the context then the number of zeros trimmed */ 1.6630 +/* may be limited if the exponent is high. */ 1.6631 +/* All fields are updated as required. This is a utility operation, */ 1.6632 +/* so special values are unchanged and no error is possible. */ 1.6633 +/* ------------------------------------------------------------------ */ 1.6634 +static decNumber * decTrim(decNumber *dn, decContext *set, Flag all, 1.6635 + Flag noclamp, Int *dropped) { 1.6636 + Int d, exp; /* work */ 1.6637 + uInt cut; /* .. */ 1.6638 + Unit *up; /* -> current Unit */ 1.6639 + 1.6640 + #if DECCHECK 1.6641 + if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn; 1.6642 + #endif 1.6643 + 1.6644 + *dropped=0; /* assume no zeros dropped */ 1.6645 + if ((dn->bits & DECSPECIAL) /* fast exit if special .. */ 1.6646 + || (*dn->lsu & 0x01)) return dn; /* .. or odd */ 1.6647 + if (ISZERO(dn)) { /* .. or 0 */ 1.6648 + dn->exponent=0; /* (sign is preserved) */ 1.6649 + return dn; 1.6650 + } 1.6651 + 1.6652 + /* have a finite number which is even */ 1.6653 + exp=dn->exponent; 1.6654 + cut=1; /* digit (1-DECDPUN) in Unit */ 1.6655 + up=dn->lsu; /* -> current Unit */ 1.6656 + for (d=0; d<dn->digits-1; d++) { /* [don't strip the final digit] */ 1.6657 + /* slice by powers */ 1.6658 + #if DECDPUN<=4 1.6659 + uInt quot=QUOT10(*up, cut); 1.6660 + if ((*up-quot*powers[cut])!=0) break; /* found non-0 digit */ 1.6661 + #else 1.6662 + if (*up%powers[cut]!=0) break; /* found non-0 digit */ 1.6663 + #endif 1.6664 + /* have a trailing 0 */ 1.6665 + if (!all) { /* trimming */ 1.6666 + /* [if exp>0 then all trailing 0s are significant for trim] */ 1.6667 + if (exp<=0) { /* if digit might be significant */ 1.6668 + if (exp==0) break; /* then quit */ 1.6669 + exp++; /* next digit might be significant */ 1.6670 + } 1.6671 + } 1.6672 + cut++; /* next power */ 1.6673 + if (cut>DECDPUN) { /* need new Unit */ 1.6674 + up++; 1.6675 + cut=1; 1.6676 + } 1.6677 + } /* d */ 1.6678 + if (d==0) return dn; /* none to drop */ 1.6679 + 1.6680 + /* may need to limit drop if clamping */ 1.6681 + if (set->clamp && !noclamp) { 1.6682 + Int maxd=set->emax-set->digits+1-dn->exponent; 1.6683 + if (maxd<=0) return dn; /* nothing possible */ 1.6684 + if (d>maxd) d=maxd; 1.6685 + } 1.6686 + 1.6687 + /* effect the drop */ 1.6688 + decShiftToLeast(dn->lsu, D2U(dn->digits), d); 1.6689 + dn->exponent+=d; /* maintain numerical value */ 1.6690 + dn->digits-=d; /* new length */ 1.6691 + *dropped=d; /* report the count */ 1.6692 + return dn; 1.6693 + } /* decTrim */ 1.6694 + 1.6695 +/* ------------------------------------------------------------------ */ 1.6696 +/* decReverse -- reverse a Unit array in place */ 1.6697 +/* */ 1.6698 +/* ulo is the start of the array */ 1.6699 +/* uhi is the end of the array (highest Unit to include) */ 1.6700 +/* */ 1.6701 +/* The units ulo through uhi are reversed in place (if the number */ 1.6702 +/* of units is odd, the middle one is untouched). Note that the */ 1.6703 +/* digit(s) in each unit are unaffected. */ 1.6704 +/* ------------------------------------------------------------------ */ 1.6705 +static void decReverse(Unit *ulo, Unit *uhi) { 1.6706 + Unit temp; 1.6707 + for (; ulo<uhi; ulo++, uhi--) { 1.6708 + temp=*ulo; 1.6709 + *ulo=*uhi; 1.6710 + *uhi=temp; 1.6711 + } 1.6712 + return; 1.6713 + } /* decReverse */ 1.6714 + 1.6715 +/* ------------------------------------------------------------------ */ 1.6716 +/* decShiftToMost -- shift digits in array towards most significant */ 1.6717 +/* */ 1.6718 +/* uar is the array */ 1.6719 +/* digits is the count of digits in use in the array */ 1.6720 +/* shift is the number of zeros to pad with (least significant); */ 1.6721 +/* it must be zero or positive */ 1.6722 +/* */ 1.6723 +/* returns the new length of the integer in the array, in digits */ 1.6724 +/* */ 1.6725 +/* No overflow is permitted (that is, the uar array must be known to */ 1.6726 +/* be large enough to hold the result, after shifting). */ 1.6727 +/* ------------------------------------------------------------------ */ 1.6728 +static Int decShiftToMost(Unit *uar, Int digits, Int shift) { 1.6729 + Unit *target, *source, *first; /* work */ 1.6730 + Int cut; /* odd 0's to add */ 1.6731 + uInt next; /* work */ 1.6732 + 1.6733 + if (shift==0) return digits; /* [fastpath] nothing to do */ 1.6734 + if ((digits+shift)<=DECDPUN) { /* [fastpath] single-unit case */ 1.6735 + *uar=(Unit)(*uar*powers[shift]); 1.6736 + return digits+shift; 1.6737 + } 1.6738 + 1.6739 + next=0; /* all paths */ 1.6740 + source=uar+D2U(digits)-1; /* where msu comes from */ 1.6741 + target=source+D2U(shift); /* where upper part of first cut goes */ 1.6742 + cut=DECDPUN-MSUDIGITS(shift); /* where to slice */ 1.6743 + if (cut==0) { /* unit-boundary case */ 1.6744 + for (; source>=uar; source--, target--) *target=*source; 1.6745 + } 1.6746 + else { 1.6747 + first=uar+D2U(digits+shift)-1; /* where msu of source will end up */ 1.6748 + for (; source>=uar; source--, target--) { 1.6749 + /* split the source Unit and accumulate remainder for next */ 1.6750 + #if DECDPUN<=4 1.6751 + uInt quot=QUOT10(*source, cut); 1.6752 + uInt rem=*source-quot*powers[cut]; 1.6753 + next+=quot; 1.6754 + #else 1.6755 + uInt rem=*source%powers[cut]; 1.6756 + next+=*source/powers[cut]; 1.6757 + #endif 1.6758 + if (target<=first) *target=(Unit)next; /* write to target iff valid */ 1.6759 + next=rem*powers[DECDPUN-cut]; /* save remainder for next Unit */ 1.6760 + } 1.6761 + } /* shift-move */ 1.6762 + 1.6763 + /* propagate any partial unit to one below and clear the rest */ 1.6764 + for (; target>=uar; target--) { 1.6765 + *target=(Unit)next; 1.6766 + next=0; 1.6767 + } 1.6768 + return digits+shift; 1.6769 + } /* decShiftToMost */ 1.6770 + 1.6771 +/* ------------------------------------------------------------------ */ 1.6772 +/* decShiftToLeast -- shift digits in array towards least significant */ 1.6773 +/* */ 1.6774 +/* uar is the array */ 1.6775 +/* units is length of the array, in units */ 1.6776 +/* shift is the number of digits to remove from the lsu end; it */ 1.6777 +/* must be zero or positive and <= than units*DECDPUN. */ 1.6778 +/* */ 1.6779 +/* returns the new length of the integer in the array, in units */ 1.6780 +/* */ 1.6781 +/* Removed digits are discarded (lost). Units not required to hold */ 1.6782 +/* the final result are unchanged. */ 1.6783 +/* ------------------------------------------------------------------ */ 1.6784 +static Int decShiftToLeast(Unit *uar, Int units, Int shift) { 1.6785 + Unit *target, *up; /* work */ 1.6786 + Int cut, count; /* work */ 1.6787 + Int quot, rem; /* for division */ 1.6788 + 1.6789 + if (shift==0) return units; /* [fastpath] nothing to do */ 1.6790 + if (shift==units*DECDPUN) { /* [fastpath] little to do */ 1.6791 + *uar=0; /* all digits cleared gives zero */ 1.6792 + return 1; /* leaves just the one */ 1.6793 + } 1.6794 + 1.6795 + target=uar; /* both paths */ 1.6796 + cut=MSUDIGITS(shift); 1.6797 + if (cut==DECDPUN) { /* unit-boundary case; easy */ 1.6798 + up=uar+D2U(shift); 1.6799 + for (; up<uar+units; target++, up++) *target=*up; 1.6800 + return target-uar; 1.6801 + } 1.6802 + 1.6803 + /* messier */ 1.6804 + up=uar+D2U(shift-cut); /* source; correct to whole Units */ 1.6805 + count=units*DECDPUN-shift; /* the maximum new length */ 1.6806 + #if DECDPUN<=4 1.6807 + quot=QUOT10(*up, cut); 1.6808 + #else 1.6809 + quot=*up/powers[cut]; 1.6810 + #endif 1.6811 + for (; ; target++) { 1.6812 + *target=(Unit)quot; 1.6813 + count-=(DECDPUN-cut); 1.6814 + if (count<=0) break; 1.6815 + up++; 1.6816 + quot=*up; 1.6817 + #if DECDPUN<=4 1.6818 + quot=QUOT10(quot, cut); 1.6819 + rem=*up-quot*powers[cut]; 1.6820 + #else 1.6821 + rem=quot%powers[cut]; 1.6822 + quot=quot/powers[cut]; 1.6823 + #endif 1.6824 + *target=(Unit)(*target+rem*powers[DECDPUN-cut]); 1.6825 + count-=cut; 1.6826 + if (count<=0) break; 1.6827 + } 1.6828 + return target-uar+1; 1.6829 + } /* decShiftToLeast */ 1.6830 + 1.6831 +#if DECSUBSET 1.6832 +/* ------------------------------------------------------------------ */ 1.6833 +/* decRoundOperand -- round an operand [used for subset only] */ 1.6834 +/* */ 1.6835 +/* dn is the number to round (dn->digits is > set->digits) */ 1.6836 +/* set is the relevant context */ 1.6837 +/* status is the status accumulator */ 1.6838 +/* */ 1.6839 +/* returns an allocated decNumber with the rounded result. */ 1.6840 +/* */ 1.6841 +/* lostDigits and other status may be set by this. */ 1.6842 +/* */ 1.6843 +/* Since the input is an operand, it must not be modified. */ 1.6844 +/* Instead, return an allocated decNumber, rounded as required. */ 1.6845 +/* It is the caller's responsibility to free the allocated storage. */ 1.6846 +/* */ 1.6847 +/* If no storage is available then the result cannot be used, so NULL */ 1.6848 +/* is returned. */ 1.6849 +/* ------------------------------------------------------------------ */ 1.6850 +static decNumber *decRoundOperand(const decNumber *dn, decContext *set, 1.6851 + uInt *status) { 1.6852 + decNumber *res; /* result structure */ 1.6853 + uInt newstatus=0; /* status from round */ 1.6854 + Int residue=0; /* rounding accumulator */ 1.6855 + 1.6856 + /* Allocate storage for the returned decNumber, big enough for the */ 1.6857 + /* length specified by the context */ 1.6858 + res=(decNumber *)malloc(sizeof(decNumber) 1.6859 + +(D2U(set->digits)-1)*sizeof(Unit)); 1.6860 + if (res==NULL) { 1.6861 + *status|=DEC_Insufficient_storage; 1.6862 + return NULL; 1.6863 + } 1.6864 + decCopyFit(res, dn, set, &residue, &newstatus); 1.6865 + decApplyRound(res, set, residue, &newstatus); 1.6866 + 1.6867 + /* If that set Inexact then "lost digits" is raised... */ 1.6868 + if (newstatus & DEC_Inexact) newstatus|=DEC_Lost_digits; 1.6869 + *status|=newstatus; 1.6870 + return res; 1.6871 + } /* decRoundOperand */ 1.6872 +#endif 1.6873 + 1.6874 +/* ------------------------------------------------------------------ */ 1.6875 +/* decCopyFit -- copy a number, truncating the coefficient if needed */ 1.6876 +/* */ 1.6877 +/* dest is the target decNumber */ 1.6878 +/* src is the source decNumber */ 1.6879 +/* set is the context [used for length (digits) and rounding mode] */ 1.6880 +/* residue is the residue accumulator */ 1.6881 +/* status contains the current status to be updated */ 1.6882 +/* */ 1.6883 +/* (dest==src is allowed and will be a no-op if fits) */ 1.6884 +/* All fields are updated as required. */ 1.6885 +/* ------------------------------------------------------------------ */ 1.6886 +static void decCopyFit(decNumber *dest, const decNumber *src, 1.6887 + decContext *set, Int *residue, uInt *status) { 1.6888 + dest->bits=src->bits; 1.6889 + dest->exponent=src->exponent; 1.6890 + decSetCoeff(dest, set, src->lsu, src->digits, residue, status); 1.6891 + } /* decCopyFit */ 1.6892 + 1.6893 +/* ------------------------------------------------------------------ */ 1.6894 +/* decSetCoeff -- set the coefficient of a number */ 1.6895 +/* */ 1.6896 +/* dn is the number whose coefficient array is to be set. */ 1.6897 +/* It must have space for set->digits digits */ 1.6898 +/* set is the context [for size] */ 1.6899 +/* lsu -> lsu of the source coefficient [may be dn->lsu] */ 1.6900 +/* len is digits in the source coefficient [may be dn->digits] */ 1.6901 +/* residue is the residue accumulator. This has values as in */ 1.6902 +/* decApplyRound, and will be unchanged unless the */ 1.6903 +/* target size is less than len. In this case, the */ 1.6904 +/* coefficient is truncated and the residue is updated to */ 1.6905 +/* reflect the previous residue and the dropped digits. */ 1.6906 +/* status is the status accumulator, as usual */ 1.6907 +/* */ 1.6908 +/* The coefficient may already be in the number, or it can be an */ 1.6909 +/* external intermediate array. If it is in the number, lsu must == */ 1.6910 +/* dn->lsu and len must == dn->digits. */ 1.6911 +/* */ 1.6912 +/* Note that the coefficient length (len) may be < set->digits, and */ 1.6913 +/* in this case this merely copies the coefficient (or is a no-op */ 1.6914 +/* if dn->lsu==lsu). */ 1.6915 +/* */ 1.6916 +/* Note also that (only internally, from decQuantizeOp and */ 1.6917 +/* decSetSubnormal) the value of set->digits may be less than one, */ 1.6918 +/* indicating a round to left. This routine handles that case */ 1.6919 +/* correctly; caller ensures space. */ 1.6920 +/* */ 1.6921 +/* dn->digits, dn->lsu (and as required), and dn->exponent are */ 1.6922 +/* updated as necessary. dn->bits (sign) is unchanged. */ 1.6923 +/* */ 1.6924 +/* DEC_Rounded status is set if any digits are discarded. */ 1.6925 +/* DEC_Inexact status is set if any non-zero digits are discarded, or */ 1.6926 +/* incoming residue was non-0 (implies rounded) */ 1.6927 +/* ------------------------------------------------------------------ */ 1.6928 +/* mapping array: maps 0-9 to canonical residues, so that a residue */ 1.6929 +/* can be adjusted in the range [-1, +1] and achieve correct rounding */ 1.6930 +/* 0 1 2 3 4 5 6 7 8 9 */ 1.6931 +static const uByte resmap[10]={0, 3, 3, 3, 3, 5, 7, 7, 7, 7}; 1.6932 +static void decSetCoeff(decNumber *dn, decContext *set, const Unit *lsu, 1.6933 + Int len, Int *residue, uInt *status) { 1.6934 + Int discard; /* number of digits to discard */ 1.6935 + uInt cut; /* cut point in Unit */ 1.6936 + const Unit *up; /* work */ 1.6937 + Unit *target; /* .. */ 1.6938 + Int count; /* .. */ 1.6939 + #if DECDPUN<=4 1.6940 + uInt temp; /* .. */ 1.6941 + #endif 1.6942 + 1.6943 + discard=len-set->digits; /* digits to discard */ 1.6944 + if (discard<=0) { /* no digits are being discarded */ 1.6945 + if (dn->lsu!=lsu) { /* copy needed */ 1.6946 + /* copy the coefficient array to the result number; no shift needed */ 1.6947 + count=len; /* avoids D2U */ 1.6948 + up=lsu; 1.6949 + for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN) 1.6950 + *target=*up; 1.6951 + dn->digits=len; /* set the new length */ 1.6952 + } 1.6953 + /* dn->exponent and residue are unchanged, record any inexactitude */ 1.6954 + if (*residue!=0) *status|=(DEC_Inexact | DEC_Rounded); 1.6955 + return; 1.6956 + } 1.6957 + 1.6958 + /* some digits must be discarded ... */ 1.6959 + dn->exponent+=discard; /* maintain numerical value */ 1.6960 + *status|=DEC_Rounded; /* accumulate Rounded status */ 1.6961 + if (*residue>1) *residue=1; /* previous residue now to right, so reduce */ 1.6962 + 1.6963 + if (discard>len) { /* everything, +1, is being discarded */ 1.6964 + /* guard digit is 0 */ 1.6965 + /* residue is all the number [NB could be all 0s] */ 1.6966 + if (*residue<=0) { /* not already positive */ 1.6967 + count=len; /* avoids D2U */ 1.6968 + for (up=lsu; count>0; up++, count-=DECDPUN) if (*up!=0) { /* found non-0 */ 1.6969 + *residue=1; 1.6970 + break; /* no need to check any others */ 1.6971 + } 1.6972 + } 1.6973 + if (*residue!=0) *status|=DEC_Inexact; /* record inexactitude */ 1.6974 + *dn->lsu=0; /* coefficient will now be 0 */ 1.6975 + dn->digits=1; /* .. */ 1.6976 + return; 1.6977 + } /* total discard */ 1.6978 + 1.6979 + /* partial discard [most common case] */ 1.6980 + /* here, at least the first (most significant) discarded digit exists */ 1.6981 + 1.6982 + /* spin up the number, noting residue during the spin, until get to */ 1.6983 + /* the Unit with the first discarded digit. When reach it, extract */ 1.6984 + /* it and remember its position */ 1.6985 + count=0; 1.6986 + for (up=lsu;; up++) { 1.6987 + count+=DECDPUN; 1.6988 + if (count>=discard) break; /* full ones all checked */ 1.6989 + if (*up!=0) *residue=1; 1.6990 + } /* up */ 1.6991 + 1.6992 + /* here up -> Unit with first discarded digit */ 1.6993 + cut=discard-(count-DECDPUN)-1; 1.6994 + if (cut==DECDPUN-1) { /* unit-boundary case (fast) */ 1.6995 + Unit half=(Unit)powers[DECDPUN]>>1; 1.6996 + /* set residue directly */ 1.6997 + if (*up>=half) { 1.6998 + if (*up>half) *residue=7; 1.6999 + else *residue+=5; /* add sticky bit */ 1.7000 + } 1.7001 + else { /* <half */ 1.7002 + if (*up!=0) *residue=3; /* [else is 0, leave as sticky bit] */ 1.7003 + } 1.7004 + if (set->digits<=0) { /* special for Quantize/Subnormal :-( */ 1.7005 + *dn->lsu=0; /* .. result is 0 */ 1.7006 + dn->digits=1; /* .. */ 1.7007 + } 1.7008 + else { /* shift to least */ 1.7009 + count=set->digits; /* now digits to end up with */ 1.7010 + dn->digits=count; /* set the new length */ 1.7011 + up++; /* move to next */ 1.7012 + /* on unit boundary, so shift-down copy loop is simple */ 1.7013 + for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN) 1.7014 + *target=*up; 1.7015 + } 1.7016 + } /* unit-boundary case */ 1.7017 + 1.7018 + else { /* discard digit is in low digit(s), and not top digit */ 1.7019 + uInt discard1; /* first discarded digit */ 1.7020 + uInt quot, rem; /* for divisions */ 1.7021 + if (cut==0) quot=*up; /* is at bottom of unit */ 1.7022 + else /* cut>0 */ { /* it's not at bottom of unit */ 1.7023 + #if DECDPUN<=4 1.7024 + U_ASSERT(/* cut >= 0 &&*/ cut <= 4); 1.7025 + quot=QUOT10(*up, cut); 1.7026 + rem=*up-quot*powers[cut]; 1.7027 + #else 1.7028 + rem=*up%powers[cut]; 1.7029 + quot=*up/powers[cut]; 1.7030 + #endif 1.7031 + if (rem!=0) *residue=1; 1.7032 + } 1.7033 + /* discard digit is now at bottom of quot */ 1.7034 + #if DECDPUN<=4 1.7035 + temp=(quot*6554)>>16; /* fast /10 */ 1.7036 + /* Vowels algorithm here not a win (9 instructions) */ 1.7037 + discard1=quot-X10(temp); 1.7038 + quot=temp; 1.7039 + #else 1.7040 + discard1=quot%10; 1.7041 + quot=quot/10; 1.7042 + #endif 1.7043 + /* here, discard1 is the guard digit, and residue is everything */ 1.7044 + /* else [use mapping array to accumulate residue safely] */ 1.7045 + *residue+=resmap[discard1]; 1.7046 + cut++; /* update cut */ 1.7047 + /* here: up -> Unit of the array with bottom digit */ 1.7048 + /* cut is the division point for each Unit */ 1.7049 + /* quot holds the uncut high-order digits for the current unit */ 1.7050 + if (set->digits<=0) { /* special for Quantize/Subnormal :-( */ 1.7051 + *dn->lsu=0; /* .. result is 0 */ 1.7052 + dn->digits=1; /* .. */ 1.7053 + } 1.7054 + else { /* shift to least needed */ 1.7055 + count=set->digits; /* now digits to end up with */ 1.7056 + dn->digits=count; /* set the new length */ 1.7057 + /* shift-copy the coefficient array to the result number */ 1.7058 + for (target=dn->lsu; ; target++) { 1.7059 + *target=(Unit)quot; 1.7060 + count-=(DECDPUN-cut); 1.7061 + if (count<=0) break; 1.7062 + up++; 1.7063 + quot=*up; 1.7064 + #if DECDPUN<=4 1.7065 + quot=QUOT10(quot, cut); 1.7066 + rem=*up-quot*powers[cut]; 1.7067 + #else 1.7068 + rem=quot%powers[cut]; 1.7069 + quot=quot/powers[cut]; 1.7070 + #endif 1.7071 + *target=(Unit)(*target+rem*powers[DECDPUN-cut]); 1.7072 + count-=cut; 1.7073 + if (count<=0) break; 1.7074 + } /* shift-copy loop */ 1.7075 + } /* shift to least */ 1.7076 + } /* not unit boundary */ 1.7077 + 1.7078 + if (*residue!=0) *status|=DEC_Inexact; /* record inexactitude */ 1.7079 + return; 1.7080 + } /* decSetCoeff */ 1.7081 + 1.7082 +/* ------------------------------------------------------------------ */ 1.7083 +/* decApplyRound -- apply pending rounding to a number */ 1.7084 +/* */ 1.7085 +/* dn is the number, with space for set->digits digits */ 1.7086 +/* set is the context [for size and rounding mode] */ 1.7087 +/* residue indicates pending rounding, being any accumulated */ 1.7088 +/* guard and sticky information. It may be: */ 1.7089 +/* 6-9: rounding digit is >5 */ 1.7090 +/* 5: rounding digit is exactly half-way */ 1.7091 +/* 1-4: rounding digit is <5 and >0 */ 1.7092 +/* 0: the coefficient is exact */ 1.7093 +/* -1: as 1, but the hidden digits are subtractive, that */ 1.7094 +/* is, of the opposite sign to dn. In this case the */ 1.7095 +/* coefficient must be non-0. This case occurs when */ 1.7096 +/* subtracting a small number (which can be reduced to */ 1.7097 +/* a sticky bit); see decAddOp. */ 1.7098 +/* status is the status accumulator, as usual */ 1.7099 +/* */ 1.7100 +/* This routine applies rounding while keeping the length of the */ 1.7101 +/* coefficient constant. The exponent and status are unchanged */ 1.7102 +/* except if: */ 1.7103 +/* */ 1.7104 +/* -- the coefficient was increased and is all nines (in which */ 1.7105 +/* case Overflow could occur, and is handled directly here so */ 1.7106 +/* the caller does not need to re-test for overflow) */ 1.7107 +/* */ 1.7108 +/* -- the coefficient was decreased and becomes all nines (in which */ 1.7109 +/* case Underflow could occur, and is also handled directly). */ 1.7110 +/* */ 1.7111 +/* All fields in dn are updated as required. */ 1.7112 +/* */ 1.7113 +/* ------------------------------------------------------------------ */ 1.7114 +static void decApplyRound(decNumber *dn, decContext *set, Int residue, 1.7115 + uInt *status) { 1.7116 + Int bump; /* 1 if coefficient needs to be incremented */ 1.7117 + /* -1 if coefficient needs to be decremented */ 1.7118 + 1.7119 + if (residue==0) return; /* nothing to apply */ 1.7120 + 1.7121 + bump=0; /* assume a smooth ride */ 1.7122 + 1.7123 + /* now decide whether, and how, to round, depending on mode */ 1.7124 + switch (set->round) { 1.7125 + case DEC_ROUND_05UP: { /* round zero or five up (for reround) */ 1.7126 + /* This is the same as DEC_ROUND_DOWN unless there is a */ 1.7127 + /* positive residue and the lsd of dn is 0 or 5, in which case */ 1.7128 + /* it is bumped; when residue is <0, the number is therefore */ 1.7129 + /* bumped down unless the final digit was 1 or 6 (in which */ 1.7130 + /* case it is bumped down and then up -- a no-op) */ 1.7131 + Int lsd5=*dn->lsu%5; /* get lsd and quintate */ 1.7132 + if (residue<0 && lsd5!=1) bump=-1; 1.7133 + else if (residue>0 && lsd5==0) bump=1; 1.7134 + /* [bump==1 could be applied directly; use common path for clarity] */ 1.7135 + break;} /* r-05 */ 1.7136 + 1.7137 + case DEC_ROUND_DOWN: { 1.7138 + /* no change, except if negative residue */ 1.7139 + if (residue<0) bump=-1; 1.7140 + break;} /* r-d */ 1.7141 + 1.7142 + case DEC_ROUND_HALF_DOWN: { 1.7143 + if (residue>5) bump=1; 1.7144 + break;} /* r-h-d */ 1.7145 + 1.7146 + case DEC_ROUND_HALF_EVEN: { 1.7147 + if (residue>5) bump=1; /* >0.5 goes up */ 1.7148 + else if (residue==5) { /* exactly 0.5000... */ 1.7149 + /* 0.5 goes up iff [new] lsd is odd */ 1.7150 + if (*dn->lsu & 0x01) bump=1; 1.7151 + } 1.7152 + break;} /* r-h-e */ 1.7153 + 1.7154 + case DEC_ROUND_HALF_UP: { 1.7155 + if (residue>=5) bump=1; 1.7156 + break;} /* r-h-u */ 1.7157 + 1.7158 + case DEC_ROUND_UP: { 1.7159 + if (residue>0) bump=1; 1.7160 + break;} /* r-u */ 1.7161 + 1.7162 + case DEC_ROUND_CEILING: { 1.7163 + /* same as _UP for positive numbers, and as _DOWN for negatives */ 1.7164 + /* [negative residue cannot occur on 0] */ 1.7165 + if (decNumberIsNegative(dn)) { 1.7166 + if (residue<0) bump=-1; 1.7167 + } 1.7168 + else { 1.7169 + if (residue>0) bump=1; 1.7170 + } 1.7171 + break;} /* r-c */ 1.7172 + 1.7173 + case DEC_ROUND_FLOOR: { 1.7174 + /* same as _UP for negative numbers, and as _DOWN for positive */ 1.7175 + /* [negative residue cannot occur on 0] */ 1.7176 + if (!decNumberIsNegative(dn)) { 1.7177 + if (residue<0) bump=-1; 1.7178 + } 1.7179 + else { 1.7180 + if (residue>0) bump=1; 1.7181 + } 1.7182 + break;} /* r-f */ 1.7183 + 1.7184 + default: { /* e.g., DEC_ROUND_MAX */ 1.7185 + *status|=DEC_Invalid_context; 1.7186 + #if DECTRACE || (DECCHECK && DECVERB) 1.7187 + printf("Unknown rounding mode: %d\n", set->round); 1.7188 + #endif 1.7189 + break;} 1.7190 + } /* switch */ 1.7191 + 1.7192 + /* now bump the number, up or down, if need be */ 1.7193 + if (bump==0) return; /* no action required */ 1.7194 + 1.7195 + /* Simply use decUnitAddSub unless bumping up and the number is */ 1.7196 + /* all nines. In this special case set to 100... explicitly */ 1.7197 + /* and adjust the exponent by one (as otherwise could overflow */ 1.7198 + /* the array) */ 1.7199 + /* Similarly handle all-nines result if bumping down. */ 1.7200 + if (bump>0) { 1.7201 + Unit *up; /* work */ 1.7202 + uInt count=dn->digits; /* digits to be checked */ 1.7203 + for (up=dn->lsu; ; up++) { 1.7204 + if (count<=DECDPUN) { 1.7205 + /* this is the last Unit (the msu) */ 1.7206 + if (*up!=powers[count]-1) break; /* not still 9s */ 1.7207 + /* here if it, too, is all nines */ 1.7208 + *up=(Unit)powers[count-1]; /* here 999 -> 100 etc. */ 1.7209 + for (up=up-1; up>=dn->lsu; up--) *up=0; /* others all to 0 */ 1.7210 + dn->exponent++; /* and bump exponent */ 1.7211 + /* [which, very rarely, could cause Overflow...] */ 1.7212 + if ((dn->exponent+dn->digits)>set->emax+1) { 1.7213 + decSetOverflow(dn, set, status); 1.7214 + } 1.7215 + return; /* done */ 1.7216 + } 1.7217 + /* a full unit to check, with more to come */ 1.7218 + if (*up!=DECDPUNMAX) break; /* not still 9s */ 1.7219 + count-=DECDPUN; 1.7220 + } /* up */ 1.7221 + } /* bump>0 */ 1.7222 + else { /* -1 */ 1.7223 + /* here checking for a pre-bump of 1000... (leading 1, all */ 1.7224 + /* other digits zero) */ 1.7225 + Unit *up, *sup; /* work */ 1.7226 + uInt count=dn->digits; /* digits to be checked */ 1.7227 + for (up=dn->lsu; ; up++) { 1.7228 + if (count<=DECDPUN) { 1.7229 + /* this is the last Unit (the msu) */ 1.7230 + if (*up!=powers[count-1]) break; /* not 100.. */ 1.7231 + /* here if have the 1000... case */ 1.7232 + sup=up; /* save msu pointer */ 1.7233 + *up=(Unit)powers[count]-1; /* here 100 in msu -> 999 */ 1.7234 + /* others all to all-nines, too */ 1.7235 + for (up=up-1; up>=dn->lsu; up--) *up=(Unit)powers[DECDPUN]-1; 1.7236 + dn->exponent--; /* and bump exponent */ 1.7237 + 1.7238 + /* iff the number was at the subnormal boundary (exponent=etiny) */ 1.7239 + /* then the exponent is now out of range, so it will in fact get */ 1.7240 + /* clamped to etiny and the final 9 dropped. */ 1.7241 + /* printf(">> emin=%d exp=%d sdig=%d\n", set->emin, */ 1.7242 + /* dn->exponent, set->digits); */ 1.7243 + if (dn->exponent+1==set->emin-set->digits+1) { 1.7244 + if (count==1 && dn->digits==1) *sup=0; /* here 9 -> 0[.9] */ 1.7245 + else { 1.7246 + *sup=(Unit)powers[count-1]-1; /* here 999.. in msu -> 99.. */ 1.7247 + dn->digits--; 1.7248 + } 1.7249 + dn->exponent++; 1.7250 + *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded; 1.7251 + } 1.7252 + return; /* done */ 1.7253 + } 1.7254 + 1.7255 + /* a full unit to check, with more to come */ 1.7256 + if (*up!=0) break; /* not still 0s */ 1.7257 + count-=DECDPUN; 1.7258 + } /* up */ 1.7259 + 1.7260 + } /* bump<0 */ 1.7261 + 1.7262 + /* Actual bump needed. Do it. */ 1.7263 + decUnitAddSub(dn->lsu, D2U(dn->digits), uarrone, 1, 0, dn->lsu, bump); 1.7264 + } /* decApplyRound */ 1.7265 + 1.7266 +#if DECSUBSET 1.7267 +/* ------------------------------------------------------------------ */ 1.7268 +/* decFinish -- finish processing a number */ 1.7269 +/* */ 1.7270 +/* dn is the number */ 1.7271 +/* set is the context */ 1.7272 +/* residue is the rounding accumulator (as in decApplyRound) */ 1.7273 +/* status is the accumulator */ 1.7274 +/* */ 1.7275 +/* This finishes off the current number by: */ 1.7276 +/* 1. If not extended: */ 1.7277 +/* a. Converting a zero result to clean '0' */ 1.7278 +/* b. Reducing positive exponents to 0, if would fit in digits */ 1.7279 +/* 2. Checking for overflow and subnormals (always) */ 1.7280 +/* Note this is just Finalize when no subset arithmetic. */ 1.7281 +/* All fields are updated as required. */ 1.7282 +/* ------------------------------------------------------------------ */ 1.7283 +static void decFinish(decNumber *dn, decContext *set, Int *residue, 1.7284 + uInt *status) { 1.7285 + if (!set->extended) { 1.7286 + if ISZERO(dn) { /* value is zero */ 1.7287 + dn->exponent=0; /* clean exponent .. */ 1.7288 + dn->bits=0; /* .. and sign */ 1.7289 + return; /* no error possible */ 1.7290 + } 1.7291 + if (dn->exponent>=0) { /* non-negative exponent */ 1.7292 + /* >0; reduce to integer if possible */ 1.7293 + if (set->digits >= (dn->exponent+dn->digits)) { 1.7294 + dn->digits=decShiftToMost(dn->lsu, dn->digits, dn->exponent); 1.7295 + dn->exponent=0; 1.7296 + } 1.7297 + } 1.7298 + } /* !extended */ 1.7299 + 1.7300 + decFinalize(dn, set, residue, status); 1.7301 + } /* decFinish */ 1.7302 +#endif 1.7303 + 1.7304 +/* ------------------------------------------------------------------ */ 1.7305 +/* decFinalize -- final check, clamp, and round of a number */ 1.7306 +/* */ 1.7307 +/* dn is the number */ 1.7308 +/* set is the context */ 1.7309 +/* residue is the rounding accumulator (as in decApplyRound) */ 1.7310 +/* status is the status accumulator */ 1.7311 +/* */ 1.7312 +/* This finishes off the current number by checking for subnormal */ 1.7313 +/* results, applying any pending rounding, checking for overflow, */ 1.7314 +/* and applying any clamping. */ 1.7315 +/* Underflow and overflow conditions are raised as appropriate. */ 1.7316 +/* All fields are updated as required. */ 1.7317 +/* ------------------------------------------------------------------ */ 1.7318 +static void decFinalize(decNumber *dn, decContext *set, Int *residue, 1.7319 + uInt *status) { 1.7320 + Int shift; /* shift needed if clamping */ 1.7321 + Int tinyexp=set->emin-dn->digits+1; /* precalculate subnormal boundary */ 1.7322 + 1.7323 + /* Must be careful, here, when checking the exponent as the */ 1.7324 + /* adjusted exponent could overflow 31 bits [because it may already */ 1.7325 + /* be up to twice the expected]. */ 1.7326 + 1.7327 + /* First test for subnormal. This must be done before any final */ 1.7328 + /* round as the result could be rounded to Nmin or 0. */ 1.7329 + if (dn->exponent<=tinyexp) { /* prefilter */ 1.7330 + Int comp; 1.7331 + decNumber nmin; 1.7332 + /* A very nasty case here is dn == Nmin and residue<0 */ 1.7333 + if (dn->exponent<tinyexp) { 1.7334 + /* Go handle subnormals; this will apply round if needed. */ 1.7335 + decSetSubnormal(dn, set, residue, status); 1.7336 + return; 1.7337 + } 1.7338 + /* Equals case: only subnormal if dn=Nmin and negative residue */ 1.7339 + uprv_decNumberZero(&nmin); 1.7340 + nmin.lsu[0]=1; 1.7341 + nmin.exponent=set->emin; 1.7342 + comp=decCompare(dn, &nmin, 1); /* (signless compare) */ 1.7343 + if (comp==BADINT) { /* oops */ 1.7344 + *status|=DEC_Insufficient_storage; /* abandon... */ 1.7345 + return; 1.7346 + } 1.7347 + if (*residue<0 && comp==0) { /* neg residue and dn==Nmin */ 1.7348 + decApplyRound(dn, set, *residue, status); /* might force down */ 1.7349 + decSetSubnormal(dn, set, residue, status); 1.7350 + return; 1.7351 + } 1.7352 + } 1.7353 + 1.7354 + /* now apply any pending round (this could raise overflow). */ 1.7355 + if (*residue!=0) decApplyRound(dn, set, *residue, status); 1.7356 + 1.7357 + /* Check for overflow [redundant in the 'rare' case] or clamp */ 1.7358 + if (dn->exponent<=set->emax-set->digits+1) return; /* neither needed */ 1.7359 + 1.7360 + 1.7361 + /* here when might have an overflow or clamp to do */ 1.7362 + if (dn->exponent>set->emax-dn->digits+1) { /* too big */ 1.7363 + decSetOverflow(dn, set, status); 1.7364 + return; 1.7365 + } 1.7366 + /* here when the result is normal but in clamp range */ 1.7367 + if (!set->clamp) return; 1.7368 + 1.7369 + /* here when need to apply the IEEE exponent clamp (fold-down) */ 1.7370 + shift=dn->exponent-(set->emax-set->digits+1); 1.7371 + 1.7372 + /* shift coefficient (if non-zero) */ 1.7373 + if (!ISZERO(dn)) { 1.7374 + dn->digits=decShiftToMost(dn->lsu, dn->digits, shift); 1.7375 + } 1.7376 + dn->exponent-=shift; /* adjust the exponent to match */ 1.7377 + *status|=DEC_Clamped; /* and record the dirty deed */ 1.7378 + return; 1.7379 + } /* decFinalize */ 1.7380 + 1.7381 +/* ------------------------------------------------------------------ */ 1.7382 +/* decSetOverflow -- set number to proper overflow value */ 1.7383 +/* */ 1.7384 +/* dn is the number (used for sign [only] and result) */ 1.7385 +/* set is the context [used for the rounding mode, etc.] */ 1.7386 +/* status contains the current status to be updated */ 1.7387 +/* */ 1.7388 +/* This sets the sign of a number and sets its value to either */ 1.7389 +/* Infinity or the maximum finite value, depending on the sign of */ 1.7390 +/* dn and the rounding mode, following IEEE 754 rules. */ 1.7391 +/* ------------------------------------------------------------------ */ 1.7392 +static void decSetOverflow(decNumber *dn, decContext *set, uInt *status) { 1.7393 + Flag needmax=0; /* result is maximum finite value */ 1.7394 + uByte sign=dn->bits&DECNEG; /* clean and save sign bit */ 1.7395 + 1.7396 + if (ISZERO(dn)) { /* zero does not overflow magnitude */ 1.7397 + Int emax=set->emax; /* limit value */ 1.7398 + if (set->clamp) emax-=set->digits-1; /* lower if clamping */ 1.7399 + if (dn->exponent>emax) { /* clamp required */ 1.7400 + dn->exponent=emax; 1.7401 + *status|=DEC_Clamped; 1.7402 + } 1.7403 + return; 1.7404 + } 1.7405 + 1.7406 + uprv_decNumberZero(dn); 1.7407 + switch (set->round) { 1.7408 + case DEC_ROUND_DOWN: { 1.7409 + needmax=1; /* never Infinity */ 1.7410 + break;} /* r-d */ 1.7411 + case DEC_ROUND_05UP: { 1.7412 + needmax=1; /* never Infinity */ 1.7413 + break;} /* r-05 */ 1.7414 + case DEC_ROUND_CEILING: { 1.7415 + if (sign) needmax=1; /* Infinity if non-negative */ 1.7416 + break;} /* r-c */ 1.7417 + case DEC_ROUND_FLOOR: { 1.7418 + if (!sign) needmax=1; /* Infinity if negative */ 1.7419 + break;} /* r-f */ 1.7420 + default: break; /* Infinity in all other cases */ 1.7421 + } 1.7422 + if (needmax) { 1.7423 + decSetMaxValue(dn, set); 1.7424 + dn->bits=sign; /* set sign */ 1.7425 + } 1.7426 + else dn->bits=sign|DECINF; /* Value is +/-Infinity */ 1.7427 + *status|=DEC_Overflow | DEC_Inexact | DEC_Rounded; 1.7428 + } /* decSetOverflow */ 1.7429 + 1.7430 +/* ------------------------------------------------------------------ */ 1.7431 +/* decSetMaxValue -- set number to +Nmax (maximum normal value) */ 1.7432 +/* */ 1.7433 +/* dn is the number to set */ 1.7434 +/* set is the context [used for digits and emax] */ 1.7435 +/* */ 1.7436 +/* This sets the number to the maximum positive value. */ 1.7437 +/* ------------------------------------------------------------------ */ 1.7438 +static void decSetMaxValue(decNumber *dn, decContext *set) { 1.7439 + Unit *up; /* work */ 1.7440 + Int count=set->digits; /* nines to add */ 1.7441 + dn->digits=count; 1.7442 + /* fill in all nines to set maximum value */ 1.7443 + for (up=dn->lsu; ; up++) { 1.7444 + if (count>DECDPUN) *up=DECDPUNMAX; /* unit full o'nines */ 1.7445 + else { /* this is the msu */ 1.7446 + *up=(Unit)(powers[count]-1); 1.7447 + break; 1.7448 + } 1.7449 + count-=DECDPUN; /* filled those digits */ 1.7450 + } /* up */ 1.7451 + dn->bits=0; /* + sign */ 1.7452 + dn->exponent=set->emax-set->digits+1; 1.7453 + } /* decSetMaxValue */ 1.7454 + 1.7455 +/* ------------------------------------------------------------------ */ 1.7456 +/* decSetSubnormal -- process value whose exponent is <Emin */ 1.7457 +/* */ 1.7458 +/* dn is the number (used as input as well as output; it may have */ 1.7459 +/* an allowed subnormal value, which may need to be rounded) */ 1.7460 +/* set is the context [used for the rounding mode] */ 1.7461 +/* residue is any pending residue */ 1.7462 +/* status contains the current status to be updated */ 1.7463 +/* */ 1.7464 +/* If subset mode, set result to zero and set Underflow flags. */ 1.7465 +/* */ 1.7466 +/* Value may be zero with a low exponent; this does not set Subnormal */ 1.7467 +/* but the exponent will be clamped to Etiny. */ 1.7468 +/* */ 1.7469 +/* Otherwise ensure exponent is not out of range, and round as */ 1.7470 +/* necessary. Underflow is set if the result is Inexact. */ 1.7471 +/* ------------------------------------------------------------------ */ 1.7472 +static void decSetSubnormal(decNumber *dn, decContext *set, Int *residue, 1.7473 + uInt *status) { 1.7474 + decContext workset; /* work */ 1.7475 + Int etiny, adjust; /* .. */ 1.7476 + 1.7477 + #if DECSUBSET 1.7478 + /* simple set to zero and 'hard underflow' for subset */ 1.7479 + if (!set->extended) { 1.7480 + uprv_decNumberZero(dn); 1.7481 + /* always full overflow */ 1.7482 + *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded; 1.7483 + return; 1.7484 + } 1.7485 + #endif 1.7486 + 1.7487 + /* Full arithmetic -- allow subnormals, rounded to minimum exponent */ 1.7488 + /* (Etiny) if needed */ 1.7489 + etiny=set->emin-(set->digits-1); /* smallest allowed exponent */ 1.7490 + 1.7491 + if ISZERO(dn) { /* value is zero */ 1.7492 + /* residue can never be non-zero here */ 1.7493 + #if DECCHECK 1.7494 + if (*residue!=0) { 1.7495 + printf("++ Subnormal 0 residue %ld\n", (LI)*residue); 1.7496 + *status|=DEC_Invalid_operation; 1.7497 + } 1.7498 + #endif 1.7499 + if (dn->exponent<etiny) { /* clamp required */ 1.7500 + dn->exponent=etiny; 1.7501 + *status|=DEC_Clamped; 1.7502 + } 1.7503 + return; 1.7504 + } 1.7505 + 1.7506 + *status|=DEC_Subnormal; /* have a non-zero subnormal */ 1.7507 + adjust=etiny-dn->exponent; /* calculate digits to remove */ 1.7508 + if (adjust<=0) { /* not out of range; unrounded */ 1.7509 + /* residue can never be non-zero here, except in the Nmin-residue */ 1.7510 + /* case (which is a subnormal result), so can take fast-path here */ 1.7511 + /* it may already be inexact (from setting the coefficient) */ 1.7512 + if (*status&DEC_Inexact) *status|=DEC_Underflow; 1.7513 + return; 1.7514 + } 1.7515 + 1.7516 + /* adjust>0, so need to rescale the result so exponent becomes Etiny */ 1.7517 + /* [this code is similar to that in rescale] */ 1.7518 + workset=*set; /* clone rounding, etc. */ 1.7519 + workset.digits=dn->digits-adjust; /* set requested length */ 1.7520 + workset.emin-=adjust; /* and adjust emin to match */ 1.7521 + /* [note that the latter can be <1, here, similar to Rescale case] */ 1.7522 + decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status); 1.7523 + decApplyRound(dn, &workset, *residue, status); 1.7524 + 1.7525 + /* Use 754 default rule: Underflow is set iff Inexact */ 1.7526 + /* [independent of whether trapped] */ 1.7527 + if (*status&DEC_Inexact) *status|=DEC_Underflow; 1.7528 + 1.7529 + /* if rounded up a 999s case, exponent will be off by one; adjust */ 1.7530 + /* back if so [it will fit, because it was shortened earlier] */ 1.7531 + if (dn->exponent>etiny) { 1.7532 + dn->digits=decShiftToMost(dn->lsu, dn->digits, 1); 1.7533 + dn->exponent--; /* (re)adjust the exponent. */ 1.7534 + } 1.7535 + 1.7536 + /* if rounded to zero, it is by definition clamped... */ 1.7537 + if (ISZERO(dn)) *status|=DEC_Clamped; 1.7538 + } /* decSetSubnormal */ 1.7539 + 1.7540 +/* ------------------------------------------------------------------ */ 1.7541 +/* decCheckMath - check entry conditions for a math function */ 1.7542 +/* */ 1.7543 +/* This checks the context and the operand */ 1.7544 +/* */ 1.7545 +/* rhs is the operand to check */ 1.7546 +/* set is the context to check */ 1.7547 +/* status is unchanged if both are good */ 1.7548 +/* */ 1.7549 +/* returns non-zero if status is changed, 0 otherwise */ 1.7550 +/* */ 1.7551 +/* Restrictions enforced: */ 1.7552 +/* */ 1.7553 +/* digits, emax, and -emin in the context must be less than */ 1.7554 +/* DEC_MAX_MATH (999999), and A must be within these bounds if */ 1.7555 +/* non-zero. Invalid_operation is set in the status if a */ 1.7556 +/* restriction is violated. */ 1.7557 +/* ------------------------------------------------------------------ */ 1.7558 +static uInt decCheckMath(const decNumber *rhs, decContext *set, 1.7559 + uInt *status) { 1.7560 + uInt save=*status; /* record */ 1.7561 + if (set->digits>DEC_MAX_MATH 1.7562 + || set->emax>DEC_MAX_MATH 1.7563 + || -set->emin>DEC_MAX_MATH) *status|=DEC_Invalid_context; 1.7564 + else if ((rhs->digits>DEC_MAX_MATH 1.7565 + || rhs->exponent+rhs->digits>DEC_MAX_MATH+1 1.7566 + || rhs->exponent+rhs->digits<2*(1-DEC_MAX_MATH)) 1.7567 + && !ISZERO(rhs)) *status|=DEC_Invalid_operation; 1.7568 + return (*status!=save); 1.7569 + } /* decCheckMath */ 1.7570 + 1.7571 +/* ------------------------------------------------------------------ */ 1.7572 +/* decGetInt -- get integer from a number */ 1.7573 +/* */ 1.7574 +/* dn is the number [which will not be altered] */ 1.7575 +/* */ 1.7576 +/* returns one of: */ 1.7577 +/* BADINT if there is a non-zero fraction */ 1.7578 +/* the converted integer */ 1.7579 +/* BIGEVEN if the integer is even and magnitude > 2*10**9 */ 1.7580 +/* BIGODD if the integer is odd and magnitude > 2*10**9 */ 1.7581 +/* */ 1.7582 +/* This checks and gets a whole number from the input decNumber. */ 1.7583 +/* The sign can be determined from dn by the caller when BIGEVEN or */ 1.7584 +/* BIGODD is returned. */ 1.7585 +/* ------------------------------------------------------------------ */ 1.7586 +static Int decGetInt(const decNumber *dn) { 1.7587 + Int theInt; /* result accumulator */ 1.7588 + const Unit *up; /* work */ 1.7589 + Int got; /* digits (real or not) processed */ 1.7590 + Int ilength=dn->digits+dn->exponent; /* integral length */ 1.7591 + Flag neg=decNumberIsNegative(dn); /* 1 if -ve */ 1.7592 + 1.7593 + /* The number must be an integer that fits in 10 digits */ 1.7594 + /* Assert, here, that 10 is enough for any rescale Etiny */ 1.7595 + #if DEC_MAX_EMAX > 999999999 1.7596 + #error GetInt may need updating [for Emax] 1.7597 + #endif 1.7598 + #if DEC_MIN_EMIN < -999999999 1.7599 + #error GetInt may need updating [for Emin] 1.7600 + #endif 1.7601 + if (ISZERO(dn)) return 0; /* zeros are OK, with any exponent */ 1.7602 + 1.7603 + up=dn->lsu; /* ready for lsu */ 1.7604 + theInt=0; /* ready to accumulate */ 1.7605 + if (dn->exponent>=0) { /* relatively easy */ 1.7606 + /* no fractional part [usual]; allow for positive exponent */ 1.7607 + got=dn->exponent; 1.7608 + } 1.7609 + else { /* -ve exponent; some fractional part to check and discard */ 1.7610 + Int count=-dn->exponent; /* digits to discard */ 1.7611 + /* spin up whole units until reach the Unit with the unit digit */ 1.7612 + for (; count>=DECDPUN; up++) { 1.7613 + if (*up!=0) return BADINT; /* non-zero Unit to discard */ 1.7614 + count-=DECDPUN; 1.7615 + } 1.7616 + if (count==0) got=0; /* [a multiple of DECDPUN] */ 1.7617 + else { /* [not multiple of DECDPUN] */ 1.7618 + Int rem; /* work */ 1.7619 + /* slice off fraction digits and check for non-zero */ 1.7620 + #if DECDPUN<=4 1.7621 + theInt=QUOT10(*up, count); 1.7622 + rem=*up-theInt*powers[count]; 1.7623 + #else 1.7624 + rem=*up%powers[count]; /* slice off discards */ 1.7625 + theInt=*up/powers[count]; 1.7626 + #endif 1.7627 + if (rem!=0) return BADINT; /* non-zero fraction */ 1.7628 + /* it looks good */ 1.7629 + got=DECDPUN-count; /* number of digits so far */ 1.7630 + up++; /* ready for next */ 1.7631 + } 1.7632 + } 1.7633 + /* now it's known there's no fractional part */ 1.7634 + 1.7635 + /* tricky code now, to accumulate up to 9.3 digits */ 1.7636 + if (got==0) {theInt=*up; got+=DECDPUN; up++;} /* ensure lsu is there */ 1.7637 + 1.7638 + if (ilength<11) { 1.7639 + Int save=theInt; 1.7640 + /* collect any remaining unit(s) */ 1.7641 + for (; got<ilength; up++) { 1.7642 + theInt+=*up*powers[got]; 1.7643 + got+=DECDPUN; 1.7644 + } 1.7645 + if (ilength==10) { /* need to check for wrap */ 1.7646 + if (theInt/(Int)powers[got-DECDPUN]!=(Int)*(up-1)) ilength=11; 1.7647 + /* [that test also disallows the BADINT result case] */ 1.7648 + else if (neg && theInt>1999999997) ilength=11; 1.7649 + else if (!neg && theInt>999999999) ilength=11; 1.7650 + if (ilength==11) theInt=save; /* restore correct low bit */ 1.7651 + } 1.7652 + } 1.7653 + 1.7654 + if (ilength>10) { /* too big */ 1.7655 + if (theInt&1) return BIGODD; /* bottom bit 1 */ 1.7656 + return BIGEVEN; /* bottom bit 0 */ 1.7657 + } 1.7658 + 1.7659 + if (neg) theInt=-theInt; /* apply sign */ 1.7660 + return theInt; 1.7661 + } /* decGetInt */ 1.7662 + 1.7663 +/* ------------------------------------------------------------------ */ 1.7664 +/* decDecap -- decapitate the coefficient of a number */ 1.7665 +/* */ 1.7666 +/* dn is the number to be decapitated */ 1.7667 +/* drop is the number of digits to be removed from the left of dn; */ 1.7668 +/* this must be <= dn->digits (if equal, the coefficient is */ 1.7669 +/* set to 0) */ 1.7670 +/* */ 1.7671 +/* Returns dn; dn->digits will be <= the initial digits less drop */ 1.7672 +/* (after removing drop digits there may be leading zero digits */ 1.7673 +/* which will also be removed). Only dn->lsu and dn->digits change. */ 1.7674 +/* ------------------------------------------------------------------ */ 1.7675 +static decNumber *decDecap(decNumber *dn, Int drop) { 1.7676 + Unit *msu; /* -> target cut point */ 1.7677 + Int cut; /* work */ 1.7678 + if (drop>=dn->digits) { /* losing the whole thing */ 1.7679 + #if DECCHECK 1.7680 + if (drop>dn->digits) 1.7681 + printf("decDecap called with drop>digits [%ld>%ld]\n", 1.7682 + (LI)drop, (LI)dn->digits); 1.7683 + #endif 1.7684 + dn->lsu[0]=0; 1.7685 + dn->digits=1; 1.7686 + return dn; 1.7687 + } 1.7688 + msu=dn->lsu+D2U(dn->digits-drop)-1; /* -> likely msu */ 1.7689 + cut=MSUDIGITS(dn->digits-drop); /* digits to be in use in msu */ 1.7690 + if (cut!=DECDPUN) *msu%=powers[cut]; /* clear left digits */ 1.7691 + /* that may have left leading zero digits, so do a proper count... */ 1.7692 + dn->digits=decGetDigits(dn->lsu, msu-dn->lsu+1); 1.7693 + return dn; 1.7694 + } /* decDecap */ 1.7695 + 1.7696 +/* ------------------------------------------------------------------ */ 1.7697 +/* decBiStr -- compare string with pairwise options */ 1.7698 +/* */ 1.7699 +/* targ is the string to compare */ 1.7700 +/* str1 is one of the strings to compare against (length may be 0) */ 1.7701 +/* str2 is the other; it must be the same length as str1 */ 1.7702 +/* */ 1.7703 +/* returns 1 if strings compare equal, (that is, it is the same */ 1.7704 +/* length as str1 and str2, and each character of targ is in either */ 1.7705 +/* str1 or str2 in the corresponding position), or 0 otherwise */ 1.7706 +/* */ 1.7707 +/* This is used for generic caseless compare, including the awkward */ 1.7708 +/* case of the Turkish dotted and dotless Is. Use as (for example): */ 1.7709 +/* if (decBiStr(test, "mike", "MIKE")) ... */ 1.7710 +/* ------------------------------------------------------------------ */ 1.7711 +static Flag decBiStr(const char *targ, const char *str1, const char *str2) { 1.7712 + for (;;targ++, str1++, str2++) { 1.7713 + if (*targ!=*str1 && *targ!=*str2) return 0; 1.7714 + /* *targ has a match in one (or both, if terminator) */ 1.7715 + if (*targ=='\0') break; 1.7716 + } /* forever */ 1.7717 + return 1; 1.7718 + } /* decBiStr */ 1.7719 + 1.7720 +/* ------------------------------------------------------------------ */ 1.7721 +/* decNaNs -- handle NaN operand or operands */ 1.7722 +/* */ 1.7723 +/* res is the result number */ 1.7724 +/* lhs is the first operand */ 1.7725 +/* rhs is the second operand, or NULL if none */ 1.7726 +/* context is used to limit payload length */ 1.7727 +/* status contains the current status */ 1.7728 +/* returns res in case convenient */ 1.7729 +/* */ 1.7730 +/* Called when one or both operands is a NaN, and propagates the */ 1.7731 +/* appropriate result to res. When an sNaN is found, it is changed */ 1.7732 +/* to a qNaN and Invalid operation is set. */ 1.7733 +/* ------------------------------------------------------------------ */ 1.7734 +static decNumber * decNaNs(decNumber *res, const decNumber *lhs, 1.7735 + const decNumber *rhs, decContext *set, 1.7736 + uInt *status) { 1.7737 + /* This decision tree ends up with LHS being the source pointer, */ 1.7738 + /* and status updated if need be */ 1.7739 + if (lhs->bits & DECSNAN) 1.7740 + *status|=DEC_Invalid_operation | DEC_sNaN; 1.7741 + else if (rhs==NULL); 1.7742 + else if (rhs->bits & DECSNAN) { 1.7743 + lhs=rhs; 1.7744 + *status|=DEC_Invalid_operation | DEC_sNaN; 1.7745 + } 1.7746 + else if (lhs->bits & DECNAN); 1.7747 + else lhs=rhs; 1.7748 + 1.7749 + /* propagate the payload */ 1.7750 + if (lhs->digits<=set->digits) uprv_decNumberCopy(res, lhs); /* easy */ 1.7751 + else { /* too long */ 1.7752 + const Unit *ul; 1.7753 + Unit *ur, *uresp1; 1.7754 + /* copy safe number of units, then decapitate */ 1.7755 + res->bits=lhs->bits; /* need sign etc. */ 1.7756 + uresp1=res->lsu+D2U(set->digits); 1.7757 + for (ur=res->lsu, ul=lhs->lsu; ur<uresp1; ur++, ul++) *ur=*ul; 1.7758 + res->digits=D2U(set->digits)*DECDPUN; 1.7759 + /* maybe still too long */ 1.7760 + if (res->digits>set->digits) decDecap(res, res->digits-set->digits); 1.7761 + } 1.7762 + 1.7763 + res->bits&=~DECSNAN; /* convert any sNaN to NaN, while */ 1.7764 + res->bits|=DECNAN; /* .. preserving sign */ 1.7765 + res->exponent=0; /* clean exponent */ 1.7766 + /* [coefficient was copied/decapitated] */ 1.7767 + return res; 1.7768 + } /* decNaNs */ 1.7769 + 1.7770 +/* ------------------------------------------------------------------ */ 1.7771 +/* decStatus -- apply non-zero status */ 1.7772 +/* */ 1.7773 +/* dn is the number to set if error */ 1.7774 +/* status contains the current status (not yet in context) */ 1.7775 +/* set is the context */ 1.7776 +/* */ 1.7777 +/* If the status is an error status, the number is set to a NaN, */ 1.7778 +/* unless the error was an overflow, divide-by-zero, or underflow, */ 1.7779 +/* in which case the number will have already been set. */ 1.7780 +/* */ 1.7781 +/* The context status is then updated with the new status. Note that */ 1.7782 +/* this may raise a signal, so control may never return from this */ 1.7783 +/* routine (hence resources must be recovered before it is called). */ 1.7784 +/* ------------------------------------------------------------------ */ 1.7785 +static void decStatus(decNumber *dn, uInt status, decContext *set) { 1.7786 + if (status & DEC_NaNs) { /* error status -> NaN */ 1.7787 + /* if cause was an sNaN, clear and propagate [NaN is already set up] */ 1.7788 + if (status & DEC_sNaN) status&=~DEC_sNaN; 1.7789 + else { 1.7790 + uprv_decNumberZero(dn); /* other error: clean throughout */ 1.7791 + dn->bits=DECNAN; /* and make a quiet NaN */ 1.7792 + } 1.7793 + } 1.7794 + uprv_decContextSetStatus(set, status); /* [may not return] */ 1.7795 + return; 1.7796 + } /* decStatus */ 1.7797 + 1.7798 +/* ------------------------------------------------------------------ */ 1.7799 +/* decGetDigits -- count digits in a Units array */ 1.7800 +/* */ 1.7801 +/* uar is the Unit array holding the number (this is often an */ 1.7802 +/* accumulator of some sort) */ 1.7803 +/* len is the length of the array in units [>=1] */ 1.7804 +/* */ 1.7805 +/* returns the number of (significant) digits in the array */ 1.7806 +/* */ 1.7807 +/* All leading zeros are excluded, except the last if the array has */ 1.7808 +/* only zero Units. */ 1.7809 +/* ------------------------------------------------------------------ */ 1.7810 +/* This may be called twice during some operations. */ 1.7811 +static Int decGetDigits(Unit *uar, Int len) { 1.7812 + Unit *up=uar+(len-1); /* -> msu */ 1.7813 + Int digits=(len-1)*DECDPUN+1; /* possible digits excluding msu */ 1.7814 + #if DECDPUN>4 1.7815 + uInt const *pow; /* work */ 1.7816 + #endif 1.7817 + /* (at least 1 in final msu) */ 1.7818 + #if DECCHECK 1.7819 + if (len<1) printf("decGetDigits called with len<1 [%ld]\n", (LI)len); 1.7820 + #endif 1.7821 + 1.7822 + for (; up>=uar; up--) { 1.7823 + if (*up==0) { /* unit is all 0s */ 1.7824 + if (digits==1) break; /* a zero has one digit */ 1.7825 + digits-=DECDPUN; /* adjust for 0 unit */ 1.7826 + continue;} 1.7827 + /* found the first (most significant) non-zero Unit */ 1.7828 + #if DECDPUN>1 /* not done yet */ 1.7829 + if (*up<10) break; /* is 1-9 */ 1.7830 + digits++; 1.7831 + #if DECDPUN>2 /* not done yet */ 1.7832 + if (*up<100) break; /* is 10-99 */ 1.7833 + digits++; 1.7834 + #if DECDPUN>3 /* not done yet */ 1.7835 + if (*up<1000) break; /* is 100-999 */ 1.7836 + digits++; 1.7837 + #if DECDPUN>4 /* count the rest ... */ 1.7838 + for (pow=&powers[4]; *up>=*pow; pow++) digits++; 1.7839 + #endif 1.7840 + #endif 1.7841 + #endif 1.7842 + #endif 1.7843 + break; 1.7844 + } /* up */ 1.7845 + return digits; 1.7846 + } /* decGetDigits */ 1.7847 + 1.7848 +#if DECTRACE | DECCHECK 1.7849 +/* ------------------------------------------------------------------ */ 1.7850 +/* decNumberShow -- display a number [debug aid] */ 1.7851 +/* dn is the number to show */ 1.7852 +/* */ 1.7853 +/* Shows: sign, exponent, coefficient (msu first), digits */ 1.7854 +/* or: sign, special-value */ 1.7855 +/* ------------------------------------------------------------------ */ 1.7856 +/* this is public so other modules can use it */ 1.7857 +void uprv_decNumberShow(const decNumber *dn) { 1.7858 + const Unit *up; /* work */ 1.7859 + uInt u, d; /* .. */ 1.7860 + Int cut; /* .. */ 1.7861 + char isign='+'; /* main sign */ 1.7862 + if (dn==NULL) { 1.7863 + printf("NULL\n"); 1.7864 + return;} 1.7865 + if (decNumberIsNegative(dn)) isign='-'; 1.7866 + printf(" >> %c ", isign); 1.7867 + if (dn->bits&DECSPECIAL) { /* Is a special value */ 1.7868 + if (decNumberIsInfinite(dn)) printf("Infinity"); 1.7869 + else { /* a NaN */ 1.7870 + if (dn->bits&DECSNAN) printf("sNaN"); /* signalling NaN */ 1.7871 + else printf("NaN"); 1.7872 + } 1.7873 + /* if coefficient and exponent are 0, no more to do */ 1.7874 + if (dn->exponent==0 && dn->digits==1 && *dn->lsu==0) { 1.7875 + printf("\n"); 1.7876 + return;} 1.7877 + /* drop through to report other information */ 1.7878 + printf(" "); 1.7879 + } 1.7880 + 1.7881 + /* now carefully display the coefficient */ 1.7882 + up=dn->lsu+D2U(dn->digits)-1; /* msu */ 1.7883 + printf("%ld", (LI)*up); 1.7884 + for (up=up-1; up>=dn->lsu; up--) { 1.7885 + u=*up; 1.7886 + printf(":"); 1.7887 + for (cut=DECDPUN-1; cut>=0; cut--) { 1.7888 + d=u/powers[cut]; 1.7889 + u-=d*powers[cut]; 1.7890 + printf("%ld", (LI)d); 1.7891 + } /* cut */ 1.7892 + } /* up */ 1.7893 + if (dn->exponent!=0) { 1.7894 + char esign='+'; 1.7895 + if (dn->exponent<0) esign='-'; 1.7896 + printf(" E%c%ld", esign, (LI)abs(dn->exponent)); 1.7897 + } 1.7898 + printf(" [%ld]\n", (LI)dn->digits); 1.7899 + } /* decNumberShow */ 1.7900 +#endif 1.7901 + 1.7902 +#if DECTRACE || DECCHECK 1.7903 +/* ------------------------------------------------------------------ */ 1.7904 +/* decDumpAr -- display a unit array [debug/check aid] */ 1.7905 +/* name is a single-character tag name */ 1.7906 +/* ar is the array to display */ 1.7907 +/* len is the length of the array in Units */ 1.7908 +/* ------------------------------------------------------------------ */ 1.7909 +static void decDumpAr(char name, const Unit *ar, Int len) { 1.7910 + Int i; 1.7911 + const char *spec; 1.7912 + #if DECDPUN==9 1.7913 + spec="%09d "; 1.7914 + #elif DECDPUN==8 1.7915 + spec="%08d "; 1.7916 + #elif DECDPUN==7 1.7917 + spec="%07d "; 1.7918 + #elif DECDPUN==6 1.7919 + spec="%06d "; 1.7920 + #elif DECDPUN==5 1.7921 + spec="%05d "; 1.7922 + #elif DECDPUN==4 1.7923 + spec="%04d "; 1.7924 + #elif DECDPUN==3 1.7925 + spec="%03d "; 1.7926 + #elif DECDPUN==2 1.7927 + spec="%02d "; 1.7928 + #else 1.7929 + spec="%d "; 1.7930 + #endif 1.7931 + printf(" :%c: ", name); 1.7932 + for (i=len-1; i>=0; i--) { 1.7933 + if (i==len-1) printf("%ld ", (LI)ar[i]); 1.7934 + else printf(spec, ar[i]); 1.7935 + } 1.7936 + printf("\n"); 1.7937 + return;} 1.7938 +#endif 1.7939 + 1.7940 +#if DECCHECK 1.7941 +/* ------------------------------------------------------------------ */ 1.7942 +/* decCheckOperands -- check operand(s) to a routine */ 1.7943 +/* res is the result structure (not checked; it will be set to */ 1.7944 +/* quiet NaN if error found (and it is not NULL)) */ 1.7945 +/* lhs is the first operand (may be DECUNRESU) */ 1.7946 +/* rhs is the second (may be DECUNUSED) */ 1.7947 +/* set is the context (may be DECUNCONT) */ 1.7948 +/* returns 0 if both operands, and the context are clean, or 1 */ 1.7949 +/* otherwise (in which case the context will show an error, */ 1.7950 +/* unless NULL). Note that res is not cleaned; caller should */ 1.7951 +/* handle this so res=NULL case is safe. */ 1.7952 +/* The caller is expected to abandon immediately if 1 is returned. */ 1.7953 +/* ------------------------------------------------------------------ */ 1.7954 +static Flag decCheckOperands(decNumber *res, const decNumber *lhs, 1.7955 + const decNumber *rhs, decContext *set) { 1.7956 + Flag bad=0; 1.7957 + if (set==NULL) { /* oops; hopeless */ 1.7958 + #if DECTRACE || DECVERB 1.7959 + printf("Reference to context is NULL.\n"); 1.7960 + #endif 1.7961 + bad=1; 1.7962 + return 1;} 1.7963 + else if (set!=DECUNCONT 1.7964 + && (set->digits<1 || set->round>=DEC_ROUND_MAX)) { 1.7965 + bad=1; 1.7966 + #if DECTRACE || DECVERB 1.7967 + printf("Bad context [digits=%ld round=%ld].\n", 1.7968 + (LI)set->digits, (LI)set->round); 1.7969 + #endif 1.7970 + } 1.7971 + else { 1.7972 + if (res==NULL) { 1.7973 + bad=1; 1.7974 + #if DECTRACE 1.7975 + /* this one not DECVERB as standard tests include NULL */ 1.7976 + printf("Reference to result is NULL.\n"); 1.7977 + #endif 1.7978 + } 1.7979 + if (!bad && lhs!=DECUNUSED) bad=(decCheckNumber(lhs)); 1.7980 + if (!bad && rhs!=DECUNUSED) bad=(decCheckNumber(rhs)); 1.7981 + } 1.7982 + if (bad) { 1.7983 + if (set!=DECUNCONT) uprv_decContextSetStatus(set, DEC_Invalid_operation); 1.7984 + if (res!=DECUNRESU && res!=NULL) { 1.7985 + uprv_decNumberZero(res); 1.7986 + res->bits=DECNAN; /* qNaN */ 1.7987 + } 1.7988 + } 1.7989 + return bad; 1.7990 + } /* decCheckOperands */ 1.7991 + 1.7992 +/* ------------------------------------------------------------------ */ 1.7993 +/* decCheckNumber -- check a number */ 1.7994 +/* dn is the number to check */ 1.7995 +/* returns 0 if the number is clean, or 1 otherwise */ 1.7996 +/* */ 1.7997 +/* The number is considered valid if it could be a result from some */ 1.7998 +/* operation in some valid context. */ 1.7999 +/* ------------------------------------------------------------------ */ 1.8000 +static Flag decCheckNumber(const decNumber *dn) { 1.8001 + const Unit *up; /* work */ 1.8002 + uInt maxuint; /* .. */ 1.8003 + Int ae, d, digits; /* .. */ 1.8004 + Int emin, emax; /* .. */ 1.8005 + 1.8006 + if (dn==NULL) { /* hopeless */ 1.8007 + #if DECTRACE 1.8008 + /* this one not DECVERB as standard tests include NULL */ 1.8009 + printf("Reference to decNumber is NULL.\n"); 1.8010 + #endif 1.8011 + return 1;} 1.8012 + 1.8013 + /* check special values */ 1.8014 + if (dn->bits & DECSPECIAL) { 1.8015 + if (dn->exponent!=0) { 1.8016 + #if DECTRACE || DECVERB 1.8017 + printf("Exponent %ld (not 0) for a special value [%02x].\n", 1.8018 + (LI)dn->exponent, dn->bits); 1.8019 + #endif 1.8020 + return 1;} 1.8021 + 1.8022 + /* 2003.09.08: NaNs may now have coefficients, so next tests Inf only */ 1.8023 + if (decNumberIsInfinite(dn)) { 1.8024 + if (dn->digits!=1) { 1.8025 + #if DECTRACE || DECVERB 1.8026 + printf("Digits %ld (not 1) for an infinity.\n", (LI)dn->digits); 1.8027 + #endif 1.8028 + return 1;} 1.8029 + if (*dn->lsu!=0) { 1.8030 + #if DECTRACE || DECVERB 1.8031 + printf("LSU %ld (not 0) for an infinity.\n", (LI)*dn->lsu); 1.8032 + #endif 1.8033 + decDumpAr('I', dn->lsu, D2U(dn->digits)); 1.8034 + return 1;} 1.8035 + } /* Inf */ 1.8036 + /* 2002.12.26: negative NaNs can now appear through proposed IEEE */ 1.8037 + /* concrete formats (decimal64, etc.). */ 1.8038 + return 0; 1.8039 + } 1.8040 + 1.8041 + /* check the coefficient */ 1.8042 + if (dn->digits<1 || dn->digits>DECNUMMAXP) { 1.8043 + #if DECTRACE || DECVERB 1.8044 + printf("Digits %ld in number.\n", (LI)dn->digits); 1.8045 + #endif 1.8046 + return 1;} 1.8047 + 1.8048 + d=dn->digits; 1.8049 + 1.8050 + for (up=dn->lsu; d>0; up++) { 1.8051 + if (d>DECDPUN) maxuint=DECDPUNMAX; 1.8052 + else { /* reached the msu */ 1.8053 + maxuint=powers[d]-1; 1.8054 + if (dn->digits>1 && *up<powers[d-1]) { 1.8055 + #if DECTRACE || DECVERB 1.8056 + printf("Leading 0 in number.\n"); 1.8057 + uprv_decNumberShow(dn); 1.8058 + #endif 1.8059 + return 1;} 1.8060 + } 1.8061 + if (*up>maxuint) { 1.8062 + #if DECTRACE || DECVERB 1.8063 + printf("Bad Unit [%08lx] in %ld-digit number at offset %ld [maxuint %ld].\n", 1.8064 + (LI)*up, (LI)dn->digits, (LI)(up-dn->lsu), (LI)maxuint); 1.8065 + #endif 1.8066 + return 1;} 1.8067 + d-=DECDPUN; 1.8068 + } 1.8069 + 1.8070 + /* check the exponent. Note that input operands can have exponents */ 1.8071 + /* which are out of the set->emin/set->emax and set->digits range */ 1.8072 + /* (just as they can have more digits than set->digits). */ 1.8073 + ae=dn->exponent+dn->digits-1; /* adjusted exponent */ 1.8074 + emax=DECNUMMAXE; 1.8075 + emin=DECNUMMINE; 1.8076 + digits=DECNUMMAXP; 1.8077 + if (ae<emin-(digits-1)) { 1.8078 + #if DECTRACE || DECVERB 1.8079 + printf("Adjusted exponent underflow [%ld].\n", (LI)ae); 1.8080 + uprv_decNumberShow(dn); 1.8081 + #endif 1.8082 + return 1;} 1.8083 + if (ae>+emax) { 1.8084 + #if DECTRACE || DECVERB 1.8085 + printf("Adjusted exponent overflow [%ld].\n", (LI)ae); 1.8086 + uprv_decNumberShow(dn); 1.8087 + #endif 1.8088 + return 1;} 1.8089 + 1.8090 + return 0; /* it's OK */ 1.8091 + } /* decCheckNumber */ 1.8092 + 1.8093 +/* ------------------------------------------------------------------ */ 1.8094 +/* decCheckInexact -- check a normal finite inexact result has digits */ 1.8095 +/* dn is the number to check */ 1.8096 +/* set is the context (for status and precision) */ 1.8097 +/* sets Invalid operation, etc., if some digits are missing */ 1.8098 +/* [this check is not made for DECSUBSET compilation or when */ 1.8099 +/* subnormal is not set] */ 1.8100 +/* ------------------------------------------------------------------ */ 1.8101 +static void decCheckInexact(const decNumber *dn, decContext *set) { 1.8102 + #if !DECSUBSET && DECEXTFLAG 1.8103 + if ((set->status & (DEC_Inexact|DEC_Subnormal))==DEC_Inexact 1.8104 + && (set->digits!=dn->digits) && !(dn->bits & DECSPECIAL)) { 1.8105 + #if DECTRACE || DECVERB 1.8106 + printf("Insufficient digits [%ld] on normal Inexact result.\n", 1.8107 + (LI)dn->digits); 1.8108 + uprv_decNumberShow(dn); 1.8109 + #endif 1.8110 + uprv_decContextSetStatus(set, DEC_Invalid_operation); 1.8111 + } 1.8112 + #else 1.8113 + /* next is a noop for quiet compiler */ 1.8114 + if (dn!=NULL && dn->digits==0) set->status|=DEC_Invalid_operation; 1.8115 + #endif 1.8116 + return; 1.8117 + } /* decCheckInexact */ 1.8118 +#endif 1.8119 + 1.8120 +#if DECALLOC 1.8121 +#undef malloc 1.8122 +#undef free 1.8123 +/* ------------------------------------------------------------------ */ 1.8124 +/* decMalloc -- accountable allocation routine */ 1.8125 +/* n is the number of bytes to allocate */ 1.8126 +/* */ 1.8127 +/* Semantics is the same as the stdlib malloc routine, but bytes */ 1.8128 +/* allocated are accounted for globally, and corruption fences are */ 1.8129 +/* added before and after the 'actual' storage. */ 1.8130 +/* ------------------------------------------------------------------ */ 1.8131 +/* This routine allocates storage with an extra twelve bytes; 8 are */ 1.8132 +/* at the start and hold: */ 1.8133 +/* 0-3 the original length requested */ 1.8134 +/* 4-7 buffer corruption detection fence (DECFENCE, x4) */ 1.8135 +/* The 4 bytes at the end also hold a corruption fence (DECFENCE, x4) */ 1.8136 +/* ------------------------------------------------------------------ */ 1.8137 +static void *decMalloc(size_t n) { 1.8138 + uInt size=n+12; /* true size */ 1.8139 + void *alloc; /* -> allocated storage */ 1.8140 + uByte *b, *b0; /* work */ 1.8141 + uInt uiwork; /* for macros */ 1.8142 + 1.8143 + alloc=malloc(size); /* -> allocated storage */ 1.8144 + if (alloc==NULL) return NULL; /* out of strorage */ 1.8145 + b0=(uByte *)alloc; /* as bytes */ 1.8146 + decAllocBytes+=n; /* account for storage */ 1.8147 + UBFROMUI(alloc, n); /* save n */ 1.8148 + /* printf(" alloc ++ dAB: %ld (%ld)\n", (LI)decAllocBytes, (LI)n); */ 1.8149 + for (b=b0+4; b<b0+8; b++) *b=DECFENCE; 1.8150 + for (b=b0+n+8; b<b0+n+12; b++) *b=DECFENCE; 1.8151 + return b0+8; /* -> play area */ 1.8152 + } /* decMalloc */ 1.8153 + 1.8154 +/* ------------------------------------------------------------------ */ 1.8155 +/* decFree -- accountable free routine */ 1.8156 +/* alloc is the storage to free */ 1.8157 +/* */ 1.8158 +/* Semantics is the same as the stdlib malloc routine, except that */ 1.8159 +/* the global storage accounting is updated and the fences are */ 1.8160 +/* checked to ensure that no routine has written 'out of bounds'. */ 1.8161 +/* ------------------------------------------------------------------ */ 1.8162 +/* This routine first checks that the fences have not been corrupted. */ 1.8163 +/* It then frees the storage using the 'truw' storage address (that */ 1.8164 +/* is, offset by 8). */ 1.8165 +/* ------------------------------------------------------------------ */ 1.8166 +static void decFree(void *alloc) { 1.8167 + uInt n; /* original length */ 1.8168 + uByte *b, *b0; /* work */ 1.8169 + uInt uiwork; /* for macros */ 1.8170 + 1.8171 + if (alloc==NULL) return; /* allowed; it's a nop */ 1.8172 + b0=(uByte *)alloc; /* as bytes */ 1.8173 + b0-=8; /* -> true start of storage */ 1.8174 + n=UBTOUI(b0); /* lift length */ 1.8175 + for (b=b0+4; b<b0+8; b++) if (*b!=DECFENCE) 1.8176 + printf("=== Corrupt byte [%02x] at offset %d from %ld ===\n", *b, 1.8177 + b-b0-8, (LI)b0); 1.8178 + for (b=b0+n+8; b<b0+n+12; b++) if (*b!=DECFENCE) 1.8179 + printf("=== Corrupt byte [%02x] at offset +%d from %ld, n=%ld ===\n", *b, 1.8180 + b-b0-8, (LI)b0, (LI)n); 1.8181 + free(b0); /* drop the storage */ 1.8182 + decAllocBytes-=n; /* account for storage */ 1.8183 + /* printf(" free -- dAB: %d (%d)\n", decAllocBytes, -n); */ 1.8184 + } /* decFree */ 1.8185 +#define malloc(a) decMalloc(a) 1.8186 +#define free(a) decFree(a) 1.8187 +#endif