Previous Table of Contents Next


5.3. Common Questions and Answers

There may be questions that arise out of programming in Turbo Pascal. Some common questions and the answers to those questions, which are not answered by the text itself, appear in this section.

Why do I get incorrect mathematical results from Pascal?

This results from the common overflow conditions that plague any language when computations are done. Generally, when two integers are used in a computation, an integer operation is done, and an integer is assumed in the result. Although this might be valid in most cases, in some cases this assumption would not be valid. Because Pascal was designed as a teaching language, many things are not automatic about the operation of a compiler on a computer, and which must be taken into account. The following example should describe a little of what happens, illustrating the issue:

  program tnt01;

    { demonstrates type-casts and a common error due to overflow }
    const
      a: integer = 10000; { specifically defining a type for a
                            constant }
    var
      c: longint;
    begin
      writeln;
      writeln(‘Note that by evaluating 10000 squared, it will create’);
      writeln(‘incorrect results as demonstrated below in ’);
      writeln(‘multiplying an integer by an integer, resulting in ’);
      writeln(‘overflow of the integer type assumed by the compiler ’);
      writeln(‘as a result, which is copied into a longint variable ’);
      writeln(‘*after* the computation’);
      c := a * a;
      writeln(‘10000 squared is ’, c);
      readln;
      writeln(‘Now we typecast one of the a variables in the ’);
      writeln(‘similar assignment pair as below. Note the correct ’);
      writeln(‘results now show as a part of c. This is a common ’);
      writeln(‘misjudgment made in programming for Pascal. Be ’);
      writeln(‘aware of it. The compiler now in this case assumes ’);
      writeln(‘longint multiplication, and assigns the result to a ’);
      writeln(‘longint variable, therefore overflow taken care of.’);
      c := longint(a) * a;
      writeln(‘10000 squared is ’, c);
    end.

Why doesn’t Pascal have an operator such as X**Y for taking a power of a number?

Because Wirth designed Pascal as a teaching language, he wanted to make apparent the operations of the compiler. Therefore, many statements that existed in the original Pascal standard related very closely to the number of clock ticks made as a result. Such an operator is very expensive in terms of clock ticks when called. That is not readily apparent by the appearance of the operator, which existed in Fortran (and maybe still does). A realization of how expensive the X**Y operator is can be seen in the next question.

So how would I evaluate powers in Pascal?

This answer comes down to an issue of mathematics knowledge. Let’s start with the power functions as defined earlier. The limitations are that in XY, Y must be greater than 0. This may not be acceptable because, in some cases, you may want to take fractional and negative powers. You can further develop the iterative algorithm, observing that signed integers in Y can be evaluated by using some algebra of powers, as in the following:

  function power(x: real; y: integer): real;
     var
       result: real;
       i: integer;
     begin
       result := 1;
       for i := 1 to abs(y) do
         result := result * x;
       if y < 0 then
         result := 1 / result;
       power := result;
     end;

Note that this algorithm now takes negative integers for y and could take any real number in x. However, a real number in place of y would be desirable for things such as fractional powers and setting up square roots. The ability to devise the equivalent of a real x and real y power can be derived from calculus in a definite sense or the following simple algebra manipulation:

   x^y = z
   ln (x^y) = ln z
   y * ln(x) = ln z
   e^(y * ln(x)) = z

Now given this relationship, we can evaluate real number powers, with a function written rather easily. The only limitation with this function is that a negative x may not be 0 or negative. The 0 case may be fixed easily with the rule as stated “0 to any power is 0” in mathematics. Otherwise, to counter the exception that x may not be negative, the other iterative method may be used and combined into the preceding relation to gain an expression that works with any number except where x is a real number less than 0. Of course, it could possibly be extended to work with any real number, when you start considering complex numbers.

To address the issue with timer ticks, if the final statement, exp(y*ln(x)), is observed, this expression takes many more timer ticks than the average statement.

Why does it say two types are different between units when I name them the same thing and describe them the same way?

Pascal is created as a strongly typed language. Therefore, if one type is defined, it is considered defined even if another type of the same name is used. A problem can exist if the type is needed between two units or a unit and the main program. What must be done is that the type must be declared in one unit used, and then the unit must be included into the other unit or the main program by a uses statement. Note that valid uses statements and const/ type variables must exist right after the interface declaration in an unit.


Previous Table of Contents Next