------------------------------------------------------------------ */ decCompareOp -- compare, min, or max two Numbers */ / This computes C = A ? B and carries out one of four operations: */ COMPARE -- returns the signum (as a number) giving the */ result of a comparison unless one or both */ operands is a NaN (in which case a NaN results) */ COMPSIG -- as COM
| 6000 | /* coefficient comparison if possible. */ |
| 6001 | /* ------------------------------------------------------------------ */ |
| 6002 | decNumber * decCompareOp(decNumber *res, const decNumber *lhs, |
| 6003 | const decNumber *rhs, decContext *set, |
| 6004 | Flag op, uInt *status) { |
| 6005 | #if DECSUBSET |
| 6006 | decNumber *alloclhs=NULL; // non-NULL if rounded lhs allocated |
| 6007 | decNumber *allocrhs=NULL; // .., rhs |
| 6008 | #endif |
| 6009 | Int result=0; // default result value |
| 6010 | uByte merged; // work |
| 6011 | |
| 6012 | #if DECCHECK |
| 6013 | if (decCheckOperands(res, lhs, rhs, set)) return res; |
| 6014 | #endif |
| 6015 | |
| 6016 | do { // protect allocated storage |
| 6017 | #if DECSUBSET |
| 6018 | if (!set->extended) { |
| 6019 | // reduce operands and set lostDigits status, as needed |
| 6020 | if (lhs->digits>set->digits) { |
| 6021 | alloclhs=decRoundOperand(lhs, set, status); |
| 6022 | if (alloclhs==NULL) {result=BADINT; break;} |
| 6023 | lhs=alloclhs; |
| 6024 | } |
| 6025 | if (rhs->digits>set->digits) { |
| 6026 | allocrhs=decRoundOperand(rhs, set, status); |
| 6027 | if (allocrhs==NULL) {result=BADINT; break;} |
| 6028 | rhs=allocrhs; |
| 6029 | } |
| 6030 | } |
| 6031 | #endif |
| 6032 | // [following code does not require input rounding] |
| 6033 | |
| 6034 | // If total ordering then handle differing signs 'up front' |
| 6035 | if (op==COMPTOTAL) { // total ordering |
| 6036 | if (decNumberIsNegative(lhs) & !decNumberIsNegative(rhs)) { |
| 6037 | result=-1; |
| 6038 | break; |
| 6039 | } |
| 6040 | if (!decNumberIsNegative(lhs) & decNumberIsNegative(rhs)) { |
| 6041 | result=+1; |
| 6042 | break; |
| 6043 | } |
| 6044 | } |
| 6045 | |
| 6046 | // handle NaNs specially; let infinities drop through |
| 6047 | // This assumes sNaN (even just one) leads to NaN. |
| 6048 | merged=(lhs->bits | rhs->bits) & (DECSNAN | DECNAN); |
| 6049 | if (merged) { // a NaN bit set |
| 6050 | if (op==COMPARE); // result will be NaN |
| 6051 | else if (op==COMPSIG) // treat qNaN as sNaN |
| 6052 | *status|=DEC_Invalid_operation | DEC_sNaN; |
| 6053 | else if (op==COMPTOTAL) { // total ordering, always finite |
| 6054 | // signs are known to be the same; compute the ordering here |
| 6055 | // as if the signs are both positive, then invert for negatives |
| 6056 | if (!decNumberIsNaN(lhs)) result=-1; |
| 6057 | else if (!decNumberIsNaN(rhs)) result=+1; |
| 6058 | // here if both NaNs |
| 6059 | else if (decNumberIsSNaN(lhs) && decNumberIsQNaN(rhs)) result=-1; |
no test coverage detected