楼主: luijb
4962 31

两种求和方式为什么有如此大的差异? [推广有奖]

11
pobel 在职认证  发表于 2013-9-13 10:48:28
以下纯属个人推测:

我认为这应该和SUM()函数的工作机制有关系,也就是SUM()函数将各个参数加和的方式和直接用”加号“的方式是不同的。而且SUM()函数中参数顺序的变化也会造成结果的不同,如:


data test;
   sum1=sum(35.8,17.8,17.8);
   sum2=sum(17.8,17.8,35.8);
   put sum1= hex16.;
   put sum2= hex16.;
   d=sum2-sum1;
   put d=;
run;

和谐拯救危机

12
pobel 在职认证  发表于 2013-9-13 10:57:39
在SAS中,当数值变量的值不是整数时,运算结果有时也会出乎意料,这应该和数值的存储方式有关,比如下面的例子:

data test1;
     do i=1 to 10;
            x+.1;
         end;

         if x=1 then put "---" x "equals to 1";
         else put "---" x "does not equal to 1";
run;

data test2;
     x=0.7;
         x+.1;         x+.1;         x+.1;
         if x=1 then put "---" x "equals to 1";
         else put "---" x "does not equal to 1";
run;

data test3;
    if .7+.1=.8 then put "HAHA";
        else put "-------HEHE";
run;

data test4;
    do i=.1 to 0.999999999 by .1;
           x+1;
        end;
        put x=;

        do i=.1 to 0.99999999 by .1;
           y+1;
        end;
        put y=;
run;
和谐拯救危机

13
jingju11 发表于 2013-9-13 11:10:29
我的看法。相等本身的概念是相对的。两个苹果如果误差只有一克,我们就认为它们是等重的。在没有精确度的前提之下来谈论两个值是否相同,对SAS这样的软件意义不大。比方说,如果给定误差过小,sas也许根本无法估算出最大值,最小值。因为再小的步长,也总有比他更小的。而给定的步长刚好踏到极值点上的概率根本就为0。京剧

14
playmore 发表于 2013-9-13 11:26:17
jingju11 发表于 2013-9-13 11:10
我的看法。相等本身的概念是相对的。两个苹果如果误差只有一克,我们就认为它们是等重的。在没有精确度的前 ...
嗯,其实就是浮点数在机器中二进制代码存储时的问题

在网上搜了个具体的解释i
http://www.cnblogs.com/xiongpq/archive/2010/05/17/1737747.html

这个问题在Python的早期版本还要严重
你输个1.5+1都不等于2.5的,总是要差那么一点
playmore邀请您访问ChinaTeX论坛!!!进入ChinaTeX论坛

15
愤怒的老鸟 发表于 2013-9-13 11:31:32
楼上正解
梅花香自苦寒来

16
jingju11 发表于 2013-9-13 11:41:49
the key is, (1.5+1)-2.5 <0.1, or <0.01, or <0.001. That may be enough for us. not like mathematicians, we may have never cared about if 1.5+1 =2.5 or not. We may only concern about if the two are close enough.
Jingju

17
双修阁主の 发表于 2013-9-13 15:08:15
直接相加,如果某个变量的值缺失,那么和的结果也是缺失;用SUM函数就避免了这种情况。

18
妖帝东皇 发表于 2013-9-13 15:57:33
下载了打不开!
Sum(变量1,变量2,变量n);
求和函数,当变量名连续编号时,可简写为
Sum(of 变量1-变量n);
┏━━━━━━━━━━━━━━┓
   ☞❤学而无友必然孤陋寡闻!❤
┗━━━━━━━━━━━━━━┛

19
luijb 在职认证  发表于 2013-9-13 16:27:21
应该是数据的存储方式有关,如果都限制了小数的位数,这个问题就不存在了。
问题是这类问题防不胜防,我也在筛选数据的的时候才发现的,我需要找出 总分不是100的记录,结果列出了这3条,事实上 列出的结果均等于0。
西格玛临床统计服务工作室http://www.sigma-stat.com/,luijb@163.com

20
yuerqieqie 发表于 2013-9-13 21:00:12
pobel 发表于 2013-9-13 10:48
以下纯属个人推测:

我认为这应该和SUM()函数的工作机制有关系,也就是SUM()函数将各个参数加和的方式和 ...
同意。
这不仅和浮点数用二进制表达的精度问题有关系,还跟sum()和加号的工作机制有关系。
求和结果取决于中间存储,每次存储都有可能损失精度。
sum(35.8,17.8,17.8) 和 35.8+17.8+17.8的结果是一样的,先计算35.8+17.8并存储,然后用存储值+17.8。sum(17.8,17.8,35.8) 和 17.8+17.8+35.8一样,先计算17.8+17.8并存储,然后用存储值+35.8。

如果将程序改为

data test1;
  x1 = 35.8; x2 = 17.8; x3 = 17.8;
   sum1=sum(x1,x2,x3);
   sum2=sum(x2,x3,x1);
   put sum1= hex16.;
   put sum2= hex16.;
   d=sum2-sum1;
   put d=;
run;

data test2;
  x1 = 35.8; x2 = 17.8; x3 = 17.8;
   sum1 = x1 + x2 + x3;
   sum2 = x2 + x3 + x1;
   put sum1= hex16.;
   put sum2= hex16.;
   d=sum2-sum1;
   put d=;
run;

会发现sum()的结果不一样但用加号的时候结果却是一样的。推测是在使用变量的时候,sum()仍然采用中间存储机制,但是加号却不产生中间结果

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

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2026-1-1 04:14