Référence du fichier P:/wx_LIB/Dcml/decNumber.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "decNumber.h"
#include "decNumberLocal.h"

Aller au code source de ce fichier.

Macros

#define DECVERB   1
#define powers   DECPOWERS
#define DIVIDE   0x80
#define REMAINDER   0x40
#define DIVIDEINT   0x20
#define REMNEAR   0x10
#define COMPARE   0x01
#define COMPMAX   0x02
#define COMPMIN   0x03
#define COMPTOTAL   0x04
#define COMPNAN   0x05
#define COMPSIG   0x06
#define COMPMAXMAG   0x07
#define COMPMINMAG   0x08
#define DEC_sNaN   0x40000000
#define BADINT   (Int)0x80000000
#define BIGEVEN   (Int)0x80000002
#define BIGODD   (Int)0x80000003
#define eInt   Int
#define ueInt   uInt
#define QUOT10(u, n)   ((((uInt)(u)>>(n))*multies[n])>>17)
#define decFinish(a, b, c, d)   decFinalize(a,b,c,d)
#define SPECIALARG   (rhs->bits & DECSPECIAL)
#define SPECIALARGS   ((lhs->bits | rhs->bits) & DECSPECIAL)
#define FASTMUL   (DECUSE64 && DECDPUN<5)
#define FASTBASE   1000000000
#define FASTDIGS   9
#define FASTLAZY   18
#define NEEDTWO   (DECDPUN*2)
#define LN10   "2.302585092994045684017991454684364207601"
#define LN2   "0.6931471805599453094172321214581765680755"

Fonctions

