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

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Nov 30 21:14:46 UTC 2018


 sc/qa/unit/data/functions/statistical/fods/large.fods |   16 ++-
 sc/qa/unit/data/functions/statistical/fods/small.fods |   17 ++-
 sc/source/core/inc/interpre.hxx                       |    5 
 sc/source/core/tool/interpr3.cxx                      |   93 +++++++++++++++++-
 sc/source/core/tool/interpr5.cxx                      |   33 ++++--
 5 files changed, 141 insertions(+), 23 deletions(-)

New commits:
commit e4c2d0bb57ab8ea8f5c400d103d01376b8140f22
Author:     Takeshi Abe <tabe at fixedpoint.jp>
AuthorDate: Tue Nov 27 11:28:18 2018 +0900
Commit:     Eike Rathke <erack at redhat.com>
CommitDate: Fri Nov 30 22:14:17 2018 +0100

    i#32345 Support a matrix of rank argument for LARGE()/SMALL()
    
    This is a followup of e22ab5e6f6b0ea49231ca454a567133996306116.
    
    Change-Id: I7052e113173204f7cfcd40622f52c5d4e14b3aa9
    Reviewed-on: https://gerrit.libreoffice.org/64139
    Tested-by: Jenkins
    Reviewed-by: Eike Rathke <erack at redhat.com>

diff --git a/sc/qa/unit/data/functions/statistical/fods/large.fods b/sc/qa/unit/data/functions/statistical/fods/large.fods
index 6e701e71671f..d72e3bde9a20 100644
--- a/sc/qa/unit/data/functions/statistical/fods/large.fods
+++ b/sc/qa/unit/data/functions/statistical/fods/large.fods
@@ -4794,10 +4794,18 @@
      <table:table-cell table:number-columns-repeated="2"/>
     </table:table-row>
     <table:table-row table:style-name="ro8">
-     <table:table-cell table:style-name="ce10"/>
-     <table:table-cell/>
-     <table:table-cell table:style-name="ce17"/>
-     <table:table-cell table:style-name="ce22"/>
+     <table:table-cell table:style-name="ce11" table:formula="of:=MDETERM(LARGE([.I30:.I39];{1;2|3;4}))" office:value-type="float" office:value="-2" calcext:value-type="float">
+      <text:p>-2</text:p>
+     </table:table-cell>
+     <table:table-cell office:value-type="float" office:value="-2" calcext:value-type="float">
+      <text:p>-2</text:p>
+     </table:table-cell>
+     <table:table-cell table:style-name="ce16" table:formula="of:=ROUND([.A30];12)=ROUND([.B30];12)" office:value-type="boolean" office:boolean-value="true" calcext:value-type="boolean">
+      <text:p>TRUE</text:p>
+     </table:table-cell>
+     <table:table-cell table:style-name="ce22" table:formula="of:=FORMULA([.A30])" office:value-type="string" office:string-value="=MDETERM(LARGE(I30:I39,{1,2;3,4}))" calcext:value-type="string">
+      <text:p>=MDETERM(LARGE(I30:I39,{1,2;3,4}))</text:p>
+     </table:table-cell>
      <table:table-cell table:number-columns-repeated="4"/>
      <table:table-cell table:style-name="ce11" office:value-type="float" office:value="2" calcext:value-type="float">
       <text:p>2</text:p>
diff --git a/sc/qa/unit/data/functions/statistical/fods/small.fods b/sc/qa/unit/data/functions/statistical/fods/small.fods
index 94a6ae6344ef..549be5c7e187 100644
--- a/sc/qa/unit/data/functions/statistical/fods/small.fods
+++ b/sc/qa/unit/data/functions/statistical/fods/small.fods
@@ -4186,10 +4186,19 @@
      <table:table-cell table:style-name="ce27" table:number-columns-repeated="4"/>
      <table:table-cell table:number-columns-repeated="2"/>
     </table:table-row>
