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

Function decFinalize

extern/decNumber/decNumber.c:7272–7333  ·  view source on GitHub ↗

------------------------------------------------------------------ */ decFinalize -- final check, clamp, and round of a number */ / dn is the number */ set is the context */ residue is the rounding accumulator (as in decApplyRound) */ status is the status accumulator

Source from the content-addressed store, hash-verified

7270/* All fields are updated as required. */
7271/* ------------------------------------------------------------------ */
7272static void decFinalize(decNumber *dn, decContext *set, Int *residue,
7273 uInt *status) {
7274 Int shift; // shift needed if clamping
7275 Int tinyexp=set->emin-dn->digits+1; // precalculate subnormal boundary
7276
7277 // Must be careful, here, when checking the exponent as the
7278 // adjusted exponent could overflow 31 bits [because it may already
7279 // be up to twice the expected].
7280
7281 // First test for subnormal. This must be done before any final
7282 // round as the result could be rounded to Nmin or 0.
7283 if (dn->exponent<=tinyexp) { // prefilter
7284 Int comp;
7285 decNumber nmin;
7286 // A very nasty case here is dn == Nmin and residue<0
7287 if (dn->exponent<tinyexp) {
7288 // Go handle subnormals; this will apply round if needed.
7289 decSetSubnormal(dn, set, residue, status);
7290 return;
7291 }
7292 // Equals case: only subnormal if dn=Nmin and negative residue
7293 decNumberZero(&nmin);
7294 nmin.lsu[0]=1;
7295 nmin.exponent=set->emin;
7296 comp=decCompare(dn, &nmin, 1); // (signless compare)
7297 if (comp==BADINT) { // oops
7298 *status|=DEC_Insufficient_storage; // abandon...
7299 return;
7300 }
7301 if (*residue<0 && comp==0) { // neg residue and dn==Nmin
7302 decApplyRound(dn, set, *residue, status); // might force down
7303 decSetSubnormal(dn, set, residue, status);
7304 return;
7305 }
7306 }
7307
7308 // now apply any pending round (this could raise overflow).
7309 if (*residue!=0) decApplyRound(dn, set, *residue, status);
7310
7311 // Check for overflow [redundant in the 'rare' case] or clamp
7312 if (dn->exponent<=set->emax-set->digits+1) return; // neither needed
7313
7314
7315 // here when might have an overflow or clamp to do
7316 if (dn->exponent>set->emax-dn->digits+1) { // too big
7317 decSetOverflow(dn, set, status);
7318 return;
7319 }
7320 // here when the result is normal but in clamp range
7321 if (!set->clamp) return;
7322
7323 // here when need to apply the IEEE exponent clamp (fold-down)
7324 shift=dn->exponent-(set->emax-set->digits+1);
7325
7326 // shift coefficient (if non-zero)
7327 if (!ISZERO(dn)) {
7328 dn->digits=decShiftToMost(dn->lsu, dn->digits, shift);
7329 }

Callers 11

decNumberFromStringFunction · 0.70
decNumber.cFile · 0.70
decQuantizeOpFunction · 0.70
decFinishFunction · 0.70
decDivideFunction · 0.70
decFloatAddFunction · 0.70
decFloatFMAFunction · 0.70
decFloatMultiplyFunction · 0.70
decFloatReduceFunction · 0.70
decFloatRotateFunction · 0.70
decFloatShiftFunction · 0.70

Calls 5

decSetSubnormalFunction · 0.85
decCompareFunction · 0.85
decApplyRoundFunction · 0.85
decSetOverflowFunction · 0.85
decShiftToMostFunction · 0.85

Tested by

no test coverage detected