Lines Matching +full:left +full:- +full:shift
1 /* Decimal 64-bit format module for the decNumber C Library.
29 02110-1301, USA. */
31 /* ------------------------------------------------------------------ */
32 /* Decimal 64-bit format module */
33 /* ------------------------------------------------------------------ */
41 /* ------------------------------------------------------------------ */
72 /* ------------------------------------------------------------------ */
73 /* decimal64FromNumber -- convert decNumber to decimal64 */
88 /* ------------------------------------------------------------------ */
97 uInt targar[2]={0, 0}; /* target 64-bit */ in decimal64FromNumber()
106 ae=dn->exponent+dn->digits-1; /* [0 if special] */ in decimal64FromNumber()
107 if (dn->digits>DECIMAL64_Pmax /* too many digits */ in decimal64FromNumber()
111 dc.round=set->round; /* use supplied rounding */ in decimal64FromNumber()
113 /* [this changes -0 to 0, so enforce the sign...] */ in decimal64FromNumber()
114 dw.bits|=dn->bits&DECNEG; in decimal64FromNumber()
119 if (dn->bits&DECSPECIAL) { /* a special value */ in decimal64FromNumber()
120 if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24; in decimal64FromNumber()
122 if ((*dn->lsu!=0 || dn->digits>1) /* non-zero coefficient */ in decimal64FromNumber()
123 && (dn->digits<DECIMAL64_Pmax)) { /* coefficient fits */ in decimal64FromNumber()
126 if (dn->bits&DECNAN) targhi|=DECIMAL_NaN<<24; in decimal64FromNumber()
134 if (dn->exponent<-DECIMAL64_Bias) { in decimal64FromNumber()
139 exp=dn->exponent+DECIMAL64_Bias; /* bias exponent */ in decimal64FromNumber()
147 else { /* non-zero finite number */ in decimal64FromNumber()
152 exp=(uInt)(dn->exponent+DECIMAL64_Bias); /* bias exponent */ in decimal64FromNumber()
153 if (exp>DECIMAL64_Ehigh) { /* fold-down case */ in decimal64FromNumber()
154 pad=exp-DECIMAL64_Ehigh; in decimal64FromNumber()
163 Int d=dn->digits; in decimal64FromNumber()
164 for (i=0; d>0; i++, d-=3) dpd[i]=BIN2DPD[dn->lsu[i]]; in decimal64FromNumber()
168 if (dn->digits>6) { in decimal64FromNumber()
190 if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */ in decimal64FromNumber()
193 pu=(uInt *)d64->bytes; /* overlay */ in decimal64FromNumber()
208 /* ------------------------------------------------------------------ */
209 /* decimal64ToNumber -- convert decimal64 to decNumber */
213 /* ------------------------------------------------------------------ */
220 uInt sourar[2]; /* source 64-bit */ in decimal64ToNumber()
225 pu=(const uInt *)d64->bytes; /* overlay */ in decimal64ToNumber()
238 if (sourhi&0x80000000) dn->bits=DECNEG; /* set sign if negative */ in decimal64ToNumber()
245 dn->bits|=DECINF; in decimal64ToNumber()
248 else if (sourhi&0x02000000) dn->bits|=DECSNAN; in decimal64ToNumber()
249 else dn->bits|=DECNAN; in decimal64ToNumber()
253 dn->exponent=(exp<<8)+((sourhi>>18)&0xff)-DECIMAL64_Bias; /* unbiased */ in decimal64ToNumber()
258 if (msd) { /* non-zero msd */ in decimal64ToNumber()
280 /* ------------------------------------------------------------------ */
281 /* to-scientific-string -- conversion to numeric string */
282 /* to-engineering-string -- conversion to numeric string */
293 /* ------------------------------------------------------------------ */
313 uInt sourar[2]; /* source 64-bit */ in decimal64ToString()
318 pu=(const uInt *)d64->bytes; /* overlay */ in decimal64ToString()
329 if (((Int)sourhi)<0) *c++='-'; /* handle sign */ in decimal64ToString()
348 else exp=(exp<<8)+((sourhi>>18)&0xff)-DECIMAL64_Bias; in decimal64ToString()
352 if (msd) *c++='0'+(char)msd; /* non-zero most significant digit */ in decimal64ToString()
355 /* decoded to binary and then to a 4-char sequence by table lookup; */ in decimal64ToString()
356 /* the 4-chars are a 1-char length (significant digits, except 000 */ in decimal64ToString()
357 /* has length 0). This allows us to left-align the first declet */ in decimal64ToString()
358 /* with non-zero content, then remaining ones are full 3-char */ in decimal64ToString()
359 /* length. We use fixed-length memcpys because variable-length */ in decimal64ToString()
364 else if (*u) {memcpy(c, u+4-*u, 4); c+=*u;} in decimal64ToString()
377 if (c==cstart) *c++='0'; /* all zeros -- make 0 */ in decimal64ToString()
379 if (exp==0) { /* integer or NaN case -- easy */ in decimal64ToString()
384 /* non-0 exponent */ in decimal64ToString()
386 pre=c-cstart+exp; in decimal64ToString()
387 /* [here, pre-exp is the digits count (==1 for zero)] */ in decimal64ToString()
388 if (exp>0 || pre<-5) { /* need exponential form */ in decimal64ToString()
389 e=pre-1; /* calculate E value */ in decimal64ToString()
394 s=c-1; /* source (LSD) */ in decimal64ToString()
399 for (; s>=dotat; s--, t--) *t=*s; /* open the gap; leave t at gap */ in decimal64ToString()
404 /* finally add the E-part, if needed; it will never be 0, and has */ in decimal64ToString()
410 *(c-1)='-'; /* oops, need '-' */ in decimal64ToString()
411 e=-e; /* uInt, please */ in decimal64ToString()
413 u=&BIN2CHAR[e*4]; /* -> length byte */ in decimal64ToString()
414 memcpy(c, u+4-*u, 4); /* copy fixed 4 characters [is safe] */ in decimal64ToString()
422 /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */ in decimal64ToString()
423 t=c+1-pre; in decimal64ToString()
425 for (; s>=cstart; s--, t--) *t=*s; /* shift whole coefficient right */ in decimal64ToString()
434 /* ------------------------------------------------------------------ */
435 /* to-number -- conversion from numeric string */
448 /* ------------------------------------------------------------------ */
455 dc.round=set->round; /* use supplied rounding */ in decimal64FromString()
466 /* ------------------------------------------------------------------ */
467 /* decimal64IsCanonical -- test whether encoding is canonical */
471 /* ------------------------------------------------------------------ */
482 /* ------------------------------------------------------------------ */
483 /* decimal64Canonical -- copy an encoding, ensuring it is canonical */
488 /* ------------------------------------------------------------------ */
501 and the decimal64 is in network byte order (big-endian) */
503 #define decimal64Sign(d) ((unsigned)(d)->bytes[0]>>7)
506 #define decimal64Comb(d) (((d)->bytes[0] & 0x7c)>>2)
509 #define decimal64ExpCon(d) ((((d)->bytes[0] & 0x03)<<6) \
510 | ((unsigned)(d)->bytes[1]>>2))
514 (d)->bytes[0]|=((unsigned)(b)<<7);}
520 (d)->bytes[0]|=(uint8_t)((e)>>6); \
521 (d)->bytes[1]|=(uint8_t)(((e)&0x3F)<<2);}
523 /* ------------------------------------------------------------------ */
524 /* decimal64Show -- display a decimal64 in hexadecimal [debug aid] */
525 /* d64 -- the number to show */
526 /* ------------------------------------------------------------------ */
534 sprintf(&buf[j], "%02x", d64->bytes[7-i]); in decimal64Show()
537 d64->bytes[7]>>7, (d64->bytes[7]>>2)&0x1f, in decimal64Show()
538 ((d64->bytes[7]&0x3)<<6)| (d64->bytes[6]>>2)); in decimal64Show()
540 else { /* big-endian */ in decimal64Show()
542 sprintf(&buf[j], "%02x", d64->bytes[i]); in decimal64Show()
567 #define DECMAXUNITS ((DECMAX754+DECDPUN-1)/DECDPUN)
569 /* ------------------------------------------------------------------ */
572 /* COMBEXP - 2-bit most-significant-bits of exponent */
574 /* COMBMSD - 4-bit most-significant-digit */
577 /* Both are indexed by the 5-bit combination field (0-31) */
578 /* ------------------------------------------------------------------ */
588 /* ------------------------------------------------------------------ */
589 /* decDigitsToDPD -- pack coefficient into DPD form */
592 /* targ is 1, 2, or 4-element uInt array, which the caller must */
594 /* shift is the number of 0 digits to add on the right (normally 0) */
603 /* are filled from left to right (that is, the uInt at offset 0 will */
604 /* end up with the least-significant digits). */
606 /* shift is used for 'fold-down' padding. */
609 /* ------------------------------------------------------------------ */
611 /* Constant multipliers for divide-by-power-of five using reciprocal */
612 /* multiply, after removing powers of 2 by shifting, and final shift */
615 /* QUOT10 -- macro to return the quotient of unit u divided by 10**n */
618 void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) { in decDigitsToDPD() argument
620 Int digits=dn->digits; /* digit countdown */ in decDigitsToDPD()
622 uInt bin; /* binary value 0-999 */ in decDigitsToDPD()
623 uInt *uout=targ; /* -> current output uInt */ in decDigitsToDPD()
624 uInt uoff=0; /* -> current output offset [from right] */ in decDigitsToDPD()
625 const Unit *inu=dn->lsu; /* -> current input unit */ in decDigitsToDPD()
631 if (shift!=0) { /* shift towards most significant required */ in decDigitsToDPD()
632 /* shift the units array to the left by pad digits and copy */ in decDigitsToDPD()
639 source=dn->lsu+D2U(digits)-1; /* where msu comes from */ in decDigitsToDPD()
640 target=uar+D2U(digits)-1+D2U(shift);/* where upper part of first cut goes */ in decDigitsToDPD()
641 cut=DECDPUN-MSUDIGITS(shift); /* where to slice */ in decDigitsToDPD()
642 if (cut==0) { /* unit-boundary case */ in decDigitsToDPD()
643 for (; source>=dn->lsu; source--, target--) *target=*source; in decDigitsToDPD()
646 first=uar+D2U(digits+shift)-1; /* where msu will end up */ in decDigitsToDPD()
647 for (; source>=dn->lsu; source--, target--) { in decDigitsToDPD()
651 uInt rem=*source-quot*DECPOWERS[cut]; in decDigitsToDPD()
658 next=rem*DECPOWERS[DECDPUN-cut]; /* save remainder for next Unit */ in decDigitsToDPD()
660 } /* shift-move */ in decDigitsToDPD()
662 for (; target>=uar; target--) { in decDigitsToDPD()
666 digits+=shift; /* add count (shift) of zeros added */ in decDigitsToDPD()
679 #if DECDPUN==3 /* fast path, 3-at-a-time */ in decDigitsToDPD()
681 digits-=3; /* [may go negative] */ in decDigitsToDPD()
684 #else /* must collect digit-by-digit */ in decDigitsToDPD()
686 Int j; /* digit-in-declet count */ in decDigitsToDPD()
690 dig=(Unit)(in-X10(temp)); in decDigitsToDPD()
699 digits--; in decDigitsToDPD()
714 uoff-=32; in decDigitsToDPD()
715 *uout|=dpd>>(10-uoff); /* collect top bits */ in decDigitsToDPD()
720 /* ------------------------------------------------------------------ */
721 /* decDigitsFromDPD -- unpack a format's coefficient */
723 /* dn is the target number, with 7, 16, or 34-digit space. */
724 /* sour is a 1, 2, or 4-element uInt array containing only declets */
725 /* declets is the number of (right-aligned) declets in sour to */
729 /* caller may pre-process leading zero declets. */
737 /* they are used from left to right (that is, the uInt at offset 0 */
738 /* provides the least-significant digits). */
740 /* dn->digits is set, but not the sign or exponent. */
742 /* ------------------------------------------------------------------ */
747 Unit *uout=dn->lsu; /* -> current output unit */ in decDigitsFromDPD()
749 const uInt *uin=sour; /* -> current input uInt */ in decDigitsFromDPD()
750 uInt uoff=0; /* -> current input offset [from right] */ in decDigitsFromDPD()
762 /* Expand the densely-packed integer, right to left */ in decDigitsFromDPD()
763 for (n=declets-1; n>=0; n--) { /* count down declets of 10 bits */ in decDigitsFromDPD()
768 uoff-=32; in decDigitsFromDPD()
769 dpd|=*uin<<(10-uoff); /* get waiting bits */ in decDigitsFromDPD()
776 *uout=DPD2BIN[dpd]; /* convert 10 bits to binary 0-999 */ in decDigitsFromDPD()
821 if (cut!=0) { /* some more left over */
823 if (out) last=uout; /* and note if non-zero */
828 /* inspect it to get the final digits count -- this is essentially */
830 dn->digits=(last-dn->lsu)*DECDPUN+1; /* floor of digits, plus */
834 dn->digits++; /* must be 2 at least */
836 if (*last<100) return; /* 10-99 */
837 dn->digits++; /* must be 3 at least */
839 if (*last<1000) return; /* 100-999 */
840 dn->digits++; /* must be 4 at least */
842 for (pow=&DECPOWERS[4]; *last>=*pow; pow++) dn->digits++;