Net Present Value

Date: 198x
Type: Program
Platform(s): TS 2068

This program calculates the Net Present Value (NPV) and Internal Rate of Return (IRR) for a capital investment project. It reads project parameters—initial cost, duration, periodic revenues, expenses, and a discount rate—from DATA statements, then computes discounted cash flows for each period. The IRR is found by iterating a discount rate from 0% to 100% in 0.5% steps until the NPV of cash flows falls to or below that rate. A sensitivity analysis loop allows the user to re-run calculations with a modified discount rate without restarting the program.


Program Analysis

Program Structure

The program is divided into clearly separated phases, each handling a distinct part of the financial calculation:

  1. Lines 2–18: Variable glossary display with a timed pause before clearing the screen.
  2. Lines 19–90: Header output and data initialisation; reads initial cost C and project duration V from DATA, then dimensions six arrays of size V.
  3. Lines 100–230: Reads and displays periodic revenues R(I), expenses D(I), residual value RO, and discount rate T.
  4. Lines 260–340: Prints the raw forecast table (revenues, expenses, profit per period).
  5. Lines 360–560: Computes and displays discounted present values for each period, plus the discounted residual value VR.
  6. Lines 580–660: Prints final results: NPV of cash flow and a profitability index.
  7. Lines 670–780: Iterative IRR search loop.
  8. Lines 800–840: Sensitivity analysis prompt; loops back to line 220 if the user requests a new discount rate.
  9. Lines 850–890: Subroutines — a horizontal rule printer and a column-header printer.
  10. Lines 900–930: DATA block providing the sample project parameters.

Key Financial Calculations

The core discounting formula applied at line 440460 is the standard present value formula:

  • S(I) = R(I) * (1 + T/100)^(-I) — discounted revenue for period I
  • E(I) = D(I) * (1 + T/100)^-I — discounted expense for period I
  • C(I) = S(I) - E(I) — net discounted cash flow for period I
  • VR = RO * (1 + T/100)^(-V-1) — residual value discounted one period beyond the project end (line 530)

The NPV (line 630) is B + VR - C, where B is the sum of discounted net cash flows, VR is the discounted residual, and C is the initial cost. The profitability index (line 660) is (RR + VR) / (DD + C) expressed as a percentage, rounded to two decimal places inline rather than using the FN A function.

IRR Search Algorithm

The Internal Rate of Return is found by a simple brute-force scan (lines 680750). The outer loop variable O steps from 0 to 100 in 0.5% increments. For each candidate rate, the NPV X is recomputed using B(I) (pre-calculated net profits) plus the discounted residual, minus initial cost. The loop exits when X <= O, at which point O approximates the IRR.

There is a subtle bug in line 740: the exit condition IF X <= O compares the NPV against the current rate value rather than against zero (IF X <= 0). This means the loop exits slightly early—when NPV drops below the current percentage value rather than when it crosses zero—potentially overstating the IRR by a small margin. For typical project scales the error is minor but it is technically incorrect.

Variable Name Collision

A significant naming conflict exists: the scalar variable C (initial project cost, read at line 55) is overwritten at line 90 when DIM C(V) is declared, creating an array also named C. In Sinclair BASIC, a scalar and an array of the same name cannot coexist—declaring the array erases the scalar. After line 90, any reference to C as the initial cost (e.g., lines 630, 660, 730) would actually access C(0) (the zeroth element of the array, which defaults to zero), producing incorrect NPV and profitability results. This is a genuine bug in the program as listed.

Notable BASIC Idioms

  • User-defined function: Line 19 defines FN A(X) = INT(100*X + 0.5)/100, a standard two-decimal-place rounding function used extensively in output formatting.
  • Subroutine reuse: The horizontal rule subroutine at line 850 is called over ten times, keeping the separator output consistent and saving repeated PRINT statements.
  • Sensitivity loop: Line 830 jumps back to line 220 (re-display of rate, then recalculation) rather than line 1, avoiding a full re-read of DATA and allowing repeated what-if analysis cleanly.
  • TAB positioning: Column alignment throughout the output relies entirely on TAB() calls, producing a structured multi-column report without any screen editor tricks.

DATA Layout

LineValuesMeaning
90018000, 5Initial cost C, duration V (5 periods)
9105000, 5500, 5500, 5000, 5000Revenue R(1)–R(5)
920100, 1000, 1200, 1500, 1500Expenses D(1)–D(5)
9308000, 12Residual value RO, discount rate T (%)

Content

Appears On

One of a series of library tapes. Programs on these tapes were renamed to a number series. This tape contained

Related Products

Related Articles

Related Content

Image Gallery

Net Present Value

