[comp.lang.pascal] HELP with Turbo Pascal problem

rfh@tahoe.unr.edu (Randy F. Hall) (01/06/90)

HELP!!

  I wrote the following program in TurboPascal 5.5 and got a very
wrong answer. One would expect to get an output value for j of 64516,
but instead get -1020. The only explanation I could think of was that
there is a screw up in the 2's compliment or something. I also tried
running it through TP5.0 and on other machines, but with the same result.

  It has the same problem whether j is defined as a LONGINT or REAL. 
Also for i = 255, -255 and -254. I haven't tested for any other values.
Replacing i * i with SQR (i) didn't help either.


-------------------------

Program test;

Var 
  i : integer;
  j : real;

begin 
  i := 254;
  j := i * i;
  Writeln (j);
  Readln;
end.

-------------------------

  If anybody has any idea what may be the problem, let me know. I can
get around the trouble (fortunately) by using WORD declaration for j as
j will never get above 65535. In the future this may be a problem though.

	Thanks in advance

		JaM


real BMW's have only two wheels
=============================================================================
rfh@unssun.nevada.edu      | I lit out from Reno
                           | I was trailed by twenty hounds...
============================================================================= 

dmurdoch@watstat.waterloo.edu (Duncan Murdoch) (01/06/90)

In article <3433@tahoe.unr.edu> rfh@unssun.nevada.edu  (J.A. MacDonald) writes:
>HELP!!
>
>  I wrote the following program in TurboPascal 5.5 and got a very
>wrong answer. One would expect to get an output value for j of 64516,
>but instead get -1020. 
...
>  i : integer;
>  j : real;
>
>begin 
>  i := 254;
>  j := i * i;

You got what you're supposed to get, according to the specs for TP.  It 
evaluates ordinal expressions in the smallest type that will hold the 
operands; thus i * i is evaluated as an integer, and it overflows before it
gets converted to real and stored in j.  You can get the result you expect 
by using
   j := i * longint(i);
or something similar, to force the calculation to take place as a longint.

Duncan Murdoch

bseeg@spectra.COM (Bob Seegmiller) (01/06/90)

In article <3433@tahoe.unr.edu> rfh@unssun.nevada.edu  (J.A. MacDonald) writes:
>HELP!!
>
>  I wrote the following program in TurboPascal 5.5 and got a very
>wrong answer. One would expect to get an output value for j of 64516,
>but instead get -1020. The only explanation I could think of was that
>there is a screw up in the 2's compliment or something. I also tried
>running it through TP5.0 and on other machines, but with the same result.
>
>  It has the same problem whether j is defined as a LONGINT or REAL. 
>Also for i = 255, -255 and -254. I haven't tested for any other values.
>Replacing i * i with SQR (i) didn't help either.
>
>
>-------------------------
>
>Program test;
>
>Var 
>  i : integer;
>  j : real;
>
>begin 
>  i := 254;
>  j := i * i;
>  Writeln (j);
>  Readln;
>end.
>
>-------------------------
>
>  If anybody has any idea what may be the problem, let me know. I can
>get around the trouble (fortunately) by using WORD declaration for j as
>j will never get above 65535. In the future this may be a problem though.
>
>	Thanks in advance
>
>		JaM
>rfh@unssun.nevada.edu
>============================================================================= 

Helps to read the manual, huh? ;-)  Unfortunately, it may be buried in
there (as it was in 4.0) but somewhere where it talks about arithmetic
and typing of results, you should see an explanation that the
arithmetic is done in whatever base type is "simplest" on the
right-hand side of the assignment statement, then converted to the left
hand side's type, once the compiler has okayed your program and compiled
it.

Are you sure that if "j" is word it comes out OK?  Did you mean "i"?
The problem isn't so much with the typing of "j" but of "i", although
it your're going past 16-bit signed arithmetic, make sure both
variables' types will support the answer (I haven't had as much of a
problem as long as I followed that guideline).  If you type "i" as
LONGINT, then your assignment should come out as you expected.  Even
better, make "i" real, if the final assignment is real and no
fractional parts are involved (I know, I know, it'll run slower without
a floating-point chip :-( ).

Find that section in your Borland manual and read it very carefully!!
Numerical methods on computers just aren't what you'd expect.  Also,
each language you may use may (nay, probably does) have (slightly)
different rules for arithmetic and type conversions in assignment
statements.  In general, ANSI languages' manual (ones I've seen:
Borland's TP, MS-FORTRAN, and big-computer FORTRAN) have sections
dealing with differences between their implementation and the standard,
and in there may also come up some sections on arithmetic evaluation
results.

An Alternate program:
:-------------------------
:
:Program test;
:
:Var 
:  i : longint;
:  j : real;
:
:begin 
:  i := 254 ;
:  j := i * i;
:  Writeln (j);
:  Readln;
:end.
:
:-------------------------
Good luck!
-- 
/---------------------------------------+-------------------------------------\
| Bob Seegmiller <The usual disclaimer> | .....................               |
| "Till mermaids wake us..." - Eliot    | .....................               |
| UUCP: ...!nosc!spectra!bseeg          | .....................               |