[Libreoffice-commits] core.git: sc/inc sc/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Thu Dec 13 10:43:18 UTC 2018


 sc/inc/subtotal.hxx              |    3 
 sc/source/core/tool/subtotal.cxx |  126 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 129 insertions(+)

New commits:
commit 9176dd1acdad9112df73268ad0a39d421c1307d4
Author:     Eike Rathke <erack at redhat.com>
AuthorDate: Wed Dec 12 15:18:23 2018 +0100
Commit:     Eike Rathke <erack at 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 <erack at 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;


More information about the Libreoffice-commits mailing list