------------------------------------------------------------------ */ 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
| 7270 | /* All fields are updated as required. */ |
| 7271 | /* ------------------------------------------------------------------ */ |
| 7272 | static 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 | } |
no test coverage detected