楼主: caibirdcnb
1815 9

[问答] SAS计算有bug? [推广有奖]

  • 0关注
  • 36粉丝

讲师

47%

还不是VIP/贵宾

-

威望
0
论坛币
1367 个
通用积分
16.5538
学术水平
67 点
热心指数
70 点
信用等级
64 点
经验
6762 点
帖子
206
精华
2
在线时间
433 小时
注册时间
2011-8-31
最后登录
2023-9-23

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

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

经管之家联合CDA

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

感谢您参与论坛问题回答

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

+2 论坛币
%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;

二维码

扫码加我 拉你入群

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

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

关键词:bug Data test Est let 计算

沙发
bbear 发表于 2013-1-13 00:30:45 |只看作者 |坛友微信交流群
改成
  (0 <= M *&X-O)和(M&X-O<0.05)flag=-1;
试试。
  不要写0<X<Y这种式子这样是数学式,(0 <A & A <B)才是程式

使用道具

藤椅
caibirdcnb 发表于 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;

使用道具

板凳
bobguy 发表于 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

使用道具

报纸
caibirdcnb 发表于 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;

使用道具

地板
pobel 在职认证  发表于 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
和谐拯救危机

使用道具

7
bbear 发表于 2013-1-13 11:13:34 |只看作者 |坛友微信交流群
请问楼主sas 是用那一版, 我将你写的程序放到9.2. FLAG=0;

使用道具

8
caibirdcnb 发表于 2013-1-13 12:51:17 |只看作者 |坛友微信交流群
谢谢楼上各位,我用的是9.3 64位。我看到的test和tmp结果不一样,我怀疑是SAS bug,只有这个0.05出问题,同样的程序换几个数字结果就正确了。


1    %let X=2.5;
2    data a;
3    M=0.1;
4    O=0.2;
5     test=M*&X-O;
6      tmp=0.05;
7             put  test= hex16.;
8               put tmp= hex16.;
9             if 0<=M*&X-O<0.05 then flag=-1;
10             else flag=0;
11             put _all_;
12      run;

test=3FA9999999999998
tmp=3FA999999999999A
M=0.1 O=0.2 test=0.05 tmp=0.05 flag=-1 _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.42 seconds
      cpu time            0.00 seconds

使用道具

9
bbear 发表于 2013-1-13 17:08:54 |只看作者 |坛友微信交流群
前面B大及P大说的就原因。
可以这样解。
%let X=2.5;
data a;
         M=0.1;
         O=0.2;
         test=round(M*&X-O,0.01);
         if 0<=test<0.05 then flag=-1;
         else flag=0;
run;

  data b;
         M=0.1;
         O=0.2;
         test=round(M*&X-O,0.01);
         T05=round(0.05,0.01);
         if 0<=test<T05 then flag=-1;
         else flag=0;
run;
在9.3 64上就會OK. flag=0;

使用道具

10
sxlion 发表于 2013-6-28 18:18:47 |只看作者 |坛友微信交流群

使用道具

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

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

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

GMT+8, 2024-5-2 03:56