-    <table:table-row table:style-name="ro6">
-     <table:table-cell table:number-columns-repeated="2"/>
-     <table:table-cell table:style-name="ce28"/>
-     <table:table-cell table:style-name="ce32"/>
+    <table:table-row table:style-name="ro2">
+     <table:table-cell table:style-name="ce19" table:formula="of:=MDETERM(SMALL([.F1:.F11];{1;2|3;4}))" office:value-type="float" office:value="-13" calcext:value-type="float">
+      <text:p>-13</text:p>
+     </table:table-cell>
+     <table:table-cell office:value-type="float" office:value="-13" calcext:value-type="float">
+      <text:p>-13</text:p>
+     </table:table-cell>
+     <table:table-cell table:style-name="ce25" table:formula="of:=ROUND([.A13];12)=ROUND([.B13];12)" office:value-type="boolean" office:boolean-value="true" calcext:value-type="boolean">
+      <text:p>TRUE</text:p>
+     </table:table-cell>
+     <table:table-cell table:style-name="ce32" table:formula="of:=FORMULA([.A13])" office:value-type="string" office:string-value="=MDETERM(SMALL(F1:F11,{1,2;3,4}))" calcext:value-type="string">
+      <text:p>=MDETERM(SMALL(F1:F11,{1,2;3,4}))</text:p>
+     </table:table-cell>
      <table:table-cell table:number-columns-repeated="4"/>
      <table:table-cell office:value-type="float" office:value="900000012" calcext:value-type="float">
       <text:p>900000012</text:p>
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 7608098d53bb..b6c68dcdb264 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -175,6 +175,8 @@ public:
 
     ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR, bool bEmpty = false);
 
+    ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR, const std::vector<double>& rValues);
+
     enum VolatileType {
         VOLATILE,
         VOLATILE_MACRO,
@@ -225,6 +227,8 @@ private:
 
     VolatileType meVolatileType;
 
+    void MakeMatNew(ScMatrixRef& rMat, SCSIZE nC, SCSIZE nR);
+
     /// Merge global and document specific settings.
     void MergeCalcConfig();
 
@@ -934,6 +938,7 @@ private:
     void ScMedian();
     double GetMedian( ::std::vector<double> & rArray );
     double GetPercentileExclusive( ::std::vector<double> & rArray, double fPercentile );
+    std::vector<double> GetTopNumberArray( SCSIZE& rCol, SCSIZE& rRow );
     void GetNumberSequenceArray( sal_uInt8 nParamCount, ::std::vector<double>& rArray, bool bConvertTextInArray );
     void GetSortArray( sal_uInt8 nParamCount, ::std::vector<double>& rSortArray, ::std::vector<long>* pIndexOrder, bool bConvertTextInArray, bool bAllowEmptyArray );
     static void QuickSort(::std::vector<double>& rSortArray, ::std::vector<long>* pIndexOrder);
diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx
index ac980b7257da..f91d0037ddb5 100644
--- a/sc/source/core/tool/interpr3.cxx
+++ b/sc/source/core/tool/interpr3.cxx
@@ -3639,14 +3639,15 @@ void ScInterpreter::CalculateSmallLarge(bool bSmall)
     if ( !MustHaveParamCount( GetByte(), 2 )  )
         return;
 
-    std::vector<double> aArray;
-    GetNumberSequenceArray(1, aArray, false);
+    SCSIZE nCol = 0, nRow = 0;
+    auto aArray = GetTopNumberArray(nCol, nRow);
     auto aArraySize = aArray.size();
     if (aArraySize == 0 || nGlobalError != FormulaError::NONE)
     {
         PushNoValue();
         return;
     }
+    assert(aArraySize == nCol * nRow);
     for (double fArg : aArray)
     {
         double f = ::rtl::math::approxFloor(fArg);
@@ -3701,8 +3702,7 @@ void ScInterpreter::CalculateSmallLarge(bool bSmall)
         aArray.clear();
         for (SCSIZE n : aRankArray)
             aArray.push_back(aSortArray[bSmall ? n-1 : nSize-n]);
-        ScMatrixRef pResult = GetNewMat(1, aArraySize, true);
-        pResult->PutDoubleVector(aArray, 0, 0);
+        ScMatrixRef pResult = GetNewMat(nCol, nRow, aArray);
         PushMatrix(pResult);
     }
 }
@@ -3841,6 +3841,91 @@ void ScInterpreter::ScTrimMean()
     }
 }
 
