------------------------------------------------------------------ */ decFloatCompareTotal -- compare two decFloats with total ordering */ / result gets the result of comparing dfl and dfr */ dfl is the first decFloat (lhs) */ dfr is the second decFloat (rhs) */ returns result, which may be -1, 0, or 1
| 1725 | /* returns result, which may be -1, 0, or 1 */ |
| 1726 | /* ------------------------------------------------------------------ */ |
| 1727 | decFloat * decFloatCompareTotal(decFloat *result, |
| 1728 | const decFloat *dfl, const decFloat *dfr) { |
| 1729 | Int comp; // work |
| 1730 | uInt uiwork; // for macros |
| 1731 | #if QUAD |
| 1732 | uShort uswork; // .. |
| 1733 | #endif |
| 1734 | if (DFISNAN(dfl) || DFISNAN(dfr)) { |
| 1735 | Int nanl, nanr; // work |
| 1736 | // morph NaNs to +/- 1 or 2, leave numbers as 0 |
| 1737 | nanl=DFISSNAN(dfl)+DFISQNAN(dfl)*2; // quiet > signalling |
| 1738 | if (DFISSIGNED(dfl)) nanl=-nanl; |
| 1739 | nanr=DFISSNAN(dfr)+DFISQNAN(dfr)*2; |
| 1740 | if (DFISSIGNED(dfr)) nanr=-nanr; |
| 1741 | if (nanl>nanr) comp=+1; |
| 1742 | else if (nanl<nanr) comp=-1; |
| 1743 | else { // NaNs are the same type and sign .. must compare payload |
| 1744 | // buffers need +2 for QUAD |
| 1745 | uByte bufl[DECPMAX+4]; // for LHS coefficient + foot |
| 1746 | uByte bufr[DECPMAX+4]; // for RHS coefficient + foot |
| 1747 | uByte *ub, *uc; // work |
| 1748 | Int sigl; // signum of LHS |
| 1749 | sigl=(DFISSIGNED(dfl) ? -1 : +1); |
| 1750 | |
| 1751 | // decode the coefficients |
| 1752 | // (shift both right two if Quad to make a multiple of four) |
| 1753 | #if QUAD |
| 1754 | UBFROMUS(bufl, 0); |
| 1755 | UBFROMUS(bufr, 0); |
| 1756 | #endif |
| 1757 | GETCOEFF(dfl, bufl+QUAD*2); // decode from decFloat |
| 1758 | GETCOEFF(dfr, bufr+QUAD*2); // .. |
| 1759 | // all multiples of four, here |
| 1760 | comp=0; // assume equal |
| 1761 | for (ub=bufl, uc=bufr; ub<bufl+DECPMAX+QUAD*2; ub+=4, uc+=4) { |
| 1762 | uInt ui=UBTOUI(ub); |
| 1763 | if (ui==UBTOUI(uc)) continue; // so far so same |
| 1764 | // about to find a winner; go by bytes in case little-endian |
| 1765 | for (;; ub++, uc++) { |
| 1766 | if (*ub==*uc) continue; |
| 1767 | if (*ub>*uc) comp=sigl; // difference found |
| 1768 | else comp=-sigl; // .. |
| 1769 | break; |
| 1770 | } |
| 1771 | } |
| 1772 | } // same NaN type and sign |
| 1773 | } |
| 1774 | else { |
| 1775 | // numeric comparison needed |
| 1776 | comp=decNumCompare(dfl, dfr, 1); // total ordering |
| 1777 | } |
| 1778 | decFloatZero(result); |
| 1779 | if (comp==0) return result; |
| 1780 | DFBYTE(result, DECBYTES-1)=0x01; // LSD=1 |
| 1781 | if (comp<0) DFBYTE(result, 0)|=0x80; // set sign bit |
| 1782 | return result; |
| 1783 | } // decFloatCompareTotal |
| 1784 |
no test coverage detected