diff options
Diffstat (limited to 'gcc-4.4.3/libdecnumber/decCommon.c')
-rw-r--r-- | gcc-4.4.3/libdecnumber/decCommon.c | 1770 |
1 files changed, 0 insertions, 1770 deletions
diff --git a/gcc-4.4.3/libdecnumber/decCommon.c b/gcc-4.4.3/libdecnumber/decCommon.c deleted file mode 100644 index 5c47c2e4a..000000000 --- a/gcc-4.4.3/libdecnumber/decCommon.c +++ /dev/null @@ -1,1770 +0,0 @@ -/* Common code for fixed-size types in the decNumber C Library. - Copyright (C) 2007, 2009 Free Software Foundation, Inc. - Contributed by IBM Corporation. Author Mike Cowlishaw. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -/* ------------------------------------------------------------------ */ -/* decCommon.c -- common code for all three fixed-size types */ -/* ------------------------------------------------------------------ */ -/* This module comprises code that is shared between all the formats */ -/* (decSingle, decDouble, and decQuad); it includes set and extract */ -/* of format components, widening, narrowing, and string conversions. */ -/* */ -/* Unlike decNumber, parameterization takes place at compile time */ -/* rather than at runtime. The parameters are set in the decDouble.c */ -/* (etc.) files, which then include this one to produce the compiled */ -/* code. The functions here, therefore, are code shared between */ -/* multiple formats. */ -/* ------------------------------------------------------------------ */ -/* Names here refer to decFloat rather than to decDouble, etc., and */ -/* the functions are in strict alphabetical order. */ -/* Constants, tables, and debug function(s) are included only for QUAD */ -/* (which will always be compiled if DOUBLE or SINGLE are used). */ -/* */ -/* Whenever a decContext is used, only the status may be set (using */ -/* OR) or the rounding mode read; all other fields are ignored and */ -/* untouched. */ - -#include "decCommonSymbols.h" - -/* names for simpler testing and default context */ -#if DECPMAX==7 - #define SINGLE 1 - #define DOUBLE 0 - #define QUAD 0 - #define DEFCONTEXT DEC_INIT_DECIMAL32 -#elif DECPMAX==16 - #define SINGLE 0 - #define DOUBLE 1 - #define QUAD 0 - #define DEFCONTEXT DEC_INIT_DECIMAL64 -#elif DECPMAX==34 - #define SINGLE 0 - #define DOUBLE 0 - #define QUAD 1 - #define DEFCONTEXT DEC_INIT_DECIMAL128 -#else - #error Unexpected DECPMAX value -#endif - -/* Assertions */ - -#if DECPMAX!=7 && DECPMAX!=16 && DECPMAX!=34 - #error Unexpected Pmax (DECPMAX) value for this module -#endif - -/* Assert facts about digit characters, etc. */ -#if ('9'&0x0f)!=9 - #error This module assumes characters are of the form 0b....nnnn - /* where .... are don't care 4 bits and nnnn is 0000 through 1001 */ -#endif -#if ('9'&0xf0)==('.'&0xf0) - #error This module assumes '.' has a different mask than a digit -#endif - -/* Assert ToString lay-out conditions */ -#if DECSTRING<DECPMAX+9 - #error ToString needs at least 8 characters for lead-in and dot -#endif -#if DECPMAX+DECEMAXD+5 > DECSTRING - #error Exponent form can be too long for ToString to lay out safely -#endif -#if DECEMAXD > 4 - #error Exponent form is too long for ToString to lay out - /* Note: code for up to 9 digits exists in archives [decOct] */ -#endif - -/* Private functions used here and possibly in decBasic.c, etc. */ -static decFloat * decFinalize(decFloat *, bcdnum *, decContext *); -static Flag decBiStr(const char *, const char *, const char *); - -/* Macros and private tables; those which are not format-dependent */ -/* are only included if decQuad is being built. */ - -/* ------------------------------------------------------------------ */ -/* Combination field lookup tables (uInts to save measurable work) */ -/* */ -/* DECCOMBEXP - 2 most-significant-bits of exponent (00, 01, or */ -/* 10), shifted left for format, or DECFLOAT_Inf/NaN */ -/* DECCOMBWEXP - The same, for the next-wider format (unless QUAD) */ -/* DECCOMBMSD - 4-bit most-significant-digit */ -/* [0 if the index is a special (Infinity or NaN)] */ -/* DECCOMBFROM - 5-bit combination field from EXP top bits and MSD */ -/* (placed in uInt so no shift is needed) */ -/* */ -/* DECCOMBEXP, DECCOMBWEXP, and DECCOMBMSD are indexed by the sign */ -/* and 5-bit combination field (0-63, the second half of the table */ -/* identical to the first half) */ -/* DECCOMBFROM is indexed by expTopTwoBits*16 + msd */ -/* */ -/* DECCOMBMSD and DECCOMBFROM are not format-dependent and so are */ -/* only included once, when QUAD is being built */ -/* ------------------------------------------------------------------ */ -static const uInt DECCOMBEXP[64]={ - 0, 0, 0, 0, 0, 0, 0, 0, - 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, - 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, - 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, - 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, - 0, 0, 1<<DECECONL, 1<<DECECONL, - 2<<DECECONL, 2<<DECECONL, DECFLOAT_Inf, DECFLOAT_NaN, - 0, 0, 0, 0, 0, 0, 0, 0, - 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, - 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, - 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, - 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, 2<<DECECONL, - 0, 0, 1<<DECECONL, 1<<DECECONL, - 2<<DECECONL, 2<<DECECONL, DECFLOAT_Inf, DECFLOAT_NaN}; -#if !QUAD -static const uInt DECCOMBWEXP[64]={ - 0, 0, 0, 0, 0, 0, 0, 0, - 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, - 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, - 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, - 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, - 0, 0, 1<<DECWECONL, 1<<DECWECONL, - 2<<DECWECONL, 2<<DECWECONL, DECFLOAT_Inf, DECFLOAT_NaN, - 0, 0, 0, 0, 0, 0, 0, 0, - 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, - 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, 1<<DECWECONL, - 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, - 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, 2<<DECWECONL, - 0, 0, 1<<DECWECONL, 1<<DECWECONL, - 2<<DECWECONL, 2<<DECWECONL, DECFLOAT_Inf, DECFLOAT_NaN}; -#endif - -#if QUAD -const uInt DECCOMBMSD[64]={ - 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 1, - 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0}; - -const uInt DECCOMBFROM[48]={ - 0x00000000, 0x04000000, 0x08000000, 0x0C000000, 0x10000000, 0x14000000, - 0x18000000, 0x1C000000, 0x60000000, 0x64000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x20000000, 0x24000000, - 0x28000000, 0x2C000000, 0x30000000, 0x34000000, 0x38000000, 0x3C000000, - 0x68000000, 0x6C000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x40000000, 0x44000000, 0x48000000, 0x4C000000, - 0x50000000, 0x54000000, 0x58000000, 0x5C000000, 0x70000000, 0x74000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; - -/* ------------------------------------------------------------------ */ -/* Request and include the tables to use for conversions */ -/* ------------------------------------------------------------------ */ -#define DEC_BCD2DPD 1 /* 0-0x999 -> DPD */ -#define DEC_BIN2DPD 1 /* 0-999 -> DPD */ -#define DEC_BIN2BCD8 1 /* 0-999 -> ddd, len */ -#define DEC_DPD2BCD8 1 /* DPD -> ddd, len */ -#define DEC_DPD2BIN 1 /* DPD -> 0-999 */ -#define DEC_DPD2BINK 1 /* DPD -> 0-999000 */ -#define DEC_DPD2BINM 1 /* DPD -> 0-999000000 */ -#include "decDPD.h" /* source of the lookup tables */ - -#endif - -/* ----------------------------------------------------------------- */ -/* decBiStr -- compare string with pairwise options */ -/* */ -/* targ is the string to compare */ -/* str1 is one of the strings to compare against (length may be 0) */ -/* str2 is the other; it must be the same length as str1 */ -/* */ -/* returns 1 if strings compare equal, (that is, targ is the same */ -/* length as str1 and str2, and each character of targ is in one */ -/* of str1 or str2 in the corresponding position), or 0 otherwise */ -/* */ -/* This is used for generic caseless compare, including the awkward */ -/* case of the Turkish dotted and dotless Is. Use as (for example): */ -/* if (decBiStr(test, "mike", "MIKE")) ... */ -/* ----------------------------------------------------------------- */ -static Flag decBiStr(const char *targ, const char *str1, const char *str2) { - for (;;targ++, str1++, str2++) { - if (*targ!=*str1 && *targ!=*str2) return 0; - /* *targ has a match in one (or both, if terminator) */ - if (*targ=='\0') break; - } /* forever */ - return 1; - } /* decBiStr */ - -/* ------------------------------------------------------------------ */ -/* decFinalize -- adjust and store a final result */ -/* */ -/* df is the decFloat format number which gets the final result */ -/* num is the descriptor of the number to be checked and encoded */ -/* [its values, including the coefficient, may be modified] */ -/* set is the context to use */ -/* returns df */ -/* */ -/* The num descriptor may point to a bcd8 string of any length; this */ -/* string may have leading insignificant zeros. If it has more than */ -/* DECPMAX digits then the final digit can be a round-for-reround */ -/* digit (i.e., it may include a sticky bit residue). */ -/* */ -/* The exponent (q) may be one of the codes for a special value and */ -/* can be up to 999999999 for conversion from string. */ -/* */ -/* No error is possible, but Inexact, Underflow, and/or Overflow may */ -/* be set. */ -/* ------------------------------------------------------------------ */ -/* Constant whose size varies with format; also the check for surprises */ -static uByte allnines[DECPMAX]= -#if SINGLE - {9, 9, 9, 9, 9, 9, 9}; -#elif DOUBLE - {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}; -#elif QUAD - {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}; -#endif - -static decFloat * decFinalize(decFloat *df, bcdnum *num, - decContext *set) { - uByte *ub; /* work */ - uInt dpd; /* .. */ - uByte *umsd=num->msd; /* local copy */ - uByte *ulsd=num->lsd; /* .. */ - uInt encode; /* encoding accumulator */ - Int length; /* coefficient length */ - - #if DECCHECK - Int clen=ulsd-umsd+1; - #if QUAD - #define COEXTRA 2 /* extra-long coefficent */ - #else - #define COEXTRA 0 - #endif - if (clen<1 || clen>DECPMAX*3+2+COEXTRA) - printf("decFinalize: suspect coefficient [length=%ld]\n", (LI)clen); - if (num->sign!=0 && num->sign!=DECFLOAT_Sign) - printf("decFinalize: bad sign [%08lx]\n", (LI)num->sign); - if (!EXPISSPECIAL(num->exponent) - && (num->exponent>1999999999 || num->exponent<-1999999999)) - printf("decFinalize: improbable exponent [%ld]\n", (LI)num->exponent); - /* decShowNum(num, "final"); */ - #endif - - /* A special will have an 'exponent' which is very positive and a */ - /* coefficient < DECPMAX */ - length=(uInt)(ulsd-umsd+1); /* coefficient length */ - - if (!NUMISSPECIAL(num)) { - Int drop; /* digits to be dropped */ - /* skip leading insignificant zeros to calculate an exact length */ - /* [this is quite expensive] */ - if (*umsd==0) { - for (; UINTAT(umsd)==0 && umsd+3<ulsd;) umsd+=4; - for (; *umsd==0 && umsd<ulsd;) umsd++; - length=ulsd-umsd+1; /* recalculate */ - } - drop=MAXI(length-DECPMAX, DECQTINY-num->exponent); - /* drop can now be > digits for bottom-clamp (subnormal) cases */ - if (drop>0) { /* rounding needed */ - /* (decFloatQuantize has very similar code to this, so any */ - /* changes may need to be made there, too) */ - uByte *roundat; /* -> re-round digit */ - uByte reround; /* reround value */ - /* printf("Rounding; drop=%ld\n", (LI)drop); */ - - num->exponent+=drop; /* always update exponent */ - - /* Three cases here: */ - /* 1. new LSD is in coefficient (almost always) */ - /* 2. new LSD is digit to left of coefficient (so MSD is */ - /* round-for-reround digit) */ - /* 3. new LSD is to left of case 2 (whole coefficient is sticky) */ - /* [duplicate check-stickies code to save a test] */ - /* [by-digit check for stickies as runs of zeros are rare] */ - if (drop<length) { /* NB lengths not addresses */ - roundat=umsd+length-drop; - reround=*roundat; - for (ub=roundat+1; ub<=ulsd; ub++) { - if (*ub!=0) { /* non-zero to be discarded */ - reround=DECSTICKYTAB[reround]; /* apply sticky bit */ - break; /* [remainder don't-care] */ - } - } /* check stickies */ - ulsd=roundat-1; /* new LSD */ - } - else { /* edge case */ - if (drop==length) { - roundat=umsd; - reround=*roundat; - } - else { - roundat=umsd-1; - reround=0; - } - for (ub=roundat+1; ub<=ulsd; ub++) { - if (*ub!=0) { /* non-zero to be discarded */ - reround=DECSTICKYTAB[reround]; /* apply sticky bit */ - break; /* [remainder don't-care] */ - } - } /* check stickies */ - *umsd=0; /* coefficient is a 0 */ - ulsd=umsd; /* .. */ - } - - if (reround!=0) { /* discarding non-zero */ - uInt bump=0; - set->status|=DEC_Inexact; - /* if adjusted exponent [exp+digits-1] is < EMIN then num is */ - /* subnormal -- so raise Underflow */ - if (num->exponent<DECEMIN && (num->exponent+(ulsd-umsd+1)-1)<DECEMIN) - set->status|=DEC_Underflow; - - /* next decide whether increment of the coefficient is needed */ - if (set->round==DEC_ROUND_HALF_EVEN) { /* fastpath slowest case */ - if (reround>5) bump=1; /* >0.5 goes up */ - else if (reround==5) /* exactly 0.5000 .. */ - bump=*ulsd & 0x01; /* .. up iff [new] lsd is odd */ - } /* r-h-e */ - else switch (set->round) { - case DEC_ROUND_DOWN: { - /* no change */ - break;} /* r-d */ - case DEC_ROUND_HALF_DOWN: { - if (reround>5) bump=1; - break;} /* r-h-d */ - case DEC_ROUND_HALF_UP: { - if (reround>=5) bump=1; - break;} /* r-h-u */ - case DEC_ROUND_UP: { - if (reround>0) bump=1; - break;} /* r-u */ - case DEC_ROUND_CEILING: { - /* same as _UP for positive numbers, and as _DOWN for negatives */ - if (!num->sign && reround>0) bump=1; - break;} /* r-c */ - case DEC_ROUND_FLOOR: { - /* same as _UP for negative numbers, and as _DOWN for positive */ - /* [negative reround cannot occur on 0] */ - if (num->sign && reround>0) bump=1; - break;} /* r-f */ - case DEC_ROUND_05UP: { - if (reround>0) { /* anything out there is 'sticky' */ - /* bump iff lsd=0 or 5; this cannot carry so it could be */ - /* effected immediately with no bump -- but the code */ - /* is clearer if this is done the same way as the others */ - if (*ulsd==0 || *ulsd==5) bump=1; - } - break;} /* r-r */ - default: { /* e.g., DEC_ROUND_MAX */ - set->status|=DEC_Invalid_context; - #if DECCHECK - printf("Unknown rounding mode: %ld\n", (LI)set->round); - #endif - break;} - } /* switch (not r-h-e) */ - /* printf("ReRound: %ld bump: %ld\n", (LI)reround, (LI)bump); */ - - if (bump!=0) { /* need increment */ - /* increment the coefficient; this might end up with 1000... */ - /* (after the all nines case) */ - ub=ulsd; - for(; ub-3>=umsd && UINTAT(ub-3)==0x09090909; ub-=4) UINTAT(ub-3)=0; - /* [note ub could now be to left of msd, and it is not safe */ - /* to write to the the left of the msd] */ - /* now at most 3 digits left to non-9 (usually just the one) */ - for (; ub>=umsd; *ub=0, ub--) { - if (*ub==9) continue; /* carry */ - *ub+=1; - break; - } - if (ub<umsd) { /* had all-nines */ - *umsd=1; /* coefficient to 1000... */ - /* usually the 1000... coefficient can be used as-is */ - if ((ulsd-umsd+1)==DECPMAX) { - num->exponent++; - } - else { - /* if coefficient is shorter than Pmax then num is */ - /* subnormal, so extend it; this is safe as drop>0 */ - /* (or, if the coefficient was supplied above, it could */ - /* not be 9); this may make the result normal. */ - ulsd++; - *ulsd=0; - /* [exponent unchanged] */ - #if DECCHECK - if (num->exponent!=DECQTINY) /* sanity check */ - printf("decFinalize: bad all-nines extend [^%ld, %ld]\n", - (LI)num->exponent, (LI)(ulsd-umsd+1)); - #endif - } /* subnormal extend */ - } /* had all-nines */ - } /* bump needed */ - } /* inexact rounding */ - - length=ulsd-umsd+1; /* recalculate (may be <DECPMAX) */ - } /* need round (drop>0) */ - - /* The coefficient will now fit and has final length unless overflow */ - /* decShowNum(num, "rounded"); */ - - /* if exponent is >=emax may have to clamp, overflow, or fold-down */ - if (num->exponent>DECEMAX-(DECPMAX-1)) { /* is edge case */ - /* printf("overflow checks...\n"); */ - if (*ulsd==0 && ulsd==umsd) { /* have zero */ - num->exponent=DECEMAX-(DECPMAX-1); /* clamp to max */ - } - else if ((num->exponent+length-1)>DECEMAX) { /* > Nmax */ - /* Overflow -- these could go straight to encoding, here, but */ - /* instead num is adjusted to keep the code cleaner */ - Flag needmax=0; /* 1 for finite result */ - set->status|=(DEC_Overflow | DEC_Inexact); - switch (set->round) { - case DEC_ROUND_DOWN: { - needmax=1; /* never Infinity */ - break;} /* r-d */ - case DEC_ROUND_05UP: { - needmax=1; /* never Infinity */ - break;} /* r-05 */ - case DEC_ROUND_CEILING: { - if (num->sign) needmax=1; /* Infinity iff non-negative */ - break;} /* r-c */ - case DEC_ROUND_FLOOR: { - if (!num->sign) needmax=1; /* Infinity iff negative */ - break;} /* r-f */ - default: break; /* Infinity in all other cases */ - } - if (!needmax) { /* easy .. set Infinity */ - num->exponent=DECFLOAT_Inf; - *umsd=0; /* be clean: coefficient to 0 */ - ulsd=umsd; /* .. */ - } - else { /* return Nmax */ - umsd=allnines; /* use constant array */ - ulsd=allnines+DECPMAX-1; - num->exponent=DECEMAX-(DECPMAX-1); - } - } - else { /* no overflow but non-zero and may have to fold-down */ - Int shift=num->exponent-(DECEMAX-(DECPMAX-1)); - if (shift>0) { /* fold-down needed */ - /* fold down needed; must copy to buffer in order to pad */ - /* with zeros safely; fortunately this is not the worst case */ - /* path because cannot have had a round */ - uByte buffer[ROUNDUP(DECPMAX+3, 4)]; /* [+3 allows uInt padding] */ - uByte *s=umsd; /* source */ - uByte *t=buffer; /* safe target */ - uByte *tlsd=buffer+(ulsd-umsd)+shift; /* target LSD */ - /* printf("folddown shift=%ld\n", (LI)shift); */ - for (; s<=ulsd; s+=4, t+=4) UINTAT(t)=UINTAT(s); - for (t=tlsd-shift+1; t<=tlsd; t+=4) UINTAT(t)=0; /* pad */ - num->exponent-=shift; - umsd=buffer; - ulsd=tlsd; - } - } /* fold-down? */ - length=ulsd-umsd+1; /* recalculate length */ - } /* high-end edge case */ - } /* finite number */ - - /*------------------------------------------------------------------*/ - /* At this point the result will properly fit the decFloat */ - /* encoding, and it can be encoded with no possibility of error */ - /*------------------------------------------------------------------*/ - /* Following code does not alter coefficient (could be allnines array) */ - - if (length==DECPMAX) { - return decFloatFromBCD(df, num->exponent, umsd, num->sign); - } - - /* Here when length is short */ - if (!NUMISSPECIAL(num)) { /* is still finite */ - /* encode the combination field and exponent continuation */ - uInt uexp=(uInt)(num->exponent+DECBIAS); /* biased exponent */ - uInt code=(uexp>>DECECONL)<<4; /* top two bits of exp */ - /* [msd=0] */ - /* look up the combination field and make high word */ - encode=DECCOMBFROM[code]; /* indexed by (0-2)*16+msd */ - encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */ - } - else encode=num->exponent; /* special [already in word] */ - /* [coefficient length here will be < DECPMAX] */ - - encode|=num->sign; /* add sign */ - - /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */ - /* refers to the declet from the least significant three digits) */ - /* and put the corresponding DPD code into dpd. Access to umsd and */ - /* ulsd (pointers to the most and least significant digit of the */ - /* variable-length coefficient) is assumed, along with use of a */ - /* working pointer, uInt *ub. */ - /* As not full-length then chances are there are many leading zeros */ - /* [and there may be a partial triad] */ - #define getDPD(dpd, n) ub=ulsd-(3*(n))-2; \ - if (ub<umsd-2) dpd=0; \ - else if (ub>=umsd) dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)]; \ - else {dpd=*(ub+2); if (ub+1==umsd) dpd+=*(ub+1)*16; dpd=BCD2DPD[dpd];} - - /* place the declets in the encoding words and copy to result (df), */ - /* according to endianness; in all cases complete the sign word */ - /* first */ - #if DECPMAX==7 - getDPD(dpd, 1); - encode|=dpd<<10; - getDPD(dpd, 0); - encode|=dpd; - DFWORD(df, 0)=encode; /* just the one word */ - - #elif DECPMAX==16 - getDPD(dpd, 4); encode|=dpd<<8; - getDPD(dpd, 3); encode|=dpd>>2; - DFWORD(df, 0)=encode; - encode=dpd<<30; - getDPD(dpd, 2); encode|=dpd<<20; - getDPD(dpd, 1); encode|=dpd<<10; - getDPD(dpd, 0); encode|=dpd; - DFWORD(df, 1)=encode; - - #elif DECPMAX==34 - getDPD(dpd,10); encode|=dpd<<4; - getDPD(dpd, 9); encode|=dpd>>6; - DFWORD(df, 0)=encode; - - encode=dpd<<26; - getDPD(dpd, 8); encode|=dpd<<16; - getDPD(dpd, 7); encode|=dpd<<6; - getDPD(dpd, 6); encode|=dpd>>4; - DFWORD(df, 1)=encode; - - encode=dpd<<28; - getDPD(dpd, 5); encode|=dpd<<18; - getDPD(dpd, 4); encode|=dpd<<8; - getDPD(dpd, 3); encode|=dpd>>2; - DFWORD(df, 2)=encode; - - encode=dpd<<30; - getDPD(dpd, 2); encode|=dpd<<20; - getDPD(dpd, 1); encode|=dpd<<10; - getDPD(dpd, 0); encode|=dpd; - DFWORD(df, 3)=encode; - #endif - - /* printf("Status: %08lx\n", (LI)set->status); */ - /* decFloatShow(df, "final"); */ - return df; - } /* decFinalize */ - -/* ------------------------------------------------------------------ */ -/* decFloatFromBCD -- set decFloat from exponent, BCD8, and sign */ -/* */ -/* df is the target decFloat */ -/* exp is the in-range unbiased exponent, q, or a special value in */ -/* the form returned by decFloatGetExponent */ -/* bcdar holds DECPMAX digits to set the coefficient from, one */ -/* digit in each byte (BCD8 encoding); the first (MSD) is ignored */ -/* if df is a NaN; all are ignored if df is infinite. */ -/* All bytes must be in 0-9; results undefined otherwise. */ -/* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */ -/* returns df, which will be canonical */ -/* */ -/* No error is possible, and no status will be set. */ -/* ------------------------------------------------------------------ */ -decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar, - Int sig) { - uInt encode, dpd; /* work */ - const uByte *ub; /* .. */ - - if (EXPISSPECIAL(exp)) encode=exp|sig;/* specials already encoded */ - else { /* is finite */ - /* encode the combination field and exponent continuation */ - uInt uexp=(uInt)(exp+DECBIAS); /* biased exponent */ - uInt code=(uexp>>DECECONL)<<4; /* top two bits of exp */ - code+=bcdar[0]; /* add msd */ - /* look up the combination field and make high word */ - encode=DECCOMBFROM[code]|sig; /* indexed by (0-2)*16+msd */ - encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */ - } - - /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */ - /* refers to the declet from the least significant three digits) */ - /* and put the corresponding DPD code into dpd. */ - /* Use of a working pointer, uInt *ub, is assumed. */ - - #define getDPDf(dpd, n) ub=bcdar+DECPMAX-1-(3*(n))-2; \ - dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)]; - - /* place the declets in the encoding words and copy to result (df), */ - /* according to endianness; in all cases complete the sign word */ - /* first */ - #if DECPMAX==7 - getDPDf(dpd, 1); - encode|=dpd<<10; - getDPDf(dpd, 0); - encode|=dpd; - DFWORD(df, 0)=encode; /* just the one word */ - - #elif DECPMAX==16 - getDPDf(dpd, 4); encode|=dpd<<8; - getDPDf(dpd, 3); encode|=dpd>>2; - DFWORD(df, 0)=encode; - encode=dpd<<30; - getDPDf(dpd, 2); encode|=dpd<<20; - getDPDf(dpd, 1); encode|=dpd<<10; - getDPDf(dpd, 0); encode|=dpd; - DFWORD(df, 1)=encode; - - #elif DECPMAX==34 - getDPDf(dpd,10); encode|=dpd<<4; - getDPDf(dpd, 9); encode|=dpd>>6; - DFWORD(df, 0)=encode; - - encode=dpd<<26; - getDPDf(dpd, 8); encode|=dpd<<16; - getDPDf(dpd, 7); encode|=dpd<<6; - getDPDf(dpd, 6); encode|=dpd>>4; - DFWORD(df, 1)=encode; - - encode=dpd<<28; - getDPDf(dpd, 5); encode|=dpd<<18; - getDPDf(dpd, 4); encode|=dpd<<8; - getDPDf(dpd, 3); encode|=dpd>>2; - DFWORD(df, 2)=encode; - - encode=dpd<<30; - getDPDf(dpd, 2); encode|=dpd<<20; - getDPDf(dpd, 1); encode|=dpd<<10; - getDPDf(dpd, 0); encode|=dpd; - DFWORD(df, 3)=encode; - #endif - /* decFloatShow(df, "final"); */ - return df; - } /* decFloatFromBCD */ - -/* ------------------------------------------------------------------ */ -/* decFloatFromPacked -- set decFloat from exponent and packed BCD */ -/* */ -/* df is the target decFloat */ -/* exp is the in-range unbiased exponent, q, or a special value in */ -/* the form returned by decFloatGetExponent */ -/* packed holds DECPMAX packed decimal digits plus a sign nibble */ -/* (all 6 codes are OK); the first (MSD) is ignored if df is a NaN */ -/* and all except sign are ignored if df is infinite. For DOUBLE */ -/* and QUAD the first (pad) nibble is also ignored in all cases. */ -/* All coefficient nibbles must be in 0-9 and sign in A-F; results */ -/* are undefined otherwise. */ -/* returns df, which will be canonical */ -/* */ -/* No error is possible, and no status will be set. */ -/* ------------------------------------------------------------------ */ -decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) { - uByte bcdar[DECPMAX+2]; /* work [+1 for pad, +1 for sign] */ - const uByte *ip; /* .. */ - uByte *op; /* .. */ - Int sig=0; /* sign */ - - /* expand coefficient and sign to BCDAR */ - #if SINGLE - op=bcdar+1; /* no pad digit */ - #else - op=bcdar; /* first (pad) digit ignored */ - #endif - for (ip=packed; ip<packed+((DECPMAX+2)/2); ip++) { - *op++=*ip>>4; - *op++=(uByte)(*ip&0x0f); /* [final nibble is sign] */ - } - op--; /* -> sign byte */ - if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign; - - if (EXPISSPECIAL(exp)) { /* Infinity or NaN */ - if (!EXPISINF(exp)) bcdar[1]=0; /* a NaN: ignore MSD */ - else memset(bcdar+1, 0, DECPMAX); /* Infinite: coefficient to 0 */ - } - return decFloatFromBCD(df, exp, bcdar+1, sig); - } /* decFloatFromPacked */ - -/* ------------------------------------------------------------------ */ -/* decFloatFromString -- conversion from numeric string */ -/* */ -/* result is the decFloat format number which gets the result of */ -/* the conversion */ -/* *string is the character string which should contain a valid */ -/* number (which may be a special value), \0-terminated */ -/* If there are too many significant digits in the */ -/* coefficient it will be rounded. */ -/* set is the context */ -/* returns result */ -/* */ -/* The length of the coefficient and the size of the exponent are */ -/* checked by this routine, so the correct error (Underflow or */ -/* Overflow) can be reported or rounding applied, as necessary. */ -/* */ -/* There is no limit to the coefficient length for finite inputs; */ -/* NaN payloads must be integers with no more than DECPMAX-1 digits. */ -/* Exponents may have up to nine significant digits. */ -/* */ -/* If bad syntax is detected, the result will be a quiet NaN. */ -/* ------------------------------------------------------------------ */ -decFloat * decFloatFromString(decFloat *result, const char *string, - decContext *set) { - Int digits; /* count of digits in coefficient */ - const char *dotchar=NULL; /* where dot was found [NULL if none] */ - const char *cfirst=string; /* -> first character of decimal part */ - const char *c; /* work */ - uByte *ub; /* .. */ - bcdnum num; /* collects data for finishing */ - uInt error=DEC_Conversion_syntax; /* assume the worst */ - uByte buffer[ROUNDUP(DECSTRING+11, 8)]; /* room for most coefficents, */ - /* some common rounding, +3, & pad */ - #if DECTRACE - /* printf("FromString %s ...\n", string); */ - #endif - - for(;;) { /* once-only 'loop' */ - num.sign=0; /* assume non-negative */ - num.msd=buffer; /* MSD is here always */ - - /* detect and validate the coefficient, including any leading, */ - /* trailing, or embedded '.' */ - /* [could test four-at-a-time here (saving 10% for decQuads), */ - /* but that risks storage violation because the position of the */ - /* terminator is unknown] */ - for (c=string;; c++) { /* -> input character */ - if (((unsigned)(*c-'0'))<=9) continue; /* '0' through '9' is good */ - if (*c=='\0') break; /* most common non-digit */ - if (*c=='.') { - if (dotchar!=NULL) break; /* not first '.' */ - dotchar=c; /* record offset into decimal part */ - continue;} - if (c==string) { /* first in string... */ - if (*c=='-') { /* valid - sign */ - cfirst++; - num.sign=DECFLOAT_Sign; - continue;} - if (*c=='+') { /* valid + sign */ - cfirst++; - continue;} - } - /* *c is not a digit, terminator, or a valid +, -, or '.' */ - break; - } /* c loop */ - - digits=(uInt)(c-cfirst); /* digits (+1 if a dot) */ - - if (digits>0) { /* had digits and/or dot */ - const char *clast=c-1; /* note last coefficient char position */ - Int exp=0; /* exponent accumulator */ - if (*c!='\0') { /* something follows the coefficient */ - uInt edig; /* unsigned work */ - /* had some digits and more to come; expect E[+|-]nnn now */ - const char *firstexp; /* exponent first non-zero */ - if (*c!='E' && *c!='e') break; - c++; /* to (optional) sign */ - if (*c=='-' || *c=='+') c++; /* step over sign (c=clast+2) */ - if (*c=='\0') break; /* no digits! (e.g., '1.2E') */ - for (; *c=='0';) c++; /* skip leading zeros [even last] */ - firstexp=c; /* remember start [maybe '\0'] */ - /* gather exponent digits */ - edig=(uInt)*c-(uInt)'0'; - if (edig<=9) { /* [check not bad or terminator] */ - exp+=edig; /* avoid initial X10 */ - c++; - for (;; c++) { - edig=(uInt)*c-(uInt)'0'; - if (edig>9) break; - exp=exp*10+edig; - } - } - /* if not now on the '\0', *c must not be a digit */ - if (*c!='\0') break; - - /* (this next test must be after the syntax checks) */ - /* if definitely more than the possible digits for format then */ - /* the exponent may have wrapped, so simply set it to a certain */ - /* over/underflow value */ - if (c>firstexp+DECEMAXD) exp=DECEMAX*2; - if (*(clast+2)=='-') exp=-exp; /* was negative */ - } /* digits>0 */ - - if (dotchar!=NULL) { /* had a '.' */ - digits--; /* remove from digits count */ - if (digits==0) break; /* was dot alone: bad syntax */ - exp-=(Int)(clast-dotchar); /* adjust exponent */ - /* [the '.' can now be ignored] */ - } - num.exponent=exp; /* exponent is good; store it */ - - /* Here when whole string has been inspected and syntax is good */ - /* cfirst->first digit or dot, clast->last digit or dot */ - error=0; /* no error possible now */ - - /* if the number of digits in the coefficient will fit in buffer */ - /* then it can simply be converted to bcd8 and copied -- decFinalize */ - /* will take care of leading zeros and rounding; the buffer is big */ - /* enough for all canonical coefficients, including 0.00000nn... */ - ub=buffer; - if (digits<=(Int)(sizeof(buffer)-3)) { /* [-3 allows by-4s copy] */ - c=cfirst; - if (dotchar!=NULL) { /* a dot to worry about */ - if (*(c+1)=='.') { /* common canonical case */ - *ub++=(uByte)(*c-'0'); /* copy leading digit */ - c+=2; /* prepare to handle rest */ - } - else for (; c<=clast;) { /* '.' could be anywhere */ - /* as usual, go by fours when safe; NB it has been asserted */ - /* that a '.' does not have the same mask as a digit */ - if (c<=clast-3 /* safe for four */ - && (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* test four */ - UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; /* to BCD8 */ - ub+=4; - c+=4; - continue; - } - if (*c=='.') { /* found the dot */ - c++; /* step over it .. */ - break; /* .. and handle the rest */ - } - *ub++=(uByte)(*c++-'0'); - } - } /* had dot */ - /* Now no dot; do this by fours (where safe) */ - for (; c<=clast-3; c+=4, ub+=4) UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; - for (; c<=clast; c++, ub++) *ub=(uByte)(*c-'0'); - num.lsd=buffer+digits-1; /* record new LSD */ - } /* fits */ - - else { /* too long for buffer */ - /* [This is a rare and unusual case; arbitrary-length input] */ - /* strip leading zeros [but leave final 0 if all 0's] */ - if (*cfirst=='.') cfirst++; /* step past dot at start */ - if (*cfirst=='0') { /* [cfirst always -> digit] */ - for (; cfirst<clast; cfirst++) { - if (*cfirst!='0') { /* non-zero found */ - if (*cfirst=='.') continue; /* [ignore] */ - break; /* done */ - } - digits--; /* 0 stripped */ - } /* cfirst */ - } /* at least one leading 0 */ - - /* the coefficient is now as short as possible, but may still */ - /* be too long; copy up to Pmax+1 digits to the buffer, then */ - /* just record any non-zeros (set round-for-reround digit) */ - for (c=cfirst; c<=clast && ub<=buffer+DECPMAX; c++) { - /* (see commentary just above) */ - if (c<=clast-3 /* safe for four */ - && (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */ - UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; /* to BCD8 */ - ub+=4; - c+=3; /* [will become 4] */ - continue; - } - if (*c=='.') continue; /* [ignore] */ - *ub++=(uByte)(*c-'0'); - } - ub--; /* -> LSD */ - for (; c<=clast; c++) { /* inspect remaining chars */ - if (*c!='0') { /* sticky bit needed */ - if (*c=='.') continue; /* [ignore] */ - *ub=DECSTICKYTAB[*ub]; /* update round-for-reround */ - break; /* no need to look at more */ - } - } - num.lsd=ub; /* record LSD */ - /* adjust exponent for dropped digits */ - num.exponent+=digits-(Int)(ub-buffer+1); - } /* too long for buffer */ - } /* digits or dot */ - - else { /* no digits or dot were found */ - if (*c=='\0') break; /* nothing to come is bad */ - /* only Infinities and NaNs are allowed, here */ - buffer[0]=0; /* default a coefficient of 0 */ - num.lsd=buffer; /* .. */ - if (decBiStr(c, "infinity", "INFINITY") - || decBiStr(c, "inf", "INF")) num.exponent=DECFLOAT_Inf; - else { /* should be a NaN */ - num.exponent=DECFLOAT_qNaN; /* assume quiet NaN */ - if (*c=='s' || *c=='S') { /* probably an sNaN */ - c++; - num.exponent=DECFLOAT_sNaN; /* assume is in fact sNaN */ - } - if (*c!='N' && *c!='n') break; /* check caseless "NaN" */ - c++; - if (*c!='a' && *c!='A') break; /* .. */ - c++; - if (*c!='N' && *c!='n') break; /* .. */ - c++; - /* now either nothing, or nnnn payload (no dots), expected */ - /* -> start of integer, and skip leading 0s [including plain 0] */ - for (cfirst=c; *cfirst=='0';) cfirst++; - if (*cfirst!='\0') { /* not empty or all-0, payload */ - /* payload found; check all valid digits and copy to buffer as bcd8 */ - ub=buffer; - for (c=cfirst;; c++, ub++) { - if ((unsigned)(*c-'0')>9) break; /* quit if not 0-9 */ - if (c-cfirst==DECPMAX-1) break; /* too many digits */ - *ub=(uByte)(*c-'0'); /* good bcd8 */ - } - if (*c!='\0') break; /* not all digits, or too many */ - num.lsd=ub-1; /* record new LSD */ - } - } /* NaN or sNaN */ - error=0; /* syntax is OK */ - break; /* done with specials */ - } /* digits=0 (special expected) */ - break; - } /* [for(;;) break] */ - - /* decShowNum(&num, "fromStr"); */ - - if (error!=0) { - set->status|=error; - num.exponent=DECFLOAT_qNaN; /* set up quiet NaN */ - num.sign=0; /* .. with 0 sign */ - buffer[0]=0; /* .. and coefficient */ - num.lsd=buffer; /* .. */ - /* decShowNum(&num, "oops"); */ - } - - /* decShowNum(&num, "dffs"); */ - decFinalize(result, &num, set); /* round, check, and lay out */ - /* decFloatShow(result, "fromString"); */ - return result; - } /* decFloatFromString */ - -/* ------------------------------------------------------------------ */ -/* decFloatFromWider -- conversion from next-wider format */ -/* */ -/* result is the decFloat format number which gets the result of */ -/* the conversion */ -/* wider is the decFloatWider format number which will be narrowed */ -/* set is the context */ -/* returns result */ -/* */ -/* Narrowing can cause rounding, overflow, etc., but not Invalid */ -/* operation (sNaNs are copied and do not signal). */ -/* ------------------------------------------------------------------ */ -/* narrow-to is not possible for decQuad format numbers; simply omit */ -#if !QUAD -decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider, - decContext *set) { - bcdnum num; /* collects data for finishing */ - uByte bcdar[DECWPMAX]; /* room for wider coefficient */ - uInt widerhi=DFWWORD(wider, 0); /* top word */ - Int exp; - - GETWCOEFF(wider, bcdar); - - num.msd=bcdar; /* MSD is here always */ - num.lsd=bcdar+DECWPMAX-1; /* LSD is here always */ - num.sign=widerhi&0x80000000; /* extract sign [DECFLOAT_Sign=Neg] */ - - /* decode the wider combination field to exponent */ - exp=DECCOMBWEXP[widerhi>>26]; /* decode from wider combination field */ - /* if it is a special there's nothing to do unless sNaN; if it's */ - /* finite then add the (wider) exponent continuation and unbias */ - if (EXPISSPECIAL(exp)) exp=widerhi&0x7e000000; /* include sNaN selector */ - else exp+=GETWECON(wider)-DECWBIAS; - num.exponent=exp; - - /* decShowNum(&num, "dffw"); */ - return decFinalize(result, &num, set);/* round, check, and lay out */ - } /* decFloatFromWider */ -#endif - -/* ------------------------------------------------------------------ */ -/* decFloatGetCoefficient -- get coefficient as BCD8 */ -/* */ -/* df is the decFloat from which to extract the coefficient */ -/* bcdar is where DECPMAX bytes will be written, one BCD digit in */ -/* each byte (BCD8 encoding); if df is a NaN the first byte will */ -/* be zero, and if it is infinite they will all be zero */ -/* returns the sign of the coefficient (DECFLOAT_Sign if negative, */ -/* 0 otherwise) */ -/* */ -/* No error is possible, and no status will be set. If df is a */ -/* special value the array is set to zeros (for Infinity) or to the */ -/* payload of a qNaN or sNaN. */ -/* ------------------------------------------------------------------ */ -Int decFloatGetCoefficient(const decFloat *df, uByte *bcdar) { - if (DFISINF(df)) memset(bcdar, 0, DECPMAX); - else { - GETCOEFF(df, bcdar); /* use macro */ - if (DFISNAN(df)) bcdar[0]=0; /* MSD needs correcting */ - } - return DFISSIGNED(df); - } /* decFloatGetCoefficient */ - -/* ------------------------------------------------------------------ */ -/* decFloatGetExponent -- get unbiased exponent */ -/* */ -/* df is the decFloat from which to extract the exponent */ -/* returns the exponent, q. */ -/* */ -/* No error is possible, and no status will be set. If df is a */ -/* special value the first seven bits of the decFloat are returned, */ -/* left adjusted and with the first (sign) bit set to 0 (followed by */ -/* 25 0 bits). e.g., -sNaN would return 0x7e000000 (DECFLOAT_sNaN). */ -/* ------------------------------------------------------------------ */ -Int decFloatGetExponent(const decFloat *df) { - if (DFISSPECIAL(df)) return DFWORD(df, 0)&0x7e000000; - return GETEXPUN(df); - } /* decFloatGetExponent */ - -/* ------------------------------------------------------------------ */ -/* decFloatSetCoefficient -- set coefficient from BCD8 */ -/* */ -/* df is the target decFloat (and source of exponent/special value) */ -/* bcdar holds DECPMAX digits to set the coefficient from, one */ -/* digit in each byte (BCD8 encoding); the first (MSD) is ignored */ -/* if df is a NaN; all are ignored if df is infinite. */ -/* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */ -/* returns df, which will be canonical */ -/* */ -/* No error is possible, and no status will be set. */ -/* ------------------------------------------------------------------ */ -decFloat * decFloatSetCoefficient(decFloat *df, const uByte *bcdar, - Int sig) { - uInt exp; /* for exponent */ - uByte bcdzero[DECPMAX]; /* for infinities */ - - /* Exponent/special code is extracted from df */ - if (DFISSPECIAL(df)) { - exp=DFWORD(df, 0)&0x7e000000; - if (DFISINF(df)) { - memset(bcdzero, 0, DECPMAX); - return decFloatFromBCD(df, exp, bcdzero, sig); - } - } - else exp=GETEXPUN(df); - return decFloatFromBCD(df, exp, bcdar, sig); - } /* decFloatSetCoefficient */ - -/* ------------------------------------------------------------------ */ -/* decFloatSetExponent -- set exponent or special value */ -/* */ -/* df is the target decFloat (and source of coefficient/payload) */ -/* set is the context for reporting status */ -/* exp is the unbiased exponent, q, or a special value in the form */ -/* returned by decFloatGetExponent */ -/* returns df, which will be canonical */ -/* */ -/* No error is possible, but Overflow or Underflow might occur. */ -/* ------------------------------------------------------------------ */ -decFloat * decFloatSetExponent(decFloat *df, decContext *set, Int exp) { - uByte bcdcopy[DECPMAX]; /* for coefficient */ - bcdnum num; /* work */ - num.exponent=exp; - num.sign=decFloatGetCoefficient(df, bcdcopy); /* extract coefficient */ - if (DFISSPECIAL(df)) { /* MSD or more needs correcting */ - if (DFISINF(df)) memset(bcdcopy, 0, DECPMAX); - bcdcopy[0]=0; - } - num.msd=bcdcopy; - num.lsd=bcdcopy+DECPMAX-1; - return decFinalize(df, &num, set); - } /* decFloatSetExponent */ - -/* ------------------------------------------------------------------ */ -/* decFloatRadix -- returns the base (10) */ -/* */ -/* df is any decFloat of this format */ -/* ------------------------------------------------------------------ */ -uInt decFloatRadix(const decFloat *df) { - if (df) return 10; /* to placate compiler */ - return 10; - } /* decFloatRadix */ - -#if (DECCHECK || DECTRACE) -/* ------------------------------------------------------------------ */ -/* decFloatShow -- printf a decFloat in hexadecimal and decimal */ -/* df is the decFloat to show */ -/* tag is a tag string displayed with the number */ -/* */ -/* This is a debug aid; the precise format of the string may change. */ -/* ------------------------------------------------------------------ */ -void decFloatShow(const decFloat *df, const char *tag) { - char hexbuf[DECBYTES*2+DECBYTES/4+1]; /* NB blank after every fourth */ - char buff[DECSTRING]; /* for value in decimal */ - Int i, j=0; - - for (i=0; i<DECBYTES; i++) { - #if DECLITEND - sprintf(&hexbuf[j], "%02x", df->bytes[DECBYTES-1-i]); - #else - sprintf(&hexbuf[j], "%02x", df->bytes[i]); - #endif - j+=2; - /* the next line adds blank (and terminator) after final pair, too */ - if ((i+1)%4==0) {strcpy(&hexbuf[j], " "); j++;} - } - decFloatToString(df, buff); - printf(">%s> %s [big-endian] %s\n", tag, hexbuf, buff); - return; - } /* decFloatShow */ -#endif - -/* ------------------------------------------------------------------ */ -/* decFloatToBCD -- get sign, exponent, and BCD8 from a decFloat */ -/* */ -/* df is the source decFloat */ -/* exp will be set to the unbiased exponent, q, or to a special */ -/* value in the form returned by decFloatGetExponent */ -/* bcdar is where DECPMAX bytes will be written, one BCD digit in */ -/* each byte (BCD8 encoding); if df is a NaN the first byte will */ -/* be zero, and if it is infinite they will all be zero */ -/* returns the sign of the coefficient (DECFLOAT_Sign if negative, */ -/* 0 otherwise) */ -/* */ -/* No error is possible, and no status will be set. */ -/* ------------------------------------------------------------------ */ -Int decFloatToBCD(const decFloat *df, Int *exp, uByte *bcdar) { - if (DFISINF(df)) { - memset(bcdar, 0, DECPMAX); - *exp=DFWORD(df, 0)&0x7e000000; - } - else { - GETCOEFF(df, bcdar); /* use macro */ - if (DFISNAN(df)) { - bcdar[0]=0; /* MSD needs correcting */ - *exp=DFWORD(df, 0)&0x7e000000; - } - else { /* finite */ - *exp=GETEXPUN(df); - } - } - return DFISSIGNED(df); - } /* decFloatToBCD */ - -/* ------------------------------------------------------------------ */ -/* decFloatToEngString -- conversion to numeric string, engineering */ -/* */ -/* df is the decFloat format number to convert */ -/* string is the string where the result will be laid out */ -/* */ -/* string must be at least DECPMAX+9 characters (the worst case is */ -/* "-0.00000nnn...nnn\0", which is as long as the exponent form when */ -/* DECEMAXD<=4); this condition is asserted above */ -/* */ -/* No error is possible, and no status will be set */ -/* ------------------------------------------------------------------ */ -char * decFloatToEngString(const decFloat *df, char *string){ - uInt msd; /* coefficient MSD */ - Int exp; /* exponent top two bits or full */ - uInt comb; /* combination field */ - char *cstart; /* coefficient start */ - char *c; /* output pointer in string */ - char *s, *t; /* .. (source, target) */ - Int pre, e; /* work */ - const uByte *u; /* .. */ - - /* Source words; macro handles endianness */ - uInt sourhi=DFWORD(df, 0); /* word with sign */ - #if DECPMAX==16 - uInt sourlo=DFWORD(df, 1); - #elif DECPMAX==34 - uInt sourmh=DFWORD(df, 1); - uInt sourml=DFWORD(df, 2); - uInt sourlo=DFWORD(df, 3); - #endif - - c=string; /* where result will go */ - if (((Int)sourhi)<0) *c++='-'; /* handle sign */ - comb=sourhi>>26; /* sign+combination field */ - msd=DECCOMBMSD[comb]; /* decode the combination field */ - exp=DECCOMBEXP[comb]; /* .. */ - - if (EXPISSPECIAL(exp)) { /* special */ - if (exp==DECFLOAT_Inf) { /* infinity */ - strcpy(c, "Inf"); - strcpy(c+3, "inity"); - return string; /* easy */ - } - if (sourhi&0x02000000) *c++='s'; /* sNaN */ - strcpy(c, "NaN"); /* complete word */ - c+=3; /* step past */ - /* quick exit if the payload is zero */ - #if DECPMAX==7 - if ((sourhi&0x000fffff)==0) return string; - #elif DECPMAX==16 - if (sourlo==0 && (sourhi&0x0003ffff)==0) return string; - #elif DECPMAX==34 - if (sourlo==0 && sourml==0 && sourmh==0 - && (sourhi&0x00003fff)==0) return string; - #endif - /* otherwise drop through to add integer; set correct exp etc. */ - exp=0; msd=0; /* setup for following code */ - } - else { /* complete exponent; top two bits are in place */ - exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */ - } - - /* convert the digits of the significand to characters */ - cstart=c; /* save start of coefficient */ - if (msd) *c++=(char)('0'+(char)msd); /* non-zero most significant digit */ - - /* Decode the declets. After extracting each declet, it is */ - /* decoded to a 4-uByte sequence by table lookup; the four uBytes */ - /* are the three encoded BCD8 digits followed by a 1-byte length */ - /* (significant digits, except that 000 has length 0). This allows */ - /* us to left-align the first declet with non-zero content, then */ - /* the remaining ones are full 3-char length. Fixed-length copies */ - /* are used because variable-length memcpy causes a subroutine call */ - /* in at least two compilers. (The copies are length 4 for speed */ - /* and are safe because the last item in the array is of length */ - /* three and has the length byte following.) */ - #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \ - if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;} \ - else if (*(u+3)) { \ - UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; c+=*(u+3);} - - #if DECPMAX==7 - dpd2char(sourhi>>10); /* declet 1 */ - dpd2char(sourhi); /* declet 2 */ - - #elif DECPMAX==16 - dpd2char(sourhi>>8); /* declet 1 */ - dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */ - dpd2char(sourlo>>20); /* declet 3 */ - dpd2char(sourlo>>10); /* declet 4 */ - dpd2char(sourlo); /* declet 5 */ - - #elif DECPMAX==34 - dpd2char(sourhi>>4); /* declet 1 */ - dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */ - dpd2char(sourmh>>16); /* declet 3 */ - dpd2char(sourmh>>6); /* declet 4 */ - dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */ - dpd2char(sourml>>18); /* declet 6 */ - dpd2char(sourml>>8); /* declet 7 */ - dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */ - dpd2char(sourlo>>20); /* declet 9 */ - dpd2char(sourlo>>10); /* declet 10 */ - dpd2char(sourlo); /* declet 11 */ - #endif - - if (c==cstart) *c++='0'; /* all zeros, empty -- make "0" */ - - if (exp==0) { /* integer or NaN case -- easy */ - *c='\0'; /* terminate */ - return string; - } - /* non-0 exponent */ - - e=0; /* assume no E */ - pre=(Int)(c-cstart)+exp; /* length+exp [c->LSD+1] */ - /* [here, pre-exp is the digits count (==1 for zero)] */ - - if (exp>0 || pre<-5) { /* need exponential form */ - e=pre-1; /* calculate E value */ - pre=1; /* assume one digit before '.' */ - if (e!=0) { /* engineering: may need to adjust */ - Int adj; /* adjustment */ - /* The C remainder operator is undefined for negative numbers, so */ - /* a positive remainder calculation must be used here */ - if (e<0) { - adj=(-e)%3; - if (adj!=0) adj=3-adj; - } - else { /* e>0 */ - adj=e%3; - } - e=e-adj; - /* if dealing with zero still produce an exponent which is a */ - /* multiple of three, as expected, but there will only be the */ - /* one zero before the E, still. Otherwise note the padding. */ - if (!DFISZERO(df)) pre+=adj; - else { /* is zero */ - if (adj!=0) { /* 0.00Esnn needed */ - e=e+3; - pre=-(2-adj); - } - } /* zero */ - } /* engineering adjustment */ - } /* exponential form */ - /* printf("e=%ld pre=%ld exp=%ld\n", (LI)e, (LI)pre, (LI)exp); */ - - /* modify the coefficient, adding 0s, '.', and E+nn as needed */ - if (pre>0) { /* ddd.ddd (plain), perhaps with E */ - /* or dd00 padding for engineering */ - char *dotat=cstart+pre; - if (dotat<c) { /* if embedded dot needed... */ - /* move by fours; there must be space for junk at the end */ - /* because there is still space for exponent */ - s=dotat+ROUNDDOWN4(c-dotat); /* source */ - t=s+1; /* target */ - /* open the gap */ - for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s); - *dotat='.'; - c++; /* length increased by one */ - } /* need dot? */ - else for (; c<dotat; c++) *c='0'; /* pad for engineering */ - } /* pre>0 */ - else { - /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (may have - E, but only for 0.00E+3 kind of case -- with plenty of spare - space in this case */ - pre=-pre+2; /* gap width, including "0." */ - t=cstart+ROUNDDOWN4(c-cstart)+pre; /* preferred first target point */ - /* backoff if too far to the right */ - if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */ - /* now shift the entire coefficient to the right, being careful not */ - /* to access to the left of string */ - for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(s); - /* for Quads and Singles there may be a character or two left... */ - s+=3; /* where next would come from */ - for(; s>=cstart; s--, t--) *(t+3)=*(s); - /* now have fill 0. through 0.00000; use overlaps to avoid tests */ - if (pre>=4) { - UINTAT(cstart+pre-4)=UINTAT("0000"); - UINTAT(cstart)=UINTAT("0.00"); - } - else { /* 2 or 3 */ - *(cstart+pre-1)='0'; - USHORTAT(cstart)=USHORTAT("0."); - } - c+=pre; /* to end */ - } - - /* finally add the E-part, if needed; it will never be 0, and has */ - /* a maximum length of 3 or 4 digits (asserted above) */ - if (e!=0) { - USHORTAT(c)=USHORTAT("E+"); /* starts with E, assume + */ - c++; - if (e<0) { - *c='-'; /* oops, need '-' */ - e=-e; /* uInt, please */ - } - c++; - /* Three-character exponents are easy; 4-character a little trickier */ - #if DECEMAXD<=3 - u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ - /* copy fixed 4 characters [is safe], starting at non-zero */ - /* and with character mask to convert BCD to char */ - UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; - c+=*(u+3); /* bump pointer appropriately */ - #elif DECEMAXD==4 - if (e<1000) { /* 3 (or fewer) digits case */ - u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ - UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */ - c+=*(u+3); /* bump pointer appropriately */ - } - else { /* 4-digits */ - Int thou=((e>>3)*1049)>>17; /* e/1000 */ - Int rem=e-(1000*thou); /* e%1000 */ - *c++=(char)('0'+(char)thou); /* the thousands digit */ - u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ - UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */ - c+=3; /* bump pointer, always 3 digits */ - } - #endif - } - *c='\0'; /* terminate */ - /*printf("res %s\n", string); */ - return string; - } /* decFloatToEngString */ - -/* ------------------------------------------------------------------ */ -/* decFloatToPacked -- convert decFloat to Packed decimal + exponent */ -/* */ -/* df is the source decFloat */ -/* exp will be set to the unbiased exponent, q, or to a special */ -/* value in the form returned by decFloatGetExponent */ -/* packed is where DECPMAX nibbles will be written with the sign as */ -/* final nibble (0x0c for +, 0x0d for -); a NaN has a first nibble */ -/* of zero, and an infinity is all zeros. decDouble and decQuad */ -/* have a additional leading zero nibble, leading to result */ -/* lengths of 4, 9, and 18 bytes. */ -/* returns the sign of the coefficient (DECFLOAT_Sign if negative, */ -/* 0 otherwise) */ -/* */ -/* No error is possible, and no status will be set. */ -/* ------------------------------------------------------------------ */ -Int decFloatToPacked(const decFloat *df, Int *exp, uByte *packed) { - uByte bcdar[DECPMAX+2]; /* work buffer */ - uByte *ip=bcdar, *op=packed; /* work pointers */ - if (DFISINF(df)) { - memset(bcdar, 0, DECPMAX+2); - *exp=DECFLOAT_Inf; - } - else { - GETCOEFF(df, bcdar+1); /* use macro */ - if (DFISNAN(df)) { - bcdar[1]=0; /* MSD needs clearing */ - *exp=DFWORD(df, 0)&0x7e000000; - } - else { /* finite */ - *exp=GETEXPUN(df); - } - } - /* now pack; coefficient currently at bcdar+1 */ - #if SINGLE - ip++; /* ignore first byte */ - #else - *ip=0; /* need leading zero */ - #endif - /* set final byte to Packed BCD sign value */ - bcdar[DECPMAX+1]=(DFISSIGNED(df) ? DECPMINUS : DECPPLUS); - /* pack an even number of bytes... */ - for (; op<packed+((DECPMAX+2)/2); op++, ip+=2) { - *op=(uByte)((*ip<<4)+*(ip+1)); - } - return (bcdar[DECPMAX+1]==DECPMINUS ? DECFLOAT_Sign : 0); - } /* decFloatToPacked */ - -/* ------------------------------------------------------------------ */ -/* decFloatToString -- conversion to numeric string */ -/* */ -/* df is the decFloat format number to convert */ -/* string is the string where the result will be laid out */ -/* */ -/* string must be at least DECPMAX+9 characters (the worst case is */ -/* "-0.00000nnn...nnn\0", which is as long as the exponent form when */ -/* DECEMAXD<=4); this condition is asserted above */ -/* */ -/* No error is possible, and no status will be set */ -/* ------------------------------------------------------------------ */ -char * decFloatToString(const decFloat *df, char *string){ - uInt msd; /* coefficient MSD */ - Int exp; /* exponent top two bits or full */ - uInt comb; /* combination field */ - char *cstart; /* coefficient start */ - char *c; /* output pointer in string */ - char *s, *t; /* .. (source, target) */ - Int pre, e; /* work */ - const uByte *u; /* .. */ - - /* Source words; macro handles endianness */ - uInt sourhi=DFWORD(df, 0); /* word with sign */ - #if DECPMAX==16 - uInt sourlo=DFWORD(df, 1); - #elif DECPMAX==34 - uInt sourmh=DFWORD(df, 1); - uInt sourml=DFWORD(df, 2); - uInt sourlo=DFWORD(df, 3); - #endif - - c=string; /* where result will go */ - if (((Int)sourhi)<0) *c++='-'; /* handle sign */ - comb=sourhi>>26; /* sign+combination field */ - msd=DECCOMBMSD[comb]; /* decode the combination field */ - exp=DECCOMBEXP[comb]; /* .. */ - - if (EXPISSPECIAL(exp)) { /* special */ - if (exp==DECFLOAT_Inf) { /* infinity */ - strcpy(c, "Infinity"); - return string; /* easy */ - } - if (sourhi&0x02000000) *c++='s'; /* sNaN */ - strcpy(c, "NaN"); /* complete word */ - c+=3; /* step past */ - /* quick exit if the payload is zero */ - #if DECPMAX==7 - if ((sourhi&0x000fffff)==0) return string; - #elif DECPMAX==16 - if (sourlo==0 && (sourhi&0x0003ffff)==0) return string; - #elif DECPMAX==34 - if (sourlo==0 && sourml==0 && sourmh==0 - && (sourhi&0x00003fff)==0) return string; - #endif - /* otherwise drop through to add integer; set correct exp etc. */ - exp=0; msd=0; /* setup for following code */ - } - else { /* complete exponent; top two bits are in place */ - exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */ - } - - /* convert the digits of the significand to characters */ - cstart=c; /* save start of coefficient */ - if (msd) *c++=(char)('0'+(char)msd); /* non-zero most significant digit */ - - /* Decode the declets. After extracting each declet, it is */ - /* decoded to a 4-uByte sequence by table lookup; the four uBytes */ - /* are the three encoded BCD8 digits followed by a 1-byte length */ - /* (significant digits, except that 000 has length 0). This allows */ - /* us to left-align the first declet with non-zero content, then */ - /* the remaining ones are full 3-char length. Fixed-length copies */ - /* are used because variable-length memcpy causes a subroutine call */ - /* in at least two compilers. (The copies are length 4 for speed */ - /* and are safe because the last item in the array is of length */ - /* three and has the length byte following.) */ - #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \ - if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;} \ - else if (*(u+3)) { \ - UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; c+=*(u+3);} - - #if DECPMAX==7 - dpd2char(sourhi>>10); /* declet 1 */ - dpd2char(sourhi); /* declet 2 */ - - #elif DECPMAX==16 - dpd2char(sourhi>>8); /* declet 1 */ - dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */ - dpd2char(sourlo>>20); /* declet 3 */ - dpd2char(sourlo>>10); /* declet 4 */ - dpd2char(sourlo); /* declet 5 */ - - #elif DECPMAX==34 - dpd2char(sourhi>>4); /* declet 1 */ - dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */ - dpd2char(sourmh>>16); /* declet 3 */ - dpd2char(sourmh>>6); /* declet 4 */ - dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */ - dpd2char(sourml>>18); /* declet 6 */ - dpd2char(sourml>>8); /* declet 7 */ - dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */ - dpd2char(sourlo>>20); /* declet 9 */ - dpd2char(sourlo>>10); /* declet 10 */ - dpd2char(sourlo); /* declet 11 */ - #endif - - if (c==cstart) *c++='0'; /* all zeros, empty -- make "0" */ - - /*[This fast path is valid but adds 3-5 cycles to worst case length] */ - /*if (exp==0) { // integer or NaN case -- easy */ - /* *c='\0'; // terminate */ - /* return string; */ - /* } */ - - e=0; /* assume no E */ - pre=(Int)(c-cstart)+exp; /* length+exp [c->LSD+1] */ - /* [here, pre-exp is the digits count (==1 for zero)] */ - - if (exp>0 || pre<-5) { /* need exponential form */ - e=pre-1; /* calculate E value */ - pre=1; /* assume one digit before '.' */ - } /* exponential form */ - - /* modify the coefficient, adding 0s, '.', and E+nn as needed */ - if (pre>0) { /* ddd.ddd (plain), perhaps with E */ - char *dotat=cstart+pre; - if (dotat<c) { /* if embedded dot needed... */ - /* move by fours; there must be space for junk at the end */ - /* because there is still space for exponent */ - s=dotat+ROUNDDOWN4(c-dotat); /* source */ - t=s+1; /* target */ - /* open the gap */ - for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s); - *dotat='.'; - c++; /* length increased by one */ - } /* need dot? */ - - /* finally add the E-part, if needed; it will never be 0, and has */ - /* a maximum length of 3 or 4 digits (asserted above) */ - if (e!=0) { - USHORTAT(c)=USHORTAT("E+"); /* starts with E, assume + */ - c++; - if (e<0) { - *c='-'; /* oops, need '-' */ - e=-e; /* uInt, please */ - } - c++; - /* Three-character exponents are easy; 4-character a little trickier */ - #if DECEMAXD<=3 - u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ - /* copy fixed 4 characters [is safe], starting at non-zero */ - /* and with character mask to convert BCD to char */ - UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; - c+=*(u+3); /* bump pointer appropriately */ - #elif DECEMAXD==4 - if (e<1000) { /* 3 (or fewer) digits case */ - u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ - UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */ - c+=*(u+3); /* bump pointer appropriately */ - } - else { /* 4-digits */ - Int thou=((e>>3)*1049)>>17; /* e/1000 */ - Int rem=e-(1000*thou); /* e%1000 */ - *c++=(char)('0'+(char)thou); /* the thousands digit */ - u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ - UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */ - c+=3; /* bump pointer, always 3 digits */ - } - #endif - } - *c='\0'; /* add terminator */ - /*printf("res %s\n", string); */ - return string; - } /* pre>0 */ - - /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */ - /* Surprisingly, this is close to being the worst-case path, so the */ - /* shift is done by fours; this is a little tricky because the */ - /* rightmost character to be written must not be beyond where the */ - /* rightmost terminator could be -- so backoff to not touch */ - /* terminator position if need be (this can make exact alignments */ - /* for full Doubles, but in some cases needs care not to access too */ - /* far to the left) */ - - pre=-pre+2; /* gap width, including "0." */ - t=cstart+ROUNDDOWN4(c-cstart)+pre; /* preferred first target point */ - /* backoff if too far to the right */ - if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */ - /* now shift the entire coefficient to the right, being careful not */ - /* to access to the left of string */ - for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(s); - /* for Quads and Singles there may be a character or two left... */ - s+=3; /* where next would come from */ - for(; s>=cstart; s--, t--) *(t+3)=*(s); - /* now have fill 0. through 0.00000; use overlaps to avoid tests */ - if (pre>=4) { - UINTAT(cstart+pre-4)=UINTAT("0000"); - UINTAT(cstart)=UINTAT("0.00"); - } - else { /* 2 or 3 */ - *(cstart+pre-1)='0'; - USHORTAT(cstart)=USHORTAT("0."); - } - *(c+pre)='\0'; /* terminate */ - return string; - } /* decFloatToString */ - -/* ------------------------------------------------------------------ */ -/* decFloatToWider -- conversion to next-wider format */ -/* */ -/* source is the decFloat format number which gets the result of */ -/* the conversion */ -/* wider is the decFloatWider format number which will be narrowed */ -/* returns wider */ -/* */ -/* Widening is always exact; no status is set (sNaNs are copied and */ -/* do not signal). The result will be canonical if the source is, */ -/* and may or may not be if the source is not. */ -/* ------------------------------------------------------------------ */ -/* widening is not possible for decQuad format numbers; simply omit */ -#if !QUAD -decFloatWider * decFloatToWider(const decFloat *source, decFloatWider *wider) { - uInt msd; - - /* Construct and copy the sign word */ - if (DFISSPECIAL(source)) { - /* copy sign, combination, and first bit of exponent (sNaN selector) */ - DFWWORD(wider, 0)=DFWORD(source, 0)&0xfe000000; - msd=0; - } - else { /* is finite number */ - uInt exp=GETEXPUN(source)+DECWBIAS; /* get unbiased exponent and rebias */ - uInt code=(exp>>DECWECONL)<<29; /* set two bits of exp [msd=0] */ - code|=(exp<<(32-6-DECWECONL)) & 0x03ffffff; /* add exponent continuation */ - code|=DFWORD(source, 0)&0x80000000; /* add sign */ - DFWWORD(wider, 0)=code; /* .. and place top word in wider */ - msd=GETMSD(source); /* get source coefficient MSD [0-9] */ - } - /* Copy the coefficient and clear any 'unused' words to left */ - #if SINGLE - DFWWORD(wider, 1)=(DFWORD(source, 0)&0x000fffff)|(msd<<20); - #elif DOUBLE - DFWWORD(wider, 2)=(DFWORD(source, 0)&0x0003ffff)|(msd<<18); - DFWWORD(wider, 3)=DFWORD(source, 1); - DFWWORD(wider, 1)=0; - #endif - return wider; - } /* decFloatToWider */ -#endif - -/* ------------------------------------------------------------------ */ -/* decFloatVersion -- return package version string */ -/* */ -/* returns a constant string describing this package */ -/* ------------------------------------------------------------------ */ -const char *decFloatVersion(void) { - return DECVERSION; - } /* decFloatVersion */ - -/* ------------------------------------------------------------------ */ -/* decFloatZero -- set to canonical (integer) zero */ -/* */ -/* df is the decFloat format number to integer +0 (q=0, c=+0) */ -/* returns df */ -/* */ -/* No error is possible, and no status can be set. */ -/* ------------------------------------------------------------------ */ -decFloat * decFloatZero(decFloat *df){ - DFWORD(df, 0)=ZEROWORD; /* set appropriate top word */ - #if DOUBLE || QUAD - DFWORD(df, 1)=0; - #if QUAD - DFWORD(df, 2)=0; - DFWORD(df, 3)=0; - #endif - #endif - /* decFloatShow(df, "zero"); */ - return df; - } /* decFloatZero */ - -/* ------------------------------------------------------------------ */ -/* Private generic function (not format-specific) for development use */ -/* ------------------------------------------------------------------ */ -/* This is included once only, for all to use */ -#if QUAD && (DECCHECK || DECTRACE) - /* ---------------------------------------------------------------- */ - /* decShowNum -- display bcd8 number in debug form */ - /* */ - /* num is the bcdnum to display */ - /* tag is a string to label the display */ - /* ---------------------------------------------------------------- */ - void decShowNum(const bcdnum *num, const char *tag) { - const char *csign="+"; /* sign character */ - uByte *ub; /* work */ - if (num->sign==DECFLOAT_Sign) csign="-"; - - printf(">%s> ", tag); - if (num->exponent==DECFLOAT_Inf) printf("%sInfinity", csign); - else if (num->exponent==DECFLOAT_qNaN) printf("%sqNaN", csign); - else if (num->exponent==DECFLOAT_sNaN) printf("%ssNaN", csign); - else { /* finite */ - char qbuf[10]; /* for right-aligned q */ - char *c; /* work */ - const uByte *u; /* .. */ - Int e=num->exponent; /* .. exponent */ - strcpy(qbuf, "q="); - c=&qbuf[2]; /* where exponent will go */ - /* lay out the exponent */ - if (e<0) { - *c++='-'; /* add '-' */ - e=-e; /* uInt, please */ - } - #if DECEMAXD>4 - #error Exponent form is too long for ShowNum to lay out - #endif - if (e==0) *c++='0'; /* 0-length case */ - else if (e<1000) { /* 3 (or fewer) digits case */ - u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ - UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */ - c+=*(u+3); /* bump pointer appropriately */ - } - else { /* 4-digits */ - Int thou=((e>>3)*1049)>>17; /* e/1000 */ - Int rem=e-(1000*thou); /* e%1000 */ - *c++=(char)('0'+(char)thou); /* the thousands digit */ - u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ - UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */ - c+=3; /* bump pointer, always 3 digits */ - } - *c='\0'; /* add terminator */ - printf("%7s c=%s", qbuf, csign); - } - - if (!EXPISSPECIAL(num->exponent) || num->msd!=num->lsd || *num->lsd!=0) { - for (ub=num->msd; ub<=num->lsd; ub++) { /* coefficient... */ - printf("%1x", *ub); - if ((num->lsd-ub)%3==0 && ub!=num->lsd) printf(" "); /* 4-space */ - } - } - printf("\n"); - } /* decShowNum */ -#endif |