Commit 2a96dd8a authored by Dmitry.Shahtanov's avatar Dmitry.Shahtanov Committed by Alexander.Trofimov

для бага Bug 24901 - Некорректная ошибка в формуле XIRR, если аргумент Dates...

для бага Bug 24901 - Некорректная ошибка в формуле XIRR, если аргумент Dates не является допустимой датой
поправлено:
"При вводе недопустимой даты в B3 сейчас ошибка #NUM вместо #VALUE. При очистке (или ввода нуля) кнопкой Delete диапазона B3:B7 показывается ошибка #VALUE вместо #NUM."

git-svn-id: svn://192.168.3.15/activex/AVS/Sources/TeamlabOffice/trunk/OfficeWeb@57471 954022d7-b5bf-4e40-9824-e11837661b57
parent b851dcde
...@@ -4599,9 +4599,9 @@ ...@@ -4599,9 +4599,9 @@
if ( res <= -1 ) if ( res <= -1 )
return "#NUM!" return "#NUM!"
var fMaxEps = 1e-10, maxIter = 50; var fMaxEps = 1e-6, maxIter = 100;
var newRate, eps, xirrRes, bContLoop, nIter = 0; var newRate, eps, xirrRes, bContLoop;
do do
{ {
xirrRes = lcl_sca_XirrResult( valueArray, dateArray, res ); xirrRes = lcl_sca_XirrResult( valueArray, dateArray, res );
...@@ -4610,7 +4610,7 @@ ...@@ -4610,7 +4610,7 @@
res = newRate; res = newRate;
bContLoop = (eps > fMaxEps) && (Math.abs( xirrRes ) > fMaxEps); bContLoop = (eps > fMaxEps) && (Math.abs( xirrRes ) > fMaxEps);
} }
while ( bContLoop && (++nIter < maxIter) ); while ( --maxIter && bContLoop );
if ( bContLoop ) if ( bContLoop )
return "#NUM!"; return "#NUM!";
......
...@@ -5597,22 +5597,23 @@ cXIRR.prototype = Object.create( cBaseFunction.prototype ); ...@@ -5597,22 +5597,23 @@ cXIRR.prototype = Object.create( cBaseFunction.prototype );
cXIRR.prototype.Calculate = function ( arg ) { cXIRR.prototype.Calculate = function ( arg ) {
var arg0 = arg[0], arg1 = arg[1], arg2 = arg[2] ? arg[2] : new cNumber( 0.1 ); var arg0 = arg[0], arg1 = arg[1], arg2 = arg[2] ? arg[2] : new cNumber( 0.1 );
function lcl_sca_XirrResult( values, dates, rate ) { function xirrFunction( values, dates, rate ) {
var D_0 = dates[0]; var D_0 = dates[0],
var r = rate + 1; r = rate + 1,
var res = values[0]; res = values[0];
for ( var i = 1, count = values.length; i < count; ++i ) for ( var i = 1, count = values.length; i < count; i++ ){
res += values[i] / Math.pow( r, (dates[i] - D_0) / 365 ); res += values[i] / Math.pow( r, (dates[i] - D_0) / 365 );
}
return res; return res;
} }
function lcl_sca_XirrResult_Deriv1( values, dates, rate ) { function xirrDeriv( values, dates, rate ) {
var D_0 = dates[0]; var D_0 = dates[0],
var r = rate + 1; r = rate + 1,
var res = 0; res = 0, sumDerivI;
for ( var i = 1, count = values.length; i < count; ++i ) { for ( var i = 1, count = values.length; i < count; i++ ) {
var E_i = (dates[i] - D_0) / 365; sumDerivI = (dates[i] - D_0) / 365;
res -= E_i * values[i] / Math.pow( r, E_i + 1 ); res -= sumDerivI * values[i] / Math.pow( r, sumDerivI + 1 );
} }
return res; return res;
} }
...@@ -5621,7 +5622,13 @@ cXIRR.prototype.Calculate = function ( arg ) { ...@@ -5621,7 +5622,13 @@ cXIRR.prototype.Calculate = function ( arg ) {
var arr0 = valueArray[0], arr1 = dateArray[0]; var arr0 = valueArray[0], arr1 = dateArray[0];
if ( arr0 instanceof cError || arr1 instanceof cError || arr0.getValue() == 0 ) { if ( arr0 instanceof cError ){
return arr0;
}
if ( arr1 instanceof cError ){
return arr1;
}
if ( arr0.getValue() == 0 ) {
return new cError( cErrorType.not_numeric ); return new cError( cErrorType.not_numeric );
} }
...@@ -5633,7 +5640,7 @@ cXIRR.prototype.Calculate = function ( arg ) { ...@@ -5633,7 +5640,7 @@ cXIRR.prototype.Calculate = function ( arg ) {
return new cError( cErrorType.not_numeric ); return new cError( cErrorType.not_numeric );
var deltaEps = 1e-6, maxIter = 100, wasNeg = false, wasPos = false, var deltaEps = 1e-6, maxIter = 100, wasNeg = false, wasPos = false,
newRate, eps, xirrRes, bContLoop = true; newXirrRes, eps, xirrRes, bContLoop = true;
for ( var i = 0; i < dateArray.length; i++ ) { for ( var i = 0; i < dateArray.length; i++ ) {
dateArray[i] = dateArray[i].tocNumber(); dateArray[i] = dateArray[i].tocNumber();
...@@ -5661,13 +5668,13 @@ cXIRR.prototype.Calculate = function ( arg ) { ...@@ -5661,13 +5668,13 @@ cXIRR.prototype.Calculate = function ( arg ) {
return new cError( cErrorType.not_numeric ); return new cError( cErrorType.not_numeric );
} }
for ( var i = 0; i < maxIter && bContLoop; i++ ) { do{
xirrRes = lcl_sca_XirrResult( valueArray, dateArray, res ); xirrRes = xirrFunction( valueArray, dateArray, res );
newRate = res - xirrRes / lcl_sca_XirrResult_Deriv1( valueArray, dateArray, res ); newXirrRes = res - xirrRes / xirrDeriv( valueArray, dateArray, res );
eps = Math.abs( newRate - res ); eps = Math.abs( newXirrRes - res );
res = newRate; res = newXirrRes;
bContLoop = (eps > deltaEps) && (Math.abs( xirrRes ) > deltaEps); bContLoop = (eps > deltaEps) && (Math.abs( xirrRes ) > deltaEps);
} }while( --maxIter && bContLoop );
if ( bContLoop ) { if ( bContLoop ) {
return new cError( cErrorType.not_numeric ); return new cError( cErrorType.not_numeric );
...@@ -5727,6 +5734,9 @@ cXIRR.prototype.Calculate = function ( arg ) { ...@@ -5727,6 +5734,9 @@ cXIRR.prototype.Calculate = function ( arg ) {
if ( c instanceof cNumber ) { if ( c instanceof cNumber ) {
dateArray.push( c ); dateArray.push( c );
} }
else if ( c instanceof cEmpty ) {
dateArray.push( c.tocNumber() );
}
else { else {
dateArray.push( new cError( cErrorType.wrong_value_type ) ); dateArray.push( new cError( cErrorType.wrong_value_type ) );
} }
...@@ -5737,6 +5747,9 @@ cXIRR.prototype.Calculate = function ( arg ) { ...@@ -5737,6 +5747,9 @@ cXIRR.prototype.Calculate = function ( arg ) {
if ( c instanceof cNumber ) { if ( c instanceof cNumber ) {
dateArray.push( c ); dateArray.push( c );
} }
else if( c instanceof cEmpty ){
dateArray.push( c.tocNumber() );
}
else { else {
dateArray.push( new cError( cErrorType.wrong_value_type ) ); dateArray.push( new cError( cErrorType.wrong_value_type ) );
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment