Quote
Julian Jones <jjo...@cmcvax.mckenna.edu> wrote:
> Program quadratic (input, output);
> {This program computes the answer, x, to the quadratic equation
> ax^2+bx+c=0}
> var
> a, b, c : real;
> const
> d = sqr(b)-(4*a*c);
As has already been said, you cannot compute a compile-time constant
based on run-time variables.
I suggest, here you simply declare a variable to hold the discriminant,
and compute it later, when you will have read the values needed:
var
d: real;
Alas, standard Pascal does not allow you to express your thoughts
lucidly. You cannot define run-time constants (i.e. constants
calculated from values obtained at run-time). You cannot even define
initial values for variables (which is the 1st work-around for your
problem coming to my mind).
Quote
> begin
> writeln ('Input the values of a, b, and c');
> readln (a) ;
> readln (b) ;
> readln (c) ;
Here is the place where you can compute the discriminant:
d = sqr(b) - 4*a*c;
Quote
> if d > 0 then
..
> else if d = 0 then
> begin
> writeln ('the root is');
> writeln (-b/2*a);
> end
Here is an error that will lead to wrong output: as the multiplication
operator does not bind closer than the division operator, you have to
code either
-b/(2*a)
or
-b/2/a
The same error is made below, in the d<0 branch, while it is not made
in the d>0 branch.
Quote
> else if d < 0 then
> begin
> writeln ('the roots are');
> writeln ((-b + sqrt(abs(d))/2*a));
> writeln ((-b - sqrt(abs(d))/2*a));
> end
While this part will compile alright, it is still wrong!
Your program will report two real solutions where the equation really
has two complex ones. Replace the preceding lines with:
begin
writeln ('the two roots are');
writeln (-b/2/a, ' + ', sqrt(abs(d))/2/a, '*i');
writeln (-b/2/a, ' - ', sqrt(abs(d))/2/a, '*i');
end
Quote
> else
> writeln ('I suck');
This is entirely superfluous, as the preceding conditions, viz.
Quote
> if d > 0 then
.
> else if d = 0 then
..
> else if d < 0 then
exhaust all possibilities.
In a language that allows for run-tim constants, the hole program
would be more lucid; in particular the declaration of d's datatype
and its value would not be separated by other stuff (which can be
several hundred lines of code, in more realistic examples).
In the following example, note that keyword delimiters, and types,
are written in uppercase, while identifiers are in lower case.
Note also that LOC REAL declares a real-typed variable, while REAL
(without the LOC) declares a constant. In the language used below,
everything declared in an IF part is visible throughout the remaining
part of the IF clause (i.e. from the point of declaration through
the IF, and THEN parts, down to the end of the ELSE part); same holds
for an ELIF part, where ELIF is an abbreviation for ELSE IF.
BEGIN # This program computes the answer, x, #
# to the quadratic equation ax^2+bx+c=0 #
LOC REAL a, b, c
; write (("Input the values of a, b, and c", newline))
; read ((a, b, c))
; IF REAL d = a*a - 4*a*c
; d = 0
THEN write (( "The root is ", -b/2/a, newline ))
ELIF REAL s = sqrt (ABS d)
; d > 0
THEN write ( ( "The two roots are:", newline
, (-b+s) / (2*a) , newline
, (-b-s) / (2*a) , newline
) )
ELSE write ( ( "The two roots are:" , newline
, -b/2/a, " + ", s/2/a, "*i", newline
, -b/2/a, " - ", s/2/a, "*i*, newline
) )
FI
END
FI is IF spelled backwards; this ends the IF statement, and thus
mends a syntactic ambiguity Pascal has inherited from Algol 60,
known as "the Problem of the Dangling ELSE".
You see, a well-designed language, such as Algol 68 (used in the
example above) lets you express your thoughts more lucidly. Too bad
that Niklaus Wirth impatiently has left the Algol 68 design team and
rushed into defining and implementing Pascal.
Best wishes,
Otto Stolz