From e58b3f987681d0034f692db82345af06de217836 Mon Sep 17 00:00:00 2001 From: Winfried Donkers Date: Fri, 20 Apr 2018 21:23:08 +0200 Subject: [PATCH] tdf#117041 implement note at end of ODFF1.2 par. 6.18.37 And avoid double code by putting the non-cumulative calculation in the loop as well. Change-Id: I8538582e7d33370f5e44382924b9e3e89efa28dd Reviewed-on: https://gerrit.libreoffice.org/53221 Reviewed-by: Eike Rathke Tested-by: Eike Rathke --- .../statistical/fods/hypgeomdist.fods | 73 ++++++++++++++++--- sc/source/core/tool/interpr3.cxx | 20 +++-- 2 files changed, 71 insertions(+), 22 deletions(-) diff --git a/sc/qa/unit/data/functions/statistical/fods/hypgeomdist.fods b/sc/qa/unit/data/functions/statistical/fods/hypgeomdist.fods index 668562200ee5..86e67be89a36 100644 --- a/sc/qa/unit/data/functions/statistical/fods/hypgeomdist.fods +++ b/sc/qa/unit/data/functions/statistical/fods/hypgeomdist.fods @@ -4385,11 +4385,22 @@ - - - - - + + 0.988500551352757 + + + 0.988500551352757 + + + TRUE + + + =HYPGEOMDIST(53,55,269,300,1) + + + tdf117041 + + @@ -4399,12 +4410,52 @@ - - + + + 0.95624768719555 + + + 0.95624768719555 + + + TRUE + + + =HYPGEOMDIST(34,36,89,100,1) + + + tdf117041 + + + + + + + - - - + + + + + + + + + 0 + + + 0 + + + TRUE + + + =HYPGEOMDIST(24,36,89,100) + + + tdf117041 + + @@ -5084,4 +5135,4 @@ - \ No newline at end of file + diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx index 46328e5d8009..2a9535e31c8d 100644 --- a/sc/source/core/tool/interpr3.cxx +++ b/sc/source/core/tool/interpr3.cxx @@ -1844,7 +1844,7 @@ static void lcl_PutFactorialElements( ::std::vector< double >& cn, double fLower @see fdo#71722 @see tdf#102948, make Calc function ODFF1.2-compliant - + @see tdf#117041, implement note at bottom of ODFF1.2 par.6.18.37 */ void ScInterpreter::ScHypGeomDist( int nMinParamCount ) { @@ -1858,23 +1858,21 @@ void ScInterpreter::ScHypGeomDist( int nMinParamCount ) double n = ::rtl::math::approxFloor(GetDouble()); double x = ::rtl::math::approxFloor(GetDouble()); - if( (x < 0.0) || (n < x) || (M < x) || (N < n) || (N < M) || (x < n - N + M) ) + if ( (x < 0.0) || (n < x) || (N < n) || (N < M) || (M < 0.0) ) { PushIllegalArgument(); return; } - if ( bCumulative ) + double fVal = 0.0; + + for ( int i = ( bCumulative ? 0 : x ); i <= x && nGlobalError == FormulaError::NONE; i++ ) { - double fVal = 0.0; - - for ( int i = 0; i <= x && nGlobalError == FormulaError::NONE; i++ ) - fVal += GetHypGeomDist( i, n, M, N ); - - PushDouble( fVal ); + if ( (i >= n - N + M) || (i >= M) ) + fVal += GetHypGeomDist( i, n, M, N ); } - else - PushDouble( GetHypGeomDist( x, n, M, N ) ); + + PushDouble( fVal ); } /** Calculates a value of the hypergeometric distribution.