示例#1
0
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);
}
示例#2
0
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;
}
示例#3
0
文件: sc-fin.c 项目: GNOME/gnumeric
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);
}