[comp.sys.mac.programmer] Bug in LSP arithmetic

zaccone@rigel.bucknell.edu (Rick Zaccone) (05/23/89)

The following program produces incorrect results in LSP 2.01:

program test (input, output);
var
        a, out: real;
begin
        a := 16807.0;
        out := a * a;
        writeln(out : 10 : 0);
end.

The program prints 282475264 instead of the correct 282475249.  If I
type "a*a" in the observe window, I can see that a*a is being computed
correctly.  The error occurs when the assignment is made to out.  Can
anyone else reproduce this?  Am I missing something obvious?

I am running on a Mac Plus with Finder 6.1, and System 6.0.2.

Rick Zaccone
--
zaccone@bknlvms.bitnet
zaccone@rigel.bucknell.edu

ksitze@nmsu.edu (Kevin Sitze) (05/23/89)

In article: <zaccone@rigel.bucknell.edu's message of 23 May 89
01:19:53 GMT> Rick Zaccone writes:
>The following program produces incorrect results in LSP 2.01:
>
>program test (input, output);
>var
>        a, out: real;
>begin
>        a := 16807.0;
>        out := a * a;
>        writeln(out : 10 : 0);
>end.
>
>The program prints 282475264 instead of the correct 282475249.  If I
>type "a*a" in the observe window, I can see that a*a is being computed
>correctly.  The error occurs when the assignment is made to out.  Can
>anyone else reproduce this?  Am I missing something obvious?

Your missing something obvious.  If you look at Apple's numerics
manual (SANE manual) you'll find that real numbers have an definite
accuracy of only _6_ digits.  Anything else you see is affected by
remaining bit patterns in the real number that may or may not be
accurate.  When a*a is used in the observe window, LSP converts the
reals to extended format (as it does in the program as well) and then
prints out the answer using the _extended_ result.  The difference
lies in assigning the answer to 'out'.  The result has to be converted
back into single precision and stored in 'out' (loosing several digits
of accuracy as it's converted).  If you had done something like this:

...
    a := 16807.0
    writeln(a*a:10:0);
...

you'd get the correct answer.  If you need that precision inside a
variable then just change your variable declaration to:

var
  a : real;
  out : extended;

and everything should work fine and dandy.  Remember, floating point
numbers by the virtue of being represented by a finite number of bits
can _never_ represent the entirety (?sp?) of all real numbers.

Enjoy the limited world of computer programming...

					-Kelesi
--
------------------------------------+-------------------------------
From the Macintosh of: Kevin Sitze  | Disclamer: Who the heck needs
                                    |   a disclamer?  After all, Dan
EMail: ksitze%NMSU.edu              |   Quayle doesn't.
SMail: 601 S. Melendres             +-------------------------------
       Las Cruces, NM  88005        | "We have the answers, the
------------------------------------+  trouble lies in finding the
"The difference between intelligence|  questions..."
and stupidity is that intelligence  | "The information is there,
has a limit."           - anonymous |  finding it is another story."
The dolt confuses you -- more --    |	   	    - Any consultant
------------------------------------+-------------------------------

siegel@endor.harvard.edu (Rich Siegel) (05/23/89)

	I think the bug is in the output routines, not in the arithmetic.
I'll look into it.

	In the meantime, use "Extended" instead of "Real", and everything
should work OK.

		--Rich

~~~~~~~~~~~~~~~
 Rich Siegel
 Staff Software Developer
 Symantec Corporation, Language Products Group
 Internet: siegel@endor.harvard.edu
 UUCP: ..harvard!endor!siegel

 "She told me to make myself comfortable, so I pulled down my pants
 and sat in the pudding." -Emo Phillips
~~~~~~~~~~~~~~~