sc/qa/unit/data/functions/statistical/fods/forecast.fods | 10 +- sc/source/core/tool/interpr3.cxx | 70 +++++++-------- 2 files changed, 38 insertions(+), 42 deletions(-)
New commits: commit 040451e19087d8cb8ff4376166ca8248f909a4e0 Author: dante <dante19031...@gmail.com> AuthorDate: Sat May 1 10:41:43 2021 +0200 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Mon May 3 13:53:58 2021 +0200 tdf#137679 Use Kahan summation for interpr3.cxx (1/2) Change-Id: I8b07af0ad71f2be5acc8a660b93a48b9db6728f9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114964 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/sc/qa/unit/data/functions/statistical/fods/forecast.fods b/sc/qa/unit/data/functions/statistical/fods/forecast.fods index 2ec105af4d80..aafec26860b6 100644 --- a/sc/qa/unit/data/functions/statistical/fods/forecast.fods +++ b/sc/qa/unit/data/functions/statistical/fods/forecast.fods @@ -4197,11 +4197,11 @@ <table:table-cell table:style-name="ce33"/> </table:table-row> <table:table-row table:style-name="ro7"> - <table:table-cell office:value-type="float" office:value="129.554682838848" calcext:value-type="float"> - <text:p>129.554682838848</text:p> + <table:table-cell office:value-type="float" office:value="129.554682838849" calcext:value-type="float"> + <text:p>129.554682838849</text:p> </table:table-cell> - <table:table-cell office:value-type="float" office:value="129.554682838848" calcext:value-type="float"> - <text:p>129.554682838848</text:p> + <table:table-cell office:value-type="float" office:value="129.554682838849" calcext:value-type="float"> + <text:p>129.554682838849</text:p> </table:table-cell> <table:table-cell table:style-name="ce16" table:formula="of:=ROUND([.A34];12)=ROUND([.B34];12)" office:value-type="boolean" office:boolean-value="true" calcext:value-type="boolean"> <text:p>TRUE</text:p> @@ -4950,4 +4950,4 @@ </table:named-expressions> </office:spreadsheet> </office:body> -</office:document> \ No newline at end of file +</office:document> diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx index 193a9ca4b553..d0cd61c0a228 100644 --- a/sc/source/core/tool/interpr3.cxx +++ b/sc/source/core/tool/interpr3.cxx @@ -2915,7 +2915,7 @@ void ScInterpreter::ScKurt() void ScInterpreter::ScHarMean() { short nParamCount = GetByte(); - double nVal = 0.0; + KahanSum nVal = 0.0; double nValCount = 0.0; ScAddress aAdr; ScRange aRange; @@ -3028,7 +3028,7 @@ void ScInterpreter::ScHarMean() } } if (nGlobalError == FormulaError::NONE) - PushDouble( nValCount / nVal ); + PushDouble( nValCount / nVal.get() ); else PushError( nGlobalError); } @@ -3036,7 +3036,7 @@ void ScInterpreter::ScHarMean() void ScInterpreter::ScGeoMean() { short nParamCount = GetByte(); - double nVal = 0.0; + KahanSum nVal = 0.0; double nValCount = 0.0; ScAddress aAdr; ScRange aRange; @@ -3200,7 +3200,7 @@ void ScInterpreter::ScGeoMean() } } if (nGlobalError == FormulaError::NONE) - PushDouble(exp(nVal / nValCount)); + PushDouble(exp(nVal.get() / nValCount)); else PushError( nGlobalError); } @@ -3846,10 +3846,10 @@ void ScInterpreter::ScTrimMean() nIndex--; nIndex /= 2; OSL_ENSURE(nIndex < nSize, "ScTrimMean: wrong index"); - double fSum = 0.0; + KahanSum fSum = 0.0; for (SCSIZE i = nIndex; i < nSize-nIndex; i++) fSum += aSortArray[i]; - PushDouble(fSum/static_cast<double>(nSize-2*nIndex)); + PushDouble(fSum.get()/static_cast<double>(nSize-2*nIndex)); } } @@ -4285,7 +4285,7 @@ void ScInterpreter::ScAveDev() return; sal_uInt16 SaveSP = sp; double nMiddle = 0.0; - double rVal = 0.0; + KahanSum rVal = 0.0; double rValCount = 0.0; ScAddress aAdr; ScRange aRange; @@ -4369,7 +4369,7 @@ void ScInterpreter::ScAveDev() PushError( nGlobalError); return; } - nMiddle = rVal / rValCount; + nMiddle = rVal.get() / rValCount; sp = SaveSP; rVal = 0.0; nParam = nParamCount; @@ -4398,7 +4398,7 @@ void ScInterpreter::ScAveDev() ScValueIterator aValIter( mrDoc, aRange, mnSubTotalFlags ); if (aValIter.GetFirst(nCellVal, nErr)) { - rVal += (fabs(nCellVal - nMiddle)); + rVal += fabs(nCellVal - nMiddle); while (aValIter.GetNext(nCellVal, nErr)) rVal += fabs(nCellVal - nMiddle); } @@ -4433,7 +4433,7 @@ void ScInterpreter::ScAveDev() default : SetError(FormulaError::IllegalParameter); break; } } - PushDouble(rVal / rValCount); + PushDouble(rVal.get() / rValCount); } void ScInterpreter::ScDevSq() @@ -4477,8 +4477,8 @@ void ScInterpreter::ScProbability() PushNA(); else { - double fSum = 0.0; - double fRes = 0.0; + KahanSum fSum = 0.0; + KahanSum fRes = 0.0; bool bStop = false; double fP, fW; for ( SCSIZE i = 0; i < nC1 && !bStop; i++ ) @@ -4502,10 +4502,10 @@ void ScInterpreter::ScProbability() SetError( FormulaError::IllegalArgument); } } - if (bStop || fabs(fSum -1.0) > 1.0E-7) + if (bStop || std::abs((fSum -1.0).get()) > 1.0E-7) PushNoValue(); else - PushDouble(fRes); + PushDouble(fRes.get()); } } } @@ -4667,8 +4667,8 @@ void ScInterpreter::CalculateSlopeIntercept(bool bSlope) } // #i78250# numerical stability improved double fCount = 0.0; - double fSumX = 0.0; - double fSumY = 0.0; + KahanSum fSumX = 0.0; + KahanSum fSumY = 0.0; for (SCSIZE i = 0; i < nC1; i++) { @@ -4676,10 +4676,8 @@ void ScInterpreter::CalculateSlopeIntercept(bool bSlope) { if (!pMat1->IsStringOrEmpty(i,j) && !pMat2->IsStringOrEmpty(i,j)) { - double fValX = pMat1->GetDouble(i,j); - double fValY = pMat2->GetDouble(i,j); - fSumX += fValX; - fSumY += fValY; + fSumX += pMat1->GetDouble(i,j); + fSumY += pMat2->GetDouble(i,j); fCount++; } } @@ -4688,10 +4686,10 @@ void ScInterpreter::CalculateSlopeIntercept(bool bSlope) PushNoValue(); else { - double fSumDeltaXDeltaY = 0.0; // sum of (ValX-MeanX)*(ValY-MeanY) - double fSumSqrDeltaX = 0.0; // sum of (ValX-MeanX)^2 - double fMeanX = fSumX / fCount; - double fMeanY = fSumY / fCount; + KahanSum fSumDeltaXDeltaY = 0.0; // sum of (ValX-MeanX)*(ValY-MeanY) + KahanSum fSumSqrDeltaX = 0.0; // sum of (ValX-MeanX)^2 + double fMeanX = fSumX.get() / fCount; + double fMeanY = fSumY.get() / fCount; for (SCSIZE i = 0; i < nC1; i++) { for (SCSIZE j = 0; j < nR1; j++) @@ -4710,9 +4708,9 @@ void ScInterpreter::CalculateSlopeIntercept(bool bSlope) else { if ( bSlope ) - PushDouble( fSumDeltaXDeltaY / fSumSqrDeltaX); + PushDouble( fSumDeltaXDeltaY.get() / fSumSqrDeltaX.get()); else - PushDouble( fMeanY - fSumDeltaXDeltaY / fSumSqrDeltaX * fMeanX); + PushDouble( fMeanY - fSumDeltaXDeltaY.get() / fSumSqrDeltaX.get() * fMeanX); } } } @@ -4750,8 +4748,8 @@ void ScInterpreter::ScForecast() double fVal = GetDouble(); // #i78250# numerical stability improved double fCount = 0.0; - double fSumX = 0.0; - double fSumY = 0.0; + KahanSum fSumX = 0.0; + KahanSum fSumY = 0.0; for (SCSIZE i = 0; i < nC1; i++) { @@ -4759,10 +4757,8 @@ void ScInterpreter::ScForecast() { if (!pMat1->IsStringOrEmpty(i,j) && !pMat2->IsStringOrEmpty(i,j)) { - double fValX = pMat1->GetDouble(i,j); - double fValY = pMat2->GetDouble(i,j); - fSumX += fValX; - fSumY += fValY; + fSumX += pMat1->GetDouble(i,j); + fSumY += pMat2->GetDouble(i,j); fCount++; } } @@ -4771,10 +4767,10 @@ void ScInterpreter::ScForecast() PushNoValue(); else { - double fSumDeltaXDeltaY = 0.0; // sum of (ValX-MeanX)*(ValY-MeanY) - double fSumSqrDeltaX = 0.0; // sum of (ValX-MeanX)^2 - double fMeanX = fSumX / fCount; - double fMeanY = fSumY / fCount; + KahanSum fSumDeltaXDeltaY = 0.0; // sum of (ValX-MeanX)*(ValY-MeanY) + KahanSum fSumSqrDeltaX = 0.0; // sum of (ValX-MeanX)^2 + double fMeanX = fSumX.get() / fCount; + double fMeanY = fSumY.get() / fCount; for (SCSIZE i = 0; i < nC1; i++) { for (SCSIZE j = 0; j < nR1; j++) @@ -4791,7 +4787,7 @@ void ScInterpreter::ScForecast() if (fSumSqrDeltaX == 0.0) PushError( FormulaError::DivisionByZero); else - PushDouble( fMeanY + fSumDeltaXDeltaY / fSumSqrDeltaX * (fVal - fMeanX)); + PushDouble( fMeanY + fSumDeltaXDeltaY.get() / fSumSqrDeltaX.get() * (fVal - fMeanX)); } } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits