Date: Fri, 19 Oct 2001 10:56:40 -0700
Reply-To: Cassell.David@EPAMAIL.EPA.GOV
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: "David L. Cassell" <Cassell.David@EPAMAIL.EPA.GOV>
Subject: Re: What's wrong with this code...
Content-type: text/plain; charset=us-ascii
Jay Zhou wrote:
> The following code will not work appropriately with SAS V6.12 and
V8.1, but V8.2.
>
> data test;
> x=0.4;
> y=0.5;
> z=(y-x)/y*100;
> if z>=20 then output;
> run;
>
> It will work if changing y to 0.8 from 0.5. What's wrong?
Art, I'll take 'roundoff error' for a hundred, please.
Numbers like 0.1 and 0.4 cannot be represented exactly in your
computer's
memory. So you get roundoff, which accumulates as you fiddle with the
values.
This is not a SAS problem, but a general computer-programming problem.
Try printing your variable z using a BEST20. format and see. I'll guess
that some
of the time you get a number like 20.0000000000000531 and some of the
time you
get a number like 19.99999999999999787 [which would test as less than
20].
So that's why this works for y=0.8, where there is not a
maybe-or-maybe-not issue
present.
If you really have to test numbers like this, you may want to try
incorporating
a little 'fuzz' in your test, like this:
fuzz = 1E-16;
if z >= 20 - fuzz then output;
You'll really have a problem with roundoff if you later need to test for
exact
equality with the number 20 [or any other fixed constant] after doing
lots of
multiplying and dividing. You can do this [instead of saying "if z=20"]
as:
if abs(z-20) < fuzz then output;
You may also want to look in some of the standard comp sci texts for
more info
on roundoff errors. You can't go wrong with Knuth.
HTH,
David
--
David Cassell, CSC
Cassell.David@epa.gov
Senior computing specialist
mathematical statistician