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

Function decFloatFMA

extern/decNumber/decBasic.c:1996–2263  ·  view source on GitHub ↗

------------------------------------------------------------------ */ decFloatFMA -- multiply and add three decFloats, fused */ / result gets the result of (dfl*dfr)+dff with a single rounding */ dfl is the first decFloat (lhs) */ dfr is the second decFloat (rhs) */ dff is the final decFloat (fhs)

Source from the content-addressed store, hash-verified

1994/* */
1995/* ------------------------------------------------------------------ */
1996decFloat * decFloatFMA(decFloat *result, const decFloat *dfl,
1997 const decFloat *dfr, const decFloat *dff,
1998 decContext *set) {
1999
2000 // The accumulator has the bytes needed for FiniteMultiply, plus
2001 // one byte to the left in case of carry, plus DECPMAX+2 to the
2002 // right for the final addition (up to full fhs + round & sticky)
2003 #define FMALEN (ROUNDUP4(1+ (DECPMAX9*18+1) +DECPMAX+2))
2004 uByte acc[FMALEN]; // for multiplied coefficient in BCD
2005 // .. and for final result
2006 bcdnum mul; // for multiplication result
2007 bcdnum fin; // for final operand, expanded
2008 uByte coe[ROUNDUP4(DECPMAX)]; // dff coefficient in BCD
2009 bcdnum *hi, *lo; // bcdnum with higher/lower exponent
2010 uInt diffsign; // non-zero if signs differ
2011 uInt hipad; // pad digit for hi if needed
2012 Int padding; // excess exponent
2013 uInt carry; // +1 for ten's complement and during add
2014 uByte *ub, *uh, *ul; // work
2015 uInt uiwork; // for macros
2016
2017 // handle all the special values [any special operand leads to a
2018 // special result]
2019 if (DFISSPECIAL(dfl) || DFISSPECIAL(dfr) || DFISSPECIAL(dff)) {
2020 decFloat proxy; // multiplication result proxy
2021 // NaNs are handled as usual, giving priority to sNaNs
2022 if (DFISSNAN(dfl) || DFISSNAN(dfr)) return decNaNs(result, dfl, dfr, set);
2023 if (DFISSNAN(dff)) return decNaNs(result, dff, NULL, set);
2024 if (DFISNAN(dfl) || DFISNAN(dfr)) return decNaNs(result, dfl, dfr, set);
2025 if (DFISNAN(dff)) return decNaNs(result, dff, NULL, set);
2026 // One or more of the three is infinite
2027 // infinity times zero is bad
2028 decFloatZero(&proxy);
2029 if (DFISINF(dfl)) {
2030 if (DFISZERO(dfr)) return decInvalid(result, set);
2031 decInfinity(&proxy, &proxy);
2032 }
2033 else if (DFISINF(dfr)) {
2034 if (DFISZERO(dfl)) return decInvalid(result, set);
2035 decInfinity(&proxy, &proxy);
2036 }
2037 // compute sign of multiplication and place in proxy
2038 DFWORD(&proxy, 0)|=(DFWORD(dfl, 0)^DFWORD(dfr, 0))&DECFLOAT_Sign;
2039 if (!DFISINF(dff)) return decFloatCopy(result, &proxy);
2040 // dff is Infinite
2041 if (!DFISINF(&proxy)) return decInfinity(result, dff);
2042 // both sides of addition are infinite; different sign is bad
2043 if ((DFWORD(dff, 0)&DECFLOAT_Sign)!=(DFWORD(&proxy, 0)&DECFLOAT_Sign))
2044 return decInvalid(result, set);
2045 return decFloatCopy(result, &proxy);
2046 }
2047
2048 /* Here when all operands are finite */
2049
2050 // First multiply dfl*dfr
2051 decFiniteMultiply(&mul, acc+1, dfl, dfr);
2052 // The multiply is complete, exact and unbounded, and described in
2053 // mul with the coefficient held in acc[1...]

Callers 2

decDivideFunction · 0.85
decFloatNextTowardFunction · 0.85

Calls 7

decFloatZeroFunction · 0.85
decInvalidFunction · 0.85
decInfinityFunction · 0.85
decFloatCopyFunction · 0.85
decFiniteMultiplyFunction · 0.85
decNaNsFunction · 0.70
decFinalizeFunction · 0.70

Tested by

no test coverage detected