This program calculates and displays a month-by-month savings plan based on user-supplied initial balance, monthly deposit amount, annual interest rate, and number of months to simulate. Each iteration calls a subroutine at line 520 that adds the monthly deposit, computes interest by dividing the annual rate by 1200, and rounds both the interest and running balance to two decimal places using the INT(x*100+0.5)/100 idiom. A cumulative interest accumulator is maintained across all months, with a final summary printed after the loop. The program offers a restart option that returns to line 100, resetting the display but re-entering the same subroutine without reinitialising all variables.
Program Analysis
Program Structure
The program is organised into three logical sections:
- Introduction and input (lines 100–330): prints a description, then collects the initial amount (
J), monthly savings amount (P), yearly interest rate (I), and number of months (M). - Display loop (lines 340–460): clears the screen, prints headers, and iterates from 1 to
M, calling subroutine 520 each pass and printing per-month data. - Subroutine (lines 520–600): performs the core financial calculation — adding the deposit, computing and rounding interest, updating the balance, and accumulating cumulative interest.
Variable Usage
| Variable | Purpose |
|---|---|
J | Initial amount entered by the user; preserved for display |
B | Running balance, initialised to J |
P | Monthly savings amount (deposit) |
K | Copy of P, used only in the header display |
I | Annual interest rate as a percentage |
MI | Monthly interest rate as a decimal ((I/12)/100) |
IN | Interest earned in the current month |
CI | Cumulative interest across all months |
M | Number of months to display |
A | Loop counter (reused as restart yes/no flag at line 490) |
T | Inner delay loop counter |
Rounding Technique
Both the monthly interest and the running balance are rounded to two decimal places using the classic idiom INT(x * 100 + 0.5) / 100 (lines 550, 570–580). The half-up rounding on the balance at line 570 uses INT(B*100+0.5) and then divides by 100 on the next line, splitting the operation across two statements — likely for clarity or to stay within a line-length limit.
Delay Loop
Lines 420–430 implement a busy-wait delay of 400 iterations after printing each month’s row (FOR T=1 TO 400: NEXT T). This was a common technique to slow scrolling output to a readable pace on machines without a built-in PAUSE command or where PAUSE required a keypress.
Notable Idioms and Techniques
- The
PRINT J/PRINT P/PRINT I/PRINT Mlines immediately after eachINPUTecho the entered value back to the screen, which was necessary on ZX81/TS1000 becauseINPUTdoes not permanently display the typed value after execution. - Line 350 uses
PRINT "MONTHLY SAVINGS PLAN"— theis a zmakebas escape representing character code 72 (the letter ‘H’), which appears to be a stray character or cursor-positioning artefact rather than intentional formatting. - Variable
Kis assignedPat line 250 and used only in the header at line 370 ("MONTHLY SAVINGS AMT=$ ";K), whilePitself is used in the calculation subroutine. SincePis never modified,Kis redundant.
Bugs and Anomalies
- Typo in header: Line 360 prints
INTEREST R8TE— the digit8appears in place of the letterA, a likely keyboard entry error. - Typo in prompt: Line 310 reads
"ENTER THE NR OF MONTHS TK BE DISPLAYED"—TKshould beTO. - Restart does not reset state: When the user enters
1at line 490, the program jumps to line 100, which re-inputs all values but does not reinitialiseCI(cumulative interest) orB(balance).CIis only set to 0 at line 131, which is bypassed on restart. This means a second run will carry over the cumulative interest and balance from the first run, producing incorrect results. - Variable
Areuse:Aserves as both theFORloop counter (lines 390–440) and the yes/no restart input (line 490). After the loop completes,Aholds the valueM; overwriting it with the user’s input at line 490 is harmless but potentially confusing.
SAVE Line
Line 700 contains SAVE "1002%9" where %9 is an inverse-video digit 9, serving as an auto-run flag embedded in the filename. Line 710 (RUN) would execute automatically after loading.
Content
Source Code
10 REM %M%O%N%T%H%L%Y% %S%A%V%I%N%G%S% %P%L%A%N
100 PRINT "%M%O%N%T%H%L%Y% %S%A%V%I%N%G%S% %P%L%A%N"
130 PRINT
131 LET CI=0
140 PRINT "THIS PROGRAM CALCULATES AND DISPLAYS"
150 PRINT "A MONTHLY SAVINGS PLAN,GIVEN THE"
160 PRINT "INITIAL AMOUNT,MONTHLY SAVINGS"
170 PRINT "AMOUNT,THE YEARLY INTEREST RATE,"
180 PRINT "AND THE NUMBER OF MONTHS TO BE DISPLAYED."
190 PRINT
200 PRINT "ENTER INITIAL AMT OF PLAN"
210 INPUT J
220 PRINT J
230 PRINT "ENTER MONTHLY SAVINGS AMT."
240 INPUT P
241 PRINT P
250 LET K=P
260 LET B=J
270 PRINT
280 PRINT "ENTER YRLY INT.RATE(PCT)"
290 INPUT I
300 PRINT I
310 PRINT "ENTER THE NR OF MONTHS TK BE DISPLAYED"
320 INPUT M
321 PRINT M
330 LET MI=(I/12)/100
340 CLS
350 PRINT "MONTHLY SAVINGS PLAN"
360 PRINT "INITIAL AMOUNT=$ ";J,"INTEREST R8TE= ";I
370 PRINT "MONTHLY SAVINGS AMT=$ ";K,"STARTING AMT=$ ";J+K
380 PRINT "MONTH","BAL","INT","CUM.INT."
390 FOR A=1 TO M
400 GOSUB 520
410 PRINT A,B,IN,CI
420 FOR T=1 TO 400
430 NEXT T
440 NEXT A
450 PRINT "BALANCE AFTER ";M;" MONTHS=$ ";B
460 PRINT "TOTAL CUMULATIVE INTEREST=$ ";CI
470 PRINT "ANOTHER DISPLAY?"
480 PRINT "1=YES/0=NO"
490 INPUT A
500 IF A=1 THEN GOTO 100
510 STOP
520 REM CALC MONTHLY DATA
530 LET B=B+P
540 LET IN=B*MI
550 LET IN=INT (IN*100+.5)/100
560 LET B=B+IN
570 LET B=INT (B*100+.5)
580 LET B=B/100
590 LET CI=CI+IN
600 RETURN
700 SAVE "1002%9"
710 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
