[comp.sys.mac.programmer] THINK Pascal expression quirk

rcook@eagle.wesleyan.edu (04/12/90)

So this is what I had going on in THINK Pascal 2.0:

var
  x, a, b : integer;

begin
..
a := 400;
b := 500;
x := 11 + round( 248 * a / b );
..
end;

x was computed to be a negative number!  Do you see any minus signs above?  I
figured the '/' operator would force the whole expression inside round() to
evaluate as floating point numbers, but I suspect the compiler saw that '248*a'
was composed entirely of integers and computed an integer product, which
overflowed the range of an integer (though I didn't notice since I had range
checking off).  I changed the 248 to 248.0 and everything worked fine.  Big
deal?  Indeed, I should be using fixed point math anyway...

The next day I got THINK Pascal 3.0 and have not checked whether it has the
same quirk.

I just thought someone might be interested.  Beats drivel about upgrade prices
though :-)

Randall Cook
rcook@eagle.wesleyan.edu

phils@chaos.cs.brandeis.edu (Phil Shapiro) (04/13/90)

If you don't put on overflow checking (the V flag in the project menu,
or {$V+} in your program) then THINK Pascal will happily overflow your
integers into their sign bits.  The compiler parses the operators '*'
and '/' (which have the same precedence) from left to right, so it
compiled the multiply operation before the divide.  You could promote
one of the operands into a longint; this will prevent the integer
overflow.
--
Phil Shapiro
phils@chaos.cs.brandeis.edu

drc@claris.com (Dennis Cohen) (04/13/90)

rcook@eagle.wesleyan.edu writes:

>So this is what I had going on in THINK Pascal 2.0:

>var
>  x, a, b : integer;

>begin
>..
>a := 400;
>b := 500;
>x := 11 + round( 248 * a / b );
>..
>end;

>x was computed to be a negative number!  Do you see any minus signs above?  I
>figured the '/' operator would force the whole expression inside round() to
>evaluate as floating point numbers, but I suspect the compiler saw that '248*a'
>was composed entirely of integers and computed an integer product, which
>overflowed the range of an integer (though I didn't notice since I had range
>checking off).  I changed the 248 to 248.0 and everything worked fine.  Big
>deal?  Indeed, I should be using fixed point math anyway...

>The next day I got THINK Pascal 3.0 and have not checked whether it has the
>same quirk.

It will have the same "quirk".  So will MPW and TML (even Turbo).  It has to
do with Integer wraparound.  "x" is declared as an integer and there is no
way that you are going to fit 99200 into an integer.  You could have forced
it to floating point by changing the 248 to 248.0, but the rules of evaluation
are very well-defined in this case -- the multiplication will take place first
and then the division and type conversions will not be done since all the
arguments are integer.  You could also have avoided the problem by making
the variables longints.
-- 
Dennis Cohen
Claris Corp.
 ****************************************************
Disclaimer:  Any opinions expressed above are _MINE_!