------------------------------------------------------------------ */ decNumberNextToward -- next towards rhs */ / This computes C = A +/- infinitesimal, rounded towards */ +/-Infinity in the direction of B, as per 754-1985 nextafter */ modified during revision but dropped from 754-2008. */ / res is C, the result. C may be A or B.
| 1730 | /* This is a generalization of 754-1985 NextAfter. */ |
| 1731 | /* ------------------------------------------------------------------ */ |
| 1732 | decNumber * decNumberNextToward(decNumber *res, const decNumber *lhs, |
| 1733 | const decNumber *rhs, decContext *set) { |
| 1734 | decNumber dtiny; // constant |
| 1735 | decContext workset=*set; // work |
| 1736 | Int result; // .. |
| 1737 | uInt status=0; // accumulator |
| 1738 | #if DECCHECK |
| 1739 | if (decCheckOperands(res, lhs, rhs, set)) return res; |
| 1740 | #endif |
| 1741 | |
| 1742 | if (decNumberIsNaN(lhs) || decNumberIsNaN(rhs)) { |
| 1743 | decNaNs(res, lhs, rhs, set, &status); |
| 1744 | } |
| 1745 | else { // Is numeric, so no chance of sNaN Invalid, etc. |
| 1746 | result=decCompare(lhs, rhs, 0); // sign matters |
| 1747 | if (result==BADINT) status|=DEC_Insufficient_storage; // rare |
| 1748 | else { // valid compare |
| 1749 | if (result==0) decNumberCopySign(res, lhs, rhs); // easy |
| 1750 | else { // differ: need NextPlus or NextMinus |
| 1751 | uByte sub; // add or subtract |
| 1752 | if (result<0) { // lhs<rhs, do nextplus |
| 1753 | // -Infinity is the special case |
| 1754 | if ((lhs->bits&(DECINF|DECNEG))==(DECINF|DECNEG)) { |
| 1755 | decSetMaxValue(res, set); |
| 1756 | res->bits=DECNEG; // negative |
| 1757 | return res; // there is no status to set |
| 1758 | } |
| 1759 | workset.round=DEC_ROUND_CEILING; |
| 1760 | sub=0; // add, please |
| 1761 | } // plus |
| 1762 | else { // lhs>rhs, do nextminus |
| 1763 | // +Infinity is the special case |
| 1764 | if ((lhs->bits&(DECINF|DECNEG))==DECINF) { |
| 1765 | decSetMaxValue(res, set); |
| 1766 | return res; // there is no status to set |
| 1767 | } |
| 1768 | workset.round=DEC_ROUND_FLOOR; |
| 1769 | sub=DECNEG; // subtract, please |
| 1770 | } // minus |
| 1771 | decNumberZero(&dtiny); // start with 0 |
| 1772 | dtiny.lsu[0]=1; // make number that is .. |
| 1773 | dtiny.exponent=DEC_MIN_EMIN-1; // .. smaller than tiniest |
| 1774 | decAddOp(res, lhs, &dtiny, &workset, sub, &status); // + or - |
| 1775 | // turn off exceptions if the result is a normal number |
| 1776 | // (including Nmin), otherwise let all status through |
| 1777 | if (decNumberIsNormal(res, set)) status=0; |
| 1778 | } // unequal |
| 1779 | } // compare OK |
| 1780 | } // numeric |
| 1781 | if (status!=0) decStatus(res, status, set); |
| 1782 | return res; |
| 1783 | } // decNumberNextToward |
| 1784 | |
| 1785 | /* ------------------------------------------------------------------ */ |
| 1786 | /* decNumberOr -- OR two Numbers, digitwise */ |
nothing calls this directly
no test coverage detected