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

Function decFloatShift

extern/decNumber/decBasic.c:3398–3445  ·  view source on GitHub ↗

------------------------------------------------------------------ */ decFloatShift -- shift the coefficient of a decFloat left or right */ / result gets the result of shifting dfl */ dfl is the source decFloat to shift */ dfr is the count of digits to shift, an integer (with q=0) */ set is the context

Source from the content-addressed store, hash-verified

3396/* operand is an sNaN. The result is canonical. */
3397/* ------------------------------------------------------------------ */
3398decFloat * decFloatShift(decFloat *result,
3399 const decFloat *dfl, const decFloat *dfr,
3400 decContext *set) {
3401 Int shift; // dfr as an Int
3402 uByte buf[DECPMAX*2]; // coefficient + padding
3403 uInt digits, savestat; // work
3404 bcdnum num; // ..
3405 uInt uiwork; // for macros
3406
3407 if (DFISNAN(dfl)||DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set);
3408 if (!DFISINT(dfr)) return decInvalid(result, set);
3409 digits=decFloatDigits(dfr); // calculate digits
3410 if (digits>2) return decInvalid(result, set); // definitely out of range
3411 shift=DPD2BIN[DFWORD(dfr, DECWORDS-1)&0x3ff]; // is in bottom declet
3412 if (shift>DECPMAX) return decInvalid(result, set); // too big
3413 // [from here on no error or status change is possible]
3414
3415 if (DFISINF(dfl)) return decInfinity(result, dfl); // canonical
3416 // handle no-shift and all-shift (clear to zero) cases
3417 if (shift==0) return decCanonical(result, dfl);
3418 if (shift==DECPMAX) { // zero with sign
3419 uByte sign=(uByte)(DFBYTE(dfl, 0)&0x80); // save sign bit
3420 decFloatZero(result); // make +0
3421 DFBYTE(result, 0)=(uByte)(DFBYTE(result, 0)|sign); // and set sign
3422 // [cannot safely use CopySign]
3423 return result;
3424 }
3425 // a real shift is needed: 0 < shift < DECPMAX
3426 num.sign=DFWORD(dfl, 0)&DECFLOAT_Sign;
3427 num.exponent=GETEXPUN(dfl);
3428 num.msd=buf;
3429 GETCOEFF(dfl, buf);
3430 if (DFISSIGNED(dfr)) { // shift right
3431 // edge cases are taken care of, so this is easy
3432 num.lsd=buf+DECPMAX-shift-1;
3433 }
3434 else { // shift left -- zero padding needed to right
3435 UBFROMUI(buf+DECPMAX, 0); // 8 will handle most cases
3436 UBFROMUI(buf+DECPMAX+4, 0); // ..
3437 if (shift>8) memset(buf+DECPMAX+8, 0, 8+QUAD*18); // all other cases
3438 num.msd+=shift;
3439 num.lsd=num.msd+DECPMAX-1;
3440 }
3441 savestat=set->status; // record
3442 decFinalize(result, &num, set);
3443 set->status=savestat; // restore
3444 return result;
3445 } // decFloatShift
3446
3447/* ------------------------------------------------------------------ */
3448/* decFloatSubtract -- subtract a decFloat from another */

Callers

nothing calls this directly

Calls 7

decInvalidFunction · 0.85
decFloatDigitsFunction · 0.85
decInfinityFunction · 0.85
decCanonicalFunction · 0.85
decFloatZeroFunction · 0.85
decNaNsFunction · 0.70
decFinalizeFunction · 0.70

Tested by

no test coverage detected