MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / decFinalize

Function decFinalize

extern/decNumber/decCommon.c:230–560  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

228#endif
229
230static 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]

Callers 3

decFloatFromStringFunction · 0.70
decFloatFromWiderFunction · 0.70
decFloatSetExponentFunction · 0.70

Calls 1

decFloatFromBCDFunction · 0.85

Tested by

no test coverage detected