READY.000 C64 Coding

Quadratic Equations: Solving ax²+bx+c=0 in BASIC

QUADRATIC EQUATIONS

Type
Maths
Language
Commodore BASIC V2
Length
64 lines · 7 blocks (1,551 bytes)
Keys
Numbers and RETURN; Y for another equation
Special keys
None

Type in three numbers and the C64 solves ax² + bx + c = 0. It writes the equation out the way you would on paper, shows the discriminant, finds two real roots, one double root or two complex ones, and then checks its own answer by putting it back into the equation. If a is zero it is not a quadratic at all, and the program says what it is instead.

The C64 solving x squared plus x minus 1: discriminant 5, roots .618 and -1.618, check 0
x² + x − 1 = 0: two real roots, and the check comes back 0. Running in VICE.

The listing

Type every letter without SHIFT. The ^ is the up-arrow key, next to RESTORE: on the C64 it is the power sign, and it appears on the screen as ↑. Click each line to tick it off, or press ↓ .PRG.

A little maths first

Every quadratic equation can be solved with the same formula:

     -B + SQR(D)          -B - SQR(D)
X1 = -----------     X2 = -----------
         2*A                  2*A

where D = B*B - 4*A*C

D, the discriminant, decides everything. If it is positive there are two different real roots. If it is zero the two roots meet in one, a double root. If it is negative there is no real square root of D, and the roots are complex numbers: a real part plus or minus an imaginary part, written with i, the square root of −1.

How it works

LinesBlock
100–190Setup, the rounding function, input
200–340The equation as text, the discriminant, which case
400–480When a is 0, and “another one?”
500–750Three subroutines: real, double and complex roots
800–870Subroutine: add one term to the equation text
900–920Subroutine: check a root

Line 110: a function of your own

DEF FN R(X) defines a one-line function that rounds to four decimal places: multiply by 10,000, add a half, cut off the fraction, divide back. Why bother? The C64 stores numbers in binary with about nine significant digits, and most decimals cannot be stored exactly. Solve x² + x − 1 = 0 without rounding and put the root back in: the C64 says the result is 4.65661287E-10, not 0. That is 0.000000000466, a rounding error in the ninth digit. FN R hides that noise, and the check prints a clean 0.

Lines 170–190: INPUT

INPUT " A";A prints the text, adds a question mark and waits for a number and RETURN. Type something that is not a number and the C64 answers ?REDO FROM START and asks again, so the program never has to check.

Lines 200–250 and 800–870: writing the equation

Printing 1X^2+-5X+6 would be correct and ugly. The subroutine at 800 adds one term at a time to E$ and writes it the way a person would:

  • A term with coefficient 0 is left out completely (line 810).
  • STR$ puts a space in front of positive numbers, the place where the minus sign would go. MID$(STR$(ABS(V)),2) takes the number without its sign and without that space (line 820).
  • A coefficient of 1 is not written in front of x: x², not 1x². The constant term keeps its 1 (line 830).
  • Between terms the sign gets a space on each side; the first term gets just a minus, or nothing (lines 840–850).

E$ is emptied on line 210 before every new equation. If all three numbers are 0 nothing is added, and line 240 writes “0” so the screen does not say EQUATION:  = 0.

Lines 280–340: choosing the case

The discriminant is worked out once and printed, then exactly one of three subroutines runs. Each one prints its roots and returns, and line 340 jumps over the a = 0 block to the question at the end.

Lines 500–640: real roots and the check

The two subroutines are the formula, line for line. Each then puts the first root back into the equation through the subroutine at 900. If the result is 0, the root is right: the program checks its own answer, which is a good habit in any language.

The C64 solving x squared minus 2x plus 5: discriminant -16, roots 1 + 2I and 1 - 2I
A negative discriminant: two complex roots, 1 ± 2i.

Lines 700–750: complex roots

BASIC V2 has no complex numbers, but it does not need them. The real part is −b/2a and the imaginary part is √(−D)/2a, both ordinary numbers. ABS keeps the imaginary part positive even when a is negative, so the screen shows 1 + 2i and 1 − 2i, never 1 + -2i. Line 730 turns it into a string with no leading space, so the i sits right after the number.

The C64 solving 2x minus 4 = 0: linear, x = 2
With a = 0 the program writes the equation as 2x − 4 = 0 and solves it as a linear one.

Lines 400–430: when a is 0

With a = 0 the formula would divide by zero. The equation is then bx + c = 0, and there are three possibilities: one solution x = −c/b; no x at all (5 = 0 can never be true); or every x (0 = 0 always is).

Lines 450–480: another one?

GET reads a single key without needing RETURN, and line 460 loops until there is one. Y clears the screen and starts again; any other key ends the program.

Numbers to try

abcEquationThe C64 says
1-56x² − 5x + 6 = 0x1 = 3, x2 = 2
1-44x² − 4x + 4 = 0double root x = 2
1-25x² − 2x + 5 = 0x = 1 ± 2i
11-1x² + x − 1 = 0x1 = .618, x2 = −1.618
-104−x² + 4 = 0x1 = −2, x2 = 2
02-42x − 4 = 0linear: x = 2
0000 = 0every x is a solution
0055 = 0no solution

The fourth one is special: 1.618 is the golden ratio, and .618 is one over it. The C64 leaves out the 0 before the decimal point, and puts a negative number's minus sign in the space where a positive number has its blank, which is why you see X2 =-1.618.

Try this

  • More decimals: change both 1E4 in line 110 to 1E6.
  • Check the second root too: add :X=X2:GOSUB 900 to the end of line 540.
  • Check complex roots: harder, since BASIC has no i. Hint: for x = p + qi, the real part of ax² + bx + c is a(p² − q²) + bp + c and the imaginary part is (2ap + b)q. Both should be 0.

Run it

Press ↓ .PRG on the listing and drop the file on a VICE window. Source and program are also on GitHub.

Three equations, typed in and solved in VICE:

VS Code with QUADRATIC.bas open next to VICE listing the program
In the lab: QUADRATIC.bas in VS Code, and the same lines listed on the C64.

Comments