这两个代码在 MATLAB 中获得无限级数的和有什么区别?

What's the difference between these two codes to get the sum of infinite series in MATLAB?

1 + 1/(2^4) + 1/(3^4) + 1/(4^4) + ...

这是我想要求和的无限级数。所以我在 MATLAB 中写了这段代码。

n = 1;
numToAdd = 1;
sum = 0;
while numToAdd > 0
    numToAdd = n^(-4);
    sum = sum + numToAdd;
    n = n + 1;
end
disp(sum);

但是我无法得到结果,因为这段代码发生了死循环。但是,我在下面编写的代码——运行良好。只用了一秒钟。

n = 1;
oldsum = -1;
newsum = 0;
while newsum > oldsum
    oldsum = newsum;
    newsum = newsum + n^(-4);
    n = n+1;
end
disp(newsum);

我又看了一遍这些代码,google了一会儿,也没找到关键点。这两个代码有什么区别?是MATLAB中double的精度问题吗?

问题归结为:

x = 1.23456789; % Some random number
xEqualsXPlusEps = (x == x + 1e-20)
ZeroEqualsEps =   (0 ==     1e-20)

xEqualsXPlusEps 将是 true,而 ZeroEqualsEps 是错误的。这是由于浮点运算的工作方式。值 1e-20 小于 x 的最低有效位,因此 x+1e-20 不会大于 x。但是 1e-20 不被认为等于 0。相对于x1e-20比较小,而相对于01e-20一点也不小。

要解决此问题,您必须使用:

while numToAdd > tolerance %// Instead of > 0

其中 tolerance 是一些大于零的小数。

第一个版本必须下降到双倍 ~10^-308 的最小值,而第二个只需要下降到 machine epsilon ~10^-16。 epsilon 值是满足 1+x = 1.

的最大值 x

这意味着第一个版本大约需要 10^77 次迭代,而第二个版本只需要 10^4 .