--- title: "Math" id: 57440 type: "computer_media" slug: "math-3" url: "http://localhost/computer_media/math-3/" markdown_url: "http://localhost/computer_media/math-3.md" published_at: "2024-10-05T13:45:38+00:00" modified_at: "2026-04-03T07:58:30+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/241_Math.png" excerpt: "A complete eight-topic maths toolkit packed into one program, featuring Euclidean GCD, bisection zero-finding, Horner polynomial evaluation, and a coordinate-scaled function plotter." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Mathematics" slug: "mathematics" taxonomy: "genre" url: "http://localhost/type/mathematics/" media_contents: - id: 56736 title: "Timex Sinclair Public Domain Library Tape 1005" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1005/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/241_Math.png" media_type_tags: "Mathematics" --- # Math This program is a multi-section mathematics toolkit covering eight topics: greatest common divisor (Euclidean algorithm), least common multiple, prime factorisation, quadratic equations, zero-finding for functions, polynomial evaluation, polynomial multiplication, and function plotting. The zero-finding routine (lines 1440–1750) uses a sign-change bisection method with user-supplied interval, step size, and epsilon tolerance. The polynomial evaluator (lines 1940–1990) applies Horner’s method for efficient computation. The function plotter (lines 2820–2890) maps mathematical coordinates to the 64×44 pixel display grid using scaling factors MX and MY, and plots the hardcoded function sin(x)+sin(2x). *** ## Program Analysis ### Program Structure The program is organised as a menu dispatcher with eight numbered sections. Lines 2–120 display the main menu, line 150 calls the key-reading subroutine at 8800, and lines 155–190 dispatch to each section via a chain of `IF … THEN GOTO` statements. Each section ends by calling the “press a key” subroutine at 9000, which offers return-to-index or re-run of the current section. | Menu Option | Topic | Start Line | | --- | --- | --- | | 1 | Greatest Common Divisor | 200 | | 2 | Smallest Common Multiple | 400 | | 3 | Prime Factoring | 700 | | 4 | Quadratic Equation | 1000 | | 5 | Zeroes of a Function | 1300 | | 6 | Value of a Function | 1800 | | 7 | Polynomial (multiplication) | 2100 | | 8 | Plot of Functions | 2500 | ### Key Input Subroutine (line 8800) The subroutine at line 8800 polls `INKEY$` in a tight loop, rejecting any character outside “1”–”8″. Once a valid digit is detected it reads `INKEY$` a second time at line 8810 with `LET W=VAL INKEY$` to convert it to a number. This introduces a potential race condition: if the key is released between lines 8800 and 8810, `INKEY$` returns an empty string and `VAL ""` yields 0, sending the dispatcher to an unmatched branch. In practice SLOW mode makes this unlikely but it is a latent bug. ### Greatest Common Divisor (lines 200–330) The implementation is the classic Euclidean algorithm: compute quotient `Q=INT(A/B)`, remainder `R=A-Q*B`, reassign `A=B, B=R`, and loop while `R>0`. The result is left in `A` and printed as “LCD=” (a labelling quirk — the correct abbreviation for Largest Common Divisor/Greatest Common Divisor is GCD or HCF). ### Smallest Common Multiple (lines 400–620) The SCM routine uses brute-force trial: starting from `X=A`, it increments `X` by 1 until `X` is divisible by all three inputs A, B, and C. Each divisibility test restarts the scan from the current `X` (via `GOTO 510`) rather than continuing forward, which is correct behaviour. This approach is slow for large inputs but straightforward. ### Prime Factorisation (lines 700–930) The routine at line 800 takes the absolute value of the input, then iterates `I` from 2 to the original value `Z`. For each candidate divisor, an inner loop repeatedly divides and counts the multiplicity `N`. A running product `T` tracks how much of the number has been accounted for; when `T=E` (the original absolute value) the outer `FOR` loop is exited early via `GOTO 910`. Negative inputs are handled by printing a leading minus sign before the factorisation. ### Quadratic Equation (lines 1000–1220) The discriminant is computed as `Q=B*B-4*A*C`. If negative, “NO REAL SOLUTION” is printed. Otherwise the formula is evaluated as `Q=SQR Q/(2*A)` and `C=-B/(2*A)`, giving `X1=C+Q` and `X2=C-Q`. Note that operator precedence means `SQR Q/(2*A)` is parsed as `(SQR Q)/(2*A)`, which is the intended formula. ### Zero-Finding by Bisection (lines 1300–1780) This section implements a sign-change bisection search. The outer scan (lines 1440–1600) steps across the interval `[XA, XE]` with step `H`, calling the function subroutine `FCT` at line 1610 and watching for a sign change in `Y`. When a sign change is detected, the bisection refinement subroutine `SFZ` at line 1640 narrows the bracket until `ABS(Y) < E`. The function itself is hardcoded at line 1620 as `Y = X³ - 4X² - 11X + 30`, which has roots at x = -3, 2, and 5. `FAST` mode is engaged for the numerical search and `SLOW` restored afterwards. Subroutine addresses are stored in variables (`LET FCT=1610`, `LET SFZ=1640`) and called with `GOSUB FCT` — a notable technique exploiting the fact that `GOSUB` accepts a numeric variable as its target line number. ### Polynomial Evaluation — Horner’s Method (lines 1800–2090) Coefficients are stored in array `W()` with `W(1)` holding the constant term `A(0)`. The evaluation at lines 1940–1990 applies Horner’s scheme: initialise with the leading coefficient, then repeatedly multiply by `X` and add the next coefficient working down to degree 1, finally adding `W(1)`. This minimises multiplications compared to naive power evaluation. ### Polynomial Multiplication (lines 2100–2495) Two polynomials are entered separately. The first polynomial’s coefficients are copied into array `A()` of size `K+1`. The product array `E()` is initialised to zero, then the convolution sum `E(I+J-1) += W(I)*A(J)` is computed for all pairs `(I,J)`. The result is printed as a list of coefficients `E(0)` through `E(K+N)`. This is a correct discrete convolution of the coefficient arrays. ### Function Plotter (lines 2500–2950) The plotter draws axes at pixel position (31, 22) — roughly centred on the 64×44 display. Scaling factors are computed as `MX=63/|XE-XA|` and `MY=43/|YE-YA|`. The plotted function is hardcoded at line 2840 as `Y = SIN(X) + SIN(2*X)`. Coordinate transformation applies at lines 2850–2860: `X = X*MX + X0`, `Y = Y*MY + Y0`. A bounds check at line 2870 prevents `PLOT` errors for out-of-range points. ### Navigation Subroutine (line 9000) The subroutine at 9000 displays a two-line prompt, waits with `PAUSE 30` to debounce, then enters an `INKEY$` poll loop. Pressing “R” returns to the main menu index (line 5, which is the `REM` crediting the source book). Any other key returns to the caller for re-entry of the same section. Line 9040 (`SAVE "1024%1"`) is unreachable dead code following the conditional returns. ### Notable Techniques and Anomalies - Variable-target `GOSUB FCT` (lines 1450, 1500, 1540, 1670) stores line numbers in variables — an efficient and flexible dispatch mechanism. - `FAST`/`SLOW` mode switching (lines 1310 and 1760) is used only in the zero-finding section, where the iterative bisection benefits most from faster execution. - The SCM section accepts three inputs but the algorithm restarts from `X=A` rather than incrementing by A; for large coprime numbers this will be very slow. - The prime factorisation loop iterates `FOR I=2 TO Z` using the original (potentially large) value of Z rather than the progressively reduced quotient, making it inefficient for numbers with large prime factors. - The key-reading race condition at lines 8800–8810 (double `INKEY$` read) could return `W=0`, causing all dispatch conditions at lines 155–190 to fail silently and loop back to the menu display. - Section 6 (“Value of a Function”) shares the polynomial input subroutine code with section 7 but duplicates it at lines 1830–1930 rather than sharing lines 2130–2230, increasing program size unnecessarily. ## Source Code ``` 2 SLOW 5 REM "FROM BOOK BY ING. WINFRIED HOFACKER PUBLISHING COMPANY" 10 CLEAR 15 CLS 20 PRINT "WELCOME TO MATHEMATICS" 25 PRINT 30 PRINT "PRESS DESIRED SELECTION NUMBER" 35 PRINT 40 PRINT "1> LARGEST COMMON DIVISOR" 45 PRINT 50 PRINT "2> SMALLEST COMMON MULTIPLE" 55 PRINT 60 PRINT "3> PRIME FACTORING OF NUMBERS" 65 PRINT 70 PRINT "4> QUADRATIC EQUATION" 75 PRINT 80 PRINT "5> ZEROES OF A FUNCTION" 85 PRINT 90 PRINT "6> VALUE OF A FUNCTION" 95 PRINT 100 PRINT "7> POLYNOMIAL" 105 PRINT 110 PRINT "8> PLOT OF FUNCTIONS" 120 PRINT AT 21,4;" RUN IN SLOW MODE" 150 GOSUB 8800 155 IF W=1 THEN GOTO 200 160 IF W=2 THEN GOTO 400 165 IF W=3 THEN GOTO 700 170 IF W=4 THEN GOTO 1000 175 IF W=5 THEN GOTO 1300 180 IF W=6 THEN GOTO 1800 185 IF W=7 THEN GOTO 2100 190 IF W=8 THEN GOTO 2500 200 CLS 205 CLEAR 208 PRINT "LARGEST COMMON DIVISOR" 209 PRINT 210 PRINT "A="; 220 INPUT A 230 PRINT A 240 PRINT "B="; 250 INPUT B 260 PRINT B 270 LET Q=INT (A/B) 280 LET R=A-Q*B 290 LET A=B 300 LET B=R 310 IF R>0 THEN GOTO 270 320 PRINT "LCD=";A 325 GOSUB 9000 330 GOTO 200 400 CLS 405 CLEAR 408 PRINT "SMALLEST COMMON MULTIPLE" 409 PRINT 410 PRINT "A="; 420 INPUT A 430 PRINT A 440 PRINT "B="; 450 INPUT B 460 PRINT B 470 PRINT "C="; 480 INPUT C 490 PRINT C 500 LET X=A 510 IF INT (X/A)=X/A THEN GOTO 540 520 LET X=X+1 530 GOTO 510 540 IF INT (X/B)=X/B THEN GOTO 570 550 LET X=X+1 560 GOTO 510 570 IF INT (X/C)=X/C THEN GOTO 600 580 LET X=X+1 590 GOTO 510 600 PRINT "SCM=";X 610 GOSUB 9000 620 GOTO 400 700 CLS 705 CLEAR 708 PRINT "PRIME FACTORING OF NUMBERS" 710 PRINT 720 PRINT "NUMBER="; 730 INPUT Z 740 PRINT Z 750 PRINT Z;"="; 760 IF Z<0 THEN PRINT "-"; 770 PRINT "1"; 800 LET Z=ABS Z 805 LET E=Z 808 LET T=1 810 FOR I=2 TO Z 820 LET N=0 830 IF Z/I<>INT (Z/I) THEN GOTO 870 840 LET Z=Z/I 850 LET N=N+1 860 GOTO 830 870 IF N=0 THEN GOTO 900 880 FOR J=1 TO N 885 PRINT "*";I; 887 LET T=T*I 888 IF T=E THEN GOTO 910 890 NEXT J 900 NEXT I 910 PRINT 920 GOSUB 9000 930 GOTO 700 1000 CLS 1002 CLEAR 1004 PRINT "QUADRATIC EQUATION" 1006 PRINT 1008 PRINT "A*X*X+B*X+C=0" 1010 PRINT "A="; 1020 INPUT A 1030 PRINT A 1040 PRINT "B="; 1050 INPUT B 1060 PRINT B 1070 PRINT "C="; 1080 INPUT C 1090 PRINT C 1100 LET Q=B*B-4*A*C 1110 IF Q<0 THEN GOTO 1200 1120 LET Q=SQR Q/(2*A) 1130 LET C=-B/(2*A) 1140 LET X1=C+Q 1145 PRINT "X1="; 1150 PRINT X1 1160 LET X2=C-Q 1165 PRINT "X2="; 1170 PRINT X2 1180 GOSUB 9000 1190 GOTO 1000 1200 PRINT "NO REAL SOLUTION" 1210 GOSUB 9000 1220 GOTO 1000 1300 CLS 1302 CLEAR 1304 PRINT "ZEROES OF A FUNCTION" 1305 PRINT 1306 REM "FUNCTION IS FCT" 1308 REM "SEARCHING FOR ZEROES IS SFZ" 1310 FAST 1312 PRINT "XA="; 1315 INPUT XA 1320 PRINT XA 1330 PRINT "XE="; 1340 INPUT XE 1350 PRINT XE 1360 PRINT "H="; 1370 INPUT H 1380 PRINT H 1390 PRINT "EPS="; 1400 INPUT E 1410 PRINT E 1420 LET FCT=1610 1430 LET SFZ=1640 1440 LET X=XA 1450 GOSUB FCT 1460 LET YA=Y 1470 LET XA=X 1480 LET X=XA+H 1490 IF X>XE THEN GOTO 1760 1500 GOSUB FCT 1510 IF SGN Y=SGN YA THEN GOTO 1580 1520 LET YN=Y 1530 LET XN=X 1540 GOSUB SFZ 1550 PRINT "ZERO AT POSITION X=";X 1560 IF X"2" AND INKEY$<>"3" AND INKEY$<>"4" AND INKEY$<>"5" AND INKEY$<>"6" AND INKEY$<>"7" AND INKEY$<>"8" THEN GOTO 8800 8810 LET W=VAL INKEY$ 8815 RETURN 9000 PRINT AT 20,0;"PRESS TO GET INDEX,PRESS ANY" 9003 PRINT AT 21,0;"OTHER KEY TO RERUN THIS SECTION" 9005 PAUSE 30 9010 IF INKEY$="" THEN GOTO 9010 9015 IF INKEY$="R" THEN GOTO 5 9020 IF INKEY$<>"R" THEN RETURN 9040 SAVE "1024%1" 9050 GOTO 2 ```