calcualting digits of pi

lately, gaining intest in pi from some insight from a friend, i wrote this function to fill and array with digits of pi. it seems, however to work only for the first 17 digits of pi, yet my mathematical reasoning seems sound.

since pi is equal to:

       ∞
π =  ∑    2(-1)^k x 3^(1/2-k)
     k=0  -----------------------
                     2k + 1

what i decided to do is to evaulate each term. one i found that the one's column was no longer affected, that i could round off the deciamals, so for the first case, get 3, subtract that from the current obtained value of pi, then multiply this value by 10 and any other caluclated terms now by 10... one i find that the ones now is no longer affected, i do that same thing over again... extract the 1, multiply pi by 10, and any other terms now by 100.

However... this system only works for calculating the first 17 or so digits of pi. what am i doing wrong? here is the code to aid u helping me ;)



CODE------------------------------------------------------------------------------------



// Evaluates the numerator for the calc_pi function; SEE BELOW
inline double numerator_pow(int k, int i)
{
      double value = 2 * pow(3.0, (0.5 - double(k))) * pow(10.0, i);
      return (k % 2 == 1) ? -1 * value : value;
}

// Fills an array with the various digits of pi
//        ∞
// π =  ∑    2(-1)^k x 3^(1/2-k)
//       k=0 -----------------------
//                       2k + 1
//
// NOTE: Floating point impression prevents this line:
// double value = numerator(++k) / (2*k + 1) * pow(10.0, i);
// from producing a value greater than zero after the first 15 digits
void pi_digits(char* digits, int length)
{
      int k = 0;                                                            // Term counter for the sumnation
      double pi = 2 * sqrt(3.0);                                    // Calculate the first term in the expansion
      const double delta = 0.0000001;                              // Calculate a limiter value of the set precision
      const double neg_delta = -1 * delta;                  // Negative limiter. Half the term are negative so lowers
                                                                              // the number of operations if its calculated before
      
      for(int i = 0; i < length; ++i)
      {
            do
            {
                  double value = (numerator_pow(++k, i)) / (2*k + 1);
                  cout << i << " " << value << endl;
                  if(((k % 2 == 1) ? neg_delta : value) > ((k % 2 == 1) ? value : delta))
                        pi += value;
                  else
                  {
                        int digit = (int)pi;
                        double temp = (pi + value) * 10;
                        pi = temp - (digit * 10);
                        digits[i] = digit;
                        break;
                  }
            } while(true);
      }
}

cimnik2999Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

cimnik2999Author Commented:
damn unicode, okay... quickly to ease things

//        &#8734;
// &#960; =  &#8721;    2(-1)^k x 3^(1/2-k)
//       k=0 -----------------------
//                       2k + 1
//

&#8734 = ifinity
&#960 = pi
&#8721 = sigma/summnation notation
xf10036Commented:
Just keep in mind that rounding error accumulates quickly.

x.mar
jkrCommented:
Also, you 'minimum delta' seems kinda large. I'd suggest to use

#include <limits>

const double delta = std::numeric_limits<double>::epsilon();
Exploring ASP.NET Core: Fundamentals

Learn to build web apps and services, IoT apps, and mobile backends by covering the fundamentals of ASP.NET Core and  exploring the core foundations for app libraries.

cimnik2999Author Commented:
well... if i made it smaller, such as 0.1, i would then only get 15 digits, instead of 17... what is the value of std::numeric_limits<double>::epslon() anyways?
jkrCommented:
That depends on your machine - it is the maximum accuracy or the minimal difference between floating point numbers that your processor can handle.
waysideCommented:
doubles have only 17 digits of precision or thereabouts, so that seems logical that any algorithm that uses only doubles would be accurate to 17 digits or so.

You might want to use an arbitrary precision library such as GMP (http://www.swox.com/gmp/index.orig.html)

Or you could check this page, it seems to have lots of implementations for computing pi: http://projectpi.sourceforge.net/

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
cimnik2999Author Commented:
yeah i figured it might be a precision error, and thats why i made sure that the current digit would be above the decimal, in an attempt to get around this impressions... would that not get around it? ill look into an arbitrary precision library
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.