MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / decFloatNextToward

Function decFloatNextToward

extern/decNumber/decBasic.c:2781–2831  ·  view source on GitHub ↗

------------------------------------------------------------------ */ 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

Source from the content-addressed store, hash-verified

2779/* number. */
2780/* ------------------------------------------------------------------ */
2781decFloat * 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 */

Callers

nothing calls this directly

Calls 7

decNumCompareFunction · 0.85
decFloatCopySignFunction · 0.85
decFloatZeroFunction · 0.85
decFloatFromStringFunction · 0.85
decFloatFMAFunction · 0.85
decFloatIsNormalFunction · 0.85
decNaNsFunction · 0.70

Tested by

no test coverage detected