------------------------------------------------------------------ */ decApplyRound -- apply pending rounding to a number */ / dn is the number, with space for set->digits digits */ set is the context [for size and rounding mode] */ residue indicates pending rounding, being any accumulated */ guard and sticky information. It may be:
| 7066 | /* */ |
| 7067 | /* ------------------------------------------------------------------ */ |
| 7068 | static void decApplyRound(decNumber *dn, decContext *set, Int residue, |
| 7069 | uInt *status) { |
| 7070 | Int bump; // 1 if coefficient needs to be incremented |
| 7071 | // -1 if coefficient needs to be decremented |
| 7072 | |
| 7073 | if (residue==0) return; // nothing to apply |
| 7074 | |
| 7075 | bump=0; // assume a smooth ride |
| 7076 | |
| 7077 | // now decide whether, and how, to round, depending on mode |
| 7078 | switch (set->round) { |
| 7079 | case DEC_ROUND_05UP: { // round zero or five up (for reround) |
| 7080 | // This is the same as DEC_ROUND_DOWN unless there is a |
| 7081 | // positive residue and the lsd of dn is 0 or 5, in which case |
| 7082 | // it is bumped; when residue is <0, the number is therefore |
| 7083 | // bumped down unless the final digit was 1 or 6 (in which |
| 7084 | // case it is bumped down and then up -- a no-op) |
| 7085 | Int lsd5=*dn->lsu%5; // get lsd and quintate |
| 7086 | if (residue<0 && lsd5!=1) bump=-1; |
| 7087 | else if (residue>0 && lsd5==0) bump=1; |
| 7088 | // [bump==1 could be applied directly; use common path for clarity] |
| 7089 | break;} // r-05 |
| 7090 | |
| 7091 | case DEC_ROUND_DOWN: { |
| 7092 | // no change, except if negative residue |
| 7093 | if (residue<0) bump=-1; |
| 7094 | break;} // r-d |
| 7095 | |
| 7096 | case DEC_ROUND_HALF_DOWN: { |
| 7097 | if (residue>5) bump=1; |
| 7098 | break;} // r-h-d |
| 7099 | |
| 7100 | case DEC_ROUND_HALF_EVEN: { |
| 7101 | if (residue>5) bump=1; // >0.5 goes up |
| 7102 | else if (residue==5) { // exactly 0.5000... |
| 7103 | // 0.5 goes up iff [new] lsd is odd |
| 7104 | if (*dn->lsu & 0x01) bump=1; |
| 7105 | } |
| 7106 | break;} // r-h-e |
| 7107 | |
| 7108 | case DEC_ROUND_HALF_UP: { |
| 7109 | if (residue>=5) bump=1; |
| 7110 | break;} // r-h-u |
| 7111 | |
| 7112 | case DEC_ROUND_UP: { |
| 7113 | if (residue>0) bump=1; |
| 7114 | break;} // r-u |
| 7115 | |
| 7116 | case DEC_ROUND_CEILING: { |
| 7117 | // same as _UP for positive numbers, and as _DOWN for negatives |
| 7118 | // [negative residue cannot occur on 0] |
| 7119 | if (decNumberIsNegative(dn)) { |
| 7120 | if (residue<0) bump=-1; |
| 7121 | } |
| 7122 | else { |
| 7123 | if (residue>0) bump=1; |
| 7124 | } |
| 7125 | break;} // r-c |
no test coverage detected