summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2014-06-13 14:16:11 +0200
committerKohei Yoshida <libreoffice@kohei.us>2014-06-13 13:38:40 +0000
commitd6c55b4b2c549f19fe5bb7ab06d823ae5eced5df (patch)
tree38256af630b0662b2e0b530dbb66148afa6de788
parent087ec3cb8e55cd207d4cb655dcffbff18e9fcd26 (diff)
resolved fdo#79978 propagate error through DoubleArray of matrix
Regression introduced with 83f77ab0661df992f241e5f9ecb1aa8f8eaeafec. Interpreter errors are transported using NaN coded doubles, using simple setNan()/isNan() to flag and ignore non-numeric values skips all error values. Change-Id: I0d3cb30262bc5ba7ee77e53a2bc45e56569fbc4b (cherry picked from commit a288bebbcec0b16e1ced09a601de5ffbb6b1bbe0) Reviewed-on: https://gerrit.libreoffice.org/9768 Reviewed-by: Kohei Yoshida <libreoffice@kohei.us> Tested-by: Kohei Yoshida <libreoffice@kohei.us>
-rw-r--r--include/formula/errorcodes.hxx4
-rw-r--r--sc/source/core/tool/interpr1.cxx2
-rw-r--r--sc/source/core/tool/interpr5.cxx16
-rw-r--r--sc/source/core/tool/scmatrix.cxx10
4 files changed, 24 insertions, 8 deletions
diff --git a/include/formula/errorcodes.hxx b/include/formula/errorcodes.hxx
index d178aec680bd..87dab2baa6ba 100644
--- a/include/formula/errorcodes.hxx
+++ b/include/formula/errorcodes.hxx
@@ -75,6 +75,10 @@ const sal_uInt16 errNotNumericString = 534;
// ScInterpreter internal: jump matrix already has a result at this position,
// do not overwrite in case of empty code path.
const sal_uInt16 errJumpMatHasResult = 535;
+// ScInterpreter internal: (matrix) element is not a numeric value, i.e.
+// string or empty, to be distinguished from the general errNoValue NAN and not
+// to be used as result.
+const sal_uInt16 errElementNaN = 536;
// Interpreter: NA() not available condition, not a real error
const sal_uInt16 NOTAVAILABLE = 0x7fff;
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 758ce156e057..a834488ee091 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -5615,7 +5615,7 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
continue;
fVal = *itMain;
- if (rtl::math::isNan(fVal))
+ if (GetDoubleErrorValue(fVal) == errElementNaN)
continue;
++fCount;
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index d8b97c03ed5f..6f1b9ba37df8 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -1598,13 +1598,25 @@ namespace {
class SumValues : std::unary_function<double, void>
{
double mfSum;
+ bool mbError;
public:
- SumValues() : mfSum(0.0) {}
+ SumValues() : mfSum(0.0), mbError(false) {}
void operator() (double f)
{
- if (!rtl::math::isNan(f))
+ if (mbError)
+ return;
+
+ sal_uInt16 nErr = GetDoubleErrorValue(f);
+ if (!nErr)
mfSum += f;
+ else if (nErr != errElementNaN)
+ {
+ // Propagate the first error encountered, ignore "this is not a
+ // number" elements.
+ mfSum = f;
+ mbError = true;
+ }
}
double getValue() const { return mfSum; }
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 3b2c42c2bb09..4f210a80bec4 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -1512,7 +1512,7 @@ public:
ToDoubleArray( size_t nSize, bool bEmptyAsZero ) :
maArray(nSize, 0.0), miPos(maArray.begin()), mbEmptyAsZero(bEmptyAsZero)
{
- rtl::math::setNan(&mfNaN);
+ mfNaN = CreateDoubleError( errElementNaN);
}
void operator() (const MatrixImplType::element_block_node_type& node)
@@ -1583,7 +1583,7 @@ class MergeDoubleArrayFunc : std::unary_function<MatrixImplType::element_block_t
public:
MergeDoubleArrayFunc(std::vector<double>& rArray) : mrArray(rArray), miPos(mrArray.begin())
{
- rtl::math::setNan(&mfNaN);
+ mfNaN = CreateDoubleError( errElementNaN);
}
void operator() (const MatrixImplType::element_block_node_type& node)
@@ -1599,7 +1599,7 @@ public:
numeric_element_block::const_iterator itEnd = numeric_element_block::end(*node.data);
for (; it != itEnd; ++it, ++miPos)
{
- if (rtl::math::isNan(*miPos))
+ if (GetDoubleErrorValue(*miPos) == errElementNaN)
continue;
*miPos = op(*miPos, *it);
@@ -1612,7 +1612,7 @@ public:
boolean_element_block::const_iterator itEnd = boolean_element_block::end(*node.data);
for (; it != itEnd; ++it, ++miPos)
{
- if (rtl::math::isNan(*miPos))
+ if (GetDoubleErrorValue(*miPos) == errElementNaN)
continue;
*miPos = op(*miPos, *it ? 1.0 : 0.0);
@@ -1630,7 +1630,7 @@ public:
// Empty element is equivalent of having a numeric value of 0.0.
for (size_t i = 0; i < node.size; ++i, ++miPos)
{
- if (rtl::math::isNan(*miPos))
+ if (GetDoubleErrorValue(*miPos) == errElementNaN)
continue;
*miPos = op(*miPos, 0.0);