Money Analyzer 2 is a multi-module financial analysis suite covering three related engineering-economics calculations: asset depreciation, present worth comparison of investment alternatives, and rate of return estimation. The depreciation module implements three standard methods — straight-line, sum-of-years-digits, and declining balance — displaying a year-by-year table of depreciation charges and remaining book value. The present worth module finds a common life multiple (up to 20 iterations) across alternatives with differing expected lives before computing net present worth for each. The rate of return module uses a three-pass bisection-style search, stepping through interest rates at decreasing granularity (0.05, 0.01, then 0.001) to converge on a solution to two decimal places, switching to FAST mode during computation and back to SLOW for display.
Program Analysis
Money Analyzer 2 is structured as three largely independent BASIC programs sharing a common financial theme. Each begins near or at line 100 and manages its own input/output flow. The depreciation section uses low-numbered subroutines (lines 10–39) dispatched via a computed GOSUB X*10, while the present worth and rate of return sections are self-contained sequential programs. The listing appears to represent the programs concatenated for publication rather than a single unified program.
Module 1: Depreciation
The main loop at lines 100–300 collects the asset’s initial value (P), salvage value (S), and expected life in years (N), then presents a menu of four options. The dispatcher at line 290 uses the elegant idiom GOSUB X*10 to branch to the appropriate subroutine based on the user’s numeric choice, routing to line 10, 20, or 30 for the three depreciation methods.
- Straight-line (lines 10–16): Computes a fixed annual charge
D = INT((P-S)/N + 0.5)and accumulates the book value by subtraction each year. - Sum-of-years-digits (lines 20–28): Calculates the SYD denominator as
N*(N+1)/2, then weights each year’s charge by the remaining life fraction(N-I+A)/SYD, whereAis used as the constant 1. - Declining balance (lines 30–39): Prompts for a depreciation rate
R, computes each year’s charge asINT(R*P*((A-R)**(I-A)) + 0.5), and includes a floor guard at line 34 to prevent book value dropping below salvage:IF V-D<S THEN LET D=V-S.
Variable names A, B, C, E are used as numeric constants throughout (likely set before the listing begins via LET A=1, LET B=3, etc., acting as column and row offsets for PRINT AT and TAB). SCROLL is used before each row of output to keep the table scrolling without a “scroll?” prompt. After displaying the full schedule, PAUSE 40000 holds the screen before returning to the method menu.
Module 2: Present Worth Comparison
This module collects data for up to six attributes of up to N investment alternatives into a two-dimensional array D(6,N) (line 140). The fields stored per alternative are first cost, yearly cost, salvage value, and expected life. A common analysis period C is found by searching integer multiples of the longest alternative life L until all life spans divide evenly (lines 310–380).
The present worth formula at line 490 deserves close reading:
Saccumulates the present worth of repeated replacement cycles (excluding the final cycle):(F-V)*(1/((1+A)**(I*E)))forIfrom 1 toZ = C/E - 1.- The final expression combines this with first cost, terminal salvage, and the present worth of the uniform annual cost series:
INT(S + F - V/L + Y*((L-1)/(A*L))), whereLis reused here as the compound interest factor(1+A)**C(line 440), shadowing its earlier role as maximum life. This reuse is a potential source of confusion.
If no common multiple is found within 20 multiples, the program prints a “NO COMMON MULTIPLE FOUND” message (lines 376–378) and falls through to line 520, which does not appear in the listing — this is a dangling GOTO and would cause an error at runtime if triggered.
Module 3: Rate of Return
This module estimates the interest rate at which an investment breaks even, using a three-pass successive-approximation approach rather than a closed-form solution. The core inequality tested in subroutine line 60 is:
P + Y1*PWUA(I,N) >= Y2*PWUA(I,N) + F*PW(I,N)
where PWUA is the present-worth uniform-annuity factor ((1+I)**N - 1)/(I*(1+I)**N) and PW is the present-worth factor 1/(1+I)**N. When the inequality is first satisfied the current I is saved to G via line 50, and GOTO T exits the subroutine back to the appropriate outer loop — T is set to 400, 500, or 600 depending on the current pass (lines 305, 405, 505).
| Pass | Range | Step | GOTO on match |
|---|---|---|---|
| 1 | 0 to 2 | 0.05 | 400 |
| 2 | G−0.05 to G+0.01 | 0.01 | 500 |
| 3 | G−0.01 to G+0.01 | 0.001 | 600 |
The IF I=0 THEN GOTO guard on lines 310, 410, and 510 skips the subroutine when I is exactly zero to avoid division by zero in the annuity formula. After convergence, line 603 rounds to four decimal places and line 603 converts to a percentage: (INT(I*10000+0.5))/100. FAST mode is engaged at line 230 for the iterative computation and SLOW is restored at line 605 before printing the result.
Notable Techniques and Anomalies
- The computed
GOSUB X*10dispatch (line 290) is an efficient and readable alternative to a chain ofIFstatements. - Single-letter constants (
A,B,C,E) for screen layout coordinates reduce repetition but depend on initialization code not present in this listing. - In the present worth module, variable
Lis repurposed between lines 275 (maximum life) and 440 (compound factor), making the formula at line 490 ambiguous without careful reading of execution order. - The
GOTO 520at line 378 targets a line that does not exist in the listing, which would generate an error if no common multiple is found. - In the rate of return module,
GOTO Tuses a variable as the branch target, an efficient idiom for multi-exit subroutine control flow. - Rounding of depreciation and present worth figures throughout uses the standard
INT(x + 0.5)idiom for nearest-integer rounding.
Content
Image Gallery
Source Code
10 LET D=INT (((P-S)/N)+.5)
11 FOR I=A TO N
12 LET V=INT (P-I*D)
13 SCROLL
14 PRINT " ";I;TAB C;"$";D;TAB E;"$";V
15 NEXT I
16 RETURN
20 LET SYD=(N*(N+1))/2
22 FOR I=A TO N
23 LET D=INT ((((N-I+A)*(P-S))/SYD)+.5)
24 LET V=V-D
25 SCROLL
26 PRINT " ";I;TAB C;"$";D;TAB E;"$";V
27 NEXT I
28 RETURN
30 PRINT AT A,C;" INPUT RATE"
31 INPUT R
32 FOR I=A TO N
33 LET D=INT ((R*P*((A-R)**(I-A)))+.5)
34 IF V-D<S THEN LET D=V-S
35 LET V=V-D
36 SCROLL
37 PRINT " ";I;TAB C;"$";D;TAB E;"$";V
38 NEXT I
39 RETURN
90 SAVE "DEPRECIATIO[N]"
100 PRINT AT 0,C;"DEPRECIATION";AT A,C;"▀▀▀▀▀▀▀▀▀▀▀▀"
120 PRINT AT B,B;" INPUT INITIAL VALUE"
130 INPUT P
140 PRINT AT B,B;" INPUT SALVAGE VALUE"
150 INPUT S
160 PRINT AT B,B;" INPUT EXPECTED LIFE"
170 INPUT N
200 CLS
210 PRINT AT B,2;"SELECT DEPRECIATION METHOD:"
220 PRINT AT 7,2;"CODE METHOD"
230 PRINT AT C,B;"1 STRAIGHT LINE"
240 PRINT AT 10,B;"2 SUM OF YEARS DIGITS"
250 PRINT AT 11,B;"3 DECLINING BALANCE"
260 PRINT AT 12,B;"4 NEW DATA"
270 INPUT X
280 IF X<A OR X>B THEN GOTO 210
284 CLS
285 IF X=4 THEN GOTO 100
286 PRINT AT 20,0;"YEAR DEPRECIATION BOOK VALUE"
287 PRINT " 0";TAB 12;"-";TAB E;"$";P
289 LET V=P
290 GOSUB X*10
291 PAUSE 40000
300 GOTO 200
100 PRINT AT 1,3;"PRESENT WORTH COMPARISON"
110 PRINT AT 2,3;"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
120 PRINT AT 5,1;" INPUT NUMBER OF ALTERNATIVES"
125 LET L=0
130 INPUT N
140 DIM D(6,N)
150 PRINT AT 5,1;" INPUT DATA FOR ALTERNATE ";
160 FOR X=1 TO N
170 PRINT AT 5,28;X
180 PRINT AT 7,7;" FIRST COST? "
190 INPUT D(1,X)
220 PRINT AT 7,6;" YEARLY COST?"
230 INPUT D(2,X)
240 PRINT AT 7,3;" SALVAGE VALUE? "
250 INPUT D(3,X)
260 PRINT AT 7,7;"EXPECTED LIFE?"
270 INPUT D(4,X)
275 IF L<D(4,X) THEN LET L=D(4,X)
280 NEXT X
290 PRINT AT 7,7;"INTEREST RATE"
300 INPUT A
310 FOR X=1 TO 20
320 LET S=0
330 LET C=L*X
340 FOR I=1 TO N
350 IF INT (C/D(4,I))-C/D(4,I)<0 THEN GOTO 380
360 LET S=S+1
370 NEXT I
375 IF S=N THEN GOTO 381
376 CLS
377 PRINT " NO COMMON MULTIPLE FOUND";AT 1,8;" FOR YEARS"
378 GOTO 520
380 NEXT X
381 CLS
382 PRINT TAB 5;"ALT";TAB 15;"PRESENT WORTH"
390 FOR X=1 TO N
400 LET F=D(1,X)
410 LET Y=D(2,X)
420 LET V=D(3,X)
430 LET E=D(4,X)
440 LET L=(1+A)**C
450 LET Z=(C/E)-1
455 LET S=0
460 FOR I=1 TO Z
470 LET S=S+(F-V)*(1/((1+A)**(I*E)))
480 NEXT I
490 LET D(6,X)=INT (S+F-V/L+Y*((L-1)/(A*L)))
500 PRINT AT 3+X,6;X;TAB 18;"$";D(6,X)
510 NEXT X
10 GOTO 100
50 LET G=I
60 IF P+(Y1*((1+I)**N-1))/(I*(1+I)**N)>=Y2*((1+I)**N-1)/(I*(1+I)**N)+F/(1+I)**N THEN GOTO T
70 RETURN
100 PRINT AT 0,8;"RATE OF RETURN"
110 PRINT AT 1,8;"▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
120 PRINT AT 5,1;"INPUTS:"
125 PRINT AT 7,3;"INITIAL INVESTMENT?"
130 INPUT P
140 PRINT AT 7,21;"..$";P;AT 9,3;"YEARLY COST?"
150 INPUT Y1
160 PRINT AT 9,14;".........$";Y1;AT 11,3;"YEARLY RETURN?"
170 INPUT Y2
180 PRINT AT 11,16;".......$";Y2;AT 13,3;"FINAL VALUE?"
190 INPUT F
200 PRINT AT 13,14;".........$";F;AT 15,3;"INVESTMENT TERM?"
210 INPUT N
220 PRINT AT 15,18;".....";N;" YEARS"
225 PAUSE 200
230 FAST
300 FOR I=0 TO 2 STEP .05
305 LET T=400
310 IF I=0 THEN GOTO 330
320 GOSUB 50
330 NEXT I
400 FOR I=G-.05 TO G+.01 STEP .01
405 LET T=500
410 IF I=0 THEN GOTO 430
420 GOSUB 50
430 NEXT I
500 FOR I=G-.01 TO G+.01 STEP .001
505 LET T=600
510 IF I=0 THEN GOTO 530
520 GOSUB 50
530 NEXT I
600 IF I<=.001 THEN LET I=0
603 LET I=(INT (I*10000+.5))/100
605 SLOW
610 PRINT AT 17,3;"RATE OF RETURN......";I;" P/C"
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.