PI迭代算法存在的问题 [英] Problems with iterative algorithm for PI
问题描述
我正在尝试一些近似Pi的公式,但这个 [ ^ ]一个给了我一些麻烦:
I was trying out some of the formulas for approximating Pi, but this[^] one gives me some trouble:
Dim alpha As Decimal = 6D - 4D * Math.Sqrt(CDec(2))
Dim piY As Decimal = Math.Sqrt(CDec(2)) - 1D
''' <summary>
'''
''' </summary>
''' <param name="N">Greater than or equal to 1</param>
''' <returns></returns>
''' <remarks></remarks>
Private Function GetPi(ByVal N As Integer) As Decimal
Dim result As Decimal
Dim TempAlpha, TempYPi As Decimal
TempAlpha = alpha
TempYPi = piY
If N = 0 Then
Return 1D / TempAlpha
End If
For i As Integer = 1 To N
TempYPi = (1D - Math.Pow((1D - Math.Pow(TempYPi, 4D)), 1D / 4D)) / (1D + Math.Pow((1D - Math.Pow(TempYPi, 4D)), 1D / 4D))
TempAlpha = Math.Pow(1D + TempYPi, 4D) * TempAlpha - Math.Pow(2D, 2D * (CDec(i) - 1D) + 3D) * TempYPi * (1D + TempYPi + Math.Pow(TempYPi, 2D))
Next
result = 1D / TempAlpha
Return result
End Function
仅仅3次迭代后它就会停止变好(理论上它可以改善2 * 4 ^ n的精度),即使我将预制形式改为双精度到十进制也是如此。有人知道为什么或如何解决它?
PS。当然我可以使用Numerics.BigInteger做最后一个这里 [ ^ ],但这有些不同。
It stops getting better after just 3 iterations (theoretically it shoud improve the precistion with 2*4^n), even when I change the precition form double to decimal. Does anybody know why, or how to fix it?
PS. Sure I could use the Numerics.BigInteger and do the last one here[^], but thats something slightly different.
推荐答案
来自维基百科页面:
From the wikipedia page:
你无法获得这样的精度(100位), double
或十进制
数字。
那里实际上你的代码没有错,只是小数不适用于Math.Pow
和Math.Sqrt
。经过两次迭代后,所有数字都已正确。至少他们在我的电脑上。 :)
这里我使用的例子(C#WindowsForms):
There is actually nothing wrong with your code except that decimals won't work forMath.Pow
andMath.Sqrt
. After just two iterations all the digits are already correct. At least they were on my PC. :)
Here the example I worked with (C# WindowsForms):
namespace PI
{
public partial class Form1 : Form
{
static double alpha = 6d - 4d * Math.Sqrt(2d);
static double piY = Math.Sqrt(2d) - 1d;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int iterations = int.Parse(textBox2.Text);
GetPi(iterations);
}
private double GetPi(int n)
{
double result;
double TempAlpha, TempYPi;
TempAlpha = alpha;
TempYPi = piY;
result = 1d / TempAlpha;
textBox1.Clear();
for(int i = 1; i<=n; i++)
{
TempYPi = (1d - Math.Pow((1d - Math.Pow(TempYPi, 4d)), 1d / 4d)) / (1d + Math.Pow((1d - Math.Pow(TempYPi, 4d)), 1d / 4d));
TempAlpha = Math.Pow(1d + TempYPi, 4d) * TempAlpha - Math.Pow(2d, 2d * ((double)i - 1d) + 3d) * TempYPi * (1d + TempYPi + Math.Pow(TempYPi, 2d));
result = 1d / TempAlpha;
textBox1.Text += String.Format("{0} : {1}\r\n", i, result);
}
return result;
}
}
}
2次迭代的输出是:
The output for 2 iterations is:
1 : 3,14159264621355
2 : 3,14159265358979
PI: 3,1415926535897932384626433832795028841971693993751058209...
正如你在2次迭代后很容易看到的那样,double的精度已经用完了,所有计算的数字都已经正确了。
问候,
Manfred
As you can easily see after just 2 iteration the precision for double is already exhausted an all the digits calculated are already correct.
Regards,
Manfred
这篇关于PI迭代算法存在的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!