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 (November 2007, week 4)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:         Wed, 28 Nov 2007 16:21:20 +0000
Reply-To:     iw1junk@COMCAST.NET
Sender:       "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:         Ian Whitlock <iw1junk@COMCAST.NET>
Subject:      Re: Arithmetic precision comparison
Comments: cc: "Richard A. DeVenezia" <rdevenezia@WILDBLUE.NET>,
          Tree Frog <tree.frog2@HOTMAIL.COM>

Summary: Decimal precision and Macros that act like DATA step functions #iw-value=1

Richard,

I am not sure that your task makes any sense. You say that

>> I _don't_ have to deal with the situation where precision of >> comparison cannot be inferred from the LL and UL. (Such a situation >> would be LL=1.00 and UL=3.00, SAS would have no way, from the UL & >> LL values alone, to know that 2 decimal places of precision are >> desired)

The same can be said about any finite decimals since the precision is a function of the representation, not the number. Consider

ll = 1.1100 ul = 2.11000

What is the precision of rounding to be? For that matter suppose

ul = 4/3

What would the precision be?

With that said one can ask for a precision based on the number of decimal places in the BEST12. representation. Here is your example without the macro.

data foo; ll = 3; ul=5.5; pll = input(tranwrd(translate(cats(put(ll,best12.),"q") ,'000000000','123456789') ,"0q", "1") ,best12.) ; pul = input(tranwrd(translate(cats(put(ul,best12.),"q") ,'000000000','123456789') ,"0q", "1") ,best12.) ; pr = min ( pll, pul ) ;

do x = 5.5485 to 5.5525 by 0.0001; if ( round(x,pr) < LL ) then status = 'fail-low'; else if ( round(x,pr) > UL ) then status = 'fail-high'; else status = 'pass'; put x= ul= status=; end; run;

As you can see PR can be expressed as the composition of functions in terms of LL UL. Hence eliminating the clarity of extra variables can produce a macro that generates the DATA step expression for PR. Details LTR.

Ian Whitlock ==============

Date: Wed, 28 Nov 2007 09:03:39 -0500 Reply-To: "Richard A. DeVenezia" <rdevenezia@WILDBLUE.NET> Sender: "SAS(r) Discussion" From: "Richard A. DeVenezia" <rdevenezia@WILDBLUE.NET> Organization: Internet News Service Subject: Re: Arithmetic precision comparison Comments: To: sas-l Tree Frog wrote: > Richard > > Does this fit the bill? > > %macro maxprecision(ul,ll); > %let ind_ul=%sysfunc(index(&ul,.)); > %let rem_ul=%sysfunc(substr(&ul,%eval(&ind_ul+1))); > %let lgt_ul=%sysfunc(length(&rem_ul)); > %let ind_ll=%sysfunc(index(&ll,.)); > %let rem_ll=%sysfunc(substr(&ll,%eval(&ind_ll+1))); > %let lgt_ll=%sysfunc(length(&rem_ll)); > %if %eval(&lgt_ul>&lgt_ll) %then %do; > %let lgtf=z&lgt_ul..; > %end; > %else %do; > %let lgtf=z&lgt_ll..; > %end; > 0.%sysfunc(sum(1),&lgtf) > %mend; > > Tree Frog

Unfortunately, no. I want a macro that generates a piece of DATA step code (or a piece of SQL code) that functionally computes the maxprecision of values in two variables (or expressions) -- not the values as found in two macro variables.

With this program, the log should show status=pass for all x's < 5.55.

%macro maxprecision(expr1,expr2); ... ? ... %mend;

data foo; ll = 3; ul=5.5;

do x = 5.5485 to 5.5525 by 0.0001;

if ( Round(X,%MAXPRECISION(LL,UL)) < LL ) then status = 'fail-low'; else if ( Round(X,%MAXPRECISION(LL,UL)) > UL ) then status = 'fail-high'; else status = 'pass';

put status=; end; run;

-- Richard A. DeVenezia http://www.devenezia.com/

> > On Nov 28, 2:48 pm, "Richard A. DeVenezia" <rdevene...@wildblue.net> > wrote: >> Consider two values, lower limit and upper limit. >> LL: 1 >> UL: 3.25 >> And some computed value X that has to be evaluated against the >> limits. X: 2.314159 >> >> The evaluation that has to be done is >> LL <= Round(X,0.01) <= UL >> >> The 0.01 (10**-2) comes from the arithmetic precision of UL (2). >> >> Can anyone think up a functional form macro, >> %MAXPRECISION(expr1,expr2), that could be used as such: >> >> if ( Round(X,%MAXPRECISION(LL,UL)) < LL ) then >> status = 'fail-low'; >> else >> if ( Round(X,%MAXPRECISION(LL,UL)) > UL ) then >> status = 'fail-high'; >> else >> status = 'pass'; >> >> I _don't_ have to deal with the situation where precision of >> comparison cannot be inferred from the LL and UL. (Such a situation >> would be LL=1.00 and UL=3.00, SAS would have no way, from the UL & >> LL values alone, to know that 2 decimal places of precision are >> desired)


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