Author: regina
Date: Mon Apr 6 15:51:04 2015
New Revision: 1671558
URL: http://svn.apache.org/r1671558
Log:
#i95167 XIRR() function gives Err:502
Patch by: Driss Ben Zoubeir driss.zoub...@gmail.com
Review by: Regina Henschel rb.hensc...@t-online.de
Modified:
openoffice/trunk/main/scaddins/source/analysis/financial.cxx
Modified: openoffice/trunk/main/scaddins/source/analysis/financial.cxx
URL:
http://svn.apache.org/viewvc/openoffice/trunk/main/scaddins/source/analysis/financial.cxx?rev=1671558r1=1671557r2=1671558view=diff
==
--- openoffice/trunk/main/scaddins/source/analysis/financial.cxx (original)
+++ openoffice/trunk/main/scaddins/source/analysis/financial.cxx Mon Apr 6
15:51:04 2015
@@ -545,16 +545,36 @@ double SAL_CALL AnalysisAddIn::getXirr(
// Newton's method - try to find a fResultRate, so that
lcl_sca_XirrResult() returns 0.
double fNewRate, fRateEps, fResultValue;
sal_Int32 nIter = 0;
-bool bContLoop;
+sal_Int32 nIterScan = 0;
+bool bContLoop = false;
+bool bResultRateScanEnd = false;
+
+// First the inner while-loop will be executed using the default Value
fResultRate
+// or the user guessed fResultRate if those do not deliver a solution for
the
+// Newton's method then the range from -0.99 to +0.99 will be scanned with
a
+// step size of 0.01 to find fResultRate's value which can deliver a
solution
do
{
-fResultValue = lcl_sca_XirrResult( aValues, aDates, fResultRate );
-fNewRate = fResultRate - fResultValue / lcl_sca_XirrResult_Deriv1(
aValues, aDates, fResultRate );
-fRateEps = fabs( fNewRate - fResultRate );
-fResultRate = fNewRate;
-bContLoop = (fRateEps fMaxEps) (fabs( fResultValue ) fMaxEps);
+if (nIterScan =1)
+fResultRate = -0.99 + (nIterScan -1)* 0.01;
+do
+{
+fResultValue = lcl_sca_XirrResult( aValues, aDates, fResultRate );
+fNewRate = fResultRate - fResultValue / lcl_sca_XirrResult_Deriv1(
aValues, aDates, fResultRate );
+fRateEps = fabs( fNewRate - fResultRate );
+fResultRate = fNewRate;
+bContLoop = (fRateEps fMaxEps) (fabs( fResultValue )
fMaxEps);
+}
+while( bContLoop (++nIter nMaxIter) );
+nIter = 0;
+if ( ::rtl::math::isNan(fResultRate) ||
::rtl::math::isInf(fResultRate)
+||::rtl::math::isNan(fResultValue) ||
::rtl::math::isInf(fResultValue))
+bContLoop = true;
+
+++nIterScan;
+bResultRateScanEnd = (nIterScan = 200);
}
-while( bContLoop (++nIter nMaxIter) );
+while(bContLoop !bResultRateScanEnd);
if( bContLoop )
THROW_IAE;