Source Code

    2 REM "NET PRES V"
    4 PRINT " VARIABLES: ": PRINT 
    5 PRINT "B   TOTAL DISCOUNTED PROFITS"
    6 PRINT "B(I)  PROFIT FOR PERIOD I"
    7 PRINT "C(I)   DISCOUNTED PROFIT FOR PER       I"
    8 PRINT "C   INITIAL COST OF PROJECT--       line 900"
    9 PRINT "D(I)   EXPENSES FOR PERIOD I--         line--920"
   10 PRINT "DD   TOTAL DISCOUNTED EXPENSES"
   11 PRINT "E(I)   DISCOUNTED EXP FOR PER I"
   12 PRINT "R(I)   REVENUES FOR PERIOD I--         line 910"
   13 PRINT "RO RESIDUAL VALUE OF PROJECT--         line 930"
   14 PRINT "S(I)   DISCOUNTED REV FOR PER I"
   15 PRINT "T   DISCOUNT RATE--                 line 930"
   16 PRINT "V   EST DURATION OF PROJECT--       line 900"
   17 PRINT "VR   DISCOUNTED RESIDUAL VALUE"
   18 PAUSE 340: CLS 
   19 DEF FN A(X)=INT (100*X+.5)/100
   20 PRINT : PRINT 
   30 PRINT " NET PRESENT VALUE AND"
   40 PRINT "INTERNAL RATE OF RETURN"
   45 PRINT "-------------------------------"
   50 PRINT : PRINT 
   55 READ C,V
   60 PRINT "INITIAL COST OF THE INVESTMENT? ";C
   70 PRINT 
   80 PRINT "ESTIMATED DURATION OF PROJECT? ";V
   90 DIM R(V): DIM D(V): DIM B(V): DIM C(V): DIM E(V): DIM S(V)
  100 PRINT 
  110 PRINT "PERIODIC INCOME FROM PROJECT:"
  120 FOR I=1 TO V
  125 READ R(I)
  130 PRINT "--PERIOD #";I;TAB ( 15);R(I)
  150 NEXT I: PRINT 
  160 PRINT "EXPENSES FORECAST:"
  170 FOR I=1 TO V
  175 READ D(I)
  180 PRINT "--PERIOD #";I;TAB ( 15);D(I)
  200 NEXT I: PRINT 
  205 READ RO,T
  210 PRINT "RESIDUAL VALUE OF THE INVESTMENT? ";RO
  220 PRINT 
  230 PRINT "RATE OF RETURN ON INVESTMENT? (%) ";T
  240 REM     PRINT OUTPUT
  250 PRINT : PRINT 
  260 PRINT "FORECASTS:"
  270 GO SUB 850
  280 GO SUB 870
  290 GO SUB 850
  300 FOR I=1 TO V
  310 LET B(I)=R(I)-D(I)
  320 PRINT TAB ( 2);I;TAB ( 8);R(I);TAB ( 15);D(I);TAB 22;B(I)
  330 NEXT I
  340 GO SUB 850
  350 PRINT : PRINT : PRINT 
  360 REM  PRESENT VALUE
  370 PRINT "PRESENT VALUE: "
  380 GO SUB 850
  390 GO SUB 870
  395 LET P$="(PRES VAL)"
  400 PRINT TAB ( 2);P$;TAB ( 12);P$;TAB ( 22);P$
  410 GO SUB 850
  420 LET B=0: LET RR=0: LET DD=0
  430 FOR I=1 TO V
  440 LET S(I)=R(I)*(1+T/100)^(-I)
  450 LET E(I)=D(I)*(1+T/100)^-I
  460 LET C(I)=S(I)-E(I)
  470 LET B=B+C(I)
  480 LET RR=RR+S(I)
  490 LET DD=DD+E(I)
  500 PRINT TAB ( 2);FN A(I);TAB ( 7);FN A(S(I));
  505 PRINT TAB ( 15);FN A(E(I));TAB ( 24);FN A(C(I))
  510 NEXT I
  520 GO SUB 850
  530 LET VR=RO*(1+T/100)^(-V-1)
  540 PRINT "PRESENT VALUE OF RESIDUAL = ";
  550 PRINT TAB ( 25);FN A(VR)
  560 GO SUB 850
  570 REM  PRINT OUTPUT
  580 PRINT : PRINT 
  590 PRINT "RESULTS OF THE ANALYSIS:"
  595 PRINT 
  600 GO SUB 850
  610 PRINT "NET PRESENT VALUE OF CASH-FLOW"
  620 PRINT "(INCLUDING RESIDUAL VALUE)"
  630 PRINT TAB ( 15);" = ";TAB ( 25);FN A(B+VR-C)
  640 GO SUB 850
  650 PRINT "PROFITABILITY INDEX = ";
  660 PRINT TAB ( 25);INT (10000*((RR+VR)/(DD+C))+.5)/100;"%"
  670 REM CALCULATE INTERNAL RATEOF RETIURN
  680 FOR O=0 TO 100 STEP 0.5
  690 LET X=0
  700 FOR I=1 TO V
  710 LET X=X+B(I)*(1+O/100)^-I
  720 NEXT I
  730 LET X=X+RO*(1+O/100)^(-V-1)-C
  740 IF X<=O THEN GO TO 760
  750 NEXT O
  760 GO SUB 850
  770 PRINT "INTERNAL RATE OF RETURN = ";
  780 PRINT TAB (31);FN A(O);"%"
  790 GO SUB 850
  800 PRINT : PRINT 
  810 PRINT "PERFORM SENSITIVITY ANALYSIS BY "
  820 INPUT "MODIFYING THE RATE OF RETURN?(Y/N) ";C$
  830 IF C$="Y" THEN PRINT "Input a new rate": INPUT T: GO TO 220
  835 GO TO 840
  840 STOP 
  850 PRINT "-------------------------------"
  860 RETURN 
  870 PRINT "PER EXPECTED ESTIMATED EXPECTED"
  880 PRINT "    REVENUES EXPENSES  PROFITS"
  890 RETURN 
  900 DATA 18000,5
  910 DATA 5000,5500,5500,5000,5000
  920 DATA 100,1000,1200,1500,1500
  930 DATA 8000,12

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top