[comp.sys.mac.programmer] MPW Pascal Bug? Or am I wrong.

dorourke@polyslo.UUCP (David O'Rourke) (06/18/88)

This isn't a serious problem, but I thought I'd share it with netland anyways.
Given the following peice of code:

procedure doSomething;
  var
    X, Y : INTEGER;
    Z    : LONGINT;
  begin
    Z := X * Y;
  end;  {doSomething}

If X*Y causes an overflow and I have overflow checking turned off it stores
the wrong result, usually negative, in Z even though Z is a LONGINT.  Now is
this what the compiler is suppose to do, or is it suppose to convert to the
LONGINT.

My problem is that the multiply seems to be taking place in 16-bit precision
even thought there is a LONGINT that it's being assigned too.

I know the solution, {read work-around}, to this problem.  But I was under
the impression that the compiler would allow this sort of math and that I
wouldn't get the overflow stored in the LONGINT, but I would get the actual
value of the multiply, anyone care to comment on this.  I'd appreciate any
help in understanding why the compiler can't deal with the code as is and
yeild the correct result.

I'm running the latest version of MPW 2.0 and the lastest version of MPW
pascal 2.0.

Thanks for any help.

-- 
David M. O'Rourke

Disclaimer: I don't represent the school.  All opinions are mine!

drc@dbase.UUCP (Dennis Cohen) (06/21/88)

In article <3203@polyslo.UUCP>, dorourke@polyslo.UUCP (David O'Rourke) writes:
> procedure doSomething;
>   var
>     X, Y : INTEGER;
>     Z    : LONGINT;
>   begin
>     Z := X * Y;
>   end;  {doSomething}
> 
> If X*Y causes an overflow and I have overflow checking turned off it stores
> the wrong result, usually negative, in Z even though Z is a LONGINT.  Now is
> this what the compiler is suppose to do, or is it suppose to convert to the
> LONGINT.
> 

No, unfortunately this is exactly what the compiler is "supposed" to do (read
that "is documented to do").  The coercion is not done until the assignment is
made and by then it is too late.  If either of the arguments had been a Longint,
the problem would not arise as it would have done a long multiply rather than
a word multiply.  I, too, would like the compiler to be smarter in this instance
but don't expect that this will change.

Dennis Cohen
Ashton-Tate Macintosh Division
dBASE Mac Development Team
--------------------------
Disclaimer:  Any opinions expressed above are _MINE_!

lsr@Apple.COM (Larry Rosenstein) (06/21/88)

In article <3203@polyslo.UUCP> dorourke@polyslo.UUCP (David O'Rourke) writes:
>
>the wrong result, usually negative, in Z even though Z is a LONGINT.  Now is
>this what the compiler is suppose to do, or is it suppose to convert to the
>LONGINT.

The compiler is oprating correctly.  If you turn on overflow checking, then
you would get a runtime exception.  The reason that overflow checking is not
on all the time is that it expands the resulting code enormously.

One workaround is to coerce one value to a LONGINT so that the compiler uses
32-bit multiplication.  The only problem with that is that the
multiplication requires a library routine, since the 68000 doesn't have a
32-bit multiply.

A really nifty solution (used in MacApp) is to define the following
function:

FUNCTION IntMultiply(x,y: INTEGER): LONGINT; INLINE $301F, $C1DF, $2E80;

This takes the 2 integers and multiplies them using the 68000 multiply
instruction, yielding a longint.  It doesn't require a call to the Pascal
library, and is relatively fast.

-- 
		 Larry Rosenstein,  Object Specialist
 Apple Computer, Inc.  20525 Mariani Ave, MS 27-AJ  Cupertino, CA 95014
	    AppleLink:Rosenstein1    domain:lsr@Apple.COM
		UUCP:{sun,voder,nsc,decwrl}!apple!lsr

newsuser@LTH.Se (Lund Institute of Technology news server) (06/24/88)

In article <3203@polyslo.UUCP> dorourke@polyslo.UUCP (David O'Rourke) writes:
>This isn't a serious problem, but I thought I'd share it with netland anyways.
>Given the following peice of code:
>
>procedure doSomething;
>  var
>    X, Y : INTEGER;
>    Z    : LONGINT;
>  begin
>    Z := X * Y;
>  end;  {doSomething}
>
>If X*Y causes an overflow and I have overflow checking turned off it stores
>the wrong result, usually negative, in Z even though Z is a LONGINT.  Now is
>this what the compiler is suppose to do, or is it suppose to convert to the
>LONGINT.

This is not a bug. Check the MPW Pascal manual, page 4-7.
   "When both operands of an operator are of type integer, 16-bit operations
    are always performed and the result is of type integer (truncated
    to 16 bits if necessary)."

A simple solution is to change the assignment statement to
   Z := ord4 (X) * Y

-- 
Roland Mansson, Dept of Comp Sc, Lund University, Box 118, S221 00 Lund, Sweden
Phone: +46-46109640 (work), +46-46111539 (home)    Bitnet: lthlib@seldc52
Internet: roland@dna.lth.se   or   roland%dna.lth.se@uunet.uu.net
UUCP: {uunet,mcvax}!enea!dna.lth.se!roland    AppleLink: IT0073