/* DEC *ModifiedIRR(irr, flows, nflow, intr, safe) * * ARGUMENT * DEC *irr, **flows, *intr, *safe; * int nflow; * * DESCRIPTION * Calculates the modified int. rate of return of a series of cash flows. * The nflow cash flows in the array flows are invested at interest * rate intr for positive cash flows and borrows at interest rate safe * for negative cash flows. * The modified internal rate of return is calculated and stored in irr. * * SIDE EFFECTS * None. * * RETURNS * irr if successful, otherwise GM_NULL. * * * POSSIBLE ERRORS * GM_NULLPOINTER * GM_ARGVAL * * AUTHOR * Jared Levy * Copyright (C) 1988-1990 Greenleaf Software Inc. All rights reserved. * * MODIFICATIONS * * */ #include <stdio.h> #include "gm.h" #include "gmsystem.h" DEC *ModifiedIRR(irr, flows, nflow, intr, safe) DEC *irr, **flows, *intr, *safe; int nflow; { int i; mbool wfNeg, wfPos; DEC dtemp, *temp=&dtemp, dooopi, *ooopi=&dooopi; DEC dpow, *pow=&dpow, dopi, *opi=&dopi; DEC dnpvn, *npvn=&dnpvn, dnfvp, *nfvp=&dnfvp; DEC *p; _MacStart(GM_MIRR); if (nflow<2) { _MacErr(GM_ARGVAL); _MacRet(GM_NULL); } _MacInVarD(intr); _MacInVarD(safe); if (!flows) { _MacErr(GM_NULLPOINTER); _MacRet(GM_NULL); } _MacOutVarD(irr); /* check for null pointers, at least one pos & neg cash flow */ wfPos=FALSE; wfNeg=FALSE; for (i=0;i<nflow;i++) { p = flows[i]; _MacInVarD(p); wfPos=wfPos||_MacIsDecP(p); wfNeg=wfNeg||_MacIsDecN(p); } if (!wfPos||!wfNeg) { _MacErr(GM_ARGVAL); _MacRet(GM_NULL); } if ((CompareDecimal(intr,&decMinusHundred)!=1) ||(CompareDecimal(safe,&decMinusHundred)!=1)) { _MacErr(GM_ARGVAL); _MacRet(GM_NULL); } /* calculate npv of negative values at safe rate */ _MacDZero(npvn); _MacDCopy(temp, safe); temp->dc.id+=2; (void) _AddDec80Bit(temp, temp, &decOne); (void) _DivDec80Bit(ooopi, &decOne, temp); _MacDCopy(pow, (&decOne)); for (i=0;i<nflow;i++) { if (_MacIsDecN(flows[i])) { (void) _MulDec80Bit(temp, flows[i], pow); (void) _AddDec80Bit(npvn, npvn, temp); } (void) _MulDec80Bit(pow, pow, ooopi); } /* calculate nfv of positive values at intr */ _MacDZero(nfvp); _MacDCopy(temp, intr); temp->dc.id+=2; (void) _AddDec80Bit(opi, temp, &decOne); _MacDCopy(pow, (&decOne)); for (i=nflow-1;i>=0;i--) { if (_MacIsDecP(flows[i])) { (void) _MulDec80Bit(temp, flows[i], pow); (void) _AddDec80Bit(nfvp, nfvp, temp); } (void) _MulDec80Bit(pow, pow, opi); } /* calculate modified internal rate of return */ _MacDChgs(npvn); (void) _DivDec80Bit(temp, nfvp, npvn); (void) _LnDec80Bit(temp, temp); (void) ConvLongToDecimal(pow, (long) (nflow-1)); (void) _DivDec80Bit(temp, temp, pow); (void) _ExpDec80Bit(temp, temp); (void) _SubDec80Bit(temp, temp, &decOne); if (temp->dc.id>=2) temp->dc.id -=2; else { ConvLongToDecimal(pow, 100L); (void) _MulDec80Bit(temp, temp, pow); } (void) _Sq5UnsTo4Uns(temp); _MacDCopy(irr,temp); _MacRet(irr); }