+std::vector<double> ScInterpreter::GetTopNumberArray( SCSIZE& rCol, SCSIZE& rRow )
+{
+    std::vector<double> aArray;
+    switch (GetStackType())
+    {
+        case svDouble:
+            aArray.push_back(PopDouble());
+            rCol = rRow = 1;
+        break;
+        case svSingleRef:
+        {
+            ScAddress aAdr;
+            PopSingleRef(aAdr);
+            ScRefCellValue aCell(*pDok, aAdr);
+            if (aCell.hasNumeric())
+            {
+                aArray.push_back(GetCellValue(aAdr, aCell));
+                rCol = rRow = 1;
+            }
+        }
+        break;
+        case svDoubleRef:
+        {
+            ScRange aRange;
+            PopDoubleRef(aRange, true);
+            if (nGlobalError != FormulaError::NONE)
+                break;
+
+            // give up unless the start and end are in the same sheet
+            if (aRange.aStart.Tab() != aRange.aEnd.Tab())
+            {
+                SetError(FormulaError::IllegalParameter);
+                break;
+            }
+
+            // the range already is in order
+            assert(aRange.aStart.Col() <= aRange.aEnd.Col());
+            assert(aRange.aStart.Row() <= aRange.aEnd.Row());
+            rCol = aRange.aEnd.Col() - aRange.aStart.Col() + 1;
+            rRow = aRange.aEnd.Row() - aRange.aStart.Row() + 1;
+            aArray.reserve(rCol * rRow);
+
+            FormulaError nErr = FormulaError::NONE;
+            double fCellVal;
+            ScValueIterator aValIter(pDok, aRange, mnSubTotalFlags);
+            if (aValIter.GetFirst(fCellVal, nErr))
+            {
+                do
+                    aArray.push_back(fCellVal);
+                while (aValIter.GetNext(fCellVal, nErr) && nErr == FormulaError::NONE);
+            }
+            if (aArray.size() != rCol * rRow)
+            {
+                aArray.clear();
+                SetError(nErr);
+            }
+        }
+        break;
+        case svMatrix:
+        case svExternalSingleRef:
+        case svExternalDoubleRef:
+        {
+            ScMatrixRef pMat = GetMatrix();
+            if (!pMat)
+                break;
+
+            if (pMat->IsNumeric())
+            {
+                SCSIZE nCount = pMat->GetElementCount();
+                aArray.reserve(nCount);
+                for (SCSIZE i = 0; i < nCount; ++i)
+                    aArray.push_back(pMat->GetDouble(i));
+                pMat->GetDimensions(rCol, rRow);
+            }
+            else
+                SetError(FormulaError::IllegalParameter);
+        }
+        break;
+        default:
+            SetError(FormulaError::IllegalParameter);
+        break;
+    }
+    return aArray;
+}
+
 void ScInterpreter::GetNumberSequenceArray( sal_uInt8 nParamCount, vector<double>& rArray, bool bConvertTextInArray )
 {
     ScAddress aAdr;
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index c898d7a95057..db6500b067f1 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -281,25 +281,36 @@ void ScInterpreter:: ScLCM()
     }
 }
 
-ScMatrixRef ScInterpreter::GetNewMat(SCSIZE nC, SCSIZE nR, bool bEmpty)
+void ScInterpreter::MakeMatNew(ScMatrixRef& rMat, SCSIZE nC, SCSIZE nR)
 {
-    ScMatrixRef pMat;
-    if (bEmpty)
-        pMat = new ScMatrix(nC, nR);
-    else
-        pMat = new ScMatrix(nC, nR, 0.0);
-
-    pMat->SetErrorInterpreter( this);
+    rMat->SetErrorInterpreter( this);
     // A temporary matrix is mutable and ScMatrix::CloneIfConst() returns the
     // very matrix.
-    pMat->SetMutable();
+    rMat->SetMutable();
     SCSIZE nCols, nRows;
-    pMat->GetDimensions( nCols, nRows);
+    rMat->GetDimensions( nCols, nRows);
     if ( nCols != nC || nRows != nR )
     {   // arbitrary limit of elements exceeded
         SetError( FormulaError::MatrixSize);
-        pMat.reset();
+        rMat.reset();
     }
+}
+
+ScMatrixRef ScInterpreter::GetNewMat(SCSIZE nC, SCSIZE nR, bool bEmpty)
+{
+    ScMatrixRef pMat;
+    if (bEmpty)
+        pMat = new ScMatrix(nC, nR);
+    else
+        pMat = new ScMatrix(nC, nR, 0.0);
+    MakeMatNew(pMat, nC, nR);
+    return pMat;
+}
+
+ScMatrixRef ScInterpreter::GetNewMat(SCSIZE nC, SCSIZE nR, const std::vector<double>& rValues)
+{
+    ScMatrixRef pMat(new ScMatrix(nC, nR, rValues));
+    MakeMatNew(pMat, nC, nR);
     return pMat;
 }
 


More information about the Libreoffice-commits mailing list