Mercurial > hg > CbC > CbC_gcc
comparison libdecnumber/decCommon.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | 855418dad1a3 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
97 /* Private functions used here and possibly in decBasic.c, etc. */ | 97 /* Private functions used here and possibly in decBasic.c, etc. */ |
98 static decFloat * decFinalize(decFloat *, bcdnum *, decContext *); | 98 static decFloat * decFinalize(decFloat *, bcdnum *, decContext *); |
99 static Flag decBiStr(const char *, const char *, const char *); | 99 static Flag decBiStr(const char *, const char *, const char *); |
100 | 100 |
101 /* Macros and private tables; those which are not format-dependent */ | 101 /* Macros and private tables; those which are not format-dependent */ |
102 /* are only included if decQuad is being built. */ | 102 /* are only included if decQuad is being built. */ |
103 | 103 |
104 /* ------------------------------------------------------------------ */ | 104 /* ------------------------------------------------------------------ */ |
105 /* Combination field lookup tables (uInts to save measurable work) */ | 105 /* Combination field lookup tables (uInts to save measurable work) */ |
106 /* */ | 106 /* */ |
107 /* DECCOMBEXP - 2 most-significant-bits of exponent (00, 01, or */ | 107 /* DECCOMBEXP - 2 most-significant-bits of exponent (00, 01, or */ |
108 /* 10), shifted left for format, or DECFLOAT_Inf/NaN */ | 108 /* 10), shifted left for format, or DECFLOAT_Inf/NaN */ |
109 /* DECCOMBWEXP - The same, for the next-wider format (unless QUAD) */ | 109 /* DECCOMBWEXP - The same, for the next-wider format (unless QUAD) */ |
110 /* DECCOMBMSD - 4-bit most-significant-digit */ | 110 /* DECCOMBMSD - 4-bit most-significant-digit */ |
111 /* [0 if the index is a special (Infinity or NaN)] */ | 111 /* [0 if the index is a special (Infinity or NaN)] */ |
112 /* DECCOMBFROM - 5-bit combination field from EXP top bits and MSD */ | 112 /* DECCOMBFROM - 5-bit combination field from EXP top bits and MSD */ |
113 /* (placed in uInt so no shift is needed) */ | 113 /* (placed in uInt so no shift is needed) */ |
114 /* */ | 114 /* */ |
115 /* DECCOMBEXP, DECCOMBWEXP, and DECCOMBMSD are indexed by the sign */ | 115 /* DECCOMBEXP, DECCOMBWEXP, and DECCOMBMSD are indexed by the sign */ |
116 /* and 5-bit combination field (0-63, the second half of the table */ | 116 /* and 5-bit combination field (0-63, the second half of the table */ |
117 /* identical to the first half) */ | 117 /* identical to the first half) */ |
118 /* DECCOMBFROM is indexed by expTopTwoBits*16 + msd */ | 118 /* DECCOMBFROM is indexed by expTopTwoBits*16 + msd */ |
119 /* */ | 119 /* */ |
120 /* DECCOMBMSD and DECCOMBFROM are not format-dependent and so are */ | 120 /* DECCOMBMSD and DECCOMBFROM are not format-dependent and so are */ |
121 /* only included once, when QUAD is being built */ | 121 /* only included once, when QUAD is being built */ |
122 /* ------------------------------------------------------------------ */ | 122 /* ------------------------------------------------------------------ */ |
123 static const uInt DECCOMBEXP[64]={ | 123 static const uInt DECCOMBEXP[64]={ |
124 0, 0, 0, 0, 0, 0, 0, 0, | 124 0, 0, 0, 0, 0, 0, 0, 0, |
125 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, | 125 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, |
126 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, | 126 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, 1<<DECECONL, |
154 #endif | 154 #endif |
155 | 155 |
156 #if QUAD | 156 #if QUAD |
157 const uInt DECCOMBMSD[64]={ | 157 const uInt DECCOMBMSD[64]={ |
158 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, | 158 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, |
159 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 1, | 159 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0, |
160 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, | 160 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, |
161 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0}; | 161 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0}; |
162 | 162 |
163 const uInt DECCOMBFROM[48]={ | 163 const uInt DECCOMBFROM[48]={ |
164 0x00000000, 0x04000000, 0x08000000, 0x0C000000, 0x10000000, 0x14000000, | 164 0x00000000, 0x04000000, 0x08000000, 0x0C000000, 0x10000000, 0x14000000, |
216 /* [its values, including the coefficient, may be modified] */ | 216 /* [its values, including the coefficient, may be modified] */ |
217 /* set is the context to use */ | 217 /* set is the context to use */ |
218 /* returns df */ | 218 /* returns df */ |
219 /* */ | 219 /* */ |
220 /* The num descriptor may point to a bcd8 string of any length; this */ | 220 /* The num descriptor may point to a bcd8 string of any length; this */ |
221 /* string may have leading insignificant zeros. If it has more than */ | 221 /* string may have leading insignificant zeros. If it has more than */ |
222 /* DECPMAX digits then the final digit can be a round-for-reround */ | 222 /* DECPMAX digits then the final digit can be a round-for-reround */ |
223 /* digit (i.e., it may include a sticky bit residue). */ | 223 /* digit (i.e., it may include a sticky bit residue). */ |
224 /* */ | 224 /* */ |
225 /* The exponent (q) may be one of the codes for a special value and */ | 225 /* The exponent (q) may be one of the codes for a special value and */ |
226 /* can be up to 999999999 for conversion from string. */ | 226 /* can be up to 999999999 for conversion from string. */ |
241 | 241 |
242 static decFloat * decFinalize(decFloat *df, bcdnum *num, | 242 static decFloat * decFinalize(decFloat *df, bcdnum *num, |
243 decContext *set) { | 243 decContext *set) { |
244 uByte *ub; /* work */ | 244 uByte *ub; /* work */ |
245 uInt dpd; /* .. */ | 245 uInt dpd; /* .. */ |
246 uByte *umsd=num->msd; /* local copy */ | 246 uInt uiwork; /* for macros */ |
247 uByte *ulsd=num->lsd; /* .. */ | 247 uByte *umsd=num->msd; /* local copy */ |
248 uByte *ulsd=num->lsd; /* .. */ | |
248 uInt encode; /* encoding accumulator */ | 249 uInt encode; /* encoding accumulator */ |
249 Int length; /* coefficient length */ | 250 Int length; /* coefficient length */ |
250 | 251 |
251 #if DECCHECK | 252 #if DECCHECK |
252 Int clen=ulsd-umsd+1; | 253 Int clen=ulsd-umsd+1; |
268 /* A special will have an 'exponent' which is very positive and a */ | 269 /* A special will have an 'exponent' which is very positive and a */ |
269 /* coefficient < DECPMAX */ | 270 /* coefficient < DECPMAX */ |
270 length=(uInt)(ulsd-umsd+1); /* coefficient length */ | 271 length=(uInt)(ulsd-umsd+1); /* coefficient length */ |
271 | 272 |
272 if (!NUMISSPECIAL(num)) { | 273 if (!NUMISSPECIAL(num)) { |
273 Int drop; /* digits to be dropped */ | 274 Int drop; /* digits to be dropped */ |
274 /* skip leading insignificant zeros to calculate an exact length */ | 275 /* skip leading insignificant zeros to calculate an exact length */ |
275 /* [this is quite expensive] */ | 276 /* [this is quite expensive] */ |
276 if (*umsd==0) { | 277 if (*umsd==0) { |
277 for (; UINTAT(umsd)==0 && umsd+3<ulsd;) umsd+=4; | 278 for (; umsd+3<ulsd && UBTOUI(umsd)==0;) umsd+=4; |
278 for (; *umsd==0 && umsd<ulsd;) umsd++; | 279 for (; *umsd==0 && umsd<ulsd;) umsd++; |
279 length=ulsd-umsd+1; /* recalculate */ | 280 length=ulsd-umsd+1; /* recalculate */ |
280 } | 281 } |
281 drop=MAXI(length-DECPMAX, DECQTINY-num->exponent); | 282 drop=MAXI(length-DECPMAX, DECQTINY-num->exponent); |
282 /* drop can now be > digits for bottom-clamp (subnormal) cases */ | 283 /* drop can now be > digits for bottom-clamp (subnormal) cases */ |
298 /* [by-digit check for stickies as runs of zeros are rare] */ | 299 /* [by-digit check for stickies as runs of zeros are rare] */ |
299 if (drop<length) { /* NB lengths not addresses */ | 300 if (drop<length) { /* NB lengths not addresses */ |
300 roundat=umsd+length-drop; | 301 roundat=umsd+length-drop; |
301 reround=*roundat; | 302 reround=*roundat; |
302 for (ub=roundat+1; ub<=ulsd; ub++) { | 303 for (ub=roundat+1; ub<=ulsd; ub++) { |
303 if (*ub!=0) { /* non-zero to be discarded */ | 304 if (*ub!=0) { /* non-zero to be discarded */ |
304 reround=DECSTICKYTAB[reround]; /* apply sticky bit */ | 305 reround=DECSTICKYTAB[reround]; /* apply sticky bit */ |
305 break; /* [remainder don't-care] */ | 306 break; /* [remainder don't-care] */ |
306 } | 307 } |
307 } /* check stickies */ | 308 } /* check stickies */ |
308 ulsd=roundat-1; /* new LSD */ | 309 ulsd=roundat-1; /* new LSD */ |
309 } | 310 } |
310 else { /* edge case */ | 311 else { /* edge case */ |
311 if (drop==length) { | 312 if (drop==length) { |
312 roundat=umsd; | 313 roundat=umsd; |
313 reround=*roundat; | 314 reround=*roundat; |
315 else { | 316 else { |
316 roundat=umsd-1; | 317 roundat=umsd-1; |
317 reround=0; | 318 reround=0; |
318 } | 319 } |
319 for (ub=roundat+1; ub<=ulsd; ub++) { | 320 for (ub=roundat+1; ub<=ulsd; ub++) { |
320 if (*ub!=0) { /* non-zero to be discarded */ | 321 if (*ub!=0) { /* non-zero to be discarded */ |
321 reround=DECSTICKYTAB[reround]; /* apply sticky bit */ | 322 reround=DECSTICKYTAB[reround]; /* apply sticky bit */ |
322 break; /* [remainder don't-care] */ | 323 break; /* [remainder don't-care] */ |
323 } | 324 } |
324 } /* check stickies */ | 325 } /* check stickies */ |
325 *umsd=0; /* coefficient is a 0 */ | 326 *umsd=0; /* coefficient is a 0 */ |
326 ulsd=umsd; /* .. */ | 327 ulsd=umsd; /* .. */ |
327 } | 328 } |
328 | 329 |
329 if (reround!=0) { /* discarding non-zero */ | 330 if (reround!=0) { /* discarding non-zero */ |
330 uInt bump=0; | 331 uInt bump=0; |
331 set->status|=DEC_Inexact; | 332 set->status|=DEC_Inexact; |
332 /* if adjusted exponent [exp+digits-1] is < EMIN then num is */ | 333 /* if adjusted exponent [exp+digits-1] is < EMIN then num is */ |
333 /* subnormal -- so raise Underflow */ | 334 /* subnormal -- so raise Underflow */ |
334 if (num->exponent<DECEMIN && (num->exponent+(ulsd-umsd+1)-1)<DECEMIN) | 335 if (num->exponent<DECEMIN && (num->exponent+(ulsd-umsd+1)-1)<DECEMIN) |
335 set->status|=DEC_Underflow; | 336 set->status|=DEC_Underflow; |
336 | 337 |
337 /* next decide whether increment of the coefficient is needed */ | 338 /* next decide whether increment of the coefficient is needed */ |
338 if (set->round==DEC_ROUND_HALF_EVEN) { /* fastpath slowest case */ | 339 if (set->round==DEC_ROUND_HALF_EVEN) { /* fastpath slowest case */ |
339 if (reround>5) bump=1; /* >0.5 goes up */ | 340 if (reround>5) bump=1; /* >0.5 goes up */ |
340 else if (reround==5) /* exactly 0.5000 .. */ | 341 else if (reround==5) /* exactly 0.5000 .. */ |
341 bump=*ulsd & 0x01; /* .. up iff [new] lsd is odd */ | 342 bump=*ulsd & 0x01; /* .. up iff [new] lsd is odd */ |
342 } /* r-h-e */ | 343 } /* r-h-e */ |
343 else switch (set->round) { | 344 else switch (set->round) { |
344 case DEC_ROUND_DOWN: { | 345 case DEC_ROUND_DOWN: { |
345 /* no change */ | 346 /* no change */ |
375 #if DECCHECK | 376 #if DECCHECK |
376 printf("Unknown rounding mode: %ld\n", (LI)set->round); | 377 printf("Unknown rounding mode: %ld\n", (LI)set->round); |
377 #endif | 378 #endif |
378 break;} | 379 break;} |
379 } /* switch (not r-h-e) */ | 380 } /* switch (not r-h-e) */ |
380 /* printf("ReRound: %ld bump: %ld\n", (LI)reround, (LI)bump); */ | 381 /* printf("ReRound: %ld bump: %ld\n", (LI)reround, (LI)bump); */ |
381 | 382 |
382 if (bump!=0) { /* need increment */ | 383 if (bump!=0) { /* need increment */ |
383 /* increment the coefficient; this might end up with 1000... */ | 384 /* increment the coefficient; this might end up with 1000... */ |
384 /* (after the all nines case) */ | 385 /* (after the all nines case) */ |
385 ub=ulsd; | 386 ub=ulsd; |
386 for(; ub-3>=umsd && UINTAT(ub-3)==0x09090909; ub-=4) UINTAT(ub-3)=0; | 387 for(; ub-3>=umsd && UBTOUI(ub-3)==0x09090909; ub-=4) { |
388 UBFROMUI(ub-3, 0); /* to 00000000 */ | |
389 } | |
387 /* [note ub could now be to left of msd, and it is not safe */ | 390 /* [note ub could now be to left of msd, and it is not safe */ |
388 /* to write to the the left of the msd] */ | 391 /* to write to the the left of the msd] */ |
389 /* now at most 3 digits left to non-9 (usually just the one) */ | 392 /* now at most 3 digits left to non-9 (usually just the one) */ |
390 for (; ub>=umsd; *ub=0, ub--) { | 393 for (; ub>=umsd; *ub=0, ub--) { |
391 if (*ub==9) continue; /* carry */ | 394 if (*ub==9) continue; /* carry */ |
429 num->exponent=DECEMAX-(DECPMAX-1); /* clamp to max */ | 432 num->exponent=DECEMAX-(DECPMAX-1); /* clamp to max */ |
430 } | 433 } |
431 else if ((num->exponent+length-1)>DECEMAX) { /* > Nmax */ | 434 else if ((num->exponent+length-1)>DECEMAX) { /* > Nmax */ |
432 /* Overflow -- these could go straight to encoding, here, but */ | 435 /* Overflow -- these could go straight to encoding, here, but */ |
433 /* instead num is adjusted to keep the code cleaner */ | 436 /* instead num is adjusted to keep the code cleaner */ |
434 Flag needmax=0; /* 1 for finite result */ | 437 Flag needmax=0; /* 1 for finite result */ |
435 set->status|=(DEC_Overflow | DEC_Inexact); | 438 set->status|=(DEC_Overflow | DEC_Inexact); |
436 switch (set->round) { | 439 switch (set->round) { |
437 case DEC_ROUND_DOWN: { | 440 case DEC_ROUND_DOWN: { |
438 needmax=1; /* never Infinity */ | 441 needmax=1; /* never Infinity */ |
439 break;} /* r-d */ | 442 break;} /* r-d */ |
446 case DEC_ROUND_FLOOR: { | 449 case DEC_ROUND_FLOOR: { |
447 if (!num->sign) needmax=1; /* Infinity iff negative */ | 450 if (!num->sign) needmax=1; /* Infinity iff negative */ |
448 break;} /* r-f */ | 451 break;} /* r-f */ |
449 default: break; /* Infinity in all other cases */ | 452 default: break; /* Infinity in all other cases */ |
450 } | 453 } |
451 if (!needmax) { /* easy .. set Infinity */ | 454 if (!needmax) { /* easy .. set Infinity */ |
452 num->exponent=DECFLOAT_Inf; | 455 num->exponent=DECFLOAT_Inf; |
453 *umsd=0; /* be clean: coefficient to 0 */ | 456 *umsd=0; /* be clean: coefficient to 0 */ |
454 ulsd=umsd; /* .. */ | 457 ulsd=umsd; /* .. */ |
455 } | 458 } |
456 else { /* return Nmax */ | 459 else { /* return Nmax */ |
457 umsd=allnines; /* use constant array */ | 460 umsd=allnines; /* use constant array */ |
458 ulsd=allnines+DECPMAX-1; | 461 ulsd=allnines+DECPMAX-1; |
459 num->exponent=DECEMAX-(DECPMAX-1); | 462 num->exponent=DECEMAX-(DECPMAX-1); |
460 } | 463 } |
461 } | 464 } |
468 uByte buffer[ROUNDUP(DECPMAX+3, 4)]; /* [+3 allows uInt padding] */ | 471 uByte buffer[ROUNDUP(DECPMAX+3, 4)]; /* [+3 allows uInt padding] */ |
469 uByte *s=umsd; /* source */ | 472 uByte *s=umsd; /* source */ |
470 uByte *t=buffer; /* safe target */ | 473 uByte *t=buffer; /* safe target */ |
471 uByte *tlsd=buffer+(ulsd-umsd)+shift; /* target LSD */ | 474 uByte *tlsd=buffer+(ulsd-umsd)+shift; /* target LSD */ |
472 /* printf("folddown shift=%ld\n", (LI)shift); */ | 475 /* printf("folddown shift=%ld\n", (LI)shift); */ |
473 for (; s<=ulsd; s+=4, t+=4) UINTAT(t)=UINTAT(s); | 476 for (; s<=ulsd; s+=4, t+=4) UBFROMUI(t, UBTOUI(s)); |
474 for (t=tlsd-shift+1; t<=tlsd; t+=4) UINTAT(t)=0; /* pad */ | 477 for (t=tlsd-shift+1; t<=tlsd; t+=4) UBFROMUI(t, 0); /* pad 0s */ |
475 num->exponent-=shift; | 478 num->exponent-=shift; |
476 umsd=buffer; | 479 umsd=buffer; |
477 ulsd=tlsd; | 480 ulsd=tlsd; |
478 } | 481 } |
479 } /* fold-down? */ | 482 } /* fold-down? */ |
485 /* At this point the result will properly fit the decFloat */ | 488 /* At this point the result will properly fit the decFloat */ |
486 /* encoding, and it can be encoded with no possibility of error */ | 489 /* encoding, and it can be encoded with no possibility of error */ |
487 /*------------------------------------------------------------------*/ | 490 /*------------------------------------------------------------------*/ |
488 /* Following code does not alter coefficient (could be allnines array) */ | 491 /* Following code does not alter coefficient (could be allnines array) */ |
489 | 492 |
493 /* fast path possible when DECPMAX digits */ | |
490 if (length==DECPMAX) { | 494 if (length==DECPMAX) { |
491 return decFloatFromBCD(df, num->exponent, umsd, num->sign); | 495 return decFloatFromBCD(df, num->exponent, umsd, num->sign); |
492 } | 496 } /* full-length */ |
493 | 497 |
494 /* Here when length is short */ | 498 /* slower path when not a full-length number; must care about length */ |
499 /* [coefficient length here will be < DECPMAX] */ | |
495 if (!NUMISSPECIAL(num)) { /* is still finite */ | 500 if (!NUMISSPECIAL(num)) { /* is still finite */ |
496 /* encode the combination field and exponent continuation */ | 501 /* encode the combination field and exponent continuation */ |
497 uInt uexp=(uInt)(num->exponent+DECBIAS); /* biased exponent */ | 502 uInt uexp=(uInt)(num->exponent+DECBIAS); /* biased exponent */ |
498 uInt code=(uexp>>DECECONL)<<4; /* top two bits of exp */ | 503 uInt code=(uexp>>DECECONL)<<4; /* top two bits of exp */ |
499 /* [msd=0] */ | 504 /* [msd==0] */ |
500 /* look up the combination field and make high word */ | 505 /* look up the combination field and make high word */ |
501 encode=DECCOMBFROM[code]; /* indexed by (0-2)*16+msd */ | 506 encode=DECCOMBFROM[code]; /* indexed by (0-2)*16+msd */ |
502 encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */ | 507 encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */ |
503 } | 508 } |
504 else encode=num->exponent; /* special [already in word] */ | 509 else encode=num->exponent; /* special [already in word] */ |
505 /* [coefficient length here will be < DECPMAX] */ | |
506 | |
507 encode|=num->sign; /* add sign */ | 510 encode|=num->sign; /* add sign */ |
508 | 511 |
509 /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */ | 512 /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */ |
510 /* refers to the declet from the least significant three digits) */ | 513 /* refers to the declet from the least significant three digits) */ |
511 /* and put the corresponding DPD code into dpd. Access to umsd and */ | 514 /* and put the corresponding DPD code into dpd. Access to umsd and */ |
512 /* ulsd (pointers to the most and least significant digit of the */ | 515 /* ulsd (pointers to the most and least significant digit of the */ |
513 /* variable-length coefficient) is assumed, along with use of a */ | 516 /* variable-length coefficient) is assumed, along with use of a */ |
514 /* working pointer, uInt *ub. */ | 517 /* working pointer, uInt *ub. */ |
515 /* As not full-length then chances are there are many leading zeros */ | 518 /* As not full-length then chances are there are many leading zeros */ |
516 /* [and there may be a partial triad] */ | 519 /* [and there may be a partial triad] */ |
517 #define getDPD(dpd, n) ub=ulsd-(3*(n))-2; \ | 520 #define getDPDt(dpd, n) ub=ulsd-(3*(n))-2; \ |
518 if (ub<umsd-2) dpd=0; \ | 521 if (ub<umsd-2) dpd=0; \ |
519 else if (ub>=umsd) dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)]; \ | 522 else if (ub>=umsd) dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)]; \ |
520 else {dpd=*(ub+2); if (ub+1==umsd) dpd+=*(ub+1)*16; dpd=BCD2DPD[dpd];} | 523 else {dpd=*(ub+2); if (ub+1==umsd) dpd+=*(ub+1)*16; dpd=BCD2DPD[dpd];} |
521 | 524 |
522 /* place the declets in the encoding words and copy to result (df), */ | 525 /* place the declets in the encoding words and copy to result (df), */ |
523 /* according to endianness; in all cases complete the sign word */ | 526 /* according to endianness; in all cases complete the sign word */ |
524 /* first */ | 527 /* first */ |
525 #if DECPMAX==7 | 528 #if DECPMAX==7 |
526 getDPD(dpd, 1); | 529 getDPDt(dpd, 1); |
527 encode|=dpd<<10; | 530 encode|=dpd<<10; |
528 getDPD(dpd, 0); | 531 getDPDt(dpd, 0); |
529 encode|=dpd; | 532 encode|=dpd; |
530 DFWORD(df, 0)=encode; /* just the one word */ | 533 DFWORD(df, 0)=encode; /* just the one word */ |
531 | 534 |
532 #elif DECPMAX==16 | 535 #elif DECPMAX==16 |
533 getDPD(dpd, 4); encode|=dpd<<8; | 536 getDPDt(dpd, 4); encode|=dpd<<8; |
534 getDPD(dpd, 3); encode|=dpd>>2; | 537 getDPDt(dpd, 3); encode|=dpd>>2; |
535 DFWORD(df, 0)=encode; | 538 DFWORD(df, 0)=encode; |
536 encode=dpd<<30; | 539 encode=dpd<<30; |
537 getDPD(dpd, 2); encode|=dpd<<20; | 540 getDPDt(dpd, 2); encode|=dpd<<20; |
538 getDPD(dpd, 1); encode|=dpd<<10; | 541 getDPDt(dpd, 1); encode|=dpd<<10; |
539 getDPD(dpd, 0); encode|=dpd; | 542 getDPDt(dpd, 0); encode|=dpd; |
540 DFWORD(df, 1)=encode; | 543 DFWORD(df, 1)=encode; |
541 | 544 |
542 #elif DECPMAX==34 | 545 #elif DECPMAX==34 |
543 getDPD(dpd,10); encode|=dpd<<4; | 546 getDPDt(dpd,10); encode|=dpd<<4; |
544 getDPD(dpd, 9); encode|=dpd>>6; | 547 getDPDt(dpd, 9); encode|=dpd>>6; |
545 DFWORD(df, 0)=encode; | 548 DFWORD(df, 0)=encode; |
546 | 549 |
547 encode=dpd<<26; | 550 encode=dpd<<26; |
548 getDPD(dpd, 8); encode|=dpd<<16; | 551 getDPDt(dpd, 8); encode|=dpd<<16; |
549 getDPD(dpd, 7); encode|=dpd<<6; | 552 getDPDt(dpd, 7); encode|=dpd<<6; |
550 getDPD(dpd, 6); encode|=dpd>>4; | 553 getDPDt(dpd, 6); encode|=dpd>>4; |
551 DFWORD(df, 1)=encode; | 554 DFWORD(df, 1)=encode; |
552 | 555 |
553 encode=dpd<<28; | 556 encode=dpd<<28; |
554 getDPD(dpd, 5); encode|=dpd<<18; | 557 getDPDt(dpd, 5); encode|=dpd<<18; |
555 getDPD(dpd, 4); encode|=dpd<<8; | 558 getDPDt(dpd, 4); encode|=dpd<<8; |
556 getDPD(dpd, 3); encode|=dpd>>2; | 559 getDPDt(dpd, 3); encode|=dpd>>2; |
557 DFWORD(df, 2)=encode; | 560 DFWORD(df, 2)=encode; |
558 | 561 |
559 encode=dpd<<30; | 562 encode=dpd<<30; |
560 getDPD(dpd, 2); encode|=dpd<<20; | 563 getDPDt(dpd, 2); encode|=dpd<<20; |
561 getDPD(dpd, 1); encode|=dpd<<10; | 564 getDPDt(dpd, 1); encode|=dpd<<10; |
562 getDPD(dpd, 0); encode|=dpd; | 565 getDPDt(dpd, 0); encode|=dpd; |
563 DFWORD(df, 3)=encode; | 566 DFWORD(df, 3)=encode; |
564 #endif | 567 #endif |
565 | 568 |
566 /* printf("Status: %08lx\n", (LI)set->status); */ | 569 /* printf("Status: %08lx\n", (LI)set->status); */ |
567 /* decFloatShow(df, "final"); */ | 570 /* decFloatShow(df, "final2"); */ |
568 return df; | 571 return df; |
569 } /* decFinalize */ | 572 } /* decFinalize */ |
570 | 573 |
571 /* ------------------------------------------------------------------ */ | 574 /* ------------------------------------------------------------------ */ |
572 /* decFloatFromBCD -- set decFloat from exponent, BCD8, and sign */ | 575 /* decFloatFromBCD -- set decFloat from exponent, BCD8, and sign */ |
573 /* */ | 576 /* */ |
574 /* df is the target decFloat */ | 577 /* df is the target decFloat */ |
575 /* exp is the in-range unbiased exponent, q, or a special value in */ | 578 /* exp is the in-range unbiased exponent, q, or a special value in */ |
576 /* the form returned by decFloatGetExponent */ | 579 /* the form returned by decFloatGetExponent */ |
577 /* bcdar holds DECPMAX digits to set the coefficient from, one */ | 580 /* bcdar holds DECPMAX digits to set the coefficient from, one */ |
578 /* digit in each byte (BCD8 encoding); the first (MSD) is ignored */ | 581 /* digit in each byte (BCD8 encoding); the first (MSD) is ignored */ |
579 /* if df is a NaN; all are ignored if df is infinite. */ | 582 /* if df is a NaN; all are ignored if df is infinite. */ |
580 /* All bytes must be in 0-9; results undefined otherwise. */ | 583 /* All bytes must be in 0-9; results are undefined otherwise. */ |
581 /* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */ | 584 /* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */ |
582 /* returns df, which will be canonical */ | 585 /* returns df, which will be canonical */ |
583 /* */ | 586 /* */ |
584 /* No error is possible, and no status will be set. */ | 587 /* No error is possible, and no status will be set. */ |
585 /* ------------------------------------------------------------------ */ | 588 /* ------------------------------------------------------------------ */ |
586 decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar, | 589 decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar, |
587 Int sig) { | 590 Int sig) { |
602 /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */ | 605 /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */ |
603 /* refers to the declet from the least significant three digits) */ | 606 /* refers to the declet from the least significant three digits) */ |
604 /* and put the corresponding DPD code into dpd. */ | 607 /* and put the corresponding DPD code into dpd. */ |
605 /* Use of a working pointer, uInt *ub, is assumed. */ | 608 /* Use of a working pointer, uInt *ub, is assumed. */ |
606 | 609 |
607 #define getDPDf(dpd, n) ub=bcdar+DECPMAX-1-(3*(n))-2; \ | 610 #define getDPDb(dpd, n) ub=bcdar+DECPMAX-1-(3*(n))-2; \ |
608 dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)]; | 611 dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)]; |
609 | 612 |
610 /* place the declets in the encoding words and copy to result (df), */ | 613 /* place the declets in the encoding words and copy to result (df), */ |
611 /* according to endianness; in all cases complete the sign word */ | 614 /* according to endianness; in all cases complete the sign word */ |
612 /* first */ | 615 /* first */ |
613 #if DECPMAX==7 | 616 #if DECPMAX==7 |
614 getDPDf(dpd, 1); | 617 getDPDb(dpd, 1); |
615 encode|=dpd<<10; | 618 encode|=dpd<<10; |
616 getDPDf(dpd, 0); | 619 getDPDb(dpd, 0); |
617 encode|=dpd; | 620 encode|=dpd; |
618 DFWORD(df, 0)=encode; /* just the one word */ | 621 DFWORD(df, 0)=encode; /* just the one word */ |
619 | 622 |
620 #elif DECPMAX==16 | 623 #elif DECPMAX==16 |
621 getDPDf(dpd, 4); encode|=dpd<<8; | 624 getDPDb(dpd, 4); encode|=dpd<<8; |
622 getDPDf(dpd, 3); encode|=dpd>>2; | 625 getDPDb(dpd, 3); encode|=dpd>>2; |
623 DFWORD(df, 0)=encode; | 626 DFWORD(df, 0)=encode; |
624 encode=dpd<<30; | 627 encode=dpd<<30; |
625 getDPDf(dpd, 2); encode|=dpd<<20; | 628 getDPDb(dpd, 2); encode|=dpd<<20; |
626 getDPDf(dpd, 1); encode|=dpd<<10; | 629 getDPDb(dpd, 1); encode|=dpd<<10; |
627 getDPDf(dpd, 0); encode|=dpd; | 630 getDPDb(dpd, 0); encode|=dpd; |
628 DFWORD(df, 1)=encode; | 631 DFWORD(df, 1)=encode; |
629 | 632 |
630 #elif DECPMAX==34 | 633 #elif DECPMAX==34 |
631 getDPDf(dpd,10); encode|=dpd<<4; | 634 getDPDb(dpd,10); encode|=dpd<<4; |
632 getDPDf(dpd, 9); encode|=dpd>>6; | 635 getDPDb(dpd, 9); encode|=dpd>>6; |
633 DFWORD(df, 0)=encode; | 636 DFWORD(df, 0)=encode; |
634 | 637 |
635 encode=dpd<<26; | 638 encode=dpd<<26; |
636 getDPDf(dpd, 8); encode|=dpd<<16; | 639 getDPDb(dpd, 8); encode|=dpd<<16; |
637 getDPDf(dpd, 7); encode|=dpd<<6; | 640 getDPDb(dpd, 7); encode|=dpd<<6; |
638 getDPDf(dpd, 6); encode|=dpd>>4; | 641 getDPDb(dpd, 6); encode|=dpd>>4; |
639 DFWORD(df, 1)=encode; | 642 DFWORD(df, 1)=encode; |
640 | 643 |
641 encode=dpd<<28; | 644 encode=dpd<<28; |
642 getDPDf(dpd, 5); encode|=dpd<<18; | 645 getDPDb(dpd, 5); encode|=dpd<<18; |
643 getDPDf(dpd, 4); encode|=dpd<<8; | 646 getDPDb(dpd, 4); encode|=dpd<<8; |
644 getDPDf(dpd, 3); encode|=dpd>>2; | 647 getDPDb(dpd, 3); encode|=dpd>>2; |
645 DFWORD(df, 2)=encode; | 648 DFWORD(df, 2)=encode; |
646 | 649 |
647 encode=dpd<<30; | 650 encode=dpd<<30; |
648 getDPDf(dpd, 2); encode|=dpd<<20; | 651 getDPDb(dpd, 2); encode|=dpd<<20; |
649 getDPDf(dpd, 1); encode|=dpd<<10; | 652 getDPDb(dpd, 1); encode|=dpd<<10; |
650 getDPDf(dpd, 0); encode|=dpd; | 653 getDPDb(dpd, 0); encode|=dpd; |
651 DFWORD(df, 3)=encode; | 654 DFWORD(df, 3)=encode; |
652 #endif | 655 #endif |
653 /* decFloatShow(df, "final"); */ | 656 /* decFloatShow(df, "fromB"); */ |
654 return df; | 657 return df; |
655 } /* decFloatFromBCD */ | 658 } /* decFloatFromBCD */ |
656 | 659 |
657 /* ------------------------------------------------------------------ */ | 660 /* ------------------------------------------------------------------ */ |
658 /* decFloatFromPacked -- set decFloat from exponent and packed BCD */ | 661 /* decFloatFromPacked -- set decFloat from exponent and packed BCD */ |
664 /* (all 6 codes are OK); the first (MSD) is ignored if df is a NaN */ | 667 /* (all 6 codes are OK); the first (MSD) is ignored if df is a NaN */ |
665 /* and all except sign are ignored if df is infinite. For DOUBLE */ | 668 /* and all except sign are ignored if df is infinite. For DOUBLE */ |
666 /* and QUAD the first (pad) nibble is also ignored in all cases. */ | 669 /* and QUAD the first (pad) nibble is also ignored in all cases. */ |
667 /* All coefficient nibbles must be in 0-9 and sign in A-F; results */ | 670 /* All coefficient nibbles must be in 0-9 and sign in A-F; results */ |
668 /* are undefined otherwise. */ | 671 /* are undefined otherwise. */ |
669 /* returns df, which will be canonical */ | 672 /* returns df, which will be canonical */ |
670 /* */ | 673 /* */ |
671 /* No error is possible, and no status will be set. */ | 674 /* No error is possible, and no status will be set. */ |
672 /* ------------------------------------------------------------------ */ | 675 /* ------------------------------------------------------------------ */ |
673 decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) { | 676 decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) { |
674 uByte bcdar[DECPMAX+2]; /* work [+1 for pad, +1 for sign] */ | 677 uByte bcdar[DECPMAX+2]; /* work [+1 for pad, +1 for sign] */ |
684 #endif | 687 #endif |
685 for (ip=packed; ip<packed+((DECPMAX+2)/2); ip++) { | 688 for (ip=packed; ip<packed+((DECPMAX+2)/2); ip++) { |
686 *op++=*ip>>4; | 689 *op++=*ip>>4; |
687 *op++=(uByte)(*ip&0x0f); /* [final nibble is sign] */ | 690 *op++=(uByte)(*ip&0x0f); /* [final nibble is sign] */ |
688 } | 691 } |
689 op--; /* -> sign byte */ | 692 op--; /* -> sign byte */ |
690 if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign; | 693 if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign; |
691 | 694 |
692 if (EXPISSPECIAL(exp)) { /* Infinity or NaN */ | 695 if (EXPISSPECIAL(exp)) { /* Infinity or NaN */ |
693 if (!EXPISINF(exp)) bcdar[1]=0; /* a NaN: ignore MSD */ | 696 if (!EXPISINF(exp)) bcdar[1]=0; /* a NaN: ignore MSD */ |
694 else memset(bcdar+1, 0, DECPMAX); /* Infinite: coefficient to 0 */ | 697 else memset(bcdar+1, 0, DECPMAX); /* Infinite: coefficient to 0 */ |
695 } | 698 } |
696 return decFloatFromBCD(df, exp, bcdar+1, sig); | 699 return decFloatFromBCD(df, exp, bcdar+1, sig); |
697 } /* decFloatFromPacked */ | 700 } /* decFloatFromPacked */ |
698 | 701 |
699 /* ------------------------------------------------------------------ */ | 702 /* ------------------------------------------------------------------ */ |
700 /* decFloatFromString -- conversion from numeric string */ | 703 /* decFloatFromPackedChecked -- set from exponent and packed; checked */ |
704 /* */ | |
705 /* df is the target decFloat */ | |
706 /* exp is the in-range unbiased exponent, q, or a special value in */ | |
707 /* the form returned by decFloatGetExponent */ | |
708 /* packed holds DECPMAX packed decimal digits plus a sign nibble */ | |
709 /* (all 6 codes are OK); the first (MSD) must be 0 if df is a NaN */ | |
710 /* and all digits must be 0 if df is infinite. For DOUBLE and */ | |
711 /* QUAD the first (pad) nibble must be 0. */ | |
712 /* All coefficient nibbles must be in 0-9 and sign in A-F. */ | |
713 /* returns df, which will be canonical or NULL if any of the */ | |
714 /* requirements are not met (if this case df is unchanged); that */ | |
715 /* is, the input data must be as returned by decFloatToPacked, */ | |
716 /* except that all six sign codes are acccepted. */ | |
717 /* */ | |
718 /* No status will be set. */ | |
719 /* ------------------------------------------------------------------ */ | |
720 decFloat * decFloatFromPackedChecked(decFloat *df, Int exp, | |
721 const uByte *packed) { | |
722 uByte bcdar[DECPMAX+2]; /* work [+1 for pad, +1 for sign] */ | |
723 const uByte *ip; /* .. */ | |
724 uByte *op; /* .. */ | |
725 Int sig=0; /* sign */ | |
726 | |
727 /* expand coefficient and sign to BCDAR */ | |
728 #if SINGLE | |
729 op=bcdar+1; /* no pad digit */ | |
730 #else | |
731 op=bcdar; /* first (pad) digit here */ | |
732 #endif | |
733 for (ip=packed; ip<packed+((DECPMAX+2)/2); ip++) { | |
734 *op=*ip>>4; | |
735 if (*op>9) return NULL; | |
736 op++; | |
737 *op=(uByte)(*ip&0x0f); /* [final nibble is sign] */ | |
738 if (*op>9 && ip<packed+((DECPMAX+2)/2)-1) return NULL; | |
739 op++; | |
740 } | |
741 op--; /* -> sign byte */ | |
742 if (*op<=9) return NULL; /* bad sign */ | |
743 if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign; | |
744 | |
745 #if !SINGLE | |
746 if (bcdar[0]!=0) return NULL; /* bad pad nibble */ | |
747 #endif | |
748 | |
749 if (EXPISNAN(exp)) { /* a NaN */ | |
750 if (bcdar[1]!=0) return NULL; /* bad msd */ | |
751 } /* NaN */ | |
752 else if (EXPISINF(exp)) { /* is infinite */ | |
753 Int i; | |
754 for (i=0; i<DECPMAX; i++) { | |
755 if (bcdar[i+1]!=0) return NULL; /* should be all zeros */ | |
756 } | |
757 } /* infinity */ | |
758 else { /* finite */ | |
759 /* check the exponent is in range */ | |
760 if (exp>DECEMAX-DECPMAX+1) return NULL; | |
761 if (exp<DECEMIN-DECPMAX+1) return NULL; | |
762 } | |
763 return decFloatFromBCD(df, exp, bcdar+1, sig); | |
764 } /* decFloatFromPacked */ | |
765 | |
766 /* ------------------------------------------------------------------ */ | |
767 /* decFloatFromString -- conversion from numeric string */ | |
701 /* */ | 768 /* */ |
702 /* result is the decFloat format number which gets the result of */ | 769 /* result is the decFloat format number which gets the result of */ |
703 /* the conversion */ | 770 /* the conversion */ |
704 /* *string is the character string which should contain a valid */ | 771 /* *string is the character string which should contain a valid */ |
705 /* number (which may be a special value), \0-terminated */ | 772 /* number (which may be a special value), \0-terminated */ |
706 /* If there are too many significant digits in the */ | 773 /* If there are too many significant digits in the */ |
707 /* coefficient it will be rounded. */ | 774 /* coefficient it will be rounded. */ |
708 /* set is the context */ | 775 /* set is the context */ |
709 /* returns result */ | 776 /* returns result */ |
710 /* */ | 777 /* */ |
711 /* The length of the coefficient and the size of the exponent are */ | 778 /* The length of the coefficient and the size of the exponent are */ |
712 /* checked by this routine, so the correct error (Underflow or */ | 779 /* checked by this routine, so the correct error (Underflow or */ |
713 /* Overflow) can be reported or rounding applied, as necessary. */ | 780 /* Overflow) can be reported or rounding applied, as necessary. */ |
714 /* */ | 781 /* */ |
715 /* There is no limit to the coefficient length for finite inputs; */ | 782 /* There is no limit to the coefficient length for finite inputs; */ |
716 /* NaN payloads must be integers with no more than DECPMAX-1 digits. */ | 783 /* NaN payloads must be integers with no more than DECPMAX-1 digits. */ |
717 /* Exponents may have up to nine significant digits. */ | 784 /* Exponents may have up to nine significant digits. */ |
718 /* */ | 785 /* */ |
719 /* If bad syntax is detected, the result will be a quiet NaN. */ | 786 /* If bad syntax is detected, the result will be a quiet NaN. */ |
720 /* ------------------------------------------------------------------ */ | 787 /* ------------------------------------------------------------------ */ |
721 decFloat * decFloatFromString(decFloat *result, const char *string, | 788 decFloat * decFloatFromString(decFloat *result, const char *string, |
722 decContext *set) { | 789 decContext *set) { |
723 Int digits; /* count of digits in coefficient */ | 790 Int digits; /* count of digits in coefficient */ |
724 const char *dotchar=NULL; /* where dot was found [NULL if none] */ | 791 const char *dotchar=NULL; /* where dot was found [NULL if none] */ |
725 const char *cfirst=string; /* -> first character of decimal part */ | 792 const char *cfirst=string; /* -> first character of decimal part */ |
726 const char *c; /* work */ | 793 const char *c; /* work */ |
727 uByte *ub; /* .. */ | 794 uByte *ub; /* .. */ |
795 uInt uiwork; /* for macros */ | |
728 bcdnum num; /* collects data for finishing */ | 796 bcdnum num; /* collects data for finishing */ |
729 uInt error=DEC_Conversion_syntax; /* assume the worst */ | 797 uInt error=DEC_Conversion_syntax; /* assume the worst */ |
730 uByte buffer[ROUNDUP(DECSTRING+11, 8)]; /* room for most coefficents, */ | 798 uByte buffer[ROUNDUP(DECSTRING+11, 8)]; /* room for most coefficents, */ |
731 /* some common rounding, +3, & pad */ | 799 /* some common rounding, +3, & pad */ |
732 #if DECTRACE | 800 #if DECTRACE |
733 /* printf("FromString %s ...\n", string); */ | 801 /* printf("FromString %s ...\n", string); */ |
734 #endif | 802 #endif |
735 | 803 |
736 for(;;) { /* once-only 'loop' */ | 804 for(;;) { /* once-only 'loop' */ |
737 num.sign=0; /* assume non-negative */ | 805 num.sign=0; /* assume non-negative */ |
738 num.msd=buffer; /* MSD is here always */ | 806 num.msd=buffer; /* MSD is here always */ |
739 | 807 |
740 /* detect and validate the coefficient, including any leading, */ | 808 /* detect and validate the coefficient, including any leading, */ |
741 /* trailing, or embedded '.' */ | 809 /* trailing, or embedded '.' */ |
742 /* [could test four-at-a-time here (saving 10% for decQuads), */ | 810 /* [could test four-at-a-time here (saving 10% for decQuads), */ |
803 digits--; /* remove from digits count */ | 871 digits--; /* remove from digits count */ |
804 if (digits==0) break; /* was dot alone: bad syntax */ | 872 if (digits==0) break; /* was dot alone: bad syntax */ |
805 exp-=(Int)(clast-dotchar); /* adjust exponent */ | 873 exp-=(Int)(clast-dotchar); /* adjust exponent */ |
806 /* [the '.' can now be ignored] */ | 874 /* [the '.' can now be ignored] */ |
807 } | 875 } |
808 num.exponent=exp; /* exponent is good; store it */ | 876 num.exponent=exp; /* exponent is good; store it */ |
809 | 877 |
810 /* Here when whole string has been inspected and syntax is good */ | 878 /* Here when whole string has been inspected and syntax is good */ |
811 /* cfirst->first digit or dot, clast->last digit or dot */ | 879 /* cfirst->first digit or dot, clast->last digit or dot */ |
812 error=0; /* no error possible now */ | 880 error=0; /* no error possible now */ |
813 | 881 |
825 } | 893 } |
826 else for (; c<=clast;) { /* '.' could be anywhere */ | 894 else for (; c<=clast;) { /* '.' could be anywhere */ |
827 /* as usual, go by fours when safe; NB it has been asserted */ | 895 /* as usual, go by fours when safe; NB it has been asserted */ |
828 /* that a '.' does not have the same mask as a digit */ | 896 /* that a '.' does not have the same mask as a digit */ |
829 if (c<=clast-3 /* safe for four */ | 897 if (c<=clast-3 /* safe for four */ |
830 && (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* test four */ | 898 && (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* test four */ |
831 UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; /* to BCD8 */ | 899 UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); /* to BCD8 */ |
832 ub+=4; | 900 ub+=4; |
833 c+=4; | 901 c+=4; |
834 continue; | 902 continue; |
835 } | 903 } |
836 if (*c=='.') { /* found the dot */ | 904 if (*c=='.') { /* found the dot */ |
839 } | 907 } |
840 *ub++=(uByte)(*c++-'0'); | 908 *ub++=(uByte)(*c++-'0'); |
841 } | 909 } |
842 } /* had dot */ | 910 } /* had dot */ |
843 /* Now no dot; do this by fours (where safe) */ | 911 /* Now no dot; do this by fours (where safe) */ |
844 for (; c<=clast-3; c+=4, ub+=4) UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; | 912 for (; c<=clast-3; c+=4, ub+=4) UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); |
845 for (; c<=clast; c++, ub++) *ub=(uByte)(*c-'0'); | 913 for (; c<=clast; c++, ub++) *ub=(uByte)(*c-'0'); |
846 num.lsd=buffer+digits-1; /* record new LSD */ | 914 num.lsd=buffer+digits-1; /* record new LSD */ |
847 } /* fits */ | 915 } /* fits */ |
848 | 916 |
849 else { /* too long for buffer */ | 917 else { /* too long for buffer */ |
850 /* [This is a rare and unusual case; arbitrary-length input] */ | 918 /* [This is a rare and unusual case; arbitrary-length input] */ |
851 /* strip leading zeros [but leave final 0 if all 0's] */ | 919 /* strip leading zeros [but leave final 0 if all 0's] */ |
852 if (*cfirst=='.') cfirst++; /* step past dot at start */ | 920 if (*cfirst=='.') cfirst++; /* step past dot at start */ |
853 if (*cfirst=='0') { /* [cfirst always -> digit] */ | 921 if (*cfirst=='0') { /* [cfirst always -> digit] */ |
854 for (; cfirst<clast; cfirst++) { | 922 for (; cfirst<clast; cfirst++) { |
855 if (*cfirst!='0') { /* non-zero found */ | 923 if (*cfirst!='0') { /* non-zero found */ |
856 if (*cfirst=='.') continue; /* [ignore] */ | 924 if (*cfirst=='.') continue; /* [ignore] */ |
857 break; /* done */ | 925 break; /* done */ |
858 } | 926 } |
859 digits--; /* 0 stripped */ | 927 digits--; /* 0 stripped */ |
860 } /* cfirst */ | 928 } /* cfirst */ |
864 /* be too long; copy up to Pmax+1 digits to the buffer, then */ | 932 /* be too long; copy up to Pmax+1 digits to the buffer, then */ |
865 /* just record any non-zeros (set round-for-reround digit) */ | 933 /* just record any non-zeros (set round-for-reround digit) */ |
866 for (c=cfirst; c<=clast && ub<=buffer+DECPMAX; c++) { | 934 for (c=cfirst; c<=clast && ub<=buffer+DECPMAX; c++) { |
867 /* (see commentary just above) */ | 935 /* (see commentary just above) */ |
868 if (c<=clast-3 /* safe for four */ | 936 if (c<=clast-3 /* safe for four */ |
869 && (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */ | 937 && (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */ |
870 UINTAT(ub)=UINTAT(c)&0x0f0f0f0f; /* to BCD8 */ | 938 UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f); /* to BCD8 */ |
871 ub+=4; | 939 ub+=4; |
872 c+=3; /* [will become 4] */ | 940 c+=3; /* [will become 4] */ |
873 continue; | 941 continue; |
874 } | 942 } |
875 if (*c=='.') continue; /* [ignore] */ | 943 if (*c=='.') continue; /* [ignore] */ |
876 *ub++=(uByte)(*c-'0'); | 944 *ub++=(uByte)(*c-'0'); |
877 } | 945 } |
878 ub--; /* -> LSD */ | 946 ub--; /* -> LSD */ |
879 for (; c<=clast; c++) { /* inspect remaining chars */ | 947 for (; c<=clast; c++) { /* inspect remaining chars */ |
880 if (*c!='0') { /* sticky bit needed */ | 948 if (*c!='0') { /* sticky bit needed */ |
881 if (*c=='.') continue; /* [ignore] */ | 949 if (*c=='.') continue; /* [ignore] */ |
882 *ub=DECSTICKYTAB[*ub]; /* update round-for-reround */ | 950 *ub=DECSTICKYTAB[*ub]; /* update round-for-reround */ |
883 break; /* no need to look at more */ | 951 break; /* no need to look at more */ |
884 } | 952 } |
918 if ((unsigned)(*c-'0')>9) break; /* quit if not 0-9 */ | 986 if ((unsigned)(*c-'0')>9) break; /* quit if not 0-9 */ |
919 if (c-cfirst==DECPMAX-1) break; /* too many digits */ | 987 if (c-cfirst==DECPMAX-1) break; /* too many digits */ |
920 *ub=(uByte)(*c-'0'); /* good bcd8 */ | 988 *ub=(uByte)(*c-'0'); /* good bcd8 */ |
921 } | 989 } |
922 if (*c!='\0') break; /* not all digits, or too many */ | 990 if (*c!='\0') break; /* not all digits, or too many */ |
923 num.lsd=ub-1; /* record new LSD */ | 991 num.lsd=ub-1; /* record new LSD */ |
924 } | 992 } |
925 } /* NaN or sNaN */ | 993 } /* NaN or sNaN */ |
926 error=0; /* syntax is OK */ | 994 error=0; /* syntax is OK */ |
927 break; /* done with specials */ | 995 break; /* done with specials */ |
928 } /* digits=0 (special expected) */ | 996 } /* digits=0 (special expected) */ |
931 | 999 |
932 /* decShowNum(&num, "fromStr"); */ | 1000 /* decShowNum(&num, "fromStr"); */ |
933 | 1001 |
934 if (error!=0) { | 1002 if (error!=0) { |
935 set->status|=error; | 1003 set->status|=error; |
936 num.exponent=DECFLOAT_qNaN; /* set up quiet NaN */ | 1004 num.exponent=DECFLOAT_qNaN; /* set up quiet NaN */ |
937 num.sign=0; /* .. with 0 sign */ | 1005 num.sign=0; /* .. with 0 sign */ |
938 buffer[0]=0; /* .. and coefficient */ | 1006 buffer[0]=0; /* .. and coefficient */ |
939 num.lsd=buffer; /* .. */ | 1007 num.lsd=buffer; /* .. */ |
940 /* decShowNum(&num, "oops"); */ | 1008 /* decShowNum(&num, "oops"); */ |
941 } | 1009 } |
942 | 1010 |
950 /* decFloatFromWider -- conversion from next-wider format */ | 1018 /* decFloatFromWider -- conversion from next-wider format */ |
951 /* */ | 1019 /* */ |
952 /* result is the decFloat format number which gets the result of */ | 1020 /* result is the decFloat format number which gets the result of */ |
953 /* the conversion */ | 1021 /* the conversion */ |
954 /* wider is the decFloatWider format number which will be narrowed */ | 1022 /* wider is the decFloatWider format number which will be narrowed */ |
955 /* set is the context */ | 1023 /* set is the context */ |
956 /* returns result */ | 1024 /* returns result */ |
957 /* */ | 1025 /* */ |
958 /* Narrowing can cause rounding, overflow, etc., but not Invalid */ | 1026 /* Narrowing can cause rounding, overflow, etc., but not Invalid */ |
959 /* operation (sNaNs are copied and do not signal). */ | 1027 /* operation (sNaNs are copied and do not signal). */ |
960 /* ------------------------------------------------------------------ */ | 1028 /* ------------------------------------------------------------------ */ |
961 /* narrow-to is not possible for decQuad format numbers; simply omit */ | 1029 /* narrow-to is not possible for decQuad format numbers; simply omit */ |
962 #if !QUAD | 1030 #if !QUAD |
963 decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider, | 1031 decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider, |
964 decContext *set) { | 1032 decContext *set) { |
965 bcdnum num; /* collects data for finishing */ | 1033 bcdnum num; /* collects data for finishing */ |
966 uByte bcdar[DECWPMAX]; /* room for wider coefficient */ | 1034 uByte bcdar[DECWPMAX]; /* room for wider coefficient */ |
967 uInt widerhi=DFWWORD(wider, 0); /* top word */ | 1035 uInt widerhi=DFWWORD(wider, 0); /* top word */ |
968 Int exp; | 1036 Int exp; |
969 | 1037 |
970 GETWCOEFF(wider, bcdar); | 1038 GETWCOEFF(wider, bcdar); |
971 | 1039 |
972 num.msd=bcdar; /* MSD is here always */ | 1040 num.msd=bcdar; /* MSD is here always */ |
973 num.lsd=bcdar+DECWPMAX-1; /* LSD is here always */ | 1041 num.lsd=bcdar+DECWPMAX-1; /* LSD is here always */ |
974 num.sign=widerhi&0x80000000; /* extract sign [DECFLOAT_Sign=Neg] */ | 1042 num.sign=widerhi&0x80000000; /* extract sign [DECFLOAT_Sign=Neg] */ |
975 | 1043 |
976 /* decode the wider combination field to exponent */ | 1044 /* decode the wider combination field to exponent */ |
977 exp=DECCOMBWEXP[widerhi>>26]; /* decode from wider combination field */ | 1045 exp=DECCOMBWEXP[widerhi>>26]; /* decode from wider combination field */ |
978 /* if it is a special there's nothing to do unless sNaN; if it's */ | 1046 /* if it is a special there's nothing to do unless sNaN; if it's */ |
979 /* finite then add the (wider) exponent continuation and unbias */ | 1047 /* finite then add the (wider) exponent continuation and unbias */ |
980 if (EXPISSPECIAL(exp)) exp=widerhi&0x7e000000; /* include sNaN selector */ | 1048 if (EXPISSPECIAL(exp)) exp=widerhi&0x7e000000; /* include sNaN selector */ |
981 else exp+=GETWECON(wider)-DECWBIAS; | 1049 else exp+=GETWECON(wider)-DECWBIAS; |
982 num.exponent=exp; | 1050 num.exponent=exp; |
994 /* each byte (BCD8 encoding); if df is a NaN the first byte will */ | 1062 /* each byte (BCD8 encoding); if df is a NaN the first byte will */ |
995 /* be zero, and if it is infinite they will all be zero */ | 1063 /* be zero, and if it is infinite they will all be zero */ |
996 /* returns the sign of the coefficient (DECFLOAT_Sign if negative, */ | 1064 /* returns the sign of the coefficient (DECFLOAT_Sign if negative, */ |
997 /* 0 otherwise) */ | 1065 /* 0 otherwise) */ |
998 /* */ | 1066 /* */ |
999 /* No error is possible, and no status will be set. If df is a */ | 1067 /* No error is possible, and no status will be set. If df is a */ |
1000 /* special value the array is set to zeros (for Infinity) or to the */ | 1068 /* special value the array is set to zeros (for Infinity) or to the */ |
1001 /* payload of a qNaN or sNaN. */ | 1069 /* payload of a qNaN or sNaN. */ |
1002 /* ------------------------------------------------------------------ */ | 1070 /* ------------------------------------------------------------------ */ |
1003 Int decFloatGetCoefficient(const decFloat *df, uByte *bcdar) { | 1071 Int decFloatGetCoefficient(const decFloat *df, uByte *bcdar) { |
1004 if (DFISINF(df)) memset(bcdar, 0, DECPMAX); | 1072 if (DFISINF(df)) memset(bcdar, 0, DECPMAX); |
1008 } | 1076 } |
1009 return DFISSIGNED(df); | 1077 return DFISSIGNED(df); |
1010 } /* decFloatGetCoefficient */ | 1078 } /* decFloatGetCoefficient */ |
1011 | 1079 |
1012 /* ------------------------------------------------------------------ */ | 1080 /* ------------------------------------------------------------------ */ |
1013 /* decFloatGetExponent -- get unbiased exponent */ | 1081 /* decFloatGetExponent -- get unbiased exponent */ |
1014 /* */ | 1082 /* */ |
1015 /* df is the decFloat from which to extract the exponent */ | 1083 /* df is the decFloat from which to extract the exponent */ |
1016 /* returns the exponent, q. */ | 1084 /* returns the exponent, q. */ |
1017 /* */ | 1085 /* */ |
1018 /* No error is possible, and no status will be set. If df is a */ | 1086 /* No error is possible, and no status will be set. If df is a */ |
1019 /* special value the first seven bits of the decFloat are returned, */ | 1087 /* special value the first seven bits of the decFloat are returned, */ |
1020 /* left adjusted and with the first (sign) bit set to 0 (followed by */ | 1088 /* left adjusted and with the first (sign) bit set to 0 (followed by */ |
1021 /* 25 0 bits). e.g., -sNaN would return 0x7e000000 (DECFLOAT_sNaN). */ | 1089 /* 25 0 bits). e.g., -sNaN would return 0x7e000000 (DECFLOAT_sNaN). */ |
1022 /* ------------------------------------------------------------------ */ | 1090 /* ------------------------------------------------------------------ */ |
1023 Int decFloatGetExponent(const decFloat *df) { | 1091 Int decFloatGetExponent(const decFloat *df) { |
1027 | 1095 |
1028 /* ------------------------------------------------------------------ */ | 1096 /* ------------------------------------------------------------------ */ |
1029 /* decFloatSetCoefficient -- set coefficient from BCD8 */ | 1097 /* decFloatSetCoefficient -- set coefficient from BCD8 */ |
1030 /* */ | 1098 /* */ |
1031 /* df is the target decFloat (and source of exponent/special value) */ | 1099 /* df is the target decFloat (and source of exponent/special value) */ |
1032 /* bcdar holds DECPMAX digits to set the coefficient from, one */ | 1100 /* bcdar holds DECPMAX digits to set the coefficient from, one */ |
1033 /* digit in each byte (BCD8 encoding); the first (MSD) is ignored */ | 1101 /* digit in each byte (BCD8 encoding); the first (MSD) is ignored */ |
1034 /* if df is a NaN; all are ignored if df is infinite. */ | 1102 /* if df is a NaN; all are ignored if df is infinite. */ |
1035 /* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */ | 1103 /* sig is DECFLOAT_Sign to set the sign bit, 0 otherwise */ |
1036 /* returns df, which will be canonical */ | 1104 /* returns df, which will be canonical */ |
1037 /* */ | 1105 /* */ |
1038 /* No error is possible, and no status will be set. */ | 1106 /* No error is possible, and no status will be set. */ |
1039 /* ------------------------------------------------------------------ */ | 1107 /* ------------------------------------------------------------------ */ |
1040 decFloat * decFloatSetCoefficient(decFloat *df, const uByte *bcdar, | 1108 decFloat * decFloatSetCoefficient(decFloat *df, const uByte *bcdar, |
1041 Int sig) { | 1109 Int sig) { |
1053 else exp=GETEXPUN(df); | 1121 else exp=GETEXPUN(df); |
1054 return decFloatFromBCD(df, exp, bcdar, sig); | 1122 return decFloatFromBCD(df, exp, bcdar, sig); |
1055 } /* decFloatSetCoefficient */ | 1123 } /* decFloatSetCoefficient */ |
1056 | 1124 |
1057 /* ------------------------------------------------------------------ */ | 1125 /* ------------------------------------------------------------------ */ |
1058 /* decFloatSetExponent -- set exponent or special value */ | 1126 /* decFloatSetExponent -- set exponent or special value */ |
1059 /* */ | 1127 /* */ |
1060 /* df is the target decFloat (and source of coefficient/payload) */ | 1128 /* df is the target decFloat (and source of coefficient/payload) */ |
1061 /* set is the context for reporting status */ | 1129 /* set is the context for reporting status */ |
1062 /* exp is the unbiased exponent, q, or a special value in the form */ | 1130 /* exp is the unbiased exponent, q, or a special value in the form */ |
1063 /* returned by decFloatGetExponent */ | 1131 /* returned by decFloatGetExponent */ |
1064 /* returns df, which will be canonical */ | 1132 /* returns df, which will be canonical */ |
1065 /* */ | 1133 /* */ |
1066 /* No error is possible, but Overflow or Underflow might occur. */ | 1134 /* No error is possible, but Overflow or Underflow might occur. */ |
1067 /* ------------------------------------------------------------------ */ | 1135 /* ------------------------------------------------------------------ */ |
1068 decFloat * decFloatSetExponent(decFloat *df, decContext *set, Int exp) { | 1136 decFloat * decFloatSetExponent(decFloat *df, decContext *set, Int exp) { |
1069 uByte bcdcopy[DECPMAX]; /* for coefficient */ | 1137 uByte bcdcopy[DECPMAX]; /* for coefficient */ |
1070 bcdnum num; /* work */ | 1138 bcdnum num; /* work */ |
1071 num.exponent=exp; | 1139 num.exponent=exp; |
1072 num.sign=decFloatGetCoefficient(df, bcdcopy); /* extract coefficient */ | 1140 num.sign=decFloatGetCoefficient(df, bcdcopy); /* extract coefficient */ |
1073 if (DFISSPECIAL(df)) { /* MSD or more needs correcting */ | 1141 if (DFISSPECIAL(df)) { /* MSD or more needs correcting */ |
1074 if (DFISINF(df)) memset(bcdcopy, 0, DECPMAX); | 1142 if (DFISINF(df)) memset(bcdcopy, 0, DECPMAX); |
1089 return 10; | 1157 return 10; |
1090 } /* decFloatRadix */ | 1158 } /* decFloatRadix */ |
1091 | 1159 |
1092 #if (DECCHECK || DECTRACE) | 1160 #if (DECCHECK || DECTRACE) |
1093 /* ------------------------------------------------------------------ */ | 1161 /* ------------------------------------------------------------------ */ |
1094 /* decFloatShow -- printf a decFloat in hexadecimal and decimal */ | 1162 /* decFloatShow -- printf a decFloat in hexadecimal and decimal */ |
1095 /* df is the decFloat to show */ | 1163 /* df is the decFloat to show */ |
1096 /* tag is a tag string displayed with the number */ | 1164 /* tag is a tag string displayed with the number */ |
1097 /* */ | 1165 /* */ |
1098 /* This is a debug aid; the precise format of the string may change. */ | 1166 /* This is a debug aid; the precise format of the string may change. */ |
1099 /* ------------------------------------------------------------------ */ | 1167 /* ------------------------------------------------------------------ */ |
1100 void decFloatShow(const decFloat *df, const char *tag) { | 1168 void decFloatShow(const decFloat *df, const char *tag) { |
1101 char hexbuf[DECBYTES*2+DECBYTES/4+1]; /* NB blank after every fourth */ | 1169 char hexbuf[DECBYTES*2+DECBYTES/4+1]; /* NB blank after every fourth */ |
1102 char buff[DECSTRING]; /* for value in decimal */ | 1170 char buff[DECSTRING]; /* for value in decimal */ |
1103 Int i, j=0; | 1171 Int i, j=0; |
1104 | 1172 |
1105 for (i=0; i<DECBYTES; i++) { | 1173 for (i=0; i<DECBYTES; i++) { |
1106 #if DECLITEND | 1174 #if DECLITEND |
1107 sprintf(&hexbuf[j], "%02x", df->bytes[DECBYTES-1-i]); | 1175 sprintf(&hexbuf[j], "%02x", df->bytes[DECBYTES-1-i]); |
1121 /* ------------------------------------------------------------------ */ | 1189 /* ------------------------------------------------------------------ */ |
1122 /* decFloatToBCD -- get sign, exponent, and BCD8 from a decFloat */ | 1190 /* decFloatToBCD -- get sign, exponent, and BCD8 from a decFloat */ |
1123 /* */ | 1191 /* */ |
1124 /* df is the source decFloat */ | 1192 /* df is the source decFloat */ |
1125 /* exp will be set to the unbiased exponent, q, or to a special */ | 1193 /* exp will be set to the unbiased exponent, q, or to a special */ |
1126 /* value in the form returned by decFloatGetExponent */ | 1194 /* value in the form returned by decFloatGetExponent */ |
1127 /* bcdar is where DECPMAX bytes will be written, one BCD digit in */ | 1195 /* bcdar is where DECPMAX bytes will be written, one BCD digit in */ |
1128 /* each byte (BCD8 encoding); if df is a NaN the first byte will */ | 1196 /* each byte (BCD8 encoding); if df is a NaN the first byte will */ |
1129 /* be zero, and if it is infinite they will all be zero */ | 1197 /* be zero, and if it is infinite they will all be zero */ |
1130 /* returns the sign of the coefficient (DECFLOAT_Sign if negative, */ | 1198 /* returns the sign of the coefficient (DECFLOAT_Sign if negative, */ |
1131 /* 0 otherwise) */ | 1199 /* 0 otherwise) */ |
1151 } /* decFloatToBCD */ | 1219 } /* decFloatToBCD */ |
1152 | 1220 |
1153 /* ------------------------------------------------------------------ */ | 1221 /* ------------------------------------------------------------------ */ |
1154 /* decFloatToEngString -- conversion to numeric string, engineering */ | 1222 /* decFloatToEngString -- conversion to numeric string, engineering */ |
1155 /* */ | 1223 /* */ |
1156 /* df is the decFloat format number to convert */ | 1224 /* df is the decFloat format number to convert */ |
1157 /* string is the string where the result will be laid out */ | 1225 /* string is the string where the result will be laid out */ |
1158 /* */ | 1226 /* */ |
1159 /* string must be at least DECPMAX+9 characters (the worst case is */ | 1227 /* string must be at least DECPMAX+9 characters (the worst case is */ |
1160 /* "-0.00000nnn...nnn\0", which is as long as the exponent form when */ | 1228 /* "-0.00000nnn...nnn\0", which is as long as the exponent form when */ |
1161 /* DECEMAXD<=4); this condition is asserted above */ | 1229 /* DECEMAXD<=4); this condition is asserted above */ |
1164 /* ------------------------------------------------------------------ */ | 1232 /* ------------------------------------------------------------------ */ |
1165 char * decFloatToEngString(const decFloat *df, char *string){ | 1233 char * decFloatToEngString(const decFloat *df, char *string){ |
1166 uInt msd; /* coefficient MSD */ | 1234 uInt msd; /* coefficient MSD */ |
1167 Int exp; /* exponent top two bits or full */ | 1235 Int exp; /* exponent top two bits or full */ |
1168 uInt comb; /* combination field */ | 1236 uInt comb; /* combination field */ |
1169 char *cstart; /* coefficient start */ | 1237 char *cstart; /* coefficient start */ |
1170 char *c; /* output pointer in string */ | 1238 char *c; /* output pointer in string */ |
1171 char *s, *t; /* .. (source, target) */ | 1239 char *s, *t; /* .. (source, target) */ |
1172 Int pre, e; /* work */ | 1240 Int pre, e; /* work */ |
1173 const uByte *u; /* .. */ | 1241 const uByte *u; /* .. */ |
1242 uInt uiwork; /* for macros [one compiler needs */ | |
1243 /* volatile here to avoid bug, but */ | |
1244 /* that doubles execution time] */ | |
1174 | 1245 |
1175 /* Source words; macro handles endianness */ | 1246 /* Source words; macro handles endianness */ |
1176 uInt sourhi=DFWORD(df, 0); /* word with sign */ | 1247 uInt sourhi=DFWORD(df, 0); /* word with sign */ |
1177 #if DECPMAX==16 | 1248 #if DECPMAX==16 |
1178 uInt sourlo=DFWORD(df, 1); | 1249 uInt sourlo=DFWORD(df, 1); |
1183 #endif | 1254 #endif |
1184 | 1255 |
1185 c=string; /* where result will go */ | 1256 c=string; /* where result will go */ |
1186 if (((Int)sourhi)<0) *c++='-'; /* handle sign */ | 1257 if (((Int)sourhi)<0) *c++='-'; /* handle sign */ |
1187 comb=sourhi>>26; /* sign+combination field */ | 1258 comb=sourhi>>26; /* sign+combination field */ |
1188 msd=DECCOMBMSD[comb]; /* decode the combination field */ | 1259 msd=DECCOMBMSD[comb]; /* decode the combination field */ |
1189 exp=DECCOMBEXP[comb]; /* .. */ | 1260 exp=DECCOMBEXP[comb]; /* .. */ |
1190 | 1261 |
1191 if (EXPISSPECIAL(exp)) { /* special */ | 1262 if (EXPISSPECIAL(exp)) { /* special */ |
1192 if (exp==DECFLOAT_Inf) { /* infinity */ | 1263 if (exp==DECFLOAT_Inf) { /* infinity */ |
1193 strcpy(c, "Inf"); | 1264 strcpy(c, "Inf"); |
1194 strcpy(c+3, "inity"); | 1265 strcpy(c+3, "inity"); |
1195 return string; /* easy */ | 1266 return string; /* easy */ |
1196 } | 1267 } |
1197 if (sourhi&0x02000000) *c++='s'; /* sNaN */ | 1268 if (sourhi&0x02000000) *c++='s'; /* sNaN */ |
1198 strcpy(c, "NaN"); /* complete word */ | 1269 strcpy(c, "NaN"); /* complete word */ |
1220 /* Decode the declets. After extracting each declet, it is */ | 1291 /* Decode the declets. After extracting each declet, it is */ |
1221 /* decoded to a 4-uByte sequence by table lookup; the four uBytes */ | 1292 /* decoded to a 4-uByte sequence by table lookup; the four uBytes */ |
1222 /* are the three encoded BCD8 digits followed by a 1-byte length */ | 1293 /* are the three encoded BCD8 digits followed by a 1-byte length */ |
1223 /* (significant digits, except that 000 has length 0). This allows */ | 1294 /* (significant digits, except that 000 has length 0). This allows */ |
1224 /* us to left-align the first declet with non-zero content, then */ | 1295 /* us to left-align the first declet with non-zero content, then */ |
1225 /* the remaining ones are full 3-char length. Fixed-length copies */ | 1296 /* the remaining ones are full 3-char length. Fixed-length copies */ |
1226 /* are used because variable-length memcpy causes a subroutine call */ | 1297 /* are used because variable-length memcpy causes a subroutine call */ |
1227 /* in at least two compilers. (The copies are length 4 for speed */ | 1298 /* in at least two compilers. (The copies are length 4 for speed */ |
1228 /* and are safe because the last item in the array is of length */ | 1299 /* and are safe because the last item in the array is of length */ |
1229 /* three and has the length byte following.) */ | 1300 /* three and has the length byte following.) */ |
1230 #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \ | 1301 #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \ |
1231 if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;} \ | 1302 if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \ |
1232 else if (*(u+3)) { \ | 1303 else if (*(u+3)) { \ |
1233 UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; c+=*(u+3);} | 1304 UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);} |
1234 | 1305 |
1235 #if DECPMAX==7 | 1306 #if DECPMAX==7 |
1236 dpd2char(sourhi>>10); /* declet 1 */ | 1307 dpd2char(sourhi>>10); /* declet 1 */ |
1237 dpd2char(sourhi); /* declet 2 */ | 1308 dpd2char(sourhi); /* declet 2 */ |
1238 | 1309 |
1239 #elif DECPMAX==16 | 1310 #elif DECPMAX==16 |
1240 dpd2char(sourhi>>8); /* declet 1 */ | 1311 dpd2char(sourhi>>8); /* declet 1 */ |
1241 dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */ | 1312 dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */ |
1242 dpd2char(sourlo>>20); /* declet 3 */ | 1313 dpd2char(sourlo>>20); /* declet 3 */ |
1243 dpd2char(sourlo>>10); /* declet 4 */ | 1314 dpd2char(sourlo>>10); /* declet 4 */ |
1244 dpd2char(sourlo); /* declet 5 */ | 1315 dpd2char(sourlo); /* declet 5 */ |
1245 | 1316 |
1246 #elif DECPMAX==34 | 1317 #elif DECPMAX==34 |
1247 dpd2char(sourhi>>4); /* declet 1 */ | 1318 dpd2char(sourhi>>4); /* declet 1 */ |
1248 dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */ | 1319 dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */ |
1249 dpd2char(sourmh>>16); /* declet 3 */ | 1320 dpd2char(sourmh>>16); /* declet 3 */ |
1250 dpd2char(sourmh>>6); /* declet 4 */ | 1321 dpd2char(sourmh>>6); /* declet 4 */ |
1251 dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */ | 1322 dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */ |
1252 dpd2char(sourml>>18); /* declet 6 */ | 1323 dpd2char(sourml>>18); /* declet 6 */ |
1253 dpd2char(sourml>>8); /* declet 7 */ | 1324 dpd2char(sourml>>8); /* declet 7 */ |
1254 dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */ | 1325 dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */ |
1255 dpd2char(sourlo>>20); /* declet 9 */ | 1326 dpd2char(sourlo>>20); /* declet 9 */ |
1256 dpd2char(sourlo>>10); /* declet 10 */ | 1327 dpd2char(sourlo>>10); /* declet 10 */ |
1257 dpd2char(sourlo); /* declet 11 */ | 1328 dpd2char(sourlo); /* declet 11 */ |
1258 #endif | 1329 #endif |
1259 | 1330 |
1260 if (c==cstart) *c++='0'; /* all zeros, empty -- make "0" */ | 1331 if (c==cstart) *c++='0'; /* all zeros, empty -- make "0" */ |
1261 | 1332 |
1262 if (exp==0) { /* integer or NaN case -- easy */ | 1333 if (exp==0) { /* integer or NaN case -- easy */ |
1263 *c='\0'; /* terminate */ | 1334 *c='\0'; /* terminate */ |
1264 return string; | 1335 return string; |
1265 } | 1336 } |
1266 /* non-0 exponent */ | 1337 /* non-0 exponent */ |
1267 | 1338 |
1270 /* [here, pre-exp is the digits count (==1 for zero)] */ | 1341 /* [here, pre-exp is the digits count (==1 for zero)] */ |
1271 | 1342 |
1272 if (exp>0 || pre<-5) { /* need exponential form */ | 1343 if (exp>0 || pre<-5) { /* need exponential form */ |
1273 e=pre-1; /* calculate E value */ | 1344 e=pre-1; /* calculate E value */ |
1274 pre=1; /* assume one digit before '.' */ | 1345 pre=1; /* assume one digit before '.' */ |
1275 if (e!=0) { /* engineering: may need to adjust */ | 1346 if (e!=0) { /* engineering: may need to adjust */ |
1276 Int adj; /* adjustment */ | 1347 Int adj; /* adjustment */ |
1277 /* The C remainder operator is undefined for negative numbers, so */ | 1348 /* The C remainder operator is undefined for negative numbers, so */ |
1278 /* a positive remainder calculation must be used here */ | 1349 /* a positive remainder calculation must be used here */ |
1279 if (e<0) { | 1350 if (e<0) { |
1280 adj=(-e)%3; | 1351 adj=(-e)%3; |
1305 if (dotat<c) { /* if embedded dot needed... */ | 1376 if (dotat<c) { /* if embedded dot needed... */ |
1306 /* move by fours; there must be space for junk at the end */ | 1377 /* move by fours; there must be space for junk at the end */ |
1307 /* because there is still space for exponent */ | 1378 /* because there is still space for exponent */ |
1308 s=dotat+ROUNDDOWN4(c-dotat); /* source */ | 1379 s=dotat+ROUNDDOWN4(c-dotat); /* source */ |
1309 t=s+1; /* target */ | 1380 t=s+1; /* target */ |
1310 /* open the gap */ | 1381 /* open the gap [cannot use memcpy] */ |
1311 for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s); | 1382 for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s)); |
1312 *dotat='.'; | 1383 *dotat='.'; |
1313 c++; /* length increased by one */ | 1384 c++; /* length increased by one */ |
1314 } /* need dot? */ | 1385 } /* need dot? */ |
1315 else for (; c<dotat; c++) *c='0'; /* pad for engineering */ | 1386 else for (; c<dotat; c++) *c='0'; /* pad for engineering */ |
1316 } /* pre>0 */ | 1387 } /* pre>0 */ |
1317 else { | 1388 else { |
1318 /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (may have | 1389 /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (may have |
1319 E, but only for 0.00E+3 kind of case -- with plenty of spare | 1390 E, but only for 0.00E+3 kind of case -- with plenty of spare |
1320 space in this case */ | 1391 space in this case */ |
1321 pre=-pre+2; /* gap width, including "0." */ | 1392 pre=-pre+2; /* gap width, including "0." */ |
1322 t=cstart+ROUNDDOWN4(c-cstart)+pre; /* preferred first target point */ | 1393 t=cstart+ROUNDDOWN4(c-cstart)+pre; /* preferred first target point */ |
1323 /* backoff if too far to the right */ | 1394 /* backoff if too far to the right */ |
1324 if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */ | 1395 if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */ |
1325 /* now shift the entire coefficient to the right, being careful not */ | 1396 /* now shift the entire coefficient to the right, being careful not */ |
1326 /* to access to the left of string */ | 1397 /* to access to the left of string [cannot use memcpy] */ |
1327 for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(s); | 1398 for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s)); |
1328 /* for Quads and Singles there may be a character or two left... */ | 1399 /* for Quads and Singles there may be a character or two left... */ |
1329 s+=3; /* where next would come from */ | 1400 s+=3; /* where next would come from */ |
1330 for(; s>=cstart; s--, t--) *(t+3)=*(s); | 1401 for(; s>=cstart; s--, t--) *(t+3)=*(s); |
1331 /* now have fill 0. through 0.00000; use overlaps to avoid tests */ | 1402 /* now have fill 0. through 0.00000; use overlaps to avoid tests */ |
1332 if (pre>=4) { | 1403 if (pre>=4) { |
1333 UINTAT(cstart+pre-4)=UINTAT("0000"); | 1404 memcpy(cstart+pre-4, "0000", 4); |
1334 UINTAT(cstart)=UINTAT("0.00"); | 1405 memcpy(cstart, "0.00", 4); |
1335 } | 1406 } |
1336 else { /* 2 or 3 */ | 1407 else { /* 2 or 3 */ |
1337 *(cstart+pre-1)='0'; | 1408 *(cstart+pre-1)='0'; |
1338 USHORTAT(cstart)=USHORTAT("0."); | 1409 memcpy(cstart, "0.", 2); |
1339 } | 1410 } |
1340 c+=pre; /* to end */ | 1411 c+=pre; /* to end */ |
1341 } | 1412 } |
1342 | 1413 |
1343 /* finally add the E-part, if needed; it will never be 0, and has */ | 1414 /* finally add the E-part, if needed; it will never be 0, and has */ |
1344 /* a maximum length of 3 or 4 digits (asserted above) */ | 1415 /* a maximum length of 3 or 4 digits (asserted above) */ |
1345 if (e!=0) { | 1416 if (e!=0) { |
1346 USHORTAT(c)=USHORTAT("E+"); /* starts with E, assume + */ | 1417 memcpy(c, "E+", 2); /* starts with E, assume + */ |
1347 c++; | 1418 c++; |
1348 if (e<0) { | 1419 if (e<0) { |
1349 *c='-'; /* oops, need '-' */ | 1420 *c='-'; /* oops, need '-' */ |
1350 e=-e; /* uInt, please */ | 1421 e=-e; /* uInt, please */ |
1351 } | 1422 } |
1352 c++; | 1423 c++; |
1353 /* Three-character exponents are easy; 4-character a little trickier */ | 1424 /* Three-character exponents are easy; 4-character a little trickier */ |
1354 #if DECEMAXD<=3 | 1425 #if DECEMAXD<=3 |
1355 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ | 1426 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ |
1356 /* copy fixed 4 characters [is safe], starting at non-zero */ | 1427 /* copy fixed 4 characters [is safe], starting at non-zero */ |
1357 /* and with character mask to convert BCD to char */ | 1428 /* and with character mask to convert BCD to char */ |
1358 UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; | 1429 UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); |
1359 c+=*(u+3); /* bump pointer appropriately */ | 1430 c+=*(u+3); /* bump pointer appropriately */ |
1360 #elif DECEMAXD==4 | 1431 #elif DECEMAXD==4 |
1361 if (e<1000) { /* 3 (or fewer) digits case */ | 1432 if (e<1000) { /* 3 (or fewer) digits case */ |
1362 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ | 1433 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ |
1363 UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */ | 1434 UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */ |
1364 c+=*(u+3); /* bump pointer appropriately */ | 1435 c+=*(u+3); /* bump pointer appropriately */ |
1365 } | 1436 } |
1366 else { /* 4-digits */ | 1437 else { /* 4-digits */ |
1367 Int thou=((e>>3)*1049)>>17; /* e/1000 */ | 1438 Int thou=((e>>3)*1049)>>17; /* e/1000 */ |
1368 Int rem=e-(1000*thou); /* e%1000 */ | 1439 Int rem=e-(1000*thou); /* e%1000 */ |
1369 *c++=(char)('0'+(char)thou); /* the thousands digit */ | 1440 *c++=(char)('0'+(char)thou); /* the thousands digit */ |
1370 u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ | 1441 u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ |
1371 UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */ | 1442 UBFROMUI(c, UBTOUI(u)|CHARMASK);/* copy fixed 3+1 characters [is safe] */ |
1372 c+=3; /* bump pointer, always 3 digits */ | 1443 c+=3; /* bump pointer, always 3 digits */ |
1373 } | 1444 } |
1374 #endif | 1445 #endif |
1375 } | 1446 } |
1376 *c='\0'; /* terminate */ | 1447 *c='\0'; /* terminate */ |
1381 /* ------------------------------------------------------------------ */ | 1452 /* ------------------------------------------------------------------ */ |
1382 /* decFloatToPacked -- convert decFloat to Packed decimal + exponent */ | 1453 /* decFloatToPacked -- convert decFloat to Packed decimal + exponent */ |
1383 /* */ | 1454 /* */ |
1384 /* df is the source decFloat */ | 1455 /* df is the source decFloat */ |
1385 /* exp will be set to the unbiased exponent, q, or to a special */ | 1456 /* exp will be set to the unbiased exponent, q, or to a special */ |
1386 /* value in the form returned by decFloatGetExponent */ | 1457 /* value in the form returned by decFloatGetExponent */ |
1387 /* packed is where DECPMAX nibbles will be written with the sign as */ | 1458 /* packed is where DECPMAX nibbles will be written with the sign as */ |
1388 /* final nibble (0x0c for +, 0x0d for -); a NaN has a first nibble */ | 1459 /* final nibble (0x0c for +, 0x0d for -); a NaN has a first nibble */ |
1389 /* of zero, and an infinity is all zeros. decDouble and decQuad */ | 1460 /* of zero, and an infinity is all zeros. decDouble and decQuad */ |
1390 /* have a additional leading zero nibble, leading to result */ | 1461 /* have a additional leading zero nibble, leading to result */ |
1391 /* lengths of 4, 9, and 18 bytes. */ | 1462 /* lengths of 4, 9, and 18 bytes. */ |
1427 } /* decFloatToPacked */ | 1498 } /* decFloatToPacked */ |
1428 | 1499 |
1429 /* ------------------------------------------------------------------ */ | 1500 /* ------------------------------------------------------------------ */ |
1430 /* decFloatToString -- conversion to numeric string */ | 1501 /* decFloatToString -- conversion to numeric string */ |
1431 /* */ | 1502 /* */ |
1432 /* df is the decFloat format number to convert */ | 1503 /* df is the decFloat format number to convert */ |
1433 /* string is the string where the result will be laid out */ | 1504 /* string is the string where the result will be laid out */ |
1434 /* */ | 1505 /* */ |
1435 /* string must be at least DECPMAX+9 characters (the worst case is */ | 1506 /* string must be at least DECPMAX+9 characters (the worst case is */ |
1436 /* "-0.00000nnn...nnn\0", which is as long as the exponent form when */ | 1507 /* "-0.00000nnn...nnn\0", which is as long as the exponent form when */ |
1437 /* DECEMAXD<=4); this condition is asserted above */ | 1508 /* DECEMAXD<=4); this condition is asserted above */ |
1440 /* ------------------------------------------------------------------ */ | 1511 /* ------------------------------------------------------------------ */ |
1441 char * decFloatToString(const decFloat *df, char *string){ | 1512 char * decFloatToString(const decFloat *df, char *string){ |
1442 uInt msd; /* coefficient MSD */ | 1513 uInt msd; /* coefficient MSD */ |
1443 Int exp; /* exponent top two bits or full */ | 1514 Int exp; /* exponent top two bits or full */ |
1444 uInt comb; /* combination field */ | 1515 uInt comb; /* combination field */ |
1445 char *cstart; /* coefficient start */ | 1516 char *cstart; /* coefficient start */ |
1446 char *c; /* output pointer in string */ | 1517 char *c; /* output pointer in string */ |
1447 char *s, *t; /* .. (source, target) */ | 1518 char *s, *t; /* .. (source, target) */ |
1448 Int pre, e; /* work */ | 1519 Int pre, e; /* work */ |
1449 const uByte *u; /* .. */ | 1520 const uByte *u; /* .. */ |
1521 uInt uiwork; /* for macros [one compiler needs */ | |
1522 /* volatile here to avoid bug, but */ | |
1523 /* that doubles execution time] */ | |
1450 | 1524 |
1451 /* Source words; macro handles endianness */ | 1525 /* Source words; macro handles endianness */ |
1452 uInt sourhi=DFWORD(df, 0); /* word with sign */ | 1526 uInt sourhi=DFWORD(df, 0); /* word with sign */ |
1453 #if DECPMAX==16 | 1527 #if DECPMAX==16 |
1454 uInt sourlo=DFWORD(df, 1); | 1528 uInt sourlo=DFWORD(df, 1); |
1459 #endif | 1533 #endif |
1460 | 1534 |
1461 c=string; /* where result will go */ | 1535 c=string; /* where result will go */ |
1462 if (((Int)sourhi)<0) *c++='-'; /* handle sign */ | 1536 if (((Int)sourhi)<0) *c++='-'; /* handle sign */ |
1463 comb=sourhi>>26; /* sign+combination field */ | 1537 comb=sourhi>>26; /* sign+combination field */ |
1464 msd=DECCOMBMSD[comb]; /* decode the combination field */ | 1538 msd=DECCOMBMSD[comb]; /* decode the combination field */ |
1465 exp=DECCOMBEXP[comb]; /* .. */ | 1539 exp=DECCOMBEXP[comb]; /* .. */ |
1466 | 1540 |
1467 if (EXPISSPECIAL(exp)) { /* special */ | 1541 if (!EXPISSPECIAL(exp)) { /* finite */ |
1542 /* complete exponent; top two bits are in place */ | |
1543 exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */ | |
1544 } | |
1545 else { /* IS special */ | |
1468 if (exp==DECFLOAT_Inf) { /* infinity */ | 1546 if (exp==DECFLOAT_Inf) { /* infinity */ |
1469 strcpy(c, "Infinity"); | 1547 strcpy(c, "Infinity"); |
1470 return string; /* easy */ | 1548 return string; /* easy */ |
1471 } | 1549 } |
1472 if (sourhi&0x02000000) *c++='s'; /* sNaN */ | 1550 if (sourhi&0x02000000) *c++='s'; /* sNaN */ |
1482 && (sourhi&0x00003fff)==0) return string; | 1560 && (sourhi&0x00003fff)==0) return string; |
1483 #endif | 1561 #endif |
1484 /* otherwise drop through to add integer; set correct exp etc. */ | 1562 /* otherwise drop through to add integer; set correct exp etc. */ |
1485 exp=0; msd=0; /* setup for following code */ | 1563 exp=0; msd=0; /* setup for following code */ |
1486 } | 1564 } |
1487 else { /* complete exponent; top two bits are in place */ | |
1488 exp+=GETECON(df)-DECBIAS; /* .. + continuation and unbias */ | |
1489 } | |
1490 | 1565 |
1491 /* convert the digits of the significand to characters */ | 1566 /* convert the digits of the significand to characters */ |
1492 cstart=c; /* save start of coefficient */ | 1567 cstart=c; /* save start of coefficient */ |
1493 if (msd) *c++=(char)('0'+(char)msd); /* non-zero most significant digit */ | 1568 if (msd) *c++=(char)('0'+(char)msd); /* non-zero most significant digit */ |
1494 | 1569 |
1495 /* Decode the declets. After extracting each declet, it is */ | 1570 /* Decode the declets. After extracting each declet, it is */ |
1496 /* decoded to a 4-uByte sequence by table lookup; the four uBytes */ | 1571 /* decoded to a 4-uByte sequence by table lookup; the four uBytes */ |
1497 /* are the three encoded BCD8 digits followed by a 1-byte length */ | 1572 /* are the three encoded BCD8 digits followed by a 1-byte length */ |
1498 /* (significant digits, except that 000 has length 0). This allows */ | 1573 /* (significant digits, except that 000 has length 0). This allows */ |
1499 /* us to left-align the first declet with non-zero content, then */ | 1574 /* us to left-align the first declet with non-zero content, then */ |
1500 /* the remaining ones are full 3-char length. Fixed-length copies */ | 1575 /* the remaining ones are full 3-char length. Fixed-length copies */ |
1501 /* are used because variable-length memcpy causes a subroutine call */ | 1576 /* are used because variable-length memcpy causes a subroutine call */ |
1502 /* in at least two compilers. (The copies are length 4 for speed */ | 1577 /* in at least two compilers. (The copies are length 4 for speed */ |
1503 /* and are safe because the last item in the array is of length */ | 1578 /* and are safe because the last item in the array is of length */ |
1504 /* three and has the length byte following.) */ | 1579 /* three and has the length byte following.) */ |
1505 #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \ | 1580 #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4]; \ |
1506 if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;} \ | 1581 if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \ |
1507 else if (*(u+3)) { \ | 1582 else if (*(u+3)) { \ |
1508 UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; c+=*(u+3);} | 1583 UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);} |
1509 | 1584 |
1510 #if DECPMAX==7 | 1585 #if DECPMAX==7 |
1511 dpd2char(sourhi>>10); /* declet 1 */ | 1586 dpd2char(sourhi>>10); /* declet 1 */ |
1512 dpd2char(sourhi); /* declet 2 */ | 1587 dpd2char(sourhi); /* declet 2 */ |
1513 | 1588 |
1514 #elif DECPMAX==16 | 1589 #elif DECPMAX==16 |
1515 dpd2char(sourhi>>8); /* declet 1 */ | 1590 dpd2char(sourhi>>8); /* declet 1 */ |
1516 dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */ | 1591 dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */ |
1517 dpd2char(sourlo>>20); /* declet 3 */ | 1592 dpd2char(sourlo>>20); /* declet 3 */ |
1518 dpd2char(sourlo>>10); /* declet 4 */ | 1593 dpd2char(sourlo>>10); /* declet 4 */ |
1519 dpd2char(sourlo); /* declet 5 */ | 1594 dpd2char(sourlo); /* declet 5 */ |
1520 | 1595 |
1521 #elif DECPMAX==34 | 1596 #elif DECPMAX==34 |
1522 dpd2char(sourhi>>4); /* declet 1 */ | 1597 dpd2char(sourhi>>4); /* declet 1 */ |
1523 dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */ | 1598 dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */ |
1524 dpd2char(sourmh>>16); /* declet 3 */ | 1599 dpd2char(sourmh>>16); /* declet 3 */ |
1525 dpd2char(sourmh>>6); /* declet 4 */ | 1600 dpd2char(sourmh>>6); /* declet 4 */ |
1526 dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */ | 1601 dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */ |
1527 dpd2char(sourml>>18); /* declet 6 */ | 1602 dpd2char(sourml>>18); /* declet 6 */ |
1528 dpd2char(sourml>>8); /* declet 7 */ | 1603 dpd2char(sourml>>8); /* declet 7 */ |
1529 dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */ | 1604 dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */ |
1530 dpd2char(sourlo>>20); /* declet 9 */ | 1605 dpd2char(sourlo>>20); /* declet 9 */ |
1531 dpd2char(sourlo>>10); /* declet 10 */ | 1606 dpd2char(sourlo>>10); /* declet 10 */ |
1532 dpd2char(sourlo); /* declet 11 */ | 1607 dpd2char(sourlo); /* declet 11 */ |
1533 #endif | 1608 #endif |
1534 | 1609 |
1535 if (c==cstart) *c++='0'; /* all zeros, empty -- make "0" */ | 1610 if (c==cstart) *c++='0'; /* all zeros, empty -- make "0" */ |
1536 | 1611 |
1551 | 1626 |
1552 /* modify the coefficient, adding 0s, '.', and E+nn as needed */ | 1627 /* modify the coefficient, adding 0s, '.', and E+nn as needed */ |
1553 if (pre>0) { /* ddd.ddd (plain), perhaps with E */ | 1628 if (pre>0) { /* ddd.ddd (plain), perhaps with E */ |
1554 char *dotat=cstart+pre; | 1629 char *dotat=cstart+pre; |
1555 if (dotat<c) { /* if embedded dot needed... */ | 1630 if (dotat<c) { /* if embedded dot needed... */ |
1631 /* [memmove is a disaster, here] */ | |
1556 /* move by fours; there must be space for junk at the end */ | 1632 /* move by fours; there must be space for junk at the end */ |
1557 /* because there is still space for exponent */ | 1633 /* because exponent is still possible */ |
1558 s=dotat+ROUNDDOWN4(c-dotat); /* source */ | 1634 s=dotat+ROUNDDOWN4(c-dotat); /* source */ |
1559 t=s+1; /* target */ | 1635 t=s+1; /* target */ |
1560 /* open the gap */ | 1636 /* open the gap [cannot use memcpy] */ |
1561 for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s); | 1637 for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s)); |
1562 *dotat='.'; | 1638 *dotat='.'; |
1563 c++; /* length increased by one */ | 1639 c++; /* length increased by one */ |
1564 } /* need dot? */ | 1640 } /* need dot? */ |
1565 | 1641 |
1566 /* finally add the E-part, if needed; it will never be 0, and has */ | 1642 /* finally add the E-part, if needed; it will never be 0, and has */ |
1567 /* a maximum length of 3 or 4 digits (asserted above) */ | 1643 /* a maximum length of 3 or 4 digits (asserted above) */ |
1568 if (e!=0) { | 1644 if (e!=0) { |
1569 USHORTAT(c)=USHORTAT("E+"); /* starts with E, assume + */ | 1645 memcpy(c, "E+", 2); /* starts with E, assume + */ |
1570 c++; | 1646 c++; |
1571 if (e<0) { | 1647 if (e<0) { |
1572 *c='-'; /* oops, need '-' */ | 1648 *c='-'; /* oops, need '-' */ |
1573 e=-e; /* uInt, please */ | 1649 e=-e; /* uInt, please */ |
1574 } | 1650 } |
1575 c++; | 1651 c++; |
1576 /* Three-character exponents are easy; 4-character a little trickier */ | 1652 /* Three-character exponents are easy; 4-character a little trickier */ |
1577 #if DECEMAXD<=3 | 1653 #if DECEMAXD<=3 |
1578 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ | 1654 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ |
1579 /* copy fixed 4 characters [is safe], starting at non-zero */ | 1655 /* copy fixed 4 characters [is safe], starting at non-zero */ |
1580 /* and with character mask to convert BCD to char */ | 1656 /* and with character mask to convert BCD to char */ |
1581 UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; | 1657 UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); |
1582 c+=*(u+3); /* bump pointer appropriately */ | 1658 c+=*(u+3); /* bump pointer appropriately */ |
1583 #elif DECEMAXD==4 | 1659 #elif DECEMAXD==4 |
1584 if (e<1000) { /* 3 (or fewer) digits case */ | 1660 if (e<1000) { /* 3 (or fewer) digits case */ |
1585 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ | 1661 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ |
1586 UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */ | 1662 UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */ |
1587 c+=*(u+3); /* bump pointer appropriately */ | 1663 c+=*(u+3); /* bump pointer appropriately */ |
1588 } | 1664 } |
1589 else { /* 4-digits */ | 1665 else { /* 4-digits */ |
1590 Int thou=((e>>3)*1049)>>17; /* e/1000 */ | 1666 Int thou=((e>>3)*1049)>>17; /* e/1000 */ |
1591 Int rem=e-(1000*thou); /* e%1000 */ | 1667 Int rem=e-(1000*thou); /* e%1000 */ |
1592 *c++=(char)('0'+(char)thou); /* the thousands digit */ | 1668 *c++=(char)('0'+(char)thou); /* the thousands digit */ |
1593 u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ | 1669 u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ |
1594 UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */ | 1670 UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */ |
1595 c+=3; /* bump pointer, always 3 digits */ | 1671 c+=3; /* bump pointer, always 3 digits */ |
1596 } | 1672 } |
1597 #endif | 1673 #endif |
1598 } | 1674 } |
1599 *c='\0'; /* add terminator */ | 1675 *c='\0'; /* add terminator */ |
1600 /*printf("res %s\n", string); */ | 1676 /*printf("res %s\n", string); */ |
1613 pre=-pre+2; /* gap width, including "0." */ | 1689 pre=-pre+2; /* gap width, including "0." */ |
1614 t=cstart+ROUNDDOWN4(c-cstart)+pre; /* preferred first target point */ | 1690 t=cstart+ROUNDDOWN4(c-cstart)+pre; /* preferred first target point */ |
1615 /* backoff if too far to the right */ | 1691 /* backoff if too far to the right */ |
1616 if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */ | 1692 if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */ |
1617 /* now shift the entire coefficient to the right, being careful not */ | 1693 /* now shift the entire coefficient to the right, being careful not */ |
1618 /* to access to the left of string */ | 1694 /* to access to the left of string [cannot use memcpy] */ |
1619 for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(s); | 1695 for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s)); |
1620 /* for Quads and Singles there may be a character or two left... */ | 1696 /* for Quads and Singles there may be a character or two left... */ |
1621 s+=3; /* where next would come from */ | 1697 s+=3; /* where next would come from */ |
1622 for(; s>=cstart; s--, t--) *(t+3)=*(s); | 1698 for(; s>=cstart; s--, t--) *(t+3)=*(s); |
1623 /* now have fill 0. through 0.00000; use overlaps to avoid tests */ | 1699 /* now have fill 0. through 0.00000; use overlaps to avoid tests */ |
1624 if (pre>=4) { | 1700 if (pre>=4) { |
1625 UINTAT(cstart+pre-4)=UINTAT("0000"); | 1701 memcpy(cstart+pre-4, "0000", 4); |
1626 UINTAT(cstart)=UINTAT("0.00"); | 1702 memcpy(cstart, "0.00", 4); |
1627 } | 1703 } |
1628 else { /* 2 or 3 */ | 1704 else { /* 2 or 3 */ |
1629 *(cstart+pre-1)='0'; | 1705 *(cstart+pre-1)='0'; |
1630 USHORTAT(cstart)=USHORTAT("0."); | 1706 memcpy(cstart, "0.", 2); |
1631 } | 1707 } |
1632 *(c+pre)='\0'; /* terminate */ | 1708 *(c+pre)='\0'; /* terminate */ |
1633 return string; | 1709 return string; |
1634 } /* decFloatToString */ | 1710 } /* decFloatToString */ |
1635 | 1711 |
1660 uInt exp=GETEXPUN(source)+DECWBIAS; /* get unbiased exponent and rebias */ | 1736 uInt exp=GETEXPUN(source)+DECWBIAS; /* get unbiased exponent and rebias */ |
1661 uInt code=(exp>>DECWECONL)<<29; /* set two bits of exp [msd=0] */ | 1737 uInt code=(exp>>DECWECONL)<<29; /* set two bits of exp [msd=0] */ |
1662 code|=(exp<<(32-6-DECWECONL)) & 0x03ffffff; /* add exponent continuation */ | 1738 code|=(exp<<(32-6-DECWECONL)) & 0x03ffffff; /* add exponent continuation */ |
1663 code|=DFWORD(source, 0)&0x80000000; /* add sign */ | 1739 code|=DFWORD(source, 0)&0x80000000; /* add sign */ |
1664 DFWWORD(wider, 0)=code; /* .. and place top word in wider */ | 1740 DFWWORD(wider, 0)=code; /* .. and place top word in wider */ |
1665 msd=GETMSD(source); /* get source coefficient MSD [0-9] */ | 1741 msd=GETMSD(source); /* get source coefficient MSD [0-9] */ |
1666 } | 1742 } |
1667 /* Copy the coefficient and clear any 'unused' words to left */ | 1743 /* Copy the coefficient and clear any 'unused' words to left */ |
1668 #if SINGLE | 1744 #if SINGLE |
1669 DFWWORD(wider, 1)=(DFWORD(source, 0)&0x000fffff)|(msd<<20); | 1745 DFWWORD(wider, 1)=(DFWORD(source, 0)&0x000fffff)|(msd<<20); |
1670 #elif DOUBLE | 1746 #elif DOUBLE |
1718 /* tag is a string to label the display */ | 1794 /* tag is a string to label the display */ |
1719 /* ---------------------------------------------------------------- */ | 1795 /* ---------------------------------------------------------------- */ |
1720 void decShowNum(const bcdnum *num, const char *tag) { | 1796 void decShowNum(const bcdnum *num, const char *tag) { |
1721 const char *csign="+"; /* sign character */ | 1797 const char *csign="+"; /* sign character */ |
1722 uByte *ub; /* work */ | 1798 uByte *ub; /* work */ |
1799 uInt uiwork; /* for macros */ | |
1723 if (num->sign==DECFLOAT_Sign) csign="-"; | 1800 if (num->sign==DECFLOAT_Sign) csign="-"; |
1724 | 1801 |
1725 printf(">%s> ", tag); | 1802 printf(">%s> ", tag); |
1726 if (num->exponent==DECFLOAT_Inf) printf("%sInfinity", csign); | 1803 if (num->exponent==DECFLOAT_Inf) printf("%sInfinity", csign); |
1727 else if (num->exponent==DECFLOAT_qNaN) printf("%sqNaN", csign); | 1804 else if (num->exponent==DECFLOAT_qNaN) printf("%sqNaN", csign); |
1742 #error Exponent form is too long for ShowNum to lay out | 1819 #error Exponent form is too long for ShowNum to lay out |
1743 #endif | 1820 #endif |
1744 if (e==0) *c++='0'; /* 0-length case */ | 1821 if (e==0) *c++='0'; /* 0-length case */ |
1745 else if (e<1000) { /* 3 (or fewer) digits case */ | 1822 else if (e<1000) { /* 3 (or fewer) digits case */ |
1746 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ | 1823 u=&BIN2BCD8[e*4]; /* -> 3 digits + length byte */ |
1747 UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */ | 1824 UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */ |
1748 c+=*(u+3); /* bump pointer appropriately */ | 1825 c+=*(u+3); /* bump pointer appropriately */ |
1749 } | 1826 } |
1750 else { /* 4-digits */ | 1827 else { /* 4-digits */ |
1751 Int thou=((e>>3)*1049)>>17; /* e/1000 */ | 1828 Int thou=((e>>3)*1049)>>17; /* e/1000 */ |
1752 Int rem=e-(1000*thou); /* e%1000 */ | 1829 Int rem=e-(1000*thou); /* e%1000 */ |
1753 *c++=(char)('0'+(char)thou); /* the thousands digit */ | 1830 *c++=(char)('0'+(char)thou); /* the thousands digit */ |
1754 u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ | 1831 u=&BIN2BCD8[rem*4]; /* -> 3 digits + length byte */ |
1755 UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */ | 1832 UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */ |
1756 c+=3; /* bump pointer, always 3 digits */ | 1833 c+=3; /* bump pointer, always 3 digits */ |
1757 } | 1834 } |
1758 *c='\0'; /* add terminator */ | 1835 *c='\0'; /* add terminator */ |
1759 printf("%7s c=%s", qbuf, csign); | 1836 printf("%7s c=%s", qbuf, csign); |
1760 } | 1837 } |