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

Winfried Donkers winfrieddonkers at libreoffice.org
Tue Jan 3 20:31:11 UTC 2017


 sc/source/core/inc/interpre.hxx  |    2 -
 sc/source/core/tool/interpr3.cxx |   60 ++++++++++++++++-----------------------
 sc/source/core/tool/interpr4.cxx |    4 +-
 3 files changed, 28 insertions(+), 38 deletions(-)

New commits:
commit 482db19e3c792892c536898408dd7da98265073a
Author: Winfried Donkers <winfrieddonkers at libreoffice.org>
Date:   Sat Dec 31 16:24:27 2016 +0100

    tdf#105019 fix POISSON/POISSON.DIST deficiencies.
    
    Apply constraint lambda > 0.
    For POISSON.DIST all 3 arguments are mandatory.
    
    Change-Id: Ica056a2b315c10f0a22dd105c121d8ce97ea1717
    Reviewed-on: https://gerrit.libreoffice.org/32538
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Eike Rathke <erack at redhat.com>

diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index b093fec..2a810ab 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -861,7 +861,7 @@ void ScGammaDist( bool bODFF );
 void ScGammaInv();
 void ScExpDist();
 void ScBinomDist();
-void ScPoissonDist();
+void ScPoissonDist( bool bODFF );
 void ScCombin();
 void ScCombinA();
 void ScPermut();
diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx
index 1b6a367..205e1aa 100644
--- a/sc/source/core/tool/interpr3.cxx
+++ b/sc/source/core/tool/interpr3.cxx
@@ -1765,61 +1765,51 @@ void ScInterpreter::ScWeibull()
     }
 }
 
-void ScInterpreter::ScPoissonDist()
+void ScInterpreter::ScPoissonDist( bool bODFF )
 {
     sal_uInt8 nParamCount = GetByte();
-    if ( MustHaveParamCount( nParamCount, 2, 3 ) )
+    if ( MustHaveParamCount( nParamCount, ( bODFF ? 2 : 3 ), 3 ) )
     {
-        bool bCumulative = nParamCount != 3 || GetBool(); // default cumulative
+        bool bCumulative = nParamCount != 3 || GetBool();         // default cumulative
         double lambda    = GetDouble();                           // Mean
         double x         = ::rtl::math::approxFloor(GetDouble()); // discrete distribution
-        if (lambda < 0.0 || x < 0.0)
+        if (lambda <= 0.0 || x < 0.0)
             PushIllegalArgument();
         else if (!bCumulative)                            // Probability mass function
         {
-            if (lambda == 0.0)
-                PushInt(0);
+            if (lambda >712.0)    // underflow in exp(-lambda)
+            {   // accuracy 11 Digits
+                PushDouble( exp(x*log(lambda)-lambda-GetLogGamma(x+1.0)));
+            }
             else
             {
-                if (lambda >712)    // underflow in exp(-lambda)
-                {   // accuracy 11 Digits
-                    PushDouble( exp(x*log(lambda)-lambda-GetLogGamma(x+1.0)));
-                }
-                else
-                {
-                    double fPoissonVar = 1.0;
-                    for ( double f = 0.0; f < x; ++f )
-                        fPoissonVar *= lambda / ( f + 1.0 );
-                    PushDouble( fPoissonVar * exp( -lambda ) );
-                }
+                double fPoissonVar = 1.0;
+                for ( double f = 0.0; f < x; ++f )
+                    fPoissonVar *= lambda / ( f + 1.0 );
+                PushDouble( fPoissonVar * exp( -lambda ) );
             }
         }
         else                                // Cumulative distribution function
         {
-            if (lambda == 0.0)
-                PushInt(1);
+            if (lambda > 712.0)  // underflow in exp(-lambda)
+            {   // accuracy 12 Digits
+                PushDouble(GetUpRegIGamma(x+1.0,lambda));
+            }
             else
             {
-                if (lambda > 712 )  // underflow in exp(-lambda)
-                {   // accuracy 12 Digits
-                    PushDouble(GetUpRegIGamma(x+1.0,lambda));
-                }
+                if (x >= 936.0) // result is always undistinghable from 1
+                    PushDouble (1.0);
                 else
                 {
-                    if (x >= 936.0) // result is always undistinghable from 1
-                        PushDouble (1.0);
-                    else
+                    double fSummand = exp(-lambda);
+                    double fSum = fSummand;
+                    int nEnd = sal::static_int_cast<int>( x );
+                    for (int i = 1; i <= nEnd; i++)
                     {
-                        double fSummand = exp(-lambda);
-                        double fSum = fSummand;
-                        int nEnd = sal::static_int_cast<int>( x );
-                        for (int i = 1; i <= nEnd; i++)
-                        {
-                            fSummand = (fSummand * lambda)/(double)i;
-                            fSum += fSummand;
-                        }
-                        PushDouble(fSum);
+                        fSummand = (fSummand * lambda)/(double)i;
+                        fSum += fSummand;
                     }
+                    PushDouble(fSum);
                 }
             }
         }
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 11a8870..94d04ac 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -4203,8 +4203,8 @@ StackVar ScInterpreter::Interpret()
                 case ocExpDist_MS       : ScExpDist();                  break;
                 case ocBinomDist        :
                 case ocBinomDist_MS     : ScBinomDist();                break;
-                case ocPoissonDist      :
-                case ocPoissonDist_MS   : ScPoissonDist();              break;
+                case ocPoissonDist      : ScPoissonDist( true );        break;
+                case ocPoissonDist_MS   : ScPoissonDist( false );       break;
                 case ocCombin           : ScCombin();                   break;
                 case ocCombinA          : ScCombinA();                  break;
                 case ocPermut           : ScPermut();                   break;


More information about the Libreoffice-commits mailing list