| Date: | Fri, 6 Apr 2007 12:03:10 -0700 |
| Reply-To: | "Terjeson, Mark" <Mterjeson@RUSSELL.COM> |
| Sender: | "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU> |
| From: | "Terjeson, Mark" <Mterjeson@RUSSELL.COM> |
| Subject: | Re: data step |
|
| In-Reply-To: | A<1175884625.972424.247230@e65g2000hsc.googlegroups.com> |
| Content-Type: | text/plain; charset="us-ascii" |
Hi Mindy,
Computers only have N-number of digits of precision
to store floating-point numbers. When the precision
is about 14 or 15 digits worth and then certain
arithmetic operations utilize the use of log tables
to convert numbers for internal use to handle the
processing of small or large numbers there are going
to be certain combinations of mantissa that lose a
microscopic amount of precision. You can see this
by adding a larger formatting to your numeric variables
of your sample for the purpose of debugging this. e.g.
data
test;
input a
b;
c=a-b;
format a b c 25.20;
if c < 1 then status_c =
'c<1';
else if c = 1 then status_c =
'c=1';
else if c > 1 then status_c =
'c>1';
cards;
4.6 3.6
8.2
7.2
9.3
8.3
;
run;
proc print;
run;
You can see that by adding a good amount 25.20 for
20 digits of mantissa that the real situation becomes
visible. 20.15 only yield reality for one of the numbers.
25.20 allows you to *see* why the comparison result ended
up the way they did. So you will have to use some int()
or round() functions to chop off the errant infinitesimal
goober and have more solid whole numbers such as
c=round(a-b,0.1);
or whatever number of decimal places you want.
Hope this is helpful.
Mark Terjeson
Senior Programmer Analyst, IM&R
Russell Investment Group
Russell
Global Leaders in Multi-Manager Investing
-----Original Message-----
From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of
Mindy
Sent: Friday, April 06, 2007 11:37 AM
To: SAS-L@LISTSERV.UGA.EDU
Subject: data step
hey, guys,
My colleague brings in an interesting question , the code and output
are as below. Could anybody explain why the results are not as we
expected?
data
test;
input a
b;
c=a-b;
if c < 1 then status_c =
'c<1';
else if c = 1 then status_c =
'c=1';
else if c > 1 then status_c =
'c>1';
cards;
4.6 3.6
8.2
7.2
9.3
8.3
;
run;
proc print;
run;
Output is :
obs a b c Status_c
1 4.6 3.6 1 C<1
2 8.2 7.2 1 C<1
3 9.3 8.3 1 C=1
Thanks.
Mindy
|