Hi,
new here! I'd like to know why this example works on SAS Studio
%macro test_macro();
%let a = 1.0;
%let b = 2.0;
%let delta = %sysevalf(&a. - &b.);
%put delta = &delta.;
%if &delta. <= 0.0 %then %do;
%put delta is NEGATIVE;
%end;
%mend test_macro;
%test_macro();
while instead the following code produces an error.
%macro test_macro();
%let a = 0.1;
%let b = 0.11;
%let delta = %sysevalf(&a. - &b.);
%put delta = &delta.;
%if &delta. <= 0.0 %then %do;
%put delta is NEGATIVE;
%end;
%mend test_macro;
%test_macro();
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: &delta. <= 0.0 ERROR: The macro TEST_MACRO will stop executing.
Is there any solution available?
This should work:
%macro test_macro();
%let a = 0.1;
%let b = 0.11;
%let delta = %sysevalf(&a. - &b.);
%put delta = &delta.;
%if %sysevalf(&delta. <= 0.0) %then %do;
%put delta is NEGATIVE;
%end;
%mend test_macro;
Without the %sysevalf, the macro processor doesn't do non-integer arithmetic.
This should work:
%macro test_macro();
%let a = 0.1;
%let b = 0.11;
%let delta = %sysevalf(&a. - &b.);
%put delta = &delta.;
%if %sysevalf(&delta. <= 0.0) %then %do;
%put delta is NEGATIVE;
%end;
%mend test_macro;
Without the %sysevalf, the macro processor doesn't do non-integer arithmetic.
You show that you understand how to force the macro processor to handle non-integer arithmetic.
%let delta = %sysevalf(&a. - &b.);
So why didn't you use that later on?
%if %sysevalf(&delta. <= 0.0) %then %do;
SAS makes its own rules. Whatever you learned from those other 8 programming languages may or may not apply to SAS.
Regarding "an unclear distinction between integer and non-integer logical operations", the documentation for %SYSEVALF says so clearly
%SYSEVALF Macro Function
Evaluates arithmetic and logical expressions using floating-point arithmetic.
@caerbannog wrote:
Even though I've been able to put together that example, I haven't written the original code but I've been asked to maintain it and run it. I'm familiar with 8 programming languages and proficient (professionally) with at least half of them. Still, I think this is the only case where I've seen such an unclear distinction between integer and non-integer logical operations, and the error message tells something about a character operand. In addition, 1.0, 2.0 and 0.0 might look like integers to a human being, but usually, a parser should interpret them as non-integer numbers, so I also assumed that was the case for SAS.
It is probably helps to understand that SAS code and macro code are two different languages.
In SAS code there is only one type of number, floating point numbers. But in some languages support other type of numbers including integers. Try calculating 5/3 and 5.0/3.0 in one of the languages and see if you get the same results. In SAS code you always get the same answer since SAS only using floating point numbers.
But the macro processor is just a text manipulation tool. Everything is a character string to the macro processor. But to support things like %DO loops they needed to include some recognition of numbers. So they build in some integer arithmetic (including integer comparison operators) with the %EVAL() function. That is what is used by %IF and %DO loops to deal with integer arithmetic. Since integers do not need a decimal place, that is why something with a period is seen as a string.
To support the occasional need for floating point arithmetic they added the %SYSEVALF() function.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.