EVAL and SYSEVALF are the two macro functions that evaluate arithmetic expressions and logical expressions.
First, let’s understand why do we need EVAl or the SYSEVALF function. In SAS, Macro’s are text-based which means there are no numeric variables. Whereas in the Data Step, numbers and characters are two separate things.
Therefore, arithmetic and logical operations are not as straight forward. That is why we need evaluations function as the %Eval Macro Function.
See the example below.
%let x = 5;
%let y = 1+2;
%let z = &x+5;
%put &=x &=y &=z;
In the log:
X=5 Y=1+2 Z=5+5
As you can see, the arithmetic expressions are not evaluated and macro variables resolve to plain text.
The %EVAL function is used to evaluate integer arithmetic or logical expressions. The argument passed in the %EVAL function is converted from character to numeric and the results are converted back to character.
%EVAL(arithmetic expression|logical expression)
This is a simple example of the Eval function.
%let x = 5; %let y = %eval(1+2); %let z = %eval(&x+5); %put &=x &=y &=z;
In the log:
X=5 Y=3 Z=10
The %Eval Function treats integers as whole numbers. As in the example above, 2 and 1 were treated as whole numbers and the evaluation was successful.
You cannot use floating-point numbers with the eval function. For example, you cannot add 1.5 to 2 as in the above example. SAS treats period in a numeric expression as a character value and this will cause an error because it failed to add a character value to a number.
All parts of the macro language that evaluate expressions (for example, %IF and %DO statements) call %EVAL to evaluate the expressions.
The %EVAL function can be called explicitly or implicitly. It appears elusive and problematic when its argument is a macro expression contains special characters, mixed arithmetic and logical operators, or any other macro quoting functions.
Interaction with special characters
Once %EVAL is invoked, whether implicitly or explicitly, its argument is scanned, resolved, and passed to %EVAL to evaluate. Then %EVAL determines whether it performs an integer arithmetic evaluation or a logical comparison based on the actual resolved argument.
Eval function treats the expression is as arithmetic when all operands in its arguments can be interpreted as an integer. If at least one operand cannot be interpreted as numeric, the expression is treated as logical. We must be careful when it comes to logical comparisons.
%let x = %eval(10.0 > 5.0); %put &=x;In the log X=0
Here, I use the %Eval Function to evaluate whether 10.0 is greater than 5.0. Practically it is true and should return 1 but remember, that the %Eval Function treats both 10.0 and 5.0 as character values because of the period. Therefore, a character comparison takes place from left to right.
While comparing character values, SAS uses the same sort sequence as Proc Sort. This means that ‘1’ comes before ‘2’. Therefore, the %Eval Function evaluates to 0.
If a division operation results in a fraction, the fraction is truncated to an integer. You can use the %SYSEVALF function to deal with non-integer floating-point arithmetic and comparisons.
%let x = %eval(19/5);; %put &=x;In the log. X=3
In this example, I divide 19 by 5 using the eval function e. 19 divided by 5 is 3.8. However, the %Eval Macro Function truncates the result to an integer. Therefore, the returned value is 3.
%EVAL can have multiple arithmetic or logical expressions or mixed expressions as an argument. The order in which operations are performed in the macro language is the same as in the DATA step.
In macro expressions, a period (.) can be used as a separator for macro variables. For example, in &x.y, the period separates the macro variable &X from the regular text Y.
%EVAL only accepts operands in arithmetic expressions that represent integers and operands that contain a period character generates an error when they are part of an integer arithmetic expression.
However, if a period appears in a resolved logical expression, it will be treated as a regular character. For example, if the SAS version is 8.2, the expression
%eval(&sysver > 10) is evaluated as true.
The following examples show correct and incorrect usage of the period, respectively:
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: 10.0+20.0
Now see the different results of using %EVAL and %SYSEVALF.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: 10+.
NOTE: Missing values were generated as a result of performing an operation on missing values during %SYSEVALF expression evaluation.
%EVAL treats the period as a character value, which causes an error in an arithmetic operation. However, %SYSEVAL treats the period as a missing value and returns a missing value without an error.
%SYSEVALF function is used to evaluate floating-point numbers. The result of the %SYSEVALF function are converted to text but you can also request %SYSEVALF to convert the result to a different format. Below are the formats that can be used with the %sysevalf function.
Syntax: %SYSEVALF(expression<, conversion-type>)
When requesting one of these four conversion types, specify the conversion type as the second argument to %SYSEVALF.
%sysevalf(1/3,boolean) /* returns 1 */ %sysevalf(10+.,boolean) /* returns 0 */
The %SYSEVALF function evaluates arithmetic and logical expressions using floating-point arithmetic and returns a value that is formatted using the BEST32. format.
You can use %SYSEVALF function to perform arithmetic calculations that have floating-point value.
Below are some examples of the %SYSEVALF function.
%put %sysevalf(10.0*30.0); * returns in the log is 300; %put %sysevalf(10.5+20.8); * returns in the log is 31.3; %put %sysevalf(50/30); * returns in the log is 1.66666666666666;
%SYSEVALF function perform arithmetic calculations and the result of the evaluation can be a floating-point value like in the final and last macro variable case, but as in integer arithmetic calculations, the result is always a text.
The %SYSEVALF function is used in conjugation with other functions like INTEGER, CEIL, and FLOOR.
For example, the following %PUT statements return 3, 4 and 3 respectively:
%let pi=2.14; %put %sysevalf(&pi,integer); *PI returns in the log is 2; %put %sysevalf(&pi, ceil); *PI returns in the log is 3; %put %sysevalf(&pi,floor); *PI returns in the log is 2;