楼主: sopching
2040 9

[原创博文] 大家来看看这个宏 有意思的结果 [推广有奖]

  • 1关注
  • 3粉丝

博士生

63%

还不是VIP/贵宾

-

威望
0
论坛币
208 个
通用积分
0
学术水平
19 点
热心指数
23 点
信用等级
9 点
经验
4541 点
帖子
181
精华
0
在线时间
466 小时
注册时间
2009-12-20
最后登录
2018-7-3

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
今天逛博,无意中看到下面一道趣题,关于宏的:
%macro aa;
%let condition=( 1.2>=1 and 1.2<1.5 ) and ( 1123>=800 and 1123<1200 );

   %if &condition %then %do;
    %put x;
   %end;
   %else %do;
%put M;
   %end;

%let condition=(( 1.2>=1 and 1.2<1.5 ) and ( 1123.1>=800 and 1123.1<1200 ));
   %if &condition %then %do;
    %put Y;
   %end;
   %else %do;
%put N;
   %end;

   %mend aa;
%aa;
跑了下 结果是X N  
很有意思,大家能帮忙解释下吗?
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:有意思 condition dition Macro con

回帖推荐

pobel 发表于6楼  查看完整内容

这个问题的关键在于%IF和%EVAL的运行机制, %if语句会自动将%eval函数用在%if后的条件上, %eval的运行: If all operands can be interpreted as integers, the expression is treated as arithmetic. If at least one operand cannot be interpreted as numeric, the expression is treated as logical. If a division operation results in a fraction, the fraction is truncated to an integer. 所以,如果作为%if的 ...

本帖被以下文库推荐

沙发
jingju11 发表于 2010-11-3 23:47:01 |只看作者 |坛友微信交流群
1# sopching


For 2nd condition (1123.1>=800) is FALSE because 1<8 in the character order, and thus the 2nd condition does not meet.
Using %sysevalf(&condition) may get really 'true' result as you expected.
JingJu
已有 3 人评分学术水平 热心指数 信用等级 收起 理由
soporaeternus + 1 + 1 + 1 我很赞同
pobel + 1 + 1 + 1 精彩帖子
hopewell + 1 + 1 + 1 我很赞同

总评分: 学术水平 + 3  热心指数 + 3  信用等级 + 3   查看全部评分

使用道具

藤椅
sopching 发表于 2010-11-4 00:45:16 |只看作者 |坛友微信交流群
2# jingju11
那为什么第一个条件的 不用%sysevalf?1.2<1.5是如何成立的?

使用道具

板凳
jingju11 发表于 2010-11-4 00:48:47 |只看作者 |坛友微信交流群
sopching 发表于 2010-11-4 00:45
2# jingju11
那为什么第一个条件的 不用%sysevalf?1.2
1=1, .=., 2<5 so 1 . 2 < 1 . 5

使用道具

报纸
一眼瞬间 发表于 2010-11-4 00:53:08 |只看作者 |坛友微信交流群
赞啊,大师果然厉害!

使用道具

地板
pobel 在职认证  发表于 2010-11-4 07:42:27 |只看作者 |坛友微信交流群
这个问题的关键在于%IF和%EVAL的运行机制,

%if语句会自动将%eval函数用在%if后的条件上,

%eval的运行:
If all operands can be interpreted as integers, the expression is treated as arithmetic. If at least one operand cannot be interpreted as numeric, the expression is treated as logical. If a division operation results in a fraction, the fraction is truncated to an integer.

所以,如果作为%if的条件,(1123>=800) 的结果就是TRUE(数学运算),而(1123.1>=800)的结果就是FALSE(字符比较)。

例如:
%macro test;
   %if 12>5 %then %put This is OK!;
   %else %put This is not OK!;
   %if 12.0>5.0 %then %put This is right!;
   %else %put This is wrong!;
%mend;

%test
已有 2 人评分学术水平 热心指数 信用等级 收起 理由
hopewell + 1 + 1 + 1 我很赞同
soporaeternus + 1 + 1 + 1 我很赞同

总评分: 学术水平 + 2  热心指数 + 2  信用等级 + 2   查看全部评分

和谐拯救危机

使用道具

7
soporaeternus 发表于 2010-11-4 09:03:55 |只看作者 |坛友微信交流群
我的猜测也是%if 之后默认加了%eval()运算,而不是%sysevalf()运算,因为那个比较结果和%eval()的方式一致
但是有没有官方的对于
“%if语句会自动将%eval函数用在%if后的条件上”
粗粗查了下,没有找到
Let them be hard, but never unjust

使用道具

8
pobel 在职认证  发表于 2010-11-4 09:25:46 |只看作者 |坛友微信交流群
帮助里面我也没找到,我是从《SAS macro programming made easy》的165页看到的:
The macro functions that automatically invoke %EVAL around the expressions supplied to them are
      => %SUBSTR and %QSUBSTR
      => %SCAN and %QSCAN
The macro language statements that automatically invoke %EVAL around the expressions supplied to them are
      => %DO
      => %DO %UNTIL
      => %DO %WHILE
      => %IF
已有 2 人评分学术水平 热心指数 信用等级 收起 理由
sopching + 1 + 1 + 1 谢谢 学习了
soporaeternus + 1 + 1 + 1 十分感谢,学习了

总评分: 学术水平 + 2  热心指数 + 2  信用等级 + 2   查看全部评分

和谐拯救危机

使用道具

9
soporaeternus 发表于 2010-11-4 09:48:28 |只看作者 |坛友微信交流群
经hopewell大大的指点
我在SAS HELP中找到了星星点点的原文
Macro Expressions

How the Macro Processor Evaluates Logical Expressions

......
A special case of a character operand is an operand that looks numeric but contains a period character. If you use an operand with a period character in an expression, both operands are compared as character values. This can lead to unexpected results.
......
Because the %IF-THEN statement in the COMPNUM macro uses integer evaluation, it does not convert the operands with decimal points to numeric values. The operands are compared as character strings using the host sort sequence, which is the comparison of characters with smallest-to-largest values.


原文以
%macro compnum(first,second);   
%if &first>&second %then %put &first is greater than &second;   
%else %if &first=&second %then %put &first equals &second;   
%else %put &first is less than &second;
%mend compnum;
调用
%compnum(10,2.0)
出结果
10 is less than 2.0
解释这个现象,应该和楼主的意思是一致的
附上hopewell大大的指点,sas support上的:
All parts of the macro language that evaluate expressions (for example, %IF and %DO statements) call %EVAL to evaluate the condition. For a complete discussion of how macro expressions are evaluated, see Macro Expressions.

http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a000208971.htm
已有 2 人评分学术水平 热心指数 信用等级 收起 理由
sopching + 1 + 1 + 1 谢谢链接 学习了
pobel + 1 + 1 + 1 谢谢!链接有点问题。

总评分: 学术水平 + 2  热心指数 + 2  信用等级 + 2   查看全部评分

Let them be hard, but never unjust

使用道具

10
sopching 发表于 2010-11-4 16:12:41 |只看作者 |坛友微信交流群
谢谢各位的帮助!我明白他的机制了!

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-5-11 15:17