Date: Fri, 4 Nov 2005 13:32:55 -0500
Reply-To: Chang Chung <chang_y_chung@HOTMAIL.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Chang Chung <chang_y_chung@HOTMAIL.COM>
Subject: Re: Trying to avoid division by zero...
On Fri, 4 Nov 2005 10:09:50 -0800, Dale McLerran <stringplayer_2@YAHOO.COM>
wrote:
>--- Kevin Myers <KMyers@PROCOMINC.NET> 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; */
>/* <code when true> */
>/* 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
|