为什么在MATLAB中sin(Pi)不是精确的,而sin(pi/2)是精确的?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (565)

我在计算时遇到了问题matlab。我知道“ pi”是一个浮动数字,并不准确。所以,在matlab sin(pi)中并不完全是零。我的问题是如果“ pi”不是确切的,那么为什么sin(pi/2)完全等于1。

sin(pi)- >并不完全是因为pi。但 sin(pi/2)完全相等1

提问于
用户回答回答于

我不知道Matlab计算的确切方式sin(x)- 但你可以通过使用幂级数来计算它,例如

sin x = x - (x^3)/3! + (x^5)/5! - (x^7)/7! + (x^9)/9! ...

把它变成一些Matlab代码,我们用下面的代码表示它:

clc
x = pi;     %  or x = pi/2
res = x;
factor = -1;
for ii=3:2:19
  res = res + factor*power(x,ii)/factorial(ii);
  factor = factor*-1;  
  fprintf ( 'iteration %2i  sin(x)=%1.16f\n', (ii-1)/2, res );
end
res

运行这两个代码x=pix=pi/2你可以看到x=pi/2很快(9次迭代)收敛于正确的结果(eps错误内) - 而x=pi案例不会在相同的时间范围内收敛。

有用的是要注意,在9次迭代中,最后阶乘(19)中正在计算的阶乘。在这个序列中计算的下一个因子是21.这是由于双精度而可以用100%精度表示的最后一个因子(参见参考资料help factorial)。

所以我认为最近发生的事情是,对于pi / 2,数学解决方案收敛于1,在pi情况下以更快的双精度收敛。事实上,由于数学的局限性和可以以双精度结果存储的精度,pi情况完全不能完全收敛。

说了这么多的sin(pi)距离eps,所以你应该使用这个事实为你的目的。

我已经复制了我得到的结果(R2015b):

Results for PI/2
iteration  1  sin(x)=0.9248322292886504
iteration  2  sin(x)=1.0045248555348174
iteration  3  sin(x)=0.9998431013994987
iteration  4  sin(x)=1.0000035425842861
iteration  5  sin(x)=0.9999999437410510
iteration  6  sin(x)=1.0000000006627803
iteration  7  sin(x)=0.9999999999939768
iteration  8  sin(x)=1.0000000000000437
iteration  9  sin(x)=1.0000000000000000
Final Result: 1.0000000000000000


Results for PI
iteration  1  sin(x)=-2.0261201264601763
iteration  2  sin(x)=0.5240439134171688
iteration  3  sin(x)=-0.0752206159036231
iteration  4  sin(x)=0.0069252707075051
iteration  5  sin(x)=-0.0004451602382092
iteration  6  sin(x)=0.0000211425675584
iteration  7  sin(x)=-0.0000007727858894
iteration  8  sin(x)=0.0000000224195107
iteration  9  sin(x)=-0.0000000005289183
Final Result: -0.0000000005289183
用户回答回答于

原因是,sin(pi)=0.0所以每一个小小的错误,无论多么小,都是相当巨大的0,因此是可见的。

不同的是,sin(pi/2)=1如果算法产生的误差小于eps(大约2.220446e-16),则不会看到此错误,因为1+eps=1

该误差部分是由于不精确的输入(pi值不准确),部分是计算过程中的舍入结果。一个人必须深入研究代码才能做到正确。

另一个重要因素是功能本身。考虑到泰勒级数的错误传播pipi/2我们可以看到:

sin(pi+dx)=sin(pi)+cos(pi)dx+o(dx^2)=-dx+o(dx^2)
sin(pi/2+dx)=sin(pi/2)+cos(pi/2)dx+o(dx^2)=1+o(dx^2)

很明显:如果dxeps,那么由于不精确的输入所导致的错误将会是大约的eps*eps,因此与之相比是不可见的1

扫码关注云+社区

领取腾讯云代金券