Index: source/core/inc/interpre.hxx =================================================================== --- source/core/inc/interpre.hxx (revision 269987) +++ source/core/inc/interpre.hxx (working copy) @@ -660,6 +660,7 @@ void ScBadName(); // Statistik: double phi(double x); +double integralPhi(double x); double taylor(double* pPolynom, USHORT nMax, double x); double gauss(double x); double gaussinv(double x); Index: source/core/tool/interpr3.cxx =================================================================== --- source/core/tool/interpr3.cxx (revision 269987) +++ source/core/tool/interpr3.cxx (working copy) @@ -209,6 +209,11 @@ return 0.39894228040143268 * exp(-(x * x) / 2.0); } +double ScInterpreter::integralPhi(double x) +{ // Using gauss(x)+0.5 has severe cancellation errors for x<-4 + return 0.5 * ::rtl::math::erfc(-x * 0.7071067811865475); // * 1/sqrt(2) +} + double ScInterpreter::taylor(double* pPolynom, USHORT nMax, double x) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::taylor" ); @@ -1499,46 +1504,59 @@ void ScInterpreter::ScNormDist() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScNormDist" ); - if ( MustHaveParamCount( GetByte(), 4 ) ) + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 3, 4)) + return; + bool bCumulative = nParamCount == 4 ? GetBool() : true; + double sigma = GetDouble(); // standard deviation + double mue = GetDouble(); // mean + double x = GetDouble(); // x + if (sigma <= 0.0) { - double kum = GetDouble(); // 0 oder 1 - double sigma = GetDouble(); // Stdabw - double mue = GetDouble(); // Mittelwert - double x = GetDouble(); // x - if (sigma < 0.0) - PushError( errIllegalArgument); - else if (sigma == 0.0) - PushError( errDivisionByZero); - else if (kum == 0.0) // Dichte - PushDouble(phi((x-mue)/sigma)/sigma); - else // Verteilung - PushDouble(0.5 + gauss((x-mue)/sigma)); + PushIllegalArgument(); + return; } + if (bCumulative) + PushDouble(integralPhi((x-mue)/sigma)); + else + PushDouble(phi((x-mue)/sigma)/sigma); } -void ScInterpreter::ScLogNormDist() +void ScInterpreter::ScLogNormDist() //expanded, see #i100119# { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScLogNormDist" ); - if ( MustHaveParamCount( GetByte(), 3 ) ) + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 1, 4)) + return; + bool bCumulative = nParamCount == 4 ? GetBool() : true; // cumulative + double sigma = nParamCount >= 3 ? GetDouble() : 1.0; // standard deviation + double mue = nParamCount >= 2 ? GetDouble() : 0.0; // mean + double x = GetDouble(); // x + if (sigma <= 0.0) { - double sigma = GetDouble(); // Stdabw - double mue = GetDouble(); // Mittelwert - double x = GetDouble(); // x - if (sigma < 0.0) - PushError( errIllegalArgument); - else if (sigma == 0.0) - PushError( errDivisionByZero); - else if (x <= 0.0) + PushIllegalArgument(); + return; + } + if (bCumulative) + { // cumulative + if (x <= 0.0) + PushDouble(0.0); + else + PushDouble(integralPhi((log(x)-mue)/sigma)); + } + else + { // density + if (x <= 0.0) PushIllegalArgument(); else - PushDouble(0.5 + gauss((log(x)-mue)/sigma)); + PushDouble(phi((log(x)-mue)/sigma)/sigma/x); } } void ScInterpreter::ScStdNormDist() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScStdNormDist" ); - PushDouble(0.5 + gauss(GetDouble())); + PushDouble(integralPhi(GetDouble())); } void ScInterpreter::ScExpDist() Index: source/filter/excel/xeformula.cxx =================================================================== --- source/filter/excel/xeformula.cxx (revision 269987) +++ source/filter/excel/xeformula.cxx (working copy) @@ -1813,6 +1813,35 @@ } break; + case ocNormDist: + if( nParamCount == 3 ) + { + // NORMDIST function needs 4 parameters in Excel + PrepareParam( rFuncData ); + AppendBoolToken( true ); + FinishParam( rFuncData ); + } + break; + + case ocLogNormDist: + switch( nParamCount ) + { + //LOGNORMSIST function needs 3 parameters in Excel + case 1: + PrepareParam( rFuncData ); + AppendIntToken( 0 ); + FinishParam( rFuncData ); + // do not break, add next default parameter + case 2: + PrepareParam( rFuncData ); + AppendIntToken( 1 ); + FinishParam( rFuncData ); + break; + default:; + } + + break; + default:; } } Index: source/ui/src/scfuncs.src =================================================================== --- source/ui/src/scfuncs.src (revision 269987) +++ source/ui/src/scfuncs.src (working copy) @@ -5718,7 +5718,7 @@ 0; ID_FUNCTION_GRP_STATISTIC; U2S( HID_FUNC_NORMVERT ); - 4; 0; 0; 0; 0; + 4; 0; 0; 0; 1; 0; }; String 2 // Name of Parameter 1 @@ -5731,7 +5731,7 @@ }; String 4 // Name of Parameter 2 { - Text [ en-US ] = "mean" ; + Text [ en-US ] = "Mean" ; }; String 5 // Description of Parameter 2 { @@ -5751,7 +5751,7 @@ }; String 9 // Description of Parameter 4 { - Text [ en-US ] = "Cumulated. C=0 calculates the density function, C=1 the distribution." ; + Text [ en-US ] = "0 or FALSE calculates the probability density function. Any other value or TRUE or omitted calculates the cumulative distribution function." ; }; }; // -=*# Resource for function NORMINV #*=- @@ -5854,7 +5854,7 @@ 0; ID_FUNCTION_GRP_STATISTIC; U2S( HID_FUNC_LOGNORMVERT ); - 3; 0; 0; 0; + 4; 0; 1; 1; 1; 0; }; String 2 // Name of Parameter 1 @@ -5871,7 +5871,7 @@ }; String 5 // Description of Parameter 2 { - Text [ en-US ] = "Mean value. The mean value of the log normal distribution." ; + Text [ en-US ] = "The mean value of the log normal distribution. It is set to 0 if omitted." ; }; String 6 // Name of Parameter 3 { @@ -5879,8 +5879,16 @@ }; String 7 // Description of Parameter 3 { - Text [ en-US ] = "Standard deviation. The standard deviation of the log normal distribution." ; + Text [ en-US ] = "The standard deviation of the log normal distribution. It is set to 1 if omitted." ; }; + String 8 // Name of Parameter 4 + { + Text [ en-US] = "Cumulative"; + }; + String 9 // Description of Parameter 4 + { + Text [ en-US] = "0 or FALSE calculates the probability density function. Any other value or TRUE or omitted calculates the cumulative distribution function." ; + }; }; // -=*# Resource for function LOGINV #*=- Resource SC_OPCODE_LOG_INV