sc/inc/subtotal.hxx | 3 sc/source/core/tool/subtotal.cxx | 126 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+)
New commits: commit 9176dd1acdad9112df73268ad0a39d421c1307d4 Author: Eike Rathke <er...@redhat.com> AuthorDate: Wed Dec 12 15:18:23 2018 +0100 Commit: Eike Rathke <er...@redhat.com> CommitDate: Thu Dec 13 11:43:04 2018 +0100 Introduce ScFunctionData::update() and getResult() ... to further replace code where that is explicitly done. Change-Id: I2d4065ee2c111a073b65bfc0e42e3479fbd9cf6e Reviewed-on: https://gerrit.libreoffice.org/65039 Tested-by: Jenkins Reviewed-by: Eike Rathke <er...@redhat.com> diff --git a/sc/inc/subtotal.hxx b/sc/inc/subtotal.hxx index 46f6fcc7693c..2fa9e717ad19 100644 --- a/sc/inc/subtotal.hxx +++ b/sc/inc/subtotal.hxx @@ -60,6 +60,9 @@ struct ScFunctionData // to calculate single functions ScFunctionData( ScSubTotalFunc eFn ) : eFunc(eFn), nVal(0.0), nCount(0), bError(false) {} + void update( double fNewVal ); + /// Check bError after (!) obtaining the result. + double getResult(); }; #endif diff --git a/sc/source/core/tool/subtotal.cxx b/sc/source/core/tool/subtotal.cxx index ec908b16eeec..ad657815b06c 100644 --- a/sc/source/core/tool/subtotal.cxx +++ b/sc/source/core/tool/subtotal.cxx @@ -62,6 +62,132 @@ bool SubTotal::SafeDiv(double& fVal1, double fVal2) return bOk; } +void ScFunctionData::update( double fNewVal ) +{ + if (bError) + return; + + switch (eFunc) + { + case SUBTOTAL_FUNC_SUM: + if (!SubTotal::SafePlus(nVal, fNewVal)) + bError = true; + break; + case SUBTOTAL_FUNC_PROD: + if (nCount == 0) // copy first value (nVal is initialized to 0) + { + nVal = fNewVal; + nCount = 1; // don't care about further count + } + else if (!SubTotal::SafeMult(nVal, fNewVal)) + bError = true; + break; + case SUBTOTAL_FUNC_CNT: + case SUBTOTAL_FUNC_CNT2: + ++nCount; + break; + case SUBTOTAL_FUNC_AVE: + if (!SubTotal::SafePlus(nVal, fNewVal)) + bError = true; + else + ++nCount; + break; + case SUBTOTAL_FUNC_MAX: + if (nCount == 0) // copy first value (nVal is initialized to 0) + { + nVal = fNewVal; + nCount = 1; // don't care about further count + } + else if (fNewVal > nVal) + nVal = fNewVal; + break; + case SUBTOTAL_FUNC_MIN: + if (nCount == 0) // copy first value (nVal is initialized to 0) + { + nVal = fNewVal; + nCount = 1; // don't care about further count + } + else if (fNewVal < nVal) + nVal = fNewVal; + break; + case SUBTOTAL_FUNC_VAR: + case SUBTOTAL_FUNC_STD: + case SUBTOTAL_FUNC_VARP: + case SUBTOTAL_FUNC_STDP: + maWelford.update( fNewVal); + break; + default: + // unhandled unknown + bError = true; + } +} + +double ScFunctionData::getResult() +{ + if (bError) + return 0.0; + + double fRet = 0.0; + switch (eFunc) + { + case SUBTOTAL_FUNC_CNT: + case SUBTOTAL_FUNC_CNT2: + fRet = nCount; + break; + case SUBTOTAL_FUNC_SUM: + case SUBTOTAL_FUNC_MAX: + case SUBTOTAL_FUNC_MIN: + // Note that nVal is 0.0 for MAX and MIN if nCount==0, that's also + // how it is defined in ODFF. + fRet = nVal; + break; + case SUBTOTAL_FUNC_PROD: + fRet = (nCount > 0) ? nVal : 0.0; + break; + case SUBTOTAL_FUNC_AVE: + if (nCount == 0) + bError = true; + else + fRet = nVal / nCount; + break; + case SUBTOTAL_FUNC_VAR: + case SUBTOTAL_FUNC_STD: + if (maWelford.getCount() < 2) + bError = true; + else + { + fRet = maWelford.getVarianceSample(); + if (fRet < 0.0) + bError = true; + else if (eFunc == SUBTOTAL_FUNC_STD) + fRet = sqrt( fRet); + } + break; + case SUBTOTAL_FUNC_VARP: + case SUBTOTAL_FUNC_STDP: + if (maWelford.getCount() < 1) + bError = true; + else if (maWelford.getCount() == 1) + fRet = 0.0; + else + { + fRet = maWelford.getVariancePopulation(); + if (fRet < 0.0) + bError = true; + else if (eFunc == SUBTOTAL_FUNC_STDP) + fRet = sqrt( fRet); + } + break; + default: + assert(!"unhandled unknown"); + bError = true; + break; + } + if (bError) + fRet = 0.0; + return fRet; +} + void WelfordRunner::update( double fVal ) { ++nCount; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits