--- title: "Net Present Value" id: 56308 type: "computer_media" slug: "netpresval" url: "http://localhost/computer_media/netpresval/" markdown_url: "http://localhost/computer_media/netpresval.md" published_at: "2024-08-04T10:49:54+00:00" modified_at: "2026-03-30T21:44:17+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/08/SCR-20240804-jsoi.png" excerpt: "A financial analysis tool that computes Net Present Value and Internal Rate of Return for multi-period investments, complete with iterative IRR search and sensitivity analysis." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Business" slug: "business" taxonomy: "genre" url: "http://localhost/type/business/" - name: "Finance" slug: "finance" taxonomy: "genre" url: "http://localhost/type/finance/" media_contents: - id: 56277 title: "Timex Sinclair Public Domain Library Tape 2001" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-2001/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/NetPresVal%20%28198x%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/08/SCR-20240804-jsoi.png" - url: "http://localhost/wp-content/uploads/2024/08/SCR-20240804-jsnn.png" media_type_tags: "Business, Finance" --- # Net Present Value 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 `440`–`460` 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 `680`–`750`). 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 | Line | Values | Meaning | | --- | --- | --- | | `900` | 18000, 5 | Initial cost C, duration V (5 periods) | | `910` | 5000, 5500, 5500, 5000, 5000 | Revenue R(1)–R(5) | | `920` | 100, 1000, 1200, 1500, 1500 | Expenses D(1)–D(5) | | `930` | 8000, 12 | Residual value RO, discount rate T (%) | ## 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 ```