| 228 | #endif |
| 229 | |
| 230 | static decFloat * decFinalize(decFloat *df, bcdnum *num, |
| 231 | decContext *set) { |
| 232 | uByte *ub; // work |
| 233 | uInt dpd; // .. |
| 234 | uInt uiwork; // for macros |
| 235 | uByte *umsd=num->msd; // local copy |
| 236 | uByte *ulsd=num->lsd; // .. |
| 237 | uInt encode; // encoding accumulator |
| 238 | Int length; // coefficient length |
| 239 | uByte buffer[ROUNDUP(DECPMAX+3, 4)]; // [+3 allows uInt padding] |
| 240 | |
| 241 | #if DECCHECK |
| 242 | Int clen=ulsd-umsd+1; |
| 243 | #if QUAD |
| 244 | #define COEXTRA 2 // extra-long coefficent |
| 245 | #else |
| 246 | #define COEXTRA 0 |
| 247 | #endif |
| 248 | if (clen<1 || clen>DECPMAX*3+2+COEXTRA) |
| 249 | printf("decFinalize: suspect coefficient [length=%ld]\n", (LI)clen); |
| 250 | if (num->sign!=0 && num->sign!=DECFLOAT_Sign) |
| 251 | printf("decFinalize: bad sign [%08lx]\n", (LI)num->sign); |
| 252 | if (!EXPISSPECIAL(num->exponent) |
| 253 | && (num->exponent>1999999999 || num->exponent<-1999999999)) |
| 254 | printf("decFinalize: improbable exponent [%ld]\n", (LI)num->exponent); |
| 255 | // decShowNum(num, "final"); |
| 256 | #endif |
| 257 | |
| 258 | // A special will have an 'exponent' which is very positive and a |
| 259 | // coefficient < DECPMAX |
| 260 | length=(uInt)(ulsd-umsd+1); // coefficient length |
| 261 | |
| 262 | if (!NUMISSPECIAL(num)) { |
| 263 | Int drop; // digits to be dropped |
| 264 | // skip leading insignificant zeros to calculate an exact length |
| 265 | // [this is quite expensive] |
| 266 | if (*umsd==0) { |
| 267 | for (; umsd+3<ulsd && UBTOUI(umsd)==0;) umsd+=4; |
| 268 | for (; *umsd==0 && umsd<ulsd;) umsd++; |
| 269 | length=ulsd-umsd+1; // recalculate |
| 270 | } |
| 271 | drop=MAXI(length-DECPMAX, DECQTINY-num->exponent); |
| 272 | // drop can now be > digits for bottom-clamp (subnormal) cases |
| 273 | if (drop>0) { // rounding needed |
| 274 | // (decFloatQuantize has very similar code to this, so any |
| 275 | // changes may need to be made there, too) |
| 276 | uByte *roundat; // -> re-round digit |
| 277 | uByte reround; // reround value |
| 278 | // printf("Rounding; drop=%ld\n", (LI)drop); |
| 279 | |
| 280 | num->exponent+=drop; // always update exponent |
| 281 | |
| 282 | // Three cases here: |
| 283 | // 1. new LSD is in coefficient (almost always) |
| 284 | // 2. new LSD is digit to left of coefficient (so MSD is |
| 285 | // round-for-reround digit) |
| 286 | // 3. new LSD is to left of case 2 (whole coefficient is sticky) |
| 287 | // [duplicate check-stickies code to save a test] |
no test coverage detected