这两个代码在 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
。相对于x
,1e-20
比较小,而相对于0
,1e-20
一点也不小。
要解决此问题,您必须使用:
while numToAdd > tolerance %// Instead of > 0
其中 tolerance
是一些大于零的小数。
第一个版本必须下降到双倍 ~10^-308
的最小值,而第二个只需要下降到 machine epsilon ~10^-16
。 epsilon 值是满足 1+x = 1
.
的最大值 x
这意味着第一个版本大约需要 10^77
次迭代,而第二个版本只需要 10^4
.
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
。相对于x
,1e-20
比较小,而相对于0
,1e-20
一点也不小。
要解决此问题,您必须使用:
while numToAdd > tolerance %// Instead of > 0
其中 tolerance
是一些大于零的小数。
第一个版本必须下降到双倍 ~10^-308
的最小值,而第二个只需要下降到 machine epsilon ~10^-16
。 epsilon 值是满足 1+x = 1
.
x
这意味着第一个版本大约需要 10^77
次迭代,而第二个版本只需要 10^4
.