明白你说的误差来源了,我想起了当年上《大学物理》时的情景。
以下只说浮点数。
实际上必然存在这个误差,但因为浮点数的有效位的个数基本是固定的,现在处理器的计算精度在我们普通的需求面前应该能够确保这点,所以,上面两个版本从有效位的角度来说最终的结果可以认为没有任何差异。
还有一点这里提一下,前一个版本计算应该快几个 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]]