用MATLAB计算pi,结果不好

时间:2015-04-19 09:17:33

标签: matlab symbolic-math arbitrary-precision

我正在使用这个.m文件用MATLAB

计算pi
function calpi(n)
    S = 0;
    for i=1:n
        if mod(i,2) == 0
            S=S-1/(2*i-1)*(4*((1/5)^(2*i-1))-(1/239)^(2*i-1));
        else
            S=S+1/(2*i-1)*(4*((1/5)^(2*i-1))-(1/239)^(2*i-1));
        end    
    end
    S = 4*S;
    S=vpa(S,50)

n <= 8时,没关系。 但是当n >= 9时,结果完全变为实际的pi。 我想要的只是获得实际结果来分析这种方法。

>> calpi(9)
S =
3.1415926535897932384626433832795028841971693993751

>> vpa(pi,50)
ans =
3.1415926535897932384626433832795028841971693993751

MATLAB有什么问题?

1 个答案:

答案 0 :(得分:4)

首先:您需要在MATLAB中指定您希望变量精度 之前实际进行计算。

您的函数calpi的作用是:使用内置的double - precision数据类型计算近似值,然后将其转换为符号vpa 。如果你这样做的话,你不能得到比double更准确的近似值。

所以第一步是在计算之前使用vpa

function S = calpi(n)
S = vpa(0,50);
for i = 1:n
    if mod(i,2) == 0
        S=S-1/(2*i-1)*(4*((1/5)^(2*i-1))-(1/239)^(2*i-1));
    else
        S=S+1/(2*i-1)*(4*((1/5)^(2*i-1))-(1/239)^(2*i-1));
    end
end
S = 4*S;

如果您查看输出,您将看到仍然只返回双精度结果。 这是因为当完成计算1/(2*i-1)*...时,仍然仅使用双精度计算它。您可以使用符号评估

来解决此问题
vpa(subs('1/(2*i-1)*(4*((1/5)^(2*i-1))-(1/239)^(2*i-1))','i',i),50)

代替:

function S = calpi(n)
S = vpa(0,50);
for i = 1:n
    tmp = vpa(subs('1/(2*i-1)*(4*((1/5)^(2*i-1))-(1/239)^(2*i-1))','i',i),50);
    if mod(i,2) == 0
        S = S-tmp;
    else
        S = S+tmp;
    end
end
S = 4*S;

至于为什么你的计算实际上更准确比你预期的更多: 当您使用正常vpa(x,50)变量double致电x时,会发生默认转化sym(x,'r')。 (见help sym)。

  

'r'代表&#39;理性&#39;。获得的浮点数       评估表单p/qp*pi/qsqrt(p)2^q10^q的表达式       对于适度大小的整数pq将转换为相应的整数       象征性的形式。

因此,当您调用vpa(S,50)时,MATLAB会检查您的双精度值是否接近某个分数p/q或分数p*pi/q等,如果是,则将值向上舍入那。在我们的情况下,Spi的足够好的近似值,vpa(S,50)sym('pi')四舍五入。如果我们不想舍入,我们可以使用类似vpa(sym(S,'f'), 50)的内容。