#include "decContext.h"
Aller au code source de ce fichier.
#define DECAUTHOR "Mike Cowlishaw" |
Définition à la ligne 26 du fichier decNumber.h.
#define DECDPUN 3 |
Définition à la ligne 45 du fichier decNumber.h.
Référencé par decAddOp(), decApplyRound(), decDecap(), decDivideOp(), decGetDigits(), decGetInt(), decMultiplyOp(), decNaNs(), decNumberAnd(), decNumberCopy(), decNumberGetBCD(), decNumberInvert(), decNumberOr(), decNumberRotate(), decNumberSetBCD(), decNumberToInt32(), decNumberToUInt32(), decNumberXor(), decSetCoeff(), decSetMaxValue(), decShiftToLeast(), decShiftToMost(), decToString(), decTrim(), decUnitAddSub(), et decUnitCompare().
#define DECFULLNAME "Decimal Number Module" |
Définition à la ligne 25 du fichier decNumber.h.
#define DECINF 0x40 |
Définition à la ligne 34 du fichier decNumber.h.
Référencé par decAddOp(), decCompare(), decDivideOp(), decLnOp(), decMultiplyOp(), decNumberFromString(), decNumberLogB(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberPower(), decQuantizeOp(), et decSetOverflow().
#define DECNAME "decNumber" |
Définition à la ligne 24 du fichier decNumber.h.
#define DECNAN 0x20 |
Définition à la ligne 35 du fichier decNumber.h.
Référencé par decAddOp(), decCompareOp(), decDivideOp(), decMultiplyOp(), decNaNs(), decNumberFMA(), decNumberFromString(), decQuantizeOp(), et decStatus().
#define DECNEG 0x80 |
Définition à la ligne 33 du fichier decNumber.h.
Référencé par decAddOp(), decCompareOp(), decDivideOp(), decLnOp(), decMultiplyOp(), decNumberAbs(), decNumberCompareTotalMag(), decNumberCopyAbs(), decNumberCopyNegate(), decNumberCopySign(), decNumberFromInt32(), decNumberFromString(), decNumberLog10(), decNumberLogB(), decNumberMinus(), decNumberNextMinus(), decNumberNextPlus(), decNumberNextToward(), decNumberPower(), decNumberSquareRoot(), decNumberSubtract(), decNumberToInt32(), decNumberToUInt32(), et decSetOverflow().
#define DECNUMBER |
Définition à la ligne 23 du fichier decNumber.h.
#define decNumberIsCanonical | ( | dn | ) | (1) |
Définition à la ligne 171 du fichier decNumber.h.
#define decNumberIsFinite | ( | dn | ) | (((dn)->bits&DECSPECIAL)==0) |
Définition à la ligne 172 du fichier decNumber.h.
#define decNumberIsInfinite | ( | dn | ) | (((dn)->bits&DECINF)!=0) |
Définition à la ligne 173 du fichier decNumber.h.
Référencé par decAddOp(), decCompare(), decDivideOp(), decExpOp(), decLnOp(), decNumberLogB(), decNumberPower(), decNumberRotate(), decNumberSameQuantum(), decNumberScaleB(), decNumberShift(), decNumberSquareRoot(), decNumberToIntegralExact(), et decToString().
#define decNumberIsNaN | ( | dn | ) | (((dn)->bits&(DECNAN|DECSNAN))!=0) |
Définition à la ligne 174 du fichier decNumber.h.
Référencé par decCompareOp(), decNumberLogB(), decNumberNextToward(), decNumberPower(), decNumberReduce(), decNumberRotate(), decNumberSameQuantum(), decNumberScaleB(), et decNumberShift().
#define decNumberIsNegative | ( | dn | ) | (((dn)->bits&DECNEG)!=0) |
Définition à la ligne 175 du fichier decNumber.h.
Référencé par decApplyRound(), decCompare(), decCompareOp(), decExpOp(), decGetInt(), decLnOp(), decNumberAnd(), decNumberClass(), decNumberCompareTotalMag(), decNumberInvert(), decNumberOr(), decNumberPower(), decNumberSquareRoot(), decNumberXor(), decToString(), et operator<().
#define decNumberIsQNaN | ( | dn | ) | (((dn)->bits&(DECNAN))!=0) |
Définition à la ligne 176 du fichier decNumber.h.
Référencé par decCompareOp(), et decNumberClass().
#define decNumberIsSNaN | ( | dn | ) | (((dn)->bits&(DECSNAN))!=0) |
Définition à la ligne 177 du fichier decNumber.h.
Référencé par decCompareOp(), et decNumberClass().
#define decNumberIsSpecial | ( | dn | ) | (((dn)->bits&DECSPECIAL)!=0) |
Définition à la ligne 178 du fichier decNumber.h.
Référencé par decNumberAnd(), decNumberClass(), decNumberFMA(), decNumberInvert(), decNumberIsNormal(), decNumberIsSubnormal(), decNumberOr(), et decNumberXor().
#define decNumberIsZero | ( | dn | ) |
Valeur :
(*(dn)->lsu==0 \ && (dn)->digits==1 \ && (((dn)->bits&DECSPECIAL)==0))
Définition à la ligne 179 du fichier decNumber.h.
Référencé par decLnOp(), decNumberClass(), decNumberIsNormal(), decNumberIsSubnormal(), decNumberLogB(), decNumberPower(), operator<(), operator==(), et DecFloat_::SameQuantum().
#define decNumberRadix | ( | dn | ) | (10) |
Définition à la ligne 182 du fichier decNumber.h.
#define decNumberUnit uint16_t |
Définition à la ligne 61 du fichier decNumber.h.
#define DECNUMDIGITS 1 |
Définition à la ligne 53 du fichier decNumber.h.
#define DECNUMUNITS ((DECNUMDIGITS+DECDPUN-1)/DECDPUN) |
Définition à la ligne 66 du fichier decNumber.h.
#define DECSNAN 0x10 |
Définition à la ligne 36 du fichier decNumber.h.
Référencé par decAddOp(), decCompareOp(), decDivideOp(), decMultiplyOp(), decNaNs(), decNumberFromString(), decQuantizeOp(), et decToString().
#define DECSPECIAL (DECINF|DECNAN|DECSNAN) |
Définition à la ligne 38 du fichier decNumber.h.
Référencé par decNumberLog10(), decNumberToInt32(), decNumberToUInt32(), decToString(), et decTrim().
decNumber* decNumberAbs | ( | decNumber * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
Définition à la ligne 815 du fichier decNumber.c.
Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decContext::digits, decNumber::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 * | , | |
decContext * | ||||
) |
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 | ) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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
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
Référencé par operator<(), et operator==().
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
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
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
Définition à la ligne 1066 du fichier decNumber.c.
Références decCheckMath(), decExpOp(), decStatus(), decContext::digits, decNumber::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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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(), decNumber::digits, decContext::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* decNumberFromString | ( | decNumber * | , | |
const char * | , | |||
decContext * | ||||
) |
uint8_t* decNumberGetBCD | ( | const decNumber * | , | |
uint8_t * | ||||
) |
decNumber* decNumberInvert | ( | decNumber * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
Définition à la ligne 1213 du fichier decNumber.c.
Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decContext::digits, decNumber::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
int32_t decNumberIsNormal | ( | const decNumber * | , | |
decContext * | ||||
) |
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
int32_t decNumberIsSubnormal | ( | const decNumber * | , | |
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
Définition à la ligne 1286 du fichier decNumber.c.
Références DEC_Invalid_operation, decCheckMath(), decLnOp(), decStatus(), decContext::digits, decNumber::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 * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
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(), decContext::digits, decNumber::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, ©stat); // 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 * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
Définition à la ligne 1824 du fichier decNumber.c.
Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decContext::digits, decNumber::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 * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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(), decNumber::digits, decContext::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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
Définition à la ligne 2331 du fichier decNumber.c.
Références decCopyFit(), decFinish, decNaNs(), decNumberIsNaN, decStatus(), decTrim(), decContext::digits, decNumber::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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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* decNumberShift | ( | decNumber * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
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(), decContext::digits, decNumber::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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
char * | ||||
) |
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
int32_t decNumberToInt32 | ( | const decNumber * | , | |
decContext * | ||||
) |
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 * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
Définition à la ligne 3191 du fichier decNumber.c.
Références decNaNs(), decNumberCopy(), decNumberIsInfinite, decNumberQuantize(), decNumberZero(), decStatus(), decNumber::digits, decContext::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 * | , | |
const decNumber * | , | |||
decContext * | ||||
) |
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 * | , | |
char * | ||||
) |
Définition à la ligne 450 du fichier decNumber.c.
Références decToString().
00450 { 00451 decToString(dn, string, 0); 00452 return string; 00453 } // DecNumberToString
uint32_t decNumberToUInt32 | ( | const decNumber * | , | |
decContext * | ||||
) |
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
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 * | , | |
const decNumber * | , | |||
const decNumber * | , | |||
decContext * | ||||
) |
Définition à la ligne 3247 du fichier decNumber.c.
Références decNumber::bits, D2U, DEC_Invalid_operation, DECDPUN, decGetDigits(), decNumberIsNegative, decNumberIsSpecial, decStatus(), decContext::digits, decNumber::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
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