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