Click here to Skip to main content
15,890,527 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I was trying out some of the formulas for approximating Pi, but this[^] one gives me some trouble:

VB
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


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.
Posted
Updated 22-Sep-13 23:56pm
v2
Comments
Manfred Rudolf Bihy 22-Sep-13 12:27pm    
I searched your post, but I can't find any recursion happening anywhere. What am I missing?

Cheers,

Manfred
Kenneth Haugland 22-Sep-13 12:53pm    
A t the top in the first link:
Extremely long decimal expansions of π are typically computed with iterative formulae like the Gauss–Legendre algorithm and Borwein's algorithm. The latter, found in 1985 by Jonathan and Peter Borwein, converges extremely fast:

etc...
Manfred Rudolf Bihy 22-Sep-13 15:15pm    
Whatever, your algorithm displayed is iterative. That is why I asked in the first place. No recursion to be seen anywhere. So you are asking about how to turn (a possibly) recursive solution into an iterative one? Why not place the two next to each other, why would I want to visit another site without direct comparison.

Cheers,

Manfred
Kenneth Haugland 22-Sep-13 16:06pm    
It is not what type of algorithm that is used that really is the problem, the problem is that it wont improve the guess for Pi, even if the type is changed from double to decimal(as the given code is programmed with). Why is that?

The code can with ease be made recursive, but thats not the goal. To make it work on the other hand ;-)
Manfred Rudolf Bihy 22-Sep-13 17:00pm    
It could be I'm just being dumb, but why does the title of your post still say "recursive" when there's no trace of any recursion going on at all. The title is completely distracting from the intention of your post. The title is the first thing that one sees so why not make it more pertinent to the real question.

Just saying!

From the wikipedia page:

converges quartically to PI, giving about 100 digits in three steps and over a trillion digits after 20 steps


You cannot obtain such a precision (100 digits) with double or decimal numbers.
 
Share this answer
 
v2
Comments
Kenneth Haugland 23-Sep-13 6:26am    
I understand that, but this code only gives med 6 - 7 correct digits, wheter it is double or decimal precition, surly I must expect more than that?
Manfred Rudolf Bihy 23-Sep-13 6:44am    
I don't think using decimal instead of double will help you at all, since most of the functions in Math work only on double, especially Math.Sqrt and Math.Pow. Cheers!
Kenneth Haugland 23-Sep-13 6:56am    
This seems to answer the question, or at least parts of it:
http://msdn.microsoft.com/en-us/library/system.math.sqrt.aspx
http://msdn.microsoft.com/en-us/library/system.math.pow.aspx

Dosnt seem to support decimal value calcualtions at all, or?
CPallini 23-Sep-13 6:59am    
OK, but what about double? You should get better results than '6-7 digits', I suppose.
Kenneth Haugland 23-Sep-13 7:15am    
I coudnt find any difference in double vs decimal calcualtion, perhaps its just an extremely greedy algorithm, powers of 4 and 4th root might kill this accuracy wise. Though I dont really know for sure-
There is actually nothing wrong with your code except that decimals won't work for Math.Pow and Math.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):

C#
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;
        }

    }
}


The output for 2 iterations is:

1 : 3,14159264621355
2 : 3,14159265358979
PI: 3,1415926535897932384626433832795028841971693993751058209...


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
 
Share this answer
 
Comments
Kenneth Haugland 23-Sep-13 12:15pm    
Actually it calcualtes more digits than it shows, type this instead:
result.ToString("N30")
However it only calcualtes to to 27 digits, and after the digits shown by you, they stop being correct. My calcualtions give me:
1 : 3,141592646213553642351489486500
2 : 3,141592653589799866274749263000
3 : 3,141592653589799866274749263000
PI : 3,141592653589790000000000000000
So not to bad after all, but no point in calcualtion it yourself like this :-)
Manfred Rudolf Bihy 23-Sep-13 13:57pm    
Precision for a double is 15 - 16 digits. We've got fifteen here so there's no more to expect from a double.
double (C# Reference)
It's to bad we cant use Math.Pow and Math.Sqrt with decimal, eventhough that also has only about 28 - 29 digits at most.

Cheers!
Kenneth Haugland 23-Sep-13 14:03pm    
Well, MAth.Sqrt I can fix with Newton iterations, but Pow is worse, if you are going to deal with non integer powers at least.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900