sc/source/core/inc/arraysumfunctor.hxx | 22 ++++++++++++++++++++++ sc/source/core/tool/interpr6.cxx | 10 ++++++++++ sc/source/core/tool/scmatrix.cxx | 6 +++--- 3 files changed, 35 insertions(+), 3 deletions(-)
New commits: commit 85196f9b88bd9bbee6978781a7baae63f76e02db Author: Tor Lillqvist <[email protected]> Date: Fri Feb 5 14:58:11 2016 +0200 tdf#97587: Treat plain NaNs as zero in the software interpreter for SUM The NaNs that have been stored in the arrays by ScColumn::FetchVectorRefArray() and other code correspond to empty cells. For the purpose of SUM they should be treated as zero. Change-Id: I8ac0c8afdf71da415ed120f9f8f6d51a8b5edb15 diff --git a/sc/source/core/inc/arraysumfunctor.hxx b/sc/source/core/inc/arraysumfunctor.hxx index 200fdc6..b2d1216 100644 --- a/sc/source/core/inc/arraysumfunctor.hxx +++ b/sc/source/core/inc/arraysumfunctor.hxx @@ -12,6 +12,7 @@ #define INCLUDED_SC_SOURCE_CORE_INC_ARRAYSUMFUNCTOR_HXX #include <cstdint> +#include <rtl/math.hxx> #include <tools/cpuid.hxx> #if defined(LO_SSE2_AVAILABLE) @@ -65,6 +66,27 @@ public: for (; i < mnSize; ++i) fSum += mpArray[i]; + // If the sum is a NaN, some of the terms were empty cells, probably. + // Re-calculate, carefully + if (!rtl::math::isFinite(fSum)) + { + sal_uInt32 nErr = reinterpret_cast< sal_math_Double * >(&fSum)->nan_parts.fraction_lo; + if (nErr & 0xffff0000) + { + fSum = 0; + for (i = 0; i < mnSize; i++) + { + if (!rtl::math::isFinite(mpArray[i])) + { + nErr = reinterpret_cast< const sal_math_Double * >(&mpArray[i])->nan_parts.fraction_lo; + if (!(nErr & 0xffff0000)) + fSum += mpArray[i]; // Let errors encoded as NaNs propagate ??? + } + else + fSum += mpArray[i]; + } + } + } return fSum; } diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx index 5bf4533..e7e321b 100644 --- a/sc/source/core/tool/interpr6.cxx +++ b/sc/source/core/tool/interpr6.cxx @@ -412,6 +412,16 @@ void IterateMatrix( case ifSUM: { ScMatrix::IterateResult aRes = pMat->Sum(bTextAsZero); + // If the first value is a NaN, it probably means it was an empty cell, + // and should be treated as zero. + if ( !rtl::math::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 commit 68b18511dd4468d9705e94812869410a03922c2f Author: Tor Lillqvist <[email protected]> Date: Fri Feb 5 15:01:48 2016 +0200 tdf#97369: Use correct limits when SUMming in the software interpreter GetRefRowSize() is not what we want, but GetArrayLength(). I think. At least helps in the sample document. (Need a hard recalc after loading it, though, but I assume that is expected.) Change-Id: I21477ca83042a40a300bc033e4a8b74ab5fc3015 diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx index d3816b5..f5df7c3 100644 --- a/sc/source/core/tool/scmatrix.cxx +++ b/sc/source/core/tool/scmatrix.cxx @@ -3397,13 +3397,13 @@ ScMatrix::IterateResult ScVectorRefMatrix::Sum(bool bTextAsZero) const const std::vector<formula::VectorRefArray>& rArrays = mpToken->GetArrays(); size_t nDataSize = mnRowSize; - if (mnRowStart >= mpToken->GetRefRowSize()) + if (mnRowStart >= mpToken->GetArrayLength()) { return ScMatrix::IterateResult(0.0, 0.0, 0); } - else if (nDataSize > mpToken->GetRefRowSize() + mnRowStart) + else if (nDataSize > mpToken->GetArrayLength() + mnRowStart) { - nDataSize = mpToken->GetRefRowSize() - mnRowStart; + nDataSize = mpToken->GetArrayLength() - mnRowStart; } double mfFirst = 0.0; _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
