SAS 宏变量逻辑比较与科学记数法

SAS Macro Variable Logical Comparison with Scientific Notation

我在 SAS 中有一个宏无法正常工作。我有一个 %goto 语句,如果宏变量的值大于某个固定数字,就会触发该语句。宏变量由以下示例代码创建;

proc sql noprint;
select num into :num
from table;
quit;

当打开table时,num变量有标准符号的数字(例如645,435,243)。但是,宏变量&num。把它选为 6.4544E8。当 SAS 尝试将此值与 1,000,000 等数字进行比较时,这会导致出现问题。

我能够用下面的简单宏重现这个问题,唯一的区别在于宏变量赋值的方式。在下面的代码中,我直接分配 j 1E8 而不是通过 proc sql 语句。

我的问题是:为什么 SAS 无法正确计算 1E8 > 5?

%macro test();

%let i = 1;
%let j = 1E8;

data test0;
x = &i.;
output;
run;

%let i = 2;

%do %until (&i. = 11);

%put &i.;

%if &i. >= 7 %then %do;
    %if &j. > 5 %then %do;
        %goto done;
    %end;
%end;

data test&i.;
x = &i.;
output;
run;

proc append base=test0 data=test&i.;
run;

proc datasets library=work nolist;
delete test&i.;
run;

%let i = %eval(&i + 1);

%end;

%done: %mend;

%test();

因为 %if &j > 5 不是在执行 "mathematical" 比较,而是有效的文本比较。常规的旧 %eval 只会进行整数数学运算,比较基本上只是将两者作为文本进行比较。 SAS 宏变量几乎总是被视为文本,而不是其他任何东西,因此如果您希望 SAS 首先将它们视为数字,请始终使用 %sysevalf - 或者使用常规数据步变量。

如果你想让SAS把宏变量内容当作实数,你需要使用%sysevalf

%if &i. >= 7 %then %do;
    %if %sysevalf(&j. > 5,boolean) %then %do;
        %goto done;
    %end;
%end;

请注意,如果您选择了 %let j = 7E8;,它似乎会起作用 - 因为它只是将 57 进行比较,这是事实。

甚至更好,%let J = 5E8; 会更大——因为 E 总比没有大——但是如果你比较 &j > 5A 它仍然有效,而 &j > 5F 则无效。它在那里比较 E(字母)和 F(字母),发现 F 更大。