This program performs subtraction of two multi-digit integers entered as strings, displaying the operation in a vertical arithmetic layout (minuend, subtrahend, and result). It implements subtraction via the nine’s complement (nines’ complement) method: the subroutine at line 500 replaces each digit of the subtrahend with its nine’s complement (9 minus the digit), and then adds one via the carry initialisation at line 80, effectively computing A − B as A + (9s complement of B) + 1. The subroutine at line 1000 zero-pads both input strings to equal length before processing. Leading zeros in each number are stripped and replaced with spaces for a clean printed display before the result is shown.
Program Analysis
Program Structure
The program is organised into a main flow and two subroutines:
- Lines 1–36: Initialisation, user input of two number strings, and a
PAUSEbefore switching to fast mode. - Lines 38–140: Core computation — pad strings, compute nine’s complement, perform digit-by-digit addition with carry to produce the result string
C$. - Lines 150–260: Leading-zero suppression for display, replacing leading
"0"characters with spaces inA$,B$, andC$. - Lines 270–370: Output the vertical subtraction layout, wait for a keypress, clear screen, and restart.
- Lines 500–540: Subroutine — compute nine’s complement of each digit in
B$, stored inE$. - Lines 1000–1060: Subroutine — zero-pad
A$andB$to equal lengthA.
Nine’s Complement Subtraction
Rather than implementing borrow logic directly, the program uses the classical nine’s complement technique. The subroutine at line 500 replaces each digit d of B$ with 9 - d, storing the result in E$. The main loop then computes A$ + E$ + 1 digit by digit (the +1 is injected via the carry initialisation R=1 forced at line 80 on the first iteration where N=A, i.e. the units column). This is equivalent to computing A - B when A ≥ B, as A + (9s complement of B) + 1 = A - B + 10^n, and the leading carry digit is simply discarded.
Carry Logic
The carry variable R is computed in lines 100–120. D$ is assigned the string form of the column sum (including carry). If LEN D$ <> 1 (i.e. the sum is ≥ 10), then R is set to 1 (carry out). If LEN D$ = 1, carry is cleared to 0. The result digit appended to C$ is always the last character of D$, which correctly gives the units digit of the column sum in both cases.
String Padding — Subroutine 1000
Before computation, both strings are zero-padded to the same length A (set to the maximum of the two input lengths at line 40). The padding loops prepend "0" characters as needed. This ensures all digit indexing from 1 to A is valid for both operand strings.
Leading Zero Suppression
The loops at lines 150–260 scan each padded string from left to right. Any leading "0" is replaced with a space, and the loop exits on the first non-zero, non-space character. This is handled identically for A$, B$, and C$. Line 270 adds a leading space to C$ if it is shorter than A (which can happen when the result has fewer digits than the inputs).
Display and Restart
The result is displayed as a vertical subtraction sum using tab-indented PRINT statements (lines 300–340). The program waits for an INPUT at line 350 (effectively a keypress), clears the screen, and loops back to RUN at line 370. The SLOW/FAST pair (lines 1 and 38) ensures the display is rendered in slow mode but calculation proceeds at full speed.
Bugs and Anomalies
- No negative result handling: If B > A, the nine’s complement method produces an incorrect result (the ten’s complement of the true answer) with no error or warning to the user.
- Carry initialisation via loop condition: The check
IF N=A THEN LET R=R+1at line 80 fires on every pass whenN=A(i.e. only once, on the first iteration), incrementing the pre-cleared carryR=0to 1. This is a slightly fragile way to inject the initial +1, sinceRis not explicitly zeroed before this point in the loop — it retains whatever value it had from initialisation at line 6 (R=0) or a prior run. - Line 998 SAVE: The program saves itself at line 998 and immediately falls through to
RUNat line 999, so the save is triggered only if execution somehow reaches that point (it does not during normal operation). - INPUT at line 350 used as pause: Waiting for
INPUT A$after display reuses the input variable and overwrites the previous operand; this is harmless sinceRUNreinitialises everything, but it is unconventional.
Key Variables
| Variable | Purpose |
|---|---|
A$ | First number (minuend) as a string |
B$ | Second number (subtrahend) as a string |
C$ | Result string, built right-to-left |
E$ | Nine’s complement of B$ |
A | Working length (max of both inputs) |
R | Carry digit between columns |
D$ | Temporary string for current column sum |
N, I | Loop counters |
Content
Source Code
1 SLOW
5 LET C$=""
6 LET R=0
10 PRINT ,,"FIRST NUMBER?"
15 INPUT A$
20 LET A=LEN A$
24 PRINT ,,A$
26 PRINT ,,"SECOND NUMBER?"
30 INPUT B$
34 PRINT ,,B$
36 PAUSE 200
38 FAST
40 IF A<LEN B$ THEN LET A=LEN B$
50 GOSUB 1000
60 GOSUB 500
70 FOR N=A TO 1 STEP -1
80 IF N=A THEN LET R=R+1
100 LET D$=STR$ (R+VAL A$(N)+VAL E$(N))
110 IF LEN D$<>1 THEN LET R=1
120 IF LEN D$=1 THEN LET R=0
130 LET C$=D$(LEN D$)+C$
140 NEXT N
150 FOR N=1 TO A
160 IF A$(N)="0" THEN LET A$(N)=" "
170 IF A$(N)<>" " THEN GOTO 190
180 NEXT N
190 FOR N=1 TO A
200 IF B$(N)="0" THEN LET B$(N)=" "
210 IF B$(N)<>" " THEN GOTO 230
220 NEXT N
230 FOR N=1 TO A
240 IF C$(N)="0" THEN LET C$(N)=" "
250 IF C$(N)<>" " THEN GOTO 270
260 NEXT N
270 IF LEN C$<A THEN LET C$=" "+C$
300 PRINT ,,,," ";A$
310 PRINT " -"
320 PRINT " ";B$
330 PRINT " ="
340 PRINT " ";C$
350 INPUT A$
360 CLS
370 RUN
500 LET E$=B$
510 FOR N=1 TO A
520 LET E$(N)=STR$ (9-VAL B$(N))
530 NEXT N
540 RETURN
998 SAVE "SUBTRACTIO%N"
999 RUN
1000 FOR I=1 TO A-LEN A$
1010 LET A$="0"+A$
1020 NEXT I
1030 FOR I=1 TO A-LEN B$
1040 LET B$="0"+B$
1050 NEXT I
1060 RETURN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
