全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 SAS专版
2026 9
2013-01-13
%let X=2.5;
data a;
        M=0.1;
        O=0.2;
        test=M*&X-O;
        if 0<=M*&X-O<0.05 then flag=-1;
        else flag=0;
run;

我不敢相信自己,请高手多多指导,谢谢!

上面程序运行结果发现flag=-1,但明明M*&X-O等于0.05,而不是小于0.05,flag结果应该是0才对。一百万个想不通。

下面同样的程序,改点数字,结果就正确了。
%let X=5;
data a;
        M=0.1;
        O=0.2;
        test=M*&X-O;
        if 0<=M*&X-O<0.3 then flag=-1;
        else flag=0;
run;

二维码

扫码加我 拉你入群

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

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

全部回复
2013-1-13 00:30:45
改成
  (0 <= M *&X-O)和(M&X-O<0.05)flag=-1;
试试。
  不要写0<X<Y这种式子这样是数学式,(0 <A & A <B)才是程式
二维码

扫码加我 拉你入群

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

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

2013-1-13 00:50:56
我不觉得这是问题,事实上,写成下面形式结果也不对。
%let X=2.5;
data a;
        M=0.1;
        O=0.2;
        test=M*&X-O;
        if 0<=M*&X-O and M*&X-O<0.05 then flag=-1;
        else flag=0;
run;
二维码

扫码加我 拉你入群

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

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

2013-1-13 01:20:10
Your example may not be valid. But it could be an issue in a numeric comparison, see example
after your code. You need to understand the numeric precision in SAS Software. SAS stores all numeric values using floating-point, or real binary, representation. It also depends on the system(IBM mainframe, windows, etc.). The difference is very small. You can see from example below. You can avoid the situation by introducing a round function.




101  %let X=5;
102  data a;
103          M=0.1;
104          O=0.2;
105          test=M*&X-O;
106          if 0<=M*&X-O<0.3 then flag=-1;
107          else flag=0;
108    put (_all_) (=);
109  run;

M=0.1 O=0.2 test=0.3 flag=0
NOTE: The data set WORK.A has 1 observations and 4 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.01 seconds


110
111
112
113  data _null_;
114     do i=-0.3 to 0.3 by .1;
115        flag=(i=0);
116        put (_all_) (=);
117     end;
118  run;

i=-0.3 flag=0
i=-0.2 flag=0
i=-0.1 flag=0
i=2.775558E-17 flag=0
i=0.1 flag=0
i=0.2 flag=0
i=0.3 flag=0
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.01 seconds

119
120
121  data _null_;
122     do i=-0.3 to 0.3 by .1;
123        flag=(round(i,1e-12)=0);
124        put (_all_) (=);
125     end;
126  run;

i=-0.3 flag=0
i=-0.2 flag=0
i=-0.1 flag=0
i=2.775558E-17 flag=1
i=0.1 flag=0
i=0.2 flag=0
i=0.3 flag=0
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.01 seconds

二维码

扫码加我 拉你入群

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

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

2013-1-13 01:55:38
bobguy, thanks. Understand your point, still I think that is some bug.

If 'test'=0.049999... or 0.050000...1 then I agree we can blame to the numeric storage problem.
My point is 'test' is a length 8 number, if it is true M*&X-O not exactly 0.05, why not show that in 'test' but only in the inequality?

%let X=2.5;
data a;
        M=0.1;
        O=0.2;
        test=M*&X-O;
        if 0<=M*&X-O<0.05 then flag=-1;
        else flag=0;
run;
二维码

扫码加我 拉你入群

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

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

2013-1-13 10:03:29
caibirdcnb 发表于 2013-1-13 01:55
bobguy, thanks. Understand your point, still I think that is some bug.

If 'test'=0.049999... or  ...
我这里显示flag=0.

楼主可以将变量的饿16进制格式的值put出来看看。

40   %let X=2.5;
41   data a;
42           M=0.1;
43           O=0.2;
44           test=M*&X-O;
45           tmp=0.05;
46           put  test= hex16.;
47           put tmp= hex16.;
48           if 0<=M*&X-O<0.05 then flag=-1;
49           else flag=0;
50           put _all_;
51   run;

test=3FA999999999999A
tmp=3FA999999999999A
M=0.1 O=0.2 test=0.05 tmp=0.05 flag=0 _ERROR_=0 _N_=1
NOTE: The data set WORK.A has 1 observations and 5 variables.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds
二维码

扫码加我 拉你入群

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

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

点击查看更多内容…
相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群