ANY-BASE is a general number base conversion utility that converts an integer from any base to any other base. The program accepts three inputs — the argument, the source base, and the target base — then performs conversion through base 10 as an intermediate step when neither base is 10. A subroutine at line 390 builds the result digit by digit using repeated integer division and a positional accumulator. A second subroutine at line 500 attempts to compute a power-of-10 scaling factor using the LN function, though the formula contains a known error (discussed below). The program validates that all three inputs are non-negative integers before proceeding.
Program Structure
The program is organized into a main input/validation loop, a conversion dispatch block, two subroutines, and a display section. Control flow is as follows:
- Lines 20–150: Clear screen, prompt for and validate the argument (
C), source base (D), and target base (E). Each input is checked withIF X <> INT (ABS X)to reject non-integers. - Lines 160–240: If the source base is not 10, convert the argument from base
Dto base 10 via the subroutine at line 390, storing the decimal result inN. - Lines 250–330: If the target base is not 10, convert the base-10 intermediate value
Nto baseEvia the same subroutine at line 390. - Lines 340–380: Display the result and loop back to the input prompt.
- Lines 390–470: Subroutine — converts integer
Sfrom baseRto baseQusing repeated division, accumulating intoN. - Lines 500–510: Subroutine — attempts to compute a power-of-10 scaling factor using the
LNfunction, storing the result inV.
Conversion Algorithm (Lines 390–470)
The digit-extraction subroutine uses repeated integer division. Variable P holds the working value, R is the source base, Q is the positional multiplier base, and M tracks the digit position. Each iteration extracts the least-significant digit of P in base R, scales it by Q^M, and adds it to accumulator N. The +.5 in line 440 is a rounding guard against floating-point error.
The termination condition at line 455 reads IF P = O THEN RETURN (where O is presumably initialized to 0 elsewhere, though no explicit initialization of O appears in the listing — this relies on the default value of unassigned variables being 0). The raw listing shows \{16}\{0} before O, which are control characters that may have been present in the original file and do not affect runtime behavior if O evaluates to 0.
LN-Based Scaling Subroutine (Line 500)
Line 500 attempts to compute the number of decimal digits needed to represent a number in base U — essentially floor(log10(U)) + 1 or a similar scaling value — using the formula:
LET V = INT (10 * 1 + INT (LN 10 * U - 1 / LN 10)) + .5
This formula is malformed. Due to operator precedence, 1 / LN 10 is evaluated before multiplication by U, which is not the intended order. The author’s inline comments at lines 480–490 (“LN is perhaps the function?” and “Somebody want to fix this up?”) explicitly acknowledge that the subroutine is broken and unfinished. Because the main conversion loop calls this subroutine (via GO SUB 500) and uses its result V as a multiplier, conversions involving a non-10 source or target base will produce incorrect output.
Notable Techniques and Idioms
- Input validation loop: The pattern
IF X <> INT (ABS X) THEN GO TO linerejects fractional or negative inputs cleanly without a dedicated error message. - Base-10 as pivot: The program routes all conversions through decimal, requiring at most two passes through the digit-extraction subroutine — an approach that keeps code compact but relies on line 500 working correctly.
- Rounding guard: Adding
0.5before truncation withINTcompensates for floating-point representation errors in intermediate arithmetic. - Uninitialized variable as zero: Variable
Ois used as a zero constant throughout (lines 390, 400, 455). This relies on the system initializing all numeric variables to 0 at program start — a valid assumption, but fragile if the program is ever restarted mid-session withOleft at a non-zero value. - SAVE with LINE: Line 520 uses
SAVE "ANY-BASE" LINE 20to save the program with an auto-run entry point at line 20, skipping theREMtitle line.
Bugs and Anomalies
| Location | Issue |
|---|---|
| Line 500 | The LN-based formula is acknowledged as broken by the author’s own comments. The expression LN 10 * U - 1 / LN 10 does not correctly compute the intended logarithmic scaling due to precedence. |
| Lines 390, 400, 455 | Variable O is used as a zero sentinel but is never explicitly initialized with LET O = 0. This works on a fresh run but is a latent bug. |
| Line 360 | The PRINT statement is missing a trailing space before "TO BASE 10", so the numeric value of S will run directly into the string. |
| Lines 480–490 | Author comments left in the final listing indicate the program was published in an incomplete state. |
Content
Source Code
10 REM "ANY BASE TO ANY BASE CONVERSION"
20 CLS
30 PRINT "GENERAL BASE CONVERSION"
40 PRINT "ENTER ARGUMENT?";
50 INPUT C
60 PRINT C
70 IF C <> INT (ABS C) THEN GO TO 40
80 PRINT "ENTER OLD BASE?";
90 INPUT D
100 PRINT D
110 IF D <> INT (ABS D) THEN GO TO 80
120 PRINT "ENTER NEW BASE?";
130 INPUT E
140 PRINT E
150 IF E <> INT (ABS E) THEN GO TO 120
160 IF D <>10 THEN GO TO 190
170 LET N=C
180 GO TO 250
190 LET U=D
200 GO SUB 500
210 LET S=C
220 LET Q=D
230 LET R=V
240 GO SUB 390
250 IF E <>10 THEN GO TO 280
260 LET S=N
270 GO TO 340
280 LET U=E
290 GO SUB 500
300 LET S=N
310 LET Q=V
320 LET R=E
330 GO SUB 390
340 PRINT C;" TO BASE ";D
350 PRINT "=";N;" TO BASE ";E
360 IF D <>10 AND E <>10 THEN PRINT "=";S;"TO BASE 10"
370 PRINT " "
380 GO TO 40
390 LET M=O
400 LET N=O
410 LET P=S
420 LET T=P
430 LET P= INT (P/R)
440 LET N=N+ INT ((T-P*R)*Q*M+.5)
450 IF P=\{16}\{0}O THEN RETURN
460 LET M=M+1
470 GO TO 420
480 REM LN REM LN is perhaps the function?
490 REM Somebody wantto fix ths up?
500 LET V= INT (10*1+ INT (LN 10*U-1\{16}\{0}/ LN 10))+.5
510 RETURN
520 SAVE "ANY-BASE" LINE 20
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