static decNumberdecAddOp (decNumber *, const decNumber *, const decNumber *, decContext *, uByte, uInt *)
static Flag decBiStr (const char *, const char *, const char *)
static uInt decCheckMath (const decNumber *, decContext *, uInt *)
static void decApplyRound (decNumber *, decContext *, Int, uInt *)
static Int decCompare (const decNumber *lhs, const decNumber *rhs, Flag)
static decNumberdecCompareOp (decNumber *, const decNumber *, const decNumber *, decContext *, Flag, uInt *)
static void decCopyFit (decNumber *, const decNumber *, decContext *, Int *, uInt *)
static decNumberdecDecap (decNumber *, Int)
static decNumberdecDivideOp (decNumber *, const decNumber *, const decNumber *, decContext *, Flag, uInt *)
static decNumberdecExpOp (decNumber *, const decNumber *, decContext *, uInt *)
static void decFinalize (decNumber *, decContext *, Int *, uInt *)
static Int decGetDigits (Unit *, Int)
static Int decGetInt (const decNumber *)
static decNumberdecLnOp (decNumber *, const decNumber *, decContext *, uInt *)
static decNumberdecMultiplyOp (decNumber *, const decNumber *, const decNumber *, decContext *, uInt *)
static decNumberdecNaNs (decNumber *, const decNumber *, const decNumber *, decContext *, uInt *)
static decNumberdecQuantizeOp (decNumber *, const decNumber *, const decNumber *, decContext *, Flag, uInt *)
static void decReverse (Unit *, Unit *)
static void decSetCoeff (decNumber *, decContext *, const Unit *, Int, Int *, uInt *)
static void decSetMaxValue (decNumber *, decContext *)
static void decSetOverflow (decNumber *, decContext *, uInt *)
static void decSetSubnormal (decNumber *, decContext *, Int *, uInt *)
static Int decShiftToLeast (Unit *, Int, Int)
static Int decShiftToMost (Unit *, Int, Int)
static void decStatus (decNumber *, uInt, decContext *)
static void decToString (const decNumber *, char[], Flag)
static decNumberdecTrim (decNumber *, decContext *, Flag, Flag, Int *)
static Int decUnitAddSub (const Unit *, Int, const Unit *, Int, Int, Unit *, Int)
static Int decUnitCompare (const Unit *, Int, const Unit *, Int, Int)
decNumberdecNumberFromInt32 (decNumber *dn, Int in)
decNumberdecNumberFromUInt32 (decNumber *dn, uInt uin)
Int decNumberToInt32 (const decNumber *dn, decContext *set)
uInt decNumberToUInt32 (const decNumber *dn, decContext *set)
char * decNumberToString (const decNumber *dn, char *string)
char * decNumberToEngString (const decNumber *dn, char *string)
decNumberdecNumberFromString (decNumber *dn, const char chars[], decContext *set)
decNumberdecNumberAbs (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberAdd (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberAnd (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberCompare (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberCompareSignal (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberCompareTotal (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberCompareTotalMag (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberDivide (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberDivideInteger (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberExp (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberFMA (decNumber *res, const decNumber *lhs, const decNumber *rhs, const decNumber *fhs, decContext *set)
decNumberdecNumberInvert (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberLn (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberLogB (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberLog10 (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberMax (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberMaxMag (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberMin (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberMinMag (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberMinus (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberNextMinus (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberNextPlus (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberNextToward (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberOr (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberPlus (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberMultiply (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberPower (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberQuantize (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberNormalize (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberReduce (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberRescale (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberRemainder (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberRemainderNear (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberRotate (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberSameQuantum (decNumber *res, const decNumber *lhs, const decNumber *rhs)
decNumberdecNumberScaleB (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberShift (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberSquareRoot (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberSubtract (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
decNumberdecNumberToIntegralExact (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberToIntegralValue (decNumber *res, const decNumber *rhs, decContext *set)
decNumberdecNumberXor (decNumber *res, const decNumber *lhs, const decNumber *rhs, decContext *set)
enum decClass decNumberClass (const decNumber *dn, decContext *set)
const char * decNumberClassToString (enum decClass eclass)
decNumberdecNumberCopy (decNumber *dest, const decNumber *src)
decNumberdecNumberCopyAbs (decNumber *res, const decNumber *rhs)
decNumberdecNumberCopyNegate (decNumber *res, const decNumber *rhs)
decNumberdecNumberCopySign (decNumber *res, const decNumber *lhs, const decNumber *rhs)
uByte * decNumberGetBCD (const decNumber *dn, uByte *bcd)
decNumberdecNumberSetBCD (decNumber *dn, const uByte *bcd, uInt n)
Int decNumberIsNormal (const decNumber *dn, decContext *set)
Int decNumberIsSubnormal (const decNumber *dn, decContext *set)
decNumberdecNumberTrim (decNumber *dn)
const char * decNumberVersion (void)
decNumberdecNumberZero (decNumber *dn)
static void decToString (const decNumber *dn, char *string, Flag eng)

Variables

const uByte d2utable [DECMAXD2U+1] = D2UTABLE
static Unit uarrone [1] = {1}
static const uInt multies [] = {131073, 26215, 5243, 1049, 210}
const uShort LNnn [90]
static const uByte resmap [10] = {0, 3, 3, 3, 3, 5, 7, 7, 7, 7}


Documentation des macros

#define BADINT   (Int)0x80000000

Définition à la ligne 196 du fichier decNumber.c.

Référencé par decCompare(), decCompareOp(), decDivideOp(), decExpOp(), decFinalize(), decGetInt(), decNumberFromInt32(), decNumberNextToward(), decNumberPower(), decNumberRotate(), decNumberScaleB(), decNumberShift(), decQuantizeOp(), et decUnitCompare().

#define BIGEVEN   (Int)0x80000002

Définition à la ligne 198 du fichier decNumber.c.

Référencé par decGetInt(), decNumberPower(), decNumberRotate(), decNumberScaleB(), decNumberShift(), et decQuantizeOp().

#define BIGODD   (Int)0x80000003

Définition à la ligne 199 du fichier decNumber.c.

Référencé par decGetInt(), decNumberPower(), decNumberRotate(), decNumberScaleB(), decNumberShift(), et decQuantizeOp().

#define COMPARE   0x01

Définition à la ligne 186 du fichier decNumber.c.

Référencé par decCompareOp(), decLnOp(), decNumberCompare(), et decNumberSquareRoot().

#define COMPMAX   0x02

Définition à la ligne 187 du fichier decNumber.c.

Référencé par decCompareOp(), et decNumberMax().

#define COMPMAXMAG   0x07

Définition à la ligne 192 du fichier decNumber.c.

Référencé par decCompareOp(), et decNumberMaxMag().

#define COMPMIN   0x03

Définition à la ligne 188 du fichier decNumber.c.

Référencé par decCompareOp(), et decNumberMin().

#define COMPMINMAG   0x08

Définition à la ligne 193 du fichier decNumber.c.

Référencé par decCompareOp(), et decNumberMinMag().

#define COMPNAN   0x05

Définition à la ligne 190 du fichier decNumber.c.

Référencé par decCompareOp().

#define COMPSIG   0x06

Définition à la ligne 191 du fichier decNumber.c.

Référencé par decCompareOp(), et decNumberCompareSignal().

#define COMPTOTAL   0x04

Définition à la ligne 189 du fichier decNumber.c.

Référencé par decCompareOp(), decNumberCompareTotal(), et decNumberCompareTotalMag().

#define DEC_sNaN   0x40000000

Définition à la ligne 195 du fichier decNumber.c.

Référencé par decCompareOp(), decNaNs(), decNumberFMA(), decNumberLog10(), decNumberNextMinus(), decNumberNextPlus(), et decStatus().

#define decFinish ( a,
b,
c,
 )     decFinalize(a,b,c,d)

Définition à la ligne 269 du fichier decNumber.c.

Référencé par decAddOp(), decCompareOp(), decDivideOp(), decExpOp(), decLnOp(), decMultiplyOp(), decNumberLog10(), decNumberPower(), decNumberReduce(), et decNumberSquareRoot().

#define DECVERB   1

Définition à la ligne 178 du fichier decNumber.c.

#define DIVIDE   0x80

Définition à la ligne 182 du fichier decNumber.c.

Référencé par decDivideOp(), decExpOp(), decNumberDivide(), decNumberLog10(), decNumberPower(), et decNumberSquareRoot().

#define DIVIDEINT   0x20

Définition à la ligne 184 du fichier decNumber.c.

Référencé par decDivideOp(), et decNumberDivideInteger().

#define eInt   Int

Définition à la ligne 205 du fichier decNumber.c.

Référencé par decDivideOp(), et decUnitAddSub().

#define FASTBASE   1000000000

Référencé par decMultiplyOp().

#define FASTDIGS   9

Référencé par decMultiplyOp().

#define FASTLAZY   18

Référencé par decMultiplyOp().

#define FASTMUL   (DECUSE64 && DECDPUN<5)

Définition à la ligne 4849 du fichier decNumber.c.

#define LN10   "2.302585092994045684017991454684364207601"

Référencé par decLnOp().

#define LN2   "0.6931471805599453094172321214581765680755"

Référencé par decLnOp().

#define NEEDTWO   (DECDPUN*2)

Référencé par decMultiplyOp().

#define powers   DECPOWERS

Définition à la ligne 179 du fichier decNumber.c.

Référencé par decAddOp(), decDivideOp(), decExpOp(), decMultiplyOp(), decNumberAnd(), decNumberInvert(), decNumberOr(), decNumberRotate(), decNumberToInt32(), decNumberToUInt32(), decNumberXor(), decSetCoeff(), decShiftToLeast(), decShiftToMost(), decTrim(), et decUnitCompare().

#define QUOT10 ( u,
 )     ((((uInt)(u)>>(n))*multies[n])>>17)

Définition à la ligne 212 du fichier decNumber.c.

Référencé par decDivideOp(), decGetInt(), decShiftToLeast(), decShiftToMost(), decTrim(), et decUnitAddSub().

#define REMAINDER   0x40

Définition à la ligne 183 du fichier decNumber.c.

Référencé par decDivideOp(), et decNumberRemainder().

#define REMNEAR   0x10

Définition à la ligne 185 du fichier decNumber.c.

Référencé par decDivideOp(), et decNumberRemainderNear().

#define SPECIALARG   (rhs->bits & DECSPECIAL)

Définition à la ligne 277 du fichier decNumber.c.

Référencé par decExpOp(), decLnOp(), decNumberSquareRoot(), et decNumberToIntegralExact().

#define SPECIALARGS   ((lhs->bits | rhs->bits) & DECSPECIAL)

Définition à la ligne 278 du fichier decNumber.c.

Référencé par decAddOp(), decDivideOp(), decMultiplyOp(), decNumberPower(), decNumberSameQuantum(), et decQuantizeOp().

#define ueInt   uInt

Définition à la ligne 206 du fichier decNumber.c.

Référencé par decUnitAddSub().


Documentation des fonctions

static decNumber * decAddOp ( decNumber ,
const decNumber ,
const decNumber ,
decContext ,
uByte  ,
uInt *   
) [static]

Définition à la ligne 3816 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Inexact, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_ROUND_FLOOR, DEC_Rounded, decApplyRound(), DECBUFFER, decCopyFit(), DECDPUN, decFinish, decGetDigits(), DECINF, DECNAN, decNaNs(), DECNEG, decNumberCopy(), decNumberIsInfinite, decNumberZero(), decSetCoeff(), decShiftToMost(), DECSNAN, DECSUBSET, decUnitAddSub(), decNumber::digits, decContext::digits, decContext::emax, decContext::emin, decNumber::exponent, Flag, Int, ISZERO, decNumber::lsu, powers, decContext::round, SD2U, SPECIALARGS, et uByte.

Référencé par decExpOp(), decLnOp(), decNumberAbs(), decNumberAdd(), decNumberFMA(), decNumberMinus(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberPlus(), decNumberSquareRoot(), et decNumberSubtract().

03818                                                         {
03819   #if DECSUBSET
03820   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
03821   decNumber *allocrhs=NULL;        // .., rhs
03822   #endif
03823   Int   rhsshift;                  // working shift (in Units)
03824   Int   maxdigits;                 // longest logical length
03825   Int   mult;                      // multiplier
03826   Int   residue;                   // rounding accumulator
03827   uByte bits;                      // result bits
03828   Flag  diffsign;                  // non-0 if arguments have different sign
03829   Unit  *acc;                      // accumulator for result
03830   Unit  accbuff[SD2U(DECBUFFER*2+20)]; // local buffer [*2+20 reduces many
03831                                    // allocations when called from
03832                                    // other operations, notable exp]
03833   Unit  *allocacc=NULL;            // -> allocated acc buffer, iff allocated
03834   Int   reqdigits=set->digits;     // local copy; requested DIGITS
03835   Int   padding;                   // work
03836 
03837   #if DECCHECK
03838   if (decCheckOperands(res, lhs, rhs, set)) return res;
03839   #endif
03840 
03841   do {                             // protect allocated storage
03842     #if DECSUBSET
03843     if (!set->extended) {
03844       // reduce operands and set lostDigits status, as needed
03845       if (lhs->digits>reqdigits) {
03846         alloclhs=decRoundOperand(lhs, set, status);
03847         if (alloclhs==NULL) break;
03848         lhs=alloclhs;
03849         }
03850       if (rhs->digits>reqdigits) {
03851         allocrhs=decRoundOperand(rhs, set, status);
03852         if (allocrhs==NULL) break;
03853         rhs=allocrhs;
03854         }
03855       }
03856     #endif
03857     // [following code does not require input rounding]
03858 
03859     // note whether signs differ [used all paths]
03860     diffsign=(Flag)((lhs->bits^rhs->bits^negate)&DECNEG);
03861 
03862     // handle infinities and NaNs
03863     if (SPECIALARGS) {                  // a special bit set
03864       if (SPECIALARGS & (DECSNAN | DECNAN))  // a NaN
03865         decNaNs(res, lhs, rhs, set, status);
03866        else { // one or two infinities
03867         if (decNumberIsInfinite(lhs)) { // LHS is infinity
03868           // two infinities with different signs is invalid
03869           if (decNumberIsInfinite(rhs) && diffsign) {
03870             *status|=DEC_Invalid_operation;
03871             break;
03872             }
03873           bits=lhs->bits & DECNEG;      // get sign from LHS
03874           }
03875          else bits=(rhs->bits^negate) & DECNEG;// RHS must be Infinity
03876         bits|=DECINF;
03877         decNumberZero(res);
03878         res->bits=bits;                 // set +/- infinity
03879         } // an infinity
03880       break;
03881       }
03882 
03883     // Quick exit for add 0s; return the non-0, modified as need be
03884     if (ISZERO(lhs)) {
03885       Int adjust;                       // work
03886       Int lexp=lhs->exponent;           // save in case LHS==RES
03887       bits=lhs->bits;                   // ..
03888       residue=0;                        // clear accumulator
03889       decCopyFit(res, rhs, set, &residue, status); // copy (as needed)
03890       res->bits^=negate;                // flip if rhs was negated
03891       #if DECSUBSET
03892       if (set->extended) {              // exponents on zeros count
03893       #endif
03894         // exponent will be the lower of the two
03895         adjust=lexp-res->exponent;      // adjustment needed [if -ve]
03896         if (ISZERO(res)) {              // both 0: special IEEE 754 rules
03897           if (adjust<0) res->exponent=lexp;  // set exponent
03898           // 0-0 gives +0 unless rounding to -infinity, and -0-0 gives -0
03899           if (diffsign) {
03900             if (set->round!=DEC_ROUND_FLOOR) res->bits=0;
03901              else res->bits=DECNEG;     // preserve 0 sign
03902             }
03903           }
03904          else { // non-0 res
03905           if (adjust<0) {     // 0-padding needed
03906             if ((res->digits-adjust)>set->digits) {
03907               adjust=res->digits-set->digits;     // to fit exactly
03908               *status|=DEC_Rounded;               // [but exact]
03909               }
03910             res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
03911             res->exponent+=adjust;                // set the exponent.
03912             }
03913           } // non-0 res
03914       #if DECSUBSET
03915         } // extended
03916       #endif
03917       decFinish(res, set, &residue, status);      // clean and finalize
03918       break;}
03919 
03920     if (ISZERO(rhs)) {                  // [lhs is non-zero]
03921       Int adjust;                       // work
03922       Int rexp=rhs->exponent;           // save in case RHS==RES
03923       bits=rhs->bits;                   // be clean
03924       residue=0;                        // clear accumulator
03925       decCopyFit(res, lhs, set, &residue, status); // copy (as needed)
03926       #if DECSUBSET
03927       if (set->extended) {              // exponents on zeros count
03928       #endif
03929         // exponent will be the lower of the two
03930         // [0-0 case handled above]
03931         adjust=rexp-res->exponent;      // adjustment needed [if -ve]
03932         if (adjust<0) {     // 0-padding needed
03933           if ((res->digits-adjust)>set->digits) {
03934             adjust=res->digits-set->digits;     // to fit exactly
03935             *status|=DEC_Rounded;               // [but exact]
03936             }
03937           res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
03938           res->exponent+=adjust;                // set the exponent.
03939           }
03940       #if DECSUBSET
03941         } // extended
03942       #endif
03943       decFinish(res, set, &residue, status);      // clean and finalize
03944       break;}
03945 
03946     // [NB: both fastpath and mainpath code below assume these cases
03947     // (notably 0-0) have already been handled]
03948 
03949     // calculate the padding needed to align the operands
03950     padding=rhs->exponent-lhs->exponent;
03951 
03952     // Fastpath cases where the numbers are aligned and normal, the RHS
03953     // is all in one unit, no operand rounding is needed, and no carry,
03954     // lengthening, or borrow is needed
03955     if (padding==0
03956         && rhs->digits<=DECDPUN
03957         && rhs->exponent>=set->emin     // [some normals drop through]
03958         && rhs->exponent<=set->emax-set->digits+1 // [could clamp]
03959         && rhs->digits<=reqdigits
03960         && lhs->digits<=reqdigits) {
03961       Int partial=*lhs->lsu;
03962       if (!diffsign) {                  // adding
03963         partial+=*rhs->lsu;
03964         if ((partial<=DECDPUNMAX)       // result fits in unit
03965          && (lhs->digits>=DECDPUN ||    // .. and no digits-count change
03966              partial<(Int)powers[lhs->digits])) { // ..
03967           if (res!=lhs) decNumberCopy(res, lhs);  // not in place
03968           *res->lsu=(Unit)partial;      // [copy could have overwritten RHS]
03969           break;
03970           }
03971         // else drop out for careful add
03972         }
03973        else {                           // signs differ
03974         partial-=*rhs->lsu;
03975         if (partial>0) { // no borrow needed, and non-0 result
03976           if (res!=lhs) decNumberCopy(res, lhs);  // not in place
03977           *res->lsu=(Unit)partial;
03978           // this could have reduced digits [but result>0]
03979           res->digits=decGetDigits(res->lsu, D2U(res->digits));
03980           break;
03981           }
03982         // else drop out for careful subtract
03983         }
03984       }
03985 
03986     // Now align (pad) the lhs or rhs so they can be added or
03987     // subtracted, as necessary.  If one number is much larger than
03988     // the other (that is, if in plain form there is a least one
03989     // digit between the lowest digit of one and the highest of the
03990     // other) padding with up to DIGITS-1 trailing zeros may be
03991     // needed; then apply rounding (as exotic rounding modes may be
03992     // affected by the residue).
03993     rhsshift=0;               // rhs shift to left (padding) in Units
03994     bits=lhs->bits;           // assume sign is that of LHS
03995     mult=1;                   // likely multiplier
03996 
03997     // [if padding==0 the operands are aligned; no padding is needed]
03998     if (padding!=0) {
03999       // some padding needed; always pad the RHS, as any required
04000       // padding can then be effected by a simple combination of
04001       // shifts and a multiply
04002       Flag swapped=0;
04003       if (padding<0) {                  // LHS needs the padding
04004         const decNumber *t;
04005         padding=-padding;               // will be +ve
04006         bits=(uByte)(rhs->bits^negate); // assumed sign is now that of RHS
04007         t=lhs; lhs=rhs; rhs=t;
04008         swapped=1;
04009         }
04010 
04011       // If, after pad, rhs would be longer than lhs by digits+1 or
04012       // more then lhs cannot affect the answer, except as a residue,
04013       // so only need to pad up to a length of DIGITS+1.
04014       if (rhs->digits+padding > lhs->digits+reqdigits+1) {
04015         // The RHS is sufficient
04016         // for residue use the relative sign indication...
04017         Int shift=reqdigits-rhs->digits;     // left shift needed
04018         residue=1;                           // residue for rounding
04019         if (diffsign) residue=-residue;      // signs differ
04020         // copy, shortening if necessary
04021         decCopyFit(res, rhs, set, &residue, status);
04022         // if it was already shorter, then need to pad with zeros
04023         if (shift>0) {
04024           res->digits=decShiftToMost(res->lsu, res->digits, shift);
04025           res->exponent-=shift;              // adjust the exponent.
04026           }
04027         // flip the result sign if unswapped and rhs was negated
04028         if (!swapped) res->bits^=negate;
04029         decFinish(res, set, &residue, status);    // done
04030         break;}
04031 
04032       // LHS digits may affect result
04033       rhsshift=D2U(padding+1)-1;        // this much by Unit shift ..
04034       mult=powers[padding-(rhsshift*DECDPUN)]; // .. this by multiplication
04035       } // padding needed
04036 
04037     if (diffsign) mult=-mult;           // signs differ
04038 
04039     // determine the longer operand
04040     maxdigits=rhs->digits+padding;      // virtual length of RHS
04041     if (lhs->digits>maxdigits) maxdigits=lhs->digits;
04042 
04043     // Decide on the result buffer to use; if possible place directly
04044     // into result.
04045     acc=res->lsu;                       // assume add direct to result
04046     // If destructive overlap, or the number is too long, or a carry or
04047     // borrow to DIGITS+1 might be possible, a buffer must be used.
04048     // [Might be worth more sophisticated tests when maxdigits==reqdigits]
04049     if ((maxdigits>=reqdigits)          // is, or could be, too large
04050      || (res==rhs && rhsshift>0)) {     // destructive overlap
04051       // buffer needed, choose it; units for maxdigits digits will be
04052       // needed, +1 Unit for carry or borrow
04053       Int need=D2U(maxdigits)+1;
04054       acc=accbuff;                      // assume use local buffer
04055       if (need*sizeof(Unit)>sizeof(accbuff)) {
04056         // printf("malloc add %ld %ld\n", need, sizeof(accbuff));
04057         allocacc=(Unit *)malloc(need*sizeof(Unit));
04058         if (allocacc==NULL) {           // hopeless -- abandon
04059           *status|=DEC_Insufficient_storage;
04060           break;}
04061         acc=allocacc;
04062         }
04063       }
04064 
04065     res->bits=(uByte)(bits&DECNEG);     // it's now safe to overwrite..
04066     res->exponent=lhs->exponent;        // .. operands (even if aliased)
04067 
04068     #if DECTRACE
04069       decDumpAr('A', lhs->lsu, D2U(lhs->digits));
04070       decDumpAr('B', rhs->lsu, D2U(rhs->digits));
04071       printf("  :h: %ld %ld\n", rhsshift, mult);
04072     #endif
04073 
04074     // add [A+B*m] or subtract [A+B*(-m)]
04075     res->digits=decUnitAddSub(lhs->lsu, D2U(lhs->digits),
04076                               rhs->lsu, D2U(rhs->digits),
04077                               rhsshift, acc, mult)
04078                *DECDPUN;           // [units -> digits]
04079     if (res->digits<0) {           // borrowed...
04080       res->digits=-res->digits;
04081       res->bits^=DECNEG;           // flip the sign
04082       }
04083     #if DECTRACE
04084       decDumpAr('+', acc, D2U(res->digits));
04085     #endif
04086 
04087     // If a buffer was used the result must be copied back, possibly
04088     // shortening.  (If no buffer was used then the result must have
04089     // fit, so can't need rounding and residue must be 0.)
04090     residue=0;                     // clear accumulator
04091     if (acc!=res->lsu) {
04092       #if DECSUBSET
04093       if (set->extended) {         // round from first significant digit
04094       #endif
04095         // remove leading zeros that were added due to rounding up to
04096         // integral Units -- before the test for rounding.
04097         if (res->digits>reqdigits)
04098           res->digits=decGetDigits(acc, D2U(res->digits));
04099         decSetCoeff(res, set, acc, res->digits, &residue, status);
04100       #if DECSUBSET
04101         }
04102        else { // subset arithmetic rounds from original significant digit
04103         // May have an underestimate.  This only occurs when both
04104         // numbers fit in DECDPUN digits and are padding with a
04105         // negative multiple (-10, -100...) and the top digit(s) become
04106         // 0.  (This only matters when using X3.274 rules where the
04107         // leading zero could be included in the rounding.)
04108         if (res->digits<maxdigits) {
04109           *(acc+D2U(res->digits))=0; // ensure leading 0 is there
04110           res->digits=maxdigits;
04111           }
04112          else {
04113           // remove leading zeros that added due to rounding up to
04114           // integral Units (but only those in excess of the original
04115           // maxdigits length, unless extended) before test for rounding.
04116           if (res->digits>reqdigits) {
04117             res->digits=decGetDigits(acc, D2U(res->digits));
04118             if (res->digits<maxdigits) res->digits=maxdigits;
04119             }
04120           }
04121         decSetCoeff(res, set, acc, res->digits, &residue, status);
04122         // Now apply rounding if needed before removing leading zeros.
04123         // This is safe because subnormals are not a possibility
04124         if (residue!=0) {
04125           decApplyRound(res, set, residue, status);
04126           residue=0;                 // did what needed to be done
04127           }
04128         } // subset
04129       #endif
04130       } // used buffer
04131 
04132     // strip leading zeros [these were left on in case of subset subtract]
04133     res->digits=decGetDigits(res->lsu, D2U(res->digits));
04134 
04135     // apply checks and rounding
04136     decFinish(res, set, &residue, status);
04137 
04138     // "When the sum of two operands with opposite signs is exactly
04139     // zero, the sign of that sum shall be '+' in all rounding modes
04140     // except round toward -Infinity, in which mode that sign shall be
04141     // '-'."  [Subset zeros also never have '-', set by decFinish.]
04142     if (ISZERO(res) && diffsign
04143      #if DECSUBSET
04144      && set->extended
04145      #endif
04146      && (*status&DEC_Inexact)==0) {
04147       if (set->round==DEC_ROUND_FLOOR) res->bits|=DECNEG;   // sign -
04148                                   else res->bits&=~DECNEG;  // sign +
04149       }
04150     } while(0);                              // end protected
04151 
04152   if (allocacc!=NULL) free(allocacc);        // drop any storage used
04153   #if DECSUBSET
04154   if (allocrhs!=NULL) free(allocrhs);        // ..
04155   if (alloclhs!=NULL) free(alloclhs);        // ..
04156   #endif
04157   return res;
04158   } // decAddOp

static void decApplyRound ( decNumber ,
decContext ,
Int  ,
uInt *   
) [static]

Définition à la ligne 7083 du fichier decNumber.c.

Références DEC_Invalid_context, DEC_ROUND_05UP, DEC_ROUND_CEILING, DEC_ROUND_DOWN, DEC_ROUND_FLOOR, DEC_ROUND_HALF_DOWN, DEC_ROUND_HALF_EVEN, DEC_ROUND_HALF_UP, DEC_ROUND_UP, DECDPUN, decNumberIsNegative, decSetOverflow(), decNumber::digits, decContext::emax, decNumber::exponent, Int, decNumber::lsu, decContext::round, et uInt.

Référencé par decAddOp(), decFinalize(), decQuantizeOp(), et decSetSubnormal().

07084                                         {
07085   Int  bump;                  // 1 if coefficient needs to be incremented
07086                               // -1 if coefficient needs to be decremented
07087 
07088   if (residue==0) return;     // nothing to apply
07089 
07090   bump=0;                     // assume a smooth ride
07091 
07092   // now decide whether, and how, to round, depending on mode
07093   switch (set->round) {
07094     case DEC_ROUND_05UP: {    // round zero or five up (for reround)
07095       // This is the same as DEC_ROUND_DOWN unless there is a
07096       // positive residue and the lsd of dn is 0 or 5, in which case
07097       // it is bumped; when residue is <0, the number is therefore
07098       // bumped down unless the final digit was 1 or 6 (in which
07099       // case it is bumped down and then up -- a no-op)
07100       Int lsd5=*dn->lsu%5;     // get lsd and quintate
07101       if (residue<0 && lsd5!=1) bump=-1;
07102        else if (residue>0 && lsd5==0) bump=1;
07103       // [bump==1 could be applied directly; use common path for clarity]
07104       break;} // r-05
07105 
07106     case DEC_ROUND_DOWN: {
07107       // no change, except if negative residue
07108       if (residue<0) bump=-1;
07109       break;} // r-d
07110 
07111     case DEC_ROUND_HALF_DOWN: {
07112       if (residue>5) bump=1;
07113       break;} // r-h-d
07114 
07115     case DEC_ROUND_HALF_EVEN: {
07116       if (residue>5) bump=1;            // >0.5 goes up
07117        else if (residue==5) {           // exactly 0.5000...
07118         // 0.5 goes up iff [new] lsd is odd
07119         if (*dn->lsu & 0x01) bump=1;
07120         }
07121       break;} // r-h-e
07122 
07123     case DEC_ROUND_HALF_UP: {
07124       if (residue>=5) bump=1;
07125       break;} // r-h-u
07126 
07127     case DEC_ROUND_UP: {
07128       if (residue>0) bump=1;
07129       break;} // r-u
07130 
07131     case DEC_ROUND_CEILING: {
07132       // same as _UP for positive numbers, and as _DOWN for negatives
07133       // [negative residue cannot occur on 0]
07134       if (decNumberIsNegative(dn)) {
07135         if (residue<0) bump=-1;
07136         }
07137        else {
07138         if (residue>0) bump=1;
07139         }
07140       break;} // r-c
07141 
07142     case DEC_ROUND_FLOOR: {
07143       // same as _UP for negative numbers, and as _DOWN for positive
07144       // [negative residue cannot occur on 0]
07145       if (!decNumberIsNegative(dn)) {
07146         if (residue<0) bump=-1;
07147         }
07148        else {
07149         if (residue>0) bump=1;
07150         }
07151       break;} // r-f
07152 
07153     default: {      // e.g., DEC_ROUND_MAX
07154       *status|=DEC_Invalid_context;
07155       #if DECTRACE || (DECCHECK && DECVERB)
07156       printf("Unknown rounding mode: %d\n", set->round);
07157       #endif
07158       break;}
07159     } // switch
07160 
07161   // now bump the number, up or down, if need be
07162   if (bump==0) return;                       // no action required
07163 
07164   // Simply use decUnitAddSub unless bumping up and the number is
07165   // all nines.  In this special case set to 100... explicitly
07166   // and adjust the exponent by one (as otherwise could overflow
07167   // the array)
07168   // Similarly handle all-nines result if bumping down.
07169   if (bump>0) {
07170     Unit *up;                                // work
07171     uInt count=dn->digits;                   // digits to be checked
07172     for (up=dn->lsu; ; up++) {
07173       if (count<=DECDPUN) {
07174         // this is the last Unit (the msu)
07175         if (*up!=powers[count]-1) break;     // not still 9s
07176         // here if it, too, is all nines
07177         *up=(Unit)powers[count-1];           // here 999 -> 100 etc.
07178         for (up=up-1; up>=dn->lsu; up--) *up=0; // others all to 0
07179         dn->exponent++;                      // and bump exponent
07180         // [which, very rarely, could cause Overflow...]
07181         if ((dn->exponent+dn->digits)>set->emax+1) {
07182           decSetOverflow(dn, set, status);
07183           }
07184         return;                              // done
07185         }
07186       // a full unit to check, with more to come
07187       if (*up!=DECDPUNMAX) break;            // not still 9s
07188       count-=DECDPUN;
07189       } // up
07190     } // bump>0
07191    else {                                    // -1
07192     // here checking for a pre-bump of 1000... (leading 1, all
07193     // other digits zero)
07194     Unit *up, *sup;                          // work
07195     uInt count=dn->digits;                   // digits to be checked
07196     for (up=dn->lsu; ; up++) {
07197       if (count<=DECDPUN) {
07198         // this is the last Unit (the msu)
07199         if (*up!=powers[count-1]) break;     // not 100..
07200         // here if have the 1000... case
07201         sup=up;                              // save msu pointer
07202         *up=(Unit)powers[count]-1;           // here 100 in msu -> 999
07203         // others all to all-nines, too
07204         for (up=up-1; up>=dn->lsu; up--) *up=(Unit)powers[DECDPUN]-1;
07205         dn->exponent--;                      // and bump exponent
07206 
07207         // iff the number was at the subnormal boundary (exponent=etiny)
07208         // then the exponent is now out of range, so it will in fact get
07209         // clamped to etiny and the final 9 dropped.
07210         // printf(">> emin=%d exp=%d sdig=%d\n", set->emin,
07211         //        dn->exponent, set->digits);
07212         if (dn->exponent+1==set->emin-set->digits+1) {
07213           if (count==1 && dn->digits==1) *sup=0;  // here 9 -> 0[.9]
07214            else {
07215             *sup=(Unit)powers[count-1]-1;    // here 999.. in msu -> 99..
07216             dn->digits--;
07217             }
07218           dn->exponent++;
07219           *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
07220           }
07221         return;                              // done
07222         }
07223 
07224       // a full unit to check, with more to come
07225       if (*up!=0) break;                     // not still 0s
07226       count-=DECDPUN;
07227       } // up
07228 
07229     } // bump<0
07230 
07231   // Actual bump needed.  Do it.
07232   decUnitAddSub(dn->lsu, D2U(dn->digits), uarrone, 1, 0, dn->lsu, bump);
07233   } // decApplyRound

static Flag decBiStr ( const char *  ,
const char *  ,
const char *   
) [static]

Définition à la ligne 7680 du fichier decNumber.c.

Référencé par decNumberFromString().

07680                                                                            {
07681   for (;;targ++, str1++, str2++) {
07682     if (*targ!=*str1 && *targ!=*str2) return 0;
07683     // *targ has a match in one (or both, if terminator)
07684     if (*targ=='\0') break;
07685     } // forever
07686   return 1;
07687   } // decBiStr

static uInt decCheckMath ( const decNumber ,
decContext ,
uInt *   
) [static]

Définition à la ligne 7527 du fichier decNumber.c.

Références DEC_Invalid_context, DEC_Invalid_operation, DEC_MAX_MATH, decNumber::digits, decContext::digits, decContext::emax, decContext::emin, decNumber::exponent, ISZERO, et uInt.

Référencé par decNumberExp(), decNumberFMA(), decNumberLn(), decNumberLog10(), et decNumberPower().

07528                                        {
07529   uInt save=*status;                         // record
07530   if (set->digits>DEC_MAX_MATH
07531    || set->emax>DEC_MAX_MATH
07532    || -set->emin>DEC_MAX_MATH) *status|=DEC_Invalid_context;
07533    else if ((rhs->digits>DEC_MAX_MATH
07534      || rhs->exponent+rhs->digits>DEC_MAX_MATH+1
07535      || rhs->exponent+rhs->digits<2*(1-DEC_MAX_MATH))
07536      && !ISZERO(rhs)) *status|=DEC_Invalid_operation;
07537   return (*status!=save);
07538   } // decCheckMath

static Int decCompare ( const decNumber lhs,
const decNumber rhs,
Flag   
) [static]

Définition à la ligne 6182 du fichier decNumber.c.

Références BADINT, decNumber::bits, D2U, DECINF, decNumberIsInfinite, decNumberIsNegative, decUnitCompare(), decNumber::digits, decNumber::exponent, Int, ISZERO, et decNumber::lsu.

Référencé par decCompareOp(), decExpOp(), decFinalize(), et decNumberNextToward().

06183                                 {
06184   Int   result;                    // result value
06185   Int   sigr;                      // rhs signum
06186   Int   compare;                   // work
06187 
06188   result=1;                                  // assume signum(lhs)
06189   if (ISZERO(lhs)) result=0;
06190   if (abs) {
06191     if (ISZERO(rhs)) return result;          // LHS wins or both 0
06192     // RHS is non-zero
06193     if (result==0) return -1;                // LHS is 0; RHS wins
06194     // [here, both non-zero, result=1]
06195     }
06196    else {                                    // signs matter
06197     if (result && decNumberIsNegative(lhs)) result=-1;
06198     sigr=1;                                  // compute signum(rhs)
06199     if (ISZERO(rhs)) sigr=0;
06200      else if (decNumberIsNegative(rhs)) sigr=-1;
06201     if (result > sigr) return +1;            // L > R, return 1
06202     if (result < sigr) return -1;            // L < R, return -1
06203     if (result==0) return 0;                   // both 0
06204     }
06205 
06206   // signums are the same; both are non-zero
06207   if ((lhs->bits | rhs->bits) & DECINF) {    // one or more infinities
06208     if (decNumberIsInfinite(rhs)) {
06209       if (decNumberIsInfinite(lhs)) result=0;// both infinite
06210        else result=-result;                  // only rhs infinite
06211       }
06212     return result;
06213     }
06214   // must compare the coefficients, allowing for exponents
06215   if (lhs->exponent>rhs->exponent) {         // LHS exponent larger
06216     // swap sides, and sign
06217     const decNumber *temp=lhs;
06218     lhs=rhs;
06219     rhs=temp;
06220     result=-result;
06221     }
06222   compare=decUnitCompare(lhs->lsu, D2U(lhs->digits),
06223                          rhs->lsu, D2U(rhs->digits),
06224                          rhs->exponent-lhs->exponent);
06225   if (compare!=BADINT) compare*=result;      // comparison succeeded
06226   return compare;
06227   } // decCompare

decNumber * decCompareOp ( decNumber ,
const decNumber ,
const decNumber ,
decContext ,
Flag  ,
uInt *   
) [static]

Définition à la ligne 6017 du fichier decNumber.c.

Références BADINT, decNumber::bits, COMPARE, COMPMAX, COMPMAXMAG, COMPMIN, COMPMINMAG, COMPNAN, COMPSIG, COMPTOTAL, D2U, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_sNaN, decCompare(), decCopyFit(), decFinish, DECNAN, decNaNs(), DECNEG, decNumberIsNaN, decNumberIsNegative, decNumberIsQNaN, decNumberIsSNaN, decNumberZero(), DECSNAN, decUnitCompare(), decContext::digits, decNumber::digits, decNumber::exponent, Int, decNumber::lsu, et uByte.

Référencé par decLnOp(), decNumberCompare(), decNumberCompareSignal(), decNumberCompareTotal(), decNumberCompareTotalMag(), decNumberMax(), decNumberMaxMag(), decNumberMin(), decNumberMinMag(), et decNumberSquareRoot().

06019                                                 {
06020   #if DECSUBSET
06021   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
06022   decNumber *allocrhs=NULL;        // .., rhs
06023   #endif
06024   Int   result=0;                  // default result value
06025   uByte merged;                    // work
06026 
06027   #if DECCHECK
06028   if (decCheckOperands(res, lhs, rhs, set)) return res;
06029   #endif
06030 
06031   do {                             // protect allocated storage
06032     #if DECSUBSET
06033     if (!set->extended) {
06034       // reduce operands and set lostDigits status, as needed
06035       if (lhs->digits>set->digits) {
06036         alloclhs=decRoundOperand(lhs, set, status);
06037         if (alloclhs==NULL) {result=BADINT; break;}
06038         lhs=alloclhs;
06039         }
06040       if (rhs->digits>set->digits) {
06041         allocrhs=decRoundOperand(rhs, set, status);
06042         if (allocrhs==NULL) {result=BADINT; break;}
06043         rhs=allocrhs;
06044         }
06045       }
06046     #endif
06047     // [following code does not require input rounding]
06048 
06049     // If total ordering then handle differing signs 'up front'
06050     if (op==COMPTOTAL) {                // total ordering
06051       if (decNumberIsNegative(lhs) & !decNumberIsNegative(rhs)) {
06052         result=-1;
06053         break;
06054         }
06055       if (!decNumberIsNegative(lhs) & decNumberIsNegative(rhs)) {
06056         result=+1;
06057         break;
06058         }
06059       }
06060 
06061     // handle NaNs specially; let infinities drop through
06062     // This assumes sNaN (even just one) leads to NaN.
06063     merged=(lhs->bits | rhs->bits) & (DECSNAN | DECNAN);
06064     if (merged) {                       // a NaN bit set
06065       if (op==COMPARE);                 // result will be NaN
06066        else if (op==COMPSIG)            // treat qNaN as sNaN
06067         *status|=DEC_Invalid_operation | DEC_sNaN;
06068        else if (op==COMPTOTAL) {        // total ordering, always finite
06069         // signs are known to be the same; compute the ordering here
06070         // as if the signs are both positive, then invert for negatives
06071         if (!decNumberIsNaN(lhs)) result=-1;
06072          else if (!decNumberIsNaN(rhs)) result=+1;
06073          // here if both NaNs
06074          else if (decNumberIsSNaN(lhs) && decNumberIsQNaN(rhs)) result=-1;
06075          else if (decNumberIsQNaN(lhs) && decNumberIsSNaN(rhs)) result=+1;
06076          else { // both NaN or both sNaN
06077           // now it just depends on the payload
06078           result=decUnitCompare(lhs->lsu, D2U(lhs->digits),
06079                                 rhs->lsu, D2U(rhs->digits), 0);
06080           // [Error not possible, as these are 'aligned']
06081           } // both same NaNs
06082         if (decNumberIsNegative(lhs)) result=-result;
06083         break;
06084         } // total order
06085 
06086        else if (merged & DECSNAN);           // sNaN -> qNaN
06087        else { // here if MIN or MAX and one or two quiet NaNs
06088         // min or max -- 754 rules ignore single NaN
06089         if (!decNumberIsNaN(lhs) || !decNumberIsNaN(rhs)) {
06090           // just one NaN; force choice to be the non-NaN operand
06091           op=COMPMAX;
06092           if (lhs->bits & DECNAN) result=-1; // pick rhs
06093                              else result=+1; // pick lhs
06094           break;
06095           }
06096         } // max or min
06097       op=COMPNAN;                            // use special path
06098       decNaNs(res, lhs, rhs, set, status);   // propagate NaN
06099       break;
06100       }
06101     // have numbers
06102     if (op==COMPMAXMAG || op==COMPMINMAG) result=decCompare(lhs, rhs, 1);
06103      else result=decCompare(lhs, rhs, 0);    // sign matters
06104     } while(0);                              // end protected
06105 
06106   if (result==BADINT) *status|=DEC_Insufficient_storage; // rare
06107    else {
06108     if (op==COMPARE || op==COMPSIG ||op==COMPTOTAL) { // returning signum
06109       if (op==COMPTOTAL && result==0) {
06110         // operands are numerically equal or same NaN (and same sign,
06111         // tested first); if identical, leave result 0
06112         if (lhs->exponent!=rhs->exponent) {
06113           if (lhs->exponent<rhs->exponent) result=-1;
06114            else result=+1;
06115           if (decNumberIsNegative(lhs)) result=-result;
06116           } // lexp!=rexp
06117         } // total-order by exponent
06118       decNumberZero(res);               // [always a valid result]
06119       if (result!=0) {                  // must be -1 or +1
06120         *res->lsu=1;
06121         if (result<0) res->bits=DECNEG;
06122         }
06123       }
06124      else if (op==COMPNAN);             // special, drop through
06125      else {                             // MAX or MIN, non-NaN result
06126       Int residue=0;                    // rounding accumulator
06127       // choose the operand for the result
06128       const decNumber *choice;
06129       if (result==0) { // operands are numerically equal
06130         // choose according to sign then exponent (see 754)
06131         uByte slhs=(lhs->bits & DECNEG);
06132         uByte srhs=(rhs->bits & DECNEG);
06133         #if DECSUBSET
06134         if (!set->extended) {           // subset: force left-hand
06135           op=COMPMAX;
06136           result=+1;
06137           }
06138         else
06139         #endif
06140         if (slhs!=srhs) {          // signs differ
06141           if (slhs) result=-1;     // rhs is max
06142                else result=+1;     // lhs is max
06143           }
06144          else if (slhs && srhs) {  // both negative
06145           if (lhs->exponent<rhs->exponent) result=+1;
06146                                       else result=-1;
06147           // [if equal, use lhs, technically identical]
06148           }
06149          else {                    // both positive
06150           if (lhs->exponent>rhs->exponent) result=+1;
06151                                       else result=-1;
06152           // [ditto]
06153           }
06154         } // numerically equal
06155       // here result will be non-0; reverse if looking for MIN
06156       if (op==COMPMIN || op==COMPMINMAG) result=-result;
06157       choice=(result>0 ? lhs : rhs);    // choose
06158       // copy chosen to result, rounding if need be
06159       decCopyFit(res, choice, set, &residue, status);
06160       decFinish(res, set, &residue, status);
06161       }
06162     }
06163   #if DECSUBSET
06164   if (allocrhs!=NULL) free(allocrhs);   // free any storage used
06165   if (alloclhs!=NULL) free(alloclhs);   // ..
06166   #endif
06167   return res;
06168   } // decCompareOp

static void decCopyFit ( decNumber ,
const decNumber ,
decContext ,
Int *  ,
uInt *   
) [static]

Définition à la ligne 6856 du fichier decNumber.c.

Références decNumber::bits, decSetCoeff(), decNumber::digits, decNumber::exponent, et decNumber::lsu.

Référencé par decAddOp(), decCompareOp(), decDivideOp(), decExpOp(), decLnOp(), decNumberLog10(), decNumberPower(), decNumberReduce(), decNumberSquareRoot(), et decQuantizeOp().

06857                                                                     {
06858   dest->bits=src->bits;
06859   dest->exponent=src->exponent;
06860   decSetCoeff(dest, set, src->lsu, src->digits, residue, status);
06861   } // decCopyFit

static decNumber * decDecap ( decNumber ,
Int   
) [static]

Définition à la ligne 7644 du fichier decNumber.c.

Références D2U, DECDPUN, decGetDigits(), decNumber::digits, Int, decNumber::lsu, et MSUDIGITS.

Référencé par decNaNs(), et decNumberShift().

07644                                                     {
07645   Unit *msu;                            // -> target cut point
07646   Int cut;                              // work
07647   if (drop>=dn->digits) {               // losing the whole thing
07648     #if DECCHECK
07649     if (drop>dn->digits)
07650       printf("decDecap called with drop>digits [%ld>%ld]\n",
07651              (LI)drop, (LI)dn->digits);
07652     #endif
07653     dn->lsu[0]=0;
07654     dn->digits=1;
07655     return dn;
07656     }
07657   msu=dn->lsu+D2U(dn->digits-drop)-1;   // -> likely msu
07658   cut=MSUDIGITS(dn->digits-drop);       // digits to be in use in msu
07659   if (cut!=DECDPUN) *msu%=powers[cut];  // clear left digits
07660   // that may have left leading zero digits, so do a proper count...
07661   dn->digits=decGetDigits(dn->lsu, msu-dn->lsu+1);
07662   return dn;
07663   } // decDecap

static decNumber * decDivideOp ( decNumber ,
const decNumber ,
const decNumber ,
decContext ,
Flag  ,
uInt *   
) [static]

Définition à la ligne 4230 du fichier decNumber.c.

Références BADINT, decNumber::bits, D2U, DEC_Clamped, DEC_Division_by_zero, DEC_Division_impossible, DEC_Division_undefined, DEC_Insufficient_storage, DEC_Invalid_operation, DECBUFFER, decCopyFit(), DECDPUN, decFinalize(), decFinish, decGetDigits(), DECINF, DECNAN, decNaNs(), DECNEG, decNumberCopy(), decNumberIsInfinite, decNumberZero(), decSetCoeff(), decShiftToLeast(), DECSNAN, decTrim(), decUnitAddSub(), decUnitCompare(), decNumber::digits, decContext::digits, DIVIDE, DIVIDEINT, eInt, decContext::emin, decNumber::exponent, Flag, Int, ISZERO, decNumber::lsu, pow(), powers, QUOT10, REMAINDER, REMNEAR, SD2U, SPECIALARGS, uByte, et uInt.

Référencé par decExpOp(), decNumberDivide(), decNumberDivideInteger(), decNumberLog10(), decNumberPower(), decNumberRemainder(), decNumberRemainderNear(), et decNumberSquareRoot().

04232                                                                        {
04233   #if DECSUBSET
04234   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
04235   decNumber *allocrhs=NULL;        // .., rhs
04236   #endif
04237   Unit  accbuff[SD2U(DECBUFFER+DECDPUN+10)]; // local buffer
04238   Unit  *acc=accbuff;              // -> accumulator array for result
04239   Unit  *allocacc=NULL;            // -> allocated buffer, iff allocated
04240   Unit  *accnext;                  // -> where next digit will go
04241   Int   acclength;                 // length of acc needed [Units]
04242   Int   accunits;                  // count of units accumulated
04243   Int   accdigits;                 // count of digits accumulated
04244 
04245   Unit  varbuff[SD2U(DECBUFFER*2+DECDPUN)];  // buffer for var1
04246   Unit  *var1=varbuff;             // -> var1 array for long subtraction
04247   Unit  *varalloc=NULL;            // -> allocated buffer, iff used
04248   Unit  *msu1;                     // -> msu of var1
04249 
04250   const Unit *var2;                // -> var2 array
04251   const Unit *msu2;                // -> msu of var2
04252   Int   msu2plus;                  // msu2 plus one [does not vary]
04253   eInt  msu2pair;                  // msu2 pair plus one [does not vary]
04254 
04255   Int   var1units, var2units;      // actual lengths
04256   Int   var2ulen;                  // logical length (units)
04257   Int   var1initpad=0;             // var1 initial padding (digits)
04258   Int   maxdigits;                 // longest LHS or required acc length
04259   Int   mult;                      // multiplier for subtraction
04260   Unit  thisunit;                  // current unit being accumulated
04261   Int   residue;                   // for rounding
04262   Int   reqdigits=set->digits;     // requested DIGITS
04263   Int   exponent;                  // working exponent
04264   Int   maxexponent=0;             // DIVIDE maximum exponent if unrounded
04265   uByte bits;                      // working sign
04266   Unit  *target;                   // work
04267   const Unit *source;              // ..
04268   uInt  const *pow;                // ..
04269   Int   shift, cut;                // ..
04270   #if DECSUBSET
04271   Int   dropped;                   // work
04272   #endif
04273 
04274   #if DECCHECK
04275   if (decCheckOperands(res, lhs, rhs, set)) return res;
04276   #endif
04277 
04278   do {                             // protect allocated storage
04279     #if DECSUBSET
04280     if (!set->extended) {
04281       // reduce operands and set lostDigits status, as needed
04282       if (lhs->digits>reqdigits) {
04283         alloclhs=decRoundOperand(lhs, set, status);
04284         if (alloclhs==NULL) break;
04285         lhs=alloclhs;
04286         }
04287       if (rhs->digits>reqdigits) {
04288         allocrhs=decRoundOperand(rhs, set, status);
04289         if (allocrhs==NULL) break;
04290         rhs=allocrhs;
04291         }
04292       }
04293     #endif
04294     // [following code does not require input rounding]
04295 
04296     bits=(lhs->bits^rhs->bits)&DECNEG;  // assumed sign for divisions
04297 
04298     // handle infinities and NaNs
04299     if (SPECIALARGS) {                  // a special bit set
04300       if (SPECIALARGS & (DECSNAN | DECNAN)) { // one or two NaNs
04301         decNaNs(res, lhs, rhs, set, status);
04302         break;
04303         }
04304       // one or two infinities
04305       if (decNumberIsInfinite(lhs)) {   // LHS (dividend) is infinite
04306         if (decNumberIsInfinite(rhs) || // two infinities are invalid ..
04307             op & (REMAINDER | REMNEAR)) { // as is remainder of infinity
04308           *status|=DEC_Invalid_operation;
04309           break;
04310           }
04311         // [Note that infinity/0 raises no exceptions]
04312         decNumberZero(res);
04313         res->bits=bits|DECINF;          // set +/- infinity
04314         break;
04315         }
04316        else {                           // RHS (divisor) is infinite
04317         residue=0;
04318         if (op&(REMAINDER|REMNEAR)) {
04319           // result is [finished clone of] lhs
04320           decCopyFit(res, lhs, set, &residue, status);
04321           }
04322          else {  // a division
04323           decNumberZero(res);
04324           res->bits=bits;               // set +/- zero
04325           // for DIVIDEINT the exponent is always 0.  For DIVIDE, result
04326           // is a 0 with infinitely negative exponent, clamped to minimum
04327           if (op&DIVIDE) {
04328             res->exponent=set->emin-set->digits+1;
04329             *status|=DEC_Clamped;
04330             }
04331           }
04332         decFinish(res, set, &residue, status);
04333         break;
04334         }
04335       }
04336 
04337     // handle 0 rhs (x/0)
04338     if (ISZERO(rhs)) {                  // x/0 is always exceptional
04339       if (ISZERO(lhs)) {
04340         decNumberZero(res);             // [after lhs test]
04341         *status|=DEC_Division_undefined;// 0/0 will become NaN
04342         }
04343        else {
04344         decNumberZero(res);
04345         if (op&(REMAINDER|REMNEAR)) *status|=DEC_Invalid_operation;
04346          else {
04347           *status|=DEC_Division_by_zero; // x/0
04348           res->bits=bits|DECINF;         // .. is +/- Infinity
04349           }
04350         }
04351       break;}
04352 
04353     // handle 0 lhs (0/x)
04354     if (ISZERO(lhs)) {                  // 0/x [x!=0]
04355       #if DECSUBSET
04356       if (!set->extended) decNumberZero(res);
04357        else {
04358       #endif
04359         if (op&DIVIDE) {
04360           residue=0;
04361           exponent=lhs->exponent-rhs->exponent; // ideal exponent
04362           decNumberCopy(res, lhs);      // [zeros always fit]
04363           res->bits=bits;               // sign as computed
04364           res->exponent=exponent;       // exponent, too
04365           decFinalize(res, set, &residue, status);   // check exponent
04366           }
04367          else if (op&DIVIDEINT) {
04368           decNumberZero(res);           // integer 0
04369           res->bits=bits;               // sign as computed
04370           }
04371          else {                         // a remainder
04372           exponent=rhs->exponent;       // [save in case overwrite]
04373           decNumberCopy(res, lhs);      // [zeros always fit]
04374           if (exponent<res->exponent) res->exponent=exponent; // use lower
04375           }
04376       #if DECSUBSET
04377         }
04378       #endif
04379       break;}
04380 
04381     // Precalculate exponent.  This starts off adjusted (and hence fits
04382     // in 31 bits) and becomes the usual unadjusted exponent as the
04383     // division proceeds.  The order of evaluation is important, here,
04384     // to avoid wrap.
04385     exponent=(lhs->exponent+lhs->digits)-(rhs->exponent+rhs->digits);
04386 
04387     // If the working exponent is -ve, then some quick exits are
04388     // possible because the quotient is known to be <1
04389     // [for REMNEAR, it needs to be < -1, as -0.5 could need work]
04390     if (exponent<0 && !(op==DIVIDE)) {
04391       if (op&DIVIDEINT) {
04392         decNumberZero(res);                  // integer part is 0
04393         #if DECSUBSET
04394         if (set->extended)
04395         #endif
04396           res->bits=bits;                    // set +/- zero
04397         break;}
04398       // fastpath remainders so long as the lhs has the smaller
04399       // (or equal) exponent
04400       if (lhs->exponent<=rhs->exponent) {
04401         if (op&REMAINDER || exponent<-1) {
04402           // It is REMAINDER or safe REMNEAR; result is [finished
04403           // clone of] lhs  (r = x - 0*y)
04404           residue=0;
04405           decCopyFit(res, lhs, set, &residue, status);
04406           decFinish(res, set, &residue, status);
04407           break;
04408           }
04409         // [unsafe REMNEAR drops through]
04410         }
04411       } // fastpaths
04412 
04413     /* Long (slow) division is needed; roll up the sleeves... */
04414 
04415     // The accumulator will hold the quotient of the division.
04416     // If it needs to be too long for stack storage, then allocate.
04417     acclength=D2U(reqdigits+DECDPUN);   // in Units
04418     if (acclength*sizeof(Unit)>sizeof(accbuff)) {
04419       // printf("malloc dvacc %ld units\n", acclength);
04420       allocacc=(Unit *)malloc(acclength*sizeof(Unit));
04421       if (allocacc==NULL) {             // hopeless -- abandon
04422         *status|=DEC_Insufficient_storage;
04423         break;}
04424       acc=allocacc;                     // use the allocated space
04425       }
04426 
04427     // var1 is the padded LHS ready for subtractions.
04428     // If it needs to be too long for stack storage, then allocate.
04429     // The maximum units needed for var1 (long subtraction) is:
04430     // Enough for
04431     //     (rhs->digits+reqdigits-1) -- to allow full slide to right
04432     // or  (lhs->digits)             -- to allow for long lhs
04433     // whichever is larger
04434     //   +1                -- for rounding of slide to right
04435     //   +1                -- for leading 0s
04436     //   +1                -- for pre-adjust if a remainder or DIVIDEINT
04437     // [Note: unused units do not participate in decUnitAddSub data]
04438     maxdigits=rhs->digits+reqdigits-1;
04439     if (lhs->digits>maxdigits) maxdigits=lhs->digits;
04440     var1units=D2U(maxdigits)+2;
04441     // allocate a guard unit above msu1 for REMAINDERNEAR
04442     if (!(op&DIVIDE)) var1units++;
04443     if ((var1units+1)*sizeof(Unit)>sizeof(varbuff)) {
04444       // printf("malloc dvvar %ld units\n", var1units+1);
04445       varalloc=(Unit *)malloc((var1units+1)*sizeof(Unit));
04446       if (varalloc==NULL) {             // hopeless -- abandon
04447         *status|=DEC_Insufficient_storage;
04448         break;}
04449       var1=varalloc;                    // use the allocated space
04450       }
04451 
04452     // Extend the lhs and rhs to full long subtraction length.  The lhs
04453     // is truly extended into the var1 buffer, with 0 padding, so a
04454     // subtract in place is always possible.  The rhs (var2) has
04455     // virtual padding (implemented by decUnitAddSub).
04456     // One guard unit was allocated above msu1 for rem=rem+rem in
04457     // REMAINDERNEAR.
04458     msu1=var1+var1units-1;              // msu of var1
04459     source=lhs->lsu+D2U(lhs->digits)-1; // msu of input array
04460     for (target=msu1; source>=lhs->lsu; source--, target--) *target=*source;
04461     for (; target>=var1; target--) *target=0;
04462 
04463     // rhs (var2) is left-aligned with var1 at the start
04464     var2ulen=var1units;                 // rhs logical length (units)
04465     var2units=D2U(rhs->digits);         // rhs actual length (units)
04466     var2=rhs->lsu;                      // -> rhs array
04467     msu2=var2+var2units-1;              // -> msu of var2 [never changes]
04468     // now set up the variables which will be used for estimating the
04469     // multiplication factor.  If these variables are not exact, add
04470     // 1 to make sure that the multiplier is never overestimated.
04471     msu2plus=*msu2;                     // it's value ..
04472     if (var2units>1) msu2plus++;        // .. +1 if any more
04473     msu2pair=(eInt)*msu2*(DECDPUNMAX+1);// top two pair ..
04474     if (var2units>1) {                  // .. [else treat 2nd as 0]
04475       msu2pair+=*(msu2-1);              // ..
04476       if (var2units>2) msu2pair++;      // .. +1 if any more
04477       }
04478 
04479     // The calculation is working in units, which may have leading zeros,
04480     // but the exponent was calculated on the assumption that they are
04481     // both left-aligned.  Adjust the exponent to compensate: add the
04482     // number of leading zeros in var1 msu and subtract those in var2 msu.
04483     // [This is actually done by counting the digits and negating, as
04484     // lead1=DECDPUN-digits1, and similarly for lead2.]
04485     for (pow=&powers[1]; *msu1>=*pow; pow++) exponent--;
04486     for (pow=&powers[1]; *msu2>=*pow; pow++) exponent++;
04487 
04488     // Now, if doing an integer divide or remainder, ensure that
04489     // the result will be Unit-aligned.  To do this, shift the var1
04490     // accumulator towards least if need be.  (It's much easier to
04491     // do this now than to reassemble the residue afterwards, if
04492     // doing a remainder.)  Also ensure the exponent is not negative.
04493     if (!(op&DIVIDE)) {
04494       Unit *u;                          // work
04495       // save the initial 'false' padding of var1, in digits
04496       var1initpad=(var1units-D2U(lhs->digits))*DECDPUN;
04497       // Determine the shift to do.
04498       if (exponent<0) cut=-exponent;
04499        else cut=DECDPUN-exponent%DECDPUN;
04500       decShiftToLeast(var1, var1units, cut);
04501       exponent+=cut;                    // maintain numerical value
04502       var1initpad-=cut;                 // .. and reduce padding
04503       // clean any most-significant units which were just emptied
04504       for (u=msu1; cut>=DECDPUN; cut-=DECDPUN, u--) *u=0;
04505       } // align
04506      else { // is DIVIDE
04507       maxexponent=lhs->exponent-rhs->exponent;    // save
04508       // optimization: if the first iteration will just produce 0,
04509       // preadjust to skip it [valid for DIVIDE only]
04510       if (*msu1<*msu2) {
04511         var2ulen--;                     // shift down
04512         exponent-=DECDPUN;              // update the exponent
04513         }
04514       }
04515 
04516     // ---- start the long-division loops ------------------------------
04517     accunits=0;                         // no units accumulated yet
04518     accdigits=0;                        // .. or digits
04519     accnext=acc+acclength-1;            // -> msu of acc [NB: allows digits+1]
04520     for (;;) {                          // outer forever loop
04521       thisunit=0;                       // current unit assumed 0
04522       // find the next unit
04523       for (;;) {                        // inner forever loop
04524         // strip leading zero units [from either pre-adjust or from
04525         // subtract last time around].  Leave at least one unit.
04526         for (; *msu1==0 && msu1>var1; msu1--) var1units--;
04527 
04528         if (var1units<var2ulen) break;       // var1 too low for subtract
04529         if (var1units==var2ulen) {           // unit-by-unit compare needed
04530           // compare the two numbers, from msu
04531           const Unit *pv1, *pv2;
04532           Unit v2;                           // units to compare
04533           pv2=msu2;                          // -> msu
04534           for (pv1=msu1; ; pv1--, pv2--) {
04535             // v1=*pv1 -- always OK
04536             v2=0;                            // assume in padding
04537             if (pv2>=var2) v2=*pv2;          // in range
04538             if (*pv1!=v2) break;             // no longer the same
04539             if (pv1==var1) break;            // done; leave pv1 as is
04540             }
04541           // here when all inspected or a difference seen
04542           if (*pv1<v2) break;                // var1 too low to subtract
04543           if (*pv1==v2) {                    // var1 == var2
04544             // reach here if var1 and var2 are identical; subtraction
04545             // would increase digit by one, and the residue will be 0 so
04546             // the calculation is done; leave the loop with residue=0.
04547             thisunit++;                      // as though subtracted
04548             *var1=0;                         // set var1 to 0
04549             var1units=1;                     // ..
04550             break;  // from inner
04551             } // var1 == var2
04552           // *pv1>v2.  Prepare for real subtraction; the lengths are equal
04553           // Estimate the multiplier (there's always a msu1-1)...
04554           // Bring in two units of var2 to provide a good estimate.
04555           mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2pair);
04556           } // lengths the same
04557          else { // var1units > var2ulen, so subtraction is safe
04558           // The var2 msu is one unit towards the lsu of the var1 msu,
04559           // so only one unit for var2 can be used.
04560           mult=(Int)(((eInt)*msu1*(DECDPUNMAX+1)+*(msu1-1))/msu2plus);
04561           }
04562         if (mult==0) mult=1;                 // must always be at least 1
04563         // subtraction needed; var1 is > var2
04564         thisunit=(Unit)(thisunit+mult);      // accumulate
04565         // subtract var1-var2, into var1; only the overlap needs
04566         // processing, as this is an in-place calculation
04567         shift=var2ulen-var2units;
04568         #if DECTRACE
04569           decDumpAr('1', &var1[shift], var1units-shift);
04570           decDumpAr('2', var2, var2units);
04571           printf("m=%ld\n", -mult);
04572         #endif
04573         decUnitAddSub(&var1[shift], var1units-shift,
04574                       var2, var2units, 0,
04575                       &var1[shift], -mult);
04576         #if DECTRACE
04577           decDumpAr('#', &var1[shift], var1units-shift);
04578         #endif
04579         // var1 now probably has leading zeros; these are removed at the
04580         // top of the inner loop.
04581         } // inner loop
04582 
04583       // The next unit has been calculated in full; unless it's a
04584       // leading zero, add to acc
04585       if (accunits!=0 || thisunit!=0) {      // is first or non-zero
04586         *accnext=thisunit;                   // store in accumulator
04587         // account exactly for the new digits
04588         if (accunits==0) {
04589           accdigits++;                       // at least one
04590           for (pow=&powers[1]; thisunit>=*pow; pow++) accdigits++;
04591           }
04592          else accdigits+=DECDPUN;
04593         accunits++;                          // update count
04594         accnext--;                           // ready for next
04595         if (accdigits>reqdigits) break;      // have enough digits
04596         }
04597 
04598       // if the residue is zero, the operation is done (unless divide
04599       // or divideInteger and still not enough digits yet)
04600       if (*var1==0 && var1units==1) {        // residue is 0
04601         if (op&(REMAINDER|REMNEAR)) break;
04602         if ((op&DIVIDE) && (exponent<=maxexponent)) break;
04603         // [drop through if divideInteger]
04604         }
04605       // also done enough if calculating remainder or integer
04606       // divide and just did the last ('units') unit
04607       if (exponent==0 && !(op&DIVIDE)) break;
04608 
04609       // to get here, var1 is less than var2, so divide var2 by the per-
04610       // Unit power of ten and go for the next digit
04611       var2ulen--;                            // shift down
04612       exponent-=DECDPUN;                     // update the exponent
04613       } // outer loop
04614 
04615     // ---- division is complete ---------------------------------------
04616     // here: acc      has at least reqdigits+1 of good results (or fewer
04617     //                if early stop), starting at accnext+1 (its lsu)
04618     //       var1     has any residue at the stopping point
04619     //       accunits is the number of digits collected in acc
04620     if (accunits==0) {             // acc is 0
04621       accunits=1;                  // show have a unit ..
04622       accdigits=1;                 // ..
04623       *accnext=0;                  // .. whose value is 0
04624       }
04625      else accnext++;               // back to last placed
04626     // accnext now -> lowest unit of result
04627 
04628     residue=0;                     // assume no residue
04629     if (op&DIVIDE) {
04630       // record the presence of any residue, for rounding
04631       if (*var1!=0 || var1units>1) residue=1;
04632        else { // no residue
04633         // Had an exact division; clean up spurious trailing 0s.
04634         // There will be at most DECDPUN-1, from the final multiply,
04635         // and then only if the result is non-0 (and even) and the
04636         // exponent is 'loose'.
04637         #if DECDPUN>1
04638         Unit lsu=*accnext;
04639         if (!(lsu&0x01) && (lsu!=0)) {
04640           // count the trailing zeros
04641           Int drop=0;
04642           for (;; drop++) {    // [will terminate because lsu!=0]
04643             if (exponent>=maxexponent) break;     // don't chop real 0s
04644             #if DECDPUN<=4
04645               if ((lsu-QUOT10(lsu, drop+1)
04646                   *powers[drop+1])!=0) break;     // found non-0 digit
04647             #else
04648               if (lsu%powers[drop+1]!=0) break;   // found non-0 digit
04649             #endif
04650             exponent++;
04651             }
04652           if (drop>0) {
04653             accunits=decShiftToLeast(accnext, accunits, drop);
04654             accdigits=decGetDigits(accnext, accunits);
04655             accunits=D2U(accdigits);
04656             // [exponent was adjusted in the loop]
04657             }
04658           } // neither odd nor 0
04659         #endif
04660         } // exact divide
04661       } // divide
04662      else /* op!=DIVIDE */ {
04663       // check for coefficient overflow
04664       if (accdigits+exponent>reqdigits) {
04665         *status|=DEC_Division_impossible;
04666         break;
04667         }
04668       if (op & (REMAINDER|REMNEAR)) {
04669         // [Here, the exponent will be 0, because var1 was adjusted
04670         // appropriately.]
04671         Int postshift;                       // work
04672         Flag wasodd=0;                       // integer was odd
04673         Unit *quotlsu;                       // for save
04674         Int  quotdigits;                     // ..
04675 
04676         bits=lhs->bits;                      // remainder sign is always as lhs
04677 
04678         // Fastpath when residue is truly 0 is worthwhile [and
04679         // simplifies the code below]
04680         if (*var1==0 && var1units==1) {      // residue is 0
04681           Int exp=lhs->exponent;             // save min(exponents)
04682           if (rhs->exponent<exp) exp=rhs->exponent;
04683           decNumberZero(res);                // 0 coefficient
04684           #if DECSUBSET
04685           if (set->extended)
04686           #endif
04687           res->exponent=exp;                 // .. with proper exponent
04688           res->bits=(uByte)(bits&DECNEG);          // [cleaned]
04689           decFinish(res, set, &residue, status);   // might clamp
04690           break;
04691           }
04692         // note if the quotient was odd
04693         if (*accnext & 0x01) wasodd=1;       // acc is odd
04694         quotlsu=accnext;                     // save in case need to reinspect
04695         quotdigits=accdigits;                // ..
04696 
04697         // treat the residue, in var1, as the value to return, via acc
04698         // calculate the unused zero digits.  This is the smaller of:
04699         //   var1 initial padding (saved above)
04700         //   var2 residual padding, which happens to be given by:
04701         postshift=var1initpad+exponent-lhs->exponent+rhs->exponent;
04702         // [the 'exponent' term accounts for the shifts during divide]
04703         if (var1initpad<postshift) postshift=var1initpad;
04704 
04705         // shift var1 the requested amount, and adjust its digits
04706         var1units=decShiftToLeast(var1, var1units, postshift);
04707         accnext=var1;
04708         accdigits=decGetDigits(var1, var1units);
04709         accunits=D2U(accdigits);
04710 
04711         exponent=lhs->exponent;         // exponent is smaller of lhs & rhs
04712         if (rhs->exponent<exponent) exponent=rhs->exponent;
04713 
04714         // Now correct the result if doing remainderNear; if it
04715         // (looking just at coefficients) is > rhs/2, or == rhs/2 and
04716         // the integer was odd then the result should be rem-rhs.
04717         if (op&REMNEAR) {
04718           Int compare, tarunits;        // work
04719           Unit *up;                     // ..
04720           // calculate remainder*2 into the var1 buffer (which has
04721           // 'headroom' of an extra unit and hence enough space)
04722           // [a dedicated 'double' loop would be faster, here]
04723           tarunits=decUnitAddSub(accnext, accunits, accnext, accunits,
04724                                  0, accnext, 1);
04725           // decDumpAr('r', accnext, tarunits);
04726 
04727           // Here, accnext (var1) holds tarunits Units with twice the
04728           // remainder's coefficient, which must now be compared to the
04729           // RHS.  The remainder's exponent may be smaller than the RHS's.
04730           compare=decUnitCompare(accnext, tarunits, rhs->lsu, D2U(rhs->digits),
04731                                  rhs->exponent-exponent);
04732           if (compare==BADINT) {             // deep trouble
04733             *status|=DEC_Insufficient_storage;
04734             break;}
04735 
04736           // now restore the remainder by dividing by two; the lsu
04737           // is known to be even.
04738           for (up=accnext; up<accnext+tarunits; up++) {
04739             Int half;              // half to add to lower unit
04740             half=*up & 0x01;
04741             *up/=2;                // [shift]
04742             if (!half) continue;
04743             *(up-1)+=(DECDPUNMAX+1)/2;
04744             }
04745           // [accunits still describes the original remainder length]
04746 
04747           if (compare>0 || (compare==0 && wasodd)) { // adjustment needed
04748             Int exp, expunits, exprem;       // work
04749             // This is effectively causing round-up of the quotient,
04750             // so if it was the rare case where it was full and all
04751             // nines, it would overflow and hence division-impossible
04752             // should be raised
04753             Flag allnines=0;                 // 1 if quotient all nines
04754             if (quotdigits==reqdigits) {     // could be borderline
04755               for (up=quotlsu; ; up++) {
04756                 if (quotdigits>DECDPUN) {
04757                   if (*up!=DECDPUNMAX) break;// non-nines
04758                   }
04759                  else {                      // this is the last Unit
04760                   if (*up==powers[quotdigits]-1) allnines=1;
04761                   break;
04762                   }
04763                 quotdigits-=DECDPUN;         // checked those digits
04764                 } // up
04765               } // borderline check
04766             if (allnines) {
04767               *status|=DEC_Division_impossible;
04768               break;}
04769 
04770             // rem-rhs is needed; the sign will invert.  Again, var1
04771             // can safely be used for the working Units array.
04772             exp=rhs->exponent-exponent;      // RHS padding needed
04773             // Calculate units and remainder from exponent.
04774             expunits=exp/DECDPUN;
04775             exprem=exp%DECDPUN;
04776             // subtract [A+B*(-m)]; the result will always be negative
04777             accunits=-decUnitAddSub(accnext, accunits,
04778                                     rhs->lsu, D2U(rhs->digits),
04779                                     expunits, accnext, -(Int)powers[exprem]);
04780             accdigits=decGetDigits(accnext, accunits); // count digits exactly
04781             accunits=D2U(accdigits);    // and recalculate the units for copy
04782             // [exponent is as for original remainder]
04783             bits^=DECNEG;               // flip the sign
04784             }
04785           } // REMNEAR
04786         } // REMAINDER or REMNEAR
04787       } // not DIVIDE
04788 
04789     // Set exponent and bits
04790     res->exponent=exponent;
04791     res->bits=(uByte)(bits&DECNEG);          // [cleaned]
04792 
04793     // Now the coefficient.
04794     decSetCoeff(res, set, accnext, accdigits, &residue, status);
04795 
04796     decFinish(res, set, &residue, status);   // final cleanup
04797 
04798     #if DECSUBSET
04799     // If a divide then strip trailing zeros if subset [after round]
04800     if (!set->extended && (op==DIVIDE)) decTrim(res, set, 0, 1, &dropped);
04801     #endif
04802     } while(0);                              // end protected
04803 
04804   if (varalloc!=NULL) free(varalloc);   // drop any storage used
04805   if (allocacc!=NULL) free(allocacc);   // ..
04806   #if DECSUBSET
04807   if (allocrhs!=NULL) free(allocrhs);   // ..
04808   if (alloclhs!=NULL) free(alloclhs);   // ..
04809   #endif
04810   return res;
04811   } // decDivideOp

decNumber * decExpOp ( decNumber ,
const decNumber ,
decContext ,
uInt *   
) [static]

Définition à la ligne 5240 du fichier decNumber.c.

Références BADINT, decContext::clamp, D2N, D2U, DEC_Inexact, DEC_INIT_DECIMAL64, DEC_Insufficient_storage, DEC_MIN_EMIN, DEC_Overflow, DEC_Rounded, DEC_Underflow, decAddOp(), DECBUFFER, DECCHECK, decCompare(), decContextDefault(), decCopyFit(), decDivideOp(), decFinish, decMultiplyOp(), decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberIsNegative, decNumberZero(), decShiftToMost(), decNumber::digits, decContext::digits, DIVIDE, decContext::emax, decContext::emin, decNumber::exponent, Int, ISZERO, decNumber::lsu, MAXI, MINI, powers, SPECIALARG, et uInt.

Référencé par decLnOp(), decNumberExp(), et decNumberPower().

05241                                                         {
05242   uInt ignore=0;                   // working status
05243   Int h;                           // adjusted exponent for 0.xxxx
05244   Int p;                           // working precision
05245   Int residue;                     // rounding residue
05246   uInt needbytes;                  // for space calculations
05247   const decNumber *x=rhs;          // (may point to safe copy later)
05248   decContext aset, tset, dset;     // working contexts
05249   Int comp;                        // work
05250 
05251   // the argument is often copied to normalize it, so (unusually) it
05252   // is treated like other buffers, using DECBUFFER, +1 in case
05253   // DECBUFFER is 0
05254   decNumber bufr[D2N(DECBUFFER*2+1)];
05255   decNumber *allocrhs=NULL;        // non-NULL if rhs buffer allocated
05256 
05257   // the working precision will be no more than set->digits+8+1
05258   // so for on-stack buffers DECBUFFER+9 is used, +1 in case DECBUFFER
05259   // is 0 (and twice that for the accumulator)
05260 
05261   // buffer for t, term (working precision plus)
05262   decNumber buft[D2N(DECBUFFER*2+9+1)];
05263   decNumber *allocbuft=NULL;       // -> allocated buft, iff allocated
05264   decNumber *t=buft;               // term
05265   // buffer for a, accumulator (working precision * 2), at least 9
05266   decNumber bufa[D2N(DECBUFFER*4+18+1)];
05267   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
05268   decNumber *a=bufa;               // accumulator
05269   // decNumber for the divisor term; this needs at most 9 digits
05270   // and so can be fixed size [16 so can use standard context]
05271   decNumber bufd[D2N(16)];
05272   decNumber *d=bufd;               // divisor
05273   decNumber numone;                // constant 1
05274 
05275   #if DECCHECK
05276   Int iterations=0;                // for later sanity check
05277   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
05278   #endif
05279 
05280   do {                                  // protect allocated storage
05281     if (SPECIALARG) {                   // handle infinities and NaNs
05282       if (decNumberIsInfinite(rhs)) {   // an infinity
05283         if (decNumberIsNegative(rhs))   // -Infinity -> +0
05284           decNumberZero(res);
05285          else decNumberCopy(res, rhs);  // +Infinity -> self
05286         }
05287        else decNaNs(res, rhs, NULL, set, status); // a NaN
05288       break;}
05289 
05290     if (ISZERO(rhs)) {                  // zeros -> exact 1
05291       decNumberZero(res);               // make clean 1
05292       *res->lsu=1;                      // ..
05293       break;}                           // [no status to set]
05294 
05295     // e**x when 0 < x < 0.66 is < 1+3x/2, hence can fast-path
05296     // positive and negative tiny cases which will result in inexact
05297     // 1.  This also allows the later add-accumulate to always be
05298     // exact (because its length will never be more than twice the
05299     // working precision).
05300     // The comparator (tiny) needs just one digit, so use the
05301     // decNumber d for it (reused as the divisor, etc., below); its
05302     // exponent is such that if x is positive it will have
05303     // set->digits-1 zeros between the decimal point and the digit,
05304     // which is 4, and if x is negative one more zero there as the
05305     // more precise result will be of the form 0.9999999 rather than
05306     // 1.0000001.  Hence, tiny will be 0.0000004  if digits=7 and x>0
05307     // or 0.00000004 if digits=7 and x<0.  If RHS not larger than
05308     // this then the result will be 1.000000
05309     decNumberZero(d);                   // clean
05310     *d->lsu=4;                          // set 4 ..
05311     d->exponent=-set->digits;           // * 10**(-d)
05312     if (decNumberIsNegative(rhs)) d->exponent--;  // negative case
05313     comp=decCompare(d, rhs, 1);         // signless compare
05314     if (comp==BADINT) {
05315       *status|=DEC_Insufficient_storage;
05316       break;}
05317     if (comp>=0) {                      // rhs < d
05318       Int shift=set->digits-1;
05319       decNumberZero(res);               // set 1
05320       *res->lsu=1;                      // ..
05321       res->digits=decShiftToMost(res->lsu, 1, shift);
05322       res->exponent=-shift;                  // make 1.0000...
05323       *status|=DEC_Inexact | DEC_Rounded;    // .. inexactly
05324       break;} // tiny
05325 
05326     // set up the context to be used for calculating a, as this is
05327     // used on both paths below
05328     decContextDefault(&aset, DEC_INIT_DECIMAL64);
05329     // accumulator bounds are as requested (could underflow)
05330     aset.emax=set->emax;                // usual bounds
05331     aset.emin=set->emin;                // ..
05332     aset.clamp=0;                       // and no concrete format
05333 
05334     // calculate the adjusted (Hull & Abrham) exponent (where the
05335     // decimal point is just to the left of the coefficient msd)
05336     h=rhs->exponent+rhs->digits;
05337     // if h>8 then 10**h cannot be calculated safely; however, when
05338     // h=8 then exp(|rhs|) will be at least exp(1E+7) which is at
05339     // least 6.59E+4342944, so (due to the restriction on Emax/Emin)
05340     // overflow (or underflow to 0) is guaranteed -- so this case can
05341     // be handled by simply forcing the appropriate excess
05342     if (h>8) {                          // overflow/underflow
05343       // set up here so Power call below will over or underflow to
05344       // zero; set accumulator to either 2 or 0.02
05345       // [stack buffer for a is always big enough for this]
05346       decNumberZero(a);
05347       *a->lsu=2;                        // not 1 but < exp(1)
05348       if (decNumberIsNegative(rhs)) a->exponent=-2; // make 0.02
05349       h=8;                              // clamp so 10**h computable
05350       p=9;                              // set a working precision
05351       }
05352      else {                             // h<=8
05353       Int maxlever=(rhs->digits>8?1:0);
05354       // [could/should increase this for precisions >40 or so, too]
05355 
05356       // if h is 8, cannot normalize to a lower upper limit because
05357       // the final result will not be computable (see notes above),
05358       // but leverage can be applied whenever h is less than 8.
05359       // Apply as much as possible, up to a MAXLEVER digits, which
05360       // sets the tradeoff against the cost of the later a**(10**h).
05361       // As h is increased, the working precision below also
05362       // increases to compensate for the "constant digits at the
05363       // front" effect.
05364       Int lever=MINI(8-h, maxlever);    // leverage attainable
05365       Int use=-rhs->digits-lever;       // exponent to use for RHS
05366       h+=lever;                         // apply leverage selected
05367       if (h<0) {                        // clamp
05368         use+=h;                         // [may end up subnormal]
05369         h=0;
05370         }
05371       // Take a copy of RHS if it needs normalization (true whenever x>=1)
05372       if (rhs->exponent!=use) {
05373         decNumber *newrhs=bufr;         // assume will fit on stack
05374         needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
05375         if (needbytes>sizeof(bufr)) {   // need malloc space
05376           allocrhs=(decNumber *)malloc(needbytes);
05377           if (allocrhs==NULL) {         // hopeless -- abandon
05378             *status|=DEC_Insufficient_storage;
05379             break;}
05380           newrhs=allocrhs;              // use the allocated space
05381           }
05382         decNumberCopy(newrhs, rhs);     // copy to safe space
05383         newrhs->exponent=use;           // normalize; now <1
05384         x=newrhs;                       // ready for use
05385         // decNumberShow(x);
05386         }
05387 
05388       // Now use the usual power series to evaluate exp(x).  The
05389       // series starts as 1 + x + x^2/2 ... so prime ready for the
05390       // third term by setting the term variable t=x, the accumulator
05391       // a=1, and the divisor d=2.
05392 
05393       // First determine the working precision.  From Hull & Abrham
05394       // this is set->digits+h+2.  However, if x is 'over-precise' we
05395       // need to allow for all its digits to potentially participate
05396       // (consider an x where all the excess digits are 9s) so in
05397       // this case use x->digits+h+2
05398       p=MAXI(x->digits, set->digits)+h+2;    // [h<=8]
05399 
05400       // a and t are variable precision, and depend on p, so space
05401       // must be allocated for them if necessary
05402 
05403       // the accumulator needs to be able to hold 2p digits so that
05404       // the additions on the second and subsequent iterations are
05405       // sufficiently exact.
05406       needbytes=sizeof(decNumber)+(D2U(p*2)-1)*sizeof(Unit);
05407       if (needbytes>sizeof(bufa)) {     // need malloc space
05408         allocbufa=(decNumber *)malloc(needbytes);
05409         if (allocbufa==NULL) {          // hopeless -- abandon
05410           *status|=DEC_Insufficient_storage;
05411           break;}
05412         a=allocbufa;                    // use the allocated space
05413         }
05414       // the term needs to be able to hold p digits (which is
05415       // guaranteed to be larger than x->digits, so the initial copy
05416       // is safe); it may also be used for the raise-to-power
05417       // calculation below, which needs an extra two digits
05418       needbytes=sizeof(decNumber)+(D2U(p+2)-1)*sizeof(Unit);
05419       if (needbytes>sizeof(buft)) {     // need malloc space
05420         allocbuft=(decNumber *)malloc(needbytes);
05421         if (allocbuft==NULL) {          // hopeless -- abandon
05422           *status|=DEC_Insufficient_storage;
05423           break;}
05424         t=allocbuft;                    // use the allocated space
05425         }
05426 
05427       decNumberCopy(t, x);              // term=x
05428       decNumberZero(a); *a->lsu=1;      // accumulator=1
05429       decNumberZero(d); *d->lsu=2;      // divisor=2
05430       decNumberZero(&numone); *numone.lsu=1; // constant 1 for increment
05431 
05432       // set up the contexts for calculating a, t, and d
05433       decContextDefault(&tset, DEC_INIT_DECIMAL64);
05434       dset=tset;
05435       // accumulator bounds are set above, set precision now
05436       aset.digits=p*2;                  // double
05437       // term bounds avoid any underflow or overflow
05438       tset.digits=p;
05439       tset.emin=DEC_MIN_EMIN;           // [emax is plenty]
05440       // [dset.digits=16, etc., are sufficient]
05441 
05442       // finally ready to roll
05443       for (;;) {
05444         #if DECCHECK
05445         iterations++;
05446         #endif
05447         // only the status from the accumulation is interesting
05448         // [but it should remain unchanged after first add]
05449         decAddOp(a, a, t, &aset, 0, status);           // a=a+t
05450         decMultiplyOp(t, t, x, &tset, &ignore);        // t=t*x
05451         decDivideOp(t, t, d, &tset, DIVIDE, &ignore);  // t=t/d
05452         // the iteration ends when the term cannot affect the result,
05453         // if rounded to p digits, which is when its value is smaller
05454         // than the accumulator by p+1 digits.  There must also be
05455         // full precision in a.
05456         if (((a->digits+a->exponent)>=(t->digits+t->exponent+p+1))
05457             && (a->digits>=p)) break;
05458         decAddOp(d, d, &numone, &dset, 0, &ignore);    // d=d+1
05459         } // iterate
05460 
05461       #if DECCHECK
05462       // just a sanity check; comment out test to show always
05463       if (iterations>p+3)
05464         printf("Exp iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
05465                (LI)iterations, (LI)*status, (LI)p, (LI)x->digits);
05466       #endif
05467       } // h<=8
05468 
05469     // apply postconditioning: a=a**(10**h) -- this is calculated
05470     // at a slightly higher precision than Hull & Abrham suggest
05471     if (h>0) {
05472       Int seenbit=0;               // set once a 1-bit is seen
05473       Int i;                       // counter
05474       Int n=powers[h];             // always positive
05475       aset.digits=p+2;             // sufficient precision
05476       // avoid the overhead and many extra digits of decNumberPower
05477       // as all that is needed is the short 'multipliers' loop; here
05478       // accumulate the answer into t
05479       decNumberZero(t); *t->lsu=1; // acc=1
05480       for (i=1;;i++){              // for each bit [top bit ignored]
05481         // abandon if have had overflow or terminal underflow
05482         if (*status & (DEC_Overflow|DEC_Underflow)) { // interesting?
05483           if (*status&DEC_Overflow || ISZERO(t)) break;}
05484         n=n<<1;                    // move next bit to testable position
05485         if (n<0) {                 // top bit is set
05486           seenbit=1;               // OK, have a significant bit
05487           decMultiplyOp(t, t, a, &aset, status); // acc=acc*x
05488           }
05489         if (i==31) break;          // that was the last bit
05490         if (!seenbit) continue;    // no need to square 1
05491         decMultiplyOp(t, t, t, &aset, status); // acc=acc*acc [square]
05492         } /*i*/ // 32 bits
05493       // decNumberShow(t);
05494       a=t;                         // and carry on using t instead of a
05495       }
05496 
05497     // Copy and round the result to res
05498     residue=1;                          // indicate dirt to right ..
05499     if (ISZERO(a)) residue=0;           // .. unless underflowed to 0
05500     aset.digits=set->digits;            // [use default rounding]
05501     decCopyFit(res, a, &aset, &residue, status); // copy & shorten
05502     decFinish(res, set, &residue, status);       // cleanup/set flags
05503     } while(0);                         // end protected
05504 
05505   if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
05506   if (allocbufa!=NULL) free(allocbufa); // ..
05507   if (allocbuft!=NULL) free(allocbuft); // ..
05508   // [status is handled by caller]
05509   return res;
05510   } // decExpOp

static void decFinalize ( decNumber ,
decContext ,
Int *  ,
uInt *   
) [static]

Définition à la ligne 7287 du fichier decNumber.c.

Références BADINT, decContext::clamp, DEC_Clamped, DEC_Insufficient_storage, decApplyRound(), decCompare(), decNumberZero(), decSetOverflow(), decSetSubnormal(), decShiftToMost(), decContext::digits, decNumber::digits, decContext::emax, decContext::emin, decNumber::exponent, Int, ISZERO, et decNumber::lsu.

Référencé par decDivideOp(), decNumberPower(), decNumberScaleB(), et decQuantizeOp().

07288                                       {
07289   Int shift;                            // shift needed if clamping
07290   Int tinyexp=set->emin-dn->digits+1;   // precalculate subnormal boundary
07291 
07292   // Must be careful, here, when checking the exponent as the
07293   // adjusted exponent could overflow 31 bits [because it may already
07294   // be up to twice the expected].
07295 
07296   // First test for subnormal.  This must be done before any final
07297   // round as the result could be rounded to Nmin or 0.
07298   if (dn->exponent<=tinyexp) {          // prefilter
07299     Int comp;
07300     decNumber nmin;
07301     // A very nasty case here is dn == Nmin and residue<0
07302     if (dn->exponent<tinyexp) {
07303       // Go handle subnormals; this will apply round if needed.
07304       decSetSubnormal(dn, set, residue, status);
07305       return;
07306       }
07307     // Equals case: only subnormal if dn=Nmin and negative residue
07308     decNumberZero(&nmin);
07309     nmin.lsu[0]=1;
07310     nmin.exponent=set->emin;
07311     comp=decCompare(dn, &nmin, 1);                // (signless compare)
07312     if (comp==BADINT) {                           // oops
07313       *status|=DEC_Insufficient_storage;          // abandon...
07314       return;
07315       }
07316     if (*residue<0 && comp==0) {                  // neg residue and dn==Nmin
07317       decApplyRound(dn, set, *residue, status);   // might force down
07318       decSetSubnormal(dn, set, residue, status);
07319       return;
07320       }
07321     }
07322 
07323   // now apply any pending round (this could raise overflow).
07324   if (*residue!=0) decApplyRound(dn, set, *residue, status);
07325 
07326   // Check for overflow [redundant in the 'rare' case] or clamp
07327   if (dn->exponent<=set->emax-set->digits+1) return;   // neither needed
07328 
07329 
07330   // here when might have an overflow or clamp to do
07331   if (dn->exponent>set->emax-dn->digits+1) {           // too big
07332     decSetOverflow(dn, set, status);
07333     return;
07334     }
07335   // here when the result is normal but in clamp range
07336   if (!set->clamp) return;
07337 
07338   // here when need to apply the IEEE exponent clamp (fold-down)
07339   shift=dn->exponent-(set->emax-set->digits+1);
07340 
07341   // shift coefficient (if non-zero)
07342   if (!ISZERO(dn)) {
07343     dn->digits=decShiftToMost(dn->lsu, dn->digits, shift);
07344     }
07345   dn->exponent-=shift;   // adjust the exponent to match
07346   *status|=DEC_Clamped;  // and record the dirty deed
07347   return;
07348   } // decFinalize

static Int decGetDigits ( Unit *  ,
Int   
) [static]

Définition à la ligne 7780 du fichier decNumber.c.

Références DECDPUN, Int, pow(), et uInt.

Référencé par decAddOp(), decDecap(), decDivideOp(), decMultiplyOp(), decNumberAnd(), decNumberFromUInt32(), decNumberInvert(), decNumberOr(), decNumberRotate(), et decNumberXor().

07780                                             {
07781   Unit *up=uar+(len-1);            // -> msu
07782   Int  digits=(len-1)*DECDPUN+1;   // possible digits excluding msu
07783   #if DECDPUN>4
07784   uInt const *pow;                 // work
07785   #endif
07786                                    // (at least 1 in final msu)
07787   #if DECCHECK
07788   if (len<1) printf("decGetDigits called with len<1 [%ld]\n", (LI)len);
07789   #endif
07790 
07791   for (; up>=uar; up--) {
07792     if (*up==0) {                  // unit is all 0s
07793       if (digits==1) break;        // a zero has one digit
07794       digits-=DECDPUN;             // adjust for 0 unit
07795       continue;}
07796     // found the first (most significant) non-zero Unit
07797     #if DECDPUN>1                  // not done yet
07798     if (*up<10) break;             // is 1-9
07799     digits++;
07800     #if DECDPUN>2                  // not done yet
07801     if (*up<100) break;            // is 10-99
07802     digits++;
07803     #if DECDPUN>3                  // not done yet
07804     if (*up<1000) break;           // is 100-999
07805     digits++;
07806     #if DECDPUN>4                  // count the rest ...
07807     for (pow=&powers[4]; *up>=*pow; pow++) digits++;
07808     #endif
07809     #endif
07810     #endif
07811     #endif
07812     break;
07813     } // up
07814   return digits;
07815   } // decGetDigits

static Int decGetInt ( const decNumber  )  [static]

Définition à la ligne 7555 du fichier decNumber.c.

Références BADINT, BIGEVEN, BIGODD, DECDPUN, decNumberIsNegative, decNumber::digits, decNumber::exponent, Flag, Int, ISZERO, decNumber::lsu, et QUOT10.

Référencé par decLnOp(), decNumberPower(), decNumberRotate(), decNumberScaleB(), decNumberShift(), et decQuantizeOp().

07555                                           {
07556   Int  theInt;                          // result accumulator
07557   const Unit *up;                       // work
07558   Int  got;                             // digits (real or not) processed
07559   Int  ilength=dn->digits+dn->exponent; // integral length
07560   Flag neg=decNumberIsNegative(dn);     // 1 if -ve
07561 
07562   // The number must be an integer that fits in 10 digits
07563   // Assert, here, that 10 is enough for any rescale Etiny
07564   #if DEC_MAX_EMAX > 999999999
07565     #error GetInt may need updating [for Emax]
07566   #endif
07567   #if DEC_MIN_EMIN < -999999999
07568     #error GetInt may need updating [for Emin]
07569   #endif
07570   if (ISZERO(dn)) return 0;             // zeros are OK, with any exponent
07571 
07572   up=dn->lsu;                           // ready for lsu
07573   theInt=0;                             // ready to accumulate
07574   if (dn->exponent>=0) {                // relatively easy
07575     // no fractional part [usual]; allow for positive exponent
07576     got=dn->exponent;
07577     }
07578    else { // -ve exponent; some fractional part to check and discard
07579     Int count=-dn->exponent;            // digits to discard
07580     // spin up whole units until reach the Unit with the unit digit
07581     for (; count>=DECDPUN; up++) {
07582       if (*up!=0) return BADINT;        // non-zero Unit to discard
07583       count-=DECDPUN;
07584       }
07585     if (count==0) got=0;                // [a multiple of DECDPUN]
07586      else {                             // [not multiple of DECDPUN]
07587       Int rem;                          // work
07588       // slice off fraction digits and check for non-zero
07589       #if DECDPUN<=4
07590         theInt=QUOT10(*up, count);
07591         rem=*up-theInt*powers[count];
07592       #else
07593         rem=*up%powers[count];          // slice off discards
07594         theInt=*up/powers[count];
07595       #endif
07596       if (rem!=0) return BADINT;        // non-zero fraction
07597       // it looks good
07598       got=DECDPUN-count;                // number of digits so far
07599       up++;                             // ready for next
07600       }
07601     }
07602   // now it's known there's no fractional part
07603 
07604   // tricky code now, to accumulate up to 9.3 digits
07605   if (got==0) {theInt=*up; got+=DECDPUN; up++;} // ensure lsu is there
07606 
07607   if (ilength<11) {
07608     Int save=theInt;
07609     // collect any remaining unit(s)
07610     for (; got<ilength; up++) {
07611       theInt+=*up*powers[got];
07612       got+=DECDPUN;
07613       }
07614     if (ilength==10) {                  // need to check for wrap
07615       if (theInt/(Int)powers[got-DECDPUN]!=(Int)*(up-1)) ilength=11;
07616          // [that test also disallows the BADINT result case]
07617        else if (neg && theInt>1999999997) ilength=11;
07618        else if (!neg && theInt>999999999) ilength=11;
07619       if (ilength==11) theInt=save;     // restore correct low bit
07620       }
07621     }
07622 
07623   if (ilength>10) {                     // too big
07624     if (theInt&1) return BIGODD;        // bottom bit 1
07625     return BIGEVEN;                     // bottom bit 0
07626     }
07627 
07628   if (neg) theInt=-theInt;              // apply sign
07629   return theInt;
07630   } // decGetInt

decNumber * decLnOp ( decNumber ,
const decNumber ,
decContext ,
uInt *   
) [static]

Définition à la ligne 5600 du fichier decNumber.c.

Références decNumber::bits, decContext::clamp, COMPARE, D2N, D2U, DEC_Inexact, DEC_INIT_DECIMAL64, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_MAX_MATH, DEC_ROUND_DOWN, DEC_ROUND_HALF_EVEN, DEC_Rounded, decAddOp(), DECBUFFER, DECCHECK, decCompareOp(), decContextDefault(), decCopyFit(), decExpOp(), decFinish, decGetInt(), DECINF, decMultiplyOp(), decNaNs(), DECNEG, decNumberCopy(), decNumberFromInt32(), decNumberFromString(), decNumberIsInfinite, decNumberIsNegative, decNumberIsZero, decNumberZero(), decNumber::digits, decContext::digits, decContext::emax, decContext::emin, decNumber::exponent, Int, ISZERO, LN10, LN2, decNumber::lsu, MAXI, decContext::round, SPECIALARG, uInt, et X10.

Référencé par decNumberLn(), decNumberLog10(), et decNumberPower().

05601                                                    {
05602   uInt ignore=0;                   // working status accumulator
05603   uInt needbytes;                  // for space calculations
05604   Int residue;                     // rounding residue
05605   Int r;                           // rhs=f*10**r [see below]
05606   Int p;                           // working precision
05607   Int pp;                          // precision for iteration
05608   Int t;                           // work
05609 
05610   // buffers for a (accumulator, typically precision+2) and b
05611   // (adjustment calculator, same size)
05612   decNumber bufa[D2N(DECBUFFER+12)];
05613   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
05614   decNumber *a=bufa;               // accumulator/work
05615   decNumber bufb[D2N(DECBUFFER*2+2)];
05616   decNumber *allocbufb=NULL;       // -> allocated bufa, iff allocated
05617   decNumber *b=bufb;               // adjustment/work
05618 
05619   decNumber  numone;               // constant 1
05620   decNumber  cmp;                  // work
05621   decContext aset, bset;           // working contexts
05622 
05623   #if DECCHECK
05624   Int iterations=0;                // for later sanity check
05625   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
05626   #endif
05627 
05628   do {                                  // protect allocated storage
05629     if (SPECIALARG) {                   // handle infinities and NaNs
05630       if (decNumberIsInfinite(rhs)) {   // an infinity
05631         if (decNumberIsNegative(rhs))   // -Infinity -> error
05632           *status|=DEC_Invalid_operation;
05633          else decNumberCopy(res, rhs);  // +Infinity -> self
05634         }
05635        else decNaNs(res, rhs, NULL, set, status); // a NaN
05636       break;}
05637 
05638     if (ISZERO(rhs)) {                  // +/- zeros -> -Infinity
05639       decNumberZero(res);               // make clean
05640       res->bits=DECINF|DECNEG;          // set - infinity
05641       break;}                           // [no status to set]
05642 
05643     // Non-zero negatives are bad...
05644     if (decNumberIsNegative(rhs)) {     // -x -> error
05645       *status|=DEC_Invalid_operation;
05646       break;}
05647 
05648     // Here, rhs is positive, finite, and in range
05649 
05650     // lookaside fastpath code for ln(2) and ln(10) at common lengths
05651     if (rhs->exponent==0 && set->digits<=40) {
05652       #if DECDPUN==1
05653       if (rhs->lsu[0]==0 && rhs->lsu[1]==1 && rhs->digits==2) { // ln(10)
05654       #else
05655       if (rhs->lsu[0]==10 && rhs->digits==2) {                  // ln(10)
05656       #endif
05657         aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
05658         #define LN10 "2.302585092994045684017991454684364207601"
05659         decNumberFromString(res, LN10, &aset);
05660         *status|=(DEC_Inexact | DEC_Rounded); // is inexact
05661         break;}
05662       if (rhs->lsu[0]==2 && rhs->digits==1) { // ln(2)
05663         aset=*set; aset.round=DEC_ROUND_HALF_EVEN;
05664         #define LN2 "0.6931471805599453094172321214581765680755"
05665         decNumberFromString(res, LN2, &aset);
05666         *status|=(DEC_Inexact | DEC_Rounded);
05667         break;}
05668       } // integer and short
05669 
05670     // Determine the working precision.  This is normally the
05671     // requested precision + 2, with a minimum of 9.  However, if
05672     // the rhs is 'over-precise' then allow for all its digits to
05673     // potentially participate (consider an rhs where all the excess
05674     // digits are 9s) so in this case use rhs->digits+2.
05675     p=MAXI(rhs->digits, MAXI(set->digits, 7))+2;
05676 
05677     // Allocate space for the accumulator and the high-precision
05678     // adjustment calculator, if necessary.  The accumulator must
05679     // be able to hold p digits, and the adjustment up to
05680     // rhs->digits+p digits.  They are also made big enough for 16
05681     // digits so that they can be used for calculating the initial
05682     // estimate.
05683     needbytes=sizeof(decNumber)+(D2U(MAXI(p,16))-1)*sizeof(Unit);
05684     if (needbytes>sizeof(bufa)) {     // need malloc space
05685       allocbufa=(decNumber *)malloc(needbytes);
05686       if (allocbufa==NULL) {          // hopeless -- abandon
05687         *status|=DEC_Insufficient_storage;
05688         break;}
05689       a=allocbufa;                    // use the allocated space
05690       }
05691     pp=p+rhs->digits;
05692     needbytes=sizeof(decNumber)+(D2U(MAXI(pp,16))-1)*sizeof(Unit);
05693     if (needbytes>sizeof(bufb)) {     // need malloc space
05694       allocbufb=(decNumber *)malloc(needbytes);
05695       if (allocbufb==NULL) {          // hopeless -- abandon
05696         *status|=DEC_Insufficient_storage;
05697         break;}
05698       b=allocbufb;                    // use the allocated space
05699       }
05700 
05701     // Prepare an initial estimate in acc. Calculate this by
05702     // considering the coefficient of x to be a normalized fraction,
05703     // f, with the decimal point at far left and multiplied by
05704     // 10**r.  Then, rhs=f*10**r and 0.1<=f<1, and
05705     //   ln(x) = ln(f) + ln(10)*r
05706     // Get the initial estimate for ln(f) from a small lookup
05707     // table (see above) indexed by the first two digits of f,
05708     // truncated.
05709 
05710     decContextDefault(&aset, DEC_INIT_DECIMAL64); // 16-digit extended
05711     r=rhs->exponent+rhs->digits;        // 'normalised' exponent
05712     decNumberFromInt32(a, r);           // a=r
05713     decNumberFromInt32(b, 2302585);     // b=ln(10) (2.302585)
05714     b->exponent=-6;                     //  ..
05715     decMultiplyOp(a, a, b, &aset, &ignore);  // a=a*b
05716     // now get top two digits of rhs into b by simple truncate and
05717     // force to integer
05718     residue=0;                          // (no residue)
05719     aset.digits=2; aset.round=DEC_ROUND_DOWN;
05720     decCopyFit(b, rhs, &aset, &residue, &ignore); // copy & shorten
05721     b->exponent=0;                      // make integer
05722     t=decGetInt(b);                     // [cannot fail]
05723     if (t<10) t=X10(t);                 // adjust single-digit b
05724     t=LNnn[t-10];                       // look up ln(b)
05725     decNumberFromInt32(b, t>>2);        // b=ln(b) coefficient
05726     b->exponent=-(t&3)-3;               // set exponent
05727     b->bits=DECNEG;                     // ln(0.10)->ln(0.99) always -ve
05728     aset.digits=16; aset.round=DEC_ROUND_HALF_EVEN; // restore
05729     decAddOp(a, a, b, &aset, 0, &ignore); // acc=a+b
05730     // the initial estimate is now in a, with up to 4 digits correct.
05731     // When rhs is at or near Nmax the estimate will be low, so we
05732     // will approach it from below, avoiding overflow when calling exp.
05733 
05734     decNumberZero(&numone); *numone.lsu=1;   // constant 1 for adjustment
05735 
05736     // accumulator bounds are as requested (could underflow, but
05737     // cannot overflow)
05738     aset.emax=set->emax;
05739     aset.emin=set->emin;
05740     aset.clamp=0;                       // no concrete format
05741     // set up a context to be used for the multiply and subtract
05742     bset=aset;
05743     bset.emax=DEC_MAX_MATH*2;           // use double bounds for the
05744     bset.emin=-DEC_MAX_MATH*2;          // adjustment calculation
05745                                         // [see decExpOp call below]
05746     // for each iteration double the number of digits to calculate,
05747     // up to a maximum of p
05748     pp=9;                               // initial precision
05749     // [initially 9 as then the sequence starts 7+2, 16+2, and
05750     // 34+2, which is ideal for standard-sized numbers]
05751     aset.digits=pp;                     // working context
05752     bset.digits=pp+rhs->digits;         // wider context
05753     for (;;) {                          // iterate
05754       #if DECCHECK
05755       iterations++;
05756       if (iterations>24) break;         // consider 9 * 2**24
05757       #endif
05758       // calculate the adjustment (exp(-a)*x-1) into b.  This is a
05759       // catastrophic subtraction but it really is the difference
05760       // from 1 that is of interest.
05761       // Use the internal entry point to Exp as it allows the double
05762       // range for calculating exp(-a) when a is the tiniest subnormal.
05763       a->bits^=DECNEG;                  // make -a
05764       decExpOp(b, a, &bset, &ignore);   // b=exp(-a)
05765       a->bits^=DECNEG;                  // restore sign of a
05766       // now multiply by rhs and subtract 1, at the wider precision
05767       decMultiplyOp(b, b, rhs, &bset, &ignore);        // b=b*rhs
05768       decAddOp(b, b, &numone, &bset, DECNEG, &ignore); // b=b-1
05769 
05770       // the iteration ends when the adjustment cannot affect the
05771       // result by >=0.5 ulp (at the requested digits), which
05772       // is when its value is smaller than the accumulator by
05773       // set->digits+1 digits (or it is zero) -- this is a looser
05774       // requirement than for Exp because all that happens to the
05775       // accumulator after this is the final rounding (but note that
05776       // there must also be full precision in a, or a=0).
05777 
05778       if (decNumberIsZero(b) ||
05779           (a->digits+a->exponent)>=(b->digits+b->exponent+set->digits+1)) {
05780         if (a->digits==p) break;
05781         if (decNumberIsZero(a)) {
05782           decCompareOp(&cmp, rhs, &numone, &aset, COMPARE, &ignore); // rhs=1 ?
05783           if (cmp.lsu[0]==0) a->exponent=0;            // yes, exact 0
05784            else *status|=(DEC_Inexact | DEC_Rounded);  // no, inexact
05785           break;
05786           }
05787         // force padding if adjustment has gone to 0 before full length
05788         if (decNumberIsZero(b)) b->exponent=a->exponent-p;
05789         }
05790 
05791       // not done yet ...
05792       decAddOp(a, a, b, &aset, 0, &ignore);  // a=a+b for next estimate
05793       if (pp==p) continue;                   // precision is at maximum
05794       // lengthen the next calculation
05795       pp=pp*2;                               // double precision
05796       if (pp>p) pp=p;                        // clamp to maximum
05797       aset.digits=pp;                        // working context
05798       bset.digits=pp+rhs->digits;            // wider context
05799       } // Newton's iteration
05800 
05801     #if DECCHECK
05802     // just a sanity check; remove the test to show always
05803     if (iterations>24)
05804       printf("Ln iterations=%ld, status=%08lx, p=%ld, d=%ld\n",
05805             (LI)iterations, (LI)*status, (LI)p, (LI)rhs->digits);
05806     #endif
05807 
05808     // Copy and round the result to res
05809     residue=1;                          // indicate dirt to right
05810     if (ISZERO(a)) residue=0;           // .. unless underflowed to 0
05811     aset.digits=set->digits;            // [use default rounding]
05812     decCopyFit(res, a, &aset, &residue, status); // copy & shorten
05813     decFinish(res, set, &residue, status);       // cleanup/set flags
05814     } while(0);                         // end protected
05815 
05816   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
05817   if (allocbufb!=NULL) free(allocbufb); // ..
05818   // [status is handled by caller]
05819   return res;
05820   } // decLnOp

static decNumber * decMultiplyOp ( decNumber ,
const decNumber ,
const decNumber ,
decContext ,
uInt *   
) [static]

Définition à la ligne 4850 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Insufficient_storage, DEC_Invalid_operation, DECBUFFER, DECDPUN, decFinish, decGetDigits(), DECINF, DECNAN, decNaNs(), DECNEG, decNumberZero(), DECNUMMAXE, decSetCoeff(), DECSNAN, decUnitAddSub(), decContext::digits, decNumber::digits, decNumber::exponent, FASTBASE, FASTDIGS, FASTLAZY, Int, ISZERO, decNumber::lsu, NEEDTWO, powers, SD2U, SPECIALARGS, uByte, uInt, et uLong.

Référencé par decExpOp(), decLnOp(), decNumberFMA(), decNumberMultiply(), decNumberPower(), et decNumberSquareRoot().

04852                                                {
04853   Int    accunits;                 // Units of accumulator in use
04854   Int    exponent;                 // work
04855   Int    residue=0;                // rounding residue
04856   uByte  bits;                     // result sign
04857   Unit  *acc;                      // -> accumulator Unit array
04858   Int    needbytes;                // size calculator
04859   void  *allocacc=NULL;            // -> allocated accumulator, iff allocated
04860   Unit  accbuff[SD2U(DECBUFFER*4+1)]; // buffer (+1 for DECBUFFER==0,
04861                                    // *4 for calls from other operations)
04862   const Unit *mer, *mermsup;       // work
04863   Int   madlength;                 // Units in multiplicand
04864   Int   shift;                     // Units to shift multiplicand by
04865 
04866   #if FASTMUL
04867     // if DECDPUN is 1 or 3 work in base 10**9, otherwise
04868     // (DECDPUN is 2 or 4) then work in base 10**8
04869     #if DECDPUN & 1                // odd
04870       #define FASTBASE 1000000000  // base
04871       #define FASTDIGS          9  // digits in base
04872       #define FASTLAZY         18  // carry resolution point [1->18]
04873     #else
04874       #define FASTBASE  100000000
04875       #define FASTDIGS          8
04876       #define FASTLAZY       1844  // carry resolution point [1->1844]
04877     #endif
04878     // three buffers are used, two for chunked copies of the operands
04879     // (base 10**8 or base 10**9) and one base 2**64 accumulator with
04880     // lazy carry evaluation
04881     uInt   zlhibuff[(DECBUFFER*2+1)/8+1]; // buffer (+1 for DECBUFFER==0)
04882     uInt  *zlhi=zlhibuff;                 // -> lhs array
04883     uInt  *alloclhi=NULL;                 // -> allocated buffer, iff allocated
04884     uInt   zrhibuff[(DECBUFFER*2+1)/8+1]; // buffer (+1 for DECBUFFER==0)
04885     uInt  *zrhi=zrhibuff;                 // -> rhs array
04886     uInt  *allocrhi=NULL;                 // -> allocated buffer, iff allocated
04887     uLong  zaccbuff[(DECBUFFER*2+1)/4+2]; // buffer (+1 for DECBUFFER==0)
04888     // [allocacc is shared for both paths, as only one will run]
04889     uLong *zacc=zaccbuff;          // -> accumulator array for exact result
04890     #if DECDPUN==1
04891     Int    zoff;                   // accumulator offset
04892     #endif
04893     uInt  *lip, *rip;              // item pointers
04894     uInt  *lmsi, *rmsi;            // most significant items
04895     Int    ilhs, irhs, iacc;       // item counts in the arrays
04896     Int    lazy;                   // lazy carry counter
04897     uLong  lcarry;                 // uLong carry
04898     uInt   carry;                  // carry (NB not uLong)
04899     Int    count;                  // work
04900     const  Unit *cup;              // ..
04901     Unit  *up;                     // ..
04902     uLong *lp;                     // ..
04903     Int    p;                      // ..
04904   #endif
04905 
04906   #if DECSUBSET
04907     decNumber *alloclhs=NULL;      // -> allocated buffer, iff allocated
04908     decNumber *allocrhs=NULL;      // -> allocated buffer, iff allocated
04909   #endif
04910 
04911   #if DECCHECK
04912   if (decCheckOperands(res, lhs, rhs, set)) return res;
04913   #endif
04914 
04915   // precalculate result sign
04916   bits=(uByte)((lhs->bits^rhs->bits)&DECNEG);
04917 
04918   // handle infinities and NaNs
04919   if (SPECIALARGS) {               // a special bit set
04920     if (SPECIALARGS & (DECSNAN | DECNAN)) { // one or two NaNs
04921       decNaNs(res, lhs, rhs, set, status);
04922       return res;}
04923     // one or two infinities; Infinity * 0 is invalid
04924     if (((lhs->bits & DECINF)==0 && ISZERO(lhs))
04925       ||((rhs->bits & DECINF)==0 && ISZERO(rhs))) {
04926       *status|=DEC_Invalid_operation;
04927       return res;}
04928     decNumberZero(res);
04929     res->bits=bits|DECINF;         // infinity
04930     return res;}
04931 
04932   // For best speed, as in DMSRCN [the original Rexx numerics
04933   // module], use the shorter number as the multiplier (rhs) and
04934   // the longer as the multiplicand (lhs) to minimise the number of
04935   // adds (partial products)
04936   if (lhs->digits<rhs->digits) {   // swap...
04937     const decNumber *hold=lhs;
04938     lhs=rhs;
04939     rhs=hold;
04940     }
04941 
04942   do {                             // protect allocated storage
04943     #if DECSUBSET
04944     if (!set->extended) {
04945       // reduce operands and set lostDigits status, as needed
04946       if (lhs->digits>set->digits) {
04947         alloclhs=decRoundOperand(lhs, set, status);
04948         if (alloclhs==NULL) break;
04949         lhs=alloclhs;
04950         }
04951       if (rhs->digits>set->digits) {
04952         allocrhs=decRoundOperand(rhs, set, status);
04953         if (allocrhs==NULL) break;
04954         rhs=allocrhs;
04955         }
04956       }
04957     #endif
04958     // [following code does not require input rounding]
04959 
04960     #if FASTMUL                    // fastpath can be used
04961     // use the fast path if there are enough digits in the shorter
04962     // operand to make the setup and takedown worthwhile
04963     #define NEEDTWO (DECDPUN*2)    // within two decUnitAddSub calls
04964     if (rhs->digits>NEEDTWO) {     // use fastpath...
04965       // calculate the number of elements in each array
04966       ilhs=(lhs->digits+FASTDIGS-1)/FASTDIGS; // [ceiling]
04967       irhs=(rhs->digits+FASTDIGS-1)/FASTDIGS; // ..
04968       iacc=ilhs+irhs;
04969 
04970       // allocate buffers if required, as usual
04971       needbytes=ilhs*sizeof(uInt);
04972       if (needbytes>(Int)sizeof(zlhibuff)) {
04973         alloclhi=(uInt *)malloc(needbytes);
04974         zlhi=alloclhi;}
04975       needbytes=irhs*sizeof(uInt);
04976       if (needbytes>(Int)sizeof(zrhibuff)) {
04977         allocrhi=(uInt *)malloc(needbytes);
04978         zrhi=allocrhi;}
04979 
04980       // Allocating the accumulator space needs a special case when
04981       // DECDPUN=1 because when converting the accumulator to Units
04982       // after the multiplication each 8-byte item becomes 9 1-byte
04983       // units.  Therefore iacc extra bytes are needed at the front
04984       // (rounded up to a multiple of 8 bytes), and the uLong
04985       // accumulator starts offset the appropriate number of units
04986       // to the right to avoid overwrite during the unchunking.
04987       needbytes=iacc*sizeof(uLong);
04988       #if DECDPUN==1
04989       zoff=(iacc+7)/8;        // items to offset by
04990       needbytes+=zoff*8;
04991       #endif
04992       if (needbytes>(Int)sizeof(zaccbuff)) {
04993         allocacc=(uLong *)malloc(needbytes);
04994         zacc=(uLong *)allocacc;}
04995       if (zlhi==NULL||zrhi==NULL||zacc==NULL) {
04996         *status|=DEC_Insufficient_storage;
04997         break;}
04998 
04999       acc=(Unit *)zacc;       // -> target Unit array
05000       #if DECDPUN==1
05001       zacc+=zoff;             // start uLong accumulator to right
05002       #endif
05003 
05004       // assemble the chunked copies of the left and right sides
05005       for (count=lhs->digits, cup=lhs->lsu, lip=zlhi; count>0; lip++)
05006         for (p=0, *lip=0; p<FASTDIGS && count>0;
05007              p+=DECDPUN, cup++, count-=DECDPUN)
05008           *lip+=*cup*powers[p];
05009       lmsi=lip-1;     // save -> msi
05010       for (count=rhs->digits, cup=rhs->lsu, rip=zrhi; count>0; rip++)
05011         for (p=0, *rip=0; p<FASTDIGS && count>0;
05012              p+=DECDPUN, cup++, count-=DECDPUN)
05013           *rip+=*cup*powers[p];
05014       rmsi=rip-1;     // save -> msi
05015 
05016       // zero the accumulator
05017       for (lp=zacc; lp<zacc+iacc; lp++) *lp=0;
05018 
05019       /* Start the multiplication */
05020       // Resolving carries can dominate the cost of accumulating the
05021       // partial products, so this is only done when necessary.
05022       // Each uLong item in the accumulator can hold values up to
05023       // 2**64-1, and each partial product can be as large as
05024       // (10**FASTDIGS-1)**2.  When FASTDIGS=9, this can be added to
05025       // itself 18.4 times in a uLong without overflowing, so during
05026       // the main calculation resolution is carried out every 18th
05027       // add -- every 162 digits.  Similarly, when FASTDIGS=8, the
05028       // partial products can be added to themselves 1844.6 times in
05029       // a uLong without overflowing, so intermediate carry
05030       // resolution occurs only every 14752 digits.  Hence for common
05031       // short numbers usually only the one final carry resolution
05032       // occurs.
05033       // (The count is set via FASTLAZY to simplify experiments to
05034       // measure the value of this approach: a 35% improvement on a
05035       // [34x34] multiply.)
05036       lazy=FASTLAZY;                         // carry delay count
05037       for (rip=zrhi; rip<=rmsi; rip++) {     // over each item in rhs
05038         lp=zacc+(rip-zrhi);                  // where to add the lhs
05039         for (lip=zlhi; lip<=lmsi; lip++, lp++) { // over each item in lhs
05040           *lp+=(uLong)(*lip)*(*rip);         // [this should in-line]
05041           } // lip loop
05042         lazy--;
05043         if (lazy>0 && rip!=rmsi) continue;
05044         lazy=FASTLAZY;                       // reset delay count
05045         // spin up the accumulator resolving overflows
05046         for (lp=zacc; lp<zacc+iacc; lp++) {
05047           if (*lp<FASTBASE) continue;        // it fits
05048           lcarry=*lp/FASTBASE;               // top part [slow divide]
05049           // lcarry can exceed 2**32-1, so check again; this check
05050           // and occasional extra divide (slow) is well worth it, as
05051           // it allows FASTLAZY to be increased to 18 rather than 4
05052           // in the FASTDIGS=9 case
05053           if (lcarry<FASTBASE) carry=(uInt)lcarry;  // [usual]
05054            else { // two-place carry [fairly rare]
05055             uInt carry2=(uInt)(lcarry/FASTBASE);    // top top part
05056             *(lp+2)+=carry2;                        // add to item+2
05057             *lp-=((uLong)FASTBASE*FASTBASE*carry2); // [slow]
05058             carry=(uInt)(lcarry-((uLong)FASTBASE*carry2)); // [inline]
05059             }
05060           *(lp+1)+=carry;                    // add to item above [inline]
05061           *lp-=((uLong)FASTBASE*carry);      // [inline]
05062           } // carry resolution
05063         } // rip loop
05064 
05065       // The multiplication is complete; time to convert back into
05066       // units.  This can be done in-place in the accumulator and in
05067       // 32-bit operations, because carries were resolved after the
05068       // final add.  This needs N-1 divides and multiplies for
05069       // each item in the accumulator (which will become up to N
05070       // units, where 2<=N<=9).
05071       for (lp=zacc, up=acc; lp<zacc+iacc; lp++) {
05072         uInt item=(uInt)*lp;                 // decapitate to uInt
05073         for (p=0; p<FASTDIGS-DECDPUN; p+=DECDPUN, up++) {
05074           uInt part=item/(DECDPUNMAX+1);
05075           *up=(Unit)(item-(part*(DECDPUNMAX+1)));
05076           item=part;
05077           } // p
05078         *up=(Unit)item; up++;                // [final needs no division]
05079         } // lp
05080       accunits=up-acc;                       // count of units
05081       }
05082      else { // here to use units directly, without chunking ['old code']
05083     #endif
05084 
05085       // if accumulator will be too long for local storage, then allocate
05086       acc=accbuff;                 // -> assume buffer for accumulator
05087       needbytes=(D2U(lhs->digits)+D2U(rhs->digits))*sizeof(Unit);
05088       if (needbytes>(Int)sizeof(accbuff)) {
05089         allocacc=(Unit *)malloc(needbytes);
05090         if (allocacc==NULL) {*status|=DEC_Insufficient_storage; break;}
05091         acc=(Unit *)allocacc;                // use the allocated space
05092         }
05093 
05094       /* Now the main long multiplication loop */
05095       // Unlike the equivalent in the IBM Java implementation, there
05096       // is no advantage in calculating from msu to lsu.  So, do it
05097       // by the book, as it were.
05098       // Each iteration calculates ACC=ACC+MULTAND*MULT
05099       accunits=1;                  // accumulator starts at '0'
05100       *acc=0;                      // .. (lsu=0)
05101       shift=0;                     // no multiplicand shift at first
05102       madlength=D2U(lhs->digits);  // this won't change
05103       mermsup=rhs->lsu+D2U(rhs->digits); // -> msu+1 of multiplier
05104 
05105       for (mer=rhs->lsu; mer<mermsup; mer++) {
05106         // Here, *mer is the next Unit in the multiplier to use
05107         // If non-zero [optimization] add it...
05108         if (*mer!=0) accunits=decUnitAddSub(&acc[shift], accunits-shift,
05109                                             lhs->lsu, madlength, 0,
05110                                             &acc[shift], *mer)
05111                                             + shift;
05112          else { // extend acc with a 0; it will be used shortly
05113           *(acc+accunits)=0;       // [this avoids length of <=0 later]
05114           accunits++;
05115           }
05116         // multiply multiplicand by 10**DECDPUN for next Unit to left
05117         shift++;                   // add this for 'logical length'
05118         } // n
05119     #if FASTMUL
05120       } // unchunked units
05121     #endif
05122     // common end-path
05123     #if DECTRACE
05124       decDumpAr('*', acc, accunits);         // Show exact result
05125     #endif
05126 
05127     // acc now contains the exact result of the multiplication,
05128     // possibly with a leading zero unit; build the decNumber from
05129     // it, noting if any residue
05130     res->bits=bits;                          // set sign
05131     res->digits=decGetDigits(acc, accunits); // count digits exactly
05132 
05133     // There can be a 31-bit wrap in calculating the exponent.
05134     // This can only happen if both input exponents are negative and
05135     // both their magnitudes are large.  If there was a wrap, set a
05136     // safe very negative exponent, from which decFinalize() will
05137     // raise a hard underflow shortly.
05138     exponent=lhs->exponent+rhs->exponent;    // calculate exponent
05139     if (lhs->exponent<0 && rhs->exponent<0 && exponent>0)
05140       exponent=-2*DECNUMMAXE;                // force underflow
05141     res->exponent=exponent;                  // OK to overwrite now
05142 
05143 
05144     // Set the coefficient.  If any rounding, residue records
05145     decSetCoeff(res, set, acc, res->digits, &residue, status);
05146     decFinish(res, set, &residue, status);   // final cleanup
05147     } while(0);                         // end protected
05148 
05149   if (allocacc!=NULL) free(allocacc);   // drop any storage used
05150   #if DECSUBSET
05151   if (allocrhs!=NULL) free(allocrhs);   // ..
05152   if (alloclhs!=NULL) free(alloclhs);   // ..
05153   #endif
05154   #if FASTMUL
05155   if (allocrhi!=NULL) free(allocrhi);   // ..
05156   if (alloclhi!=NULL) free(alloclhi);   // ..
05157   #endif
05158   return res;
05159   } // decMultiplyOp

static decNumber * decNaNs ( decNumber ,
const decNumber ,
const decNumber ,
decContext ,
uInt *   
) [static]

Définition à la ligne 7703 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Invalid_operation, DEC_sNaN, decDecap(), DECDPUN, DECNAN, decNumberCopy(), DECSNAN, decContext::digits, decNumber::digits, decNumber::exponent, et decNumber::lsu.

Référencé par decAddOp(), decCompareOp(), decDivideOp(), decExpOp(), decLnOp(), decMultiplyOp(), decNumberLogB(), decNumberNextToward(), decNumberPower(), decNumberReduce(), decNumberRotate(), decNumberScaleB(), decNumberShift(), decNumberSquareRoot(), decNumberToIntegralExact(), et decQuantizeOp().

07705                                          {
07706   // This decision tree ends up with LHS being the source pointer,
07707   // and status updated if need be
07708   if (lhs->bits & DECSNAN)
07709     *status|=DEC_Invalid_operation | DEC_sNaN;
07710    else if (rhs==NULL);
07711    else if (rhs->bits & DECSNAN) {
07712     lhs=rhs;
07713     *status|=DEC_Invalid_operation | DEC_sNaN;
07714     }
07715    else if (lhs->bits & DECNAN);
07716    else lhs=rhs;
07717 
07718   // propagate the payload
07719   if (lhs->digits<=set->digits) decNumberCopy(res, lhs); // easy
07720    else { // too long
07721     const Unit *ul;
07722     Unit *ur, *uresp1;
07723     // copy safe number of units, then decapitate
07724     res->bits=lhs->bits;                // need sign etc.
07725     uresp1=res->lsu+D2U(set->digits);
07726     for (ur=res->lsu, ul=lhs->lsu; ur<uresp1; ur++, ul++) *ur=*ul;
07727     res->digits=D2U(set->digits)*DECDPUN;
07728     // maybe still too long
07729     if (res->digits>set->digits) decDecap(res, res->digits-set->digits);
07730     }
07731 
07732   res->bits&=~DECSNAN;        // convert any sNaN to NaN, while
07733   res->bits|=DECNAN;          // .. preserving sign
07734   res->exponent=0;            // clean exponent
07735                               // [coefficient was copied/decapitated]
07736   return res;
07737   } // decNaNs

decNumber* decNumberAbs ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 757 du fichier decNumber.c.

Références decNumber::bits, decAddOp(), DECNEG, decNumberZero(), decStatus(), decNumber::exponent, uByte, et uInt.

Référencé par abs().

00758                                           {
00759   decNumber dzero;                      // for 0
00760   uInt status=0;                        // accumulator
00761 
00762   #if DECCHECK
00763   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
00764   #endif
00765 
00766   decNumberZero(&dzero);                // set 0
00767   dzero.exponent=rhs->exponent;         // [no coefficient expansion]
00768   decAddOp(res, &dzero, rhs, set, (uByte)(rhs->bits & DECNEG), &status);
00769   if (status!=0) decStatus(res, status, set);
00770   #if DECCHECK
00771   decCheckInexact(res, set);
00772   #endif
00773   return res;
00774   } // decNumberAbs

decNumber* decNumberAdd ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 789 du fichier decNumber.c.

Références decAddOp(), decStatus(), et uInt.

Référencé par DecFloat_::operator+=().

00790                                                                 {
00791   uInt status=0;                        // accumulator
00792   decAddOp(res, lhs, rhs, set, 0, &status);
00793   if (status!=0) decStatus(res, status, set);
00794   #if DECCHECK
00795   decCheckInexact(res, set);
00796   #endif
00797   return res;
00798   } // decNumberAdd

decNumber* decNumberAnd ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 815 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decNumber::digits, decContext::digits, decNumber::exponent, Int, decNumber::lsu, MSUDIGITS, et powers.

00816                                                                 {
00817   const Unit *ua, *ub;                  // -> operands
00818   const Unit *msua, *msub;              // -> operand msus
00819   Unit *uc,  *msuc;                     // -> result and its msu
00820   Int   msudigs;                        // digits in res msu
00821   #if DECCHECK
00822   if (decCheckOperands(res, lhs, rhs, set)) return res;
00823   #endif
00824 
00825   if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
00826    || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
00827     decStatus(res, DEC_Invalid_operation, set);
00828     return res;
00829     }
00830 
00831   // operands are valid
00832   ua=lhs->lsu;                          // bottom-up
00833   ub=rhs->lsu;                          // ..
00834   uc=res->lsu;                          // ..
00835   msua=ua+D2U(lhs->digits)-1;           // -> msu of lhs
00836   msub=ub+D2U(rhs->digits)-1;           // -> msu of rhs
00837   msuc=uc+D2U(set->digits)-1;           // -> msu of result
00838   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
00839   for (; uc<=msuc; ua++, ub++, uc++) {  // Unit loop
00840     Unit a, b;                          // extract units
00841     if (ua>msua) a=0;
00842      else a=*ua;
00843     if (ub>msub) b=0;
00844      else b=*ub;
00845     *uc=0;                              // can now write back
00846     if (a|b) {                          // maybe 1 bits to examine
00847       Int i, j;
00848       *uc=0;                            // can now write back
00849       // This loop could be unrolled and/or use BIN2BCD tables
00850       for (i=0; i<DECDPUN; i++) {
00851         if (a&b&1) *uc=*uc+(Unit)powers[i];  // effect AND
00852         j=a%10;
00853         a=a/10;
00854         j|=b%10;
00855         b=b/10;
00856         if (j>1) {
00857           decStatus(res, DEC_Invalid_operation, set);
00858           return res;
00859           }
00860         if (uc==msuc && i==msudigs-1) break; // just did final digit
00861         } // each digit
00862       } // both OK
00863     } // each unit
00864   // [here uc-1 is the msu of the result]
00865   res->digits=decGetDigits(res->lsu, uc-res->lsu);
00866   res->exponent=0;                      // integer
00867   res->bits=0;                          // sign=0
00868   return res;  // [no status to set]
00869   } // decNumberAnd

enum decClass decNumberClass ( const decNumber dn,
decContext set 
)

Définition à la ligne 3312 du fichier decNumber.c.

Références DEC_CLASS_NEG_INF, DEC_CLASS_NEG_NORMAL, DEC_CLASS_NEG_SUBNORMAL, DEC_CLASS_NEG_ZERO, DEC_CLASS_POS_INF, DEC_CLASS_POS_NORMAL, DEC_CLASS_POS_SUBNORMAL, DEC_CLASS_POS_ZERO, DEC_CLASS_QNAN, DEC_CLASS_SNAN, decNumberIsNegative, decNumberIsNormal(), decNumberIsQNaN, decNumberIsSNaN, decNumberIsSpecial, et decNumberIsZero.

03312                                                                    {
03313   if (decNumberIsSpecial(dn)) {
03314     if (decNumberIsQNaN(dn)) return DEC_CLASS_QNAN;
03315     if (decNumberIsSNaN(dn)) return DEC_CLASS_SNAN;
03316     // must be an infinity
03317     if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_INF;
03318     return DEC_CLASS_POS_INF;
03319     }
03320   // is finite
03321   if (decNumberIsNormal(dn, set)) { // most common
03322     if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_NORMAL;
03323     return DEC_CLASS_POS_NORMAL;
03324     }
03325   // is subnormal or zero
03326   if (decNumberIsZero(dn)) {    // most common
03327     if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_ZERO;
03328     return DEC_CLASS_POS_ZERO;
03329     }
03330   if (decNumberIsNegative(dn)) return DEC_CLASS_NEG_SUBNORMAL;
03331   return DEC_CLASS_POS_SUBNORMAL;
03332   } // decNumberClass

const char* decNumberClassToString ( enum decClass  eclass  ) 

Définition à la ligne 3340 du fichier decNumber.c.

Références DEC_CLASS_NEG_INF, DEC_CLASS_NEG_NORMAL, DEC_CLASS_NEG_SUBNORMAL, DEC_CLASS_NEG_ZERO, DEC_CLASS_POS_INF, DEC_CLASS_POS_NORMAL, DEC_CLASS_POS_SUBNORMAL, DEC_CLASS_POS_ZERO, DEC_CLASS_QNAN, DEC_CLASS_SNAN, DEC_ClassString_NI, DEC_ClassString_NN, DEC_ClassString_NS, DEC_ClassString_NZ, DEC_ClassString_PI, DEC_ClassString_PN, DEC_ClassString_PS, DEC_ClassString_PZ, DEC_ClassString_QN, DEC_ClassString_SN, et DEC_ClassString_UN.

03340                                                          {
03341   if (eclass==DEC_CLASS_POS_NORMAL)    return DEC_ClassString_PN;
03342   if (eclass==DEC_CLASS_NEG_NORMAL)    return DEC_ClassString_NN;
03343   if (eclass==DEC_CLASS_POS_ZERO)      return DEC_ClassString_PZ;
03344   if (eclass==DEC_CLASS_NEG_ZERO)      return DEC_ClassString_NZ;
03345   if (eclass==DEC_CLASS_POS_SUBNORMAL) return DEC_ClassString_PS;
03346   if (eclass==DEC_CLASS_NEG_SUBNORMAL) return DEC_ClassString_NS;
03347   if (eclass==DEC_CLASS_POS_INF)       return DEC_ClassString_PI;
03348   if (eclass==DEC_CLASS_NEG_INF)       return DEC_ClassString_NI;
03349   if (eclass==DEC_CLASS_QNAN)          return DEC_ClassString_QN;
03350   if (eclass==DEC_CLASS_SNAN)          return DEC_ClassString_SN;
03351   return DEC_ClassString_UN;           // Unknown
03352   } // decNumberClassToString

decNumber* decNumberCompare ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 883 du fichier decNumber.c.

Références COMPARE, decCompareOp(), decStatus(), et uInt.

Référencé par decNumberPower(), operator<(), et operator==().

00884                                                                     {
00885   uInt status=0;                        // accumulator
00886   decCompareOp(res, lhs, rhs, set, COMPARE, &status);
00887   if (status!=0) decStatus(res, status, set);
00888   return res;
00889   } // decNumberCompare

decNumber* decNumberCompareSignal ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 903 du fichier decNumber.c.

Références COMPSIG, decCompareOp(), decStatus(), et uInt.

00904                                                                           {
00905   uInt status=0;                        // accumulator
00906   decCompareOp(res, lhs, rhs, set, COMPSIG, &status);
00907   if (status!=0) decStatus(res, status, set);
00908   return res;
00909   } // decNumberCompareSignal

decNumber* decNumberCompareTotal ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 924 du fichier decNumber.c.

Références COMPTOTAL, decCompareOp(), decStatus(), et uInt.

00925                                                                          {
00926   uInt status=0;                        // accumulator
00927   decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
00928   if (status!=0) decStatus(res, status, set);
00929   return res;
00930   } // decNumberCompareTotal

decNumber* decNumberCompareTotalMag ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 945 du fichier decNumber.c.

Références decNumber::bits, COMPTOTAL, D2N, D2U, DEC_Insufficient_storage, DECBUFFER, decCompareOp(), DECNEG, decNumberCopy(), decNumberIsNegative, decStatus(), decNumber::digits, et uInt.

00946                                                                             {
00947   uInt status=0;                   // accumulator
00948   uInt needbytes;                  // for space calculations
00949   decNumber bufa[D2N(DECBUFFER+1)];// +1 in case DECBUFFER=0
00950   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
00951   decNumber bufb[D2N(DECBUFFER+1)];
00952   decNumber *allocbufb=NULL;       // -> allocated bufb, iff allocated
00953   decNumber *a, *b;                // temporary pointers
00954 
00955   #if DECCHECK
00956   if (decCheckOperands(res, lhs, rhs, set)) return res;
00957   #endif
00958 
00959   do {                                  // protect allocated storage
00960     // if either is negative, take a copy and absolute
00961     if (decNumberIsNegative(lhs)) {     // lhs<0
00962       a=bufa;
00963       needbytes=sizeof(decNumber)+(D2U(lhs->digits)-1)*sizeof(Unit);
00964       if (needbytes>sizeof(bufa)) {     // need malloc space
00965         allocbufa=(decNumber *)malloc(needbytes);
00966         if (allocbufa==NULL) {          // hopeless -- abandon
00967           status|=DEC_Insufficient_storage;
00968           break;}
00969         a=allocbufa;                    // use the allocated space
00970         }
00971       decNumberCopy(a, lhs);            // copy content
00972       a->bits&=~DECNEG;                 // .. and clear the sign
00973       lhs=a;                            // use copy from here on
00974       }
00975     if (decNumberIsNegative(rhs)) {     // rhs<0
00976       b=bufb;
00977       needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
00978       if (needbytes>sizeof(bufb)) {     // need malloc space
00979         allocbufb=(decNumber *)malloc(needbytes);
00980         if (allocbufb==NULL) {          // hopeless -- abandon
00981           status|=DEC_Insufficient_storage;
00982           break;}
00983         b=allocbufb;                    // use the allocated space
00984         }
00985       decNumberCopy(b, rhs);            // copy content
00986       b->bits&=~DECNEG;                 // .. and clear the sign
00987       rhs=b;                            // use copy from here on
00988       }
00989     decCompareOp(res, lhs, rhs, set, COMPTOTAL, &status);
00990     } while(0);                         // end protected
00991 
00992   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
00993   if (allocbufb!=NULL) free(allocbufb); // ..
00994   if (status!=0) decStatus(res, status, set);
00995   return res;
00996   } // decNumberCompareTotalMag

decNumber* decNumberCopy ( decNumber dest,
const decNumber src 
)

Définition à la ligne 3365 du fichier decNumber.c.

Références decNumber::bits, D2U, DECDPUN, decNumberZero(), decNumber::digits, decNumber::exponent, et decNumber::lsu.

Référencé par decAddOp(), decDivideOp(), decExpOp(), decLnOp(), decNaNs(), decNumberCompareTotalMag(), decNumberCopyAbs(), decNumberCopyNegate(), decNumberCopySign(), decNumberLog10(), decNumberPower(), decNumberRotate(), decNumberScaleB(), decNumberShift(), decNumberSquareRoot(), decNumberToIntegralExact(), decQuantizeOp(), et DecFloat_::operator=().

03365                                                                  {
03366 
03367   #if DECCHECK
03368   if (src==NULL) return decNumberZero(dest);
03369   #endif
03370 
03371   if (dest==src) return dest;                // no copy required
03372 
03373   // Use explicit assignments here as structure assignment could copy
03374   // more than just the lsu (for small DECDPUN).  This would not affect
03375   // the value of the results, but could disturb test harness spill
03376   // checking.
03377   dest->bits=src->bits;
03378   dest->exponent=src->exponent;
03379   dest->digits=src->digits;
03380   dest->lsu[0]=src->lsu[0];
03381   if (src->digits>DECDPUN) {                 // more Units to come
03382     const Unit *smsup, *s;                   // work
03383     Unit  *d;                                // ..
03384     // memcpy for the remaining Units would be safe as they cannot
03385     // overlap.  However, this explicit loop is faster in short cases.
03386     d=dest->lsu+1;                           // -> first destination
03387     smsup=src->lsu+D2U(src->digits);         // -> source msu+1
03388     for (s=src->lsu+1; s<smsup; s++, d++) *d=*s;
03389     }
03390   return dest;
03391   } // decNumberCopy

decNumber* decNumberCopyAbs ( decNumber res,
const decNumber rhs 
)

Définition à la ligne 3405 du fichier decNumber.c.

Références decNumber::bits, DECNEG, et decNumberCopy().

Référencé par decNumberLogB().

03405                                                                    {
03406   #if DECCHECK
03407   if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
03408   #endif
03409   decNumberCopy(res, rhs);
03410   res->bits&=~DECNEG;                   // turn off sign
03411   return res;
03412   } // decNumberCopyAbs

decNumber* decNumberCopyNegate ( decNumber res,
const decNumber rhs 
)

Définition à la ligne 3426 du fichier decNumber.c.

Références decNumber::bits, DECNEG, et decNumberCopy().

03426                                                                       {
03427   #if DECCHECK
03428   if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
03429   #endif
03430   decNumberCopy(res, rhs);
03431   res->bits^=DECNEG;                    // invert the sign
03432   return res;
03433   } // decNumberCopyNegate

decNumber* decNumberCopySign ( decNumber res,
const decNumber lhs,
const decNumber rhs 
)

Définition à la ligne 3447 du fichier decNumber.c.

Références decNumber::bits, DECNEG, decNumberCopy(), et uByte.

Référencé par decNumberNextToward().

03448                                                     {
03449   uByte sign;                           // rhs sign
03450   #if DECCHECK
03451   if (decCheckOperands(res, DECUNUSED, rhs, DECUNCONT)) return res;
03452   #endif
03453   sign=rhs->bits & DECNEG;              // save sign bit
03454   decNumberCopy(res, lhs);
03455   res->bits&=~DECNEG;                   // clear the sign
03456   res->bits|=sign;                      // set from rhs
03457   return res;
03458   } // decNumberCopySign

decNumber* decNumberDivide ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1010 du fichier decNumber.c.

Références decDivideOp(), decStatus(), DIVIDE, et uInt.

Référencé par DecFloat_::operator/=().

01011                                                                    {
01012   uInt status=0;                        // accumulator
01013   decDivideOp(res, lhs, rhs, set, DIVIDE, &status);
01014   if (status!=0) decStatus(res, status, set);
01015   #if DECCHECK
01016   decCheckInexact(res, set);
01017   #endif
01018   return res;
01019   } // decNumberDivide

decNumber* decNumberDivideInteger ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1033 du fichier decNumber.c.

Références decDivideOp(), decStatus(), DIVIDEINT, et uInt.

Référencé par DivideInteger().

01034                                                                           {
01035   uInt status=0;                        // accumulator
01036   decDivideOp(res, lhs, rhs, set, DIVIDEINT, &status);
01037   if (status!=0) decStatus(res, status, set);
01038   return res;
01039   } // decNumberDivideInteger

decNumber* decNumberExp ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1066 du fichier decNumber.c.

Références decCheckMath(), decExpOp(), decStatus(), decNumber::digits, decContext::digits, et uInt.

01067                                           {
01068   uInt status=0;                        // accumulator
01069   #if DECSUBSET
01070   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
01071   #endif
01072 
01073   #if DECCHECK
01074   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01075   #endif
01076 
01077   // Check restrictions; these restrictions ensure that if h=8 (see
01078   // decExpOp) then the result will either overflow or underflow to 0.
01079   // Other math functions restrict the input range, too, for inverses.
01080   // If not violated then carry out the operation.
01081   if (!decCheckMath(rhs, set, &status)) do { // protect allocation
01082     #if DECSUBSET
01083     if (!set->extended) {
01084       // reduce operand and set lostDigits status, as needed
01085       if (rhs->digits>set->digits) {
01086         allocrhs=decRoundOperand(rhs, set, &status);
01087         if (allocrhs==NULL) break;
01088         rhs=allocrhs;
01089         }
01090       }
01091     #endif
01092     decExpOp(res, rhs, set, &status);
01093     } while(0);                         // end protected
01094 
01095   #if DECSUBSET
01096   if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
01097   #endif
01098   // apply significant status
01099   if (status!=0) decStatus(res, status, set);
01100   #if DECCHECK
01101   decCheckInexact(res, set);
01102   #endif
01103   return res;
01104   } // decNumberExp

decNumber* decNumberFMA ( decNumber res,
const decNumber lhs,
const decNumber rhs,
const decNumber fhs,
decContext set 
)

Définition à la ligne 1122 du fichier decNumber.c.

Références D2N, D2U, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_MAX_EMAX, DEC_MIN_EMIN, DEC_sNaN, decAddOp(), DECBUFFER, decCheckMath(), decMultiplyOp(), DECNAN, decNumberIsSpecial, decNumberZero(), decStatus(), decContext::digits, decNumber::digits, decContext::emax, decContext::emin, et uInt.

01124                                           {
01125   uInt status=0;                   // accumulator
01126   decContext dcmul;                // context for the multiplication
01127   uInt needbytes;                  // for space calculations
01128   decNumber bufa[D2N(DECBUFFER*2+1)];
01129   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
01130   decNumber *acc;                  // accumulator pointer
01131   decNumber dzero;                 // work
01132 
01133   #if DECCHECK
01134   if (decCheckOperands(res, lhs, rhs, set)) return res;
01135   if (decCheckOperands(res, fhs, DECUNUSED, set)) return res;
01136   #endif
01137 
01138   do {                                  // protect allocated storage
01139     #if DECSUBSET
01140     if (!set->extended) {               // [undefined if subset]
01141       status|=DEC_Invalid_operation;
01142       break;}
01143     #endif
01144     // Check math restrictions [these ensure no overflow or underflow]
01145     if ((!decNumberIsSpecial(lhs) && decCheckMath(lhs, set, &status))
01146      || (!decNumberIsSpecial(rhs) && decCheckMath(rhs, set, &status))
01147      || (!decNumberIsSpecial(fhs) && decCheckMath(fhs, set, &status))) break;
01148     // set up context for multiply
01149     dcmul=*set;
01150     dcmul.digits=lhs->digits+rhs->digits; // just enough
01151     // [The above may be an over-estimate for subset arithmetic, but that's OK]
01152     dcmul.emax=DEC_MAX_EMAX;            // effectively unbounded ..
01153     dcmul.emin=DEC_MIN_EMIN;            // [thanks to Math restrictions]
01154     // set up decNumber space to receive the result of the multiply
01155     acc=bufa;                           // may fit
01156     needbytes=sizeof(decNumber)+(D2U(dcmul.digits)-1)*sizeof(Unit);
01157     if (needbytes>sizeof(bufa)) {       // need malloc space
01158       allocbufa=(decNumber *)malloc(needbytes);
01159       if (allocbufa==NULL) {            // hopeless -- abandon
01160         status|=DEC_Insufficient_storage;
01161         break;}
01162       acc=allocbufa;                    // use the allocated space
01163       }
01164     // multiply with extended range and necessary precision
01165     //printf("emin=%ld\n", dcmul.emin);
01166     decMultiplyOp(acc, lhs, rhs, &dcmul, &status);
01167     // Only Invalid operation (from sNaN or Inf * 0) is possible in
01168     // status; if either is seen than ignore fhs (in case it is
01169     // another sNaN) and set acc to NaN unless we had an sNaN
01170     // [decMultiplyOp leaves that to caller]
01171     // Note sNaN has to go through addOp to shorten payload if
01172     // necessary
01173     if ((status&DEC_Invalid_operation)!=0) {
01174       if (!(status&DEC_sNaN)) {         // but be true invalid
01175         decNumberZero(res);             // acc not yet set
01176         res->bits=DECNAN;
01177         break;
01178         }
01179       decNumberZero(&dzero);            // make 0 (any non-NaN would do)
01180       fhs=&dzero;                       // use that
01181       }
01182     #if DECCHECK
01183      else { // multiply was OK
01184       if (status!=0) printf("Status=%08lx after FMA multiply\n", (LI)status);
01185       }
01186     #endif
01187     // add the third operand and result -> res, and all is done
01188     decAddOp(res, acc, fhs, set, 0, &status);
01189     } while(0);                         // end protected
01190 
01191   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
01192   if (status!=0) decStatus(res, status, set);
01193   #if DECCHECK
01194   decCheckInexact(res, set);
01195   #endif
01196   return res;
01197   } // decNumberFMA

decNumber* decNumberFromInt32 ( decNumber dn,
Int  in 
)

Définition à la ligne 336 du fichier decNumber.c.

Références BADINT, decNumber::bits, DECNEG, decNumberFromUInt32(), et uInt.

Référencé par decLnOp(), decNumberLog10(), et decNumberLogB().

00336                                                       {
00337   uInt unsig;
00338   if (in>=0) unsig=in;
00339    else {                               // negative (possibly BADINT)
00340     if (in==BADINT) unsig=(uInt)1073741824*2; // special case
00341      else unsig=-in;                    // invert
00342     }
00343   // in is now positive
00344   decNumberFromUInt32(dn, unsig);
00345   if (in<0) dn->bits=DECNEG;            // sign needed
00346   return dn;
00347   } // decNumberFromInt32

decNumber* decNumberFromString ( decNumber dn,
const char  chars[],
decContext set 
)

Définition à la ligne 480 du fichier decNumber.c.

Références _EnFr_, decContext::clamp, DEC_Conversion_syntax, DEC_English, DEC_French, decBiStr(), DECBUFFER, DECINF, DECNAN, DECNEG, decNumberZero(), DECNUMMAXE, DECSNAN, decContext::digits, Flag, Int, SD2U, uByte, uInt, Unit, et X10.

Référencé par DecFloat_::DecFloat_(), decLnOp(), DecFloat_::operator=(), operator>>(), et DecFloat_::ToChar().

00481                                                  {
00482   Int   exponent=0;                // working exponent [assume 0]
00483   uByte bits=0;                    // working flags [assume +ve]
00484   Unit  *res;                      // where result will be built
00485   Unit  resbuff[SD2U(DECBUFFER+9)];// local buffer in case need temporary
00486                                    // [+9 allows for ln() constants]
00487   Unit  *allocres=NULL;            // -> allocated result, iff allocated
00488   Int   d=0;                       // count of digits found in decimal part
00489   const char *dotchar=NULL;        // where dot was found
00490   const char *cfirst=chars;        // -> first character of decimal part
00491   const char *last=NULL;           // -> last digit of decimal part
00492   const char *c;                   // work
00493   Unit  *up;                       // ..
00494   #if DECDPUN>1
00495   Int   cut, out;                  // ..
00496   #endif
00497   Int   residue;                   // rounding residue
00498   uInt  status=0;                  // error code
00499 
00500   #if DECCHECK
00501   if (decCheckOperands(DECUNRESU, DECUNUSED, DECUNUSED, set))
00502     return decNumberZero(dn);
00503   #endif
00504 
00505   do {                             // status & malloc protection
00506     for (c=chars;; c++) {          // -> input character
00507       if (*c>='0' && *c<='9') {    // test for Arabic digit
00508         last=c;
00509         d++;                       // count of real digits
00510         continue;                  // still in decimal part
00511         }
00512  // JPL french ------------------------------------------------------------
00513 
00514  switch (_EnFr_){
00515 
00516  case  DEC_English :    if (*c=='.' && dotchar==NULL) { // first '.'
00517         dotchar=c;                 // record offset into decimal part
00518         if (c==cfirst) cfirst++;   // first digit must follow
00519         continue;} break ;
00520  case   DEC_French :    if (*c==',' && dotchar==NULL) { // first ','
00521         dotchar=c;                 // record offset into decimal part
00522         if (c==cfirst) cfirst++;   // first digit must follow
00523         continue;} break ;
00524 // JPL french ------------------------------------------------------------
00525  }
00526 
00527       if (c==chars) {              // first in string...
00528         if (*c=='-') {             // valid - sign
00529           cfirst++;
00530           bits=DECNEG;
00531           continue;}
00532         if (*c=='+') {             // valid + sign
00533           cfirst++;
00534           continue;}
00535         }
00536       // *c is not a digit, or a valid +, -, or '.'
00537       break;
00538       } // c
00539 
00540     if (last==NULL) {              // no digits yet
00541       status=DEC_Conversion_syntax;// assume the worst
00542       if (*c=='\0') break;         // and no more to come...
00543       #if DECSUBSET
00544       // if subset then infinities and NaNs are not allowed
00545       if (!set->extended) break;   // hopeless
00546       #endif
00547       // Infinities and NaNs are possible, here
00548       if (dotchar!=NULL) break;    // .. unless had a dot
00549       decNumberZero(dn);           // be optimistic
00550       if (decBiStr(c, "infinity", "INFINITY")
00551        || decBiStr(c, "inf", "INF")) {
00552         dn->bits=bits | DECINF;
00553         status=0;                  // is OK
00554         break; // all done
00555         }
00556       // a NaN expected
00557       // 2003.09.10 NaNs are now permitted to have a sign
00558       dn->bits=bits | DECNAN;      // assume simple NaN
00559       if (*c=='s' || *c=='S') {    // looks like an sNaN
00560         c++;
00561         dn->bits=bits | DECSNAN;
00562         }
00563       if (*c!='n' && *c!='N') break;    // check caseless "NaN"
00564       c++;
00565       if (*c!='a' && *c!='A') break;    // ..
00566       c++;
00567       if (*c!='n' && *c!='N') break;    // ..
00568       c++;
00569       // now either nothing, or nnnn payload, expected
00570       // -> start of integer and skip leading 0s [including plain 0]
00571       for (cfirst=c; *cfirst=='0';) cfirst++;
00572       if (*cfirst=='\0') {         // "NaN" or "sNaN", maybe with all 0s
00573         status=0;                  // it's good
00574         break;                     // ..
00575         }
00576       // something other than 0s; setup last and d as usual [no dots]
00577       for (c=cfirst;; c++, d++) {
00578         if (*c<'0' || *c>'9') break; // test for Arabic digit
00579         last=c;
00580         }
00581       if (*c!='\0') break;         // not all digits
00582       if (d>set->digits-1) {
00583         // [NB: payload in a decNumber can be full length unless
00584         // clamped, in which case can only be digits-1]
00585         if (set->clamp) break;
00586         if (d>set->digits) break;
00587         } // too many digits?
00588       // good; drop through to convert the integer to coefficient
00589       status=0;                    // syntax is OK
00590       bits=dn->bits;               // for copy-back
00591       } // last==NULL
00592 
00593      else if (*c!='\0') {          // more to process...
00594       // had some digits; exponent is only valid sequence now
00595       Flag nege;                   // 1=negative exponent
00596       const char *firstexp;        // -> first significant exponent digit
00597       status=DEC_Conversion_syntax;// assume the worst
00598       if (*c!='e' && *c!='E') break;
00599       /* Found 'e' or 'E' -- now process explicit exponent */
00600       // 1998.07.11: sign no longer required
00601       nege=0;
00602       c++;                         // to (possible) sign
00603 
00604       if (*c=='-') {nege=1; c++;}
00605           else if (*c=='+') c++;
00606       if (*c=='\0') break;
00607 
00608 
00609       for (; *c=='0' && *(c+1)!='\0';) c++;  // strip insignificant zeros
00610       firstexp=c;                            // save exponent digit place
00611       for (; ;c++) {
00612         if (*c<'0' || *c>'9') break;         // not a digit
00613         exponent=X10(exponent)+(Int)*c-(Int)'0';
00614         } // c
00615       // if not now on a '\0', *c must not be a digit
00616       if (*c!='\0') break;
00617 
00618       // (this next test must be after the syntax checks)
00619       // if it was too long the exponent may have wrapped, so check
00620       // carefully and set it to a certain overflow if wrap possible
00621       if (c>=firstexp+9+1) {
00622         if (c>firstexp+9+1 || *firstexp>'1') exponent=DECNUMMAXE*2;
00623         // [up to 1999999999 is OK, for example 1E-1000000998]
00624         }
00625       if (nege) exponent=-exponent;     // was negative
00626       status=0;                         // is OK
00627       } // stuff after digits
00628 
00629     // Here when whole string has been inspected; syntax is good
00630     // cfirst->first digit (never dot), last->last digit (ditto)
00631 
00632     // strip leading zeros/dot [leave final 0 if all 0's]
00633     if (*cfirst=='0') {                 // [cfirst has stepped over .]
00634       for (c=cfirst; c<last; c++, cfirst++) {
00635 // JPL-------------------------------------------------------------------
00636         if (*c=='.' && _EnFr_ == DEC_English) continue;          // ignore dots
00637         if (*c==',' && _EnFr_ == DEC_French) continue;          // ignore dots
00638 // JPL-------------------------------------------------------------------
00639         if (*c!='0') break;             // non-zero found
00640         d--;                            // 0 stripped
00641         } // c
00642       #if DECSUBSET
00643       // make a rapid exit for easy zeros if !extended
00644       if (*cfirst=='0' && !set->extended) {
00645         decNumberZero(dn);              // clean result
00646         break;                          // [could be return]
00647         }
00648       #endif
00649       } // at least one leading 0
00650 
00651     // Handle decimal point...
00652     if (dotchar!=NULL && dotchar<last)  // non-trailing '.' found?
00653       exponent-=(last-dotchar);         // adjust exponent
00654     // [we can now ignore the .]
00655 
00656     // OK, the digits string is good.  Assemble in the decNumber, or in
00657     // a temporary units array if rounding is needed
00658     if (d<=set->digits) res=dn->lsu;    // fits into supplied decNumber
00659      else {                             // rounding needed
00660       Int needbytes=D2U(d)*sizeof(Unit);// bytes needed
00661       res=resbuff;                      // assume use local buffer
00662       if (needbytes>(Int)sizeof(resbuff)) { // too big for local
00663         allocres=(Unit *)malloc(needbytes);
00664         if (allocres==NULL) {status|=DEC_Insufficient_storage; break;}
00665         res=allocres;
00666         }
00667       }
00668     // res now -> number lsu, buffer, or allocated storage for Unit array
00669 
00670     // Place the coefficient into the selected Unit array
00671     // [this is often 70% of the cost of this function when DECDPUN>1]
00672     #if DECDPUN>1
00673     out=0;                         // accumulator
00674     up=res+D2U(d)-1;               // -> msu
00675     cut=d-(up-res)*DECDPUN;        // digits in top unit
00676     for (c=cfirst;; c++) {         // along the digits
00677 // JPL ----------------------------------------------------------------------------
00678       if (*c=='.' && _EnFr_ ==DEC_English ) continue;       // ignore '.' [don't decrement cut]
00679       if (*c==',' && _EnFr_ ==DEC_French ) continue;       // ignore ',' [don't decrement cut]
00680 // JPL ----------------------------------------------------------------------------
00681       out=X10(out)+(Int)*c-(Int)'0';
00682       if (c==last) break;          // done [never get to trailing '.']
00683       cut--;
00684       if (cut>0) continue;         // more for this unit
00685       *up=(Unit)out;               // write unit
00686       up--;                        // prepare for unit below..
00687       cut=DECDPUN;                 // ..
00688       out=0;                       // ..
00689       } // c
00690     *up=(Unit)out;                 // write lsu
00691 
00692     #else
00693     // DECDPUN==1
00694     up=res;                        // -> lsu
00695     for (c=last; c>=cfirst; c--) { // over each character, from least
00696   switch (_EnFr_){
00697 
00698  case  DEC_English :
00699       if (*c=='.') continue; break;      // ignore . [don't step up]
00700 
00701 // JPL french ------------------------------------------------------------
00702  case  DEC_French :
00703            if (*c==',') continue;  break     // ignore . [don't step up]
00704 // JPL french ------------------------------------------------------------
00705   }
00706       *up=(Unit)((Int)*c-(Int)'0');
00707       up++;
00708       } // c
00709     #endif
00710 
00711     dn->bits=bits;
00712     dn->exponent=exponent;
00713     dn->digits=d;
00714 
00715     // if not in number (too long) shorten into the number
00716     if (d>set->digits) {
00717       residue=0;
00718       decSetCoeff(dn, set, res, d, &residue, &status);
00719       // always check for overflow or subnormal and round as needed
00720       decFinalize(dn, set, &residue, &status);
00721       }
00722      else { // no rounding, but may still have overflow or subnormal
00723       // [these tests are just for performance; finalize repeats them]
00724       if ((dn->exponent-1<set->emin-dn->digits)
00725        || (dn->exponent-1>set->emax-set->digits)) {
00726         residue=0;
00727         decFinalize(dn, set, &residue, &status);
00728         }
00729       }
00730     // decNumberShow(dn);
00731     } while(0);                         // [for break]
00732 
00733   if (allocres!=NULL) free(allocres);   // drop any storage used
00734   if (status!=0) decStatus(dn, status, set);
00735   return dn;
00736   } /* decNumberFromString */

decNumber* decNumberFromUInt32 ( decNumber dn,
uInt  uin 
)

Définition à la ligne 349 du fichier decNumber.c.

Références decGetDigits(), decNumberZero(), decNumber::digits, decNumber::lsu, et Unit.

Référencé par decNumberFromInt32().

00349                                                          {
00350   Unit *up;                             // work pointer
00351   decNumberZero(dn);                    // clean
00352   if (uin==0) return dn;                // [or decGetDigits bad call]
00353   for (up=dn->lsu; uin>0; up++) {
00354     *up=(Unit)(uin%(DECDPUNMAX+1));
00355     uin=uin/(DECDPUNMAX+1);
00356     }
00357   dn->digits=decGetDigits(dn->lsu, up-dn->lsu);
00358   return dn;
00359   } // decNumberFromUInt32

uByte* decNumberGetBCD ( const decNumber dn,
uByte *  bcd 
)

Définition à la ligne 3470 du fichier decNumber.c.

Références DECDPUN, decNumber::digits, decNumber::lsu, uByte, et uInt.

03470                                                          {
03471   uByte *ub=bcd+dn->digits-1;      // -> lsd
03472   const Unit *up=dn->lsu;          // Unit pointer, -> lsu
03473 
03474   #if DECDPUN==1                   // trivial simple copy
03475     for (; ub>=bcd; ub--, up++) *ub=*up;
03476   #else                            // chopping needed
03477     uInt u=*up;                    // work
03478     uInt cut=DECDPUN;              // downcounter through unit
03479     for (; ub>=bcd; ub--) {
03480       *ub=(uByte)(u%10);           // [*6554 trick inhibits, here]
03481       u=u/10;
03482       cut--;
03483       if (cut>0) continue;         // more in this unit
03484       up++;
03485       u=*up;
03486       cut=DECDPUN;
03487       }
03488   #endif
03489   return bcd;
03490   } // decNumberGetBCD

decNumber* decNumberInvert ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1213 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decNumber::digits, decContext::digits, decNumber::exponent, Int, decNumber::lsu, MSUDIGITS, et powers.

01214                                              {
01215   const Unit *ua, *msua;                // -> operand and its msu
01216   Unit  *uc, *msuc;                     // -> result and its msu
01217   Int   msudigs;                        // digits in res msu
01218   #if DECCHECK
01219   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01220   #endif
01221 
01222   if (rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
01223     decStatus(res, DEC_Invalid_operation, set);
01224     return res;
01225     }
01226   // operand is valid
01227   ua=rhs->lsu;                          // bottom-up
01228   uc=res->lsu;                          // ..
01229   msua=ua+D2U(rhs->digits)-1;           // -> msu of rhs
01230   msuc=uc+D2U(set->digits)-1;           // -> msu of result
01231   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
01232   for (; uc<=msuc; ua++, uc++) {        // Unit loop
01233     Unit a;                             // extract unit
01234     Int  i, j;                          // work
01235     if (ua>msua) a=0;
01236      else a=*ua;
01237     *uc=0;                              // can now write back
01238     // always need to examine all bits in rhs
01239     // This loop could be unrolled and/or use BIN2BCD tables
01240     for (i=0; i<DECDPUN; i++) {
01241       if ((~a)&1) *uc=*uc+(Unit)powers[i];   // effect INVERT
01242       j=a%10;
01243       a=a/10;
01244       if (j>1) {
01245         decStatus(res, DEC_Invalid_operation, set);
01246         return res;
01247         }
01248       if (uc==msuc && i==msudigs-1) break;   // just did final digit
01249       } // each digit
01250     } // each unit
01251   // [here uc-1 is the msu of the result]
01252   res->digits=decGetDigits(res->lsu, uc-res->lsu);
01253   res->exponent=0;                      // integer
01254   res->bits=0;                          // sign=0
01255   return res;  // [no status to set]
01256   } // decNumberInvert

Int decNumberIsNormal ( const decNumber dn,
decContext set 
)

Définition à la ligne 3529 du fichier decNumber.c.

Références decNumberIsSpecial, decNumberIsZero, decNumber::digits, decNumber::exponent, et Int.

Référencé par decNumberClass(), et decNumberNextToward().

03529                                                             {
03530   Int ae;                               // adjusted exponent
03531   #if DECCHECK
03532   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
03533   #endif
03534 
03535   if (decNumberIsSpecial(dn)) return 0; // not finite
03536   if (decNumberIsZero(dn)) return 0;    // not non-zero
03537 
03538   ae=dn->exponent+dn->digits-1;         // adjusted exponent
03539   if (ae<set->emin) return 0;           // is subnormal
03540   return 1;
03541   } // decNumberIsNormal

Int decNumberIsSubnormal ( const decNumber dn,
decContext set 
)

Définition à la ligne 3549 du fichier decNumber.c.

Références decNumberIsSpecial, decNumberIsZero, decNumber::digits, decNumber::exponent, et Int.

03549                                                                {
03550   Int ae;                               // adjusted exponent
03551   #if DECCHECK
03552   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
03553   #endif
03554 
03555   if (decNumberIsSpecial(dn)) return 0; // not finite
03556   if (decNumberIsZero(dn)) return 0;    // not non-zero
03557 
03558   ae=dn->exponent+dn->digits-1;         // adjusted exponent
03559   if (ae<set->emin) return 1;           // is subnormal
03560   return 0;
03561   } // decNumberIsSubnormal

decNumber* decNumberLn ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1286 du fichier decNumber.c.

Références DEC_Invalid_operation, decCheckMath(), decLnOp(), decStatus(), decNumber::digits, decContext::digits, ISZERO, et uInt.

01287                                          {
01288   uInt status=0;                   // accumulator
01289   #if DECSUBSET
01290   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
01291   #endif
01292 
01293   #if DECCHECK
01294   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01295   #endif
01296 
01297   // Check restrictions; this is a math function; if not violated
01298   // then carry out the operation.
01299   if (!decCheckMath(rhs, set, &status)) do { // protect allocation
01300     #if DECSUBSET
01301     if (!set->extended) {
01302       // reduce operand and set lostDigits status, as needed
01303       if (rhs->digits>set->digits) {
01304         allocrhs=decRoundOperand(rhs, set, &status);
01305         if (allocrhs==NULL) break;
01306         rhs=allocrhs;
01307         }
01308       // special check in subset for rhs=0
01309       if (ISZERO(rhs)) {                // +/- zeros -> error
01310         status|=DEC_Invalid_operation;
01311         break;}
01312       } // extended=0
01313     #endif
01314     decLnOp(res, rhs, set, &status);
01315     } while(0);                         // end protected
01316 
01317   #if DECSUBSET
01318   if (allocrhs !=NULL) free(allocrhs);  // drop any storage used
01319   #endif
01320   // apply significant status
01321   if (status!=0) decStatus(res, status, set);
01322   #if DECCHECK
01323   decCheckInexact(res, set);
01324   #endif
01325   return res;
01326   } // decNumberLn

decNumber* decNumberLog10 ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1408 du fichier decNumber.c.

Références decNumber::bits, decContext::clamp, D2N, D2U, DEC_Inexact, DEC_INIT_DECIMAL64, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_MAX_MATH, DEC_NaNs, DEC_sNaN, DECBUFFER, decCheckMath(), decContextDefault(), decCopyFit(), decDivideOp(), decFinish, decLnOp(), DECNEG, decNumberCopy(), decNumberFromInt32(), decNumberZero(), DECSPECIAL, decStatus(), decNumber::digits, decContext::digits, DIVIDE, decContext::emax, decContext::emin, decNumber::exponent, Int, ISZERO, decNumber::lsu, et uInt.

01409                                            {
01410   uInt status=0, ignore=0;         // status accumulators
01411   uInt needbytes;                  // for space calculations
01412   Int p;                           // working precision
01413   Int t;                           // digits in exponent of A
01414 
01415   // buffers for a and b working decimals
01416   // (adjustment calculator, same size)
01417   decNumber bufa[D2N(DECBUFFER+2)];
01418   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
01419   decNumber *a=bufa;               // temporary a
01420   decNumber bufb[D2N(DECBUFFER+2)];
01421   decNumber *allocbufb=NULL;       // -> allocated bufb, iff allocated
01422   decNumber *b=bufb;               // temporary b
01423   decNumber bufw[D2N(10)];         // working 2-10 digit number
01424   decNumber *w=bufw;               // ..
01425   #if DECSUBSET
01426   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
01427   #endif
01428 
01429   decContext aset;                 // working context
01430 
01431   #if DECCHECK
01432   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01433   #endif
01434 
01435   // Check restrictions; this is a math function; if not violated
01436   // then carry out the operation.
01437   if (!decCheckMath(rhs, set, &status)) do { // protect malloc
01438     #if DECSUBSET
01439     if (!set->extended) {
01440       // reduce operand and set lostDigits status, as needed
01441       if (rhs->digits>set->digits) {
01442         allocrhs=decRoundOperand(rhs, set, &status);
01443         if (allocrhs==NULL) break;
01444         rhs=allocrhs;
01445         }
01446       // special check in subset for rhs=0
01447       if (ISZERO(rhs)) {                // +/- zeros -> error
01448         status|=DEC_Invalid_operation;
01449         break;}
01450       } // extended=0
01451     #endif
01452 
01453     decContextDefault(&aset, DEC_INIT_DECIMAL64); // clean context
01454 
01455     // handle exact powers of 10; only check if +ve finite
01456     if (!(rhs->bits&(DECNEG|DECSPECIAL)) && !ISZERO(rhs)) {
01457       Int residue=0;               // (no residue)
01458       uInt copystat=0;             // clean status
01459 
01460       // round to a single digit...
01461       aset.digits=1;
01462       decCopyFit(w, rhs, &aset, &residue, &copystat); // copy & shorten
01463       // if exact and the digit is 1, rhs is a power of 10
01464       if (!(copystat&DEC_Inexact) && w->lsu[0]==1) {
01465         // the exponent, conveniently, is the power of 10; making
01466         // this the result needs a little care as it might not fit,
01467         // so first convert it into the working number, and then move
01468         // to res
01469         decNumberFromInt32(w, w->exponent);
01470         residue=0;
01471         decCopyFit(res, w, set, &residue, &status); // copy & round
01472         decFinish(res, set, &residue, &status);     // cleanup/set flags
01473         break;
01474         } // not a power of 10
01475       } // not a candidate for exact
01476 
01477     // simplify the information-content calculation to use 'total
01478     // number of digits in a, including exponent' as compared to the
01479     // requested digits, as increasing this will only rarely cost an
01480     // iteration in ln(a) anyway
01481     t=6;                                // it can never be >6
01482 
01483     // allocate space when needed...
01484     p=(rhs->digits+t>set->digits?rhs->digits+t:set->digits)+3;
01485     needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
01486     if (needbytes>sizeof(bufa)) {       // need malloc space
01487       allocbufa=(decNumber *)malloc(needbytes);
01488       if (allocbufa==NULL) {            // hopeless -- abandon
01489         status|=DEC_Insufficient_storage;
01490         break;}
01491       a=allocbufa;                      // use the allocated space
01492       }
01493     aset.digits=p;                      // as calculated
01494     aset.emax=DEC_MAX_MATH;             // usual bounds
01495     aset.emin=-DEC_MAX_MATH;            // ..
01496     aset.clamp=0;                       // and no concrete format
01497     decLnOp(a, rhs, &aset, &status);    // a=ln(rhs)
01498 
01499     // skip the division if the result so far is infinite, NaN, or
01500     // zero, or there was an error; note NaN from sNaN needs copy
01501     if (status&DEC_NaNs && !(status&DEC_sNaN)) break;
01502     if (a->bits&DECSPECIAL || ISZERO(a)) {
01503       decNumberCopy(res, a);            // [will fit]
01504       break;}
01505 
01506     // for ln(10) an extra 3 digits of precision are needed
01507     p=set->digits+3;
01508     needbytes=sizeof(decNumber)+(D2U(p)-1)*sizeof(Unit);
01509     if (needbytes>sizeof(bufb)) {       // need malloc space
01510       allocbufb=(decNumber *)malloc(needbytes);
01511       if (allocbufb==NULL) {            // hopeless -- abandon
01512         status|=DEC_Insufficient_storage;
01513         break;}
01514       b=allocbufb;                      // use the allocated space
01515       }
01516     decNumberZero(w);                   // set up 10...
01517     #if DECDPUN==1
01518     w->lsu[1]=1; w->lsu[0]=0;           // ..
01519     #else
01520     w->lsu[0]=10;                       // ..
01521     #endif
01522     w->digits=2;                        // ..
01523 
01524     aset.digits=p;
01525     decLnOp(b, w, &aset, &ignore);      // b=ln(10)
01526 
01527     aset.digits=set->digits;            // for final divide
01528     decDivideOp(res, a, b, &aset, DIVIDE, &status); // into result
01529     } while(0);                         // [for break]
01530 
01531   if (allocbufa!=NULL) free(allocbufa); // drop any storage used
01532   if (allocbufb!=NULL) free(allocbufb); // ..
01533   #if DECSUBSET
01534   if (allocrhs !=NULL) free(allocrhs);  // ..
01535   #endif
01536   // apply significant status
01537   if (status!=0) decStatus(res, status, set);
01538   #if DECCHECK
01539   decCheckInexact(res, set);
01540   #endif
01541   return res;
01542   } // decNumberLog10

decNumber* decNumberLogB ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1352 du fichier decNumber.c.

Références DEC_Division_by_zero, DECINF, decNaNs(), DECNEG, decNumberCopyAbs(), decNumberFromInt32(), decNumberIsInfinite, decNumberIsNaN, decNumberIsZero, decNumberZero(), decStatus(), decNumber::digits, decNumber::exponent, Int, et uInt.

01353                                            {
01354   uInt status=0;                   // accumulator
01355 
01356   #if DECCHECK
01357   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01358   #endif
01359 
01360   // NaNs as usual; Infinities return +Infinity; 0->oops
01361   if (decNumberIsNaN(rhs)) decNaNs(res, rhs, NULL, set, &status);
01362    else if (decNumberIsInfinite(rhs)) decNumberCopyAbs(res, rhs);
01363    else if (decNumberIsZero(rhs)) {
01364     decNumberZero(res);                 // prepare for Infinity
01365     res->bits=DECNEG|DECINF;            // -Infinity
01366     status|=DEC_Division_by_zero;       // as per 754
01367     }
01368    else { // finite non-zero
01369     Int ae=rhs->exponent+rhs->digits-1; // adjusted exponent
01370     decNumberFromInt32(res, ae);        // lay it out
01371     }
01372 
01373   if (status!=0) decStatus(res, status, set);
01374   return res;
01375   } // decNumberLogB

decNumber* decNumberMax ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1556 du fichier decNumber.c.

Références COMPMAX, decCompareOp(), decStatus(), et uInt.

Référencé par max().

01557                                                                 {
01558   uInt status=0;                        // accumulator
01559   decCompareOp(res, lhs, rhs, set, COMPMAX, &status);
01560   if (status!=0) decStatus(res, status, set);
01561   #if DECCHECK
01562   decCheckInexact(res, set);
01563   #endif
01564   return res;
01565   } // decNumberMax

decNumber* decNumberMaxMag ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1579 du fichier decNumber.c.

Références COMPMAXMAG, decCompareOp(), decStatus(), et uInt.

01580                                                                 {
01581   uInt status=0;                        // accumulator
01582   decCompareOp(res, lhs, rhs, set, COMPMAXMAG, &status);
01583   if (status!=0) decStatus(res, status, set);
01584   #if DECCHECK
01585   decCheckInexact(res, set);
01586   #endif
01587   return res;
01588   } // decNumberMaxMag

decNumber* decNumberMin ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1602 du fichier decNumber.c.

Références COMPMIN, decCompareOp(), decStatus(), et uInt.

Référencé par min().

01603                                                                 {
01604   uInt status=0;                        // accumulator
01605   decCompareOp(res, lhs, rhs, set, COMPMIN, &status);
01606   if (status!=0) decStatus(res, status, set);
01607   #if DECCHECK
01608   decCheckInexact(res, set);
01609   #endif
01610   return res;
01611   } // decNumberMin

decNumber* decNumberMinMag ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1625 du fichier decNumber.c.

Références COMPMINMAG, decCompareOp(), decStatus(), et uInt.

01626                                                                 {
01627   uInt status=0;                        // accumulator
01628   decCompareOp(res, lhs, rhs, set, COMPMINMAG, &status);
01629   if (status!=0) decStatus(res, status, set);
01630   #if DECCHECK
01631   decCheckInexact(res, set);
01632   #endif
01633   return res;
01634   } // decNumberMinMag

decNumber* decNumberMinus ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1650 du fichier decNumber.c.

Références decAddOp(), DECNEG, decNumberZero(), decStatus(), decNumber::exponent, et uInt.

Référencé par DecFloat_::operator-().

01651                                             {
01652   decNumber dzero;
01653   uInt status=0;                        // accumulator
01654 
01655   #if DECCHECK
01656   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01657   #endif
01658 
01659   decNumberZero(&dzero);                // make 0
01660   dzero.exponent=rhs->exponent;         // [no coefficient expansion]
01661   decAddOp(res, &dzero, rhs, set, DECNEG, &status);
01662   if (status!=0) decStatus(res, status, set);
01663   #if DECCHECK
01664   decCheckInexact(res, set);
01665   #endif
01666   return res;
01667   } // decNumberMinus

decNumber* decNumberMultiply ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1924 du fichier decNumber.c.

Références decMultiplyOp(), decStatus(), et uInt.

Référencé par DecFloat_::operator *=().

01925                                                                      {
01926   uInt status=0;                   // accumulator
01927   decMultiplyOp(res, lhs, rhs, set, &status);
01928   if (status!=0) decStatus(res, status, set);
01929   #if DECCHECK
01930   decCheckInexact(res, set);
01931   #endif
01932   return res;
01933   } // decNumberMultiply

decNumber* decNumberNextMinus ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1680 du fichier decNumber.c.

Références decNumber::bits, DEC_Invalid_operation, DEC_MIN_EMIN, DEC_ROUND_FLOOR, DEC_sNaN, decAddOp(), DECINF, DECNEG, decNumberZero(), decSetMaxValue(), decStatus(), decNumber::exponent, decNumber::lsu, decContext::round, et uInt.

01681                                                 {
01682   decNumber dtiny;                           // constant
01683   decContext workset=*set;                   // work
01684   uInt status=0;                             // accumulator
01685   #if DECCHECK
01686   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01687   #endif
01688 
01689   // +Infinity is the special case
01690   if ((rhs->bits&(DECINF|DECNEG))==DECINF) {
01691     decSetMaxValue(res, set);                // is +ve
01692     // there is no status to set
01693     return res;
01694     }
01695   decNumberZero(&dtiny);                     // start with 0
01696   dtiny.lsu[0]=1;                            // make number that is ..
01697   dtiny.exponent=DEC_MIN_EMIN-1;             // .. smaller than tiniest
01698   workset.round=DEC_ROUND_FLOOR;
01699   decAddOp(res, rhs, &dtiny, &workset, DECNEG, &status);
01700   status&=DEC_Invalid_operation|DEC_sNaN;    // only sNaN Invalid please
01701   if (status!=0) decStatus(res, status, set);
01702   return res;
01703   } // decNumberNextMinus

decNumber* decNumberNextPlus ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1716 du fichier decNumber.c.

Références decNumber::bits, DEC_Invalid_operation, DEC_MIN_EMIN, DEC_ROUND_CEILING, DEC_sNaN, decAddOp(), DECINF, DECNEG, decNumberZero(), decSetMaxValue(), decStatus(), decNumber::exponent, decNumber::lsu, decContext::round, et uInt.

01717                                                {
01718   decNumber dtiny;                           // constant
01719   decContext workset=*set;                   // work
01720   uInt status=0;                             // accumulator
01721   #if DECCHECK
01722   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01723   #endif
01724 
01725   // -Infinity is the special case
01726   if ((rhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
01727     decSetMaxValue(res, set);
01728     res->bits=DECNEG;                        // negative
01729     // there is no status to set
01730     return res;
01731     }
01732   decNumberZero(&dtiny);                     // start with 0
01733   dtiny.lsu[0]=1;                            // make number that is ..
01734   dtiny.exponent=DEC_MIN_EMIN-1;             // .. smaller than tiniest
01735   workset.round=DEC_ROUND_CEILING;
01736   decAddOp(res, rhs, &dtiny, &workset, 0, &status);
01737   status&=DEC_Invalid_operation|DEC_sNaN;    // only sNaN Invalid please
01738   if (status!=0) decStatus(res, status, set);
01739   return res;
01740   } // decNumberNextPlus

decNumber* decNumberNextToward ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1756 du fichier decNumber.c.

Références BADINT, decNumber::bits, DEC_Insufficient_storage, DEC_MIN_EMIN, DEC_ROUND_CEILING, DEC_ROUND_FLOOR, decAddOp(), decCompare(), DECINF, decNaNs(), DECNEG, decNumberCopySign(), decNumberIsNaN, decNumberIsNormal(), decNumberZero(), decSetMaxValue(), decStatus(), decNumber::exponent, Int, decNumber::lsu, decContext::round, uByte, et uInt.

01757                                                                        {
01758   decNumber dtiny;                           // constant
01759   decContext workset=*set;                   // work
01760   Int result;                                // ..
01761   uInt status=0;                             // accumulator
01762   #if DECCHECK
01763   if (decCheckOperands(res, lhs, rhs, set)) return res;
01764   #endif
01765 
01766   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) {
01767     decNaNs(res, lhs, rhs, set, &status);
01768     }
01769    else { // Is numeric, so no chance of sNaN Invalid, etc.
01770     result=decCompare(lhs, rhs, 0);     // sign matters
01771     if (result==BADINT) status|=DEC_Insufficient_storage; // rare
01772      else { // valid compare
01773       if (result==0) decNumberCopySign(res, lhs, rhs); // easy
01774        else { // differ: need NextPlus or NextMinus
01775         uByte sub;                      // add or subtract
01776         if (result<0) {                 // lhs<rhs, do nextplus
01777           // -Infinity is the special case
01778           if ((lhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) {
01779             decSetMaxValue(res, set);
01780             res->bits=DECNEG;           // negative
01781             return res;                 // there is no status to set
01782             }
01783           workset.round=DEC_ROUND_CEILING;
01784           sub=0;                        // add, please
01785           } // plus
01786          else {                         // lhs>rhs, do nextminus
01787           // +Infinity is the special case
01788           if ((lhs->bits&(DECINF|DECNEG))==DECINF) {
01789             decSetMaxValue(res, set);
01790             return res;                 // there is no status to set
01791             }
01792           workset.round=DEC_ROUND_FLOOR;
01793           sub=DECNEG;                   // subtract, please
01794           } // minus
01795         decNumberZero(&dtiny);          // start with 0
01796         dtiny.lsu[0]=1;                 // make number that is ..
01797         dtiny.exponent=DEC_MIN_EMIN-1;  // .. smaller than tiniest
01798         decAddOp(res, lhs, &dtiny, &workset, sub, &status); // + or -
01799         // turn off exceptions if the result is a normal number
01800         // (including Nmin), otherwise let all status through
01801         if (decNumberIsNormal(res, set)) status=0;
01802         } // unequal
01803       } // compare OK
01804     } // numeric
01805   if (status!=0) decStatus(res, status, set);
01806   return res;
01807   } // decNumberNextToward

decNumber* decNumberNormalize ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 2326 du fichier decNumber.c.

Références decNumberReduce().

Référencé par DecFloat_::Normalize().

02327                                                 {
02328   return decNumberReduce(res, rhs, set);
02329   } // decNumberNormalize

decNumber* decNumberOr ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1824 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decNumber::digits, decContext::digits, decNumber::exponent, Int, decNumber::lsu, MSUDIGITS, et powers.

01825                                                                {
01826   const Unit *ua, *ub;                  // -> operands
01827   const Unit *msua, *msub;              // -> operand msus
01828   Unit  *uc, *msuc;                     // -> result and its msu
01829   Int   msudigs;                        // digits in res msu
01830   #if DECCHECK
01831   if (decCheckOperands(res, lhs, rhs, set)) return res;
01832   #endif
01833 
01834   if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
01835    || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
01836     decStatus(res, DEC_Invalid_operation, set);
01837     return res;
01838     }
01839   // operands are valid
01840   ua=lhs->lsu;                          // bottom-up
01841   ub=rhs->lsu;                          // ..
01842   uc=res->lsu;                          // ..
01843   msua=ua+D2U(lhs->digits)-1;           // -> msu of lhs
01844   msub=ub+D2U(rhs->digits)-1;           // -> msu of rhs
01845   msuc=uc+D2U(set->digits)-1;           // -> msu of result
01846   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
01847   for (; uc<=msuc; ua++, ub++, uc++) {  // Unit loop
01848     Unit a, b;                          // extract units
01849     if (ua>msua) a=0;
01850      else a=*ua;
01851     if (ub>msub) b=0;
01852      else b=*ub;
01853     *uc=0;                              // can now write back
01854     if (a|b) {                          // maybe 1 bits to examine
01855       Int i, j;
01856       // This loop could be unrolled and/or use BIN2BCD tables
01857       for (i=0; i<DECDPUN; i++) {
01858         if ((a|b)&1) *uc=*uc+(Unit)powers[i];     // effect OR
01859         j=a%10;
01860         a=a/10;
01861         j|=b%10;
01862         b=b/10;
01863         if (j>1) {
01864           decStatus(res, DEC_Invalid_operation, set);
01865           return res;
01866           }
01867         if (uc==msuc && i==msudigs-1) break;      // just did final digit
01868         } // each digit
01869       } // non-zero
01870     } // each unit
01871   // [here uc-1 is the msu of the result]
01872   res->digits=decGetDigits(res->lsu, uc-res->lsu);
01873   res->exponent=0;                      // integer
01874   res->bits=0;                          // sign=0
01875   return res;  // [no status to set]
01876   } // decNumberOr

decNumber* decNumberPlus ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1894 du fichier decNumber.c.

Références decAddOp(), decNumberZero(), decStatus(), decNumber::exponent, et uInt.

Référencé par DecFloat_::operator+().

01895                                            {
01896   decNumber dzero;
01897   uInt status=0;                        // accumulator
01898   #if DECCHECK
01899   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
01900   #endif
01901 
01902   decNumberZero(&dzero);                // make 0
01903   dzero.exponent=rhs->exponent;         // [no coefficient expansion]
01904   decAddOp(res, &dzero, rhs, set, 0, &status);
01905   if (status!=0) decStatus(res, status, set);
01906   #if DECCHECK
01907   decCheckInexact(res, set);
01908   #endif
01909   return res;
01910   } // decNumberPlus

decNumber* decNumberPower ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 1961 du fichier decNumber.c.

Références BADINT, BIGEVEN, BIGODD, decNumber::bits, decContext::clamp, D2N, D2U, DEC_Inexact, DEC_INIT_DECIMAL64, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_MAX_MATH, DEC_Overflow, DEC_ROUND_HALF_EVEN, DEC_Rounded, DEC_Subnormal, DEC_Underflow, DECBUFFER, decCheckMath(), decContextDefault(), decCopyFit(), decDivideOp(), decExpOp(), decFinalize(), decFinish, decGetInt(), DECINF, decLnOp(), decMultiplyOp(), decNaNs(), DECNEG, decNumberCompare(), decNumberCopy(), decNumberIsInfinite, decNumberIsNaN, decNumberIsNegative, decNumberIsZero, decNumberZero(), DECNUMMAXP, decShiftToMost(), decStatus(), decTrim(), decContext::digits, decNumber::digits, DIVIDE, decContext::emax, decContext::emin, decNumber::exponent, Flag, Int, ISZERO, decNumber::lsu, MAXI, decContext::round, SPECIALARGS, uByte, et uInt.

Référencé par pow().

01962                                                                   {
01963   #if DECSUBSET
01964   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
01965   decNumber *allocrhs=NULL;        // .., rhs
01966   #endif
01967   decNumber *allocdac=NULL;        // -> allocated acc buffer, iff used
01968   decNumber *allocinv=NULL;        // -> allocated 1/x buffer, iff used
01969   Int   reqdigits=set->digits;     // requested DIGITS
01970   Int   n;                         // rhs in binary
01971   Flag  rhsint=0;                  // 1 if rhs is an integer
01972   Flag  useint=0;                  // 1 if can use integer calculation
01973   Flag  isoddint=0;                // 1 if rhs is an integer and odd
01974   Int   i;                         // work
01975   #if DECSUBSET
01976   Int   dropped;                   // ..
01977   #endif
01978   uInt  needbytes;                 // buffer size needed
01979   Flag  seenbit;                   // seen a bit while powering
01980   Int   residue=0;                 // rounding residue
01981   uInt  status=0;                  // accumulators
01982   uByte bits=0;                    // result sign if errors
01983   decContext aset;                 // working context
01984   decNumber dnOne;                 // work value 1...
01985   // local accumulator buffer [a decNumber, with digits+elength+1 digits]
01986   decNumber dacbuff[D2N(DECBUFFER+9)];
01987   decNumber *dac=dacbuff;          // -> result accumulator
01988   // same again for possible 1/lhs calculation
01989   decNumber invbuff[D2N(DECBUFFER+9)];
01990 
01991   #if DECCHECK
01992   if (decCheckOperands(res, lhs, rhs, set)) return res;
01993   #endif
01994 
01995   do {                             // protect allocated storage
01996     #if DECSUBSET
01997     if (!set->extended) { // reduce operands and set status, as needed
01998       if (lhs->digits>reqdigits) {
01999         alloclhs=decRoundOperand(lhs, set, &status);
02000         if (alloclhs==NULL) break;
02001         lhs=alloclhs;
02002         }
02003       if (rhs->digits>reqdigits) {
02004         allocrhs=decRoundOperand(rhs, set, &status);
02005         if (allocrhs==NULL) break;
02006         rhs=allocrhs;
02007         }
02008       }
02009     #endif
02010     // [following code does not require input rounding]
02011 
02012     // handle NaNs and rhs Infinity (lhs infinity is harder)
02013     if (SPECIALARGS) {
02014       if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) { // NaNs
02015         decNaNs(res, lhs, rhs, set, &status);
02016         break;}
02017       if (decNumberIsInfinite(rhs)) {   // rhs Infinity
02018         Flag rhsneg=rhs->bits&DECNEG;   // save rhs sign
02019         if (decNumberIsNegative(lhs)    // lhs<0
02020          && !decNumberIsZero(lhs))      // ..
02021           status|=DEC_Invalid_operation;
02022          else {                         // lhs >=0
02023           decNumberZero(&dnOne);        // set up 1
02024           dnOne.lsu[0]=1;
02025           decNumberCompare(dac, lhs, &dnOne, set); // lhs ? 1
02026           decNumberZero(res);           // prepare for 0/1/Infinity
02027           if (decNumberIsNegative(dac)) {    // lhs<1
02028             if (rhsneg) res->bits|=DECINF;   // +Infinity [else is +0]
02029             }
02030            else if (dac->lsu[0]==0) {        // lhs=1
02031             // 1**Infinity is inexact, so return fully-padded 1.0000
02032             Int shift=set->digits-1;
02033             *res->lsu=1;                     // was 0, make int 1
02034             res->digits=decShiftToMost(res->lsu, 1, shift);
02035             res->exponent=-shift;            // make 1.0000...
02036             status|=DEC_Inexact|DEC_Rounded; // deemed inexact
02037             }
02038            else {                            // lhs>1
02039             if (!rhsneg) res->bits|=DECINF;  // +Infinity [else is +0]
02040             }
02041           } // lhs>=0
02042         break;}
02043       // [lhs infinity drops through]
02044       } // specials
02045 
02046     // Original rhs may be an integer that fits and is in range
02047     n=decGetInt(rhs);
02048     if (n!=BADINT) {                    // it is an integer
02049       rhsint=1;                         // record the fact for 1**n
02050       isoddint=(Flag)n&1;               // [works even if big]
02051       if (n!=BIGEVEN && n!=BIGODD)      // can use integer path?
02052         useint=1;                       // looks good
02053       }
02054 
02055     if (decNumberIsNegative(lhs)        // -x ..
02056       && isoddint) bits=DECNEG;         // .. to an odd power
02057 
02058     // handle LHS infinity
02059     if (decNumberIsInfinite(lhs)) {     // [NaNs already handled]
02060       uByte rbits=rhs->bits;            // save
02061       decNumberZero(res);               // prepare
02062       if (n==0) *res->lsu=1;            // [-]Inf**0 => 1
02063        else {
02064         // -Inf**nonint -> error
02065         if (!rhsint && decNumberIsNegative(lhs)) {
02066           status|=DEC_Invalid_operation;     // -Inf**nonint is error
02067           break;}
02068         if (!(rbits & DECNEG)) bits|=DECINF; // was not a **-n
02069         // [otherwise will be 0 or -0]
02070         res->bits=bits;
02071         }
02072       break;}
02073 
02074     // similarly handle LHS zero
02075     if (decNumberIsZero(lhs)) {
02076       if (n==0) {                            // 0**0 => Error
02077         #if DECSUBSET
02078         if (!set->extended) {                // [unless subset]
02079           decNumberZero(res);
02080           *res->lsu=1;                       // return 1
02081           break;}
02082         #endif
02083         status|=DEC_Invalid_operation;
02084         }
02085        else {                                // 0**x
02086         uByte rbits=rhs->bits;               // save
02087         if (rbits & DECNEG) {                // was a 0**(-n)
02088           #if DECSUBSET
02089           if (!set->extended) {              // [bad if subset]
02090             status|=DEC_Invalid_operation;
02091             break;}
02092           #endif
02093           bits|=DECINF;
02094           }
02095         decNumberZero(res);                  // prepare
02096         // [otherwise will be 0 or -0]
02097         res->bits=bits;
02098         }
02099       break;}
02100 
02101     // here both lhs and rhs are finite; rhs==0 is handled in the
02102     // integer path.  Next handle the non-integer cases
02103     if (!useint) {                      // non-integral rhs
02104       // any -ve lhs is bad, as is either operand or context out of
02105       // bounds
02106       if (decNumberIsNegative(lhs)) {
02107         status|=DEC_Invalid_operation;
02108         break;}
02109       if (decCheckMath(lhs, set, &status)
02110        || decCheckMath(rhs, set, &status)) break; // variable status
02111 
02112       decContextDefault(&aset, DEC_INIT_DECIMAL64); // clean context
02113       aset.emax=DEC_MAX_MATH;           // usual bounds
02114       aset.emin=-DEC_MAX_MATH;          // ..
02115       aset.clamp=0;                     // and no concrete format
02116 
02117       // calculate the result using exp(ln(lhs)*rhs), which can
02118       // all be done into the accumulator, dac.  The precision needed
02119       // is enough to contain the full information in the lhs (which
02120       // is the total digits, including exponent), or the requested
02121       // precision, if larger, + 4; 6 is used for the exponent
02122       // maximum length, and this is also used when it is shorter
02123       // than the requested digits as it greatly reduces the >0.5 ulp
02124       // cases at little cost (because Ln doubles digits each
02125       // iteration so a few extra digits rarely causes an extra
02126       // iteration)
02127       aset.digits=MAXI(lhs->digits, set->digits)+6+4;
02128       } // non-integer rhs
02129 
02130      else { // rhs is in-range integer
02131       if (n==0) {                       // x**0 = 1
02132         // (0**0 was handled above)
02133         decNumberZero(res);             // result=1
02134         *res->lsu=1;                    // ..
02135         break;}
02136       // rhs is a non-zero integer
02137       if (n<0) n=-n;                    // use abs(n)
02138 
02139       aset=*set;                        // clone the context
02140       aset.round=DEC_ROUND_HALF_EVEN;   // internally use balanced
02141       // calculate the working DIGITS
02142       aset.digits=reqdigits+(rhs->digits+rhs->exponent)+2;
02143       #if DECSUBSET
02144       if (!set->extended) aset.digits--;     // use classic precision
02145       #endif
02146       // it's an error if this is more than can be handled
02147       if (aset.digits>DECNUMMAXP) {status|=DEC_Invalid_operation; break;}
02148       } // integer path
02149 
02150     // aset.digits is the count of digits for the accumulator needed
02151     // if accumulator is too long for local storage, then allocate
02152     needbytes=sizeof(decNumber)+(D2U(aset.digits)-1)*sizeof(Unit);
02153     // [needbytes also used below if 1/lhs needed]
02154     if (needbytes>sizeof(dacbuff)) {
02155       allocdac=(decNumber *)malloc(needbytes);
02156       if (allocdac==NULL) {   // hopeless -- abandon
02157         status|=DEC_Insufficient_storage;
02158         break;}
02159       dac=allocdac;           // use the allocated space
02160       }
02161     // here, aset is set up and accumulator is ready for use
02162 
02163     if (!useint) {                           // non-integral rhs
02164       // x ** y; special-case x=1 here as it will otherwise always
02165       // reduce to integer 1; decLnOp has a fastpath which detects
02166       // the case of x=1
02167       decLnOp(dac, lhs, &aset, &status);     // dac=ln(lhs)
02168       // [no error possible, as lhs 0 already handled]
02169       if (ISZERO(dac)) {                     // x==1, 1.0, etc.
02170         // need to return fully-padded 1.0000 etc., but rhsint->1
02171         *dac->lsu=1;                         // was 0, make int 1
02172         if (!rhsint) {                       // add padding
02173           Int shift=set->digits-1;
02174           dac->digits=decShiftToMost(dac->lsu, 1, shift);
02175           dac->exponent=-shift;              // make 1.0000...
02176           status|=DEC_Inexact|DEC_Rounded;   // deemed inexact
02177           }
02178         }
02179        else {
02180         decMultiplyOp(dac, dac, rhs, &aset, &status);  // dac=dac*rhs
02181         decExpOp(dac, dac, &aset, &status);            // dac=exp(dac)
02182         }
02183       // and drop through for final rounding
02184       } // non-integer rhs
02185 
02186      else {                             // carry on with integer
02187       decNumberZero(dac);               // acc=1
02188       *dac->lsu=1;                      // ..
02189 
02190       // if a negative power the constant 1 is needed, and if not subset
02191       // invert the lhs now rather than inverting the result later
02192       if (decNumberIsNegative(rhs)) {   // was a **-n [hence digits>0]
02193         decNumber *inv=invbuff;         // asssume use fixed buffer
02194         decNumberCopy(&dnOne, dac);     // dnOne=1;  [needed now or later]
02195         #if DECSUBSET
02196         if (set->extended) {            // need to calculate 1/lhs
02197         #endif
02198           // divide lhs into 1, putting result in dac [dac=1/dac]
02199           decDivideOp(dac, &dnOne, lhs, &aset, DIVIDE, &status);
02200           // now locate or allocate space for the inverted lhs
02201           if (needbytes>sizeof(invbuff)) {
02202             allocinv=(decNumber *)malloc(needbytes);
02203             if (allocinv==NULL) {       // hopeless -- abandon
02204               status|=DEC_Insufficient_storage;
02205               break;}
02206             inv=allocinv;               // use the allocated space
02207             }
02208           // [inv now points to big-enough buffer or allocated storage]
02209           decNumberCopy(inv, dac);      // copy the 1/lhs
02210           decNumberCopy(dac, &dnOne);   // restore acc=1
02211           lhs=inv;                      // .. and go forward with new lhs
02212         #if DECSUBSET
02213           }
02214         #endif
02215         }
02216 
02217       // Raise-to-the-power loop...
02218       seenbit=0;                   // set once a 1-bit is encountered
02219       for (i=1;;i++){              // for each bit [top bit ignored]
02220         // abandon if had overflow or terminal underflow
02221         if (status & (DEC_Overflow|DEC_Underflow)) { // interesting?
02222           if (status&DEC_Overflow || ISZERO(dac)) break;
02223           }
02224         // [the following two lines revealed an optimizer bug in a C++
02225         // compiler, with symptom: 5**3 -> 25, when n=n+n was used]
02226         n=n<<1;                    // move next bit to testable position
02227         if (n<0) {                 // top bit is set
02228           seenbit=1;               // OK, significant bit seen
02229           decMultiplyOp(dac, dac, lhs, &aset, &status); // dac=dac*x
02230           }
02231         if (i==31) break;          // that was the last bit
02232         if (!seenbit) continue;    // no need to square 1
02233         decMultiplyOp(dac, dac, dac, &aset, &status); // dac=dac*dac [square]
02234         } /*i*/ // 32 bits
02235 
02236       // complete internal overflow or underflow processing
02237       if (status & (DEC_Overflow|DEC_Underflow)) {
02238         #if DECSUBSET
02239         // If subset, and power was negative, reverse the kind of -erflow
02240         // [1/x not yet done]
02241         if (!set->extended && decNumberIsNegative(rhs)) {
02242           if (status & DEC_Overflow)
02243             status^=DEC_Overflow | DEC_Underflow | DEC_Subnormal;
02244            else { // trickier -- Underflow may or may not be set
02245             status&=~(DEC_Underflow | DEC_Subnormal); // [one or both]
02246             status|=DEC_Overflow;
02247             }
02248           }
02249         #endif
02250         dac->bits=(dac->bits & ~DECNEG) | bits; // force correct sign
02251         // round subnormals [to set.digits rather than aset.digits]
02252         // or set overflow result similarly as required
02253         decFinalize(dac, set, &residue, &status);
02254         decNumberCopy(res, dac);   // copy to result (is now OK length)
02255         break;
02256         }
02257 
02258       #if DECSUBSET
02259       if (!set->extended &&                  // subset math
02260           decNumberIsNegative(rhs)) {        // was a **-n [hence digits>0]
02261         // so divide result into 1 [dac=1/dac]
02262         decDivideOp(dac, &dnOne, dac, &aset, DIVIDE, &status);
02263         }
02264       #endif
02265       } // rhs integer path
02266 
02267     // reduce result to the requested length and copy to result
02268     decCopyFit(res, dac, set, &residue, &status);
02269     decFinish(res, set, &residue, &status);  // final cleanup
02270     #if DECSUBSET
02271     if (!set->extended) decTrim(res, set, 0, 1, &dropped); // trailing zeros
02272     #endif
02273     } while(0);                         // end protected
02274 
02275   if (allocdac!=NULL) free(allocdac);   // drop any storage used
02276   if (allocinv!=NULL) free(allocinv);   // ..
02277   #if DECSUBSET
02278   if (alloclhs!=NULL) free(alloclhs);   // ..
02279   if (allocrhs!=NULL) free(allocrhs);   // ..
02280   #endif
02281   if (status!=0) decStatus(res, status, set);
02282   #if DECCHECK
02283   decCheckInexact(res, set);
02284   #endif
02285   return res;
02286   } // decNumberPower

decNumber* decNumberQuantize ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 2306 du fichier decNumber.c.

Références decQuantizeOp(), decStatus(), et uInt.

Référencé par decNumberToIntegralExact(), et DecFloat_::Quantize().

02307                                                                      {
02308   uInt status=0;                        // accumulator
02309   decQuantizeOp(res, lhs, rhs, set, 1, &status);
02310   if (status!=0) decStatus(res, status, set);
02311   return res;
02312   } // decNumberQuantize

decNumber* decNumberReduce ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 2331 du fichier decNumber.c.

Références decCopyFit(), decFinish, decNaNs(), decNumberIsNaN, decStatus(), decTrim(), decNumber::digits, decContext::digits, Int, et uInt.

Référencé par decNumberNormalize().

02332                                              {
02333   #if DECSUBSET
02334   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
02335   #endif
02336   uInt status=0;                   // as usual
02337   Int  residue=0;                  // as usual
02338   Int  dropped;                    // work
02339 
02340   #if DECCHECK
02341   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
02342   #endif
02343 
02344   do {                             // protect allocated storage
02345     #if DECSUBSET
02346     if (!set->extended) {
02347       // reduce operand and set lostDigits status, as needed
02348       if (rhs->digits>set->digits) {
02349         allocrhs=decRoundOperand(rhs, set, &status);
02350         if (allocrhs==NULL) break;
02351         rhs=allocrhs;
02352         }
02353       }
02354     #endif
02355     // [following code does not require input rounding]
02356 
02357     // Infinities copy through; NaNs need usual treatment
02358     if (decNumberIsNaN(rhs)) {
02359       decNaNs(res, rhs, NULL, set, &status);
02360       break;
02361       }
02362 
02363     // reduce result to the requested length and copy to result
02364     decCopyFit(res, rhs, set, &residue, &status); // copy & round
02365     decFinish(res, set, &residue, &status);       // cleanup/set flags
02366     decTrim(res, set, 1, 0, &dropped);            // normalize in place
02367                                                   // [may clamp]
02368     } while(0);                              // end protected
02369 
02370   #if DECSUBSET
02371   if (allocrhs !=NULL) free(allocrhs);       // ..
02372   #endif
02373   if (status!=0) decStatus(res, status, set);// then report status
02374   return res;
02375   } // decNumberReduce

decNumber* decNumberRemainder ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 2415 du fichier decNumber.c.

Références decDivideOp(), decStatus(), REMAINDER, et uInt.

Référencé par DecFloat_::operator%=().

02416                                                                       {
02417   uInt status=0;                        // accumulator
02418   decDivideOp(res, lhs, rhs, set, REMAINDER, &status);
02419   if (status!=0) decStatus(res, status, set);
02420   #if DECCHECK
02421   decCheckInexact(res, set);
02422   #endif
02423   return res;
02424   } // decNumberRemainder

decNumber* decNumberRemainderNear ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 2438 du fichier decNumber.c.

Références decDivideOp(), decStatus(), REMNEAR, et uInt.

Référencé par RemainderNear().

02439                                                                           {
02440   uInt status=0;                        // accumulator
02441   decDivideOp(res, lhs, rhs, set, REMNEAR, &status);
02442   if (status!=0) decStatus(res, status, set);
02443   #if DECCHECK
02444   decCheckInexact(res, set);
02445   #endif
02446   return res;
02447   } // decNumberRemainderNear

decNumber* decNumberRescale ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 2395 du fichier decNumber.c.

Références decQuantizeOp(), decStatus(), et uInt.

Référencé par DecFloat_::Rescale(), et DecFloat_::ToChar().

02396                                                                     {
02397   uInt status=0;                        // accumulator
02398   decQuantizeOp(res, lhs, rhs, set, 0, &status);
02399   if (status!=0) decStatus(res, status, set);
02400   return res;
02401   } // decNumberRescale

decNumber* decNumberRotate ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 2474 du fichier decNumber.c.

Références abs(), BADINT, BIGEVEN, BIGODD, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decGetInt(), decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberIsNaN, decReverse(), decShiftToLeast(), decStatus(), decContext::digits, decNumber::exponent, Int, MSUDIGITS, powers, et uInt.

02475                                                                   {
02476   uInt status=0;              // accumulator
02477   Int  rotate;                // rhs as an Int
02478 
02479   #if DECCHECK
02480   if (decCheckOperands(res, lhs, rhs, set)) return res;
02481   #endif
02482 
02483   // NaNs propagate as normal
02484   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
02485     decNaNs(res, lhs, rhs, set, &status);
02486    // rhs must be an integer
02487    else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
02488     status=DEC_Invalid_operation;
02489    else { // both numeric, rhs is an integer
02490     rotate=decGetInt(rhs);                   // [cannot fail]
02491     if (rotate==BADINT                       // something bad ..
02492      || rotate==BIGODD || rotate==BIGEVEN    // .. very big ..
02493      || abs(rotate)>set->digits)             // .. or out of range
02494       status=DEC_Invalid_operation;
02495      else {                                  // rhs is OK
02496       decNumberCopy(res, lhs);
02497       // convert -ve rotate to equivalent positive rotation
02498       if (rotate<0) rotate=set->digits+rotate;
02499       if (rotate!=0 && rotate!=set->digits   // zero or full rotation
02500        && !decNumberIsInfinite(res)) {       // lhs was infinite
02501         // left-rotate to do; 0 < rotate < set->digits
02502         uInt units, shift;                   // work
02503         uInt msudigits;                      // digits in result msu
02504         Unit *msu=res->lsu+D2U(res->digits)-1;    // current msu
02505         Unit *msumax=res->lsu+D2U(set->digits)-1; // rotation msu
02506         for (msu++; msu<=msumax; msu++) *msu=0;   // ensure high units=0
02507         res->digits=set->digits;                  // now full-length
02508         msudigits=MSUDIGITS(res->digits);         // actual digits in msu
02509 
02510         // rotation here is done in-place, in three steps
02511         // 1. shift all to least up to one unit to unit-align final
02512         //    lsd [any digits shifted out are rotated to the left,
02513         //    abutted to the original msd (which may require split)]
02514         //
02515         //    [if there are no whole units left to rotate, the
02516         //    rotation is now complete]
02517         //
02518         // 2. shift to least, from below the split point only, so that
02519         //    the final msd is in the right place in its Unit [any
02520         //    digits shifted out will fit exactly in the current msu,
02521         //    left aligned, no split required]
02522         //
02523         // 3. rotate all the units by reversing left part, right
02524         //    part, and then whole
02525         //
02526         // example: rotate right 8 digits (2 units + 2), DECDPUN=3.
02527         //
02528         //   start: 00a bcd efg hij klm npq
02529         //
02530         //      1a  000 0ab cde fgh|ijk lmn [pq saved]
02531         //      1b  00p qab cde fgh|ijk lmn
02532         //
02533         //      2a  00p qab cde fgh|00i jkl [mn saved]
02534         //      2b  mnp qab cde fgh|00i jkl
02535         //
02536         //      3a  fgh cde qab mnp|00i jkl
02537         //      3b  fgh cde qab mnp|jkl 00i
02538         //      3c  00i jkl mnp qab cde fgh
02539 
02540         // Step 1: amount to shift is the partial right-rotate count
02541         rotate=set->digits-rotate;      // make it right-rotate
02542         units=rotate/DECDPUN;           // whole units to rotate
02543         shift=rotate%DECDPUN;           // left-over digits count
02544         if (shift>0) {                  // not an exact number of units
02545           uInt save=res->lsu[0]%powers[shift];    // save low digit(s)
02546           decShiftToLeast(res->lsu, D2U(res->digits), shift);
02547           if (shift>msudigits) {        // msumax-1 needs >0 digits
02548             uInt rem=save%powers[shift-msudigits];// split save
02549             *msumax=(Unit)(save/powers[shift-msudigits]); // and insert
02550             *(msumax-1)=*(msumax-1)
02551                        +(Unit)(rem*powers[DECDPUN-(shift-msudigits)]); // ..
02552             }
02553            else { // all fits in msumax
02554             *msumax=*msumax+(Unit)(save*powers[msudigits-shift]); // [maybe *1]
02555             }
02556           } // digits shift needed
02557 
02558         // If whole units to rotate...
02559         if (units>0) {                  // some to do
02560           // Step 2: the units to touch are the whole ones in rotate,
02561           //   if any, and the shift is DECDPUN-msudigits (which may be
02562           //   0, again)
02563           shift=DECDPUN-msudigits;
02564           if (shift>0) {                // not an exact number of units
02565             uInt save=res->lsu[0]%powers[shift];  // save low digit(s)
02566             decShiftToLeast(res->lsu, units, shift);
02567             *msumax=*msumax+(Unit)(save*powers[msudigits]);
02568             } // partial shift needed
02569 
02570           // Step 3: rotate the units array using triple reverse
02571           // (reversing is easy and fast)
02572           decReverse(res->lsu+units, msumax);     // left part
02573           decReverse(res->lsu, res->lsu+units-1); // right part
02574           decReverse(res->lsu, msumax);           // whole
02575           } // whole units to rotate
02576         // the rotation may have left an undetermined number of zeros
02577         // on the left, so true length needs to be calculated
02578         res->digits=decGetDigits(res->lsu, msumax-res->lsu+1);
02579         } // rotate needed
02580       } // rhs OK
02581     } // numerics
02582   if (status!=0) decStatus(res, status, set);
02583   return res;
02584   } // decNumberRotate

decNumber* decNumberSameQuantum ( decNumber res,
const decNumber lhs,
const decNumber rhs 
)

Définition à la ligne 2595 du fichier decNumber.c.

Références decNumberIsInfinite, decNumberIsNaN, decNumberZero(), decNumber::exponent, decNumber::lsu, et SPECIALARGS.

Référencé par DecFloat_::SameQuantum().

02596                                                        {
02597   Unit ret=0;                      // return value
02598 
02599   #if DECCHECK
02600   if (decCheckOperands(res, lhs, rhs, DECUNCONT)) return res;
02601   #endif
02602 
02603   if (SPECIALARGS) {
02604     if (decNumberIsNaN(lhs) && decNumberIsNaN(rhs)) ret=1;
02605      else if (decNumberIsInfinite(lhs) && decNumberIsInfinite(rhs)) ret=1;
02606      // [anything else with a special gives 0]
02607     }
02608    else if (lhs->exponent==rhs->exponent) ret=1;
02609 
02610   decNumberZero(res);              // OK to overwrite an operand now
02611   *res->lsu=ret;
02612   return res;
02613   } // decNumberSameQuantum

decNumber* decNumberScaleB ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 2630 du fichier decNumber.c.

Références abs(), BADINT, BIGEVEN, BIGODD, DEC_Invalid_operation, decFinalize(), decGetInt(), decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberIsNaN, decStatus(), decContext::digits, decContext::emax, decNumber::exponent, Int, et uInt.

02631                                                                    {
02632   Int  reqexp;                // requested exponent change [B]
02633   uInt status=0;              // accumulator
02634   Int  residue;               // work
02635 
02636   #if DECCHECK
02637   if (decCheckOperands(res, lhs, rhs, set)) return res;
02638   #endif
02639 
02640   // Handle special values except lhs infinite
02641   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
02642     decNaNs(res, lhs, rhs, set, &status);
02643     // rhs must be an integer
02644    else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
02645     status=DEC_Invalid_operation;
02646    else {
02647     // lhs is a number; rhs is a finite with q==0
02648     reqexp=decGetInt(rhs);                   // [cannot fail]
02649     if (reqexp==BADINT                       // something bad ..
02650      || reqexp==BIGODD || reqexp==BIGEVEN    // .. very big ..
02651      || abs(reqexp)>(2*(set->digits+set->emax))) // .. or out of range
02652       status=DEC_Invalid_operation;
02653      else {                                  // rhs is OK
02654       decNumberCopy(res, lhs);               // all done if infinite lhs
02655       if (!decNumberIsInfinite(res)) {       // prepare to scale
02656         res->exponent+=reqexp;               // adjust the exponent
02657         residue=0;
02658         decFinalize(res, set, &residue, &status); // .. and check
02659         } // finite LHS
02660       } // rhs OK
02661     } // rhs finite
02662   if (status!=0) decStatus(res, status, set);
02663   return res;
02664   } // decNumberScaleB

decNumber* decNumberSetBCD ( decNumber dn,
const uByte *  bcd,
uInt  n 
)

Définition à la ligne 3504 du fichier decNumber.c.

Références D2U, DECDPUN, decNumber::digits, Int, decNumber::lsu, MSUDIGITS, uByte, et X10.

03504                                                                      {
03505   Unit *up=dn->lsu+D2U(dn->digits)-1;   // -> msu [target pointer]
03506   const uByte *ub=bcd;                  // -> source msd
03507 
03508   #if DECDPUN==1                        // trivial simple copy
03509     for (; ub<bcd+n; ub++, up--) *up=*ub;
03510   #else                                 // some assembly needed
03511     // calculate how many digits in msu, and hence first cut
03512     Int cut=MSUDIGITS(n);               // [faster than remainder]
03513     for (;up>=dn->lsu; up--) {          // each Unit from msu
03514       *up=0;                            // will take <=DECDPUN digits
03515       for (; cut>0; ub++, cut--) *up=X10(*up)+*ub;
03516       cut=DECDPUN;                      // next Unit has all digits
03517       }
03518   #endif
03519   dn->digits=n;                         // set digit count
03520   return dn;
03521   } // decNumberSetBCD

decNumber* decNumberShift ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 2687 du fichier decNumber.c.

Références abs(), BADINT, BIGEVEN, BIGODD, D2U, DEC_Invalid_operation, decDecap(), decGetInt(), decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberIsNaN, decShiftToLeast(), decShiftToMost(), decStatus(), decContext::digits, decNumber::exponent, Int, et uInt.

02688                                                                   {
02689   uInt status=0;              // accumulator
02690   Int  shift;                 // rhs as an Int
02691 
02692   #if DECCHECK
02693   if (decCheckOperands(res, lhs, rhs, set)) return res;
02694   #endif
02695 
02696   // NaNs propagate as normal
02697   if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs))
02698     decNaNs(res, lhs, rhs, set, &status);
02699    // rhs must be an integer
02700    else if (decNumberIsInfinite(rhs) || rhs->exponent!=0)
02701     status=DEC_Invalid_operation;
02702    else { // both numeric, rhs is an integer
02703     shift=decGetInt(rhs);                    // [cannot fail]
02704     if (shift==BADINT                        // something bad ..
02705      || shift==BIGODD || shift==BIGEVEN      // .. very big ..
02706      || abs(shift)>set->digits)              // .. or out of range
02707       status=DEC_Invalid_operation;
02708      else {                                  // rhs is OK
02709       decNumberCopy(res, lhs);
02710       if (shift!=0 && !decNumberIsInfinite(res)) { // something to do
02711         if (shift>0) {                       // to left
02712           if (shift==set->digits) {          // removing all
02713             *res->lsu=0;                     // so place 0
02714             res->digits=1;                   // ..
02715             }
02716            else {                            //
02717             // first remove leading digits if necessary
02718             if (res->digits+shift>set->digits) {
02719               decDecap(res, res->digits+shift-set->digits);
02720               // that updated res->digits; may have gone to 1 (for a
02721               // single digit or for zero
02722               }
02723             if (res->digits>1 || *res->lsu)  // if non-zero..
02724               res->digits=decShiftToMost(res->lsu, res->digits, shift);
02725             } // partial left
02726           } // left
02727          else { // to right
02728           if (-shift>=res->digits) {         // discarding all
02729             *res->lsu=0;                     // so place 0
02730             res->digits=1;                   // ..
02731             }
02732            else {
02733             decShiftToLeast(res->lsu, D2U(res->digits), -shift);
02734             res->digits-=(-shift);
02735             }
02736           } // to right
02737         } // non-0 non-Inf shift
02738       } // rhs OK
02739     } // numerics
02740   if (status!=0) decStatus(res, status, set);
02741   return res;
02742   } // decNumberShift

decNumber* decNumberSquareRoot ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 2816 du fichier decNumber.c.

Références decNumber::bits, decContext::clamp, COMPARE, D2N, D2U, DEC_Clamped, DEC_Inexact, DEC_INIT_DECIMAL64, DEC_Insufficient_storage, DEC_Invalid_operation, DEC_MAX_EMAX, DEC_MIN_EMIN, DEC_Overflow, DEC_ROUND_DOWN, DEC_ROUND_HALF_EVEN, DEC_ROUND_UP, DEC_Rounded, DEC_Subnormal, DEC_Underflow, decAddOp(), DECBUFFER, decCompareOp(), decContextDefault(), decCopyFit(), decDivideOp(), decFinish, decMultiplyOp(), decNaNs(), DECNEG, decNumberCopy(), decNumberIsInfinite, decNumberIsNegative, decNumberZero(), decShiftToLeast(), decStatus(), decTrim(), decNumber::digits, decContext::digits, DIVIDE, decContext::emax, decContext::emin, decNumber::exponent, Int, ISZERO, decNumber::lsu, MAXI, MINI, decContext::round, SPECIALARG, et uInt.

Référencé par sqrt().

02817                                                  {
02818   decContext workset, approxset;   // work contexts
02819   decNumber dzero;                 // used for constant zero
02820   Int  maxp;                       // largest working precision
02821   Int  workp;                      // working precision
02822   Int  residue=0;                  // rounding residue
02823   uInt status=0, ignore=0;         // status accumulators
02824   uInt rstatus;                    // ..
02825   Int  exp;                        // working exponent
02826   Int  ideal;                      // ideal (preferred) exponent
02827   Int  needbytes;                  // work
02828   Int  dropped;                    // ..
02829 
02830   #if DECSUBSET
02831   decNumber *allocrhs=NULL;        // non-NULL if rounded rhs allocated
02832   #endif
02833   // buffer for f [needs +1 in case DECBUFFER 0]
02834   decNumber buff[D2N(DECBUFFER+1)];
02835   // buffer for a [needs +2 to match likely maxp]
02836   decNumber bufa[D2N(DECBUFFER+2)];
02837   // buffer for temporary, b [must be same size as a]
02838   decNumber bufb[D2N(DECBUFFER+2)];
02839   decNumber *allocbuff=NULL;       // -> allocated buff, iff allocated
02840   decNumber *allocbufa=NULL;       // -> allocated bufa, iff allocated
02841   decNumber *allocbufb=NULL;       // -> allocated bufb, iff allocated
02842   decNumber *f=buff;               // reduced fraction
02843   decNumber *a=bufa;               // approximation to result
02844   decNumber *b=bufb;               // intermediate result
02845   // buffer for temporary variable, up to 3 digits
02846   decNumber buft[D2N(3)];
02847   decNumber *t=buft;               // up-to-3-digit constant or work
02848 
02849   #if DECCHECK
02850   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
02851   #endif
02852 
02853   do {                             // protect allocated storage
02854     #if DECSUBSET
02855     if (!set->extended) {
02856       // reduce operand and set lostDigits status, as needed
02857       if (rhs->digits>set->digits) {
02858         allocrhs=decRoundOperand(rhs, set, &status);
02859         if (allocrhs==NULL) break;
02860         // [Note: 'f' allocation below could reuse this buffer if
02861         // used, but as this is rare they are kept separate for clarity.]
02862         rhs=allocrhs;
02863         }
02864       }
02865     #endif
02866     // [following code does not require input rounding]
02867 
02868     // handle infinities and NaNs
02869     if (SPECIALARG) {
02870       if (decNumberIsInfinite(rhs)) {         // an infinity
02871         if (decNumberIsNegative(rhs)) status|=DEC_Invalid_operation;
02872          else decNumberCopy(res, rhs);        // +Infinity
02873         }
02874        else decNaNs(res, rhs, NULL, set, &status); // a NaN
02875       break;
02876       }
02877 
02878     // calculate the ideal (preferred) exponent [floor(exp/2)]
02879     // [It would be nicer to write: ideal=rhs->exponent>>1, but this
02880     // generates a compiler warning.  Generated code is the same.]
02881     ideal=(rhs->exponent&~1)/2;         // target
02882 
02883     // handle zeros
02884     if (ISZERO(rhs)) {
02885       decNumberCopy(res, rhs);          // could be 0 or -0
02886       res->exponent=ideal;              // use the ideal [safe]
02887       // use decFinish to clamp any out-of-range exponent, etc.
02888       decFinish(res, set, &residue, &status);
02889       break;
02890       }
02891 
02892     // any other -x is an oops
02893     if (decNumberIsNegative(rhs)) {
02894       status|=DEC_Invalid_operation;
02895       break;
02896       }
02897 
02898     // space is needed for three working variables
02899     //   f -- the same precision as the RHS, reduced to 0.01->0.99...
02900     //   a -- Hull's approximation -- precision, when assigned, is
02901     //        currentprecision+1 or the input argument precision,
02902     //        whichever is larger (+2 for use as temporary)
02903     //   b -- intermediate temporary result (same size as a)
02904     // if any is too long for local storage, then allocate
02905     workp=MAXI(set->digits+1, rhs->digits);  // actual rounding precision
02906     workp=MAXI(workp, 7);                    // at least 7 for low cases
02907     maxp=workp+2;                            // largest working precision
02908 
02909     needbytes=sizeof(decNumber)+(D2U(rhs->digits)-1)*sizeof(Unit);
02910     if (needbytes>(Int)sizeof(buff)) {
02911       allocbuff=(decNumber *)malloc(needbytes);
02912       if (allocbuff==NULL) {  // hopeless -- abandon
02913         status|=DEC_Insufficient_storage;
02914         break;}
02915       f=allocbuff;            // use the allocated space
02916       }
02917     // a and b both need to be able to hold a maxp-length number
02918     needbytes=sizeof(decNumber)+(D2U(maxp)-1)*sizeof(Unit);
02919     if (needbytes>(Int)sizeof(bufa)) {            // [same applies to b]
02920       allocbufa=(decNumber *)malloc(needbytes);
02921       allocbufb=(decNumber *)malloc(needbytes);
02922       if (allocbufa==NULL || allocbufb==NULL) {   // hopeless
02923         status|=DEC_Insufficient_storage;
02924         break;}
02925       a=allocbufa;            // use the allocated spaces
02926       b=allocbufb;            // ..
02927       }
02928 
02929     // copy rhs -> f, save exponent, and reduce so 0.1 <= f < 1
02930     decNumberCopy(f, rhs);
02931     exp=f->exponent+f->digits;               // adjusted to Hull rules
02932     f->exponent=-(f->digits);                // to range
02933 
02934     // set up working context
02935     decContextDefault(&workset, DEC_INIT_DECIMAL64);
02936     workset.emax=DEC_MAX_EMAX;
02937     workset.emin=DEC_MIN_EMIN;
02938 
02939     // [Until further notice, no error is possible and status bits
02940     // (Rounded, etc.) should be ignored, not accumulated.]
02941 
02942     // Calculate initial approximation, and allow for odd exponent
02943     workset.digits=workp;                    // p for initial calculation
02944     t->bits=0; t->digits=3;
02945     a->bits=0; a->digits=3;
02946     if ((exp & 1)==0) {                      // even exponent
02947       // Set t=0.259, a=0.819
02948       t->exponent=-3;
02949       a->exponent=-3;
02950       #if DECDPUN>=3
02951         t->lsu[0]=259;
02952         a->lsu[0]=819;
02953       #elif DECDPUN==2
02954         t->lsu[0]=59; t->lsu[1]=2;
02955         a->lsu[0]=19; a->lsu[1]=8;
02956       #else
02957         t->lsu[0]=9; t->lsu[1]=5; t->lsu[2]=2;
02958         a->lsu[0]=9; a->lsu[1]=1; a->lsu[2]=8;
02959       #endif
02960       }
02961      else {                                  // odd exponent
02962       // Set t=0.0819, a=2.59
02963       f->exponent--;                         // f=f/10
02964       exp++;                                 // e=e+1
02965       t->exponent=-4;
02966       a->exponent=-2;
02967       #if DECDPUN>=3
02968         t->lsu[0]=819;
02969         a->lsu[0]=259;
02970       #elif DECDPUN==2
02971         t->lsu[0]=19; t->lsu[1]=8;
02972         a->lsu[0]=59; a->lsu[1]=2;
02973       #else
02974         t->lsu[0]=9; t->lsu[1]=1; t->lsu[2]=8;
02975         a->lsu[0]=9; a->lsu[1]=5; a->lsu[2]=2;
02976       #endif
02977       }
02978 
02979     decMultiplyOp(a, a, f, &workset, &ignore);    // a=a*f
02980     decAddOp(a, a, t, &workset, 0, &ignore);      // ..+t
02981     // [a is now the initial approximation for sqrt(f), calculated with
02982     // currentprecision, which is also a's precision.]
02983 
02984     // the main calculation loop
02985     decNumberZero(&dzero);                   // make 0
02986     decNumberZero(t);                        // set t = 0.5
02987     t->lsu[0]=5;                             // ..
02988     t->exponent=-1;                          // ..
02989     workset.digits=3;                        // initial p
02990     for (; workset.digits<maxp;) {
02991       // set p to min(2*p - 2, maxp)  [hence 3; or: 4, 6, 10, ... , maxp]
02992       workset.digits=MINI(workset.digits*2-2, maxp);
02993       // a = 0.5 * (a + f/a)
02994       // [calculated at p then rounded to currentprecision]
02995       decDivideOp(b, f, a, &workset, DIVIDE, &ignore); // b=f/a
02996       decAddOp(b, b, a, &workset, 0, &ignore);         // b=b+a
02997       decMultiplyOp(a, b, t, &workset, &ignore);       // a=b*0.5
02998       } // loop
02999 
03000     // Here, 0.1 <= a < 1 [Hull], and a has maxp digits
03001     // now reduce to length, etc.; this needs to be done with a
03002     // having the correct exponent so as to handle subnormals
03003     // correctly
03004     approxset=*set;                          // get emin, emax, etc.
03005     approxset.round=DEC_ROUND_HALF_EVEN;
03006     a->exponent+=exp/2;                      // set correct exponent
03007     rstatus=0;                               // clear status
03008     residue=0;                               // .. and accumulator
03009     decCopyFit(a, a, &approxset, &residue, &rstatus);  // reduce (if needed)
03010     decFinish(a, &approxset, &residue, &rstatus);      // clean and finalize
03011 
03012     // Overflow was possible if the input exponent was out-of-range,
03013     // in which case quit
03014     if (rstatus&DEC_Overflow) {
03015       status=rstatus;                        // use the status as-is
03016       decNumberCopy(res, a);                 // copy to result
03017       break;
03018       }
03019 
03020     // Preserve status except Inexact/Rounded
03021     status|=(rstatus & ~(DEC_Rounded|DEC_Inexact));
03022 
03023     // Carry out the Hull correction
03024     a->exponent-=exp/2;                      // back to 0.1->1
03025 
03026     // a is now at final precision and within 1 ulp of the properly
03027     // rounded square root of f; to ensure proper rounding, compare
03028     // squares of (a - l/2 ulp) and (a + l/2 ulp) with f.
03029     // Here workset.digits=maxp and t=0.5, and a->digits determines
03030     // the ulp
03031     workset.digits--;                             // maxp-1 is OK now
03032     t->exponent=-a->digits-1;                     // make 0.5 ulp
03033     decAddOp(b, a, t, &workset, DECNEG, &ignore); // b = a - 0.5 ulp
03034     workset.round=DEC_ROUND_UP;
03035     decMultiplyOp(b, b, b, &workset, &ignore);    // b = mulru(b, b)
03036     decCompareOp(b, f, b, &workset, COMPARE, &ignore); // b ? f, reversed
03037     if (decNumberIsNegative(b)) {                 // f < b [i.e., b > f]
03038       // this is the more common adjustment, though both are rare
03039       t->exponent++;                              // make 1.0 ulp
03040       t->lsu[0]=1;                                // ..
03041       decAddOp(a, a, t, &workset, DECNEG, &ignore); // a = a - 1 ulp
03042       // assign to approx [round to length]
03043       approxset.emin-=exp/2;                      // adjust to match a
03044       approxset.emax-=exp/2;
03045       decAddOp(a, &dzero, a, &approxset, 0, &ignore);
03046       }
03047      else {
03048       decAddOp(b, a, t, &workset, 0, &ignore);    // b = a + 0.5 ulp
03049       workset.round=DEC_ROUND_DOWN;
03050       decMultiplyOp(b, b, b, &workset, &ignore);  // b = mulrd(b, b)
03051       decCompareOp(b, b, f, &workset, COMPARE, &ignore);   // b ? f
03052       if (decNumberIsNegative(b)) {               // b < f
03053         t->exponent++;                            // make 1.0 ulp
03054         t->lsu[0]=1;                              // ..
03055         decAddOp(a, a, t, &workset, 0, &ignore);  // a = a + 1 ulp
03056         // assign to approx [round to length]
03057         approxset.emin-=exp/2;                    // adjust to match a
03058         approxset.emax-=exp/2;
03059         decAddOp(a, &dzero, a, &approxset, 0, &ignore);
03060         }
03061       }
03062     // [no errors are possible in the above, and rounding/inexact during
03063     // estimation are irrelevant, so status was not accumulated]
03064 
03065     // Here, 0.1 <= a < 1  (still), so adjust back
03066     a->exponent+=exp/2;                      // set correct exponent
03067 
03068     // count droppable zeros [after any subnormal rounding] by
03069     // trimming a copy
03070     decNumberCopy(b, a);
03071     decTrim(b, set, 1, 1, &dropped);         // [drops trailing zeros]
03072 
03073     // Set Inexact and Rounded.  The answer can only be exact if
03074     // it is short enough so that squaring it could fit in workp
03075     // digits, so this is the only (relatively rare) condition that
03076     // a careful check is needed
03077     if (b->digits*2-1 > workp) {             // cannot fit
03078       status|=DEC_Inexact|DEC_Rounded;
03079       }
03080      else {                                  // could be exact/unrounded
03081       uInt mstatus=0;                        // local status
03082       decMultiplyOp(b, b, b, &workset, &mstatus); // try the multiply
03083       if (mstatus&DEC_Overflow) {            // result just won't fit
03084         status|=DEC_Inexact|DEC_Rounded;
03085         }
03086        else {                                // plausible
03087         decCompareOp(t, b, rhs, &workset, COMPARE, &mstatus); // b ? rhs
03088         if (!ISZERO(t)) status|=DEC_Inexact|DEC_Rounded; // not equal
03089          else {                              // is Exact
03090           // here, dropped is the count of trailing zeros in 'a'
03091           // use closest exponent to ideal...
03092           Int todrop=ideal-a->exponent;      // most that can be dropped
03093           if (todrop<0) status|=DEC_Rounded; // ideally would add 0s
03094            else {                            // unrounded
03095             // there are some to drop, but emax may not allow all
03096             Int maxexp=set->emax-set->digits+1;
03097             Int maxdrop=maxexp-a->exponent;
03098             if (todrop>maxdrop && set->clamp) { // apply clamping
03099               todrop=maxdrop;
03100               status|=DEC_Clamped;
03101               }
03102             if (dropped<todrop) {            // clamp to those available
03103               todrop=dropped;
03104               status|=DEC_Clamped;
03105               }
03106             if (todrop>0) {                  // have some to drop
03107               decShiftToLeast(a->lsu, D2U(a->digits), todrop);
03108               a->exponent+=todrop;           // maintain numerical value
03109               a->digits-=todrop;             // new length
03110               }
03111             }
03112           }
03113         }
03114       }
03115 
03116     // double-check Underflow, as perhaps the result could not have
03117     // been subnormal (initial argument too big), or it is now Exact
03118     if (status&DEC_Underflow) {
03119       Int ae=rhs->exponent+rhs->digits-1;    // adjusted exponent
03120       // check if truly subnormal
03121       #if DECEXTFLAG                         // DEC_Subnormal too
03122         if (ae>=set->emin*2) status&=~(DEC_Subnormal|DEC_Underflow);
03123       #else
03124         if (ae>=set->emin*2) status&=~DEC_Underflow;
03125       #endif
03126       // check if truly inexact
03127       if (!(status&DEC_Inexact)) status&=~DEC_Underflow;
03128       }
03129 
03130     decNumberCopy(res, a);                   // a is now the result
03131     } while(0);                              // end protected
03132 
03133   if (allocbuff!=NULL) free(allocbuff);      // drop any storage used
03134   if (allocbufa!=NULL) free(allocbufa);      // ..
03135   if (allocbufb!=NULL) free(allocbufb);      // ..
03136   #if DECSUBSET
03137   if (allocrhs !=NULL) free(allocrhs);       // ..
03138   #endif
03139   if (status!=0) decStatus(res, status, set);// then report status
03140   #if DECCHECK
03141   decCheckInexact(res, set);
03142   #endif
03143   return res;
03144   } // decNumberSquareRoot

decNumber* decNumberSubtract ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 3158 du fichier decNumber.c.

Références decAddOp(), DECNEG, decStatus(), et uInt.

Référencé par DecFloat_::operator-=().

03159                                                                      {
03160   uInt status=0;                        // accumulator
03161 
03162   decAddOp(res, lhs, rhs, set, DECNEG, &status);
03163   if (status!=0) decStatus(res, status, set);
03164   #if DECCHECK
03165   decCheckInexact(res, set);
03166   #endif
03167   return res;
03168   } // decNumberSubtract

char* decNumberToEngString ( const decNumber dn,
char *  string 
)

Définition à la ligne 455 du fichier decNumber.c.

Références decToString().

Référencé par DecFloat_::ToChar(), et DecFloat_::ToStr().

00455                                                               {
00456   decToString(dn, string, 1);
00457   return string;
00458   } // DecNumberToEngString

Int decNumberToInt32 ( const decNumber dn,
decContext set 
)

Définition à la ligne 371 du fichier decNumber.c.

Références decNumber::bits, DEC_Invalid_operation, decContextSetStatus(), DECDPUN, DECNEG, DECSPECIAL, decNumber::digits, decNumber::exponent, Int, decNumber::lsu, powers, uInt, Unit, et X10.

00371                                                            {
00372   #if DECCHECK
00373   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
00374   #endif
00375 
00376   // special or too many digits, or bad exponent
00377   if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0) ; // bad
00378    else { // is a finite integer with 10 or fewer digits
00379     Int d;                         // work
00380     const Unit *up;                // ..
00381     uInt hi=0, lo;                 // ..
00382     up=dn->lsu;                    // -> lsu
00383     lo=*up;                        // get 1 to 9 digits
00384     #if DECDPUN>1                  // split to higher
00385       hi=lo/10;
00386       lo=lo%10;
00387     #endif
00388     up++;
00389     // collect remaining Units, if any, into hi
00390     for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];
00391     // now low has the lsd, hi the remainder
00392     if (hi>214748364 || (hi==214748364 && lo>7)) { // out of range?
00393       // most-negative is a reprieve
00394       if (dn->bits&DECNEG && hi==214748364 && lo==8) return 0x80000000;
00395       // bad -- drop through
00396       }
00397      else { // in-range always
00398       Int i=X10(hi)+lo;
00399       if (dn->bits&DECNEG) return -i;
00400       return i;
00401       }
00402     } // integer
00403   decContextSetStatus(set, DEC_Invalid_operation); // [may not return]
00404   return 0;
00405   } // decNumberToInt32

decNumber* decNumberToIntegralExact ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 3191 du fichier decNumber.c.

Références decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberQuantize(), decNumberZero(), decStatus(), decContext::digits, decNumber::digits, decNumber::exponent, SPECIALARG, decContext::status, decContext::traps, et uInt.

Référencé par decNumberToIntegralValue().

03192                                                       {
03193   decNumber dn;
03194   decContext workset;              // working context
03195   uInt status=0;                   // accumulator
03196 
03197   #if DECCHECK
03198   if (decCheckOperands(res, DECUNUSED, rhs, set)) return res;
03199   #endif
03200 
03201   // handle infinities and NaNs
03202   if (SPECIALARG) {
03203     if (decNumberIsInfinite(rhs)) decNumberCopy(res, rhs); // an Infinity
03204      else decNaNs(res, rhs, NULL, set, &status); // a NaN
03205     }
03206    else { // finite
03207     // have a finite number; no error possible (res must be big enough)
03208     if (rhs->exponent>=0) return decNumberCopy(res, rhs);
03209     // that was easy, but if negative exponent there is work to do...
03210     workset=*set;                  // clone rounding, etc.
03211     workset.digits=rhs->digits;    // no length rounding
03212     workset.traps=0;               // no traps
03213     decNumberZero(&dn);            // make a number with exponent 0
03214     decNumberQuantize(res, rhs, &dn, &workset);
03215     status|=workset.status;
03216     }
03217   if (status!=0) decStatus(res, status, set);
03218   return res;
03219   } // decNumberToIntegralExact

decNumber* decNumberToIntegralValue ( decNumber res,
const decNumber rhs,
decContext set 
)

Définition à la ligne 3221 du fichier decNumber.c.

Références DEC_Invalid_operation, decNumberToIntegralExact(), decContext::status, et decContext::traps.

Référencé par DecFloat_::ToIntegralValue().

03222                                                       {
03223   decContext workset=*set;         // working context
03224   workset.traps=0;                 // no traps
03225   decNumberToIntegralExact(res, rhs, &workset);
03226   // this never affects set, except for sNaNs; NaN will have been set
03227   // or propagated already, so no need to call decStatus
03228   set->status|=workset.status&DEC_Invalid_operation;
03229   return res;
03230   } // decNumberToIntegralValue

char* decNumberToString ( const decNumber dn,
char *  string 
)

Définition à la ligne 450 du fichier decNumber.c.

Références decToString().

00450                                                            {
00451   decToString(dn, string, 0);
00452   return string;
00453   } // DecNumberToString

uInt decNumberToUInt32 ( const decNumber dn,
decContext set 
)

Définition à la ligne 407 du fichier decNumber.c.

Références decNumber::bits, DEC_Invalid_operation, decContextSetStatus(), DECDPUN, DECNEG, DECSPECIAL, decNumber::digits, decNumber::exponent, Int, ISZERO, decNumber::lsu, powers, uInt, Unit, et X10.

00407                                                              {
00408   #if DECCHECK
00409   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, set)) return 0;
00410   #endif
00411   // special or too many digits, or bad exponent, or negative (<0)
00412   if (dn->bits&DECSPECIAL || dn->digits>10 || dn->exponent!=0
00413     || (dn->bits&DECNEG && !ISZERO(dn)));                   // bad
00414    else { // is a finite integer with 10 or fewer digits
00415     Int d;                         // work
00416     const Unit *up;                // ..
00417     uInt hi=0, lo;                 // ..
00418     up=dn->lsu;                    // -> lsu
00419     lo=*up;                        // get 1 to 9 digits
00420     #if DECDPUN>1                  // split to higher
00421       hi=lo/10;
00422       lo=lo%10;
00423     #endif
00424     up++;
00425     // collect remaining Units, if any, into hi
00426     for (d=DECDPUN; d<dn->digits; up++, d+=DECDPUN) hi+=*up*powers[d-1];
00427 
00428     // now low has the lsd, hi the remainder
00429     if (hi>429496729 || (hi==429496729 && lo>5)) ; // no reprieve possible
00430      else return X10(hi)+lo;
00431     } // integer
00432   decContextSetStatus(set, DEC_Invalid_operation); // [may not return]
00433   return 0;
00434   } // decNumberToUInt32

decNumber* decNumberTrim ( decNumber dn  ) 

Définition à la ligne 3573 du fichier decNumber.c.

Références DEC_INIT_BASE, decContextDefault(), decTrim(), et Int.

Référencé par DecFloat_::Trim().

03573                                          {
03574   Int  dropped;                    // work
03575   decContext set;                  // ..
03576   #if DECCHECK
03577   if (decCheckOperands(DECUNRESU, DECUNUSED, dn, DECUNCONT)) return dn;
03578   #endif
03579   decContextDefault(&set, DEC_INIT_BASE);    // clamp=0
03580   return decTrim(dn, &set, 0, 1, &dropped);
03581   } // decNumberTrim

const char* decNumberVersion ( void   ) 

Définition à la ligne 3588 du fichier decNumber.c.

Références DECVERSION.

03588                                     {
03589   return DECVERSION;
03590   } // decNumberVersion

decNumber* decNumberXor ( decNumber res,
const decNumber lhs,
const decNumber rhs,
decContext set 
)

Définition à la ligne 3247 du fichier decNumber.c.

Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decNumber::digits, decContext::digits, decNumber::exponent, Int, decNumber::lsu, MSUDIGITS, et powers.

03248                                                                 {
03249   const Unit *ua, *ub;                  // -> operands
03250   const Unit *msua, *msub;              // -> operand msus
03251   Unit  *uc, *msuc;                     // -> result and its msu
03252   Int   msudigs;                        // digits in res msu
03253   #if DECCHECK
03254   if (decCheckOperands(res, lhs, rhs, set)) return res;
03255   #endif
03256 
03257   if (lhs->exponent!=0 || decNumberIsSpecial(lhs) || decNumberIsNegative(lhs)
03258    || rhs->exponent!=0 || decNumberIsSpecial(rhs) || decNumberIsNegative(rhs)) {
03259     decStatus(res, DEC_Invalid_operation, set);
03260     return res;
03261     }
03262   // operands are valid
03263   ua=lhs->lsu;                          // bottom-up
03264   ub=rhs->lsu;                          // ..
03265   uc=res->lsu;                          // ..
03266   msua=ua+D2U(lhs->digits)-1;           // -> msu of lhs
03267   msub=ub+D2U(rhs->digits)-1;           // -> msu of rhs
03268   msuc=uc+D2U(set->digits)-1;           // -> msu of result
03269   msudigs=MSUDIGITS(set->digits);       // [faster than remainder]
03270   for (; uc<=msuc; ua++, ub++, uc++) {  // Unit loop
03271     Unit a, b;                          // extract units
03272     if (ua>msua) a=0;
03273      else a=*ua;
03274     if (ub>msub) b=0;
03275      else b=*ub;
03276     *uc=0;                              // can now write back
03277     if (a|b) {                          // maybe 1 bits to examine
03278       Int i, j;
03279       // This loop could be unrolled and/or use BIN2BCD tables
03280       for (i=0; i<DECDPUN; i++) {
03281         if ((a^b)&1) *uc=*uc+(Unit)powers[i];     // effect XOR
03282         j=a%10;
03283         a=a/10;
03284         j|=b%10;
03285         b=b/10;
03286         if (j>1) {
03287           decStatus(res, DEC_Invalid_operation, set);
03288           return res;
03289           }
03290         if (uc==msuc && i==msudigs-1) break;      // just did final digit
03291         } // each digit
03292       } // non-zero
03293     } // each unit
03294   // [here uc-1 is the msu of the result]
03295   res->digits=decGetDigits(res->lsu, uc-res->lsu);
03296   res->exponent=0;                      // integer
03297   res->bits=0;                          // sign=0
03298   return res;  // [no status to set]
03299   } // decNumberXor

decNumber* decNumberZero ( decNumber dn  ) 

Définition à la ligne 3601 du fichier decNumber.c.

Références decNumber::bits, decNumber::digits, decNumber::exponent, et decNumber::lsu.

Référencé par decAddOp(), decCompareOp(), decDivideOp(), decExpOp(), decFinalize(), DecFloat_::DecFloat_(), decLnOp(), decMultiplyOp(), decNumberAbs(), decNumberCopy(), decNumberFMA(), decNumberFromString(), decNumberFromUInt32(), decNumberLog10(), decNumberLogB(), decNumberMinus(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberPlus(), decNumberPower(), decNumberSameQuantum(), decNumberSquareRoot(), decNumberToIntegralExact(), decSetOverflow(), decSetSubnormal(), et decStatus().

03601                                          {
03602 
03603   #if DECCHECK
03604   if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
03605   #endif
03606 
03607   dn->bits=0;
03608   dn->exponent=0;
03609   dn->digits=1;
03610   dn->lsu[0]=0;
03611   return dn;
03612   } // decNumberZero

static decNumber * decQuantizeOp ( decNumber ,
const decNumber ,
const decNumber ,
decContext ,
Flag  ,
uInt *   
) [static]

Définition à la ligne 5844 du fichier decNumber.c.

Références BADINT, BIGEVEN, BIGODD, decNumber::bits, DEC_Inexact, DEC_Invalid_operation, DEC_Rounded, DEC_Underflow, decApplyRound(), decCopyFit(), decFinalize(), decGetInt(), DECINF, DECNAN, decNaNs(), decNumberCopy(), decShiftToMost(), DECSNAN, decNumber::digits, decContext::digits, decContext::emax, decContext::emin, decNumber::exponent, Int, ISZERO, decNumber::lsu, et SPECIALARGS.

Référencé par decNumberQuantize(), et decNumberRescale().

05846                                                            {
05847   #if DECSUBSET
05848   decNumber *alloclhs=NULL;        // non-NULL if rounded lhs allocated
05849   decNumber *allocrhs=NULL;        // .., rhs
05850   #endif
05851   const decNumber *inrhs=rhs;      // save original rhs
05852   Int   reqdigits=set->digits;     // requested DIGITS
05853   Int   reqexp;                    // requested exponent [-scale]
05854   Int   residue=0;                 // rounding residue
05855   Int   etiny=set->emin-(reqdigits-1);
05856 
05857   #if DECCHECK
05858   if (decCheckOperands(res, lhs, rhs, set)) return res;
05859   #endif
05860 
05861   do {                             // protect allocated storage
05862     #if DECSUBSET
05863     if (!set->extended) {
05864       // reduce operands and set lostDigits status, as needed
05865       if (lhs->digits>reqdigits) {
05866         alloclhs=decRoundOperand(lhs, set, status);
05867         if (alloclhs==NULL) break;
05868         lhs=alloclhs;
05869         }
05870       if (rhs->digits>reqdigits) { // [this only checks lostDigits]
05871         allocrhs=decRoundOperand(rhs, set, status);
05872         if (allocrhs==NULL) break;
05873         rhs=allocrhs;
05874         }
05875       }
05876     #endif
05877     // [following code does not require input rounding]
05878 
05879     // Handle special values
05880     if (SPECIALARGS) {
05881       // NaNs get usual processing
05882       if (SPECIALARGS & (DECSNAN | DECNAN))
05883         decNaNs(res, lhs, rhs, set, status);
05884       // one infinity but not both is bad
05885       else if ((lhs->bits ^ rhs->bits) & DECINF)
05886         *status|=DEC_Invalid_operation;
05887       // both infinity: return lhs
05888       else decNumberCopy(res, lhs);          // [nop if in place]
05889       break;
05890       }
05891 
05892     // set requested exponent
05893     if (quant) reqexp=inrhs->exponent;  // quantize -- match exponents
05894      else {                             // rescale -- use value of rhs
05895       // Original rhs must be an integer that fits and is in range,
05896       // which could be from -1999999997 to +999999999, thanks to
05897       // subnormals
05898       reqexp=decGetInt(inrhs);               // [cannot fail]
05899       }
05900 
05901     #if DECSUBSET
05902     if (!set->extended) etiny=set->emin;     // no subnormals
05903     #endif
05904 
05905     if (reqexp==BADINT                       // bad (rescale only) or ..
05906      || reqexp==BIGODD || reqexp==BIGEVEN    // very big (ditto) or ..
05907      || (reqexp<etiny)                       // < lowest
05908      || (reqexp>set->emax)) {                // > emax
05909       *status|=DEC_Invalid_operation;
05910       break;}
05911 
05912     // the RHS has been processed, so it can be overwritten now if necessary
05913     if (ISZERO(lhs)) {                       // zero coefficient unchanged
05914       decNumberCopy(res, lhs);               // [nop if in place]
05915       res->exponent=reqexp;                  // .. just set exponent
05916       #if DECSUBSET
05917       if (!set->extended) res->bits=0;       // subset specification; no -0
05918       #endif
05919       }
05920      else {                                  // non-zero lhs
05921       Int adjust=reqexp-lhs->exponent;       // digit adjustment needed
05922       // if adjusted coefficient will definitely not fit, give up now
05923       if ((lhs->digits-adjust)>reqdigits) {
05924         *status|=DEC_Invalid_operation;
05925         break;
05926         }
05927 
05928       if (adjust>0) {                        // increasing exponent
05929         // this will decrease the length of the coefficient by adjust
05930         // digits, and must round as it does so
05931         decContext workset;                  // work
05932         workset=*set;                        // clone rounding, etc.
05933         workset.digits=lhs->digits-adjust;   // set requested length
05934         // [note that the latter can be <1, here]
05935         decCopyFit(res, lhs, &workset, &residue, status); // fit to result
05936         decApplyRound(res, &workset, residue, status);    // .. and round
05937         residue=0;                                        // [used]
05938         // If just rounded a 999s case, exponent will be off by one;
05939         // adjust back (after checking space), if so.
05940         if (res->exponent>reqexp) {
05941           // re-check needed, e.g., for quantize(0.9999, 0.001) under
05942           // set->digits==3
05943           if (res->digits==reqdigits) {      // cannot shift by 1
05944             *status&=~(DEC_Inexact | DEC_Rounded); // [clean these]
05945             *status|=DEC_Invalid_operation;
05946             break;
05947             }
05948           res->digits=decShiftToMost(res->lsu, res->digits, 1); // shift
05949           res->exponent--;                   // (re)adjust the exponent.
05950           }
05951         #if DECSUBSET
05952         if (ISZERO(res) && !set->extended) res->bits=0; // subset; no -0
05953         #endif
05954         } // increase
05955        else /* adjust<=0 */ {                // decreasing or = exponent
05956         // this will increase the length of the coefficient by -adjust
05957         // digits, by adding zero or more trailing zeros; this is
05958         // already checked for fit, above
05959         decNumberCopy(res, lhs);             // [it will fit]
05960         // if padding needed (adjust<0), add it now...
05961         if (adjust<0) {
05962           res->digits=decShiftToMost(res->lsu, res->digits, -adjust);
05963           res->exponent+=adjust;             // adjust the exponent
05964           }
05965         } // decrease
05966       } // non-zero
05967 
05968     // Check for overflow [do not use Finalize in this case, as an
05969     // overflow here is a "don't fit" situation]
05970     if (res->exponent>set->emax-res->digits+1) {  // too big
05971       *status|=DEC_Invalid_operation;
05972       break;
05973       }
05974      else {
05975       decFinalize(res, set, &residue, status);    // set subnormal flags
05976       *status&=~DEC_Underflow;          // suppress Underflow [as per 754]
05977       }
05978     } while(0);                         // end protected
05979 
05980   #if DECSUBSET
05981   if (allocrhs!=NULL) free(allocrhs);   // drop any storage used
05982   if (alloclhs!=NULL) free(alloclhs);   // ..
05983   #endif
05984   return res;
05985   } // decQuantizeOp

static void decReverse ( Unit *  ,
Unit *   
) [static]

Définition à la ligne 6675 du fichier decNumber.c.

Référencé par decNumberRotate().

06675                                              {
06676   Unit temp;
06677   for (; ulo<uhi; ulo++, uhi--) {
06678     temp=*ulo;
06679     *ulo=*uhi;
06680     *uhi=temp;
06681     }
06682   return;
06683   } // decReverse

static void decSetCoeff ( decNumber ,
decContext ,
const Unit *  ,
Int  ,
Int *  ,
uInt *   
) [static]

Définition à la ligne 6902 du fichier decNumber.c.

Références DEC_Inexact, DEC_Rounded, DECDPUN, decNumber::digits, decContext::digits, decNumber::exponent, Int, decNumber::lsu, powers, et uInt.

Référencé par decAddOp(), decCopyFit(), decDivideOp(), decMultiplyOp(), et decSetSubnormal().

06903                                                              {
06904   Int   discard;              // number of digits to discard
06905   uInt  cut;                  // cut point in Unit
06906   const Unit *up;             // work
06907   Unit  *target;              // ..
06908   Int   count;                // ..
06909   #if DECDPUN<=4
06910   uInt  temp;                 // ..
06911   #endif
06912 
06913   discard=len-set->digits;    // digits to discard
06914   if (discard<=0) {           // no digits are being discarded
06915     if (dn->lsu!=lsu) {       // copy needed
06916       // copy the coefficient array to the result number; no shift needed
06917       count=len;              // avoids D2U
06918       up=lsu;
06919       for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
06920         *target=*up;
06921       dn->digits=len;         // set the new length
06922       }
06923     // dn->exponent and residue are unchanged, record any inexactitude
06924     if (*residue!=0) *status|=(DEC_Inexact | DEC_Rounded);
06925     return;
06926     }
06927 
06928   // some digits must be discarded ...
06929   dn->exponent+=discard;      // maintain numerical value
06930   *status|=DEC_Rounded;       // accumulate Rounded status
06931   if (*residue>1) *residue=1; // previous residue now to right, so reduce
06932 
06933   if (discard>len) {          // everything, +1, is being discarded
06934     // guard digit is 0
06935     // residue is all the number [NB could be all 0s]
06936     if (*residue<=0) {        // not already positive
06937       count=len;              // avoids D2U
06938       for (up=lsu; count>0; up++, count-=DECDPUN) if (*up!=0) { // found non-0
06939         *residue=1;
06940         break;                // no need to check any others
06941         }
06942       }
06943     if (*residue!=0) *status|=DEC_Inexact; // record inexactitude
06944     *dn->lsu=0;               // coefficient will now be 0
06945     dn->digits=1;             // ..
06946     return;
06947     } // total discard
06948 
06949   // partial discard [most common case]
06950   // here, at least the first (most significant) discarded digit exists
06951 
06952   // spin up the number, noting residue during the spin, until get to
06953   // the Unit with the first discarded digit.  When reach it, extract
06954   // it and remember its position
06955   count=0;
06956   for (up=lsu;; up++) {
06957     count+=DECDPUN;
06958     if (count>=discard) break; // full ones all checked
06959     if (*up!=0) *residue=1;
06960     } // up
06961 
06962   // here up -> Unit with first discarded digit
06963   cut=discard-(count-DECDPUN)-1;
06964   if (cut==DECDPUN-1) {       // unit-boundary case (fast)
06965     Unit half=(Unit)powers[DECDPUN]>>1;
06966     // set residue directly
06967     if (*up>=half) {
06968       if (*up>half) *residue=7;
06969       else *residue+=5;       // add sticky bit
06970       }
06971      else { // <half
06972       if (*up!=0) *residue=3; // [else is 0, leave as sticky bit]
06973       }
06974     if (set->digits<=0) {     // special for Quantize/Subnormal :-(
06975       *dn->lsu=0;             // .. result is 0
06976       dn->digits=1;           // ..
06977       }
06978      else {                   // shift to least
06979       count=set->digits;      // now digits to end up with
06980       dn->digits=count;       // set the new length
06981       up++;                   // move to next
06982       // on unit boundary, so shift-down copy loop is simple
06983       for (target=dn->lsu; count>0; target++, up++, count-=DECDPUN)
06984         *target=*up;
06985       }
06986     } // unit-boundary case
06987 
06988    else { // discard digit is in low digit(s), and not top digit
06989     uInt  discard1;                // first discarded digit
06990     uInt  quot, rem;               // for divisions
06991     if (cut==0) quot=*up;          // is at bottom of unit
06992      else /* cut>0 */ {            // it's not at bottom of unit
06993       #if DECDPUN<=4
06994         quot=QUOT10(*up, cut);
06995         rem=*up-quot*powers[cut];
06996       #else
06997         rem=*up%powers[cut];
06998         quot=*up/powers[cut];
06999       #endif
07000       if (rem!=0) *residue=1;
07001       }
07002     // discard digit is now at bottom of quot
07003     #if DECDPUN<=4
07004       temp=(quot*6554)>>16;        // fast /10
07005       // Vowels algorithm here not a win (9 instructions)
07006       discard1=quot-X10(temp);
07007       quot=temp;
07008     #else
07009       discard1=quot%10;
07010       quot=quot/10;
07011     #endif
07012     // here, discard1 is the guard digit, and residue is everything
07013     // else [use mapping array to accumulate residue safely]
07014     *residue+=resmap[discard1];
07015     cut++;                         // update cut
07016     // here: up -> Unit of the array with bottom digit
07017     //       cut is the division point for each Unit
07018     //       quot holds the uncut high-order digits for the current unit
07019     if (set->digits<=0) {          // special for Quantize/Subnormal :-(
07020       *dn->lsu=0;                  // .. result is 0
07021       dn->digits=1;                // ..
07022       }
07023      else {                        // shift to least needed
07024       count=set->digits;           // now digits to end up with
07025       dn->digits=count;            // set the new length
07026       // shift-copy the coefficient array to the result number
07027       for (target=dn->lsu; ; target++) {
07028         *target=(Unit)quot;
07029         count-=(DECDPUN-cut);
07030         if (count<=0) break;
07031         up++;
07032         quot=*up;
07033         #if DECDPUN<=4
07034           quot=QUOT10(quot, cut);
07035           rem=*up-quot*powers[cut];
07036         #else
07037           rem=quot%powers[cut];
07038           quot=quot/powers[cut];
07039         #endif
07040         *target=(Unit)(*target+rem*powers[DECDPUN-cut]);
07041         count-=cut;
07042         if (count<=0) break;
07043         } // shift-copy loop
07044       } // shift to least
07045     } // not unit boundary
07046 
07047   if (*residue!=0) *status|=DEC_Inexact; // record inexactitude
07048   return;
07049   } // decSetCoeff

static void decSetMaxValue ( decNumber ,
decContext  
) [static]

Définition à la ligne 7407 du fichier decNumber.c.

Références decNumber::bits, DECDPUN, decNumber::digits, decContext::digits, decContext::emax, decNumber::exponent, Int, et decNumber::lsu.

Référencé par decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), et decSetOverflow().

07407                                                            {
07408   Unit *up;                        // work
07409   Int count=set->digits;           // nines to add
07410   dn->digits=count;
07411   // fill in all nines to set maximum value
07412   for (up=dn->lsu; ; up++) {
07413     if (count>DECDPUN) *up=DECDPUNMAX;  // unit full o'nines
07414      else {                             // this is the msu
07415       *up=(Unit)(powers[count]-1);
07416       break;
07417       }
07418     count-=DECDPUN;                // filled those digits
07419     } // up
07420   dn->bits=0;                      // + sign
07421   dn->exponent=set->emax-set->digits+1;
07422   } // decSetMaxValue

static void decSetOverflow ( decNumber ,
decContext ,
uInt *   
) [static]

Définition à la ligne 7361 du fichier decNumber.c.

Références decNumber::bits, decContext::clamp, DEC_Clamped, DEC_Inexact, DEC_Overflow, DEC_ROUND_05UP, DEC_ROUND_CEILING, DEC_ROUND_DOWN, DEC_ROUND_FLOOR, DEC_Rounded, DECINF, DECNEG, decNumberZero(), decSetMaxValue(), decContext::digits, decContext::emax, decNumber::exponent, Flag, Int, ISZERO, decContext::round, et uByte.

Référencé par decApplyRound(), et decFinalize().

07361                                                                          {
07362   Flag needmax=0;                  // result is maximum finite value
07363   uByte sign=dn->bits&DECNEG;      // clean and save sign bit
07364 
07365   if (ISZERO(dn)) {                // zero does not overflow magnitude
07366     Int emax=set->emax;                      // limit value
07367     if (set->clamp) emax-=set->digits-1;     // lower if clamping
07368     if (dn->exponent>emax) {                 // clamp required
07369       dn->exponent=emax;
07370       *status|=DEC_Clamped;
07371       }
07372     return;
07373     }
07374 
07375   decNumberZero(dn);
07376   switch (set->round) {
07377     case DEC_ROUND_DOWN: {
07378       needmax=1;                   // never Infinity
07379       break;} // r-d
07380     case DEC_ROUND_05UP: {
07381       needmax=1;                   // never Infinity
07382       break;} // r-05
07383     case DEC_ROUND_CEILING: {
07384       if (sign) needmax=1;         // Infinity if non-negative
07385       break;} // r-c
07386     case DEC_ROUND_FLOOR: {
07387       if (!sign) needmax=1;        // Infinity if negative
07388       break;} // r-f
07389     default: break;                // Infinity in all other cases
07390     }
07391   if (needmax) {
07392     decSetMaxValue(dn, set);
07393     dn->bits=sign;                 // set sign
07394     }
07395    else dn->bits=sign|DECINF;      // Value is +/-Infinity
07396   *status|=DEC_Overflow | DEC_Inexact | DEC_Rounded;
07397   } // decSetOverflow

static void decSetSubnormal ( decNumber ,
decContext ,
Int *  ,
uInt *   
) [static]

Définition à la ligne 7441 du fichier decNumber.c.

Références DEC_Clamped, DEC_Inexact, DEC_Invalid_operation, DEC_Rounded, DEC_Subnormal, DEC_Underflow, decApplyRound(), decNumberZero(), decSetCoeff(), decShiftToMost(), decNumber::digits, decContext::digits, decContext::emin, decNumber::exponent, Int, ISZERO, et decNumber::lsu.

Référencé par decFinalize().

07442                                           {
07443   decContext workset;         // work
07444   Int        etiny, adjust;   // ..
07445 
07446   #if DECSUBSET
07447   // simple set to zero and 'hard underflow' for subset
07448   if (!set->extended) {
07449     decNumberZero(dn);
07450     // always full overflow
07451     *status|=DEC_Underflow | DEC_Subnormal | DEC_Inexact | DEC_Rounded;
07452     return;
07453     }
07454   #endif
07455 
07456   // Full arithmetic -- allow subnormals, rounded to minimum exponent
07457   // (Etiny) if needed
07458   etiny=set->emin-(set->digits-1);      // smallest allowed exponent
07459 
07460   if ISZERO(dn) {                       // value is zero
07461     // residue can never be non-zero here
07462     #if DECCHECK
07463       if (*residue!=0) {
07464         printf("++ Subnormal 0 residue %ld\n", (LI)*residue);
07465         *status|=DEC_Invalid_operation;
07466         }
07467     #endif
07468     if (dn->exponent<etiny) {           // clamp required
07469       dn->exponent=etiny;
07470       *status|=DEC_Clamped;
07471       }
07472     return;
07473     }
07474 
07475   *status|=DEC_Subnormal;               // have a non-zero subnormal
07476   adjust=etiny-dn->exponent;            // calculate digits to remove
07477   if (adjust<=0) {                      // not out of range; unrounded
07478     // residue can never be non-zero here, except in the Nmin-residue
07479     // case (which is a subnormal result), so can take fast-path here
07480     // it may already be inexact (from setting the coefficient)
07481     if (*status&DEC_Inexact) *status|=DEC_Underflow;
07482     return;
07483     }
07484 
07485   // adjust>0, so need to rescale the result so exponent becomes Etiny
07486   // [this code is similar to that in rescale]
07487   workset=*set;                         // clone rounding, etc.
07488   workset.digits=dn->digits-adjust;     // set requested length
07489   workset.emin-=adjust;                 // and adjust emin to match
07490   // [note that the latter can be <1, here, similar to Rescale case]
07491   decSetCoeff(dn, &workset, dn->lsu, dn->digits, residue, status);
07492   decApplyRound(dn, &workset, *residue, status);
07493 
07494   // Use 754 default rule: Underflow is set iff Inexact
07495   // [independent of whether trapped]
07496   if (*status&DEC_Inexact) *status|=DEC_Underflow;
07497 
07498   // if rounded up a 999s case, exponent will be off by one; adjust
07499   // back if so [it will fit, because it was shortened earlier]
07500   if (dn->exponent>etiny) {
07501     dn->digits=decShiftToMost(dn->lsu, dn->digits, 1);
07502     dn->exponent--;                     // (re)adjust the exponent.
07503     }
07504 
07505   // if rounded to zero, it is by definition clamped...
07506   if (ISZERO(dn)) *status|=DEC_Clamped;
07507   } // decSetSubnormal

static Int decShiftToLeast ( Unit *  ,
Int  ,
Int   
) [static]

Définition à la ligne 6754 du fichier decNumber.c.

Références D2U, DECDPUN, Int, MSUDIGITS, powers, et QUOT10.

Référencé par decDivideOp(), decNumberRotate(), decNumberShift(), et decNumberSquareRoot().

06754                                                             {
06755   Unit  *target, *up;              // work
06756   Int   cut, count;                // work
06757   Int   quot, rem;                 // for division
06758 
06759   if (shift==0) return units;      // [fastpath] nothing to do
06760   if (shift==units*DECDPUN) {      // [fastpath] little to do
06761     *uar=0;                        // all digits cleared gives zero
06762     return 1;                      // leaves just the one
06763     }
06764 
06765   target=uar;                      // both paths
06766   cut=MSUDIGITS(shift);
06767   if (cut==DECDPUN) {              // unit-boundary case; easy
06768     up=uar+D2U(shift);
06769     for (; up<uar+units; target++, up++) *target=*up;
06770     return target-uar;
06771     }
06772 
06773   // messier
06774   up=uar+D2U(shift-cut);           // source; correct to whole Units
06775   count=units*DECDPUN-shift;       // the maximum new length
06776   #if DECDPUN<=4
06777     quot=QUOT10(*up, cut);
06778   #else
06779     quot=*up/powers[cut];
06780   #endif
06781   for (; ; target++) {
06782     *target=(Unit)quot;
06783     count-=(DECDPUN-cut);
06784     if (count<=0) break;
06785     up++;
06786     quot=*up;
06787     #if DECDPUN<=4
06788       quot=QUOT10(quot, cut);
06789       rem=*up-quot*powers[cut];
06790     #else
06791       rem=quot%powers[cut];
06792       quot=quot/powers[cut];
06793     #endif
06794     *target=(Unit)(*target+rem*powers[DECDPUN-cut]);
06795     count-=cut;
06796     if (count<=0) break;
06797     }
06798   return target-uar+1;
06799   } // decShiftToLeast

static Int decShiftToMost ( Unit *  ,
Int  ,
Int   
) [static]

Définition à la ligne 6698 du fichier decNumber.c.

Références D2U, DECDPUN, Int, MSUDIGITS, powers, QUOT10, et uInt.

Référencé par decAddOp(), decExpOp(), decFinalize(), decNumberPower(), decNumberShift(), decQuantizeOp(), et decSetSubnormal().

06698                                                             {
06699   Unit  *target, *source, *first;  // work
06700   Int   cut;                       // odd 0's to add
06701   uInt  next;                      // work
06702 
06703   if (shift==0) return digits;     // [fastpath] nothing to do
06704   if ((digits+shift)<=DECDPUN) {   // [fastpath] single-unit case
06705     *uar=(Unit)(*uar*powers[shift]);
06706     return digits+shift;
06707     }
06708 
06709   next=0;                          // all paths
06710   source=uar+D2U(digits)-1;        // where msu comes from
06711   target=source+D2U(shift);        // where upper part of first cut goes
06712   cut=DECDPUN-MSUDIGITS(shift);    // where to slice
06713   if (cut==0) {                    // unit-boundary case
06714     for (; source>=uar; source--, target--) *target=*source;
06715     }
06716    else {
06717     first=uar+D2U(digits+shift)-1; // where msu of source will end up
06718     for (; source>=uar; source--, target--) {
06719       // split the source Unit and accumulate remainder for next
06720       #if DECDPUN<=4
06721         uInt quot=QUOT10(*source, cut);
06722         uInt rem=*source-quot*powers[cut];
06723         next+=quot;
06724       #else
06725         uInt rem=*source%powers[cut];
06726         next+=*source/powers[cut];
06727       #endif
06728       if (target<=first) *target=(Unit)next;   // write to target iff valid
06729       next=rem*powers[DECDPUN-cut];            // save remainder for next Unit
06730       }
06731     } // shift-move
06732 
06733   // propagate any partial unit to one below and clear the rest
06734   for (; target>=uar; target--) {
06735     *target=(Unit)next;
06736     next=0;
06737     }
06738   return digits+shift;
06739   } // decShiftToMost

static void decStatus ( decNumber ,
uInt  ,
decContext  
) [static]

Définition à la ligne 7754 du fichier decNumber.c.

Références decNumber::bits, DEC_NaNs, DEC_sNaN, decContextSetStatus(), DECNAN, et decNumberZero().

Référencé par decNumberAbs(), decNumberAdd(), decNumberAnd(), decNumberCompare(), decNumberCompareSignal(), decNumberCompareTotal(), decNumberCompareTotalMag(), decNumberDivide(), decNumberDivideInteger(), decNumberExp(), decNumberFMA(), decNumberInvert(), decNumberLn(), decNumberLog10(), decNumberLogB(), decNumberMax(), decNumberMaxMag(), decNumberMin(), decNumberMinMag(), decNumberMinus(), decNumberMultiply(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberOr(), decNumberPlus(), decNumberPower(), decNumberQuantize(), decNumberReduce(), decNumberRemainder(), decNumberRemainderNear(), decNumberRescale(), decNumberRotate(), decNumberScaleB(), decNumberShift(), decNumberSquareRoot(), decNumberSubtract(), decNumberToIntegralExact(), et decNumberXor().

07754                                                                    {
07755   if (status & DEC_NaNs) {              // error status -> NaN
07756     // if cause was an sNaN, clear and propagate [NaN is already set up]
07757     if (status & DEC_sNaN) status&=~DEC_sNaN;
07758      else {
07759       decNumberZero(dn);                // other error: clean throughout
07760       dn->bits=DECNAN;                  // and make a quiet NaN
07761       }
07762     }
07763   decContextSetStatus(set, status);     // [may not return]
07764   return;
07765   } // decStatus

static void decToString ( const decNumber dn,
char *  string,
Flag  eng 
) [static]

Définition à la ligne 3634 du fichier decNumber.c.

Références decNumber::bits, D2U, DECDPUN, decNumberIsInfinite, decNumberIsNegative, DECSNAN, DECSPECIAL, decNumber::digits, decNumber::exponent, Flag, Int, ISZERO, decNumber::lsu, MSUDIGITS, pow(), TODIGIT, et uInt.

03634                                                                      {
03635   Int exp=dn->exponent;       // local copy
03636   Int e;                      // E-part value
03637   Int pre;                    // digits before the '.'
03638   Int cut;                    // for counting digits in a Unit
03639   char *c=string;             // work [output pointer]
03640   const Unit *up=dn->lsu+D2U(dn->digits)-1; // -> msu [input pointer]
03641   uInt u, pow;                // work
03642 
03643   #if DECCHECK
03644   if (decCheckOperands(DECUNRESU, dn, DECUNUSED, DECUNCONT)) {
03645     strcpy(string, "?");
03646     return;}
03647   #endif
03648 
03649   if (decNumberIsNegative(dn)) {   // Negatives get a minus
03650     *c='-';
03651     c++;
03652     }
03653   if (dn->bits&DECSPECIAL) {       // Is a special value
03654     if (decNumberIsInfinite(dn)) {
03655       strcpy(c,   "Inf");
03656       strcpy(c+3, "inity");
03657       return;}
03658     // a NaN
03659     if (dn->bits&DECSNAN) {        // signalling NaN
03660       *c='s';
03661       c++;
03662       }
03663     strcpy(c, "NaN");
03664     c+=3;                          // step past
03665     // if not a clean non-zero coefficient, that's all there is in a
03666     // NaN string
03667     if (exp!=0 || (*dn->lsu==0 && dn->digits==1)) return;
03668     // [drop through to add integer]
03669     }
03670 
03671   // calculate how many digits in msu, and hence first cut
03672   cut=MSUDIGITS(dn->digits);       // [faster than remainder]
03673   cut--;                           // power of ten for digit
03674 
03675   if (exp==0) {                    // simple integer [common fastpath]
03676     for (;up>=dn->lsu; up--) {     // each Unit from msu
03677       u=*up;                       // contains DECDPUN digits to lay out
03678       for (; cut>=0; c++, cut--) TODIGIT(u, cut, c, pow);
03679       cut=DECDPUN-1;               // next Unit has all digits
03680       }
03681     *c='\0';                       // terminate the string
03682     return;}
03683 
03684   /* non-0 exponent -- assume plain form */
03685   pre=dn->digits+exp;              // digits before '.'
03686   e=0;                             // no E
03687   if ((exp>0) || (pre<-5)) {       // need exponential form
03688     e=exp+dn->digits-1;            // calculate E value
03689     pre=1;                         // assume one digit before '.'
03690     if (eng && (e!=0)) {           // engineering: may need to adjust
03691       Int adj;                     // adjustment
03692       // The C remainder operator is undefined for negative numbers, so
03693       // a positive remainder calculation must be used here
03694       if (e<0) {
03695         adj=(-e)%3;
03696         if (adj!=0) adj=3-adj;
03697         }
03698        else { // e>0
03699         adj=e%3;
03700         }
03701       e=e-adj;
03702       // if dealing with zero still produce an exponent which is a
03703       // multiple of three, as expected, but there will only be the
03704       // one zero before the E, still.  Otherwise note the padding.
03705       if (!ISZERO(dn)) pre+=adj;
03706        else {  // is zero
03707         if (adj!=0) {              // 0.00Esnn needed
03708           e=e+3;
03709           pre=-(2-adj);
03710           }
03711         } // zero
03712       } // eng
03713     } // need exponent
03714 
03715   /* lay out the digits of the coefficient, adding 0s and . as needed */
03716   u=*up;
03717   if (pre>0) {                     // xxx.xxx or xx00 (engineering) form
03718     Int n=pre;
03719     for (; pre>0; pre--, c++, cut--) {
03720       if (cut<0) {                 // need new Unit
03721         if (up==dn->lsu) break;    // out of input digits (pre>digits)
03722         up--;
03723         cut=DECDPUN-1;
03724         u=*up;
03725         }
03726       TODIGIT(u, cut, c, pow);
03727       }
03728     if (n<dn->digits) {            // more to come, after '.'
03729       *c='.'; c++;
03730       for (;; c++, cut--) {
03731         if (cut<0) {               // need new Unit
03732           if (up==dn->lsu) break;  // out of input digits
03733           up--;
03734           cut=DECDPUN-1;
03735           u=*up;
03736           }
03737         TODIGIT(u, cut, c, pow);
03738         }
03739       }
03740      else for (; pre>0; pre--, c++) *c='0'; // 0 padding (for engineering) needed
03741     }
03742    else {                          // 0.xxx or 0.000xxx form
03743     *c='0'; c++;
03744     *c='.'; c++;
03745     for (; pre<0; pre++, c++) *c='0';   // add any 0's after '.'
03746     for (; ; c++, cut--) {
03747       if (cut<0) {                 // need new Unit
03748         if (up==dn->lsu) break;    // out of input digits
03749         up--;
03750         cut=DECDPUN-1;
03751         u=*up;
03752         }
03753       TODIGIT(u, cut, c, pow);
03754       }
03755     }
03756 
03757   /* Finally add the E-part, if needed.  It will never be 0, has a
03758      base maximum and minimum of +999999999 through -999999999, but
03759      could range down to -1999999998 for anormal numbers */
03760   if (e!=0) {
03761     Flag had=0;               // 1=had non-zero
03762     *c='E'; c++;
03763     *c='+'; c++;              // assume positive
03764     u=e;                      // ..
03765     if (e<0) {
03766       *(c-1)='-';             // oops, need -
03767       u=-e;                   // uInt, please
03768       }
03769     // lay out the exponent [_itoa or equivalent is not ANSI C]
03770     for (cut=9; cut>=0; cut--) {
03771       TODIGIT(u, cut, c, pow);
03772       if (*c=='0' && !had) continue;    // skip leading zeros
03773       had=1;                            // had non-0
03774       c++;                              // step for next
03775       } // cut
03776     }
03777   *c='\0';          // terminate the string (all paths)
03778   return;
03779   } // decToString

static void decToString ( const decNumber ,
char  [],
Flag   
) [static]

Référencé par decNumberToEngString(), et decNumberToString().

static decNumber * decTrim ( decNumber ,
decContext ,
Flag  ,
Flag  ,
Int *   
) [static]

Définition à la ligne 6604 du fichier decNumber.c.

Références decNumber::bits, decContext::clamp, DECDPUN, DECSPECIAL, decContext::digits, decNumber::digits, decContext::emax, decNumber::exponent, Int, ISZERO, decNumber::lsu, powers, QUOT10, et uInt.

Référencé par decDivideOp(), decNumberPower(), decNumberReduce(), decNumberSquareRoot(), et decNumberTrim().

06605                                                        {
06606   Int   d, exp;                    // work
06607   uInt  cut;                       // ..
06608   Unit  *up;                       // -> current Unit
06609 
06610   #if DECCHECK
06611   if (decCheckOperands(dn, DECUNUSED, DECUNUSED, DECUNCONT)) return dn;
06612   #endif
06613 
06614   *dropped=0;                           // assume no zeros dropped
06615   if ((dn->bits & DECSPECIAL)           // fast exit if special ..
06616     || (*dn->lsu & 0x01)) return dn;    // .. or odd
06617   if (ISZERO(dn)) {                     // .. or 0
06618     dn->exponent=0;                     // (sign is preserved)
06619     return dn;
06620     }
06621 
06622   // have a finite number which is even
06623   exp=dn->exponent;
06624   cut=1;                           // digit (1-DECDPUN) in Unit
06625   up=dn->lsu;                      // -> current Unit
06626   for (d=0; d<dn->digits-1; d++) { // [don't strip the final digit]
06627     // slice by powers
06628     #if DECDPUN<=4
06629       uInt quot=QUOT10(*up, cut);
06630       if ((*up-quot*powers[cut])!=0) break;  // found non-0 digit
06631     #else
06632       if (*up%powers[cut]!=0) break;         // found non-0 digit
06633     #endif
06634     // have a trailing 0
06635     if (!all) {                    // trimming
06636       // [if exp>0 then all trailing 0s are significant for trim]
06637       if (exp<=0) {                // if digit might be significant
06638         if (exp==0) break;         // then quit
06639         exp++;                     // next digit might be significant
06640         }
06641       }
06642     cut++;                         // next power
06643     if (cut>DECDPUN) {             // need new Unit
06644       up++;
06645       cut=1;
06646       }
06647     } // d
06648   if (d==0) return dn;             // none to drop
06649 
06650   // may need to limit drop if clamping
06651   if (set->clamp && !noclamp) {
06652     Int maxd=set->emax-set->digits+1-dn->exponent;
06653     if (maxd<=0) return dn;        // nothing possible
06654     if (d>maxd) d=maxd;
06655     }
06656 
06657   // effect the drop
06658   decShiftToLeast(dn->lsu, D2U(dn->digits), d);
06659   dn->exponent+=d;                 // maintain numerical value
06660   dn->digits-=d;                   // new length
06661   *dropped=d;                      // report the count
06662   return dn;
06663   } // decTrim

static Int decUnitAddSub ( const Unit *  ,
Int  ,
const Unit *  ,
Int  ,
Int  ,
Unit *  ,
Int   
) [static]

Définition à la ligne 6350 du fichier decNumber.c.

Références DECDPUN, eInt, Int, QUOT10, et ueInt.

Référencé par decAddOp(), decDivideOp(), decMultiplyOp(), et decUnitCompare().

06352                                          {
06353   const Unit *alsu=a;              // A lsu [need to remember it]
06354   Unit *clsu=c;                    // C ditto
06355   Unit *minC;                      // low water mark for C
06356   Unit *maxC;                      // high water mark for C
06357   eInt carry=0;                    // carry integer (could be Long)
06358   Int  add;                        // work
06359   #if DECDPUN<=4                   // myriadal, millenary, etc.
06360   Int  est;                        // estimated quotient
06361   #endif
06362 
06363   #if DECTRACE
06364   if (alength<1 || blength<1)
06365     printf("decUnitAddSub: alen blen m %ld %ld [%ld]\n", alength, blength, m);
06366   #endif
06367 
06368   maxC=c+alength;                  // A is usually the longer
06369   minC=c+blength;                  // .. and B the shorter
06370   if (bshift!=0) {                 // B is shifted; low As copy across
06371     minC+=bshift;
06372     // if in place [common], skip copy unless there's a gap [rare]
06373     if (a==c && bshift<=alength) {
06374       c+=bshift;
06375       a+=bshift;
06376       }
06377      else for (; c<clsu+bshift; a++, c++) {  // copy needed
06378       if (a<alsu+alength) *c=*a;
06379        else *c=0;
06380       }
06381     }
06382   if (minC>maxC) { // swap
06383     Unit *hold=minC;
06384     minC=maxC;
06385     maxC=hold;
06386     }
06387 
06388   // For speed, do the addition as two loops; the first where both A
06389   // and B contribute, and the second (if necessary) where only one or
06390   // other of the numbers contribute.
06391   // Carry handling is the same (i.e., duplicated) in each case.
06392   for (; c<minC; c++) {
06393     carry+=*a;
06394     a++;
06395     carry+=((eInt)*b)*m;                // [special-casing m=1/-1
06396     b++;                                // here is not a win]
06397     // here carry is new Unit of digits; it could be +ve or -ve
06398     if ((ueInt)carry<=DECDPUNMAX) {     // fastpath 0-DECDPUNMAX
06399       *c=(Unit)carry;
06400       carry=0;
06401       continue;
06402       }
06403     #if DECDPUN==4                           // use divide-by-multiply
06404       if (carry>=0) {
06405         est=(((ueInt)carry>>11)*53687)>>18;
06406         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06407         carry=est;                           // likely quotient [89%]
06408         if (*c<DECDPUNMAX+1) continue;       // estimate was correct
06409         carry++;
06410         *c-=DECDPUNMAX+1;
06411         continue;
06412         }
06413       // negative case
06414       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06415       est=(((ueInt)carry>>11)*53687)>>18;
06416       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06417       carry=est-(DECDPUNMAX+1);              // correctly negative
06418       if (*c<DECDPUNMAX+1) continue;         // was OK
06419       carry++;
06420       *c-=DECDPUNMAX+1;
06421     #elif DECDPUN==3
06422       if (carry>=0) {
06423         est=(((ueInt)carry>>3)*16777)>>21;
06424         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06425         carry=est;                           // likely quotient [99%]
06426         if (*c<DECDPUNMAX+1) continue;       // estimate was correct
06427         carry++;
06428         *c-=DECDPUNMAX+1;
06429         continue;
06430         }
06431       // negative case
06432       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06433       est=(((ueInt)carry>>3)*16777)>>21;
06434       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06435       carry=est-(DECDPUNMAX+1);              // correctly negative
06436       if (*c<DECDPUNMAX+1) continue;         // was OK
06437       carry++;
06438       *c-=DECDPUNMAX+1;
06439     #elif DECDPUN<=2
06440       // Can use QUOT10 as carry <= 4 digits
06441       if (carry>=0) {
06442         est=QUOT10(carry, DECDPUN);
06443         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06444         carry=est;                           // quotient
06445         continue;
06446         }
06447       // negative case
06448       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06449       est=QUOT10(carry, DECDPUN);
06450       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06451       carry=est-(DECDPUNMAX+1);              // correctly negative
06452     #else
06453       // remainder operator is undefined if negative, so must test
06454       if ((ueInt)carry<(DECDPUNMAX+1)*2) {   // fastpath carry +1
06455         *c=(Unit)(carry-(DECDPUNMAX+1));     // [helps additions]
06456         carry=1;
06457         continue;
06458         }
06459       if (carry>=0) {
06460         *c=(Unit)(carry%(DECDPUNMAX+1));
06461         carry=carry/(DECDPUNMAX+1);
06462         continue;
06463         }
06464       // negative case
06465       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06466       *c=(Unit)(carry%(DECDPUNMAX+1));
06467       carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);
06468     #endif
06469     } // c
06470 
06471   // now may have one or other to complete
06472   // [pretest to avoid loop setup/shutdown]
06473   if (c<maxC) for (; c<maxC; c++) {
06474     if (a<alsu+alength) {               // still in A
06475       carry+=*a;
06476       a++;
06477       }
06478      else {                             // inside B
06479       carry+=((eInt)*b)*m;
06480       b++;
06481       }
06482     // here carry is new Unit of digits; it could be +ve or -ve and
06483     // magnitude up to DECDPUNMAX squared
06484     if ((ueInt)carry<=DECDPUNMAX) {     // fastpath 0-DECDPUNMAX
06485       *c=(Unit)carry;
06486       carry=0;
06487       continue;
06488       }
06489     // result for this unit is negative or >DECDPUNMAX
06490     #if DECDPUN==4                           // use divide-by-multiply
06491       if (carry>=0) {
06492         est=(((ueInt)carry>>11)*53687)>>18;
06493         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06494         carry=est;                           // likely quotient [79.7%]
06495         if (*c<DECDPUNMAX+1) continue;       // estimate was correct
06496         carry++;
06497         *c-=DECDPUNMAX+1;
06498         continue;
06499         }
06500       // negative case
06501       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06502       est=(((ueInt)carry>>11)*53687)>>18;
06503       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06504       carry=est-(DECDPUNMAX+1);              // correctly negative
06505       if (*c<DECDPUNMAX+1) continue;         // was OK
06506       carry++;
06507       *c-=DECDPUNMAX+1;
06508     #elif DECDPUN==3
06509       if (carry>=0) {
06510         est=(((ueInt)carry>>3)*16777)>>21;
06511         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06512         carry=est;                           // likely quotient [99%]
06513         if (*c<DECDPUNMAX+1) continue;       // estimate was correct
06514         carry++;
06515         *c-=DECDPUNMAX+1;
06516         continue;
06517         }
06518       // negative case
06519       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06520       est=(((ueInt)carry>>3)*16777)>>21;
06521       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06522       carry=est-(DECDPUNMAX+1);              // correctly negative
06523       if (*c<DECDPUNMAX+1) continue;         // was OK
06524       carry++;
06525       *c-=DECDPUNMAX+1;
06526     #elif DECDPUN<=2
06527       if (carry>=0) {
06528         est=QUOT10(carry, DECDPUN);
06529         *c=(Unit)(carry-est*(DECDPUNMAX+1)); // remainder
06530         carry=est;                           // quotient
06531         continue;
06532         }
06533       // negative case
06534       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06535       est=QUOT10(carry, DECDPUN);
06536       *c=(Unit)(carry-est*(DECDPUNMAX+1));
06537       carry=est-(DECDPUNMAX+1);              // correctly negative
06538     #else
06539       if ((ueInt)carry<(DECDPUNMAX+1)*2){    // fastpath carry 1
06540         *c=(Unit)(carry-(DECDPUNMAX+1));
06541         carry=1;
06542         continue;
06543         }
06544       // remainder operator is undefined if negative, so must test
06545       if (carry>=0) {
06546         *c=(Unit)(carry%(DECDPUNMAX+1));
06547         carry=carry/(DECDPUNMAX+1);
06548         continue;
06549         }
06550       // negative case
06551       carry=carry+(eInt)(DECDPUNMAX+1)*(DECDPUNMAX+1); // make positive
06552       *c=(Unit)(carry%(DECDPUNMAX+1));
06553       carry=carry/(DECDPUNMAX+1)-(DECDPUNMAX+1);
06554     #endif
06555     } // c
06556 
06557   // OK, all A and B processed; might still have carry or borrow
06558   // return number of Units in the result, negated if a borrow
06559   if (carry==0) return c-clsu;     // no carry, so no more to do
06560   if (carry>0) {                   // positive carry
06561     *c=(Unit)carry;                // place as new unit
06562     c++;                           // ..
06563     return c-clsu;
06564     }
06565   // -ve carry: it's a borrow; complement needed
06566   add=1;                           // temporary carry...
06567   for (c=clsu; c<maxC; c++) {
06568     add=DECDPUNMAX+add-*c;
06569     if (add<=DECDPUNMAX) {
06570       *c=(Unit)add;
06571       add=0;
06572       }
06573      else {
06574       *c=0;
06575       add=1;
06576       }
06577     }
06578   // add an extra unit iff it would be non-zero
06579   #if DECTRACE
06580     printf("UAS borrow: add %ld, carry %ld\n", add, carry);
06581   #endif
06582   if ((add-carry-1)!=0) {
06583     *c=(Unit)(add-carry-1);
06584     c++;                      // interesting, include it
06585     }
06586   return clsu-c;              // -ve result indicates borrowed
06587   } // decUnitAddSub

static Int decUnitCompare ( const Unit *  ,
Int  ,
const Unit *  ,
Int  ,
Int   
) [static]

Définition à la ligne 6246 du fichier decNumber.c.

Références BADINT, D2U, DECBUFFER, DECDPUN, decUnitAddSub(), Int, powers, et SD2U.

Référencé par decCompare(), decCompareOp(), et decDivideOp().

06247                                                                {
06248   Unit  *acc;                      // accumulator for result
06249   Unit  accbuff[SD2U(DECBUFFER*2+1)]; // local buffer
06250   Unit  *allocacc=NULL;            // -> allocated acc buffer, iff allocated
06251   Int   accunits, need;            // units in use or needed for acc
06252   const Unit *l, *r, *u;           // work
06253   Int   expunits, exprem, result;  // ..
06254 
06255   if (exp==0) {                    // aligned; fastpath
06256     if (alength>blength) return 1;
06257     if (alength<blength) return -1;
06258     // same number of units in both -- need unit-by-unit compare
06259     l=a+alength-1;
06260     r=b+alength-1;
06261     for (;l>=a; l--, r--) {
06262       if (*l>*r) return 1;
06263       if (*l<*r) return -1;
06264       }
06265     return 0;                      // all units match
06266     } // aligned
06267 
06268   // Unaligned.  If one is >1 unit longer than the other, padded
06269   // approximately, then can return easily
06270   if (alength>blength+(Int)D2U(exp)) return 1;
06271   if (alength+1<blength+(Int)D2U(exp)) return -1;
06272 
06273   // Need to do a real subtract.  For this, a result buffer is needed
06274   // even though only the sign is of interest.  Its length needs
06275   // to be the larger of alength and padded blength, +2
06276   need=blength+D2U(exp);                // maximum real length of B
06277   if (need<alength) need=alength;
06278   need+=2;
06279   acc=accbuff;                          // assume use local buffer
06280   if (need*sizeof(Unit)>sizeof(accbuff)) {
06281     allocacc=(Unit *)malloc(need*sizeof(Unit));
06282     if (allocacc==NULL) return BADINT;  // hopeless -- abandon
06283     acc=allocacc;
06284     }
06285   // Calculate units and remainder from exponent.
06286   expunits=exp/DECDPUN;
06287   exprem=exp%DECDPUN;
06288   // subtract [A+B*(-m)]
06289   accunits=decUnitAddSub(a, alength, b, blength, expunits, acc,
06290                          -(Int)powers[exprem]);
06291   // [UnitAddSub result may have leading zeros, even on zero]
06292   if (accunits<0) result=-1;            // negative result
06293    else {                               // non-negative result
06294     // check units of the result before freeing any storage
06295     for (u=acc; u<acc+accunits-1 && *u==0;) u++;
06296     result=(*u==0 ? 0 : +1);
06297     }
06298   // clean up and return the result
06299   if (allocacc!=NULL) free(allocacc);   // drop any storage used
06300   return result;
06301   } // decUnitCompare


Documentation des variables

const uByte d2utable[DECMAXD2U+1] = D2UTABLE

Définition à la ligne 176 du fichier decNumber.c.

const uShort LNnn[90]

Valeur initiale :

{9016,  8652,  8316,  8008,  7724,  7456,  7208,
  6972,  6748,  6540,  6340,  6148,  5968,  5792,  5628,  5464,  5312,
  5164,  5020,  4884,  4748,  4620,  4496,  4376,  4256,  4144,  4032,
 39233, 38181, 37157, 36157, 35181, 34229, 33297, 32389, 31501, 30629,
 29777, 28945, 28129, 27329, 26545, 25777, 25021, 24281, 23553, 22837,
 22137, 21445, 20769, 20101, 19445, 18801, 18165, 17541, 16925, 16321,
 15721, 15133, 14553, 13985, 13421, 12865, 12317, 11777, 11241, 10717,
 10197,  9685,  9177,  8677,  8185,  7697,  7213,  6737,  6269,  5801,
  5341,  4889,  4437, 39930, 35534, 31186, 26886, 22630, 18418, 14254,
 10130,  6046, 20055}

Définition à la ligne 5528 du fichier decNumber.c.

const uInt multies[] = {131073, 26215, 5243, 1049, 210} [static]

Définition à la ligne 210 du fichier decNumber.c.

const uByte resmap[10] = {0, 3, 3, 3, 3, 5, 7, 7, 7, 7} [static]

Définition à la ligne 6901 du fichier decNumber.c.

Unit uarrone[1] = {1} [static]

Définition à la ligne 201 du fichier decNumber.c.


Généré le Mon Jul 20 18:22:17 2009 pour Decimal par  doxygen 1.5.1-p1