------------------------------------------------------------------ */ decFloatNextToward -- next towards a decFloat */ / result gets the next decFloat */ dfl is the decFloat to start with */ dfr is the decFloat to move toward */ set is the context
| 2779 | /* number. */ |
| 2780 | /* ------------------------------------------------------------------ */ |
| 2781 | decFloat * decFloatNextToward(decFloat *result, |
| 2782 | const decFloat *dfl, const decFloat *dfr, |
| 2783 | decContext *set) { |
| 2784 | decFloat delta; // tiny increment or decrement |
| 2785 | decFloat pointone; // 1e-1 |
| 2786 | uInt savestat; // saves status |
| 2787 | enum rounding saveround; // .. and mode |
| 2788 | uInt deltatop; // top word for delta |
| 2789 | Int comp; // work |
| 2790 | |
| 2791 | if (DFISNAN(dfl) || DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set); |
| 2792 | // Both are numeric, so Invalid no longer a possibility |
| 2793 | comp=decNumCompare(dfl, dfr, 0); |
| 2794 | if (comp==0) return decFloatCopySign(result, dfl, dfr); // equal |
| 2795 | // unequal; do NextPlus or NextMinus but with different status rules |
| 2796 | |
| 2797 | if (comp<0) { // lhs<rhs, do NextPlus, see above for commentary |
| 2798 | if (DFISINF(dfl) && DFISSIGNED(dfl)) { // -Infinity special case |
| 2799 | DFSETNMAX(result); |
| 2800 | DFWORD(result, 0)|=DECFLOAT_Sign; |
| 2801 | return result; |
| 2802 | } |
| 2803 | saveround=set->round; // save mode |
| 2804 | set->round=DEC_ROUND_CEILING; // .. round towards +Infinity |
| 2805 | deltatop=0; // positive delta |
| 2806 | } |
| 2807 | else { // lhs>rhs, do NextMinus, see above for commentary |
| 2808 | if (DFISINF(dfl) && !DFISSIGNED(dfl)) { // +Infinity special case |
| 2809 | DFSETNMAX(result); |
| 2810 | return result; |
| 2811 | } |
| 2812 | saveround=set->round; // save mode |
| 2813 | set->round=DEC_ROUND_FLOOR; // .. round towards -Infinity |
| 2814 | deltatop=DECFLOAT_Sign; // negative delta |
| 2815 | } |
| 2816 | savestat=set->status; // save status |
| 2817 | // Here, Inexact is needed where appropriate (and hence Underflow, |
| 2818 | // etc.). Therefore the tiny delta which is otherwise |
| 2819 | // unrepresentable (see NextPlus and NextMinus) is constructed |
| 2820 | // using the multiplication of FMA. |
| 2821 | decFloatZero(&delta); // set up tiny delta |
| 2822 | DFWORD(&delta, DECWORDS-1)=1; // coefficient=1 |
| 2823 | DFWORD(&delta, 0)=deltatop; // Sign + biased exponent=0 |
| 2824 | decFloatFromString(&pointone, "1E-1", set); // set up multiplier |
| 2825 | decFloatFMA(result, &delta, &pointone, dfl, set); |
| 2826 | // [Delta is truly tiny, so no need to correct sign of zero] |
| 2827 | // use new status unless the result is normal |
| 2828 | if (decFloatIsNormal(result)) set->status=savestat; // else goes forward |
| 2829 | set->round=saveround; // restore mode |
| 2830 | return result; |
| 2831 | } // decFloatNextToward |
| 2832 | |
| 2833 | /* ------------------------------------------------------------------ */ |
| 2834 | /* decFloatOr -- logical digitwise OR of two decFloats */ |
nothing calls this directly
no test coverage detected