[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