| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3249 人关注过本帖
标题:关于求平均值算法的问题
只看楼主 加入收藏
i_kakac
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2009-7-26
结帖率:0
收藏
已结贴  问题点数:20 回复次数:8 
关于求平均值算法的问题
sum+=x;avg=sum/i和avg+=(x-avg)/i
请问后者有什么好处啊?
搜索更多相关主题的帖子: 平均值 算法 
2009-07-26 23:11
xiaogu149162
Rank: 2
等 级:论坛游民
帖 子:47
专家分:97
注 册:2009-7-16
收藏
得分:5 
好像结果不一样吧
2009-07-26 23:30
bin1654
Rank: 2
等 级:论坛游民
帖 子:11
专家分:15
注 册:2009-7-8
收藏
得分:5 
avg初始化是多少
2009-07-26 23:46
i_kakac
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2009-7-26
收藏
得分:0 
回复 3楼 bin1654
当然是0.0啊
2009-07-26 23:48
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:5 
数值上应该是等价的,不过后者应该误差有点大。 优点是可以剩下计算和的空间,其实我觉得都差不多。

专心编程………
飞燕算法初级群:3996098
我的Blog
2009-07-27 02:58
prankmoon
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:161
专家分:921
注 册:2009-7-21
收藏
得分:5 
以下是引用StarWing83在2009-7-27 02:58的发言:

数值上应该是等价的,不过后者应该误差有点大。 优点是可以剩下计算和的空间,其实我觉得都差不多。


为什么后者应该误差有点大?

[[it] 本帖最后由 prankmoon 于 2009-7-27 03:56 编辑 [/it]]
2009-07-27 03:53
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
整形运算是不会产生误差的,但是浮点运算会。如果所有数据是整数(sum是整形的),那么第一个式子唯一产生误差的地方就是那个除法。而第二个式子每次都会产生误差。如果sum是浮点型的,那么sum版本每次加一次,最后除一次,而第二个版本每次都要加一次,减一次,除一次,误差自然比较大。

专心编程………
飞燕算法初级群:3996098
我的Blog
2009-07-27 03:58
prankmoon
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:161
专家分:921
注 册:2009-7-21
收藏
得分:0 
明白你说的误差来源了,我想起了当年上《大学物理》时的情景。

以下只说浮点数。

实际上必然存在这个误差,但因为浮点数的有效位的个数基本是固定的,现在处理器的计算精度在我们普通的需求面前应该能够确保这点,所以,上面两个版本从有效位的角度来说最终的结果可以认为没有任何差异。

还有一点这里提一下,前一个版本计算应该快几个 CPU 指令,后一个有可能节约一点点空间和一点点时间。我写了两个版本的函数,然后对比两者反汇编后指令的多少:
函数:
void fun(double sum, double x, double avg, int i)
{
    sum+=x;
    avg=sum/i;
   
    printf("fun: %lf\n", avg);
   
    return;
}

void foo(double sum, double x, double avg, int i)
{
    avg+=(x-avg)/i;
   
    printf("foo: %lf\n", avg);
   
    return;
}

反汇编后的比较:
00401000  /$  DD4424 04      fld     qword ptr [esp+4]
00401004  |.  DC4424 0C      fadd    qword ptr [esp+C]
00401008  |.  DA7424 1C      fidiv   dword ptr [esp+1C]
0040100C  |.  83EC 08        sub     esp, 8
0040100F  |.  DD1C24         fstp    qword ptr [esp]
00401012  |.  68 30904000    push    00409030                         ;  ASCII "fun: %lf",LF
00401017  |.  E8 74000000    call    <printf>
0040101C  |.  83C4 0C        add     esp, 0C
0040101F  \.  C3             retn
00401020  /$  DD4424 0C      fld     qword ptr [esp+C]
00401024  |.  DC6424 14      fsub    qword ptr [esp+14]
00401028  |.  DA7424 1C      fidiv   dword ptr [esp+1C]
0040102C  |.  83EC 08        sub     esp, 8
0040102F  |.  DC4424 1C      fadd    qword ptr [esp+1C]
00401033  |.  DD1C24         fstp    qword ptr [esp]
00401036  |.  68 3C904000    push    0040903C                         ;  ASCII "foo: %lf",LF
0040103B  |.  E8 50000000    call    <printf>
00401040  |.  83C4 0C        add     esp, 0C
00401043  \.  C3             retn

可以看出前一版本的指令更少。不过,也许这种比较意义不大。

完整的代码在这里:
#include <stdio.h>
#include <stdlib.h>

void fun(double sum, double x, double avg, int i)
{
    sum+=x;
    avg=sum/i;
   
    printf("fun: %lf\n", avg);
   
    return;
}

void foo(double sum, double x, double avg, int i)
{
    avg+=(x-avg)/i;
   
    printf("foo: %lf\n", avg);
   
    return;
}

int main()
{

    double sum = 0;
    double x = 13;
    double avg = 0;
    int i = 17;

    fun(sum, x, avg, i);
   
    foo(sum, x, avg, i);
   
    return 0;
}

[[it] 本帖最后由 prankmoon 于 2009-7-27 04:34 编辑 [/it]]
2009-07-27 04:12
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
我说得是有误差,但是这种误差的扩大显然是线性的,因此在正常大小的数据范围内当然比较正常,然而如果是上百万数字求平均值(数据库应用),那差别就很可观了(当然那种情况都是DBMS在处理了)。

其次,这两种有各自的适用范围的。第二种适合“一次输入数据,最后查询平均值”的情况。显然这种情况,第二次的除法是可以省掉的。第一种则适合“输入数据的同时随时查询当前的平均值“的情况,因此在查询次数很多的时候比较有优势。

从ls的分析来看,第二种方法在最坏情况(每次输入数据都查询平均值)的情况下,仍然只比第一种多一个浮点指令。而平时浮点指令少于第一种情况,因此平均性能应该强于第一种。而第一种优在只需要一个存储单元就足够了,空间比较省。各有所长吧,不过各缺点优点全都不明显,其实还是可以随便选的。至于浮点数的误差问题,就看实现和应用如何了。

专心编程………
飞燕算法初级群:3996098
我的Blog
2009-07-27 06:25
快速回复:关于求平均值算法的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.033485 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved