REM ANNUITY.BAS, Ver 1.0, December 11, 1982\ \ Phil Cary\ 2025 Tyre Circle\ Las Cruces, NM 88001\ \ Mesilla Valley RCP/M (505) 522-8856\ \ This program must be compiled with CB80. It calculates the missing\ variable of an ordinary annuity problem. Repeated calculations may\ be made without reentering the unchanged variables - only a ".".\ A clear screen code can be substituted for the nulls at clear.screen.\ \ The interest rate calculation is iterative and make take a while\ depending upon how far off the true interest rate is from the built-in\ first guess rate of 50%. This high guess value is needed to reach\ dymamic range interest rate limits of approximately .0002% to\ approximately 99.9991%. There may be lesser limits for some untested\ input values.\ \ A compiled version of this program is available on Mesilla Valley\ RCP/M, (505) 522-8856, as ANNUITY.OBJ. REM following notice required in composite program by Digital Research, Inc. license.notice$="Portions of this program (c)1982 Digital Research Inc" REM constants true% = 1 false% =0 null$ = "" escape$ = CHR$(27) clear.screen$ = null$ + null$ REM Put clear screen code for your\ terminal here, i.e. escape$ + "E" for H-19 ON ERROR GOTO process.error REM start of program PRINT clear.screen$ PRINT " ORDINARY ANNUITY" restart: PRINT:PRINT "Enter known values, for unknown value, " +\ "period <.> for same value on rerun." PRINT INPUT " Present Value(Q to Quit): $";LINE reply$ GOSUB strip.commas: IF (answer$ = "Q" OR answer$ = "q") THEN STOP IF answer$ = "."\ THEN present.value = present.value\ ELSE present.value = VAL(answer$) IF present.value = 0 THEN function% = 1 INPUT " Monthly Payment: $";LINE reply$ GOSUB strip.commas IF answer$ = "."\ THEN monthly.payment = monthly.payment\ ELSE monthly.payment = VAL(answer$) IF monthly.payment = 0 THEN function% = 2 INPUT " Annual Interest Rate: %";LINE reply$ GOSUB strip.commas IF answer$ = "."\ THEN annual.interest.rate = annual.interest.rate\ ELSE annual.interest.rate = VAL(answer$) IF annual.interest.rate = 0 THEN function% = 3:\ annual.interest.rate = 50 REM a guess to start monthly.interest.rate = annual.interest.rate / 1200 INPUT " Number Of Payments: ";LINE reply$ GOSUB strip.commas IF answer$ = "."\ THEN number.of.payments% = number.of.payments%\ ELSE number.of.payments% = VAL(answer$) IF number.of.payments% = 0 THEN function% = 4 REM define function used in calculations DEF partial.solution (monthly.interest.rate, number.of.payments%) =\ 1-1/(1+monthly.interest.rate)^number.of.payments% REM go perform the selected function ON function% GOSUB\ compute.present.value,\ compute.monthly.payment,\ compute.interest.rate,\ compute.number.of.payments GOTO restart compute.present.value: present.value = monthly.payment *\ (partial.solution\ (monthly.interest.rate,number.of.payments%)/\ monthly.interest.rate) PRINT PRINT USING " The Present Value Is: $$#,###,###,###.##";present.value RETURN compute.monthly.payment: monthly.payment = present.value *\ (monthly.interest.rate/partial.solution\ (monthly.interest.rate,number.of.payments%)) IF interest.rate.flag% THEN RETURN PRINT PRINT USING " The Monthly Payment Is: $$###,###,###.##";monthly.payment RETURN compute.interest.rate: interest.rate.flag% = true% target.payment = monthly.payment entered.monthly.interest.rate = monthly.interest.rate PRINT:PRINT " Iterating calculation, please wait."; maximum.iterations% = 50 recompute.interest.rate: FOR iteration% = 1 TO maximum.iterations% GOSUB compute.monthly.payment IF ABS(target.payment - monthly.payment) < .001\ THEN annual.interest.rate = monthly.interest.rate * 1200:\ PRINT " ";iteration%;"iterations.":\ PRINT:PRINT USING " The Annual Interest Rate Is: ##.####";\ annual.interest.rate;: PRINT " %":\ monthly.payment = target.payment:\ interest.rate.flag% = false%: RETURN correction = ABS(monthly.interest.rate - guess.new.rate)/2 guess.new.rate = monthly.interest.rate IF monthly.payment < target.payment\ THEN monthly.interest.rate = monthly.interest.rate + correction\ ELSE monthly.interest.rate = monthly.interest.rate - correction NEXT iteration% PRINT:PRINT:PRINT "No solution after";maximum.iterations%;"iterations." PRINT "There is"; PRINT USING "$$##,###,###.##";target.payment - monthly.payment; PRINT " difference between actual payment and the computed " PRINT "payment, and the computed annual interest rate is now"; PRINT USING "###.####";monthly.interest.rate * 1200;:PRINT "%." PRINT PRINT "You may have entered values that result in a negative" +\ " amortization, " PRINT "or the dynamic range of the interest rate calculations has been" PRINT "exceeded with the values entered. Try again with different" +\ " values." monthly.payment = target.payment:\ monthly.interest.rate = entered.monthly.interest.rate:\ interest.rate.flag% = false%:\ GOTO restart\ compute.number.of.payments: number.of.payments% =\ -LOG(1-(present.value *\ monthly.interest.rate/monthly.payment))/\ LOG(1 + monthly.interest.rate) PRINT PRINT USING " The Number Of Payments Is: ###";number.of.payments% RETURN strip.commas: answer$ = null$ FOR character.position% = 1 TO LEN(reply$) character$ = MID$(reply$,character.position%,1) IF character$ = "," THEN character$ = null$ answer$ = answer$ + character$ NEXT character.position% RETURN process.error: IF ERR = "DZ" THEN PRINT:PRINT " A division by zero was attempted." +\ " Please recheck your entries." GOTO restart