```Date: Fri, 4 Nov 2005 13:32:55 -0500 Reply-To: Chang Chung Sender: "SAS(r) Discussion" From: Chang Chung Subject: Re: Trying to avoid division by zero... Comments: To: Dale McLerran On Fri, 4 Nov 2005 10:09:50 -0800, Dale McLerran wrote: >--- Kevin Myers wrote: > >> By the way, here is an only slightly uglier macro to get around >> division by >> zero messages within expressions, if you really need to: >> >> %macro zdiv(n,d); >> ifn(&d,(&n)/ifn(&d,&d,1),.) >> %mend zdiv; >> >> Usage example: >> >> data _null_; >> do d=0 to 5; >> r=%zdiv(1,d); >> put d= r=; >> end; >> run; >> >> As provided above, this macro also avoids messages if the denominator >> is >> missing. Of course that could be changed very easily if desired. >> >> s/KAM > >Kevin posted this inline macro for performing division without >generating notes that indicate division by zero. I would observe >that if the denominator is missing, then Kevin's code also avoids >notes that inform about performing operations on missing values. >However, if the numerator is missing, notes are generated about >performing operations on missing values when Kevin's macro is used. > >In the spirit of an inline macro which performs division when >the numerator is nonmissing and the denominator is both nonmissing >and nonzero, I offer this further uglification of Kevin's macro. >(I am compelled here to conjure up images of Dufflepuds from C.S. >Lewis' "Voyage of the Dawn Treader". Fans of the Chronicles of >Narnia will have no problem remembering that the Dufflepuds were >uglified by the magician.) Herewith is my further uglification: > > >%macro zdiv(n,d); >/**************************************************************/ >/* macro ZDIV divides the numerator &n by the denominator &d */ >/* If the denominator is missing or zero, the division is not */ >/* performed and the result is set to missing. Also, if the */ >/* numerator is missing, the division is not performed and */ >/* the result is set to missing. */ > >/* macro ZDIV is an inline macro. It does not produce any */ >/* semicolons indicating end-of-statement. Thus, it can be */ >/* employed within a condition, as */ >/* */ >/* if %zdiv(num,denom)>1 then do; */ >/* */ >/* end; */ >/**************************************************************/ >ifn(&n>.Z, ifn(&d, ifn(&n,&n,0,0)/ifn(&d,&d,1),.), .) >%mend zdiv; > > >/*Usage example:*/ > >data _null_; > do num=1, -1, .; > do denom=., 0 to 5; > r=%zdiv(num,denom); > put num= denom= r=; > end; > end; >run; > > >I would note that this is NOT efficient code. If we were to >write code with an IF condition which examines both numerator >and denominator for proper values, we would improve efficiency >considerably. But if you demand inline code which will operate >without producing those nasty notes about division by zero or >operating on missing values, then the macro presented here may >be employed. > >Dale Hi, This is such a great one-liner... I am definitely keeping this one. Many many thanks to Dale and Kevin. Cheers, Chang ```

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