LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (June 1996, week 3)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:         Tue, 18 Jun 1996 21:46:37 -0600
Reply-To:     Andrew James Llwellyn Cary <ajlcary@IX.NETCOM.COM>
Sender:       "SAS(r) Discussion" <SAS-L@UGA.CC.UGA.EDU>
From:         Andrew James Llwellyn Cary <ajlcary@IX.NETCOM.COM>
Organization: Cary Consulting Services
Subject:      Re: Is this a bug???

<LOTS OF CODE DELETED> > The problem here is: Although the percent in data Q1 is exactly 100 > (as it should be), the dataset test1 can not output anycase. The > dataset test2 has one case with count 11 and percent 100 instead.(Note > that in test2 I use subsetting statement 'if percent GT 100' ) . > When I try to print it, however, even with format 20.16, I still get > all 0's after decimal point. > > Another interesting thing is if the count number were not 11, 'if > percent EQ 100' works well in dataset test1. > > Is is a bug in SAS? or someone can give me other explaination? > > TIA > > Andy

Is it a bug? Not really. Just an artifact.

The problem (once again) is that what you saw isn't what you got. Computers do not 'think' in decimal numbers. They think in binary numbers.

Floating point numbers are not exact. They are a binary fraction raised to a normalized binary power. The format you are using takes this binary fraction and turns it into a set of characters representing that fraction to the precision you specify. The w.d format will always look better then the real data. To see the real value you must use a Hex16. format (it will return a hex string representation of the true binary value in memory. This can be enlightening. The value HUNDRED was set to 100 using an assignment statement. The PERCENT is from your program.

HUNDRED=4059000000000000 PERCENT=4059000000000001

as you can see Percent is indeed greater then 100 (the rightmost bit) The number 11 (or I suspect any prime) used in the percent calculation is most likely the culprit. There just isn't any graceful way to represent division by a prime >2 as a binary fraction..

How to avoid this? There are a couple of things you can do.

Use the ROUND function to round PERCENT to some arbitrary precision:

IF ROUND(100,.1) = ROUND(PERCENT,.1);

Code your comparisons with an arbitrary 'fuzz' around the comparison:

IF 0.000000001 <= ABS(PERCENT-100);

use the FUZZ function to clean it up.

IF FUZZ(PERCENT) = 100;

would all work. The FUZZ function was written with this kind of comparison in mind. It returns an integer if the argument is within 10e-12 of an integer, otherwise it returns the argument.

-- Andrew J. L. Cary | I Reckon that the Opinions Senior Curmudgeon | expressed here DO represent Cary Consulting Services, Newark, CA | those of the management of ajlcary@ix.netcom.com | Cary Consulting Services


Back to: Top of message | Previous page | Main SAS-L page