Page tree

Error rendering macro 'excerpt-include'

No link could be created for 'Training Videos'.


Ensuring Decimal Precision 

Purpose 

SAS represents numeric variables in floating point representation, a derivative of scientific notation. Floating Point representation uses a mantissa, exponent, and signs for each to represent a number. Just as our base 10 number system has values that can not be represented precisely, such as 1/3, floating point does as well. Many values can not be represented precisely, and it is crucial that you never shorten the lengths of numeric variables in SAS to less than eight bytes. We need all bits to represent the value 

From standard numeric variables in SAS and doubles in Viya, we can normally guarantee up to 15 digits of precision for real numbers, with up to 12 of those after the decimal. We have not seen differences in precision between SAS and Viya to this point. 

Best Practice 

When you make a comparison of a variable to a literal value, they may not equate because the value that is being stored in not exactly equal to that of the literal. Using the ROUND function on the variable will round the stored value of the variable appropriately so the evaluation will be true. 

Note

A rule of thumb to follow is whenever you compare a numeric non-integer variable to a literal value, always use the ROUND function 


The example below shows a comparison of both using the ROUND function and not using it.  In this example, the second log indicates that after ROUND, the values will be equal. 

/* the log indicates these values are not equal */

%let std=35;

data a;

std=.01 * &std;

if std=.35 then put 'equal';

else put 'not equal';

run;

/* log indicates that after ROUND, they are equal */

%let std=35;

data a;

std=.01 * &std;

if round(std,.01)=.35 then put 'equal';

else put 'not equal';

run;

If you want to know for sure if the internal value is what you think it is, you can create a new variable with the literal value and then output the two variables with the HEX16. format. This format shows the floating point representation so you will be able to compare the two. Continuing with the example above, below is an illustration of the floating point representation. 

1550 data a;

1551 std=.01 * &std;

1552 point35=.35;

1553 put point35=hex16. std=hex16.;

1554 if std=.35 then put 'equal';

1555 else put 'not equal';

1556 run;

POINT35=3FD6666666666666 STD=3FD6666666666667

As you can see, they are not equal. You will notice that the two floating point values are almost exact, but not completely the same. Therefore, they will not ever evaluate as equal even though they are meant to. The ROUND function will make that happen. 

It is best practice to know you data and then decide the level of significance you will need. You can use the ROUND function in you comparisons and calculations, 


Note

The safest way to avoid numeric precision issues is to work with whole numbers. For instance, when working with money amounts, you would be concerned with two decimal places. You would ROUND the numbers to the hundredths place, multiply by 100 and then use the INT function to ensure stray decimals are removed. You would then be able to do your calculations with whole numbers and divide by 100 at the end to get the decimal values back.


  • No labels