0

My Challenge

I am presently working my way through reddit's /r/dailyprogrammer challenges using Node.js and have caught a snag. Being that I'm finishing out day 3 with this single exercise, I've decided to look for help. I refuse to just move on without knowing how.

Challenge #6: Your challenge for today is to create a program that can calculate pi accurately to at least 30 decimal places.

My Snag

I've managed to obtain the precision arithmetic I was seeking via mathjs, but am left stumped on how to obtain 30 decimal places. Does anyone know a library, workaround or config that could help me reach my goal?

/*jslint node: true */
"use strict";

var mathjs = require('mathjs'),
  math = mathjs();

var i,
  x,
  pi;

console.log(Math.PI);

function getPi(i, x, pi) {
  if (i === undefined) {
    pi = math.eval('3 + (4/(2*3*4))');
    i = 2;
    x = 4;
    getPi(i, x, pi);
  } else {
      pi = math.eval('pi + (4/('+x+'*'+x+1+'*'+x+2+')) - (4/('+x+2+'*'+x+3+'*'+x+4+'))');
      x += 4;
      i += 1;
    if (x < 20000) {
      getPi(i, x, pi);
    } else {
      console.log(pi);
    }
  }
}

getPi();

I have made my way through many interations of this, and in this example am using the Nilakatha Series:

Nilakatha Series

bitfed
  • 347
  • 4
  • 11
  • 1
    You've read the [bignumber documentation](https://github.com/josdejong/mathjs/blob/master/docs/datatypes/bignumbers.md) and how to configure mathjs for 30-digit precision? – Bergi May 06 '14 at 20:06
  • I tried using `Math.PI.toFixed(30)` but apparently the max number of digits toFixed allows is 20 – Brian Glaz May 06 '14 at 20:06
  • No Bergi, I hadn't thought to do that. Great idea. – bitfed May 06 '14 at 20:08
  • I've located the `DECIMAL_PLACES : 30` [option](http://mikemcl.github.io/bignumber.js/#decimal-places), but am unaware of how to implement this config with mathjs. I'm happy to throw out mathjs, but I'd still like to learn how to config the dependency. – bitfed May 06 '14 at 20:15
  • math.js supports bignumbers, but the built-in constants like `pi` are still lacking bignumber support, they are regular Numbers. bignubmer support for constants is to be implemented. – Jos de Jong May 07 '14 at 09:42
  • @JosdeJong: Does atan efficiently support bignumber? Then just set pi=4*atan(1) in the desired precision. – Lutz Lehmann May 07 '14 at 15:39
  • No, right now non of the trigonometric functions support bignumbers, sorry. ([See docs](https://github.com/josdejong/mathjs/blob/master/docs/datatypes/bignumbers.md)) – Jos de Jong May 07 '14 at 19:13
  • @JosdeJong No constants are necessary for this exercise we are actually calculating Pi. I have only included it to compare to the result in the console. – bitfed May 07 '14 at 19:18

2 Answers2

0

This question uses some algorithm to compute digits of pi, apparently to arbitrary precision. Comments on that question indicate possible sources, in particular this paper. You could easily port that approach to JavaScript.

Community
  • 1
  • 1
MvG
  • 57,380
  • 22
  • 148
  • 276
0

This algorithm has, as an alternating series, an error of about 4/n^3 if the last term is 4/((n-2)*(n-1)*n), that is, using n-3 fraction terms. To get an error smaller than 0.5*10^(-30), you would need (at least) n=2*10^10 terms of this series. With that number, you have to take care of floating point errors, especially of cancellation effects when adding a large number and a small number. The best way to avoid that is to start the summation with the smallest term and then go backwards. Or do the summation forward, but with a precision of 60 decimals, to then round the result to 30 decimals.

It would be better to use the faster converging Machin formula, or one of the Machin-like formulas, if you want to have some idea of what exactly you are computing. If not, then use one of the super fast formulas used for billions of digits, but for 30 digits this is likely overkill.

See wikipedia on the approximations of pi.

Lutz Lehmann
  • 25,219
  • 2
  • 22
  • 51