sc/inc/columnspanset.hxx | 2 sc/inc/matrixoperators.hxx | 7 - sc/inc/scmatrix.hxx | 21 +++- sc/qa/uitest/calc_tests6/tdf118638.py | 4 sc/source/core/data/columnspanset.cxx | 21 ---- sc/source/core/tool/interpr5.cxx | 4 sc/source/core/tool/interpr6.cxx | 160 ++++++++------------------------ sc/source/core/tool/matrixoperators.cxx | 19 --- sc/source/core/tool/scmatrix.cxx | 48 +++------ solenv/clang-format/excludelist | 1 10 files changed, 86 insertions(+), 201 deletions(-)
New commits: commit fd4df675dfe1012448285134082f61a0c03a7d15 Author: dante <dante19031...@gmail.com> AuthorDate: Sun Apr 25 12:20:58 2021 +0200 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Wed Apr 28 16:31:45 2021 +0200 tdf#137679 Use Kahan summation for scmatrix operations May also want implement Kahan sum in there: sc/source/core/tool/arraysumSSE2.cxx sc/source/core/inc/arraysumfunctor.hxx Under some conditions the sum of a pointer type vector may be perforemed by arraysumfunctor on NumericCellAccumulator. arraysumSSE2 implements part of it. This code has been left unmodified. Why the test has been modified: The error was: 238.89000000000001 != 238.89 | 17 th digit IEEE 754 double-precision has 53 log10(2) ≈ 15.955 digits. So it's just noise. Change-Id: I6f84826bf3875be4f444f5eb61854bc1f95769bb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114627 Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Tested-by: Jenkins diff --git a/sc/inc/columnspanset.hxx b/sc/inc/columnspanset.hxx index 570f99c10fb8..d889a4da67e4 100644 --- a/sc/inc/columnspanset.hxx +++ b/sc/inc/columnspanset.hxx @@ -80,7 +80,6 @@ public: virtual ~ColumnAction() = 0; virtual void startColumn(ScColumn* pCol) = 0; virtual void execute(SCROW nRow1, SCROW nRow2, bool bVal) = 0; - virtual void executeSum(SCROW, SCROW, bool, double& ) { return; } ; }; ColumnSpanSet(); @@ -162,7 +161,6 @@ public: RangeColumnSpanSet( const ScRange& spanRange ) : range( spanRange ) {} void executeColumnAction(ScDocument& rDoc, sc::ColumnSpanSet::ColumnAction& ac) const; - void executeColumnAction(ScDocument& rDoc, sc::ColumnSpanSet::ColumnAction& ac, double& fMem) const; private: ScRange range; }; diff --git a/sc/inc/matrixoperators.hxx b/sc/inc/matrixoperators.hxx index 540a38e93370..36fa1cabe3d6 100644 --- a/sc/inc/matrixoperators.hxx +++ b/sc/inc/matrixoperators.hxx @@ -11,6 +11,7 @@ #include <functional> +#include "math.hxx" namespace sc::op { @@ -35,19 +36,19 @@ using Op = Op_<std::function<void(double&, double)>>; struct Sum { static const double InitVal; - void operator()(double& rAccum, double fVal) const; + void operator()(KahanSum& rAccum, double fVal) const; }; struct SumSquare { static const double InitVal; - void operator()(double& rAccum, double fVal) const; + void operator()(KahanSum& rAccum, double fVal) const; }; struct Product { static const double InitVal; - void operator()(double& rAccum, double fVal) const; + void operator()(KahanSum& rAccum, double fVal) const; }; } diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx index 60587b23a5d1..2a1d9342499f 100644 --- a/sc/inc/scmatrix.hxx +++ b/sc/inc/scmatrix.hxx @@ -150,6 +150,21 @@ public: mfFirst(fFirst), mfRest(fRest), mnCount(nCount) {} }; + /** + * Version of IterateResult for using Kahan sum. + */ + struct KahanIterateResult + { + KahanSum maAccumulator; + size_t mnCount; + + KahanIterateResult(double fAccumulator, size_t nCount) + : maAccumulator(fAccumulator), mnCount(nCount) {} + + double get() { return maAccumulator.get(); } + }; + + /** Checks nC or nR for zero and uses GetElementsMax() whether a matrix of the size of nC*nR could be allocated. A zero size (both nC and nR zero) matrix is allowed for later resize. @@ -361,9 +376,9 @@ public: double Or() const ; // logical OR of all matrix values, or NAN double Xor() const ; // logical XOR of all matrix values, or NAN - IterateResult Sum( bool bTextAsZero, bool bIgnoreErrorValues = false ) const ; - IterateResult SumSquare( bool bTextAsZero, bool bIgnoreErrorValues = false ) const ; - IterateResult Product( bool bTextAsZero, bool bIgnoreErrorValues = false ) const ; + KahanIterateResult Sum( bool bTextAsZero, bool bIgnoreErrorValues = false ) const ; + KahanIterateResult SumSquare( bool bTextAsZero, bool bIgnoreErrorValues = false ) const ; + KahanIterateResult Product( bool bTextAsZero, bool bIgnoreErrorValues = false ) const ; size_t Count(bool bCountStrings, bool bCountErrors, bool bIgnoreEmptyStrings = false) const ; size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const ; size_t MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const ; diff --git a/sc/qa/uitest/calc_tests6/tdf118638.py b/sc/qa/uitest/calc_tests6/tdf118638.py index 2e1b704a82d9..cc5c97f34a30 100644 --- a/sc/qa/uitest/calc_tests6/tdf118638.py +++ b/sc/qa/uitest/calc_tests6/tdf118638.py @@ -47,8 +47,8 @@ class Subtotals(UITestCase): self.assertEqual(get_cell_by_position(document, 0, 0, 15).getString(), "5408 Sum") self.assertEqual(get_cell_by_position(document, 0, 0, 16).getString(), "Grand Sum") - self.assertEqual(get_cell_by_position(document, 0, 1, 15).getValue(), 238.89) - self.assertEqual(get_cell_by_position(document, 0, 1, 16).getValue(), 238.89) + self.assertEqual(round(get_cell_by_position(document, 0, 1, 15).getValue(),12), 238.89) + self.assertEqual(round(get_cell_by_position(document, 0, 1, 16).getValue(),12), 238.89) self.assertEqual(get_cell_by_position(document, 0, 1, 15).getString(), "$238.89") self.assertEqual(get_cell_by_position(document, 0, 1, 16).getString(), "$238.89") diff --git a/sc/source/core/data/columnspanset.cxx b/sc/source/core/data/columnspanset.cxx index fe9b55193d6f..b400cd651c5a 100644 --- a/sc/source/core/data/columnspanset.cxx +++ b/sc/source/core/data/columnspanset.cxx @@ -359,27 +359,6 @@ void RangeColumnSpanSet::executeColumnAction(ScDocument& rDoc, sc::ColumnSpanSet } } -void RangeColumnSpanSet::executeColumnAction(ScDocument& rDoc, sc::ColumnSpanSet::ColumnAction& ac, double& fMem) const -{ - for (SCTAB nTab = range.aStart.Tab(); nTab <= range.aEnd.Tab(); ++nTab) - { - ScTable* pTab = rDoc.FetchTable(nTab); - if (!pTab) - continue; - - SCCOL nEndCol = pTab->ClampToAllocatedColumns(range.aEnd.Col()); - for (SCCOL nCol = range.aStart.Col(); nCol <= nEndCol; ++nCol) - { - if (!rDoc.ValidCol(nCol)) - break; - - ScColumn& rColumn = pTab->aCol[nCol]; - ac.startColumn(&rColumn); - ac.executeSum( range.aStart.Row(), range.aEnd.Row(), true, fMem ); - } - } -} - } // namespace sc /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx index 4cf5d9ce4339..0fe64d647bfe 100644 --- a/sc/source/core/tool/interpr5.cxx +++ b/sc/source/core/tool/interpr5.cxx @@ -1871,9 +1871,7 @@ void ScInterpreter::ScSumXMY2() } else { - ScMatrix::IterateResult aRes = pResMat->SumSquare(false); - double fSum = aRes.mfFirst + aRes.mfRest; - PushDouble(fSum); + PushDouble(pResMat->SumSquare(false).get()); } } diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx index f506b9f04753..a48d7d3ad77b 100644 --- a/sc/source/core/tool/interpr6.cxx +++ b/sc/source/core/tool/interpr6.cxx @@ -207,12 +207,11 @@ namespace { class NumericCellAccumulator { - double mfFirst; - double mfRest; + KahanSum maSum; FormulaError mnError; public: - NumericCellAccumulator() : mfFirst(0.0), mfRest(0.0), mnError(FormulaError::NONE) {} + NumericCellAccumulator() : maSum(0.0), mnError(FormulaError::NONE) {} void operator() (const sc::CellStoreType::value_type& rNode, size_t nOffset, size_t nDataSize) { @@ -220,28 +219,13 @@ public: { case sc::element_type_numeric: { - const double *p = &sc::numeric_block::at(*rNode.data, nOffset); - size_t i = 0; - - // Store the first non-zero value in mfFirst (for some reason). - if (!mfFirst) - { - for (i = 0; i < nDataSize; ++i) - { - if (!mfFirst) - mfFirst = p[i]; - else - break; - } - } - p += i; - nDataSize -= i; if (nDataSize == 0) return; + const double *p = &sc::numeric_block::at(*rNode.data, nOffset); sc::ArraySumFunctor functor(p, nDataSize); - mfRest += functor(); + maSum += functor(); break; } @@ -267,10 +251,7 @@ public: return; } - if ( !mfFirst ) - mfFirst = fVal; - else - mfRest += fVal; + maSum += fVal; } } break; @@ -280,8 +261,7 @@ public: } FormulaError getError() const { return mnError; } - double getFirst() const { return mfFirst; } - double getRest() const { return mfRest; } + KahanSum getResult() const { return maSum; } }; class NumericCellCounter @@ -356,7 +336,7 @@ class FuncSum : public sc::ColumnSpanSet::ColumnAction const ScInterpreterContext& mrContext; sc::ColumnBlockConstPosition maPos; ScColumn* mpCol; - double mfSum; + KahanSum mfSum; FormulaError mnError; sal_uInt32 mnNumFmt; @@ -369,9 +349,7 @@ public: mpCol->InitBlockPosition(maPos); } - virtual void execute(SCROW, SCROW, bool) override {} - - virtual void executeSum(SCROW nRow1, SCROW nRow2, bool bVal, double& fMem ) override + virtual void execute(SCROW nRow1, SCROW nRow2, bool bVal) override { if (!bVal) return; @@ -385,19 +363,13 @@ public: if (mnError != FormulaError::NONE) return; - if ( fMem ) - mfSum += aFunc.getFirst() + aFunc.getRest(); - else - { - fMem = aFunc.getFirst(); - mfSum += aFunc.getRest(); - } + mfSum += aFunc.getResult(); mnNumFmt = mpCol->GetNumberFormat(mrContext, nRow2); }; FormulaError getError() const { return mnError; } - double getSum() const { return mfSum; } + KahanSum getSum() const { return mfSum; } sal_uInt32 getNumberFormat() const { return mnNumFmt; } }; @@ -405,7 +377,7 @@ public: static void IterateMatrix( const ScMatrixRef& pMat, ScIterFunc eFunc, bool bTextAsZero, SubtotalFlags nSubTotalFlags, - sal_uLong& rCount, SvNumFormatType& rFuncFmtType, double& fRes, double& fMem ) + sal_uLong& rCount, SvNumFormatType& rFuncFmtType, KahanSum& fRes ) { if (!pMat) return; @@ -417,24 +389,8 @@ static void IterateMatrix( case ifAVERAGE: case ifSUM: { - ScMatrix::IterateResult aRes = pMat->Sum(bTextAsZero, bIgnoreErrVal); - // If the first value is a NaN, it probably means it was an empty cell, - // and should be treated as zero. - if ( !std::isfinite(aRes.mfFirst) ) - { - sal_uInt32 nErr = reinterpret_cast< sal_math_Double * >(&aRes.mfFirst)->nan_parts.fraction_lo; - if (nErr & 0xffff0000) - { - aRes.mfFirst = 0; - } - } - if ( fMem ) - fRes += aRes.mfFirst + aRes.mfRest; - else - { - fMem = aRes.mfFirst; - fRes += aRes.mfRest; - } + ScMatrix::KahanIterateResult aRes = pMat->Sum(bTextAsZero, bIgnoreErrVal); + fRes += aRes.maAccumulator; rCount += aRes.mnCount; } break; @@ -447,17 +403,15 @@ static void IterateMatrix( break; case ifPRODUCT: { - ScMatrix::IterateResult aRes = pMat->Product(bTextAsZero, bIgnoreErrVal); - fRes *= aRes.mfFirst; - fRes *= aRes.mfRest; + ScMatrix::KahanIterateResult aRes = pMat->Product(bTextAsZero, bIgnoreErrVal); + fRes *= aRes.get(); rCount += aRes.mnCount; } break; case ifSUMSQ: { - ScMatrix::IterateResult aRes = pMat->SumSquare(bTextAsZero, bIgnoreErrVal); - fRes += aRes.mfFirst; - fRes += aRes.mfRest; + ScMatrix::KahanIterateResult aRes = pMat->SumSquare(bTextAsZero, bIgnoreErrVal); + fRes += aRes.maAccumulator; rCount += aRes.mnCount; } break; @@ -484,15 +438,12 @@ size_t ScInterpreter::GetRefListArrayMaxSize( short nParamCount ) return nSize; } -static double lcl_IterResult( ScIterFunc eFunc, double fRes, double fMem, sal_uLong nCount ) +static double lcl_IterResult( ScIterFunc eFunc, double fRes, sal_uLong nCount ) { switch( eFunc ) { - case ifSUM: - fRes = ::rtl::math::approxAdd( fRes, fMem ); - break; case ifAVERAGE: - fRes = sc::div( ::rtl::math::approxAdd( fRes, fMem ), nCount); + fRes = sc::div( fRes, nCount); break; case ifCOUNT2: case ifCOUNT: @@ -514,9 +465,8 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) const SCSIZE nMatRows = GetRefListArrayMaxSize( nParamCount); ScMatrixRef xResMat, xResCount; const double ResInitVal = (eFunc == ifPRODUCT) ? 1.0 : 0.0; - double fRes = ResInitVal; + KahanSum fRes = ResInitVal; double fVal = 0.0; - double fMem = 0.0; // first numeric value != 0.0 sal_uLong nCount = 0; ScAddress aAdr; ScRange aRange; @@ -584,12 +534,7 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) switch( eFunc ) { case ifAVERAGE: - case ifSUM: - if ( fMem ) - fRes += fVal; - else - fMem = fVal; - break; + case ifSUM: fRes += fVal; break; case ifSUMSQ: fRes += fVal * fVal; break; case ifPRODUCT: fRes *= fVal; break; default: ; // nothing @@ -636,12 +581,7 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) switch( eFunc ) { case ifAVERAGE: - case ifSUM: - if ( fMem ) - fRes += fVal; - else - fMem = fVal; - break; + case ifSUM: fRes += fVal; break; case ifSUMSQ: fRes += fVal * fVal; break; case ifPRODUCT: fRes *= fVal; break; case ifCOUNT: @@ -705,12 +645,7 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) switch( eFunc ) { case ifAVERAGE: - case ifSUM: - if ( fMem ) - fRes += fVal; - else - fMem = fVal; - break; + case ifSUM: fRes += fVal; break; case ifSUMSQ: fRes += fVal * fVal; break; case ifPRODUCT: fRes *= fVal; break; case ifCOUNT: @@ -738,11 +673,6 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) if (p && p->IsArrayResult()) { nRefArrayPos = nRefInList; - if ((eFunc == ifSUM || eFunc == ifAVERAGE) && fMem != 0.0) - { - fRes = rtl::math::approxAdd( fRes, fMem); - fMem = 0.0; - } // The "one value to all references of an array" seems to // be what Excel does if there are other types than just // arrays of references. @@ -751,7 +681,7 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) // Create and init all elements with current value. assert(nMatRows > 0); xResMat = GetNewMat( 1, nMatRows, true); - xResMat->FillDouble( fRes, 0,0, 0,nMatRows-1); + xResMat->FillDouble( fRes.get(), 0,0, 0,nMatRows-1); if (eFunc != ifSUM) { xResCount = GetNewMat( 1, nMatRows, true); @@ -775,9 +705,9 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) { double fVecRes = xResMat->GetDouble(0,i); if (eFunc == ifPRODUCT) - fVecRes *= fRes; + fVecRes *= fRes.get(); else - fVecRes += fRes; + fVecRes += fRes.get(); xResMat->PutDouble( fVecRes, 0,i); } } @@ -830,7 +760,7 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) if ( eFunc == ifSUM ) { FuncSum aAction(mrContext); - aSet.executeColumnAction( mrDoc, aAction, fMem ); + aSet.executeColumnAction( mrDoc, aAction ); FormulaError nErr = aAction.getError(); if ( nErr != FormulaError::NONE ) { @@ -874,10 +804,7 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) if ( nErr == FormulaError::NONE ) { SetError(nErr); - if ( fMem ) - fRes += fVal; - else - fMem = fVal; + fRes += fVal; nCount++; } } @@ -888,10 +815,7 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) do { SetError(nErr); - if ( fMem ) - fRes += fVal; - else - fMem = fVal; + fRes += fVal; nCount++; } while (aValIter.GetNext(fVal, nErr)); @@ -950,18 +874,13 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) if (nRefArrayPos != std::numeric_limits<size_t>::max()) { // Update vector element with current value. - if ((eFunc == ifSUM || eFunc == ifAVERAGE) && fMem != 0.0) - { - fRes = rtl::math::approxAdd( fRes, fMem); - fMem = 0.0; - } if (xResCount) xResCount->PutDouble( xResCount->GetDouble(0,nRefArrayPos) + nCount, 0,nRefArrayPos); double fVecRes = xResMat->GetDouble(0,nRefArrayPos); if (eFunc == ifPRODUCT) - fVecRes *= fRes; + fVecRes *= fRes.get(); else - fVecRes += fRes; + fVecRes += fRes.get(); xResMat->PutDouble( fVecRes, 0,nRefArrayPos); // Reset. fRes = ResInitVal; @@ -977,14 +896,14 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) if ( nGlobalError != FormulaError::NONE && !( mnSubTotalFlags & SubtotalFlags::IgnoreErrVal ) ) break; - IterateMatrix( pMat, eFunc, bTextAsZero, mnSubTotalFlags, nCount, nFuncFmtType, fRes, fMem ); + IterateMatrix( pMat, eFunc, bTextAsZero, mnSubTotalFlags, nCount, nFuncFmtType, fRes ); } break; case svMatrix : { ScMatrixRef pMat = PopMatrix(); - IterateMatrix( pMat, eFunc, bTextAsZero, mnSubTotalFlags, nCount, nFuncFmtType, fRes, fMem ); + IterateMatrix( pMat, eFunc, bTextAsZero, mnSubTotalFlags, nCount, nFuncFmtType, fRes ); } break; case svError: @@ -1021,17 +940,17 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) sal_uLong nVecCount = (xResCount ? nCount + xResCount->GetDouble(0,i) : nCount); double fVecRes = xResMat->GetDouble(0,i); if (eFunc == ifPRODUCT) - fVecRes *= fRes; + fVecRes *= fRes.get(); else - fVecRes += fRes; - fVecRes = lcl_IterResult( eFunc, fVecRes, fMem, nVecCount); + fVecRes += fRes.get(); + fVecRes = lcl_IterResult( eFunc, fVecRes, nVecCount); xResMat->PutDouble( fVecRes, 0,i); } PushMatrix( xResMat); } else { - PushDouble( lcl_IterResult( eFunc, fRes, fMem, nCount)); + PushDouble( lcl_IterResult( eFunc, fRes.get(), nCount)); } } @@ -1065,6 +984,11 @@ void ScInterpreter::ScCount2() IterateParameters( ifCOUNT2 ); } +/** + * The purpose of RAWSUBTRACT() is exactly to not apply any error correction, approximation etc. + * But use the "raw" IEEE 754 double subtraction. + * So no Kahan summation + */ void ScInterpreter::ScRawSubtract() { short nParamCount = GetByte(); diff --git a/sc/source/core/tool/matrixoperators.cxx b/sc/source/core/tool/matrixoperators.cxx index 31cf6d96b2df..e65d4d7c0dc2 100644 --- a/sc/source/core/tool/matrixoperators.cxx +++ b/sc/source/core/tool/matrixoperators.cxx @@ -9,30 +9,19 @@ #include <matrixoperators.hxx> - -namespace sc::op { - -void Sum::operator()(double& rAccum, double fVal) const +namespace sc::op { - rAccum += fVal; -} +void Sum::operator()(KahanSum& rAccum, double fVal) const { rAccum += fVal; } const double Sum::InitVal = 0.0; -void SumSquare::operator()(double& rAccum, double fVal) const -{ - rAccum += fVal * fVal; -} +void SumSquare::operator()(KahanSum& rAccum, double fVal) const { rAccum += fVal * fVal; } const double SumSquare::InitVal = 0.0; -void Product::operator()(double& rAccum, double fVal) const -{ - rAccum *= fVal; -} +void Product::operator()(KahanSum& rAccum, double fVal) const { rAccum *= fVal; } const double Product::InitVal = 1.0; - } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx index ad7f4c788df7..a10863ea3a53 100644 --- a/sc/source/core/tool/scmatrix.cxx +++ b/sc/source/core/tool/scmatrix.cxx @@ -302,9 +302,9 @@ public: double Or() const; double Xor() const; - ScMatrix::IterateResult Sum( bool bTextAsZero, bool bIgnoreErrorValues ) const; - ScMatrix::IterateResult SumSquare( bool bTextAsZero, bool bIgnoreErrorValues ) const; - ScMatrix::IterateResult Product( bool bTextAsZero, bool bIgnoreErrorValues ) const; + ScMatrix::KahanIterateResult Sum( bool bTextAsZero, bool bIgnoreErrorValues ) const; + ScMatrix::KahanIterateResult SumSquare( bool bTextAsZero, bool bIgnoreErrorValues ) const; + ScMatrix::KahanIterateResult Product( bool bTextAsZero, bool bIgnoreErrorValues ) const; size_t Count(bool bCountStrings, bool bCountErrors, bool bIgnoreEmptyStrings) const; size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const; size_t MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const; @@ -1111,17 +1111,16 @@ template<typename Op> class WalkElementBlocks { Op maOp; - ScMatrix::IterateResult maRes; - bool mbFirst:1; + ScMatrix::KahanIterateResult maRes; bool mbTextAsZero:1; bool mbIgnoreErrorValues:1; public: WalkElementBlocks(bool bTextAsZero, bool bIgnoreErrorValues) : - maRes(Op::InitVal, Op::InitVal, 0), mbFirst(true), + maRes(Op::InitVal, 0), mbTextAsZero(bTextAsZero), mbIgnoreErrorValues(bIgnoreErrorValues) {} - const ScMatrix::IterateResult& getResult() const { return maRes; } + const ScMatrix::KahanIterateResult& getResult() const { return maRes; } void operator() (const MatrixImplType::element_block_node_type& node) { @@ -1141,16 +1140,7 @@ public: ++nIgnored; continue; } - - if (mbFirst) - { - maOp(maRes.mfFirst, *it); - mbFirst = false; - } - else - { - maOp(maRes.mfRest, *it); - } + maOp(maRes.maAccumulator, *it); } maRes.mnCount += node.size - nIgnored; } @@ -1163,15 +1153,7 @@ public: block_type::const_iterator itEnd = block_type::end(*node.data); for (; it != itEnd; ++it) { - if (mbFirst) - { - maOp(maRes.mfFirst, *it); - mbFirst = false; - } - else - { - maOp(maRes.mfRest, *it); - } + maOp(maRes.maAccumulator, *it); } maRes.mnCount += node.size; } @@ -2099,7 +2081,7 @@ public: namespace { template<typename TOp> -ScMatrix::IterateResult GetValueWithCount(bool bTextAsZero, bool bIgnoreErrorValues, const MatrixImplType& maMat) +ScMatrix::KahanIterateResult GetValueWithCount(bool bTextAsZero, bool bIgnoreErrorValues, const MatrixImplType& maMat) { WalkElementBlocks<TOp> aFunc(bTextAsZero, bIgnoreErrorValues); aFunc = maMat.walk(aFunc); @@ -2108,17 +2090,17 @@ ScMatrix::IterateResult GetValueWithCount(bool bTextAsZero, bool bIgnoreErrorVal } -ScMatrix::IterateResult ScMatrixImpl::Sum(bool bTextAsZero, bool bIgnoreErrorValues) const +ScMatrix::KahanIterateResult ScMatrixImpl::Sum(bool bTextAsZero, bool bIgnoreErrorValues) const { return GetValueWithCount<sc::op::Sum>(bTextAsZero, bIgnoreErrorValues, maMat); } -ScMatrix::IterateResult ScMatrixImpl::SumSquare(bool bTextAsZero, bool bIgnoreErrorValues) const +ScMatrix::KahanIterateResult ScMatrixImpl::SumSquare(bool bTextAsZero, bool bIgnoreErrorValues) const { return GetValueWithCount<sc::op::SumSquare>(bTextAsZero, bIgnoreErrorValues, maMat); } -ScMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero, bool bIgnoreErrorValues) const +ScMatrix::KahanIterateResult ScMatrixImpl::Product(bool bTextAsZero, bool bIgnoreErrorValues) const { return GetValueWithCount<sc::op::Product>(bTextAsZero, bIgnoreErrorValues, maMat); } @@ -3226,17 +3208,17 @@ double ScMatrix::Xor() const return pImpl->Xor(); } -ScMatrix::IterateResult ScMatrix::Sum(bool bTextAsZero, bool bIgnoreErrorValues) const +ScMatrix::KahanIterateResult ScMatrix::Sum(bool bTextAsZero, bool bIgnoreErrorValues) const { return pImpl->Sum(bTextAsZero, bIgnoreErrorValues); } -ScMatrix::IterateResult ScMatrix::SumSquare(bool bTextAsZero, bool bIgnoreErrorValues) const +ScMatrix::KahanIterateResult ScMatrix::SumSquare(bool bTextAsZero, bool bIgnoreErrorValues) const { return pImpl->SumSquare(bTextAsZero, bIgnoreErrorValues); } -ScMatrix::IterateResult ScMatrix::Product(bool bTextAsZero, bool bIgnoreErrorValues) const +ScMatrix::KahanIterateResult ScMatrix::Product(bool bTextAsZero, bool bIgnoreErrorValues) const { return pImpl->Product(bTextAsZero, bIgnoreErrorValues); } diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist index 99d83dcc8730..927c1ceb781a 100644 --- a/solenv/clang-format/excludelist +++ b/solenv/clang-format/excludelist @@ -8311,7 +8311,6 @@ sc/source/core/tool/interpr8.cxx sc/source/core/tool/jumpmatrix.cxx sc/source/core/tool/listenerquery.cxx sc/source/core/tool/lookupcache.cxx -sc/source/core/tool/matrixoperators.cxx sc/source/core/tool/navicfg.cxx sc/source/core/tool/numformat.cxx sc/source/core/tool/odffmap.cxx _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits