SAS author’s tip: Performing floating point number comparisons

1

The SAS author’s tip of the week blogs are back! Sorry for the short break - I’ve been working to transition into my new role as editor of the SAS Bookshelf.

We will continue to feature these helpful tips for our readers. Please let me know if there is any other content you would like to see us cover.

Now back to this week’s author tip from Jack Shostak’s new book SAS Programming in the Pharmaceutical Industry, Second Edition.

The following excerpt is from SAS Press author Jack Shostak’s book, “SAS Programming in the Pharmaceutical Industry, Second Edition”. Copyright © 2014, SAS Institute Inc., Cary, North Carolina, USA. ALL RIGHTS RESERVED. (Please note that results may vary depending on your version of SAS software.)

Performing Floating-Point Comparisons

At times, you need to perform some form of floating-point number comparison. The following example illustrates such a comparison where you are setting laboratory value flags to indicate whether a lab test is above or below normal.

Program 4.15  Using the ROUND Function with Floating-Point Comparisons

**** FLAG LAB VALUE AS LOW OR HIGH;
data ADLB;
   set lb;
      if . < lbstresn < 3.15 then
         ANRIND = "L";
      else if lbstresn > 5.5 then
         ANRIND = "H";
run;

At first glance the SAS code snippet above looks fine. If the lab value is less than 3.15, then the lab value is low, and if it is greater than 5.5 then the lab value is high. The problem is that floating-point numbers are stored on computers as approximations of the value that you may see in a SAS printout. In other words, 3.15 might be stored as 3.1500000000000000000000000000000000012, which might make the program snippet above not work as hoped. To handle the floating-point comparison problem, this example can be written more safely like this:

**** FLAG LAB VALUE AS LOW OR HIGH;
data ADLB;
   set lb;
      if . < round(lbstresn,.000000001) < 3.15 then
        ANRIND = "L";
      else if round(lbstresn,.000000001) > 5.5 then
	 ANRIND = "H";
run;

Notice how the “lbstresn” variable has been rounded to an arbitrary precision to the ninth decimal place. This attempts to get around the floating-point comparison problem. At the same time, it avoids rounding the “lbstresn” variable to a precision where meaningful data are lost. Whenever you perform comparisons on numbers that are not integers, you should consider using the ROUND function.

You should read the excellent SAS Technical Support Note “TS-230: Dealing with Numeric Representation Error in SAS Applications” to learn more about SAS floating-point numbers and numeric storage precision in SAS. Another good resource for rounding issues is Ron Cody’s SAS Functions by Example, Second Edition (SAS Press, 2010). Remember that floating-point storage of non-integer numbers in SAS is done by machine-based approximation, and that can cause problems in comparisons, sorts, and any other operations on those numbers.

Was this helpful? If you're interested -- Get your copy today to receive all of Jack Shostak’s tips from SAS Programming in the Pharmaceutical Industry. (You’ll also find more free, bonus content!).  You'll find a free book excerpt, example code and data, and more.

Share

About Author

Maggie Miller

Education and Training

+ Maggie Miller was formerly a communications specialist at SAS. You'll likely find her writing blogs, shooting videos and sharing it all on social media. She has nearly ten years of journalism experience that she brings to her writing to help you learn and grow with SAS. Follow on Twitter @maggiemiller0

1 Comment

Back to Top