------------------------------------------------------------------ */ decQuantizeOp -- force exponent to requested value */ / This computes C = op(A, B), where op adjusts the coefficient */ of C (by rounding or shifting) such that the exponent (-scale) */ of C has the value B or matches the exponent of B. */ The numerical value of C will equal A, except for the
| 5827 | /* after the operation is guaranteed to be that requested. */ |
| 5828 | /* ------------------------------------------------------------------ */ |
| 5829 | static decNumber * decQuantizeOp(decNumber *res, const decNumber *lhs, |
| 5830 | const decNumber *rhs, decContext *set, |
| 5831 | Flag quant, uInt *status) { |
| 5832 | #if DECSUBSET |
| 5833 | decNumber *alloclhs=NULL; // non-NULL if rounded lhs allocated |
| 5834 | decNumber *allocrhs=NULL; // .., rhs |
| 5835 | #endif |
| 5836 | const decNumber *inrhs=rhs; // save original rhs |
| 5837 | Int reqdigits=set->digits; // requested DIGITS |
| 5838 | Int reqexp; // requested exponent [-scale] |
| 5839 | Int residue=0; // rounding residue |
| 5840 | Int etiny=set->emin-(reqdigits-1); |
| 5841 | |
| 5842 | #if DECCHECK |
| 5843 | if (decCheckOperands(res, lhs, rhs, set)) return res; |
| 5844 | #endif |
| 5845 | |
| 5846 | do { // protect allocated storage |
| 5847 | #if DECSUBSET |
| 5848 | if (!set->extended) { |
| 5849 | // reduce operands and set lostDigits status, as needed |
| 5850 | if (lhs->digits>reqdigits) { |
| 5851 | alloclhs=decRoundOperand(lhs, set, status); |
| 5852 | if (alloclhs==NULL) break; |
| 5853 | lhs=alloclhs; |
| 5854 | } |
| 5855 | if (rhs->digits>reqdigits) { // [this only checks lostDigits] |
| 5856 | allocrhs=decRoundOperand(rhs, set, status); |
| 5857 | if (allocrhs==NULL) break; |
| 5858 | rhs=allocrhs; |
| 5859 | } |
| 5860 | } |
| 5861 | #endif |
| 5862 | // [following code does not require input rounding] |
| 5863 | |
| 5864 | // Handle special values |
| 5865 | if (SPECIALARGS) { |
| 5866 | // NaNs get usual processing |
| 5867 | if (SPECIALARGS & (DECSNAN | DECNAN)) |
| 5868 | decNaNs(res, lhs, rhs, set, status); |
| 5869 | // one infinity but not both is bad |
| 5870 | else if ((lhs->bits ^ rhs->bits) & DECINF) |
| 5871 | *status|=DEC_Invalid_operation; |
| 5872 | // both infinity: return lhs |
| 5873 | else decNumberCopy(res, lhs); // [nop if in place] |
| 5874 | break; |
| 5875 | } |
| 5876 | |
| 5877 | // set requested exponent |
| 5878 | if (quant) reqexp=inrhs->exponent; // quantize -- match exponents |
| 5879 | else { // rescale -- use value of rhs |
| 5880 | // Original rhs must be an integer that fits and is in range, |
| 5881 | // which could be from -1999999997 to +999999999, thanks to |
| 5882 | // subnormals |
| 5883 | reqexp=decGetInt(inrhs); // [cannot fail] |
| 5884 | } |
| 5885 | |
| 5886 | #if DECSUBSET |
no test coverage detected