GnmValue * get_vdb (gnm_float cost, gnm_float salvage, gnm_float life, gnm_float start_period, gnm_float end_period, gnm_float factor, gboolean flag) { gnm_float fVdb; gnm_float fIntStart = gnm_floor (start_period); gnm_float fIntEnd = gnm_ceil (end_period); int i; int nLoopStart = (int) fIntStart; int nLoopEnd = (int) fIntEnd; fVdb = 0.0; if ( flag ) { for (i = nLoopStart + 1; i <= nLoopEnd; i++) { gnm_float fTerm; fTerm = ScGetGDA (cost, salvage, life, i, factor); if ( i == nLoopStart+1 ) fTerm *= ( MIN( end_period, fIntStart + 1.0 ) - start_period ); else if ( i == nLoopEnd ) fTerm *= ( end_period + 1.0 - fIntEnd ); fVdb += fTerm; } } else { gnm_float life1 = life; gnm_float fPart; if ( start_period != gnm_floor (start_period) ) if (factor > 1) { if (start_period >= life / 2) { fPart = start_period - life / 2; start_period = life / 2; end_period -= fPart; life1 += 1; } } cost -= ScInterVDB (cost, salvage, life, life1, start_period, factor); fVdb = ScInterVDB (cost, salvage, life, life - start_period, end_period - start_period, factor); } return value_new_float (fVdb); }
static gnm_float ScInterVDB (gnm_float cost, gnm_float salvage, gnm_float life, gnm_float life1, gnm_float period, gnm_float factor) { gnm_float fVdb = 0; gnm_float fIntEnd = gnm_ceil (period); int nLoopEnd = fIntEnd; gnm_float fTerm, fLia; gnm_float fRestwert = cost - salvage; gboolean bNowLia = FALSE; gnm_float fGda; int i; fLia = 0; for ( i = 1; i <= nLoopEnd; i++ ) { if (!bNowLia) { fGda = ScGetGDA (cost, salvage, life, i, factor); fLia = fRestwert / (life1 - (gnm_float) (i - 1)); if (fLia > fGda) { fTerm = fLia; bNowLia = TRUE; } else { fTerm = fGda; fRestwert -= fGda; } } else fTerm = fLia; if ( i == nLoopEnd) fTerm *= ( period + 1.0 - fIntEnd ); fVdb += fTerm; } return fVdb; }
GnmValue * get_vdb (gnm_float cost, gnm_float salvage, gnm_float life, gnm_float start_period, gnm_float end_period, gnm_float factor, gboolean flag) { gnm_float fVdb; gnm_float fIntStart = gnm_floor (start_period); gnm_float fIntEnd = gnm_ceil (end_period); fVdb = 0.0; if ( flag ) { int i, nLoopStart, nLoopEnd; if (fIntEnd > G_MAXINT || fIntEnd - fIntStart > 10000 /* arbitrary */) return value_new_error_VALUE (NULL); nLoopStart = (int) fIntStart; nLoopEnd = (int) fIntEnd; for (i = nLoopStart + 1; i <= nLoopEnd; i++) { gnm_float fTerm; fTerm = ScGetGDA (cost, salvage, life, i, factor); if ( i == nLoopStart+1 ) fTerm *= ( MIN( end_period, fIntStart + 1.0 ) - start_period ); else if ( i == nLoopEnd ) fTerm *= ( end_period + 1.0 - fIntEnd ); fVdb += fTerm; } } else { gnm_float fPart = 0; double fIntEnd = gnm_ceil (end_period); if (start_period > fIntStart) { // First period is partial. Calculate the excess as // the pro-rata value of the first period as-if it // was not partial. double tempcost = cost - ScInterVDB( cost, salvage, life, life, fIntStart, factor); fPart += (start_period - fIntStart) * ScInterVDB( tempcost, salvage, life, life - fIntStart, 1, factor); } if (end_period < fIntEnd) { // Last period is partial. Calculate the excess as // the pro-rata value of the last period as-if it // was not partial. double em1 = fIntEnd - 1; // Start of last period double tempcost = cost - ScInterVDB (cost, salvage, life, life, em1, factor); fPart += (fIntEnd - end_period) * ScInterVDB (tempcost, salvage, life, life - em1, 1, factor); } cost -= ScInterVDB (cost, salvage, life, life, fIntStart, factor); fVdb = ScInterVDB (cost, salvage, life, life - fIntStart, fIntEnd - fIntStart, factor); fVdb -= fPart; } return value_new_float (fVdb); }