This program converts numbers between binary, octal, decimal, and hexadecimal bases. The user prefixes their input with B, O, D, or H to indicate the source base, and the program outputs the equivalent value in all four bases. Conversion from non-decimal input uses a subroutine at line 500 that decodes each character via Spectrum character codes (digits start at code 28 offset, letters at offset 21 or adjusted for hex). The outward conversion at line 400 implements a repeated-division algorithm, building the result string from least-significant digit upward using CHR$ encoding. Lines 9550–9570 suggest a SAVE routine used during development or distribution.
Program Structure
The program is divided into four logical sections:
- Lines 100–170: Prompt and input parsing — the user types a prefixed string (e.g.
H1F), and the first character is split off intoB$to determine the base, stored as integerBB. - Lines 180–310: Main conversion loop — calls the input-parsing subroutine if needed, then calls the output subroutine three times (for bases 2, 8, and 16), collecting results into
M$,O$, andH$. - Lines 320–380: Output display of all four representations.
- Lines 400–490 and 500–580: Two subroutines for base conversion.
Subroutine: Input Parsing (Line 500)
Subroutine at line 500 converts a string in base BB into a decimal integer stored in ND. It iterates over each character of N$, extracts its Spectrum character code via CODE, and maps it to a digit value. The offset logic is:
- Digit characters (codes ≤ 37 with offset 28) map correctly:
CODE "0"= 28 on the Spectrum, soZ - 28gives 0–9. - Letter characters (codes > 37) use offset 21 for octal/binary (never needed) or
21 + 7*(BB=16)= 28 for hex, effectively mappingA–Fto 10–15. The boolean expression(BB=16)evaluates to 1 (true) or 0 (false) as a numeric multiplier — a classic Spectrum BASIC idiom.
The accumulation is the standard Horner’s method: ND = ND * BB + digit.
Subroutine: Output Conversion (Line 400)
Subroutine at line 400 converts ND (decimal) to base B as a string in Y$. It uses repeated division: remainder digits are prepended to Y$ via string concatenation. The same character-code trick maps digit values back to display characters:
- Values 0–9:
CHR$(Y + 28)yields"0"–"9". - Values 10–15 (hex):
K = 21 + 7*(B=16) = 28, but wait — actually whenY > 9, line 460 setsK = 21 + 7*(B=16). For base 16, this givesK = 28, soCHR$(10+28) = CHR$(38)which is"A"on the Spectrum (uppercase letters start at code 38). This is correct for A–F.
Notable Techniques and Idioms
- Boolean arithmetic:
(BB=16)and(B=16)return 1 or 0 and are used as multipliers to conditionally adjust the character offset, avoiding IF/THEN branches inside the subroutines. - String slicing:
N$(2 TO LEN N$)strips the prefix character, a standard Spectrum string-slice idiom. - Input base passthrough: Lines 230, 270, and 310 detect when the input base matches the target output base and substitute the original
N$string directly, avoiding a round-trip conversion that could introduce formatting differences. - Reuse of variable
K: The same variableKis used for the character-code offset in both subroutines, keeping the code compact.
Bugs and Anomalies
| Location | Issue |
|---|---|
| Lines 200, 240, 280 | Each block sets B unconditionally when BB doesn’t match, then calls GOSUB 400. However, if BB=2 and BB<>8 and BB<>16, all three GOSUB calls fire. This is correct because each call overwrites Y$, but B is set just before each call, so the logic is sound despite looking fragile. |
| Line 380 | GOTO 100 is unreachable — it follows STOP at line 370 and is never jumped to. The program simply halts after displaying results. |
| Line 140–170 | BB is never initialised before the IF chain. If an unrecognised prefix is entered, BB retains its previous value, which could cause incorrect conversion silently. |
| Hex input letters | The condition Z>37 in line 550 (where Z is the character code) correctly identifies letters (A=38 onwards on the Spectrum). However, lowercase hex input is not handled; only uppercase A–F will work. |
Content
Source Code
100 PRINT "ADD ONE OF THESE PREFIXES TO NO.B=BINARY D=DECIMAL O=OCTAL H=HEX"
110 INPUT N$
120 LET B$=N$(1)
130 LET N$=N$(2 TO LEN N$)
140 IF B$="B" THEN LET BB=2
150 IF B$="O" THEN LET BB=8
160 IF B$="D" THEN LET BB=10
170 IF B$="H" THEN LET BB=16
180 IF BB<>10 THEN GOSUB 500
190 IF BB=10 THEN LET ND=VAL N$
200 IF BB<>2 THEN LET B=2
210 GOSUB 400
220 LET M$=Y$
230 IF BB=2 THEN LET M$=N$
240 IF BB<>8 THEN LET B=8
250 GOSUB 400
260 LET O$=Y$
270 IF BB=8 THEN LET O$=N$
280 IF BB<>16 THEN LET B=16
290 GOSUB 400
300 LET H$=Y$
310 IF BB=16 THEN LET H$=N$
320 PRINT "NUMBER IN OTHER BASES"
330 PRINT "DECIMAL:";ND
340 PRINT "BINARY :";M$
350 PRINT "OCTAL :";O$
360 PRINT "HEXADEC:";H$
370 STOP
380 GOTO 100
400 LET Z=ND
410 LET Y$=""
420 LET Y=Z
430 LET Z=INT (Z/B)
440 LET Y=Y-B*Z
450 LET K=28
460 IF Y>9 THEN LET K=21+(7*(B=16))
470 LET Y$=CHR$ (Y+K)+Y$
480 IF Z>0 THEN GOTO 420
490 RETURN
500 LET ND=0
510 LET Z=0
520 FOR I=1 TO LEN N$
530 LET Z=CODE N$(I)
540 LET K=28
550 IF Z>37 THEN LET K=21+(7*(BB=16))
560 LET ND=ND*BB+Z-K
570 NEXT I
580 RETURN
\n9550 CLS
\n9560 SAVE "BAS%E"
\n9570 GOTO 100
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.


